2 * "$Id: image-png.c 6649 2007-07-11 21:46:42Z mike $"
4 * PNG image routines for the Common UNIX Printing System (CUPS).
6 * Copyright 2007 by Apple Inc.
7 * Copyright 1993-2007 by Easy Software Products.
9 * These coded instructions, statements, and computer programs are the
10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
15 * This file is subject to the Apple OS-Developed Software exception.
19 * _cupsImageReadPNG() - Read a PNG image file.
23 * Include necessary headers...
26 #include "image-private.h"
28 #if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ)
29 # include <png.h> /* Portable Network Graphics (PNG) definitions */
33 * '_cupsImageReadPNG()' - Read a PNG image file.
36 int /* O - Read status */
38 cups_image_t
*img
, /* IO - cupsImage */
39 FILE *fp
, /* I - cupsImage file */
40 cups_icspace_t primary
, /* I - Primary choice for colorspace */
41 cups_icspace_t secondary
, /* I - Secondary choice for colorspace */
42 int saturation
, /* I - Color saturation (%) */
43 int hue
, /* I - Color hue (degrees) */
44 const cups_ib_t
*lut
) /* I - Lookup table for gamma/brightness */
46 int y
; /* Looping var */
47 png_structp pp
; /* PNG read pointer */
48 png_infop info
; /* PNG info pointers */
49 png_uint_32 width
, /* Width of image */
50 height
; /* Height of image */
51 int bit_depth
, /* Bit depth */
52 color_type
, /* Color type */
53 interlace_type
, /* Interlace type */
54 compression_type
, /* Compression type */
55 filter_type
; /* Filter type */
56 png_uint_32 xppm
, /* X pixels per meter */
57 yppm
; /* Y pixels per meter */
58 int bpp
; /* Bytes per pixel */
59 int pass
, /* Current pass */
60 passes
; /* Number of passes required */
61 cups_ib_t
*in
, /* Input pixels */
62 *inptr
, /* Pointer into pixels */
63 *out
; /* Output pixels */
64 png_color_16 bg
; /* Background color */
68 * Setup the PNG data structures...
71 pp
= png_create_read_struct(PNG_LIBPNG_VER_STRING
, NULL
, NULL
, NULL
);
72 info
= png_create_info_struct(pp
);
75 * Initialize the PNG read "engine"...
81 * Get the image dimensions and load the output image...
84 png_read_info(pp
, info
);
86 png_get_IHDR(pp
, info
, &width
, &height
, &bit_depth
, &color_type
,
87 &interlace_type
, &compression_type
, &filter_type
);
89 fprintf(stderr
, "DEBUG: PNG image: %dx%dx%d, color_type=%x (%s%s%s)\n",
90 (int)width
, (int)height
, bit_depth
, color_type
,
91 (color_type
& PNG_COLOR_MASK_COLOR
) ? "RGB" : "GRAYSCALE",
92 (color_type
& PNG_COLOR_MASK_ALPHA
) ? "+ALPHA" : "",
93 (color_type
& PNG_COLOR_MASK_PALETTE
) ? "+PALETTE" : "");
95 if (color_type
& PNG_COLOR_MASK_PALETTE
)
97 else if (bit_depth
< 8)
102 else if (bit_depth
== 16)
103 png_set_strip_16(pp
);
105 if (color_type
& PNG_COLOR_MASK_COLOR
)
106 img
->colorspace
= (primary
== CUPS_IMAGE_RGB_CMYK
) ? CUPS_IMAGE_RGB
:
109 img
->colorspace
= secondary
;
111 if (width
== 0 || width
> CUPS_IMAGE_MAX_WIDTH
||
112 height
== 0 || height
> CUPS_IMAGE_MAX_HEIGHT
)
114 fprintf(stderr
, "DEBUG: PNG image has invalid dimensions %ux%u!\n",
115 (unsigned)width
, (unsigned)height
);
123 if ((xppm
= png_get_x_pixels_per_meter(pp
, info
)) != 0 &&
124 (yppm
= png_get_y_pixels_per_meter(pp
, info
)) != 0)
126 img
->xppi
= (int)((float)xppm
* 0.0254);
127 img
->yppi
= (int)((float)yppm
* 0.0254);
129 if (img
->xppi
== 0 || img
->yppi
== 0)
131 fprintf(stderr
, "DEBUG: PNG image has invalid resolution %dx%d PPI\n",
132 img
->xppi
, img
->yppi
);
134 img
->xppi
= img
->yppi
= 128;
138 cupsImageSetMaxTiles(img
, 0);
140 passes
= png_set_interlace_handling(pp
);
143 * Handle transparency...
146 if (png_get_valid(pp
, info
, PNG_INFO_tRNS
))
147 png_set_tRNS_to_alpha(pp
);
153 png_set_background(pp
, &bg
, PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
158 * Load one row at a time...
161 if (color_type
== PNG_COLOR_TYPE_GRAY
||
162 color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
163 in
= malloc(img
->xsize
);
165 in
= malloc(img
->xsize
* 3);
170 * Interlaced images must be loaded all at once...
173 if (color_type
== PNG_COLOR_TYPE_GRAY
||
174 color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
175 in
= malloc(img
->xsize
* img
->ysize
);
177 in
= malloc(img
->xsize
* img
->ysize
* 3);
180 bpp
= cupsImageGetDepth(img
);
181 out
= malloc(img
->xsize
* bpp
);
184 * Read the image, interlacing as needed...
187 for (pass
= 1; pass
<= passes
; pass
++)
188 for (inptr
= in
, y
= 0; y
< img
->ysize
; y
++)
190 png_read_row(pp
, (png_bytep
)inptr
, NULL
);
198 if (color_type
& PNG_COLOR_MASK_COLOR
)
200 if ((saturation
!= 100 || hue
!= 0) && bpp
> 1)
201 cupsImageRGBAdjust(inptr
, img
->xsize
, saturation
, hue
);
203 switch (img
->colorspace
)
205 case CUPS_IMAGE_WHITE
:
206 cupsImageRGBToWhite(inptr
, out
, img
->xsize
);
208 case CUPS_IMAGE_RGB
:
209 case CUPS_IMAGE_RGB_CMYK
:
210 cupsImageRGBToRGB(inptr
, out
, img
->xsize
);
212 case CUPS_IMAGE_BLACK
:
213 cupsImageRGBToBlack(inptr
, out
, img
->xsize
);
215 case CUPS_IMAGE_CMY
:
216 cupsImageRGBToCMY(inptr
, out
, img
->xsize
);
218 case CUPS_IMAGE_CMYK
:
219 cupsImageRGBToCMYK(inptr
, out
, img
->xsize
);
225 switch (img
->colorspace
)
227 case CUPS_IMAGE_WHITE
:
228 memcpy(out
, inptr
, img
->xsize
);
230 case CUPS_IMAGE_RGB
:
231 case CUPS_IMAGE_RGB_CMYK
:
232 cupsImageWhiteToRGB(inptr
, out
, img
->xsize
);
234 case CUPS_IMAGE_BLACK
:
235 cupsImageWhiteToBlack(inptr
, out
, img
->xsize
);
237 case CUPS_IMAGE_CMY
:
238 cupsImageWhiteToCMY(inptr
, out
, img
->xsize
);
240 case CUPS_IMAGE_CMYK
:
241 cupsImageWhiteToCMYK(inptr
, out
, img
->xsize
);
247 cupsImageLut(out
, img
->xsize
* bpp
, lut
);
249 _cupsImagePutRow(img
, 0, y
, img
->xsize
, out
);
254 if (color_type
& PNG_COLOR_MASK_COLOR
)
255 inptr
+= img
->xsize
* 3;
261 png_read_end(pp
, info
);
262 png_destroy_read_struct(&pp
, &info
, NULL
);
270 #endif /* HAVE_LIBPNG && HAVE_LIBZ */
274 * End of "$Id: image-png.c 6649 2007-07-11 21:46:42Z mike $".