Author: manolo
Date: 2011-01-17 12:51:12 -0800 (Mon, 17 Jan 2011)
New Revision: 8287
Log:
Fix 2nd part of STR #2520: added Fl_PNG_Image in-memory constructor.
This constructor has a 3rd argument, the size of the array holding the 
in-memory PNG image.
This allows the constructor to check for errors in the image.

Modified:
   branches/branch-1.3/FL/Fl_PNG_Image.H
   branches/branch-1.3/src/Fl_PNG_Image.cxx

Modified: branches/branch-1.3/FL/Fl_PNG_Image.H
===================================================================
--- branches/branch-1.3/FL/Fl_PNG_Image.H       2011-01-17 09:39:14 UTC (rev 
8286)
+++ branches/branch-1.3/FL/Fl_PNG_Image.H       2011-01-17 20:51:12 UTC (rev 
8287)
@@ -40,9 +40,12 @@
 */
 class FL_EXPORT Fl_PNG_Image : public Fl_RGB_Image {
 
-  public:
+public:
 
   Fl_PNG_Image(const char* filename);
+  Fl_PNG_Image (const char *name_png, const unsigned char *buffer, int 
datasize);
+private:
+  void load_png_(const char *name_png, const unsigned char *buffer_png, int 
datasize);
 };
 
 #endif

Modified: branches/branch-1.3/src/Fl_PNG_Image.cxx
===================================================================
--- branches/branch-1.3/src/Fl_PNG_Image.cxx    2011-01-17 09:39:14 UTC (rev 
8286)
+++ branches/branch-1.3/src/Fl_PNG_Image.cxx    2011-01-17 20:51:12 UTC (rev 
8287)
@@ -42,50 +42,96 @@
 #include <stdlib.h>
 #include <FL/fl_utf8.h>
 
+#if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ)
 extern "C"
 {
-#if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ)
 #  include <zlib.h>
 #  ifdef HAVE_PNG_H
 #    include <png.h>
 #  else
 #    include <libpng/png.h>
 #  endif // HAVE_PNG_H
-#endif // HAVE_LIBPNG && HAVE_LIBZ
 }
 
+typedef struct  {
+  png_structp pp;
+  const unsigned char *current;
+  const unsigned char *last;
+} fl_png_memory;
 
+static void png_read_data_from_mem( png_structp png_ptr, //pointer to our data
+                                  png_bytep data,  // where to copy the image 
data for libpng computing
+                                  png_size_t length) // length of data to copy
+{
+  fl_png_memory *png_mem_data = (fl_png_memory*)png_get_io_ptr(png_ptr); // 
get the pointer to our struct
+  if (png_mem_data->current + length > png_mem_data->last) {
+    png_error(png_mem_data->pp, "Invalid attempt to read row data");
+    return;
+  }
+  /* copy data from image buffer */
+  memcpy (data, png_mem_data->current, length);
+  /* advance in the memory data */
+  png_mem_data->current += length;
+}
+#endif // HAVE_LIBPNG && HAVE_LIBZ
+
+
 /**
   The constructor loads the named PNG image from the given png filename.
-  <P>The destructor free all memory and server resources that are used by
+  <P>The destructor frees all memory and server resources that are used by
   the image.
 */
-Fl_PNG_Image::Fl_PNG_Image(const char *png) // I - File to read
-  : Fl_RGB_Image(0,0,0) {
+Fl_PNG_Image::Fl_PNG_Image (const char *filename): Fl_RGB_Image(0,0,0)
+{
+  load_png_(filename, NULL, 0);
+}
+
+/** Constructor that reads a PNG image from memory.
+ \param name_png  A name given to this image
+ \param        buffer    Pointer to the start of the PNG image in memory
+ \param maxsize  Size in bytes of the memory buffer containing the PNG image
+ */
+Fl_PNG_Image::Fl_PNG_Image (
+      const char *name_png, const unsigned char *buffer, int maxsize): 
Fl_RGB_Image(0,0,0)
+{
+  load_png_(name_png, buffer, maxsize);
+}
+
+void Fl_PNG_Image::load_png_(const char *name_png, const unsigned char 
*buffer_png, int maxsize)
+{
 #if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ)
-  int          i;                      // Looping var
-  FILE         *fp;                    // File pointer
-  int          channels;               // Number of color channels
-  png_structp  pp;                     // PNG read pointer
-  png_infop    info;                   // PNG info pointers
-  png_bytep    *rows;                  // PNG row pointers
+  int i;         // Looping var
+  FILE *fp;      // File pointer
+  int channels;          // Number of color channels
+  png_structp pp; // PNG read pointer
+  png_infop info; // PNG info pointers
+  png_bytep *rows;// PNG row pointers
+  fl_png_memory png_mem_data;
+  int from_memory = (buffer_png != NULL); // true iff reading image from memory
 
+  if (!from_memory) {
+    if ((fp = fl_fopen(name_png, "rb")) == NULL) return;
+  }
 
-  // Open the PNG file...
-  if ((fp = fl_fopen(png, "rb")) == NULL) return;
-
   // Setup the PNG data structures...
   pp   = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
   info = png_create_info_struct(pp);
 
   if (setjmp(png_jmpbuf(pp)))
   {
-    Fl::warning("PNG file \"%s\" contains errors!\n", png);
+    Fl::warning("PNG file \"%s\" contains errors!\n", name_png);
     return;
   }
 
-  // Initialize the PNG read "engine"...
-  png_init_io(pp, fp);
+  if (from_memory) {
+    png_mem_data.current = buffer_png;
+    png_mem_data.last = buffer_png + maxsize;
+    png_mem_data.pp = pp;
+    // Initialize the function pointer to the PNG read "engine"...
+    png_set_read_fn (pp, (png_voidp) &png_mem_data, png_read_data_from_mem);
+  } else {
+    png_init_io(pp, fp); // Initialize the PNG file read "engine"...
+  }  
 
   // Get the image dimensions and convert to grayscale or RGB...
   png_read_info(pp, info);
@@ -101,7 +147,7 @@
   int num_trans = 0;
   png_get_tRNS(pp, info, 0, &num_trans, 0);
   if ((png_get_color_type(pp, info) & PNG_COLOR_MASK_ALPHA) || (num_trans != 
0))
-      channels ++;
+    channels ++;
 
   w((int)(png_get_image_width(pp, info)));
   h((int)(png_get_image_height(pp, info)));
@@ -150,7 +196,7 @@
   png_read_end(pp, info);
   png_destroy_read_struct(&pp, &info, NULL);
 
-  fclose(fp);
+  if (!from_memory) fclose(fp);
 #endif // HAVE_LIBPNG && HAVE_LIBZ
 }
 

_______________________________________________
fltk-commit mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-commit

Reply via email to