]> git.cworth.org Git - apitrace/blobdiff - common/image_png.cpp
os: Use CLOCK_MONOTONIC
[apitrace] / common / image_png.cpp
index cc6d3f2cc4d7ff6e476db9df609a5148e27a6546..dba07d45ea14e4864d451b4896ea2723544a74b8 100644 (file)
@@ -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_set_IHDR(png_ptr, info_ptr, width, height, 8, color_type,
-        PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+    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,
+                 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,115 +202,5 @@ no_fp:
 }
 
 
-struct png_tmp_buffer
-{
-    char *buffer;
-    size_t size;
-};
-
-static void
-pngWriteCallback(png_structp png_ptr, png_bytep data, png_size_t length)
-{
-    struct png_tmp_buffer *buf = (struct png_tmp_buffer*) png_get_io_ptr(png_ptr);
-    size_t nsize = buf->size + length;
-
-    /* allocate or grow buffer */
-    if (buf->buffer)
-        buf->buffer = (char*)realloc(buf->buffer, nsize);
-    else
-        buf->buffer = (char*)malloc(nsize);
-
-    if (!buf->buffer)
-        png_error(png_ptr, "Buffer allocation error");
-
-    memcpy(buf->buffer + buf->size, data, length);
-    buf->size += length;
-}
-
-bool writePixelsToBuffer(unsigned char *pixels,
-                         unsigned width, unsigned height, unsigned numChannels,
-                         bool flipped,
-                         char **buffer,
-                         int *size)
-{
-    struct png_tmp_buffer png_mem;
-    png_structp png_ptr;
-    png_infop info_ptr;
-    int type;
-
-    png_mem.buffer = NULL;
-    png_mem.size = 0;
-
-    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, &png_mem, 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);
-
-    *buffer = png_mem.buffer;
-    *size = png_mem.size;
-
-    return true;
-
-no_png:
-    *buffer = NULL;
-    *size = 0;
-
-    if (png_mem.buffer)
-        free(png_mem.buffer);
-    return false;
-}
 
 } /* namespace image */