1 /* pm.h - interface to format-independent part of libpbm.
2 **
3 ** Copyright (C) 1988, 1989, 1991 by Jef Poskanzer.
4 **
5 ** Permission to use, copy, modify, and distribute this software and its
6 ** documentation for any purpose and without fee is hereby granted, provided
7 ** that the above copyright notice appear in all copies and that both that
8 ** copyright notice and this permission notice appear in supporting
9 ** documentation.  This software is provided "as is" without express or
10 ** implied warranty.
11 */
12 
13 #ifndef PM_H_INCLUDED
14 #define PM_H_INCLUDED
15 
16 #include <netpbm/pm_config.h>
17 
18 #include <sys/types.h>
19 #include <ctype.h>
20 #include <stdio.h>
21 #include <errno.h>
22 #include <setjmp.h>
23 #include <sys/stat.h>
24 #include <fcntl.h>
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 #if 0
30 } /* to fake out automatic code indenters */
31 #endif
32 
33 
34 /* Definitions to make Netpbm programs work with either ANSI C or C
35    Classic.
36 
37    This is obsolete, as all compilers recognize the ANSI syntax now.
38 
39    We are slowly removing all the ARGS invocations from the programs
40    (and replacing them with explicit ANSI syntax), but we have a lot
41    of programs where we have removed ARGS from the definition but not
42    the prototype, and we have discovered that the Sun compiler
43    considers the resulting mismatch between definition and prototype
44    to be an error.  So we make ARGS create the ANSI syntax
45    unconditionally to avoid having to fix all those mismatches.  */
46 
47 #if 0
48 #if __STDC__
49 #define ARGS(alist) alist
50 #else /*__STDC__*/
51 #define ARGS(alist) ()
52 #define const
53 #endif /*__STDC__*/
54 #endif
55 #define ARGS(alist) alist
56 
57 
58 /* PM_GNU_PRINTF_ATTR lets the GNU compiler check pm_message() and pm_error()
59    calls to be sure the arguments match the format string, thus preventing
60    runtime segmentation faults and incorrect messages.
61 */
62 #ifdef __GNUC__
63 #define PM_GNU_PRINTF_ATTR(a,b) __attribute__ ((format (printf, a, b)))
64 #else
65 #define PM_GNU_PRINTF_ATTR(a,b)
66 #endif
67 
68 
69 /* PURE_FN_ATTR is the attribute you add to a function declaration
70    that indicates it's a true function -- has no side effects and return
71    value is not influenced by anything except its arguments.
72 */
73 #ifdef __GNUC__
74 #define PURE_FN_ATTR __attribute__ ((const))
75 #else
76 #define PURE_FN_ATTR
77 #endif
78 
79 
80 /* S_IRUSR is POSIX, defined in <sys/stat.h> Some old BSD systems and Windows
81    systems have S_IREAD instead.  Most Unix today (2011) has both.  In 2011,
82    Android has S_IRUSR and not S_IREAD.
83 
84    Some Windows has _S_IREAD.
85 
86    We're ignoring S_IREAD now to see if anyone misses it.  If there are still
87    users that need it, we can handle it here.
88 */
89 #if MSVCRT
90   #define PM_S_IWUSR _S_IWRITE
91   #define PM_S_IRUSR _S_IREAD
92 #else
93   #define PM_S_IWUSR S_IWUSR
94   #define PM_S_IRUSR S_IRUSR
95 #endif
96 
97 
98 
99 typedef struct {
100     /* Coordinates of a pixel within an image.  Row 0 is the top row.
101        Column 0 is the left column.
102     */
103     unsigned int row;
104     unsigned int col;
105 } pm_pixelcoord;
106 
107 extern int pm_plain_output;
108     /* Output functions are to produce plain (as opposed to raw) format
109        regardless of their 'plainformat' arguments.
110     */
111 extern const char * pm_progname;
112 
113 void
114 pm_init(const char * const progname, unsigned int const flags);
115 
116 void
117 pm_proginit(int * const argcP, const char * argv[]);
118 
119 void
120 pm_setMessage(int const newState, int * const oldStateP);
121 
122 int
123 pm_getMessage(void);
124 
125 FILE *
126 pm_tmpfile(void);
127 
128 int
129 pm_tmpfile_fd(void);
130 
131 void
132 pm_make_tmpfile(FILE **       const filePP,
133                 const char ** const filenameP);
134 
135 void
136 pm_make_tmpfile_fd(int *         const fdP,
137                    const char ** const filenameP);
138 
139 void
140 pm_nextimage(FILE * const file, int * const eofP);
141 
142 /* Variable-sized arrays definitions. */
143 
144 char**
145 pm_allocarray (int const cols, int const rows, int const size );
146 
147 void *
148 pm_allocrow(unsigned int const cols,
149             unsigned int const size);
150 
151 void
152 pm_freearray (char** const its, int const rows);
153 
154 void
155 pm_freerow(void * const row);
156 
157 
158 /* Obsolete -- use shhopt instead */
159 int
160 pm_keymatch(const char * const str,
161             const char * const keyword,
162             int          const minchars);
163 
164 
165 int PURE_FN_ATTR
166 pm_maxvaltobits(int const maxval);
167 
168 int PURE_FN_ATTR
169 pm_bitstomaxval(int const bits);
170 
171 unsigned int PURE_FN_ATTR
172 pm_lcm (unsigned int const x,
173         unsigned int const y,
174         unsigned int const z,
175         unsigned int const limit);
176 
177 void
178 pm_setjmpbuf(jmp_buf * const jmpbufP);
179 
180 void
181 pm_setjmpbufsave(jmp_buf *  const jmpbufP,
182                  jmp_buf ** const oldJmpbufPP);
183 
184 void
185 pm_longjmp(void);
186 
187 void
188 pm_fork(int *         const iAmParentP,
189         pid_t *       const childPidP,
190         const char ** const errorP);
191 
192 void
193 pm_waitpid(pid_t         const pid,
194            int *         const statusP,
195            int           const options,
196            pid_t *       const exitedPidP,
197            const char ** const errorP);
198 
199 
200 void
201 pm_waitpidSimple(pid_t const pid);
202 
203 typedef void pm_usermessagefn(const char * msg);
204 
205 void
206 pm_setusermessagefn(pm_usermessagefn * fn);
207 
208 typedef void pm_usererrormsgfn(const char * msg);
209 
210 void
211 pm_setusererrormsgfn(pm_usererrormsgfn * fn);
212 
213 void PM_GNU_PRINTF_ATTR(1,2)
214 pm_message (const char format[], ...);
215 
216 void PM_GNU_PRINTF_ATTR(1,2)
217 pm_errormsg(const char format[], ...);
218 
219 void PM_GNU_PRINTF_ATTR(1,2)
220 pm_error (const char reason[], ...);
221 
222 int
223 pm_have_float_format(void);
224 
225 /* Obsolete - use shhopt and user's manual instead */
226 void
227 pm_usage (const char usage[]);
228 
229 FILE*
230 pm_openr (const char* const name);
231 
232 FILE*
233 pm_openw (const char* const name);
234 
235 FILE *
236 pm_openr_seekable(const char name[]);
237 
238 void
239 pm_close (FILE* const f);
240 
241 void
242 pm_closer (FILE* const f);
243 
244 void
245 pm_closew (FILE* const f);
246 
247 
248 
249 void
250 pm_readchar(FILE * const ifP,
251             char * const cP);
252 
253 static __inline__ void
pm_readcharu(FILE * const ifP,unsigned char * const cP)254 pm_readcharu(FILE *          const ifP,
255              unsigned char * const cP) {
256     pm_readchar(ifP, (char *) cP);
257 }
258 
259 void
260 pm_writechar(FILE * const ofP,
261              char   const c);
262 
263 static __inline__ void
pm_writecharu(FILE * const ofP,unsigned char const c)264 pm_writecharu(FILE *        const ofP,
265               unsigned char const c) {
266     pm_writechar(ofP, (char) c);
267 }
268 
269 int
270 pm_readbigshort(FILE *  const ifP,
271                 short * const sP);
272 
273 static __inline__ int
pm_readbigshortu(FILE * const ifP,unsigned short * const sP)274 pm_readbigshortu(FILE*            const ifP,
275                  unsigned short * const sP) {
276     return pm_readbigshort(ifP, (short *) sP);
277 }
278 
279 int
280 pm_writebigshort(FILE * const ofP,
281                  short  const s);
282 
283 static __inline__ int
pm_writebigshortu(FILE * const ofP,unsigned short const s)284 pm_writebigshortu(FILE *          const ofP,
285                   unsigned short  const s) {
286     return pm_writebigshort(ofP, (short) s);
287 }
288 
289 int
290 pm_readbiglong(FILE * const ifP,
291                long * const lP);
292 
293 static __inline__ int
pm_readbiglongu(FILE * const ifP,unsigned long * const lP)294 pm_readbiglongu(FILE *          const ifP,
295                 unsigned long * const lP) {
296     return pm_readbiglong(ifP, (long *) lP);
297 }
298 
299 int
300 pm_readbiglong2(FILE * const ifP,
301                 int32_t * const lP);
302 
303 static __inline__ int
pm_readbiglongu2(FILE * const ifP,uint32_t * const lP)304 pm_readbiglongu2(FILE *     const ifP,
305                  uint32_t * const lP) {
306     return pm_readbiglong2(ifP, (int32_t *) lP);
307 }
308 
309 int
310 pm_writebiglong(FILE * const ofP,
311                 long   const l);
312 
313 static __inline__ int
pm_writebiglongu(FILE * const ofP,unsigned long const l)314 pm_writebiglongu(FILE *        const ofP,
315                  unsigned long const l) {
316     return pm_writebiglong(ofP, (long) l);
317 }
318 
319 int
320 pm_readlittleshort(FILE  * const ifP,
321                    short * const sP);
322 
323 static __inline__ int
pm_readlittleshortu(FILE * const ifP,unsigned short * const sP)324 pm_readlittleshortu(FILE  *          const ifP,
325                     unsigned short * const sP) {
326     return pm_readlittleshort(ifP, (short *) sP);
327 }
328 
329 int
330 pm_writelittleshort(FILE * const ofP,
331                     short  const s);
332 
333 static __inline__ int
pm_writelittleshortu(FILE * const ofP,unsigned short const s)334 pm_writelittleshortu(FILE *          const ofP,
335                      unsigned short  const s) {
336     return pm_writelittleshort(ofP, (short) s);
337 }
338 
339 int
340 pm_readlittlelong(FILE * const ifP,
341                   long * const lP);
342 
343 static __inline__ int
pm_readlittlelongu(FILE * const ifP,unsigned long * const lP)344 pm_readlittlelongu(FILE *          const ifP,
345                    unsigned long * const lP) {
346     return pm_readlittlelong(ifP, (long *) lP);
347 }
348 
349 int
350 pm_readlittlelong2(FILE *    const ifP,
351                    int32_t * const lP);
352 
353 static __inline__ int
pm_readlittlelong2u(FILE * const ifP,uint32_t * const lP)354 pm_readlittlelong2u(FILE *     const ifP,
355                     uint32_t * const lP) {
356     return pm_readlittlelong2(ifP, (int32_t *) lP);
357 }
358 
359 int
360 pm_writelittlelong(FILE * const ofP,
361                    long   const l);
362 
363 static __inline__ int
pm_writelittlelongu(FILE * const ofP,unsigned long const l)364 pm_writelittlelongu(FILE *        const ofP,
365                     unsigned long const l) {
366     return pm_writelittlelong(ofP, (long) l);
367 }
368 
369 int
370 pm_readmagicnumber(FILE * const ifP);
371 
372 char*
373 pm_read_unknown_size(FILE * const ifP,
374                      long * const buf);
375 
376 void
377 pm_getline(FILE *   const ifP,
378            char **  const bufferP,
379            size_t * const bufferSzP,
380            int *    const eofP,
381            size_t * const lineLenP);
382 
383 short
384 pm_bs_short(short const s);
385 
386 long
387 pm_bs_long(long const l);
388 
389 unsigned int
390 pm_tell(FILE * const fileP);
391 
392 void
393 pm_tell2(FILE *       const fileP,
394          void *       const fileposP,
395          unsigned int const fileposSize);
396 
397 void
398 pm_seek2(FILE *             const fileP,
399          const pm_filepos * const fileposP,
400          unsigned int       const fileposSize);
401 
402 void
403 pm_seek(FILE * const fileP, unsigned long filepos);
404 
405 enum pm_check_code {
406     PM_CHECK_OK,
407     PM_CHECK_UNKNOWN_TYPE,
408     PM_CHECK_TOO_LONG,
409     PM_CHECK_UNCHECKABLE,
410     PM_CHECK_TOO_SHORT
411 };
412 
413 enum pm_check_type {
414     PM_CHECK_BASIC
415 };
416 
417 void
418 pm_check(FILE *               const file,
419          enum pm_check_type   const check_type,
420          pm_filepos           const need_raster_size,
421          enum pm_check_code * const retval_p);
422 
423 void
424 pm_drain(FILE *         const fileP,
425          unsigned int   const limit,
426          unsigned int * const bytesReadP);
427 
428 char *
429 pm_arg0toprogname(const char arg0[]);
430 
431 unsigned int
432 pm_randseed(void);
433 
434 unsigned int
435 pm_parse_width(const char * const arg);
436 
437 unsigned int
438 pm_parse_height(const char * const arg);
439 
440 #ifdef __cplusplus
441 }
442 #endif
443 
444 
445 #endif
446