DO NOT REPLY TO THIS MESSAGE.  INSTEAD, POST ANY RESPONSES TO THE LINK BELOW.

[STR New]

Link: http://www.fltk.org/str.php?L2633
Version: 1.3-feature


Here is a patch to fltk 1.3 that add a static method for Fl_JPEG_Image and
Fl_PNG_Image to encode from Fl_Image to JPEG and PNG format on memory.


Link: http://www.fltk.org/str.php?L2633
Version: 1.3-feature
Index: FL/Fl_JPEG_Image.H
===================================================================
--- FL/Fl_JPEG_Image.H  (revision 8640)
+++ FL/Fl_JPEG_Image.H  (working copy)
@@ -44,6 +44,7 @@
 
   Fl_JPEG_Image(const char *filename);
   Fl_JPEG_Image(const char *name, const unsigned char *data);
+  static int encode(Fl_Image *img, int quality, unsigned char **outbuffer, int 
&outlen);
 };
 
 #endif
Index: FL/Fl_PNG_Image.H
===================================================================
--- FL/Fl_PNG_Image.H   (revision 8640)
+++ FL/Fl_PNG_Image.H   (working copy)
@@ -44,6 +44,7 @@
 
   Fl_PNG_Image(const char* filename);
   Fl_PNG_Image (const char *name_png, const unsigned char *buffer, int 
datasize);
+  static int encode(Fl_Image *img, unsigned char **outbuffer, int &outlen);
 private:
   void load_png_(const char *name_png, const unsigned char *buffer_png, int 
datasize);
 };
Index: src/Fl_JPEG_Image.cxx
===================================================================
--- src/Fl_JPEG_Image.cxx       (revision 8640)
+++ src/Fl_JPEG_Image.cxx       (working copy)
@@ -376,6 +376,62 @@
 #endif // HAVE_LIBJPEG
 }
 
+int Fl_JPEG_Image::encode(Fl_Image *img, int quality,
+                        unsigned char **outbuffer, int &outlen){
+#ifdef HAVE_LIBJPEG
+    int imgw = img->w(), imgh = img->h(), imgd = img->d();
+    outlen = imgw * imgh * imgd;
+
+    struct jpeg_compress_struct cinfo = {0};
+       struct jpeg_error_mgr       jerr;
+
+    if (imgd == 3) cinfo.in_color_space = JCS_RGB;
+    else if (imgd == 1) cinfo.in_color_space = JCS_GRAYSCALE;
+    else return -1;
+
+
+    *outbuffer = NULL;
+    unsigned long sz_outlen = 0;
+
+       /* create our in-memory output buffer to hold the jpeg */
+       *outbuffer   = (unsigned char *) malloc(outlen+8*1024); //safe margin
+
+       cinfo.err = jpeg_std_error(&jerr);
+       jpeg_create_compress(&cinfo);
+       jpeg_mem_dest(&cinfo, outbuffer, &sz_outlen);
+
+       cinfo.image_width      = imgw;
+       cinfo.image_height     = imgh;
+       cinfo.input_components = imgd;
+
+       jpeg_set_defaults(&cinfo);
+       jpeg_set_quality (&cinfo, quality, true);
+       jpeg_start_compress(&cinfo, true);
+
+       uchar * row_pointer;
+       uchar *idata    = (uchar *)img->data()[0];
+
+       /* main code to write jpeg data */
+       int iwd = imgw * imgd;
+    while (cinfo.next_scanline < cinfo.image_height) {
+        row_pointer = idata + cinfo.next_scanline * iwd;
+        (void) jpeg_write_scanlines(&cinfo, &row_pointer, 1);
+    }
+       jpeg_finish_compress(&cinfo);
+       jpeg_destroy_compress(&cinfo);
+       outlen = sz_outlen;
+
+//     FILE* outfile = fopen("test.jpeg", "wb");
+//     if (outfile){
+//         fwrite(*outbuffer, outlen,1 ,outfile);
+//         fclose(outfile);
+//     }
+       return 0;
+#else
+    return -1;
+#endif // HAVE_LIBJPEG
+}
+
 //
 // End of "$Id$".
 //
Index: src/Fl_PNG_Image.cxx
===================================================================
--- src/Fl_PNG_Image.cxx        (revision 8640)
+++ src/Fl_PNG_Image.cxx        (working copy)
@@ -218,7 +218,115 @@
 #endif // HAVE_LIBPNG && HAVE_LIBZ
 }
 
+#if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ)
+/* structure to store PNG image bytes */
+typedef struct {
+  uchar *buffer;
+  size_t size;
+  size_t size_allocated;
+} mem_encode;
 
+
+void my_png_write_data(png_structp png_ptr, png_bytep data, png_size_t length){
+  mem_encode* p=(mem_encode*)png_get_io_ptr(png_ptr);
+  size_t nsize = p->size + length;
+
+  /* allocate or grow buffer */
+  if(nsize > p->size_allocated){
+      int alloc_size = nsize * 2;
+      if(p->buffer)
+        p->buffer = (uchar*)realloc(p->buffer, alloc_size);
+      else
+        p->buffer = (uchar*)malloc(alloc_size);
+
+      if(!p->buffer) {
+        png_error(png_ptr, "Write Error");
+        return;
+      }
+      p->size_allocated = alloc_size;
+  }
+
+  /* copy new bytes to end of buffer */
+  memcpy(p->buffer + p->size, data, length);
+  p->size += length;
+}
+
+/* This is optional but included to show how png_set_write_fn() is called */
+void my_png_flush(png_structp png_ptr){}
+#endif // HAVE_LIBPNG && HAVE_LIBZ
+
+int Fl_PNG_Image::encode(Fl_Image *img, unsigned char **outbuffer, int 
&outlen){
+#if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ)
+    int imgw = img->w(), imgh = img->h(), imgd = img->d();
+    outlen = imgw * imgh * imgd;
+
+    png_structp                        pp;             // PNG data
+    png_infop                  info;           // PNG image info
+    mem_encode state;
+    /* initialise - put this before png_write_png() call */
+    state.buffer = NULL;
+    state.size = 0;
+    state.size_allocated = 0;
+
+
+    if( !((imgd == 1) || (imgd ==3) || (imgd ==4))) return -1;
+    pp = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
+    if(!pp) return -1;
+
+    info = png_create_info_struct(pp);
+    if (!info){
+        png_destroy_write_struct(&pp, 0);
+        return -1;
+    }
+
+    if (setjmp(png_jmpbuf(pp))){
+        png_destroy_write_struct(&pp, &info);
+        return -1;
+    }
+
+    //png_init_io(pp, fp);
+    /* if my_png_flush() is not needed, change the arg to NULL */
+    png_set_write_fn(pp, &state, my_png_write_data, my_png_flush);
+
+
+    png_set_compression_level(pp, Z_BEST_COMPRESSION);
+    png_set_IHDR(pp, info, imgw, imgh, 8,
+               imgd == 1 ? PNG_COLOR_TYPE_GRAY : PNG_COLOR_TYPE_RGB,
+           PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
+           PNG_FILTER_TYPE_DEFAULT);
+    png_set_sRGB(pp, info, PNG_sRGB_INTENT_PERCEPTUAL);
+    png_set_sRGB_gAMA_and_cHRM(pp, info, PNG_INFO_sRGB);
+
+    png_write_info(pp, info);
+
+    uchar *idata = (uchar *)img->data()[0];
+    int iwd = imgw * imgd;
+
+    for (int y = 0; y < imgh; y++)
+    {
+        png_write_row(pp, (png_byte *)(idata + y * iwd));
+    }
+
+    png_write_end(pp, info);
+    png_destroy_write_struct(&pp, 0);
+
+    /* cleanup */
+    //if(state.buffer) free(state.buffer);
+
+    *outbuffer = state.buffer;
+       outlen = state.size;
+
+//     FILE* outfile = fopen("test.png", "wb");
+//     if (outfile){
+//         fwrite(*outbuffer, outlen,1 ,outfile);
+//         fclose(outfile);
+//     }
+       return 0;
+#else
+    return -1;
+#endif // HAVEHAVE_LIBPNG && HAVE_LIBZ
+}
+
 //
 // End of "$Id$".
 //
_______________________________________________
fltk-dev mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-dev

Reply via email to