X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=common%2Fimage_png.cpp;h=dba07d45ea14e4864d451b4896ea2723544a74b8;hb=c3fe91d4c597da17e1eb9e75d36176465f44060a;hp=41ef1768499fc4b7ed3db8636b304617ea7db737;hpb=45080ce539648a3fc073375cd9212b031a611f10;p=apitrace diff --git a/common/image_png.cpp b/common/image_png.cpp index 41ef176..dba07d4 100644 --- a/common/image_png.cpp +++ b/common/image_png.cpp @@ -43,34 +43,20 @@ namespace image { static const int png_compression_level = Z_BEST_SPEED; +static void +pngWriteCallback(png_structp png_ptr, png_bytep data, png_size_t length) +{ + std::ostream *os = (std::ostream *) png_get_io_ptr(png_ptr); + os->write((const char *)data, length); +} + bool -Image::writePNG(const char *filename) const { - FILE *fp; +Image::writePNG(std::ostream &os) const +{ png_structp png_ptr; png_infop info_ptr; - - fp = fopen(filename, "wb"); - if (!fp) - goto no_fp; - - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (!png_ptr) - goto no_png; - - info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { - png_destroy_write_struct(&png_ptr, NULL); - goto no_png; - } - - if (setjmp(png_jmpbuf(png_ptr))) { - png_destroy_write_struct(&png_ptr, &info_ptr); - goto no_png; - } - - png_init_io(png_ptr, fp); - int color_type; + switch (channels) { case 4: color_type = PNG_COLOR_TYPE_RGB_ALPHA; @@ -86,11 +72,29 @@ Image::writePNG(const char *filename) const { break; default: assert(0); - return false; + goto no_png; + } + + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!png_ptr) + goto no_png; + + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + png_destroy_write_struct(&png_ptr, NULL); + goto no_png; + } + + if (setjmp(png_jmpbuf(png_ptr))) { + png_destroy_write_struct(&png_ptr, &info_ptr); + goto no_png; } - png_set_IHDR(png_ptr, info_ptr, width, height, 8, color_type, - PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + png_set_write_fn(png_ptr, &os, pngWriteCallback, NULL); + + png_set_IHDR(png_ptr, info_ptr, width, height, 8, + color_type, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_set_compression_level(png_ptr, png_compression_level); @@ -112,12 +116,9 @@ Image::writePNG(const char *filename) const { png_write_end(png_ptr, info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr); - fclose(fp); return true; no_png: - fclose(fp); -no_fp: return false; } @@ -201,85 +202,5 @@ no_fp: } -static void -pngWriteCallback(png_structp png_ptr, png_bytep data, png_size_t length) -{ - std::ostream *os = (std::ostream *) png_get_io_ptr(png_ptr); - os->write((const char *)data, length); -} - -bool -writePixelsToBuffer(std::ostream &os, - unsigned char *pixels, - unsigned width, unsigned height, unsigned numChannels, - bool flipped) -{ - png_structp png_ptr; - png_infop info_ptr; - int type; - - switch (numChannels) { - case 4: - type = PNG_COLOR_TYPE_RGB_ALPHA; - break; - case 3: - type = PNG_COLOR_TYPE_RGB; - break; - case 2: - type = PNG_COLOR_TYPE_GRAY_ALPHA; - break; - case 1: - type = PNG_COLOR_TYPE_GRAY; - break; - default: - goto no_png; - } - - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (!png_ptr) - goto no_png; - - info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { - png_destroy_write_struct(&png_ptr, NULL); - goto no_png; - } - - if (setjmp(png_jmpbuf(png_ptr))) { - png_destroy_write_struct(&png_ptr, &info_ptr); - goto no_png; - } - - png_set_write_fn(png_ptr, &os, pngWriteCallback, NULL); - - png_set_IHDR(png_ptr, info_ptr, width, height, 8, - type, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - - png_set_compression_level(png_ptr, png_compression_level); - - png_write_info(png_ptr, info_ptr); - - if (!flipped) { - for (unsigned y = 0; y < height; ++y) { - png_bytep row = (png_bytep)(pixels + y*width*numChannels); - png_write_rows(png_ptr, &row, 1); - } - } else { - unsigned y = height; - while (y--) { - png_bytep row = (png_bytep)(pixels + y*width*numChannels); - png_write_rows(png_ptr, &row, 1); - } - } - - png_write_end(png_ptr, info_ptr); - png_destroy_write_struct(&png_ptr, &info_ptr); - - return true; - -no_png: - return false; -} } /* namespace image */