3 #include <lib/gdi/epng.h>
6 gImage *loadPNG(const char *filename)
9 FILE *fp=fopen(filename, "rb");
15 // eDebug("couldn't open %s", filename );
18 if (!fread(header, 8, 1, fp))
20 eDebug("couldn't read");
24 if (png_sig_cmp(header, 0, 8))
29 png_structp png_ptr=png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
36 png_infop info_ptr=png_create_info_struct(png_ptr);
39 eDebug("no info ptr");
40 png_destroy_read_struct(&png_ptr, (png_infopp)0, (png_infopp)0);
44 png_infop end_info = png_create_info_struct(png_ptr);
48 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
52 if (setjmp(png_ptr->jmpbuf))
54 eDebug("das war wohl nix");
55 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
61 png_init_io(png_ptr, fp);
62 png_set_sig_bytes(png_ptr, 8);
63 png_set_invert_alpha(png_ptr);
64 png_read_info(png_ptr, info_ptr);
66 png_uint_32 width, height;
70 png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0);
72 // eDebug("%s: %dx%dx%d png, %d", filename, (int)width, (int)height, (int)bit_depth, color_type);
76 res=new gImage(eSize(width, height), bit_depth);
78 png_bytep *rowptr=new png_bytep[height];
80 for (unsigned int i=0; i<height; i++)
81 rowptr[i]=((png_byte*)(res->data))+i*res->stride;
82 png_read_rows(png_ptr, rowptr, 0, height);
86 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE))
90 png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
92 res->clut.data=new gRGB[num_palette];
95 res->clut.colors=num_palette;
97 for (int i=0; i<num_palette; i++)
99 res->clut.data[i].a=0;
100 res->clut.data[i].r=palette[i].red;
101 res->clut.data[i].g=palette[i].green;
102 res->clut.data[i].b=palette[i].blue;
104 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
107 png_get_tRNS(png_ptr, info_ptr, &trans, &num_palette, 0);
108 for (int i=0; i<num_palette; i++)
109 res->clut.data[i].a=255-trans[i];
116 png_read_end(png_ptr, end_info);
120 png_destroy_read_struct(&png_ptr, &info_ptr,&end_info);
125 int savePNG(const char *filename, gPixmap *pixmap)
127 FILE *fp=fopen(filename, "wb");
130 png_structp png_ptr=png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
133 eDebug("write png, couldnt allocate write struct");
138 png_infop info_ptr=png_create_info_struct(png_ptr);
142 png_destroy_write_struct(&png_ptr, 0);
147 if (setjmp(png_ptr->jmpbuf))
150 png_destroy_write_struct(&png_ptr, &info_ptr);
155 png_init_io(png_ptr, fp);
156 png_set_filter(png_ptr, 0, PNG_FILTER_NONE|PNG_FILTER_SUB|PNG_FILTER_PAETH);
157 png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
159 png_set_IHDR(png_ptr, info_ptr, pixmap->x, pixmap->y, pixmap->bpp,
160 pixmap->clut.data ? PNG_COLOR_TYPE_PALETTE : PNG_COLOR_TYPE_GRAY,
161 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
162 if (pixmap->clut.data)
164 png_color palette[pixmap->clut.colors];
165 png_byte trans[pixmap->clut.colors];
166 for (int i=0; i<pixmap->clut.colors; ++i)
168 palette[i].red=pixmap->clut.data[i].r;
169 palette[i].green=pixmap->clut.data[i].g;
170 palette[i].blue=pixmap->clut.data[i].b;
171 trans[i]=255-pixmap->clut.data[i].a;
173 png_set_PLTE(png_ptr, info_ptr, palette, pixmap->clut.colors);
174 png_set_tRNS(png_ptr, info_ptr, trans, pixmap->clut.colors, 0);
176 png_write_info(png_ptr, info_ptr);
177 png_set_packing(png_ptr);
178 png_byte *row_pointers[pixmap->y];
179 for (int i=0; i<pixmap->y; ++i)
180 row_pointers[i]=((png_byte*)pixmap->data)+i*pixmap->stride;
181 png_write_image(png_ptr, row_pointers);
182 png_write_end(png_ptr, info_ptr);
183 png_destroy_write_struct(&png_ptr, &info_ptr);
185 eDebug("wrote png ! fine !");