VirtualBox

source: vbox/trunk/src/libs/libpng-1.6.42/contrib/pngminus/png2pnm.c@ 103585

最後變更 在這個檔案從103585是 103316,由 vboxsync 提交於 12 月 前

libpng-1.6.42: Applied and adjusted our libpng changes to 1.6.42. bugref:8515

  • 屬性 svn:eol-style 設為 native
檔案大小: 10.1 KB
 
1/*
2 * png2pnm.c --- conversion from PNG-file to PGM/PPM-file
3 * copyright (C) 1999-2019 by Willem van Schaik <willem at schaik dot com>
4 *
5 * This software is released under the MIT license. For conditions of
6 * distribution and use, see the LICENSE file part of this package.
7 */
8
9#include <stdio.h>
10#include <stdlib.h>
11#include <fcntl.h>
12
13#ifndef BOOL
14#define BOOL unsigned char
15#endif
16#ifndef TRUE
17#define TRUE ((BOOL) 1)
18#endif
19#ifndef FALSE
20#define FALSE ((BOOL) 0)
21#endif
22
23#include "png.h"
24
25/* function prototypes */
26
27int main (int argc, char *argv[]);
28void usage ();
29BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file,
30 BOOL raw, BOOL alpha);
31BOOL do_png2pnm (png_struct *png_ptr, png_info *info_ptr,
32 FILE *pnm_file, FILE *alpha_file,
33 BOOL raw, BOOL alpha);
34
35/*
36 * main
37 */
38
39int main (int argc, char *argv[])
40{
41 FILE *fp_rd = stdin;
42 FILE *fp_wr = stdout;
43 FILE *fp_al = NULL;
44 const char *fname_wr = NULL;
45 const char *fname_al = NULL;
46 BOOL raw = TRUE;
47 BOOL alpha = FALSE;
48 int argi;
49 int ret;
50
51 for (argi = 1; argi < argc; argi++)
52 {
53 if (argv[argi][0] == '-')
54 {
55 switch (argv[argi][1])
56 {
57 case 'n':
58 raw = FALSE;
59 break;
60 case 'r':
61 raw = TRUE;
62 break;
63 case 'a':
64 alpha = TRUE;
65 argi++;
66 if ((fp_al = fopen (argv[argi], "wb")) == NULL)
67 {
68 fname_al = argv[argi];
69 fprintf (stderr, "PNM2PNG\n");
70 fprintf (stderr, "Error: cannot create alpha-channel file %s\n",
71 argv[argi]);
72 exit (1);
73 }
74 break;
75 case 'h':
76 case '?':
77 usage ();
78 exit (0);
79 break;
80 default:
81 fprintf (stderr, "PNG2PNM\n");
82 fprintf (stderr, "Error: unknown option %s\n", argv[argi]);
83 usage ();
84 exit (1);
85 break;
86 } /* end switch */
87 }
88 else if (fp_rd == stdin)
89 {
90 if ((fp_rd = fopen (argv[argi], "rb")) == NULL)
91 {
92 fprintf (stderr, "PNG2PNM\n");
93 fprintf (stderr, "Error: file %s does not exist\n", argv[argi]);
94 exit (1);
95 }
96 }
97 else if (fp_wr == stdout)
98 {
99 fname_wr = argv[argi];
100 if ((fp_wr = fopen (argv[argi], "wb")) == NULL)
101 {
102 fprintf (stderr, "PNG2PNM\n");
103 fprintf (stderr, "Error: cannot create file %s\n", argv[argi]);
104 exit (1);
105 }
106 }
107 else
108 {
109 fprintf (stderr, "PNG2PNM\n");
110 fprintf (stderr, "Error: too many parameters\n");
111 usage ();
112 exit (1);
113 }
114 } /* end for */
115
116#if defined(O_BINARY) && (O_BINARY != 0)
117 /* set stdin/stdout if required to binary */
118 if (fp_rd == stdin)
119 setmode (fileno (stdin), O_BINARY);
120 if ((raw) && (fp_wr == stdout))
121 setmode (fileno (stdout), O_BINARY);
122#endif
123
124 /* call the conversion program itself */
125 ret = png2pnm (fp_rd, fp_wr, fp_al, raw, alpha);
126
127 /* close input file */
128 fclose (fp_rd);
129 /* close output file */
130 fclose (fp_wr);
131 /* close alpha file */
132 if (alpha)
133 fclose (fp_al);
134
135 if (!ret)
136 {
137 fprintf (stderr, "PNG2PNM\n");
138 fprintf (stderr, "Error: unsuccessful conversion of PNG-image\n");
139 if (fname_wr)
140 remove (fname_wr); /* no broken output file shall remain behind */
141 if (fname_al)
142 remove (fname_al); /* ditto */
143 exit (1);
144 }
145
146 return 0;
147}
148
149/*
150 * usage
151 */
152
153void usage ()
154{
155 fprintf (stderr, "PNG2PNM\n");
156 fprintf (stderr, " by Willem van Schaik, 1999\n");
157 fprintf (stderr, "Usage: png2pnm [options] <file>.png [<file>.pnm]\n");
158 fprintf (stderr, " or: ... | png2pnm [options]\n");
159 fprintf (stderr, "Options:\n");
160 fprintf (stderr,
161 " -r[aw] write pnm-file in binary format (P4/P5/P6) (default)\n");
162 fprintf (stderr, " -n[oraw] write pnm-file in ascii format (P1/P2/P3)\n");
163 fprintf (stderr,
164 " -a[lpha] <file>.pgm write PNG alpha channel as pgm-file\n");
165 fprintf (stderr, " -h | -? print this help-information\n");
166}
167
168/*
169 * png2pnm
170 */
171
172BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file,
173 BOOL raw, BOOL alpha)
174{
175 png_struct *png_ptr;
176 png_info *info_ptr;
177 BOOL ret;
178
179 /* initialize the libpng context for reading from png_file */
180
181 png_ptr = png_create_read_struct (png_get_libpng_ver(NULL),
182 NULL, NULL, NULL);
183 if (!png_ptr)
184 return FALSE; /* out of memory */
185
186 info_ptr = png_create_info_struct (png_ptr);
187 if (!info_ptr)
188 {
189 png_destroy_read_struct (&png_ptr, NULL, NULL);
190 return FALSE; /* out of memory */
191 }
192
193 if (setjmp (png_jmpbuf (png_ptr)))
194 {
195 png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
196 return FALSE; /* generic libpng error */
197 }
198
199 png_init_io (png_ptr, png_file);
200
201 /* do the actual conversion */
202 ret = do_png2pnm (png_ptr, info_ptr, pnm_file, alpha_file, raw, alpha);
203
204 /* clean up the libpng structures and their internally-managed data */
205 png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
206
207 return ret;
208}
209
210/*
211 * do_png2pnm - does the conversion in a fully-initialized libpng context
212 */
213
214BOOL do_png2pnm (png_struct *png_ptr, png_info *info_ptr,
215 FILE *pnm_file, FILE *alpha_file,
216 BOOL raw, BOOL alpha)
217{
218 png_byte **row_pointers;
219 png_byte *pix_ptr;
220 png_uint_32 width;
221 png_uint_32 height;
222 int bit_depth;
223 int channels;
224 int color_type;
225 int alpha_present;
226 png_uint_32 row, col, i;
227 long dep_16;
228
229 /* set up the image transformations that are necessary for the PNM format */
230
231 /* set up (if applicable) the expansion of paletted images to full-color rgb,
232 * and the expansion of transparency maps to full alpha-channel */
233 png_set_expand (png_ptr);
234
235 /* set up (if applicable) the expansion of grayscale images to bit-depth 8 */
236 png_set_expand_gray_1_2_4_to_8 (png_ptr);
237
238#ifdef NJET
239 /* downgrade 16-bit images to 8-bit */
240 if (bit_depth == 16)
241 png_set_strip_16 (png_ptr);
242 /* transform grayscale images into full-color */
243 if (color_type == PNG_COLOR_TYPE_GRAY ||
244 color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
245 png_set_gray_to_rgb (png_ptr);
246 /* if the PNG image has a gAMA chunk then gamma-correct the output image */
247 {
248 double file_gamma;
249 if (png_get_gAMA (png_ptr, info_ptr, &file_gamma))
250 png_set_gamma (png_ptr, (double) 2.2, file_gamma);
251 }
252#endif
253
254 /* read the image file, with all of the above image transforms applied */
255 png_read_png (png_ptr, info_ptr, 0, NULL);
256
257 /* get the image size, bit-depth and color-type */
258 png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
259 NULL, NULL, NULL);
260
261 /* calculate the number of channels and store alpha-presence */
262 if (color_type == PNG_COLOR_TYPE_GRAY)
263 channels = 1;
264 else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
265 channels = 2;
266 else if (color_type == PNG_COLOR_TYPE_RGB)
267 channels = 3;
268 else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
269 channels = 4;
270 else
271 channels = 0; /* should never happen */
272 alpha_present = (channels - 1) % 2;
273
274 /* check if alpha is expected to be present in file */
275 if (alpha && !alpha_present)
276 {
277 fprintf (stderr, "PNG2PNM\n");
278 fprintf (stderr, "Warning: no alpha channel in PNG file\n");
279 return FALSE;
280 }
281
282 /* get address of internally-allocated image data */
283 row_pointers = png_get_rows (png_ptr, info_ptr);
284
285 /* write header of PNM file */
286
287 if ((color_type == PNG_COLOR_TYPE_GRAY) ||
288 (color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
289 {
290 fprintf (pnm_file, "%s\n", (raw) ? "P5" : "P2");
291 fprintf (pnm_file, "%d %d\n", (int) width, (int) height);
292 fprintf (pnm_file, "%ld\n", ((1L << (int) bit_depth) - 1L));
293 }
294 else if ((color_type == PNG_COLOR_TYPE_RGB) ||
295 (color_type == PNG_COLOR_TYPE_RGB_ALPHA))
296 {
297 fprintf (pnm_file, "%s\n", (raw) ? "P6" : "P3");
298 fprintf (pnm_file, "%d %d\n", (int) width, (int) height);
299 fprintf (pnm_file, "%ld\n", ((1L << (int) bit_depth) - 1L));
300 }
301
302 /* write header of PGM file with alpha channel */
303
304 if ((alpha) &&
305 ((color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
306 (color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
307 {
308 fprintf (alpha_file, "%s\n", (raw) ? "P5" : "P2");
309 fprintf (alpha_file, "%d %d\n", (int) width, (int) height);
310 fprintf (alpha_file, "%ld\n", ((1L << (int) bit_depth) - 1L));
311 }
312
313 /* write data to PNM file */
314
315 for (row = 0; row < height; row++)
316 {
317 pix_ptr = row_pointers[row];
318 for (col = 0; col < width; col++)
319 {
320 for (i = 0; i < (png_uint_32) (channels - alpha_present); i++)
321 {
322 if (raw)
323 {
324 fputc ((int) *pix_ptr++, pnm_file);
325 if (bit_depth == 16)
326 fputc ((int) *pix_ptr++, pnm_file);
327 }
328 else
329 {
330 if (bit_depth == 16)
331 {
332 dep_16 = ((long) *pix_ptr++) << 8;
333 dep_16 += ((long) *pix_ptr++);
334 fprintf (pnm_file, "%ld ", dep_16);
335 }
336 else
337 {
338 fprintf (pnm_file, "%ld ", (long) *pix_ptr++);
339 }
340 }
341 }
342 if (alpha_present)
343 {
344 if (!alpha)
345 {
346 /* skip the alpha-channel */
347 pix_ptr++;
348 if (bit_depth == 16)
349 pix_ptr++;
350 }
351 else
352 {
353 /* output the alpha-channel as pgm file */
354 if (raw)
355 {
356 fputc ((int) *pix_ptr++, alpha_file);
357 if (bit_depth == 16)
358 fputc ((int) *pix_ptr++, alpha_file);
359 }
360 else
361 {
362 if (bit_depth == 16)
363 {
364 dep_16 = ((long) *pix_ptr++) << 8;
365 dep_16 += ((long) *pix_ptr++);
366 fprintf (alpha_file, "%ld ", dep_16);
367 }
368 else
369 {
370 fprintf (alpha_file, "%ld ", (long) *pix_ptr++);
371 }
372 }
373 }
374 } /* end if alpha_present */
375
376 if (!raw)
377 if (col % 4 == 3)
378 fprintf (pnm_file, "\n");
379 } /* end for col */
380
381 if (!raw)
382 if (col % 4 != 0)
383 fprintf (pnm_file, "\n");
384 } /* end for row */
385
386 return TRUE;
387} /* end of source */
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette