121 #include "config_auto.h" 125 #include "allheaders.h" 136 #define Z_DEFAULT_COMPRESSION (-1) 142 static l_int32 var_PNG_STRIP_16_TO_8 = 1;
144 #ifndef NO_CONSOLE_IO 146 #define DEBUG_WRITE 0 188 l_int32 rval, gval, bval;
189 l_int32 i, j, k, index, ncolors, bitval;
190 l_int32 wpl, d, spp, cindex, tRNS;
191 l_uint32 png_transforms;
192 l_uint32 *data, *line, *ppixel;
193 int num_palette, num_text, num_trans;
194 png_byte bit_depth, color_type, channels;
195 png_uint_32 w, h, rowbytes;
196 png_uint_32 xres, yres;
197 png_bytep rowptr, trans;
198 png_bytep *row_pointers;
200 png_infop info_ptr, end_info;
206 PROCNAME(
"pixReadStreamPng");
209 return (
PIX *)ERROR_PTR(
"fp not defined", procName, NULL);
213 if ((png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
214 (png_voidp)NULL, NULL, NULL)) == NULL)
215 return (
PIX *)ERROR_PTR(
"png_ptr not made", procName, NULL);
217 if ((info_ptr = png_create_info_struct(png_ptr)) == NULL) {
218 png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
219 return (
PIX *)ERROR_PTR(
"info_ptr not made", procName, NULL);
222 if ((end_info = png_create_info_struct(png_ptr)) == NULL) {
223 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
224 return (
PIX *)ERROR_PTR(
"end_info not made", procName, NULL);
228 if (setjmp(png_jmpbuf(png_ptr))) {
229 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
230 return (
PIX *)ERROR_PTR(
"internal png error", procName, NULL);
233 png_init_io(png_ptr, fp);
242 if (var_PNG_STRIP_16_TO_8 == 1) {
243 png_transforms = PNG_TRANSFORM_STRIP_16;
245 png_transforms = PNG_TRANSFORM_IDENTITY;
246 L_INFO(
"not stripping 16 --> 8 in png reading\n", procName);
250 png_read_png(png_ptr, info_ptr, png_transforms, NULL);
252 row_pointers = png_get_rows(png_ptr, info_ptr);
253 w = png_get_image_width(png_ptr, info_ptr);
254 h = png_get_image_height(png_ptr, info_ptr);
255 bit_depth = png_get_bit_depth(png_ptr, info_ptr);
256 rowbytes = png_get_rowbytes(png_ptr, info_ptr);
257 color_type = png_get_color_type(png_ptr, info_ptr);
258 channels = png_get_channels(png_ptr, info_ptr);
260 tRNS = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) ? 1 : 0;
269 if (spp == 3 && bit_depth != 8) {
270 fprintf(stderr,
"Help: spp = 3 and depth = %d != 8\n!!", bit_depth);
271 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
272 return (
PIX *)ERROR_PTR(
"not implemented for this depth",
277 if (color_type == PNG_COLOR_TYPE_PALETTE ||
278 color_type == PNG_COLOR_MASK_PALETTE) {
279 png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
281 for (cindex = 0; cindex < num_palette; cindex++) {
282 rval = palette[cindex].red;
283 gval = palette[cindex].green;
284 bval = palette[cindex].blue;
289 if ((pix =
pixCreate(w, h, d)) == NULL) {
291 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
292 return (
PIX *)ERROR_PTR(
"pix not made", procName, NULL);
294 pixSetInputFormat(pix, IFF_PNG);
295 wpl = pixGetWpl(pix);
300 if (spp == 1 && !tRNS) {
301 for (i = 0; i < h; i++) {
302 line = data + i * wpl;
303 rowptr = row_pointers[i];
304 for (j = 0; j < rowbytes; j++) {
308 }
else if (spp == 2) {
309 L_INFO(
"converting (gray + alpha) ==> RGBA\n", procName);
310 for (i = 0; i < h; i++) {
311 ppixel = data + i * wpl;
312 rowptr = row_pointers[i];
313 for (j = k = 0; j < w; j++) {
323 }
else if (spp == 3 || spp == 4) {
324 for (i = 0; i < h; i++) {
325 ppixel = data + i * wpl;
326 rowptr = row_pointers[i];
327 for (j = k = 0; j < w; j++) {
343 if (spp == 1 && tRNS) {
346 L_INFO(
"transparency, 1 spp, no colormap, no transparency array: " 347 "convention is fully transparent image\n", procName);
348 L_INFO(
"converting (fully transparent 1 spp) ==> RGBA\n", procName);
353 L_INFO(
"converting (cmap + alpha) ==> RGBA\n", procName);
356 png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL);
359 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
360 return (
PIX *)ERROR_PTR(
"cmap, tRNS, but no transparency array",
371 wpl = pixGetWpl(pix);
376 fprintf(stderr,
"ncolors = %d, num_trans = %d\n",
378 for (i = 0; i < ncolors; i++) {
381 fprintf(stderr,
"(r,g,b,a) = (%d,%d,%d,%d)\n",
382 rval, gval, bval, trans[i]);
384 fprintf(stderr,
"(r,g,b,a) = (%d,%d,%d,<<255>>)\n",
393 L_INFO(
"converting 1 bpp cmap with alpha ==> RGBA\n", procName);
395 L_INFO(
"num_trans = 1; second color opaque by default\n",
397 for (i = 0; i < h; i++) {
398 ppixel = data + i * wpl;
399 rowptr = row_pointers[i];
400 for (j = 0, index = 0; j < rowbytes; j++) {
402 for (k = 0; k < 8 && index < w; k++, index++) {
403 bitval = (byte >> (7 - k)) & 1;
407 bitval < num_trans ? trans[bitval] : 255);
414 L_INFO(
"converting 8 bpp cmap with alpha ==> RGBA\n", procName);
415 for (i = 0; i < h; i++) {
416 ppixel = data + i * wpl;
417 rowptr = row_pointers[i];
418 for (j = 0; j < w; j++) {
426 index < num_trans ? trans[index] : 255);
431 L_ERROR(
"spp == 1, cmap, trans array, invalid depth: %d\n",
440 for (i = 0; i < 16; i++) {
441 fprintf(stderr,
"[%d] = %d\n", i,
442 ((l_uint8 *)(cmap->
array))[i]);
469 if (pixGetDepth(pix) == 1) {
479 xres = png_get_x_pixels_per_meter(png_ptr, info_ptr);
480 yres = png_get_y_pixels_per_meter(png_ptr, info_ptr);
481 pixSetXRes(pix, (l_int32)((l_float32)xres / 39.37 + 0.5));
482 pixSetYRes(pix, (l_int32)((l_float32)yres / 39.37 + 0.5));
485 png_get_text(png_ptr, info_ptr, &text_ptr, &num_text);
486 if (num_text && text_ptr)
489 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
527 PROCNAME(
"readHeaderPng");
533 if (piscmap) *piscmap = 0;
535 return ERROR_INT(
"filename not defined", procName, 1);
537 return ERROR_INT(
"image file not found", procName, 1);
571 PROCNAME(
"freadHeaderPng");
577 if (piscmap) *piscmap = 0;
579 return ERROR_INT(
"stream not defined", procName, 1);
583 return ERROR_INT(
"file too small to be png", procName, 1);
584 if (fread(data, 1, 40, fp) != 40)
585 return ERROR_INT(
"error reading data", procName, 1);
628 l_int32 colortype, bps, spp;
631 PROCNAME(
"readHeaderMemPng");
637 if (piscmap) *piscmap = 0;
639 return ERROR_INT(
"data not defined", procName, 1);
641 return ERROR_INT(
"size < 40", procName, 1);
644 if (data[0] != 137 || data[1] != 80 || data[2] != 78 ||
645 data[3] != 71 || data[4] != 13 || data[5] != 10 ||
646 data[6] != 26 || data[7] != 10)
647 return ERROR_INT(
"not a valid png file", procName, 1);
649 pword = (l_uint32 *)data;
650 pshort = (l_uint16 *)data;
651 if (pw) *pw = convertOnLittleEnd32(pword[4]);
652 if (ph) *ph = convertOnLittleEnd32(pword[5]);
653 twobytes = convertOnLittleEnd16(pshort[12]);
655 colortype = twobytes & 0xff;
663 L_INFO(
"gray + alpha: will extract as RGBA (spp = 4)\n", procName);
665 if (colortype == 2) {
667 }
else if (colortype == 6) {
669 }
else if (colortype == 4) {
675 if (pbps) *pbps = bps;
676 if (pspp) *pspp = spp;
704 fgetPngResolution(FILE *fp,
708 png_uint_32 xres, yres;
712 PROCNAME(
"fgetPngResolution");
714 if (pxres) *pxres = 0;
715 if (pyres) *pyres = 0;
717 return ERROR_INT(
"stream not opened", procName, 1);
718 if (!pxres || !pyres)
719 return ERROR_INT(
"&xres and &yres not both defined", procName, 1);
722 if ((png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
723 (png_voidp)NULL, NULL, NULL)) == NULL)
724 return ERROR_INT(
"png_ptr not made", procName, 1);
725 if ((info_ptr = png_create_info_struct(png_ptr)) == NULL) {
726 png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
727 return ERROR_INT(
"info_ptr not made", procName, 1);
732 if (setjmp(png_jmpbuf(png_ptr))) {
733 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
734 return ERROR_INT(
"internal png error", procName, 1);
739 png_init_io(png_ptr, fp);
740 png_read_info(png_ptr, info_ptr);
742 xres = png_get_x_pixels_per_meter(png_ptr, info_ptr);
743 yres = png_get_y_pixels_per_meter(png_ptr, info_ptr);
744 *pxres = (l_int32)((l_float32)xres / 39.37 + 0.5);
745 *pyres = (l_int32)((l_float32)yres / 39.37 + 0.5);
747 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
762 l_int32 *pinterlaced)
767 PROCNAME(
"isPngInterlaced");
770 return ERROR_INT(
"&interlaced not defined", procName, 1);
773 return ERROR_INT(
"filename not defined", procName, 1);
776 return ERROR_INT(
"stream not opened", procName, 1);
777 if (fread(buf, 1, 32, fp) != 32) {
779 return ERROR_INT(
"data not read", procName, 1);
783 *pinterlaced = (buf[28] == 0) ? 0 : 1;
805 fgetPngColormapInfo(FILE *fp,
807 l_int32 *ptransparency)
809 l_int32 i, cindex, rval, gval, bval, num_palette, num_trans;
810 png_byte bit_depth, color_type;
816 PROCNAME(
"fgetPngColormapInfo");
818 if (pcmap) *pcmap = NULL;
819 if (ptransparency) *ptransparency = 0;
820 if (!pcmap && !ptransparency)
821 return ERROR_INT(
"no output defined", procName, 1);
823 return ERROR_INT(
"stream not opened", procName, 1);
826 if ((png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
827 (png_voidp)NULL, NULL, NULL)) == NULL)
828 return ERROR_INT(
"png_ptr not made", procName, 1);
829 if ((info_ptr = png_create_info_struct(png_ptr)) == NULL) {
830 png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
831 return ERROR_INT(
"info_ptr not made", procName, 1);
836 if (setjmp(png_jmpbuf(png_ptr))) {
837 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
839 return ERROR_INT(
"internal png error", procName, 1);
844 png_init_io(png_ptr, fp);
845 png_read_info(png_ptr, info_ptr);
846 color_type = png_get_color_type(png_ptr, info_ptr);
847 if (color_type != PNG_COLOR_TYPE_PALETTE &&
848 color_type != PNG_COLOR_MASK_PALETTE) {
849 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
855 bit_depth = png_get_bit_depth(png_ptr, info_ptr);
856 png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
858 for (cindex = 0; cindex < num_palette; cindex++) {
859 rval = palette[cindex].red;
860 gval = palette[cindex].green;
861 bval = palette[cindex].blue;
868 if (ptransparency && png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
869 png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL);
871 for (i = 0; i < num_trans; i++) {
872 if (trans[i] < 255) {
878 L_ERROR(
"transparency array not returned\n", procName);
882 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
912 PROCNAME(
"pixWritePng");
915 return ERROR_INT(
"pix not defined", procName, 1);
917 return ERROR_INT(
"filename not defined", procName, 1);
920 return ERROR_INT(
"stream not opened", procName, 1);
924 return ERROR_INT(
"pix not written to stream", procName, 1);
1010 char commentstring[] =
"Comment";
1012 l_int32 wpl, d, spp, cmflag, opaque;
1013 l_int32 ncolors, compval;
1014 l_int32 *rmap, *gmap, *bmap, *amap;
1015 l_uint32 *data, *ppixel;
1016 png_byte bit_depth, color_type;
1017 png_byte alpha[256];
1019 png_uint_32 xres, yres;
1020 png_bytep *row_pointers;
1021 png_bytep rowbuffer;
1022 png_structp png_ptr;
1029 PROCNAME(
"pixWriteStreamPng");
1032 return ERROR_INT(
"stream not open", procName, 1);
1034 return ERROR_INT(
"pix not defined", procName, 1);
1037 if ((png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1038 (png_voidp)NULL, NULL, NULL)) == NULL)
1039 return ERROR_INT(
"png_ptr not made", procName, 1);
1041 if ((info_ptr = png_create_info_struct(png_ptr)) == NULL) {
1042 png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
1043 return ERROR_INT(
"info_ptr not made", procName, 1);
1047 if (setjmp(png_jmpbuf(png_ptr))) {
1048 png_destroy_write_struct(&png_ptr, &info_ptr);
1049 return ERROR_INT(
"internal png error", procName, 1);
1052 png_init_io(png_ptr, fp);
1059 compval = Z_DEFAULT_COMPRESSION;
1062 png_set_compression_level(png_ptr, compval);
1064 w = pixGetWidth(pix);
1065 h = pixGetHeight(pix);
1066 d = pixGetDepth(pix);
1067 spp = pixGetSpp(pix);
1068 if ((cmap = pixGetColormap(pix)))
1075 if (d == 32 && spp == 4) {
1077 color_type = PNG_COLOR_TYPE_RGBA;
1079 }
else if (d == 24 || d == 32) {
1081 color_type = PNG_COLOR_TYPE_RGB;
1085 color_type = PNG_COLOR_TYPE_GRAY;
1088 color_type = PNG_COLOR_TYPE_PALETTE;
1091 fprintf(stderr,
"cmflag = %d, bit_depth = %d, color_type = %d\n",
1092 cmflag, bit_depth, color_type);
1095 png_set_IHDR(png_ptr, info_ptr, w, h, bit_depth, color_type,
1096 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
1097 PNG_FILTER_TYPE_BASE);
1100 xres = (png_uint_32)(39.37 * (l_float32)pixGetXRes(pix) + 0.5);
1101 yres = (png_uint_32)(39.37 * (l_float32)pixGetYRes(pix) + 0.5);
1102 if ((xres == 0) || (yres == 0))
1103 png_set_pHYs(png_ptr, info_ptr, 0, 0, PNG_RESOLUTION_UNKNOWN);
1105 png_set_pHYs(png_ptr, info_ptr, xres, yres, PNG_RESOLUTION_METER);
1113 palette = (png_colorp)LEPT_CALLOC(ncolors,
sizeof(png_color));
1114 for (i = 0; i < ncolors; i++) {
1115 palette[i].red = (png_byte)rmap[i];
1116 palette[i].green = (png_byte)gmap[i];
1117 palette[i].blue = (png_byte)bmap[i];
1118 alpha[i] = (png_byte)amap[i];
1121 png_set_PLTE(png_ptr, info_ptr, palette, (
int)ncolors);
1123 png_set_tRNS(png_ptr, info_ptr, (png_bytep)alpha,
1124 (
int)ncolors, NULL);
1135 png_set_gAMA(png_ptr, info_ptr, (l_float64)gamma);
1138 png_text text_chunk;
1139 text_chunk.compression = PNG_TEXT_COMPRESSION_NONE;
1140 text_chunk.key = commentstring;
1141 text_chunk.text = text;
1142 text_chunk.text_length = strlen(text);
1143 #ifdef PNG_ITXT_SUPPORTED 1144 text_chunk.itxt_length = 0;
1145 text_chunk.lang = NULL;
1146 text_chunk.lang_key = NULL;
1148 png_set_text(png_ptr, info_ptr, &text_chunk, 1);
1152 png_write_info(png_ptr, info_ptr);
1154 if ((d != 32) && (d != 24)) {
1161 if (d == 1 && !cmap) {
1168 png_destroy_write_struct(&png_ptr, &info_ptr);
1169 if (cmflag) LEPT_FREE(palette);
1170 return ERROR_INT(
"pix1 not made", procName, 1);
1174 row_pointers = (png_bytep *)LEPT_CALLOC(h,
sizeof(png_bytep));
1175 wpl = pixGetWpl(pix1);
1177 for (i = 0; i < h; i++)
1178 row_pointers[i] = (png_bytep)(data + i * wpl);
1179 png_set_rows(png_ptr, info_ptr, row_pointers);
1182 png_write_image(png_ptr, row_pointers);
1183 png_write_end(png_ptr, info_ptr);
1185 if (cmflag) LEPT_FREE(palette);
1186 LEPT_FREE(row_pointers);
1188 png_destroy_write_struct(&png_ptr, &info_ptr);
1194 wpl = pixGetWpl(pix);
1196 for (i = 0; i < h; i++) {
1197 ppixel = data + i * wpl;
1198 png_write_rows(png_ptr, (png_bytepp)&ppixel, 1);
1202 rowbuffer = (png_bytep)LEPT_CALLOC(w, 4);
1203 for (i = 0; i < h; i++) {
1204 ppixel = data + i * wpl;
1205 for (j = k = 0; j < w; j++) {
1214 png_write_rows(png_ptr, &rowbuffer, 1);
1216 LEPT_FREE(rowbuffer);
1219 png_write_end(png_ptr, info_ptr);
1223 png_destroy_write_struct(&png_ptr, &info_ptr);
1253 PROCNAME(
"pixSetZlibCompression");
1256 return ERROR_INT(
"pix not defined", procName, 1);
1257 if (compval < 0 || compval > 9) {
1258 L_ERROR(
"Invalid zlib comp val; using default\n", procName);
1259 compval = Z_DEFAULT_COMPRESSION;
1261 pixSetSpecial(pix, 10 + compval);
1279 var_PNG_STRIP_16_TO_8 = flag;
1308 static void memio_png_flush(
MEMIODATA* pthing);
1309 static void memio_png_read_data(png_structp png_ptr, png_bytep outBytes,
1310 png_size_t byteCountToRead);
1311 static void memio_free(
MEMIODATA* pthing);
1313 static const l_int32 MEMIO_BUFFER_SIZE = 8192;
1334 l_int32 written = 0;
1335 l_int32 remainingSpace, remainingToWrite;
1337 thing = (
struct MemIOData*)png_get_io_ptr(png_ptr);
1340 if (len > MEMIO_BUFFER_SIZE) {
1341 last->
m_Buffer = (
char *)LEPT_MALLOC(len);
1347 last->
m_Buffer = (
char *)LEPT_MALLOC(MEMIO_BUFFER_SIZE);
1348 last->
m_Size = MEMIO_BUFFER_SIZE;
1351 while (written < len) {
1359 last = thing->
m_Last = next;
1361 last->
m_Buffer = (
char *)LEPT_MALLOC(MEMIO_BUFFER_SIZE);
1362 last->
m_Size = MEMIO_BUFFER_SIZE;
1366 remainingToWrite = len - written;
1367 if (remainingSpace < remainingToWrite) {
1370 written += remainingSpace;
1371 last->
m_Count += remainingSpace;
1375 written += remainingToWrite;
1376 last->
m_Count += remainingToWrite;
1402 if (pthing->
m_Next == NULL)
return;
1408 while (buffer != NULL) {
1414 data = (
char *)LEPT_MALLOC(amount);
1424 while (buffer != NULL && copied < amount) {
1457 memio_png_read_data(png_structp png_ptr,
1459 png_size_t byteCountToRead)
1463 thing = (
MEMIODATA *)png_get_io_ptr(png_ptr);
1465 thing->
m_Count += byteCountToRead;
1490 while (buffer != NULL) {
1521 l_int32 rval, gval, bval;
1522 l_int32 i, j, k, index, ncolors, bitval;
1523 l_int32 wpl, d, spp, cindex, tRNS;
1524 l_uint32 png_transforms;
1525 l_uint32 *data, *line, *ppixel;
1526 int num_palette, num_text, num_trans;
1527 png_byte bit_depth, color_type, channels;
1528 png_uint_32 w, h, rowbytes;
1529 png_uint_32 xres, yres;
1530 png_bytep rowptr, trans;
1531 png_bytep *row_pointers;
1532 png_structp png_ptr;
1533 png_infop info_ptr, end_info;
1540 PROCNAME(
"pixReadMemPng");
1543 return (
PIX *)ERROR_PTR(
"filedata not defined", procName, NULL);
1545 return (
PIX *)ERROR_PTR(
"invalid filesize", procName, NULL);
1555 if ((png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
1556 (png_voidp)NULL, NULL, NULL)) == NULL)
1557 return (
PIX *)ERROR_PTR(
"png_ptr not made", procName, NULL);
1559 if ((info_ptr = png_create_info_struct(png_ptr)) == NULL) {
1560 png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
1561 return (
PIX *)ERROR_PTR(
"info_ptr not made", procName, NULL);
1564 if ((end_info = png_create_info_struct(png_ptr)) == NULL) {
1565 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
1566 return (
PIX *)ERROR_PTR(
"end_info not made", procName, NULL);
1570 if (setjmp(png_jmpbuf(png_ptr))) {
1571 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
1572 return (
PIX *)ERROR_PTR(
"internal png error", procName, NULL);
1575 png_set_read_fn(png_ptr, &state, memio_png_read_data);
1584 if (var_PNG_STRIP_16_TO_8 == 1) {
1585 png_transforms = PNG_TRANSFORM_STRIP_16;
1587 png_transforms = PNG_TRANSFORM_IDENTITY;
1588 L_INFO(
"not stripping 16 --> 8 in png reading\n", procName);
1592 png_read_png(png_ptr, info_ptr, png_transforms, NULL);
1594 row_pointers = png_get_rows(png_ptr, info_ptr);
1595 w = png_get_image_width(png_ptr, info_ptr);
1596 h = png_get_image_height(png_ptr, info_ptr);
1597 bit_depth = png_get_bit_depth(png_ptr, info_ptr);
1598 rowbytes = png_get_rowbytes(png_ptr, info_ptr);
1599 color_type = png_get_color_type(png_ptr, info_ptr);
1600 channels = png_get_channels(png_ptr, info_ptr);
1602 tRNS = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) ? 1 : 0;
1611 if (spp == 3 && bit_depth != 8) {
1612 fprintf(stderr,
"Help: spp = 3 and depth = %d != 8\n!!", bit_depth);
1613 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
1614 return (
PIX *)ERROR_PTR(
"not implemented for this depth",
1619 if (color_type == PNG_COLOR_TYPE_PALETTE ||
1620 color_type == PNG_COLOR_MASK_PALETTE) {
1621 png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
1623 for (cindex = 0; cindex < num_palette; cindex++) {
1624 rval = palette[cindex].red;
1625 gval = palette[cindex].green;
1626 bval = palette[cindex].blue;
1631 if ((pix =
pixCreate(w, h, d)) == NULL) {
1633 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
1635 return (
PIX *)ERROR_PTR(
"pix not made", procName, NULL);
1637 pixSetInputFormat(pix, IFF_PNG);
1638 wpl = pixGetWpl(pix);
1641 pixSetSpp(pix, spp);
1643 if (spp == 1 && !tRNS) {
1644 for (i = 0; i < h; i++) {
1645 line = data + i * wpl;
1646 rowptr = row_pointers[i];
1647 for (j = 0; j < rowbytes; j++) {
1651 }
else if (spp == 2) {
1652 L_INFO(
"converting (gray + alpha) ==> RGBA\n", procName);
1653 for (i = 0; i < h; i++) {
1654 ppixel = data + i * wpl;
1655 rowptr = row_pointers[i];
1656 for (j = k = 0; j < w; j++) {
1666 }
else if (spp == 3 || spp == 4) {
1667 for (i = 0; i < h; i++) {
1668 ppixel = data + i * wpl;
1669 rowptr = row_pointers[i];
1670 for (j = k = 0; j < w; j++) {
1686 if (spp == 1 && tRNS) {
1689 L_INFO(
"transparency, 1 spp, no colormap, no transparency array: " 1690 "convention is fully transparent image\n", procName);
1691 L_INFO(
"converting (fully transparent 1 spp) ==> RGBA\n", procName);
1696 L_INFO(
"converting (cmap + alpha) ==> RGBA\n", procName);
1699 png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL);
1702 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
1703 return (
PIX *)ERROR_PTR(
"cmap, tRNS, but no transparency array",
1714 wpl = pixGetWpl(pix);
1719 fprintf(stderr,
"ncolors = %d, num_trans = %d\n",
1720 ncolors, num_trans);
1721 for (i = 0; i < ncolors; i++) {
1723 if (i < num_trans) {
1724 fprintf(stderr,
"(r,g,b,a) = (%d,%d,%d,%d)\n",
1725 rval, gval, bval, trans[i]);
1727 fprintf(stderr,
"(r,g,b,a) = (%d,%d,%d,<<255>>)\n",
1736 L_INFO(
"converting 1 bpp cmap with alpha ==> RGBA\n", procName);
1738 L_INFO(
"num_trans = 1; second color opaque by default\n",
1740 for (i = 0; i < h; i++) {
1741 ppixel = data + i * wpl;
1742 rowptr = row_pointers[i];
1743 for (j = 0, index = 0; j < rowbytes; j++) {
1745 for (k = 0; k < 8 && index < w; k++, index++) {
1746 bitval = (byte >> (7 - k)) & 1;
1750 bitval < num_trans ? trans[bitval] : 255);
1755 }
else if (d == 8) {
1757 L_INFO(
"converting 8 bpp cmap with alpha ==> RGBA\n", procName);
1758 for (i = 0; i < h; i++) {
1759 ppixel = data + i * wpl;
1760 rowptr = row_pointers[i];
1761 for (j = 0; j < w; j++) {
1769 index < num_trans ? trans[index] : 255);
1774 L_ERROR(
"spp == 1, cmap, trans array, invalid depth: %d\n",
1783 for (i = 0; i < 16; i++) {
1784 fprintf(stderr,
"[%d] = %d\n", i,
1785 ((l_uint8 *)(cmap->
array))[i]);
1812 if (pixGetDepth(pix) == 1) {
1822 xres = png_get_x_pixels_per_meter(png_ptr, info_ptr);
1823 yres = png_get_y_pixels_per_meter(png_ptr, info_ptr);
1824 pixSetXRes(pix, (l_int32)((l_float32)xres / 39.37 + 0.5));
1825 pixSetYRes(pix, (l_int32)((l_float32)yres / 39.37 + 0.5));
1828 png_get_text(png_ptr, info_ptr, &text_ptr, &num_text);
1829 if (num_text && text_ptr)
1832 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
1860 char commentstring[] =
"Comment";
1862 l_int32 wpl, d, spp, cmflag, opaque;
1863 l_int32 ncolors, compval;
1864 l_int32 *rmap, *gmap, *bmap, *amap;
1865 l_uint32 *data, *ppixel;
1866 png_byte bit_depth, color_type;
1867 png_byte alpha[256];
1869 png_uint_32 xres, yres;
1870 png_bytep *row_pointers;
1871 png_bytep rowbuffer;
1872 png_structp png_ptr;
1880 PROCNAME(
"pixWriteMemPng");
1882 if (pfiledata) *pfiledata = NULL;
1883 if (pfilesize) *pfilesize = 0;
1885 return ERROR_INT(
"&filedata not defined", procName, 1);
1887 return ERROR_INT(
"&filesize not defined", procName, 1);
1889 return ERROR_INT(
"pix not defined", procName, 1);
1898 if ((png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1899 (png_voidp)NULL, NULL, NULL)) == NULL)
1900 return ERROR_INT(
"png_ptr not made", procName, 1);
1902 if ((info_ptr = png_create_info_struct(png_ptr)) == NULL) {
1903 png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
1904 return ERROR_INT(
"info_ptr not made", procName, 1);
1908 if (setjmp(png_jmpbuf(png_ptr))) {
1909 png_destroy_write_struct(&png_ptr, &info_ptr);
1910 return ERROR_INT(
"internal png error", procName, 1);
1914 (png_flush_ptr)NULL);
1921 compval = Z_DEFAULT_COMPRESSION;
1924 png_set_compression_level(png_ptr, compval);
1926 w = pixGetWidth(pix);
1927 h = pixGetHeight(pix);
1928 d = pixGetDepth(pix);
1929 spp = pixGetSpp(pix);
1930 if ((cmap = pixGetColormap(pix)))
1936 if (d == 32 && spp == 4) {
1938 color_type = PNG_COLOR_TYPE_RGBA;
1940 }
else if (d == 24 || d == 32) {
1942 color_type = PNG_COLOR_TYPE_RGB;
1946 color_type = PNG_COLOR_TYPE_GRAY;
1949 color_type = PNG_COLOR_TYPE_PALETTE;
1952 fprintf(stderr,
"cmflag = %d, bit_depth = %d, color_type = %d\n",
1953 cmflag, bit_depth, color_type);
1956 png_set_IHDR(png_ptr, info_ptr, w, h, bit_depth, color_type,
1957 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
1958 PNG_FILTER_TYPE_BASE);
1961 xres = (png_uint_32)(39.37 * (l_float32)pixGetXRes(pix) + 0.5);
1962 yres = (png_uint_32)(39.37 * (l_float32)pixGetYRes(pix) + 0.5);
1963 if ((xres == 0) || (yres == 0))
1964 png_set_pHYs(png_ptr, info_ptr, 0, 0, PNG_RESOLUTION_UNKNOWN);
1966 png_set_pHYs(png_ptr, info_ptr, xres, yres, PNG_RESOLUTION_METER);
1974 palette = (png_colorp)LEPT_CALLOC(ncolors,
sizeof(png_color));
1975 for (i = 0; i < ncolors; i++) {
1976 palette[i].red = (png_byte)rmap[i];
1977 palette[i].green = (png_byte)gmap[i];
1978 palette[i].blue = (png_byte)bmap[i];
1979 alpha[i] = (png_byte)amap[i];
1982 png_set_PLTE(png_ptr, info_ptr, palette, (
int)ncolors);
1984 png_set_tRNS(png_ptr, info_ptr, (png_bytep)alpha,
1985 (
int)ncolors, NULL);
1996 png_set_gAMA(png_ptr, info_ptr, (l_float64)gamma);
1999 png_text text_chunk;
2000 text_chunk.compression = PNG_TEXT_COMPRESSION_NONE;
2001 text_chunk.key = commentstring;
2002 text_chunk.text = text;
2003 text_chunk.text_length = strlen(text);
2004 #ifdef PNG_ITXT_SUPPORTED 2005 text_chunk.itxt_length = 0;
2006 text_chunk.lang = NULL;
2007 text_chunk.lang_key = NULL;
2009 png_set_text(png_ptr, info_ptr, &text_chunk, 1);
2013 png_write_info(png_ptr, info_ptr);
2015 if ((d != 32) && (d != 24)) {
2022 if (d == 1 && !cmap) {
2029 png_destroy_write_struct(&png_ptr, &info_ptr);
2030 if (cmflag) LEPT_FREE(palette);
2032 return ERROR_INT(
"pix1 not made", procName, 1);
2036 row_pointers = (png_bytep *)LEPT_CALLOC(h,
sizeof(png_bytep));
2037 wpl = pixGetWpl(pix1);
2039 for (i = 0; i < h; i++)
2040 row_pointers[i] = (png_bytep)(data + i * wpl);
2041 png_set_rows(png_ptr, info_ptr, row_pointers);
2044 png_write_image(png_ptr, row_pointers);
2045 png_write_end(png_ptr, info_ptr);
2047 if (cmflag) LEPT_FREE(palette);
2048 LEPT_FREE(row_pointers);
2050 png_destroy_write_struct(&png_ptr, &info_ptr);
2052 memio_png_flush(&state);
2053 *pfiledata = (l_uint8 *)state.
m_Buffer;
2062 wpl = pixGetWpl(pix);
2064 for (i = 0; i < h; i++) {
2065 ppixel = data + i * wpl;
2066 png_write_rows(png_ptr, (png_bytepp)&ppixel, 1);
2070 rowbuffer = (png_bytep)LEPT_CALLOC(w, 4);
2071 for (i = 0; i < h; i++) {
2072 ppixel = data + i * wpl;
2073 for (j = k = 0; j < w; j++) {
2082 png_write_rows(png_ptr, &rowbuffer, 1);
2084 LEPT_FREE(rowbuffer);
2087 png_write_end(png_ptr, info_ptr);
2091 png_destroy_write_struct(&png_ptr, &info_ptr);
2093 memio_png_flush(&state);
2094 *pfiledata = (l_uint8 *)state.
m_Buffer;
l_int32 pixWriteStreamPng(FILE *fp, PIX *pix, l_float32 gamma)
pixWriteStreamPng()
PIX * pixRemoveColormap(PIX *pixs, l_int32 type)
pixRemoveColormap()
l_int32 pixEndianByteSwap(PIX *pixs)
pixEndianByteSwap()
PIX * pixReadStreamPng(FILE *fp)
pixReadStreamPng()
l_int32 readHeaderPng(const char *filename, l_int32 *pw, l_int32 *ph, l_int32 *pbps, l_int32 *pspp, l_int32 *piscmap)
readHeaderPng()
static void memio_png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
l_int32 freadHeaderPng(FILE *fp, l_int32 *pw, l_int32 *ph, l_int32 *pbps, l_int32 *pspp, l_int32 *piscmap)
freadHeaderPng()
l_int32 pixSetZlibCompression(PIX *pix, l_int32 compval)
pixSetZlibCompression()
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
PIX * pixInvert(PIX *pixd, PIX *pixs)
pixInvert()
void pixcmapDestroy(PIXCMAP **pcmap)
pixcmapDestroy()
l_uint32 * pixGetData(PIX *pix)
pixGetData()
l_int32 pixWriteMemPng(l_uint8 **pfiledata, size_t *pfilesize, PIX *pix, l_float32 gamma)
pixWriteMemPng()
l_int32 pixcmapGetColor(PIXCMAP *cmap, l_int32 index, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
pixcmapGetColor()
l_int32 pixcmapToArrays(PIXCMAP *cmap, l_int32 **prmap, l_int32 **pgmap, l_int32 **pbmap, l_int32 **pamap)
pixcmapToArrays()
void l_pngSetReadStrip16To8(l_int32 flag)
l_pngSetReadStrip16To8()
struct MemIOData * m_Next
PIXCMAP * pixcmapCreate(l_int32 depth)
pixcmapCreate()
l_int32 pixcmapIsOpaque(PIXCMAP *cmap, l_int32 *popaque)
pixcmapIsOpaque()
l_int32 pixcmapAddColor(PIXCMAP *cmap, l_int32 rval, l_int32 gval, l_int32 bval)
pixcmapAddColor()
l_int32 pixSetPadBits(PIX *pix, l_int32 val)
pixSetPadBits()
#define SET_DATA_BYTE(pdata, n, val)
l_int32 pixSetColormap(PIX *pix, PIXCMAP *colormap)
pixSetColormap()
size_t fnbytesInFile(FILE *fp)
fnbytesInFile()
#define GET_DATA_BYTE(pdata, n)
void pixDestroy(PIX **ppix)
pixDestroy()
PIX * pixEndianByteSwapNew(PIX *pixs)
pixEndianByteSwapNew()
FILE * fopenWriteStream(const char *filename, const char *modestring)
fopenWriteStream()
l_int32 isPngInterlaced(const char *filename, l_int32 *pinterlaced)
isPngInterlaced()
FILE * fopenReadStream(const char *filename)
fopenReadStream()
char * pixGetText(PIX *pix)
pixGetText()
l_int32 composeRGBPixel(l_int32 rval, l_int32 gval, l_int32 bval, l_uint32 *ppixel)
composeRGBPixel()
l_int32 pixcmapGetCount(PIXCMAP *cmap)
pixcmapGetCount()
l_int32 pixWritePng(const char *filename, PIX *pix, l_float32 gamma)
pixWritePng()
PIX * pixReadMemPng(const l_uint8 *filedata, size_t filesize)
pixReadMemPng()
PIXCMAP * pixcmapCopy(PIXCMAP *cmaps)
pixcmapCopy()
l_int32 readHeaderMemPng(const l_uint8 *data, size_t size, l_int32 *pw, l_int32 *ph, l_int32 *pbps, l_int32 *pspp, l_int32 *piscmap)
readHeaderMemPng()
struct MemIOData * m_Last
l_int32 pixcmapSetAlpha(PIXCMAP *cmap, l_int32 index, l_int32 aval)
pixcmapSetAlpha()
l_int32 pixSetText(PIX *pix, const char *textstring)
pixSetText()