3 #include <lib/gdi/epng.h>
6 int loadPNG(ePtr<gPixmap> &result, const char *filename)
9 FILE *fp=fopen(filename, "rb");
13 // eDebug("couldn't open %s", filename );
16 if (!fread(header, 8, 1, fp))
18 eDebug("couldn't read");
22 if (png_sig_cmp(header, 0, 8))
27 png_structp png_ptr=png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
34 png_infop info_ptr=png_create_info_struct(png_ptr);
37 eDebug("no info ptr");
38 png_destroy_read_struct(&png_ptr, (png_infopp)0, (png_infopp)0);
42 png_infop end_info = png_create_info_struct(png_ptr);
46 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
50 if (setjmp(png_ptr->jmpbuf))
52 eDebug("das war wohl nix");
53 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
58 png_init_io(png_ptr, fp);
59 png_set_sig_bytes(png_ptr, 8);
60 png_set_invert_alpha(png_ptr);
61 png_read_info(png_ptr, info_ptr);
63 png_uint_32 width, height;
67 png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0);
69 eDebug("%s: %dx%dx%d png, %d", filename, (int)width, (int)height, (int)bit_depth, color_type);
73 result=new gPixmap(eSize(width, height), bit_depth);
74 eDebug("gPixmap at %p", (gPixmap*)result);
75 gSurface *surface = result->surface;
77 png_bytep *rowptr=new png_bytep[height];
79 for (unsigned int i=0; i<height; i++)
80 rowptr[i]=((png_byte*)(surface->data))+i*surface->stride;
81 png_read_rows(png_ptr, rowptr, 0, height);
85 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE))
89 png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
91 surface->clut.data=new gRGB[num_palette];
94 surface->clut.colors=num_palette;
96 for (int i=0; i<num_palette; i++)
98 surface->clut.data[i].a=0;
99 surface->clut.data[i].r=palette[i].red;
100 surface->clut.data[i].g=palette[i].green;
101 surface->clut.data[i].b=palette[i].blue;
103 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
106 png_get_tRNS(png_ptr, info_ptr, &trans, &num_palette, 0);
107 for (int i=0; i<num_palette; i++)
108 surface->clut.data[i].a=255-trans[i];
112 surface->clut.data=0;
113 surface->clut.colors=0;
115 surface->clut.start=0;
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");
131 gSurface *surface = pixmap->surface;
135 png_structp png_ptr=png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
138 eDebug("write png, couldnt allocate write struct");
143 png_infop info_ptr=png_create_info_struct(png_ptr);
147 png_destroy_write_struct(&png_ptr, 0);
152 if (setjmp(png_ptr->jmpbuf))
155 png_destroy_write_struct(&png_ptr, &info_ptr);
160 png_init_io(png_ptr, fp);
161 png_set_filter(png_ptr, 0, PNG_FILTER_NONE|PNG_FILTER_SUB|PNG_FILTER_PAETH);
162 png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
164 png_set_IHDR(png_ptr, info_ptr, surface->x, surface->y, surface->bpp,
165 surface->clut.data ? PNG_COLOR_TYPE_PALETTE : PNG_COLOR_TYPE_GRAY,
166 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
167 if (surface->clut.data)
169 png_color palette[surface->clut.colors];
170 png_byte trans[surface->clut.colors];
171 for (int i=0; i<surface->clut.colors; ++i)
173 palette[i].red=surface->clut.data[i].r;
174 palette[i].green=surface->clut.data[i].g;
175 palette[i].blue=surface->clut.data[i].b;
176 trans[i]=255-surface->clut.data[i].a;
178 png_set_PLTE(png_ptr, info_ptr, palette, surface->clut.colors);
179 png_set_tRNS(png_ptr, info_ptr, trans, surface->clut.colors, 0);
181 png_write_info(png_ptr, info_ptr);
182 png_set_packing(png_ptr);
183 png_byte *row_pointers[surface->y];
184 for (int i=0; i<surface->y; ++i)
185 row_pointers[i]=((png_byte*)surface->data)+i*surface->stride;
186 png_write_image(png_ptr, row_pointers);
187 png_write_end(png_ptr, info_ptr);
188 png_destroy_write_struct(&png_ptr, &info_ptr);
190 eDebug("wrote png ! fine !");