diff -u -r metapixel-1.0.2/rwimg/rwgif.c metapixel-1.0.2-rwimg/rwimg/rwgif.c --- metapixel-1.0.2/rwimg/rwgif.c 2006-12-10 17:59:54.000000000 +0000 +++ metapixel-1.0.2-rwimg/rwimg/rwgif.c 2015-08-27 16:46:56.402621517 +0100 @@ -54,7 +54,7 @@ assert(data != 0); - data->file = DGifOpenFileName(filename); + data->file = DGifOpenFileName(filename, NULL); assert(data->file !=0); @@ -137,7 +137,7 @@ } free(buffer); - assert(DGifCloseFile(data->file) == GIF_OK); + assert(DGifCloseFile(data->file, NULL) == GIF_OK); return data; } diff -u -r metapixel-1.0.2/rwimg/rwpng.c metapixel-1.0.2-rwimg/rwimg/rwpng.c --- metapixel-1.0.2/rwimg/rwpng.c 2006-12-10 17:59:54.000000000 +0000 +++ metapixel-1.0.2-rwimg/rwimg/rwpng.c 2015-08-27 16:44:12.337891932 +0100 @@ -35,6 +35,7 @@ png_structp png_ptr; png_infop info_ptr, end_info; int row_stride; + int pixel_stride; int have_read; } png_data_t; @@ -42,10 +43,11 @@ open_png_file_reading (const char *filename, int *width, int *height) { png_data_t *data = (png_data_t*)malloc(sizeof(png_data_t)); + int bit_depth, color_type; assert(data != 0); - data->file = fopen(filename, "r"); + data->file = fopen(filename, "rb"); assert(data->file != 0); data->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); @@ -57,19 +59,41 @@ data->end_info = png_create_info_struct(data->png_ptr); assert(data->end_info != 0); - if (setjmp(data->png_ptr->jmpbuf)) + if (setjmp (png_jmpbuf (data->png_ptr))) assert(0); png_init_io(data->png_ptr, data->file); png_read_info(data->png_ptr, data->info_ptr); - *width = data->info_ptr->width; - *height = data->info_ptr->height; + *width = png_get_image_width (data->png_ptr, data->info_ptr); + *height = png_get_image_height (data->png_ptr, data->info_ptr); - assert(data->info_ptr->bit_depth == 8 || data->info_ptr->bit_depth == 16); - assert(data->info_ptr->color_type == PNG_COLOR_TYPE_RGB || data->info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA); - assert(data->info_ptr->interlace_type == PNG_INTERLACE_NONE); + bit_depth = png_get_bit_depth (data->png_ptr, data->info_ptr); + if (bit_depth != 8 && bit_depth != 16) + { + fprintf(stderr, "PNG files are only supported with bit depths 8 and 16.\n"); + /* FIXME: free stuff */ + return 0; + } + + color_type = png_get_color_type (data->png_ptr, data->info_ptr); + if (color_type != PNG_COLOR_TYPE_RGB + && color_type != PNG_COLOR_TYPE_RGB_ALPHA + && color_type != PNG_COLOR_TYPE_GRAY + && color_type != PNG_COLOR_TYPE_GRAY_ALPHA) + { + fprintf(stderr, "PNG files are only supported in RGB and Gray, with or without alpha.\n"); + /* FIXME: free stuff */ + return 0; + } + + if (png_get_interlace_type (data->png_ptr, data->info_ptr) != PNG_INTERLACE_NONE) + { + fprintf(stderr, "Interlaced PNG files are not supported.\n"); + /* FIXME: free stuff */ + return 0; + } data->have_read = 0; @@ -83,30 +107,44 @@ int i; int bps, spp; unsigned char *row; + int color_type, width; - if (setjmp(data->png_ptr->jmpbuf)) + if (setjmp (png_jmpbuf (data->png_ptr))) assert(0); - if (data->info_ptr->color_type == PNG_COLOR_TYPE_RGB) + color_type = png_get_color_type (data->png_ptr, data->info_ptr); + if (color_type == PNG_COLOR_TYPE_GRAY) + spp = 1; + else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + spp = 2; + else if (color_type == PNG_COLOR_TYPE_RGB) spp = 3; else spp = 4; - if (data->info_ptr->bit_depth == 16) + if (png_get_bit_depth (data->png_ptr, data->info_ptr) == 16) bps = 2; else bps = 1; - row = (unsigned char*)malloc(data->info_ptr->width * spp * bps); + width = png_get_image_width (data->png_ptr, data->info_ptr); + row = (unsigned char*)malloc (width * spp * bps); for (i = 0; i < num_lines; ++i) { int j, channel; png_read_row(data->png_ptr, (png_bytep)row, 0); - for (j = 0; j < data->info_ptr->width; ++j) - for (channel = 0; channel < 3; ++channel) - lines[i * data->info_ptr->width * 3 + j * 3 + channel] = row[j * spp * bps + channel * bps]; + + if (spp <= 2) + for (j = 0; j < width; ++j) + for (channel = 0; channel < 3; ++channel) + lines[i * width * 3 + j * 3 + channel] = row[j * spp * bps]; + else + for (j = 0; j < width; ++j) + for (channel = 0; channel < 3; ++channel) + lines[i * width * 3 + j * 3 + channel] + = row[j * spp * bps + channel * bps]; } free(row); @@ -119,7 +157,7 @@ { png_data_t *data = (png_data_t*)_data; - if (setjmp(data->png_ptr->jmpbuf)) + if (setjmp (png_jmpbuf (data->png_ptr))) assert(0); if (data->have_read) @@ -137,9 +175,9 @@ assert(data != 0); - assert(pixel_stride == 3 || pixel_stride == 4); + assert(pixel_stride >= 3); - data->file = fopen(filename, "w"); + data->file = fopen(filename, "wb"); assert(data->file != 0); data->png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); @@ -148,7 +186,7 @@ data->info_ptr = png_create_info_struct(data->png_ptr); assert(data->info_ptr != 0); - if (setjmp(data->png_ptr->jmpbuf)) + if (setjmp (png_jmpbuf (data->png_ptr))) assert(0); if (pixel_stride == 4) @@ -156,21 +194,13 @@ png_init_io(data->png_ptr, data->file); - data->info_ptr->width = width; - data->info_ptr->height = height; - data->info_ptr->valid = 0; - data->info_ptr->rowbytes = width * 3; - data->info_ptr->palette = 0; - data->info_ptr->num_palette = 0; - data->info_ptr->num_trans = 0; - data->info_ptr->bit_depth = 8; - data->info_ptr->color_type = PNG_COLOR_TYPE_RGB; - data->info_ptr->compression_type = PNG_COMPRESSION_TYPE_DEFAULT; - data->info_ptr->filter_type = PNG_FILTER_TYPE_DEFAULT; - data->info_ptr->interlace_type = PNG_INTERLACE_NONE; + png_set_IHDR (data->png_ptr, data->info_ptr, + width, height, 8, PNG_COLOR_TYPE_RGB, + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_write_info(data->png_ptr, data->info_ptr); + data->pixel_stride = pixel_stride; data->row_stride = row_stride; return data; @@ -180,13 +210,45 @@ png_write_lines (void *_data, unsigned char *lines, int num_lines) { png_data_t *data = (png_data_t*)_data; + unsigned char *packed_line; int i; + int width; - if (setjmp(data->png_ptr->jmpbuf)) + if (setjmp (png_jmpbuf (data->png_ptr))) assert(0); + width = png_get_image_width (data->png_ptr, data->info_ptr); + if (data->pixel_stride != 3) + { + packed_line = (unsigned char*)malloc(width * 3); + assert(packed_line != 0); + } + else + packed_line = 0; + for (i = 0; i < num_lines; ++i) - png_write_row(data->png_ptr, (png_bytep)(lines + i * data->row_stride)); + { + unsigned char *p = lines + i * data->row_stride; + + if (packed_line != 0) + { + int j; + + for (j = 0; j < width; ++j) + { + packed_line[j * 3 + 0] = p[j * data->pixel_stride + 0]; + packed_line[j * 3 + 1] = p[j * data->pixel_stride + 1]; + packed_line[j * 3 + 2] = p[j * data->pixel_stride + 2]; + } + + p = packed_line; + } + + png_write_row(data->png_ptr, (png_bytep)p); + } + + if (packed_line != 0) + free(packed_line); } void @@ -194,7 +256,7 @@ { png_data_t *data = (png_data_t*)_data; - if (setjmp(data->png_ptr->jmpbuf)) + if (setjmp (png_jmpbuf (data->png_ptr))) assert(0); png_write_end(data->png_ptr, data->info_ptr);