1Netpbm subroutine libNreatrpyb:m pLsmiu_bbsrryaosrutyteimFn(ue)nclstiuibborrnaosruytM:iannpeum,a_lseytsct.e(m3()) subroutine, etc.(3)
2
3
4

Name

6       pm_system - run a Netpbm program with program input and output
7
8

Synopsis

10       #include <netpbm/pm_system.h>
11
12       pm_system(void                  stdinFeeder(int, void *),
13                 void *          const feederParm,
14                 void                  stdoutAccepter(int, void *),
15                 void *          const accepterParm,
16                 const char *    const shellCommand);
17
18       pm_system_lp(const char *  const progName,
19                    void                stdinFeeder(int, void *),
20                    void *        const feederParm,
21                    void                stdoutAccepter(int, void *),
22                    void *        const accepterParm,
23                    ...);
24
25       pm_system_vp(const char *  const progName,
26                    const char ** const argArray,
27                    void                stdinFeeder(int, void *),
28                    void *        const feederParm,
29                    void                stdoutAccepter(int, void *),
30                    void *        const accepterParm);
31
32
33

Example

35       This  simple  example  converts a PNM image on Standard Input to a JFIF
36       (JPEG) image on Standard Output.  In this case, pm_system() is doing no
37       more than system() would do.
38
39           pm_system(NULL, NULL, NULL, NULL, "pnmtojpeg");
40
41       This  example  does  the  same thing, but moves the data through memory
42       buffers to illustrate use with memory buffers, and we throw in a  stage
43       to shrink the image too:
44       #include <netpbm/pm_system.h>
45
46       char              pnmData[100*1024];   /* Input file better be < 100K */
47       char              jfifData[100*1024];
48       struct bufferDesc pnmBuffer;
49       struct bufferDesc jfifBuffer;
50       unsigned int      jfifSize;
51
52       pnmBuffer.size = fread(pnmData, 1, sizeof(pnmData), stdin);
53       pnmBuffer.buffer = pnmData;
54       pnmBuffer.bytesTransferredP = NULL;
55
56       jfifBuffer.size = sizeof(jfifData);
57       jfifBuffer.buffer = jfifData;
58       jfifBuffer.bytesTransferredP = &jfifSize;
59
60       pm_system(&pm_feed_from_memory, &pnmBuffer,
61                 &pm_accept_to_memory, &jfifBuffer,
62                 "pamscale .5 | pnmtojpeg");
63
64       fwrite(jfifData, 1, jfifSize, stdout);
65
66
67       This example reads an image into libnetpbm PAM structures, then bright‐
68       ens it, then writes it out, to illustrate use  of  pm_system  with  PAM
69       structures.
70       #include <netpbm/pam.h>
71       #include <netpbm/pm_system.h>
72
73       struct pam       inpam;
74       struct pam       outpam;
75       tuple **         inTuples;
76       tuple **         outTuples;
77       struct pamtuples inPamtuples;
78       struct pamtuples outPamtuples;
79
80       inTuples = pnm_readpam(stdin, &inpam, sizeof(inpam));
81
82       outpam = inpam;
83
84       inPamtuples.pamP = &inpam;
85       inPamtuples.tuplesP = &inTuples;
86       outPamtuples.pamP = &outpam;
87       outPamtuples.tuplesP = &outTuples;
88
89       pm_system(&pm_feed_from_pamtuples, &inPamtuples,
90                 &pm_accept_to_pamtuples, &outPamtuples,
91                 "ppmbrighten -v 100");
92
93       outpam.file = stdout;
94       pnm_writepam(&outpam, outTuples);
95
96
97
98
99

DESCRIPTION

101       These library functions are part of Netpbm(1).
102
103       pm_system()  is  a lot like the standard C library system() subroutine.
104       It runs a shell and has that shell execute a  shell  command  that  you
105       specify.   But  pm_system()  gives  you  more control over the Standard
106       Input and Standard Output of that shell command  than  system().   sys‐
107       tem() passes to the shell command as Standard Input and Output whatever
108       is the Standard Input and Output of the process  that  calls  system().
109       But  with  pm_system(), you specify as arguments subroutines to execute
110       to generate the shell command's Standard Input stream  and  to  process
111       the shell command's Standard Output stream.
112
113       Your Standard Input feeder subroutine can generate the stream in limit‐
114       less ways.  pm_system() gives it a file descriptor of a pipe  to  which
115       to  write  the stream it generates.  pm_system() hooks up the other end
116       of that pipe to the shell command's Standard Input.
117
118       Likewise, your Standard Output accepter subroutine can do  anything  it
119       wants  with the stream it gets.  pm_system() gives it a file descriptor
120       of a pipe from which to read the  stream.   pm_system()  hooks  up  the
121       other end of that pipe to the shell command's Standard Output.
122
123       The  argument  stdinFeeder  is  a function pointer that identifies your
124       Standard Input feeder subroutine.   pm_system()  runs  it  in  a  child
125       process  and  waits for that process to terminate (and accepts its com‐
126       pletion status) before returning.   feederParm  is  the  argument  that
127       pm_system() passes to the subroutine; it is opaque to pm_system().
128
129       If  you pass stdinFeeder = NULL, pm_system() simply passes your current
130       Standard Input stream to the shell command (as system() would do),  and
131       does not create a child process.
132
133       The  argument stdoutAccepter is a function pointer that identifies your
134       Standard Output accepter subroutine.  pm_system() calls it in the  cur‐
135       rent process.  accepterParm is an argument analogous to feederParm.
136
137       If  you pass stdoutAccepter = NULL, pm_system() simply passes your cur‐
138       rent Standard Output stream to the shell command (as system() would do.
139
140       The argument shellCommand is a null-terminated  string  containing  the
141       shell command that the shell is to execute.  It can be any command that
142       means something to the shell and can take a pipe for Standard Input and
143       Output.  Example:
144
145           ppmbrighten -v 100 | pamdepth 255 | pamscale .5
146
147       pm_system() creates a child process to run the shell and waits for that
148       process to terminate (and accepts its completion status) before return‐
149       ing.
150
151
152   pm_system_lp()
153       pm_system_lp()  is  like  pm_system()  except that instead of running a
154       shell, which in turn typically runs another program, you run a  program
155       of your choice directly.
156
157       Argument  progName  identifies the program to run, the same way as with
158       execlp() or a shell command: if it contains a slash (/), it is the full
159       name of the file that contains the program.  If not, it is a name to be
160       looked up in the system's program search path (determined by  the  PATH
161       environment variable).
162
163       You identify the arguments to the program the same way as for execlp():
164       with the variable arguments at the end of the  pm_system_lp()  argument
165       list.  Each is a NUL-terminated string.  The last argument must be NULL
166       to tell pm_system_lp() where the arguments end.
167
168       Note that the first argument ('arg0') to a  program  is  conventionally
169       the  first  word  of the command used to run the program, as if it were
170       being run due to a shell command.  In other words, typically  the  name
171       of the program.
172
173       Example:
174
175           pm_system_lp('pnmtojpeg', NULL, NULL, NULL, NULL,
176                        'pnmtojpeg', 'mypicture.jpg', '-quality=50', NULL);
177
178       pm_system_lp()  is  much  safer than pm_system() when your program com‐
179       putes the arguments or gets them from a user.  If  you  build  a  shell
180       command using such arguments, unless you're really careful, you may end
181       up building a shell command that does  something  very  different  from
182       what  you  intended, because the argument could contain characters that
183       mean something to the shell such as '|'.
184
185       pm_system_lp() can also be considerably faster that pm_system(),  since
186       it skips the whole running of the shell.
187
188
189
190   pm_system_vp()
191       pm_system_vp()  is like pm_system_lp() except that instead of supplying
192       the program arguments as variable arguments,  you  supply  them  as  an
193       array,  as  with  execvp().  A NULL element in the array identifies the
194       end of the arguments.
195
196       Example:
197
198           const char * argArray[3];
199
200           argArray[0] = 'pnmtojpeg';
201           argArray[1] = '-quality=50';
202           argArray[2] = NULL;
203
204           pm_system_vp('pnmtojpeg', argArray, NULL, NULL, NULL, NULL);
205
206
207

Applications

209       The point of pm_system() and friends is to allow you to write a C  pro‐
210       gram  that  uses  other  programs  internally, as a shell script would.
211       This is particularly desirable with Netpbm, because Netpbm consists  of
212       a  lot  of  programs that perform basic graphic manipulations and you'd
213       like to be able to build a  program  that  does  a  more  sophisticated
214       graphic  manipulation by calling the more basic Netpbm programs.  These
215       building block programs typically take input from  Standard  Input  and
216       write output to Standard Output.
217
218       The  obvious  alternative  is  to use a higher level language -- Bourne
219       Shell or Perl, for example.  But often you  want  your  program  to  do
220       manipulations of your graphical data that are easier and more efficient
221       in C.  Or you want to use the Netpbm subroutine library  in  your  pro‐
222       gram.   The  Netpbm subroutine library is a C-linkage library; the sub‐
223       routines in it are not usable from a Bourne Shell or Perl program.
224
225       A typical use of pm_system() is to place the contents of some graphical
226       image  file  in  memory, run a Netpbm program against it, and have what
227       would ordinarily go into an output file in memory too, for further pro‐
228       cessing.   To  do  that,  you  can use the memory buffer Standard Input
229       feeder and Standard Output accepter described below.
230
231       If your program uses the Netpbm subroutine library to read, write,  and
232       manipulate images, you may have an image in an array of PAM tuples.  If
233       you want to manipulate that image with a Netpbm program (perhaps  remap
234       the  colors  using  pnmremap),  you can use the pamtuple Standard Input
235       feeder and Standard Output acceptor described below.
236
237

Broken Pipe Behavior

239       When you set up a shell command to take input from a pipe,  as  you  do
240       with pm_system(), you need to understand how pipes work with respect to
241       the programs at either end of the pipe agreeing to how much data is  to
242       be transferred.  Here are some notes on that.
243
244       It  is  normal  to  read a pipe before the process on the other end has
245       written the data you hope to read, and it is normal to write to a  pipe
246       before  the  process  on  the  other  end  has tried to read your data.
247       Writes to a pipe can be buffered until the  reading  end  requests  the
248       data.   A  process  reading or writing a pipe can block until the other
249       end is ready.  Or a read or write can complete with an indication  that
250       the other end is not ready at the moment and therefore no data, or less
251       data than was requested, was transferred.
252
253       The pipe is normally controlled by the writing end.  When you read from
254       a pipe, you keep reading until the program on the other end of the pipe
255       closes it, and then you get an end-of-file indication.  You  then  nor‐
256       mally close the reading end of the pipe, since it is no longer useful.
257
258       When you close the reading end of a pipe before getting the end-of-file
259       indication and the writer subsequently tries to write to the pipe, that
260       is  an error condition for the writer.  In a typical default Unix envi‐
261       ronment, that error causes the writer to receive a SIGPIPE  signal  and
262       that signal causes the writer process to terminate abnormally.  But if,
263       alternatively, the writer has ordered that SIGPIPE be blocked, ignored,
264       or  handled,  the  signal  does  not  cause  the  death  of the writer.
265       Instead, the write operation simply completes with an error indication.
266
267
268

Standard Feeders And Acceptors

270       You can supply anything you like as a Standard Input feeder or Standard
271       Output  acceptor,  but  the  Netpbm subroutine library comes with a few
272       that perform commonly needed functions.
273
274
275   Memory Buffer
276       These routines are for when you just want to treat an area of memory as
277       a  file.  If the shell command would ordinarily read a 513 byte regular
278       file from its Standard Input, you want it to take 513 bytes from a cer‐
279       tain address in your process' memory.  Whatever bytes the shell command
280       wants to write to its output file you  want  it  to  store  at  another
281       address in your process' memory.
282
283       The  Standard Input feeder for this is called pm_feed_from_memory.  The
284       Standard Output accepter is pm_accept_to_memory.
285
286       For both of these, the argument is the address of a struct  bufferDesc,
287       which is defined as follows:
288
289       struct bufferDesc {
290           unsigned int    size;
291           unsigned char * buffer;
292           unsigned int *  bytesTransferredP;
293       };
294
295       size  is  the  size  of the memory buffer and buffer is its location in
296       memory (address).  The Standard Input feeder will attempt to  feed  the
297       entire  buffer to the shell command's Standard Input; the Standard Out‐
298       put accepter will not accept any more data  from  the  shell  command's
299       Standard  Output  than  will fit in the buffer.  Both return the actual
300       amount of data read or written, in bytes, at the location identified by
301       bytesTransferredP.  Unless bytesTransferredP is NULL.
302
303       Because  a  process typically terminates abnormally when it is not able
304       to write everything to a pipe that it wanted to,  bytesTransferredP  is
305       not usually useful in the Standard Input feeder case.
306
307
308
309   Pamtuple
310       These  routines  are  for  when  you  have images in memory in the data
311       structures used by the PAM family of subroutines in the Netpbm  library
312       --  i.e. struct PAM and an array of struct tuple.  With these routines,
313       you can run a Netpbm program against such an image just  as  you  would
314       against the same image in a regular file.
315
316       The  Standard  Input  feeder for this is called pm_feed_from_pamtuples.
317       The Standard Output accepter is pm_accept_to_pamtuples.
318
319       For both of these, the argument is the address of a  struct  pamtuples,
320       which is defined as follows:
321
322       struct pamtuples {
323           struct pam * pamP;
324           tuple ***    tuplesP;
325       };
326
327       For  the  Standard  Input  feeder,  you  supply  a struct pam, valid up
328       through the tuple_type member (except it doesn't matter what  the  file
329       member is) and array of tuples.
330
331       For  the  Standard Output Accepter, you supply only space in memory for
332       the struct pam and the address of the tuple array.  The  routine  fills
333       in  the  struct pam up through the tuple_type member (except leaves the
334       file member undefined) and allocates space for  the  tuple  array  with
335       malloc().  You are responsible for freeing that memory.
336
337

HISTORY

339       pm_system() was introduced in Netpbm 10.13 (January 2003).
340
341
342
343netpbm documentationNetpbm subro1u7tiOncetolbiebrra2r0y0:6pm_system() subroutine, etc.(3)
Impressum