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) {
473 L_INFO(
"removing opaque cmap from 1 bpp\n", procName);
480 xres = png_get_x_pixels_per_meter(png_ptr, info_ptr);
481 yres = png_get_y_pixels_per_meter(png_ptr, info_ptr);
482 pixSetXRes(pix, (l_int32)((l_float32)xres / 39.37 + 0.5));
483 pixSetYRes(pix, (l_int32)((l_float32)yres / 39.37 + 0.5));
486 png_get_text(png_ptr, info_ptr, &text_ptr, &num_text);
487 if (num_text && text_ptr)
490 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
528 PROCNAME(
"readHeaderPng");
534 if (piscmap) *piscmap = 0;
536 return ERROR_INT(
"filename not defined", procName, 1);
538 return ERROR_INT(
"image file not found", procName, 1);
572 PROCNAME(
"freadHeaderPng");
578 if (piscmap) *piscmap = 0;
580 return ERROR_INT(
"stream not defined", procName, 1);
584 return ERROR_INT(
"file too small to be png", procName, 1);
585 if (fread(data, 1, 40, fp) != 40)
586 return ERROR_INT(
"error reading data", procName, 1);
629 l_int32 colortype, bps, spp;
632 PROCNAME(
"readHeaderMemPng");
638 if (piscmap) *piscmap = 0;
640 return ERROR_INT(
"data not defined", procName, 1);
642 return ERROR_INT(
"size < 40", procName, 1);
645 if (data[0] != 137 || data[1] != 80 || data[2] != 78 ||
646 data[3] != 71 || data[4] != 13 || data[5] != 10 ||
647 data[6] != 26 || data[7] != 10)
648 return ERROR_INT(
"not a valid png file", procName, 1);
650 pword = (l_uint32 *)data;
651 pshort = (l_uint16 *)data;
652 if (pw) *pw = convertOnLittleEnd32(pword[4]);
653 if (ph) *ph = convertOnLittleEnd32(pword[5]);
654 twobytes = convertOnLittleEnd16(pshort[12]);
656 colortype = twobytes & 0xff;
664 L_INFO(
"gray + alpha: will extract as RGBA (spp = 4)\n", procName);
666 if (colortype == 2) {
668 }
else if (colortype == 6) {
670 }
else if (colortype == 4) {
676 if (pbps) *pbps = bps;
677 if (pspp) *pspp = spp;
705 fgetPngResolution(FILE *fp,
709 png_uint_32 xres, yres;
713 PROCNAME(
"fgetPngResolution");
715 if (pxres) *pxres = 0;
716 if (pyres) *pyres = 0;
718 return ERROR_INT(
"stream not opened", procName, 1);
719 if (!pxres || !pyres)
720 return ERROR_INT(
"&xres and &yres not both defined", procName, 1);
723 if ((png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
724 (png_voidp)NULL, NULL, NULL)) == NULL)
725 return ERROR_INT(
"png_ptr not made", procName, 1);
726 if ((info_ptr = png_create_info_struct(png_ptr)) == NULL) {
727 png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
728 return ERROR_INT(
"info_ptr not made", procName, 1);
733 if (setjmp(png_jmpbuf(png_ptr))) {
734 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
735 return ERROR_INT(
"internal png error", procName, 1);
740 png_init_io(png_ptr, fp);
741 png_read_info(png_ptr, info_ptr);
743 xres = png_get_x_pixels_per_meter(png_ptr, info_ptr);
744 yres = png_get_y_pixels_per_meter(png_ptr, info_ptr);
745 *pxres = (l_int32)((l_float32)xres / 39.37 + 0.5);
746 *pyres = (l_int32)((l_float32)yres / 39.37 + 0.5);
748 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
763 l_int32 *pinterlaced)
768 PROCNAME(
"isPngInterlaced");
771 return ERROR_INT(
"&interlaced not defined", procName, 1);
774 return ERROR_INT(
"filename not defined", procName, 1);
777 return ERROR_INT(
"stream not opened", procName, 1);
778 if (fread(buf, 1, 32, fp) != 32) {
780 return ERROR_INT(
"data not read", procName, 1);
784 *pinterlaced = (buf[28] == 0) ? 0 : 1;
806 fgetPngColormapInfo(FILE *fp,
808 l_int32 *ptransparency)
810 l_int32 i, cindex, rval, gval, bval, num_palette, num_trans;
811 png_byte bit_depth, color_type;
817 PROCNAME(
"fgetPngColormapInfo");
819 if (pcmap) *pcmap = NULL;
820 if (ptransparency) *ptransparency = 0;
821 if (!pcmap && !ptransparency)
822 return ERROR_INT(
"no output defined", procName, 1);
824 return ERROR_INT(
"stream not opened", procName, 1);
827 if ((png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
828 (png_voidp)NULL, NULL, NULL)) == NULL)
829 return ERROR_INT(
"png_ptr not made", procName, 1);
830 if ((info_ptr = png_create_info_struct(png_ptr)) == NULL) {
831 png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
832 return ERROR_INT(
"info_ptr not made", procName, 1);
837 if (setjmp(png_jmpbuf(png_ptr))) {
838 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
840 return ERROR_INT(
"internal png error", procName, 1);
845 png_init_io(png_ptr, fp);
846 png_read_info(png_ptr, info_ptr);
847 color_type = png_get_color_type(png_ptr, info_ptr);
848 if (color_type != PNG_COLOR_TYPE_PALETTE &&
849 color_type != PNG_COLOR_MASK_PALETTE) {
850 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
856 bit_depth = png_get_bit_depth(png_ptr, info_ptr);
857 png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
859 for (cindex = 0; cindex < num_palette; cindex++) {
860 rval = palette[cindex].red;
861 gval = palette[cindex].green;
862 bval = palette[cindex].blue;
869 if (ptransparency && png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
870 png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL);
872 for (i = 0; i < num_trans; i++) {
873 if (trans[i] < 255) {
879 L_ERROR(
"transparency array not returned\n", procName);
883 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
913 PROCNAME(
"pixWritePng");
916 return ERROR_INT(
"pix not defined", procName, 1);
918 return ERROR_INT(
"filename not defined", procName, 1);
921 return ERROR_INT(
"stream not opened", procName, 1);
925 return ERROR_INT(
"pix not written to stream", procName, 1);
1011 char commentstring[] =
"Comment";
1013 l_int32 wpl, d, spp, cmflag, opaque;
1014 l_int32 ncolors, compval;
1015 l_int32 *rmap, *gmap, *bmap, *amap;
1016 l_uint32 *data, *ppixel;
1017 png_byte bit_depth, color_type;
1018 png_byte alpha[256];
1020 png_uint_32 xres, yres;
1021 png_bytep *row_pointers;
1022 png_bytep rowbuffer;
1023 png_structp png_ptr;
1030 PROCNAME(
"pixWriteStreamPng");
1033 return ERROR_INT(
"stream not open", procName, 1);
1035 return ERROR_INT(
"pix not defined", procName, 1);
1038 if ((png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1039 (png_voidp)NULL, NULL, NULL)) == NULL)
1040 return ERROR_INT(
"png_ptr not made", procName, 1);
1042 if ((info_ptr = png_create_info_struct(png_ptr)) == NULL) {
1043 png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
1044 return ERROR_INT(
"info_ptr not made", procName, 1);
1048 if (setjmp(png_jmpbuf(png_ptr))) {
1049 png_destroy_write_struct(&png_ptr, &info_ptr);
1050 return ERROR_INT(
"internal png error", procName, 1);
1053 png_init_io(png_ptr, fp);
1060 compval = Z_DEFAULT_COMPRESSION;
1063 png_set_compression_level(png_ptr, compval);
1065 w = pixGetWidth(pix);
1066 h = pixGetHeight(pix);
1067 d = pixGetDepth(pix);
1068 spp = pixGetSpp(pix);
1069 if ((cmap = pixGetColormap(pix)))
1076 if (d == 32 && spp == 4) {
1078 color_type = PNG_COLOR_TYPE_RGBA;
1080 }
else if (d == 24 || d == 32) {
1082 color_type = PNG_COLOR_TYPE_RGB;
1086 color_type = PNG_COLOR_TYPE_GRAY;
1089 color_type = PNG_COLOR_TYPE_PALETTE;
1092 fprintf(stderr,
"cmflag = %d, bit_depth = %d, color_type = %d\n",
1093 cmflag, bit_depth, color_type);
1096 png_set_IHDR(png_ptr, info_ptr, w, h, bit_depth, color_type,
1097 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
1098 PNG_FILTER_TYPE_BASE);
1101 xres = (png_uint_32)(39.37 * (l_float32)pixGetXRes(pix) + 0.5);
1102 yres = (png_uint_32)(39.37 * (l_float32)pixGetYRes(pix) + 0.5);
1103 if ((xres == 0) || (yres == 0))
1104 png_set_pHYs(png_ptr, info_ptr, 0, 0, PNG_RESOLUTION_UNKNOWN);
1106 png_set_pHYs(png_ptr, info_ptr, xres, yres, PNG_RESOLUTION_METER);
1114 palette = (png_colorp)LEPT_CALLOC(ncolors,
sizeof(png_color));
1115 for (i = 0; i < ncolors; i++) {
1116 palette[i].red = (png_byte)rmap[i];
1117 palette[i].green = (png_byte)gmap[i];
1118 palette[i].blue = (png_byte)bmap[i];
1119 alpha[i] = (png_byte)amap[i];
1122 png_set_PLTE(png_ptr, info_ptr, palette, (
int)ncolors);
1124 png_set_tRNS(png_ptr, info_ptr, (png_bytep)alpha,
1125 (
int)ncolors, NULL);
1136 png_set_gAMA(png_ptr, info_ptr, (l_float64)gamma);
1139 png_text text_chunk;
1140 text_chunk.compression = PNG_TEXT_COMPRESSION_NONE;
1141 text_chunk.key = commentstring;
1142 text_chunk.text = text;
1143 text_chunk.text_length = strlen(text);
1144 #ifdef PNG_ITXT_SUPPORTED 1145 text_chunk.itxt_length = 0;
1146 text_chunk.lang = NULL;
1147 text_chunk.lang_key = NULL;
1149 png_set_text(png_ptr, info_ptr, &text_chunk, 1);
1153 png_write_info(png_ptr, info_ptr);
1155 if ((d != 32) && (d != 24)) {
1162 if (d == 1 && !cmap) {
1169 png_destroy_write_struct(&png_ptr, &info_ptr);
1170 if (cmflag) LEPT_FREE(palette);
1171 return ERROR_INT(
"pix1 not made", procName, 1);
1175 row_pointers = (png_bytep *)LEPT_CALLOC(h,
sizeof(png_bytep));
1176 wpl = pixGetWpl(pix1);
1178 for (i = 0; i < h; i++)
1179 row_pointers[i] = (png_bytep)(data + i * wpl);
1180 png_set_rows(png_ptr, info_ptr, row_pointers);
1183 png_write_image(png_ptr, row_pointers);
1184 png_write_end(png_ptr, info_ptr);
1186 if (cmflag) LEPT_FREE(palette);
1187 LEPT_FREE(row_pointers);
1189 png_destroy_write_struct(&png_ptr, &info_ptr);
1195 wpl = pixGetWpl(pix);
1197 for (i = 0; i < h; i++) {
1198 ppixel = data + i * wpl;
1199 png_write_rows(png_ptr, (png_bytepp)&ppixel, 1);
1203 rowbuffer = (png_bytep)LEPT_CALLOC(w, 4);
1204 for (i = 0; i < h; i++) {
1205 ppixel = data + i * wpl;
1206 for (j = k = 0; j < w; j++) {
1215 png_write_rows(png_ptr, &rowbuffer, 1);
1217 LEPT_FREE(rowbuffer);
1220 png_write_end(png_ptr, info_ptr);
1224 png_destroy_write_struct(&png_ptr, &info_ptr);
1254 PROCNAME(
"pixSetZlibCompression");
1257 return ERROR_INT(
"pix not defined", procName, 1);
1258 if (compval < 0 || compval > 9) {
1259 L_ERROR(
"Invalid zlib comp val; using default\n", procName);
1260 compval = Z_DEFAULT_COMPRESSION;
1262 pixSetSpecial(pix, 10 + compval);
1280 var_PNG_STRIP_16_TO_8 = flag;
1309 static void memio_png_flush(
MEMIODATA* pthing);
1310 static void memio_png_read_data(png_structp png_ptr, png_bytep outBytes,
1311 png_size_t byteCountToRead);
1312 static void memio_free(
MEMIODATA* pthing);
1314 static const l_int32 MEMIO_BUFFER_SIZE = 8192;
1335 l_int32 written = 0;
1336 l_int32 remainingSpace, remainingToWrite;
1338 thing = (
struct MemIOData*)png_get_io_ptr(png_ptr);
1341 if (len > MEMIO_BUFFER_SIZE) {
1342 last->
m_Buffer = (
char *)LEPT_MALLOC(len);
1348 last->
m_Buffer = (
char *)LEPT_MALLOC(MEMIO_BUFFER_SIZE);
1349 last->
m_Size = MEMIO_BUFFER_SIZE;
1352 while (written < len) {
1360 last = thing->
m_Last = next;
1362 last->
m_Buffer = (
char *)LEPT_MALLOC(MEMIO_BUFFER_SIZE);
1363 last->
m_Size = MEMIO_BUFFER_SIZE;
1367 remainingToWrite = len - written;
1368 if (remainingSpace < remainingToWrite) {
1371 written += remainingSpace;
1372 last->
m_Count += remainingSpace;
1376 written += remainingToWrite;
1377 last->
m_Count += remainingToWrite;
1403 if (pthing->
m_Next == NULL)
return;
1409 while (buffer != NULL) {
1415 data = (
char *)LEPT_MALLOC(amount);
1425 while (buffer != NULL && copied < amount) {
1458 memio_png_read_data(png_structp png_ptr,
1460 png_size_t byteCountToRead)
1464 thing = (
MEMIODATA *)png_get_io_ptr(png_ptr);
1466 png_error(png_ptr,
"read error in memio_png_read_data");
1469 thing->
m_Count += byteCountToRead;
1494 while (buffer != NULL) {
1525 l_int32 rval, gval, bval;
1526 l_int32 i, j, k, index, ncolors, bitval;
1527 l_int32 wpl, d, spp, cindex, tRNS;
1528 l_uint32 png_transforms;
1529 l_uint32 *data, *line, *ppixel;
1530 int num_palette, num_text, num_trans;
1531 png_byte bit_depth, color_type, channels;
1532 png_uint_32 w, h, rowbytes;
1533 png_uint_32 xres, yres;
1534 png_bytep rowptr, trans;
1535 png_bytep *row_pointers;
1536 png_structp png_ptr;
1537 png_infop info_ptr, end_info;
1544 PROCNAME(
"pixReadMemPng");
1547 return (
PIX *)ERROR_PTR(
"filedata not defined", procName, NULL);
1549 return (
PIX *)ERROR_PTR(
"invalid filesize", procName, NULL);
1559 if ((png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
1560 (png_voidp)NULL, NULL, NULL)) == NULL)
1561 return (
PIX *)ERROR_PTR(
"png_ptr not made", procName, NULL);
1563 if ((info_ptr = png_create_info_struct(png_ptr)) == NULL) {
1564 png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
1565 return (
PIX *)ERROR_PTR(
"info_ptr not made", procName, NULL);
1568 if ((end_info = png_create_info_struct(png_ptr)) == NULL) {
1569 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
1570 return (
PIX *)ERROR_PTR(
"end_info not made", procName, NULL);
1574 if (setjmp(png_jmpbuf(png_ptr))) {
1575 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
1576 return (
PIX *)ERROR_PTR(
"internal png error", procName, NULL);
1579 png_set_read_fn(png_ptr, &state, memio_png_read_data);
1588 if (var_PNG_STRIP_16_TO_8 == 1) {
1589 png_transforms = PNG_TRANSFORM_STRIP_16;
1591 png_transforms = PNG_TRANSFORM_IDENTITY;
1592 L_INFO(
"not stripping 16 --> 8 in png reading\n", procName);
1596 png_read_png(png_ptr, info_ptr, png_transforms, NULL);
1598 row_pointers = png_get_rows(png_ptr, info_ptr);
1599 w = png_get_image_width(png_ptr, info_ptr);
1600 h = png_get_image_height(png_ptr, info_ptr);
1601 bit_depth = png_get_bit_depth(png_ptr, info_ptr);
1602 rowbytes = png_get_rowbytes(png_ptr, info_ptr);
1603 color_type = png_get_color_type(png_ptr, info_ptr);
1604 channels = png_get_channels(png_ptr, info_ptr);
1606 tRNS = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) ? 1 : 0;
1615 if (spp == 3 && bit_depth != 8) {
1616 fprintf(stderr,
"Help: spp = 3 and depth = %d != 8\n!!", bit_depth);
1617 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
1618 return (
PIX *)ERROR_PTR(
"not implemented for this depth",
1623 if (color_type == PNG_COLOR_TYPE_PALETTE ||
1624 color_type == PNG_COLOR_MASK_PALETTE) {
1625 png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
1627 for (cindex = 0; cindex < num_palette; cindex++) {
1628 rval = palette[cindex].red;
1629 gval = palette[cindex].green;
1630 bval = palette[cindex].blue;
1635 if ((pix =
pixCreate(w, h, d)) == NULL) {
1637 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
1639 return (
PIX *)ERROR_PTR(
"pix not made", procName, NULL);
1641 pixSetInputFormat(pix, IFF_PNG);
1642 wpl = pixGetWpl(pix);
1645 pixSetSpp(pix, spp);
1647 if (spp == 1 && !tRNS) {
1648 for (i = 0; i < h; i++) {
1649 line = data + i * wpl;
1650 rowptr = row_pointers[i];
1651 for (j = 0; j < rowbytes; j++) {
1655 }
else if (spp == 2) {
1656 L_INFO(
"converting (gray + alpha) ==> RGBA\n", procName);
1657 for (i = 0; i < h; i++) {
1658 ppixel = data + i * wpl;
1659 rowptr = row_pointers[i];
1660 for (j = k = 0; j < w; j++) {
1670 }
else if (spp == 3 || spp == 4) {
1671 for (i = 0; i < h; i++) {
1672 ppixel = data + i * wpl;
1673 rowptr = row_pointers[i];
1674 for (j = k = 0; j < w; j++) {
1690 if (spp == 1 && tRNS) {
1693 L_INFO(
"transparency, 1 spp, no colormap, no transparency array: " 1694 "convention is fully transparent image\n", procName);
1695 L_INFO(
"converting (fully transparent 1 spp) ==> RGBA\n", procName);
1700 L_INFO(
"converting (cmap + alpha) ==> RGBA\n", procName);
1703 png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL);
1706 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
1707 return (
PIX *)ERROR_PTR(
"cmap, tRNS, but no transparency array",
1718 wpl = pixGetWpl(pix);
1723 fprintf(stderr,
"ncolors = %d, num_trans = %d\n",
1724 ncolors, num_trans);
1725 for (i = 0; i < ncolors; i++) {
1727 if (i < num_trans) {
1728 fprintf(stderr,
"(r,g,b,a) = (%d,%d,%d,%d)\n",
1729 rval, gval, bval, trans[i]);
1731 fprintf(stderr,
"(r,g,b,a) = (%d,%d,%d,<<255>>)\n",
1740 L_INFO(
"converting 1 bpp cmap with alpha ==> RGBA\n", procName);
1742 L_INFO(
"num_trans = 1; second color opaque by default\n",
1744 for (i = 0; i < h; i++) {
1745 ppixel = data + i * wpl;
1746 rowptr = row_pointers[i];
1747 for (j = 0, index = 0; j < rowbytes; j++) {
1749 for (k = 0; k < 8 && index < w; k++, index++) {
1750 bitval = (byte >> (7 - k)) & 1;
1754 bitval < num_trans ? trans[bitval] : 255);
1759 }
else if (d == 8) {
1761 L_INFO(
"converting 8 bpp cmap with alpha ==> RGBA\n", procName);
1762 for (i = 0; i < h; i++) {
1763 ppixel = data + i * wpl;
1764 rowptr = row_pointers[i];
1765 for (j = 0; j < w; j++) {
1773 index < num_trans ? trans[index] : 255);
1778 L_ERROR(
"spp == 1, cmap, trans array, invalid depth: %d\n",
1787 for (i = 0; i < 16; i++) {
1788 fprintf(stderr,
"[%d] = %d\n", i,
1789 ((l_uint8 *)(cmap->
array))[i]);
1816 if (pixGetDepth(pix) == 1) {
1826 xres = png_get_x_pixels_per_meter(png_ptr, info_ptr);
1827 yres = png_get_y_pixels_per_meter(png_ptr, info_ptr);
1828 pixSetXRes(pix, (l_int32)((l_float32)xres / 39.37 + 0.5));
1829 pixSetYRes(pix, (l_int32)((l_float32)yres / 39.37 + 0.5));
1832 png_get_text(png_ptr, info_ptr, &text_ptr, &num_text);
1833 if (num_text && text_ptr)
1836 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
1864 char commentstring[] =
"Comment";
1866 l_int32 wpl, d, spp, cmflag, opaque;
1867 l_int32 ncolors, compval;
1868 l_int32 *rmap, *gmap, *bmap, *amap;
1869 l_uint32 *data, *ppixel;
1870 png_byte bit_depth, color_type;
1871 png_byte alpha[256];
1873 png_uint_32 xres, yres;
1874 png_bytep *row_pointers;
1875 png_bytep rowbuffer;
1876 png_structp png_ptr;
1884 PROCNAME(
"pixWriteMemPng");
1886 if (pfiledata) *pfiledata = NULL;
1887 if (pfilesize) *pfilesize = 0;
1889 return ERROR_INT(
"&filedata not defined", procName, 1);
1891 return ERROR_INT(
"&filesize not defined", procName, 1);
1893 return ERROR_INT(
"pix not defined", procName, 1);
1902 if ((png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
1903 (png_voidp)NULL, NULL, NULL)) == NULL)
1904 return ERROR_INT(
"png_ptr not made", procName, 1);
1906 if ((info_ptr = png_create_info_struct(png_ptr)) == NULL) {
1907 png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
1908 return ERROR_INT(
"info_ptr not made", procName, 1);
1912 if (setjmp(png_jmpbuf(png_ptr))) {
1913 png_destroy_write_struct(&png_ptr, &info_ptr);
1914 return ERROR_INT(
"internal png error", procName, 1);
1918 (png_flush_ptr)NULL);
1925 compval = Z_DEFAULT_COMPRESSION;
1928 png_set_compression_level(png_ptr, compval);
1930 w = pixGetWidth(pix);
1931 h = pixGetHeight(pix);
1932 d = pixGetDepth(pix);
1933 spp = pixGetSpp(pix);
1934 if ((cmap = pixGetColormap(pix)))
1940 if (d == 32 && spp == 4) {
1942 color_type = PNG_COLOR_TYPE_RGBA;
1944 }
else if (d == 24 || d == 32) {
1946 color_type = PNG_COLOR_TYPE_RGB;
1950 color_type = PNG_COLOR_TYPE_GRAY;
1953 color_type = PNG_COLOR_TYPE_PALETTE;
1956 fprintf(stderr,
"cmflag = %d, bit_depth = %d, color_type = %d\n",
1957 cmflag, bit_depth, color_type);
1960 png_set_IHDR(png_ptr, info_ptr, w, h, bit_depth, color_type,
1961 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
1962 PNG_FILTER_TYPE_BASE);
1965 xres = (png_uint_32)(39.37 * (l_float32)pixGetXRes(pix) + 0.5);
1966 yres = (png_uint_32)(39.37 * (l_float32)pixGetYRes(pix) + 0.5);
1967 if ((xres == 0) || (yres == 0))
1968 png_set_pHYs(png_ptr, info_ptr, 0, 0, PNG_RESOLUTION_UNKNOWN);
1970 png_set_pHYs(png_ptr, info_ptr, xres, yres, PNG_RESOLUTION_METER);
1978 palette = (png_colorp)LEPT_CALLOC(ncolors,
sizeof(png_color));
1979 for (i = 0; i < ncolors; i++) {
1980 palette[i].red = (png_byte)rmap[i];
1981 palette[i].green = (png_byte)gmap[i];
1982 palette[i].blue = (png_byte)bmap[i];
1983 alpha[i] = (png_byte)amap[i];
1986 png_set_PLTE(png_ptr, info_ptr, palette, (
int)ncolors);
1988 png_set_tRNS(png_ptr, info_ptr, (png_bytep)alpha,
1989 (
int)ncolors, NULL);
2000 png_set_gAMA(png_ptr, info_ptr, (l_float64)gamma);
2003 png_text text_chunk;
2004 text_chunk.compression = PNG_TEXT_COMPRESSION_NONE;
2005 text_chunk.key = commentstring;
2006 text_chunk.text = text;
2007 text_chunk.text_length = strlen(text);
2008 #ifdef PNG_ITXT_SUPPORTED 2009 text_chunk.itxt_length = 0;
2010 text_chunk.lang = NULL;
2011 text_chunk.lang_key = NULL;
2013 png_set_text(png_ptr, info_ptr, &text_chunk, 1);
2017 png_write_info(png_ptr, info_ptr);
2019 if ((d != 32) && (d != 24)) {
2026 if (d == 1 && !cmap) {
2033 png_destroy_write_struct(&png_ptr, &info_ptr);
2034 if (cmflag) LEPT_FREE(palette);
2036 return ERROR_INT(
"pix1 not made", procName, 1);
2040 row_pointers = (png_bytep *)LEPT_CALLOC(h,
sizeof(png_bytep));
2041 wpl = pixGetWpl(pix1);
2043 for (i = 0; i < h; i++)
2044 row_pointers[i] = (png_bytep)(data + i * wpl);
2045 png_set_rows(png_ptr, info_ptr, row_pointers);
2048 png_write_image(png_ptr, row_pointers);
2049 png_write_end(png_ptr, info_ptr);
2051 if (cmflag) LEPT_FREE(palette);
2052 LEPT_FREE(row_pointers);
2054 png_destroy_write_struct(&png_ptr, &info_ptr);
2056 memio_png_flush(&state);
2057 *pfiledata = (l_uint8 *)state.
m_Buffer;
2066 wpl = pixGetWpl(pix);
2068 for (i = 0; i < h; i++) {
2069 ppixel = data + i * wpl;
2070 png_write_rows(png_ptr, (png_bytepp)&ppixel, 1);
2074 rowbuffer = (png_bytep)LEPT_CALLOC(w, 4);
2075 for (i = 0; i < h; i++) {
2076 ppixel = data + i * wpl;
2077 for (j = k = 0; j < w; j++) {
2086 png_write_rows(png_ptr, &rowbuffer, 1);
2088 LEPT_FREE(rowbuffer);
2091 png_write_end(png_ptr, info_ptr);
2095 png_destroy_write_struct(&png_ptr, &info_ptr);
2097 memio_png_flush(&state);
2098 *pfiledata = (l_uint8 *)state.
m_Buffer;
PIX * pixRemoveColormap(PIX *pixs, l_int32 type)
pixRemoveColormap()
l_ok readHeaderMemPng(const l_uint8 *data, size_t size, l_int32 *pw, l_int32 *ph, l_int32 *pbps, l_int32 *pspp, l_int32 *piscmap)
readHeaderMemPng()
PIX * pixReadStreamPng(FILE *fp)
pixReadStreamPng()
static void memio_png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
l_ok freadHeaderPng(FILE *fp, l_int32 *pw, l_int32 *ph, l_int32 *pbps, l_int32 *pspp, l_int32 *piscmap)
freadHeaderPng()
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()
void l_pngSetReadStrip16To8(l_int32 flag)
l_pngSetReadStrip16To8()
l_ok pixWriteStreamPng(FILE *fp, PIX *pix, l_float32 gamma)
pixWriteStreamPng()
struct MemIOData * m_Next
l_ok pixSetColormap(PIX *pix, PIXCMAP *colormap)
pixSetColormap()
l_ok pixSetText(PIX *pix, const char *textstring)
pixSetText()
l_ok pixWritePng(const char *filename, PIX *pix, l_float32 gamma)
pixWritePng()
PIXCMAP * pixcmapCreate(l_int32 depth)
pixcmapCreate()
l_ok readHeaderPng(const char *filename, l_int32 *pw, l_int32 *ph, l_int32 *pbps, l_int32 *pspp, l_int32 *piscmap)
readHeaderPng()
l_ok pixcmapToArrays(PIXCMAP *cmap, l_int32 **prmap, l_int32 **pgmap, l_int32 **pbmap, l_int32 **pamap)
pixcmapToArrays()
l_ok pixWriteMemPng(l_uint8 **pfiledata, size_t *pfilesize, PIX *pix, l_float32 gamma)
pixWriteMemPng()
l_ok pixcmapGetColor(PIXCMAP *cmap, l_int32 index, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
pixcmapGetColor()
l_ok pixSetZlibCompression(PIX *pix, l_int32 compval)
pixSetZlibCompression()
l_ok pixEndianByteSwap(PIX *pixs)
pixEndianByteSwap()
#define SET_DATA_BYTE(pdata, n, val)
l_ok pixSetPadBits(PIX *pix, l_int32 val)
pixSetPadBits()
size_t fnbytesInFile(FILE *fp)
fnbytesInFile()
#define GET_DATA_BYTE(pdata, n)
l_ok pixcmapIsOpaque(PIXCMAP *cmap, l_int32 *popaque)
pixcmapIsOpaque()
void pixDestroy(PIX **ppix)
pixDestroy()
l_ok pixcmapSetAlpha(PIXCMAP *cmap, l_int32 index, l_int32 aval)
pixcmapSetAlpha()
PIX * pixEndianByteSwapNew(PIX *pixs)
pixEndianByteSwapNew()
FILE * fopenWriteStream(const char *filename, const char *modestring)
fopenWriteStream()
FILE * fopenReadStream(const char *filename)
fopenReadStream()
l_ok isPngInterlaced(const char *filename, l_int32 *pinterlaced)
isPngInterlaced()
char * pixGetText(PIX *pix)
pixGetText()
l_int32 pixcmapGetCount(PIXCMAP *cmap)
pixcmapGetCount()
PIX * pixReadMemPng(const l_uint8 *filedata, size_t filesize)
pixReadMemPng()
PIXCMAP * pixcmapCopy(PIXCMAP *cmaps)
pixcmapCopy()
l_ok composeRGBPixel(l_int32 rval, l_int32 gval, l_int32 bval, l_uint32 *ppixel)
composeRGBPixel()
l_ok pixcmapAddColor(PIXCMAP *cmap, l_int32 rval, l_int32 gval, l_int32 bval)
pixcmapAddColor()
struct MemIOData * m_Last