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

Example

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

DESCRIPTION

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

Applications

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

Broken Pipe Behavior

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

Standard Feeders And Acceptors

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

HISTORY

347       pm_system() was introduced in Netpbm 10.13 (January 2003).
348
349
350
351netpbm documentationNetpbm subro1u7tiOncetolbiebrra2r0y0:6pm_system() subroutine, etc.(3)
Impressum