2 * "$Id: image-png.c 177 2006-06-21 00:20:03Z jlovell $"
4 * PNG image routines for the Common UNIX Printing System (CUPS).
6 * Copyright 1993-2006 by Easy Software Products.
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636 USA
20 * Voice: (301) 373-9600
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
24 * This file is subject to the Apple OS-Developed Software exception.
28 * _cupsImageReadPNG() - Read a PNG image file.
32 * Include necessary headers...
35 #include "image-private.h"
37 #if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ)
38 # include <png.h> /* Portable Network Graphics (PNG) definitions */
42 * '_cupsImageReadPNG()' - Read a PNG image file.
45 int /* O - Read status */
47 cups_image_t
*img
, /* IO - cupsImage */
48 FILE *fp
, /* I - cupsImage file */
49 cups_icspace_t primary
, /* I - Primary choice for colorspace */
50 cups_icspace_t secondary
, /* I - Secondary choice for colorspace */
51 int saturation
, /* I - Color saturation (%) */
52 int hue
, /* I - Color hue (degrees) */
53 const cups_ib_t
*lut
) /* I - Lookup table for gamma/brightness */
55 int y
; /* Looping var */
56 png_structp pp
; /* PNG read pointer */
57 png_infop info
; /* PNG info pointers */
58 png_uint_32 width
, /* Width of image */
59 height
; /* Height of image */
60 int bit_depth
, /* Bit depth */
61 color_type
, /* Color type */
62 interlace_type
, /* Interlace type */
63 compression_type
, /* Compression type */
64 filter_type
; /* Filter type */
65 png_uint_32 xppm
, /* X pixels per meter */
66 yppm
; /* Y pixels per meter */
67 int bpp
; /* Bytes per pixel */
68 int pass
, /* Current pass */
69 passes
; /* Number of passes required */
70 cups_ib_t
*in
, /* Input pixels */
71 *inptr
, /* Pointer into pixels */
72 *out
; /* Output pixels */
73 png_color_16 bg
; /* Background color */
77 * Setup the PNG data structures...
80 pp
= png_create_read_struct(PNG_LIBPNG_VER_STRING
, NULL
, NULL
, NULL
);
81 info
= png_create_info_struct(pp
);
84 * Initialize the PNG read "engine"...
90 * Get the image dimensions and load the output image...
93 png_read_info(pp
, info
);
95 png_get_IHDR(pp
, info
, &width
, &height
, &bit_depth
, &color_type
,
96 &interlace_type
, &compression_type
, &filter_type
);
98 fprintf(stderr
, "DEBUG: PNG image: %dx%dx%d, color_type=%x (%s%s%s)\n",
99 (int)width
, (int)height
, bit_depth
, color_type
,
100 (color_type
& PNG_COLOR_MASK_COLOR
) ? "RGB" : "GRAYSCALE",
101 (color_type
& PNG_COLOR_MASK_ALPHA
) ? "+ALPHA" : "",
102 (color_type
& PNG_COLOR_MASK_PALETTE
) ? "+PALETTE" : "");
104 if (color_type
& PNG_COLOR_MASK_PALETTE
)
106 else if (bit_depth
< 8)
111 else if (bit_depth
== 16)
112 png_set_strip_16(pp
);
114 if (color_type
& PNG_COLOR_MASK_COLOR
)
115 img
->colorspace
= (primary
== CUPS_IMAGE_RGB_CMYK
) ? CUPS_IMAGE_RGB
:
118 img
->colorspace
= secondary
;
120 if (width
== 0 || width
> CUPS_IMAGE_MAX_WIDTH
||
121 height
== 0 || height
> CUPS_IMAGE_MAX_HEIGHT
)
123 fprintf(stderr
, "ERROR: PNG image has invalid dimensions %ux%u!\n",
124 (unsigned)width
, (unsigned)height
);
132 if ((xppm
= png_get_x_pixels_per_meter(pp
, info
)) != 0 &&
133 (yppm
= png_get_y_pixels_per_meter(pp
, info
)) != 0)
135 img
->xppi
= (int)((float)xppm
* 0.0254);
136 img
->yppi
= (int)((float)yppm
* 0.0254);
138 if (img
->xppi
== 0 || img
->yppi
== 0)
140 fprintf(stderr
, "ERROR: PNG image has invalid resolution %dx%d PPI\n",
141 img
->xppi
, img
->yppi
);
143 img
->xppi
= img
->yppi
= 128;
147 cupsImageSetMaxTiles(img
, 0);
149 passes
= png_set_interlace_handling(pp
);
152 * Handle transparency...
155 if (png_get_valid(pp
, info
, PNG_INFO_tRNS
))
156 png_set_tRNS_to_alpha(pp
);
162 png_set_background(pp
, &bg
, PNG_BACKGROUND_GAMMA_SCREEN
, 0, 1.0);
167 * Load one row at a time...
170 if (color_type
== PNG_COLOR_TYPE_GRAY
||
171 color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
172 in
= malloc(img
->xsize
);
174 in
= malloc(img
->xsize
* 3);
179 * Interlaced images must be loaded all at once...
182 if (color_type
== PNG_COLOR_TYPE_GRAY
||
183 color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
)
184 in
= malloc(img
->xsize
* img
->ysize
);
186 in
= malloc(img
->xsize
* img
->ysize
* 3);
189 bpp
= cupsImageGetDepth(img
);
190 out
= malloc(img
->xsize
* bpp
);
193 * Read the image, interlacing as needed...
196 for (pass
= 1; pass
<= passes
; pass
++)
197 for (inptr
= in
, y
= 0; y
< img
->ysize
; y
++)
199 png_read_row(pp
, (png_bytep
)inptr
, NULL
);
207 if (color_type
& PNG_COLOR_MASK_COLOR
)
209 if ((saturation
!= 100 || hue
!= 0) && bpp
> 1)
210 cupsImageRGBAdjust(inptr
, img
->xsize
, saturation
, hue
);
212 switch (img
->colorspace
)
214 case CUPS_IMAGE_WHITE
:
215 cupsImageRGBToWhite(inptr
, out
, img
->xsize
);
217 case CUPS_IMAGE_RGB
:
218 case CUPS_IMAGE_RGB_CMYK
:
219 cupsImageRGBToRGB(inptr
, out
, img
->xsize
);
221 case CUPS_IMAGE_BLACK
:
222 cupsImageRGBToBlack(inptr
, out
, img
->xsize
);
224 case CUPS_IMAGE_CMY
:
225 cupsImageRGBToCMY(inptr
, out
, img
->xsize
);
227 case CUPS_IMAGE_CMYK
:
228 cupsImageRGBToCMYK(inptr
, out
, img
->xsize
);
234 switch (img
->colorspace
)
236 case CUPS_IMAGE_WHITE
:
237 memcpy(out
, inptr
, img
->xsize
);
239 case CUPS_IMAGE_RGB
:
240 case CUPS_IMAGE_RGB_CMYK
:
241 cupsImageWhiteToRGB(inptr
, out
, img
->xsize
);
243 case CUPS_IMAGE_BLACK
:
244 cupsImageWhiteToBlack(inptr
, out
, img
->xsize
);
246 case CUPS_IMAGE_CMY
:
247 cupsImageWhiteToCMY(inptr
, out
, img
->xsize
);
249 case CUPS_IMAGE_CMYK
:
250 cupsImageWhiteToCMYK(inptr
, out
, img
->xsize
);
256 cupsImageLut(out
, img
->xsize
* bpp
, lut
);
258 _cupsImagePutRow(img
, 0, y
, img
->xsize
, out
);
263 if (color_type
& PNG_COLOR_MASK_COLOR
)
264 inptr
+= img
->xsize
* 3;
270 png_read_end(pp
, info
);
271 png_destroy_read_struct(&pp
, &info
, NULL
);
279 #endif /* HAVE_LIBPNG && HAVE_LIBZ */
283 * End of "$Id: image-png.c 177 2006-06-21 00:20:03Z jlovell $".