> For simplicity reason I like to carry the jpeg image inside the binary.
> So I have a data pointer and size of a copy of jpeg file represented
> inside the program.
>
> Is there a way to utilize the FLTK functionality with Fl_JPEG_Image?
> Fl_JPEG_Image typically wants a filename.
> Is there a way to tell Fl_JPEG_Image to point it to internal memory?
>
>
>

Had the same problem (some time before FLTK 1.3 occurred).
So I wrote (cut copy paste) my own class (for FLTK 1.1.10), that did the job. 
It is probably not complete coded as it is in FLTK 1.3 but perhaps it might 
help.
Rainer

Here it is:

The .h file:
//
// JPEG image header file for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2005 by Bill Spitzak and others.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
// Please report all bugs and problems on the following page:
//
//     http://www.fltk.org/str.php
//

#ifndef my_JPEG_Image_H
#define my_JPEG_Image_H
#  include "FL/Fl_Image.H"

class FL_EXPORT my_JPEG_Image : public Fl_RGB_Image {

  public:

  my_JPEG_Image(const unsigned char* data, int size);
};

#endif


.. and the *.cxx file:
//
// Fl_JPEG_Image routines.
//
// Copyright 1997-2005 by Easy Software Products.
// Image support donated by Matthias Melcher, Copyright 2000.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
// Please report all bugs and problems on the following page:
//
//     http://www.fltk.org/str.php
//
// Contents:
//
//   Fl_JPEG_Image::Fl_JPEG_Image() - Load a JPEG image file.
//

//
// Include necessary header files...
//

#include "my_JPEG_Image.H"
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>


// Some releases of the Cygwin JPEG libraries don't have a correctly
// updated header file for the INT32 data type; the following define
// from Shane Hill seems to be a usable workaround...

#if defined(WIN32) && defined(__CYGWIN__)
#  define XMD_H
#endif // WIN32 && __CYGWIN__


extern "C"
{
#ifdef HAVE_LIBJPEG
#  include <jpeglib.h>
#endif // HAVE_LIBJPEG
}


//
// Custom JPEG error handling structure...
//

#ifdef HAVE_LIBJPEG
struct fl_jpeg_error_mgr {
  jpeg_error_mgr        pub_;           // Destination manager...
  jmp_buf               errhand_;       // Error handler
};
#endif // HAVE_LIBJPEG


//
// Error handler for JPEG files...
//

#ifdef HAVE_LIBJPEG
extern "C" {
  static void
  fl_jpeg_error_handler(j_common_ptr dinfo) {   // I - Decompressor info
    longjmp(((fl_jpeg_error_mgr *)(dinfo->err))->errhand_, 1);
  }

  static void
  fl_jpeg_output_handler(j_common_ptr) {        // I - Decompressor info (not 
used)
  }
}
#endif // HAVE_LIBJPEG

/*
 * This is the equivalent code for a decompression source manager getting data 
from memory
 * The main routine my_JPEG_Image was built analogous to FL_JPEG_Image; so its 
structure
 * is nearly unchanged.
 * According to the libjpeg-documentation the routines of the 'data source 
manager'
 * were replaced:
 *      init_source by mem_init_source,
 *      fill_input_buffer by mem_fill_input_buffer,
 *      skip_input_data by mem_skip_input_data,
 *      (resync_to_restart remained unchanged) and
 *      term_source by mem_term_source.
 * And of course the original jpeg_stdio_src routine was replaced by a 
jpeg_mem_src function,
 * making all new functions to be used by the libjpeg.
 *
 */

typedef struct {
  struct jpeg_source_mgr pub;   /* public fields */
  JOCTET * buffer;                              /* start of buffer */
} my_source_mgr;

typedef my_source_mgr * my_src_ptr;

METHODDEF(void)
mem_init_source (j_decompress_ptr cinfo)
{
        // nothing to do
}

METHODDEF(boolean)
mem_fill_input_buffer (j_decompress_ptr cinfo)
{
  /*
   * nothing to do
  */
  return TRUE;
}

METHODDEF(void)
mem_skip_input_data (j_decompress_ptr cinfo, long num_bytes)
{
        // nothing to do ??
}

METHODDEF(void)
mem_term_source (j_decompress_ptr cinfo)
{
  /* no work necessary here */
}



GLOBAL(void)
jpeg_mem_src (j_decompress_ptr cinfo, const unsigned char *jdata, const int sz)
{
  my_src_ptr src;

  /* The source object is assumed to be completely given in jdata, its size is 
sz bytes.
   */
  if (cinfo->src == NULL) {     /* first time for this JPEG object? */
    cinfo->src = (struct jpeg_source_mgr *)
      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
                                  sizeof(my_source_mgr));
    src = (my_src_ptr) cinfo->src;
  }
  src = (my_src_ptr) cinfo->src;
  src->buffer = (JOCTET *) jdata;

  src->pub.init_source = mem_init_source;
  src->pub.fill_input_buffer = mem_fill_input_buffer;
  src->pub.skip_input_data = mem_skip_input_data;
  src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
  src->pub.term_source = mem_term_source;

  src->pub.bytes_in_buffer = sz; /* bytes in buffer */
  src->pub.next_input_byte = src->buffer; /* until buffer loaded */
}


//
// 'Fl_JPEG_Image::Fl_JPEG_Image()' - Load a JPEG from memory.
//

my_JPEG_Image::my_JPEG_Image(const unsigned char *jdata, int sz)
  : Fl_RGB_Image(0,0,0) {
#ifdef HAVE_LIBJPEG
  jpeg_decompress_struct        dinfo;  // Decompressor info
  fl_jpeg_error_mgr             jerr;   // Error handler info
  JSAMPROW                      row;    // Sample row pointer

  // the following variables are pointers allocating some private space that
  // is not reset by 'setjmp()'
  char* max_finish_decompress_err;      // count errors and give up afer a while
  char* max_destroy_decompress_err;     // to avoid recusion and deadlock

  // Clear data...
  alloc_array = 0;
  array = (uchar *)0;

  if (!jdata || !sz) return;

  // Setup the decompressor info and read the header...
  dinfo.err                = jpeg_std_error((jpeg_error_mgr *)&jerr);
  jerr.pub_.error_exit     = fl_jpeg_error_handler;
  jerr.pub_.output_message = fl_jpeg_output_handler;

  // Setup error loop variables
  max_finish_decompress_err = (char*)malloc(1);   // allocate space on the 
frame for error counters
  max_destroy_decompress_err = (char*)malloc(1);  // otherwise, the variables 
are reset on the longjmp
  *max_finish_decompress_err=10;
  *max_destroy_decompress_err=10;

  if (setjmp(jerr.errhand_))
  {
    // JPEG error handling...
    // if any of the cleanup routines hits another error, we would end up
    // in a loop. So instead, we decrement max_err for some upper cleanup limit.
    if ( ((*max_finish_decompress_err)-- > 0) && array)
      jpeg_finish_decompress(&dinfo);
    if ( (*max_destroy_decompress_err)-- > 0)
      jpeg_destroy_decompress(&dinfo);

    w(0);
    h(0);
    d(0);

    if (array) {
      delete[] (uchar *)array;
      array = 0;
      alloc_array = 0;
    }

    free(max_destroy_decompress_err);
    free(max_finish_decompress_err);

    return;
  }

  jpeg_create_decompress(&dinfo);
  jpeg_mem_src(&dinfo, jdata, sz);
  jpeg_read_header(&dinfo, 1);

  dinfo.quantize_colors      = (boolean)FALSE;
  dinfo.out_color_space      = JCS_RGB;
  dinfo.out_color_components = 3;
  dinfo.output_components    = 3;

  jpeg_calc_output_dimensions(&dinfo);

  w(dinfo.output_width);
  h(dinfo.output_height);
  d(dinfo.output_components);

  array = new uchar[w() * h() * d()];
  alloc_array = 1;

  jpeg_start_decompress(&dinfo);

  while (dinfo.output_scanline < dinfo.output_height) {
    row = (JSAMPROW)(array +
                     dinfo.output_scanline * dinfo.output_width *
                     dinfo.output_components);
    jpeg_read_scanlines(&dinfo, &row, (JDIMENSION)1);
  }

  jpeg_finish_decompress(&dinfo);
  jpeg_destroy_decompress(&dinfo);

  free(max_destroy_decompress_err);
  free(max_finish_decompress_err);

#endif // HAVE_LIBJPEG
}


_______________________________________________
fltk mailing list
fltk@easysw.com
http://lists.easysw.com/mailman/listinfo/fltk

Reply via email to