Again thanks for your attention !

I read the post you mentioned and it is a good explanation and my code  
seem to follow it.

Here it's the my code again but without attachments:

------

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 = outlen+8*1024; //safe margin to avoid  
reallocations

        /* create our in-memory output buffer to hold the jpeg */
        *outbuffer   = (unsigned char *) malloc(sz_outlen); //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
}

------

#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
}
-----


# data file for the Fltk User Interface Designer (fluid)
version 1.0300
header_name {.h}
code_name {.cxx}
decl {\#include <FL/Fl_Shared_Image.H>} {private local
}

decl {\#include <FL/Fl_JPEG_Image.H>} {private local
}

decl {\#include <FL/Fl_PNG_Image.H>} {private local
}

decl {\#include <FL/Fl_File_Chooser.H>} {private local
}

decl {Fl_Image *img_loaded = 0;} {private local
}

decl {Fl_Image *img_saved = 0;} {private local
}

decl {unsigned char *memory_img = 0;} {selected private local
}

decl {int memory_img_len = 0;} {selected private local
}

Function {load_image(Fl_Widget *w)} {open return_type void
} {
   code {char *img_fname = fl_file_chooser("Image file?","*.{jpg,png}", "");
     if(img_fname){
       btnLoaded->image(0);
       btnSaved->image(0);
       delete(img_loaded);
       delete(img_saved);
       if(memory_img){
         free(memory_img);
         memory_img = 0;
         memory_img_len = 0;
       }

       const char * img_ext = fl_filename_ext(img_fname);
       printf("%s:%s\\n",img_fname, img_ext);
       if(stricmp(img_ext, ".jpg") == 0){
           printf("%s is jpg\\n",img_fname);
           img_loaded = new Fl_JPEG_Image(img_fname);
           int result = Fl_JPEG_Image::encode(img_loaded, 85, &memory_img,  
memory_img_len);
           printf("%d:%d\\n", result, memory_img_len);
           if(result == 0){
             img_saved = new Fl_JPEG_Image("simgjpg", memory_img);
           }
       } else if(stricmp(img_ext, ".png") == 0){
           printf("%s is png\\n",img_fname);
           img_loaded = new Fl_PNG_Image(img_fname);
           int result = Fl_PNG_Image::encode(img_loaded, &memory_img,  
memory_img_len);
           printf("%d:%d\\n", result, memory_img_len);
           if(result == 0){
             img_saved = new Fl_PNG_Image("simgpng", memory_img,  
memory_img_len);
           }
       }
       btnLoaded->image(img_loaded);
       btnLoaded->redraw();
       btnSaved->image(img_saved);
       btnSaved->redraw();
     }} {}
}

Function {} {open
} {
   code {fl_register_images();} {}
   Fl_Window {} {
     label {Image Load & Save} open
     xywh {56 119 553 337} type Double visible
   } {
     Fl_Button btnLoaded {
       label Loaded
       callback {load_image(o);}
       dirty_name btnLoaded
       xywh {20 30 235 240} align 64
     }
     Fl_Button btnSaved {
       label Saved
       dirty_name btnSaved
       xywh {295 30 235 240} align 64
     }
   }
}
_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk

Reply via email to