44 #if PNG_LIBPNG_VER < 10400
46 #define png_set_expand_gray_1_2_4_to_8 png_set_gray_1_2_4_to_8
58 #define FILE_BUFFER_CAPACITY (1024*4)
60 #define ROUNDCLAMPF(x) ((x < 0.0f) ? 0 : \
61 ((x > 1.0f) ? 255 : (uint8_t)(255.0f*(x) + 0.5f)))
62 #define ROUNDCLAMP(x) ((x < 0.0) ? 0 : \
63 ((x > 1.0) ? 255 : (uint8_t)(255.0*(x) + 0.5)))
69 unsigned string_length = strlen(
string), suffix_length = strlen(suffix);
72 if(string_length < suffix_length)
75 string += string_length - suffix_length;
77 for(i = 0; i < suffix_length; i++)
78 if(tolower(
string[i]) != tolower(suffix[i]))
86 static void fill_image(uint32_t *image,
int width,
int height, uint32_t color)
91 for(y = 0; y < height; y++, image += width)
92 for(x = 0; x < width; x++)
112 int *use_alpha,
const uint32_t *image,
int width,
int height)
114 const int max_colors = 256;
115 uint32_t *palette = NULL;
117 int x, y, i, red, green, blue, alpha;
120 if(!use_color || !num_colors || !use_alpha)
123 || !(palette = (uint32_t *)
Malloc(
sizeof(uint32_t)*max_colors)))
126 *use_color = *use_alpha = 1;
130 *num_colors = *use_color = *use_alpha = 0;
132 for(y = 0; y < height; y++)
134 for(x = 0; x < width; x++)
137 red = ((uint8_t *)&pixel)[0];
138 green = ((uint8_t *)&pixel)[1];
139 blue = ((uint8_t *)&pixel)[2];
140 alpha = ((uint8_t *)&pixel)[3];
142 if(red != green || red != blue)
149 for(i = 0; i < *num_colors; i++)
150 if(pixel == palette[i])
178 w = (uint16_t) getc(file);
179 w |= ((uint16_t) getc(file) << 8);
188 dw = (uint32_t) getc(file);
189 dw |= ((uint32_t) getc(file) << 8);
190 dw |= ((uint32_t) getc(file) << 16);
191 dw |= ((uint32_t) getc(file) << 24);
199 putc(w & 0xFF, file);
200 putc((w & 0xFF00) >> 8, file);
207 putc(dw & 0xFF, file);
208 putc((dw & 0xFF00) >> 8, file);
209 putc((dw & 0xFF0000) >> 16, file);
210 putc((dw & 0xFF000000) >> 24, file);
216 FILE *file,
const uint32_t *palette)
218 int row_padding = (-(width+7)/8)&3;
222 image += ((
long int)width)*((
long int)height - 1);
224 for(y = height; y; y--, image -= width)
229 for(x = 0; x < width;)
233 for(bit = 7; bit >= 0 && x < width; bit--, code <<= 1)
234 image[x++] = palette[(code & 0x80) ? 1:0];
237 for(x = row_padding; x; x--)
247 FILE *file,
const uint32_t *palette)
249 int row_padding = (-(width+1)/2)&3;
253 image += ((
long int)width)*((
long int)height - 1);
255 for(y = height; y; y--, image -= width)
260 for(x = 0; x < width;)
263 image[x++] = palette[(code & 0xF0) >> 4];
266 image[x++] = palette[code & 0x0F];
269 for(x = row_padding; x; x--)
279 FILE *file,
const uint32_t *palette)
282 unsigned count, value;
283 uint32_t color_high, color_low;
286 image += ((
long int)width)*((
long int)height - 1);
288 for(x = 0, y = height; y;)
313 if(x >= width || y < 0)
326 image[x++] = palette[(value & 0xF0) >> 4];
333 image[x++] = palette[value & 0x0F];
341 if(((count + 1)/2) & 1)
347 color_high = palette[(value & 0xF0) >> 4];
348 color_low = palette[value & 0xF];
355 image[x++] = color_high;
363 image[x++] = color_low;
379 FILE *file,
const uint32_t *palette)
381 int row_padding = (-width)&3;
384 image += ((
long int)width)*((
long int)height - 1);
386 for(y = height; y; y--, image -= width)
391 for(x = 0; x < width; x++)
392 image[x] = palette[getc(file) & 0xFF];
394 for(x = row_padding; x; x--)
404 FILE *file,
const uint32_t *palette)
407 unsigned count, value;
411 image += ((
long int)width)*((
long int)height - 1);
413 for(x = 0, y = height; y;)
438 if(x >= width || y < 0)
450 image[x++] = palette[getc(file) & 0xFF];
459 color = palette[value & 0xFF];
478 uint8_t *image_ptr = (uint8_t *)image;
479 int row_padding = (-3*width)&3;
483 image_ptr += ((
long int)width)*((
long int)height - 1);
485 for(y = height; y; y--, image_ptr -= width)
490 for(x = 0; x < width; x += 4)
492 image_ptr[x+3] = 255;
493 image_ptr[x+2] = getc(file);
494 image_ptr[x+1] = getc(file);
495 image_ptr[x+0] = getc(file);
498 for(x = row_padding; x; x--)
508 int shift = 0, bitcount = 0;
531 shift += bitcount - 8;
536 *right_shift = shift;
540 *left_shift = -shift;
547 uint32_t redmask, uint32_t greenmask,
548 uint32_t bluemask, uint32_t alphamask)
550 uint8_t *image_ptr = (uint8_t *)image;
552 int row_padding = (-2*width)&3;
553 int redleft_shift, greenleft_shift, blueleft_shift, alphaleft_shift;
554 int redright_shift, greenright_shift, blueright_shift, alpharight_shift;
562 image_ptr += ((
long int)width)*((
long int)height - 1);
564 for(y = height; y; y--, image_ptr -= width)
569 for(x = 0; x < width; x += 4)
575 image_ptr[x + 3] = ((code & alphamask) >> alpharight_shift)
577 image_ptr[x + 2] = ((code & bluemask ) >> blueright_shift )
579 image_ptr[x + 1] = ((code & greenmask) >> greenright_shift)
581 image_ptr[x + 0] = ((code & redmask ) >> redright_shift )
585 for(x = row_padding; x; x--)
595 uint32_t redmask, uint32_t greenmask,
596 uint32_t bluemask, uint32_t alphamask)
600 int redleft_shift, greenleft_shift, blueleft_shift, alphaleft_shift;
601 int redright_shift, greenright_shift, blueright_shift, alpharight_shift;
609 image_ptr = (uint8_t *)image + ((
long int)width)*((
long int)height - 1);
611 for(y = height; y; y--, image_ptr -= width)
616 for(x = 0; x < width; x += 4)
619 image_ptr[x + 3] = ((code & alphamask) >> alpharight_shift)
621 image_ptr[x + 2] = ((code & bluemask ) >> blueright_shift )
623 image_ptr[x + 1] = ((code & greenmask) >> greenright_shift)
625 image_ptr[x + 0] = ((code & redmask ) >> redright_shift )
646 static int read_bmp(uint32_t **image,
int *width,
int *height, FILE *file)
648 uint32_t *palette = NULL;
649 uint8_t *palette_ptr;
650 long int image_data_offset, info_size;
651 unsigned i, num_planes, bits_per_pixel, compression, num_colors;
652 uint32_t redmask, greenmask, bluemask, alphamask;
653 int success = 0, os2bmp;
657 *width = *height = 0;
658 fseek(file, 0, SEEK_SET);
660 magic[0] = getc(file);
661 magic[1] = getc(file);
663 if(!(magic[0] == 0x42 && magic[1] == 0x4D)
664 || fseek(file, 8, SEEK_CUR))
680 if((os2bmp = (info_size == 12)))
688 redmask = 0x00FF0000;
689 greenmask = 0x0000FF00;
690 bluemask = 0x000000FF;
691 alphamask = 0xFF000000;
700 fseek(file, 12, SEEK_CUR);
702 fseek(file, 4, SEEK_CUR);
712 ErrorMessage(
"image dimensions exceed MAX_IMAGE_SIZE.\n");
716 if(feof(file) || num_planes != 1 || compression > 3)
720 if(!(*image = (uint32_t *)
Malloc(
721 sizeof(uint32_t)*((
long int)*width)*((
long int)*height))))
725 if(bits_per_pixel <= 8)
727 fseek(file, 14 + info_size, SEEK_SET);
730 num_colors = 1 << bits_per_pixel;
732 if(!(palette = (uint32_t *)
Malloc(
sizeof(uint32_t)*256)))
735 for(i = 0, palette_ptr = (uint8_t *)palette; i < num_colors; i++)
737 palette_ptr[3] = 255;
738 palette_ptr[2] = getc(file);
739 palette_ptr[1] = getc(file);
740 palette_ptr[0] = getc(file);
749 palette[i] = palette[0];
752 if(fseek(file, image_data_offset, SEEK_SET) || feof(file))
762 switch(bits_per_pixel)
766 *image, *width, *height, file, palette);
770 *image, *width, *height, file, palette);
774 *image, *width, *height, file, palette);
781 0x001F << 10, 0x001F << 5, 0x0001F, 0);
785 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
790 if(bits_per_pixel == 8)
792 *image, *width, *height, file, palette);
795 if(bits_per_pixel == 4)
797 *image, *width, *height, file, palette);
800 switch(bits_per_pixel)
804 redmask, greenmask, bluemask, alphamask);
808 redmask, greenmask, bluemask, alphamask);
821 if(!success && *image)
849 static int write_bmp(
const uint32_t *image,
int width,
int height, FILE *file)
851 const uint8_t *image_ptr = (uint8_t *)image;
852 uint32_t *palette = NULL;
855 int use_palette, num_colors, use_color, use_alpha;
856 int x, y, i, row_padding, success = 0;
863 image, width, height);
866 if(palette && 2*num_colors < width*height)
869 use_palette = num_colors = 0;
876 row_padding = (-width)&3;
877 imageSize = (width + row_padding)*((
long int)height);
881 row_padding = (-3*width)&3;
882 imageSize = (3*width + row_padding)*((
long int)height);
909 write_u32_le((!use_palette || num_colors == 256) ? 0:num_colors, file);
921 for(i = 0; i < num_colors; i++)
924 putc(((uint8_t *)&pixel)[2], file);
925 putc(((uint8_t *)&pixel)[1], file);
926 putc(((uint8_t *)&pixel)[0], file);
933 image_ptr += ((
long int)width)*((
long int)height - 1);
935 for(y = height; y; y--, image_ptr -= width)
939 for(x = 0; x < width; x += 4)
941 pixel = *((uint32_t *)(image_ptr + x));
943 for(i = 0; i < num_colors; i++)
944 if(pixel == palette[i])
952 for(x = 0; x < width; x += 4)
954 putc(image_ptr[x+2], file);
955 putc(image_ptr[x+1], file);
956 putc(image_ptr[x+0], file);
960 for(x = row_padding; x; x--)
986 struct jpeg_error_mgr pub;
992 METHODDEF(
void) jerr_exit(j_common_ptr cinfo)
994 hooked_jerr *jerr = (hooked_jerr *) cinfo->err;
995 (*cinfo->err->output_message)(cinfo);
996 longjmp(jerr->jmpbuf, 1);
1014 static int read_jpeg(uint32_t **image,
int *width,
int *height, FILE *file)
1016 struct jpeg_decompress_struct cinfo;
1020 unsigned i, row_size;
1023 *width = *height = 0;
1024 cinfo.err = jpeg_std_error(&jerr.pub);
1025 jerr.pub.error_exit = jerr_exit;
1027 if(setjmp(jerr.jmpbuf))
1030 jpeg_create_decompress(&cinfo);
1031 jpeg_stdio_src(&cinfo, file);
1032 jpeg_read_header(&cinfo, 1);
1033 cinfo.out_color_space = JCS_RGB;
1034 jpeg_start_decompress(&cinfo);
1035 *width = (int)cinfo.output_width;
1036 *height = (
int)cinfo.output_height;
1040 ErrorMessage(
"image dimensions exceed MAX_IMAGE_SIZE.\n");
1041 jpeg_abort_decompress(&cinfo);
1046 if(!(*image = (uint32_t *)
Malloc(
sizeof(uint32_t)
1047 *((
size_t)*width)*((
size_t)*height))))
1049 jpeg_abort_decompress(&cinfo);
1054 row_size = cinfo.output_width * cinfo.output_components;
1055 buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo,
1056 JPOOL_IMAGE, row_size, 1);
1057 image_ptr = (uint8_t *)*image;
1059 while(cinfo.output_scanline < cinfo.output_height)
1060 for(jpeg_read_scanlines(&cinfo, buffer, 1), i = 0;
1061 i < row_size; i += 3)
1063 *(image_ptr++) = buffer[0][i];
1064 *(image_ptr++) = buffer[0][i+1];
1065 *(image_ptr++) = buffer[0][i+2];
1066 *(image_ptr++) = 0xFF;
1069 jpeg_finish_decompress(&cinfo);
1070 jpeg_destroy_decompress(&cinfo);
1077 *width = *height = 0;
1078 jpeg_destroy_decompress(&cinfo);
1101 static int write_jpeg(
const uint32_t *image,
int width,
int height,
1102 FILE *file,
int quality)
1104 struct jpeg_compress_struct cinfo;
1106 uint8_t *buffer = 0, *image_ptr;
1107 unsigned i, row_size;
1112 cinfo.err = jpeg_std_error(&jerr.pub);
1113 jerr.pub.error_exit = jerr_exit;
1115 if(setjmp(jerr.jmpbuf))
1118 jpeg_create_compress(&cinfo);
1119 jpeg_stdio_dest(&cinfo, file);
1120 cinfo.image_width = width;
1121 cinfo.image_height = height;
1122 cinfo.input_components = 3;
1123 cinfo.in_color_space = JCS_RGB;
1124 jpeg_set_defaults(&cinfo);
1125 jpeg_set_quality(&cinfo, (quality < 100) ? quality : 100, 1);
1126 jpeg_start_compress(&cinfo, 1);
1129 image_ptr = (uint8_t *)image;
1131 if(!(buffer = (uint8_t *)
Malloc(row_size)))
1134 while(cinfo.next_scanline < cinfo.image_height)
1136 for(i = 0; i < row_size; i += 3)
1138 buffer[i] = image_ptr[0];
1139 buffer[i+1] = image_ptr[1];
1140 buffer[i+2] = image_ptr[2];
1144 jpeg_write_scanlines(&cinfo, &buffer, 1);
1150 jpeg_finish_compress(&cinfo);
1151 jpeg_destroy_compress(&cinfo);
1157 jpeg_destroy_compress(&cinfo);
1177 static int read_png(uint32_t **image,
int *width,
int *height, FILE *file)
1179 png_bytep *row_pointers;
1183 png_uint_32 png_width, png_height;
1184 int bit_depth, color_type, interlace_type;
1188 *width = *height = 0;
1191 if(fread(header, 1, 8, file) != 8 || png_sig_cmp(header, 0, 8))
1195 if(!(png = png_create_read_struct(
1196 PNG_LIBPNG_VER_STRING, NULL, NULL, NULL))
1197 || !(info = png_create_info_struct(png)))
1200 png_destroy_read_struct(&png, (png_infopp)NULL, (png_infopp)NULL);
1205 if(setjmp(png_jmpbuf(png)))
1208 png_init_io(png, file);
1209 png_set_sig_bytes(png, 8);
1211 png_read_info(png, info);
1212 png_get_IHDR(png, info, &png_width, &png_height, &bit_depth, &color_type,
1213 &interlace_type, (
int*)NULL, (
int*)NULL);
1214 *width = (int)png_width;
1215 *height = (int)png_height;
1218 if(color_type == PNG_COLOR_TYPE_PALETTE)
1219 png_set_palette_to_rgb(png);
1220 if(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
1221 png_set_expand_gray_1_2_4_to_8(png);
1222 if(color_type == PNG_COLOR_TYPE_GRAY
1223 || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
1224 png_set_gray_to_rgb(png);
1225 if(png_get_valid(png, info, PNG_INFO_tRNS))
1226 png_set_tRNS_to_alpha(png);
1228 png_set_strip_16(png);
1229 png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
1231 png_set_interlace_handling(png);
1232 png_read_update_info(png, info);
1235 if(!(*image = (uint32_t *)
Malloc(
sizeof(uint32_t)
1236 *((
size_t)*width)*((
size_t)*height)))
1237 || !(row_pointers = (png_bytep *)
Malloc(
sizeof(png_bytep)
1241 for(row = 0; row < png_height; row++)
1242 row_pointers[row] = (png_bytep)(*image + png_width*row);
1245 png_read_image(png, row_pointers);
1247 png_destroy_read_struct(&png, &info, (png_infopp)NULL);
1254 *width = *height = 0;
1255 png_destroy_read_struct(&png, &info, (png_infopp)NULL);
1280 static int write_png(
const uint32_t *image,
int width,
int height, FILE *file)
1282 const uint32_t *image_ptr;
1283 uint32_t *palette = NULL;
1284 uint8_t *row_buffer;
1287 png_color png_palette[256];
1288 png_byte png_trans[256];
1290 int png_color_type, num_colors, use_color, use_alpha;
1291 int x, y, i, success = 0;
1297 if(!(row_buffer = (uint8_t *)
Malloc(4*width)))
1300 if(!(png = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1302 || !(info = png_create_info_struct(png)))
1305 png_destroy_write_struct(&png, (png_infopp)NULL);
1311 if(setjmp(png_jmpbuf(png)))
1317 png_init_io(png, file);
1318 png_set_compression_level(png, Z_BEST_COMPRESSION);
1321 image, width, height);
1324 if(palette && use_color)
1325 png_color_type = PNG_COLOR_TYPE_PALETTE;
1327 png_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
1329 png_color_type = PNG_COLOR_TYPE_RGB;
1331 png_color_type = PNG_COLOR_TYPE_GRAY;
1333 png_set_IHDR(png, info, width, height, 8, png_color_type,
1334 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
1336 if(png_color_type == PNG_COLOR_TYPE_PALETTE)
1338 for(i = 0; i < num_colors; i++)
1341 png_palette[i].red = ((uint8_t *)&pixel)[0];
1342 png_palette[i].green = ((uint8_t *)&pixel)[1];
1343 png_palette[i].blue = ((uint8_t *)&pixel)[2];
1344 png_trans[i] = ((uint8_t *)&pixel)[3];
1347 png_set_PLTE(png, info, png_palette, num_colors);
1350 png_set_tRNS(png, info, png_trans, num_colors, NULL);
1353 png_write_info(png, info);
1355 for(y = 0, image_ptr = image; y < height; y++, image_ptr += width)
1357 switch(png_color_type)
1359 case PNG_COLOR_TYPE_RGB_ALPHA:
1360 png_write_row(png, (png_bytep)image_ptr);
1362 case PNG_COLOR_TYPE_RGB:
1363 for(x = 0; x < width; x++)
1365 pixel = image_ptr[x];
1366 row_buffer[3*x + 0] = ((uint8_t *)&pixel)[0];
1367 row_buffer[3*x + 1] = ((uint8_t *)&pixel)[1];
1368 row_buffer[3*x + 2] = ((uint8_t *)&pixel)[2];
1371 png_write_row(png, (png_bytep)row_buffer);
1373 case PNG_COLOR_TYPE_GRAY:
1374 for(x = 0; x < width; x++)
1376 pixel = image_ptr[x];
1377 row_buffer[x] = ((uint8_t *)&pixel)[0];
1380 png_write_row(png, (png_bytep)row_buffer);
1382 case PNG_COLOR_TYPE_PALETTE:
1383 for(x = 0; x < width; x++)
1385 pixel = image_ptr[x];
1387 for(i = 0; i < num_colors; i++)
1388 if(pixel == palette[i])
1394 png_write_row(png, (png_bytep)row_buffer);
1399 png_write_end(png, info);
1404 png_destroy_write_struct(&png, &info);
1425 static int read_tiff(uint32_t **image,
int *width,
int *height,
1426 const char *filename,
unsigned directory)
1429 uint32 image_width, image_height;
1432 *width = *height = 0;
1434 if(!(tiff = TIFFOpen(filename,
"r")))
1440 TIFFSetDirectory(tiff, directory);
1441 TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &image_width);
1442 TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &image_height);
1443 *width = (int)image_width;
1444 *height = (int)image_height;
1448 ErrorMessage(
"Image dimensions exceed MAX_IMAGE_SIZE.\n");
1452 if(!(*image = (uint32_t *)
Malloc(
1453 sizeof(uint32_t)*image_width*image_height)))
1456 if(!TIFFReadRGBAImageOriented(tiff, image_width, image_height,
1457 (uint32 *)*image, ORIENTATION_TOPLEFT, 1))
1467 *width = *height = 0;
1486 static int write_tiff(
const uint32_t *image,
int width,
int height,
1487 const char *filename)
1490 uint16 alpha = EXTRASAMPLE_ASSOCALPHA;
1495 if(!(tiff = TIFFOpen(filename,
"w")))
1501 if(TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, width) != 1
1502 || TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, height) != 1
1503 || TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 4) != 1
1504 || TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB) != 1
1505 || TIFFSetField(tiff, TIFFTAG_EXTRASAMPLES, 1, &alpha) != 1
1506 || TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 8) != 1
1507 || TIFFSetField(tiff, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT) != 1
1508 || TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG) != 1
1511 || TIFFSetField(tiff, TIFFTAG_COMPRESSION, COMPRESSION_LZW) != 1)
1518 if(TIFFWriteEncodedStrip(tiff, 0, (tdata_t)image,
1519 4*((
size_t)width)*((
size_t)height)) < 0)
1536 const int num_pixels = width*height;
1537 const int num_channels = (format & IMAGEIO_GRAYSCALE) ?
1538 1 : ((format & IMAGEIO_STRIP_ALPHA) ? 3 : 4);
1539 const int channel_stride = (format & IMAGEIO_PLANAR) ? num_pixels : 1;
1540 const int channel_stride2 = 2*channel_stride;
1541 const int channel_stride3 = 3*channel_stride;
1546 int order[4] = {0, 1, 2, 3};
1547 int i, x, y, pixel_stride, row_stride;
1550 pixel_stride = (format & IMAGEIO_PLANAR) ? 1 : num_channels;
1552 if(format & IMAGEIO_COLUMNMAJOR)
1554 row_stride = pixel_stride;
1555 pixel_stride *= height;
1558 row_stride = width*pixel_stride;
1560 if(format & IMAGEIO_BGRFLIP)
1566 if((format & IMAGEIO_AFLIP) && !(format & IMAGEIO_STRIP_ALPHA))
1568 order[3] = order[2];
1569 order[2] = order[1];
1570 order[1] = order[0];
1574 switch(format & (IMAGEIO_U8 | IMAGEIO_SINGLE | IMAGEIO_DOUBLE))
1577 if(!(dest_u8 = (uint8_t *)
Malloc(
1578 sizeof(uint8_t)*num_channels*num_pixels)))
1581 switch(num_channels)
1584 for(y = 0; y < height; y++, src += width)
1585 for(x = 0, i = row_stride*y;
1586 x < width; x++, i += pixel_stride)
1589 dest_u8[i] = (uint8_t)(0.299f*((uint8_t *)&pixel)[0]
1590 + 0.587f*((uint8_t *)&pixel)[1]
1591 + 0.114f*((uint8_t *)&pixel)[2] + 0.5f);
1595 for(y = 0; y < height; y++, src += width)
1596 for(x = 0, i = row_stride*y;
1597 x < width; x++, i += pixel_stride)
1601 ((uint8_t *)&pixel)[order[0]];
1602 dest_u8[i + channel_stride] =
1603 ((uint8_t *)&pixel)[order[1]];
1604 dest_u8[i + channel_stride2] =
1605 ((uint8_t *)&pixel)[order[2]];
1609 for(y = 0; y < height; y++, src += width)
1610 for(x = 0, i = row_stride*y;
1611 x < width; x++, i += pixel_stride)
1615 ((uint8_t *)&pixel)[order[0]];
1616 dest_u8[i + channel_stride] =
1617 ((uint8_t *)&pixel)[order[1]];
1618 dest_u8[i + channel_stride2] =
1619 ((uint8_t *)&pixel)[order[2]];
1620 dest_u8[i + channel_stride3] =
1621 ((uint8_t *)&pixel)[order[3]];
1626 case IMAGEIO_SINGLE:
1627 if(!(dest_f32 = (
float *)
Malloc(
1628 sizeof(
float)*num_channels*num_pixels)))
1631 switch(num_channels)
1634 for(y = 0; y < height; y++, src += width)
1635 for(x = 0, i = row_stride*y;
1636 x < width; x++, i += pixel_stride)
1640 1.172549019607843070675535e-3f*((uint8_t *)&pixel)[0]
1641 + 2.301960784313725357840079e-3f*((uint8_t *)&pixel)[1]
1642 + 4.470588235294117808150007e-4f*((uint8_t *)&pixel)[2];
1646 for(y = 0; y < height; y++, src += width)
1647 for(x = 0, i = row_stride*y; x < width;
1648 x++, i += pixel_stride)
1652 ((uint8_t *)&pixel)[order[0]]/255.0f;
1653 dest_f32[i + channel_stride] =
1654 ((uint8_t *)&pixel)[order[1]]/255.0f;
1655 dest_f32[i + channel_stride2] =
1656 ((uint8_t *)&pixel)[order[2]]/255.0f;
1660 for(y = 0; y < height; y++, src += width)
1661 for(x = 0, i = row_stride*y;
1662 x < width; x++, i += pixel_stride)
1666 ((uint8_t *)&pixel)[order[0]]/255.0f;
1667 dest_f32[i + channel_stride] =
1668 ((uint8_t *)&pixel)[order[1]]/255.0f;
1669 dest_f32[i + channel_stride2] =
1670 ((uint8_t *)&pixel)[order[2]]/255.0f;
1671 dest_f32[i + channel_stride3] =
1672 ((uint8_t *)&pixel)[order[3]]/255.0f;
1677 case IMAGEIO_DOUBLE:
1678 if(!(dest_f64 = (
double *)
Malloc(
sizeof(
double)*num_channels*num_pixels)))
1681 switch(num_channels)
1684 for(y = 0; y < height; y++, src += width)
1685 for(x = 0, i = row_stride*y; x < width; x++, i += pixel_stride)
1688 dest_f64[i] = 1.172549019607843070675535e-3*((uint8_t *)&pixel)[0]
1689 + 2.301960784313725357840079e-3*((uint8_t *)&pixel)[1]
1690 + 4.470588235294117808150007e-4*((uint8_t *)&pixel)[2];
1694 for(y = 0; y < height; y++, src += width)
1695 for(x = 0, i = row_stride*y; x < width; x++, i += pixel_stride)
1699 ((uint8_t *)&pixel)[order[0]]/255.0;
1700 dest_f64[i + channel_stride] =
1701 ((uint8_t *)&pixel)[order[1]]/255.0;
1702 dest_f64[i + channel_stride2] =
1703 ((uint8_t *)&pixel)[order[2]]/255.0;
1707 for(y = 0; y < height; y++, src += width)
1708 for(x = 0, i = row_stride*y; x < width; x++, i += pixel_stride)
1712 ((uint8_t *)&pixel)[order[0]]/255.0;
1713 dest_f64[i + channel_stride] =
1714 ((uint8_t *)&pixel)[order[1]]/255.0;
1715 dest_f64[i + channel_stride2] =
1716 ((uint8_t *)&pixel)[order[2]]/255.0;
1717 dest_f64[i + channel_stride3] =
1718 ((uint8_t *)&pixel)[order[3]]/255.0;
1733 const int num_pixels = width*height;
1734 const int num_channels = (format & IMAGEIO_GRAYSCALE) ?
1735 1 : ((format & IMAGEIO_STRIP_ALPHA) ? 3 : 4);
1736 const int channel_stride = (format & IMAGEIO_PLANAR) ? num_pixels : 1;
1737 const int channel_stride2 = 2*channel_stride;
1738 const int channel_stride3 = 3*channel_stride;
1739 double *src_f64 = (
double *)src;
1740 float *src_f32 = (
float *)src;
1741 uint8_t *src_u8 = (uint8_t *)src;
1742 uint8_t *dest, *dest_ptr;
1743 int order[4] = {0, 1, 2, 3};
1744 int i, x, y, pixel_stride, row_stride;
1746 if(!(dest = (uint8_t *)
Malloc(
sizeof(uint32_t)*num_pixels)))
1750 pixel_stride = (format & IMAGEIO_PLANAR) ? 1 : num_channels;
1752 if(format & IMAGEIO_COLUMNMAJOR)
1754 row_stride = pixel_stride;
1755 pixel_stride *= height;
1758 row_stride = width*pixel_stride;
1760 if(format & IMAGEIO_BGRFLIP)
1766 if((format & IMAGEIO_AFLIP) && !(format & IMAGEIO_STRIP_ALPHA))
1768 order[3] = order[2];
1769 order[2] = order[1];
1770 order[1] = order[0];
1774 switch(format & (IMAGEIO_U8 | IMAGEIO_SINGLE | IMAGEIO_DOUBLE))
1777 switch(num_channels)
1780 for(y = 0; y < height; y++, dest_ptr += 4*width)
1781 for(x = 0, i = row_stride*y;
1782 x < width; x++, i += pixel_stride)
1786 dest_ptr[4*x + 2] = src_u8[i];
1787 dest_ptr[4*x + 3] = 255;
1791 for(y = 0; y < height; y++, dest_ptr += 4*width)
1792 for(x = 0, i = row_stride*y;
1793 x < width; x++, i += pixel_stride)
1795 dest_ptr[4*x + order[0]] = src_u8[i];
1796 dest_ptr[4*x + order[1]] = src_u8[i + channel_stride];
1797 dest_ptr[4*x + order[2]] = src_u8[i + channel_stride2];
1798 dest_ptr[4*x + 3] = 255;
1802 for(y = 0; y < height; y++, dest_ptr += 4*width)
1803 for(x = 0, i = row_stride*y;
1804 x < width; x++, i += pixel_stride)
1806 dest_ptr[4*x + order[0]] = src_u8[i];
1807 dest_ptr[4*x + order[1]] = src_u8[i + channel_stride];
1808 dest_ptr[4*x + order[2]] = src_u8[i + channel_stride2];
1809 dest_ptr[4*x + order[3]] = src_u8[i + channel_stride3];
1814 case IMAGEIO_SINGLE:
1815 switch(num_channels)
1818 for(y = 0; y < height; y++, dest_ptr += 4*width)
1819 for(x = 0, i = row_stride*y;
1820 x < width; x++, i += pixel_stride)
1824 dest_ptr[4*x + 2] = ROUNDCLAMPF(src_f32[i]);
1825 dest_ptr[4*x + 3] = 255;
1829 for(y = 0; y < height; y++, dest_ptr += 4*width)
1830 for(x = 0, i = row_stride*y;
1831 x < width; x++, i += pixel_stride)
1833 dest_ptr[4*x + order[0]] =
1834 ROUNDCLAMPF(src_f32[i]);
1835 dest_ptr[4*x + order[1]] =
1836 ROUNDCLAMPF(src_f32[i + channel_stride]);
1837 dest_ptr[4*x + order[2]] =
1838 ROUNDCLAMPF(src_f32[i + channel_stride2]);
1839 dest_ptr[4*x + 3] = 255;
1843 for(y = 0; y < height; y++, dest_ptr += 4*width)
1844 for(x = 0, i = row_stride*y;
1845 x < width; x++, i += pixel_stride)
1847 dest_ptr[4*x + order[0]] =
1848 ROUNDCLAMPF(src_f32[i]);
1849 dest_ptr[4*x + order[1]] =
1850 ROUNDCLAMPF(src_f32[i + channel_stride]);
1851 dest_ptr[4*x + order[2]] =
1852 ROUNDCLAMPF(src_f32[i + channel_stride2]);
1853 dest_ptr[4*x + order[3]] =
1854 ROUNDCLAMPF(src_f32[i + channel_stride3]);
1859 case IMAGEIO_DOUBLE:
1860 switch(num_channels)
1863 for(y = 0; y < height; y++, dest_ptr += 4*width)
1864 for(x = 0, i = row_stride*y;
1865 x < width; x++, i += pixel_stride)
1869 dest_ptr[4*x + 2] = ROUNDCLAMP(src_f64[i]);
1870 dest_ptr[4*x + 3] = 255;
1874 for(y = 0; y < height; y++, dest_ptr += 4*width)
1875 for(x = 0, i = row_stride*y;
1876 x < width; x++, i += pixel_stride)
1878 dest_ptr[4*x + order[0]] =
1879 ROUNDCLAMP(src_f64[i]);
1880 dest_ptr[4*x + order[1]] =
1881 ROUNDCLAMP(src_f64[i + channel_stride]);
1882 dest_ptr[4*x + order[2]] =
1883 ROUNDCLAMP(src_f64[i + channel_stride2]);
1884 dest_ptr[4*x + 3] = 255;;
1888 for(y = 0; y < height; y++, dest_ptr += 4*width)
1889 for(x = 0, i = row_stride*y; x < width; x++, i += pixel_stride)
1891 dest_ptr[4*x + order[0]] =
1892 ROUNDCLAMP(src_f64[i]);
1893 dest_ptr[4*x + order[1]] =
1894 ROUNDCLAMP(src_f64[i + channel_stride]);
1895 dest_ptr[4*x + order[2]] =
1896 ROUNDCLAMP(src_f64[i + channel_stride2]);
1897 dest_ptr[4*x + order[3]] =
1898 ROUNDCLAMP(src_f64[i + channel_stride3]);
1907 return (uint32_t *)dest;
1927 if(!(file = fopen(filename,
"rb")))
1931 magic = ((uint32_t)getc(file));
1932 magic |= ((uint32_t)getc(file)) << 8;
1933 magic |= ((uint32_t)getc(file)) << 16;
1934 magic |= ((uint32_t)getc(file)) << 24;
1945 if((magic & 0x0000FFFFL) == 0x00004D42L)
1946 strcpy(type,
"BMP");
1947 else if((magic & 0x00FFFFFFL) == 0x00FFD8FFL)
1948 strcpy(type,
"JPEG");
1949 else if(magic == 0x474E5089L)
1950 strcpy(type,
"PNG");
1951 else if(magic == 0x002A4949L || magic == 0x2A004D4DL)
1952 strcpy(type,
"TIFF");
1953 else if(magic == 0x38464947L)
1954 strcpy(type,
"GIF");
1955 else if(magic == 0x474E4D8AL)
1956 strcpy(type,
"MNG");
1957 else if((magic & 0xF0FF00FFL) == 0x0001000AL
1958 && ((magic >> 8) & 0xFF) < 6)
1959 strcpy(type,
"PCX");
2049 const char *filename,
unsigned format)
2052 uint32_t *image_u8 = NULL;
2059 if(!(file = fopen(filename,
"rb")))
2061 ErrorMessage(
"Unable to open file \"%s\".\n", filename);
2065 if(!strcmp(type,
"BMP"))
2067 if(!
read_bmp(&image_u8, width, height, file))
2070 else if(!strcmp(type,
"JPEG"))
2073 if(!(read_jpeg(&image_u8, width, height, file)))
2077 "Compile with USE_LIBJPEG to enable JPEG reading.\n",
2081 else if(!strcmp(type,
"PNG"))
2084 if(!(read_png(&image_u8, width, height, file)))
2088 "Compile with USE_LIBPNG to enable PNG reading.\n",
2092 else if(!strcmp(type,
"TIFF"))
2097 if(!(read_tiff(&image_u8, width, height, filename, 0)))
2103 "Compile with USE_LIBTIFF to enable TIFF reading.\n",
2111 ErrorMessage(
"file \"%s\" is a %s image.", filename, type);
2113 ErrorMessage(
"file \"%s\" is an unrecognized format.", filename);
2114 fprintf(stderr,
"\nSorry, only "
2121 if(image_u8 && format)
2153 const char *filename,
unsigned format,
int quality)
2157 enum {BMP_FORMAT, JPEG_FORMAT, PNG_FORMAT, TIFF_FORMAT} fileformat;
2160 if(!image || width <= 0 || height <= 0)
2168 fileformat = BMP_FORMAT;
2172 fileformat = JPEG_FORMAT;
2175 ErrorMessage(
"Compile with USE_LIBJPEG to enable JPEG writing.\n");
2181 fileformat = PNG_FORMAT;
2184 ErrorMessage(
"Compile with USE_LIBPNG to enable PNG writing.\n");
2191 fileformat = TIFF_FORMAT;
2194 ErrorMessage(
"Compile with USE_LIBTIFF to enable TIFF writing.\n");
2209 ErrorMessage(
"Unable to determine format from extension.\n");
2216 if(!(file = fopen(filename,
"wb")))
2218 ErrorMessage(
"Unable to write to file \"%s\".\n", filename);
2228 success =
write_bmp(image_u8, width, height, file);
2232 success = write_jpeg(image_u8, width, height, file, quality);
2242 success = write_png(image_u8, width, height, file);
2248 success = write_tiff(image_u8, width, height, filename);