diff options
| -rw-r--r-- | FL/Fl_PNG_Image.H | 4 | ||||
| -rw-r--r-- | fluid/fluid.cxx | 2 | ||||
| -rw-r--r-- | src/fl_write_png.cxx | 66 |
3 files changed, 52 insertions, 20 deletions
diff --git a/FL/Fl_PNG_Image.H b/FL/Fl_PNG_Image.H index 21a01d16b..f0910a515 100644 --- a/FL/Fl_PNG_Image.H +++ b/FL/Fl_PNG_Image.H @@ -39,8 +39,8 @@ private: // Support functions to write PNG image files (since 1.4.0) -FL_EXPORT int fl_write_png(const char *filename, int w, int h, int d, const unsigned char *pixels); - FL_EXPORT int fl_write_png(const char *filename, Fl_RGB_Image *img); +FL_EXPORT int fl_write_png(const char *filename, const char *pixels, int w, int h, int d=3, int ld=0); +FL_EXPORT int fl_write_png(const char *filename, const unsigned char *pixels, int w, int h, int d=3, int ld=0); #endif diff --git a/fluid/fluid.cxx b/fluid/fluid.cxx index fdc005d42..4124aa3fa 100644 --- a/fluid/fluid.cxx +++ b/fluid/fluid.cxx @@ -348,7 +348,7 @@ void save_template_cb(Fl_Widget *, void *) { strcpy(ext, ".png"); errno = 0; - if (fl_write_png(filename, w, h, 3, pixels) != 0) { + if (fl_write_png(filename, pixels, w, h, 3) != 0) { delete[] pixels; fl_alert("Error writing %s: %s", filename, strerror(errno)); return; diff --git a/src/fl_write_png.cxx b/src/fl_write_png.cxx index e3fa56034..45e4da7ac 100644 --- a/src/fl_write_png.cxx +++ b/src/fl_write_png.cxx @@ -1,7 +1,7 @@ // // Fl_PNG_Image support functions for the Fast Light Tool Kit (FLTK). // -// Copyright 2021 by Bill Spitzak and others. +// Copyright 2005-2021 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -42,7 +42,7 @@ extern "C" { */ /** - Write a RGB(A) image to a PNG image file. + Write an RGB(A) image to a PNG image file. This is a very basic and restricted function to create a PNG image file from an RGB image (Fl_RGB_Image). @@ -53,16 +53,16 @@ extern "C" { The image file is always written with the original image size data_w() and data_h(), even if the image has been scaled. - Image depth 3 (RGB) and 4 (RGBA) are supported. + Image depth 1 (gray), 2 (gray + alpha channel), 3 (RGB) and 4 (RGBA) + are supported. - \note Behavior of grayscale images (depth 1 and 2) is currently undefined - and may or may not work. There is no error handling except for opening - the file. This function may be changed in the future. + \note Currently there is no error handling except for errors when opening + the file. This may be changed in the future. \param[in] filename Output filename, extension should be '.png' \param[in] img RGB image to be written - \return success (0) or error code + \return success (0) or error code: negative values are errors \retval 0 success, file has been written \retval -1 png or zlib library not available @@ -73,8 +73,20 @@ extern "C" { int fl_write_png(const char *filename, Fl_RGB_Image *img) { return fl_write_png(filename, - img->data_w(), img->data_h(), img->d(), - (const unsigned char *)img->data()[0]); + img->data()[0], + img->data_w(), + img->data_h(), + img->d(), + img->ld()); +} + +/** + Write raw image data to a PNG image file. + + \see fl_write_png(const char *filename, const char *pixels, int w, int h, int d, int ld) +*/ +int fl_write_png(const char *filename, const unsigned char *pixels, int w, int h, int d, int ld) { + return fl_write_png(filename, (const char *)pixels, w, h, d, ld); } /** @@ -83,44 +95,64 @@ int fl_write_png(const char *filename, Fl_RGB_Image *img) { This is a very basic and restricted function to create a PNG image file from raw image data, e.g. a screenshot. - The image data must be aligned w/o gaps after each row. + The image data must be aligned w/o gaps after each row (ld = 0 or ld = w * d) + or \p ld must be the total length of each row, i.e. w * d + gapsize. + If ld == 0 then ld = w * d is assumed. + + The total data size must be (w * d + gapsize) * h = ld' * h + where ld' = w * d if ld == 0. For further restrictions and return values please see fl_write_png(const char *filename, Fl_RGB_Image *img). \param[in] filename Output filename, extension should be '.png' + \param[in] pixels Image data \param[in] w Image data width \param[in] h Image data height - \param[in] d Image depth (3 = RGB, 4 = RGBA) - \param[in] pixels Image data (\p w * \p h * \p d bytes) + \param[in] d Image depth: 1 = GRAY, 2 = GRAY + alpha, 3 = RGB, 4 = RGBA + \param[in] ld Line delta: default (0) = w * d \return success (0) or error code, see ... \see fl_write_png(const char *filename, Fl_RGB_Image *img) - */ -int fl_write_png(const char *filename, int w, int h, int d, const unsigned char *pixels) { +*/ +int fl_write_png(const char *filename, const char *pixels, int w, int h, int d, int ld) { #if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ) FILE *fp; + int color_type; if ((fp = fl_fopen(filename, "wb")) == NULL) { return -2; } + switch (d) { + case 1: color_type = PNG_COLOR_TYPE_GRAY; break; + case 2: color_type = PNG_COLOR_TYPE_GRAY_ALPHA; break; + case 3: color_type = PNG_COLOR_TYPE_RGB; break; + case 4: color_type = PNG_COLOR_TYPE_RGB_ALPHA; break; + default: color_type = PNG_COLOR_TYPE_RGB; + } + + if (ld == 0) + ld = w * d; + png_structp pptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); png_infop iptr = png_create_info_struct(pptr); png_bytep ptr = (png_bytep)pixels; png_init_io(pptr, fp); png_set_IHDR(pptr, iptr, w, h, 8, - PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + color_type, + PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, + PNG_FILTER_TYPE_DEFAULT); png_set_sRGB(pptr, iptr, PNG_sRGB_INTENT_PERCEPTUAL); png_write_info(pptr, iptr); - for (int i = h; i > 0; i--, ptr += w * d) { + for (int i = 0; i < h; i++, ptr += ld) { png_write_row(pptr, ptr); } |
