bool
Image::writePNG(std::ostream &os) const
{
+ assert(channelType == TYPE_UNORM8);
+
png_structp png_ptr;
png_infop info_ptr;
int color_type;
}
+bool
+Image::writePNG(const char *filename) const
+{
+ std::ofstream os(filename, std::ofstream::binary);
+ if (!os) {
+ return false;
+ }
+ return writePNG(os);
+}
+
+
+static void
+pngReadCallback(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ std::istream *os = (std::istream *) png_get_io_ptr(png_ptr);
+ os->read((char *)data, length);
+}
+
+
Image *
-readPNG(const char *filename)
+readPNG(std::istream &is)
{
- FILE *fp;
png_structp png_ptr;
png_infop info_ptr;
png_infop end_info;
+ unsigned channels;
Image *image;
- fp = fopen(filename, "rb");
- if (!fp)
- goto no_fp;
-
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr)
goto no_png;
goto no_png;
}
- png_init_io(png_ptr, fp);
+ png_set_read_fn(png_ptr, &is, pngReadCallback);
png_read_info(png_ptr, info_ptr);
&bit_depth, &color_type, &interlace_type,
&compression_type, &filter_method);
- image = new Image(width, height);
- if (!image)
- goto no_image;
-
/* Convert to RGBA8 */
if (color_type == PNG_COLOR_TYPE_PALETTE)
png_set_palette_to_rgb(png_ptr);
if (bit_depth == 16)
png_set_strip_16(png_ptr);
+ channels = png_get_channels(png_ptr, info_ptr);
+ image = new Image(width, height, channels);
+ if (!image)
+ goto no_image;
+
+ assert(png_get_rowbytes(png_ptr, info_ptr) == width*channels);
for (unsigned y = 0; y < height; ++y) {
- png_bytep row = (png_bytep)(image->pixels + y*width*4);
+ png_bytep row = (png_bytep)(image->pixels + y*width*channels);
png_read_row(png_ptr, row, NULL);
}
png_read_end(png_ptr, info_ptr);
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
- fclose(fp);
+
return image;
no_image:
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
no_png:
- fclose(fp);
-no_fp:
return NULL;
}
+Image *
+readPNG(const char *filename)
+{
+ std::ifstream is(filename, std::ifstream::binary);
+ if (!is) {
+ return NULL;
+ }
+ return readPNG(filename);
+}
} /* namespace image */