22#ifdef HAVE_LIBPNG_PNG_H
23#include <libpng/png.h>
38static char *prog_state_name[] =
40 "IS_finished",
"IS_init",
"IS_nextdata"
78 png_uint_32 previous_row;
101#define DATASIZE (png->ipbufsize - png->ipbufstart)
109 png = png_get_error_ptr(png_ptr);
110 MSG(
"Png_error_handling: %s: %s\n",
URL_STR(png->url), msg);
115 longjmp(png->jmpbuf, 1);
123 png = png_get_error_ptr(png_ptr);
135 double file_gamma = 1 / 2.2;
137 _MSG(
"Png_datainfo_callback:\n");
139 png = png_get_progressive_ptr(png_ptr);
142 png_get_IHDR(png_ptr, info_ptr, &png->width, &png->height,
143 &bit_depth, &color_type, &interlace_type, NULL, NULL);
146 if (png->width == 0 || png->height == 0 ||
148 MSG(
"Png_datainfo_callback: suspicious image size request %lu x %lu\n",
154 _MSG(
"Png_datainfo_callback: png->width = %lu\n"
155 "Png_datainfo_callback: png->height = %lu\n",
159 if (color_type == PNG_COLOR_TYPE_PALETTE && bit_depth <= 8) {
161 png_set_expand (png_ptr);
162 }
else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
164 png_set_expand (png_ptr);
165 }
else if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) {
167 png_set_expand(png_ptr);
168 }
else if (bit_depth < 8) {
169 png_set_expand(png_ptr);
172 if (bit_depth == 16) {
173 png_set_strip_16(png_ptr);
179 if (png_get_gAMA(png_ptr, info_ptr, &file_gamma))
180 png_set_gamma(png_ptr, 2.2, file_gamma);
183 if (color_type == PNG_COLOR_TYPE_GRAY ||
184 color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
185 png_set_gray_to_rgb(png_ptr);
189 if (interlace_type != PNG_INTERLACE_NONE) {
190 png_set_interlace_handling(png_ptr);
194 png_read_update_info(png_ptr, info_ptr);
196 png_get_IHDR(png_ptr, info_ptr, &png->width, &png->height,
197 &bit_depth, &color_type, &interlace_type, NULL, NULL);
199 png->rowbytes = png_get_rowbytes(png_ptr, info_ptr);
200 png->channels = png_get_channels(png_ptr, info_ptr);
203 _MSG(
"Png_datainfo_callback: rowbytes = %d\n"
204 "Png_datainfo_callback: width = %lu\n"
205 "Png_datainfo_callback: height = %lu\n",
208 png->image_data = (
uchar_t *)
dMalloc(png->rowbytes * png->height);
211 for (i = 0; i < png->height; i++)
212 png->row_pointers[i] = png->image_data + (i * png->rowbytes);
214 png->linebuf =
dMalloc(3 * png->width);
225 png_uint_32 row_num,
int pass)
233 _MSG(
"Png_datarow_callback: row_num = %ld\n", row_num);
235 png = png_get_progressive_ptr(png_ptr);
237 png_progressive_combine_row(png_ptr, png->row_pointers[row_num], new_row);
239 _MSG(
"png: row_num=%u previous_row=%u\n", row_num, png->previous_row);
240 if (row_num < png->previous_row) {
243 png->previous_row = row_num;
245 switch (png->channels) {
248 png->image_data + (row_num * png->rowbytes),
255 int a, bg_red, bg_green, bg_blue;
257 uchar_t *data = png->image_data + (row_num * png->rowbytes);
261 bg_blue = (png->bgcolor) & 0xFF;
262 bg_green = (png->bgcolor>>8) & 0xFF;
263 bg_red = (png->bgcolor>>16) & 0xFF;
265 for (i = 0; i < png->width; i++) {
279 png_composite(*(pl++), *(data++), a, bg_red);
280 png_composite(*(pl++), *(data++), a, bg_green);
281 png_composite(*(pl++), *(data++), a, bg_blue);
289 MSG(
"Png_datarow_callback: unexpected number of channels=%d pass=%d\n",
290 png->channels, pass);
299 _MSG(
"Png_dataend_callback:\n");
301 MSG(
"Png_dataend_callback: info_ptr = NULL\n");
303 png = png_get_progressive_ptr(png_ptr);
312 _MSG(
"Png_free: png=%p\n", png);
314 dFree(png->image_data);
315 dFree(png->row_pointers);
317 if (setjmp(png->jmpbuf))
318 MSG_WARN(
"PNG: can't destroy read structure\n");
319 else if (png->png_ptr)
320 png_destroy_read_struct(&png->png_ptr, &png->info_ptr, NULL);
345 png->ipbufsize = BufSize;
349 _MSG(
"State = %s\n", prog_state_name[png->state]);
351 switch (png->state) {
357 if (png_sig_cmp(png->ipbuf, 0,
DATASIZE)) {
363 png->png_ptr = png_create_read_struct(
364 PNG_LIBPNG_VER_STRING,
369 png->info_ptr = png_create_info_struct(png->png_ptr);
374 png_set_progressive_read_fn(
385 if (setjmp(png->jmpbuf)) {
387 }
else if (!png->error) {
388 png_process_data( png->png_ptr,
390 png->ipbuf + png->ipbufstart,
398 MSG_WARN(
"PNG decoder: bad state = %d\n", png->state);
442 return png_get_libpng_ver(NULL);
450 DilloPng *png =
dNew0(DilloPng, 1);
451 _MSG(
"a_Png_new: png=%p\n", png);
455 png->version = version;
463 png->image_data = NULL;
464 png->row_pointers = NULL;
465 png->previous_row = 0;
void a_Dicache_set_parms(DilloUrl *url, int version, DilloImage *Image, uint_t width, uint_t height, DilloImgType type, double gamma)
Set image's width, height & type.
void a_Dicache_new_scan(const DilloUrl *url, int version)
Reset for a new scan from a multiple-scan image.
void a_Dicache_close(DilloUrl *url, int version, CacheClient_t *Client)
Implement the close method of the decoding process.
void a_Dicache_write(DilloUrl *url, int version, const uchar_t *buf, uint_t Y)
Implement the write method (Write a scan line into the Dicache entry) buf: row buffer Y : row number.
void * dMalloc(size_t size)
#define dReturn_if_fail(expr)
#define dNew0(type, count)
static void error(char *msg)
static void Png_datainfo_callback(png_structp png_ptr, png_infop info_ptr)
static void Png_datarow_callback(png_structp png_ptr, png_bytep new_row, png_uint_32 row_num, int pass)
const char * a_Png_version(void)
static void Png_write(DilloPng *png, void *Buf, uint_t BufSize)
Receive and process new chunks of PNG image data.
void * a_Png_new(DilloImage *Image, DilloUrl *url, int version)
Create the image state data that must be kept between calls.
static void Png_close(DilloPng *png, CacheClient_t *Client)
Finish the decoding process (and free the memory)
static void Png_dataend_callback(png_structp png_ptr, png_infop info_ptr)
static void Png_warning_handler(png_structp png_ptr, png_const_charp msg)
static void Png_error_handling(png_structp png_ptr, png_const_charp msg)
void a_Png_callback(int Op, void *data)
PNG callback.
static void Png_free(DilloPng *png)
Free up the resources for this image.
The DilloImage data-structure and methods.
Data structure for cache clients.
void * CbData
Client function data.
uint_t BufSize
Valid size of cache-data.
void * Buf
Pointer to cache-data.
int32_t bg_color
Background color.