FLTK logo

[master] 6d1f560 - Support all image depths (1-4) in fl_write_png()

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 All Forums  |  Back to fltk.commit  ]
 
Previous Message ]Next Message ]

[master] 6d1f560 - Support all image depths (1-4) in fl_write_png() "Albrecht Schlosser" Nov 11, 2021  
 
commit 6d1f5608ba155e57e7f9efb7925de634e59e7369
Author:     Albrecht Schlosser <albrechts.fltk@online.de>
AuthorDate: Thu Nov 11 20:58:09 2021 +0100
Commit:     Albrecht Schlosser <albrechts.fltk@online.de>
CommitDate: Thu Nov 11 20:58:09 2021 +0100

    Support all image depths (1-4) in fl_write_png()

 FL/Fl_PNG_Image.H    |  4 ++--
 fluid/fluid.cxx      |  2 +-
 src/fl_write_png.cxx | 66 ++++++++++++++++++++++++++++++++++++++--------------
 3 files changed, 52 insertions(+), 20 deletions(-)

diff --git FL/Fl_PNG_Image.H FL/Fl_PNG_Image.H
index 21a01d1..f0910a5 100644
--- FL/Fl_PNG_Image.H
+++ 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 fluid/fluid.cxx fluid/fluid.cxx
index fdc005d..4124aa3 100644
--- fluid/fluid.cxx
+++ 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 src/fl_write_png.cxx src/fl_write_png.cxx
index e3fa560..45e4da7 100644
--- src/fl_write_png.cxx
+++ 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);
   }
 
Direct Link to Message ]
 
     
Previous Message ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.