X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=image%2Fimage_png.cpp;h=324cfe9814ee53ccbc8842fed32b0ca245b56329;hb=59889aafe642e52742524da2c202a1003643fa94;hp=dba07d45ea14e4864d451b4896ea2723544a74b8;hpb=9db16b3989481f8d6dfc8932d760fcc16217ecbd;p=apitrace diff --git a/image/image_png.cpp b/image/image_png.cpp index dba07d4..324cfe9 100644 --- a/image/image_png.cpp +++ b/image/image_png.cpp @@ -123,19 +123,34 @@ no_png: } +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; @@ -157,7 +172,7 @@ readPNG(const char *filename) goto no_png; } - png_init_io(png_ptr, fp); + png_set_read_fn(png_ptr, &is, pngReadCallback); png_read_info(png_ptr, info_ptr); @@ -169,10 +184,6 @@ readPNG(const char *filename) &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); @@ -183,24 +194,37 @@ readPNG(const char *filename) 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 */