> On 10/19/2009 11:16 PM, D. Zimmer wrote:
> >>> Hello all,
> >>>
> >>> probably this has come up before, but I can't find it:
> >>>
> >>> my application has to display JPEG images, but does not load
> >>> them from disk files. They come in as blobs from a remote database.
> >>>
> >>> Is there a way to load these into an Fl_JPEG_image?
> >>>
> >>> Right now I am reduced to writing them to a temp file, and then reading
> >>> that into the image. But that is a bad solution: it assumes that I can
> >>> write to disk in this application.
> >>>
> >>> I read the code (fltk 1.1.9), there doesn't seem to be a straightforward
> >>> way, can't just hook up an istream, or something of that nature.
> >>>
> >>> Any advice?
> >>>
> >>>
> >>
> >> I expect you will have to modify Fl_JPEG_Image. FLTK 1.1.9 has
> >> Fl_JPEG_Image(const char *jpeg) which is hard-coded to expect a filename.
> >> Write a new constructor that takes your blob of JPEG data instead, and
> >> base it on the existing code from Fl_JPEG_Image.
> >>
> >> I'm pretty sure this can be done, and I think you will need to make the
> >> following changes:
> >>
> >> 1. get rid of references to the FILE pointer in the function (declaration,
> >> fopen(), flose()).
> >>
> >> 2. replace the call to jpeg_stdio_src() with code to fill the
> >> jpeg_decompress_struct with function pointers that will operate on your
> >> blob of JPEG data rather than a FILE pointer.
> >>
> >> I've never done it, but I expect you should be able to find examples on
> >> the internet... if not, how hard could it be (memcpy(), current position
> >> pointer, etc.)? If you download the actual jpeglib full source, the file
> >> djpeg.c provides function pointers for setting up the library to handle
> >> FILE pointer streams... work from that.
> >>
> >> You're probably in for a a few hours coding and testing though.
> >>
> >> good luck,
> >> Don.
> >>
> >>
> >>
> >
> > sorry, not djpeg.c but jdatasrc.c, which is part of the jpeg library
> > included with FLTK.
> >
>
> Thanks Don,
>
> Yes I saw that. On first reading, it seems that jdatasrc.c needs to be
> modified in maybe 2 lines of code. Where the data come from doesn't
> seem to make much difference, except for 2 calls to read(). But I'll try
> that in the day :)
>
> Probably I will make a new class, parallel to Fl_JPEG_image.
> FL_JPEG_image only provides a constructor (at least in 1.1.9), nothing
> else. That's reasonably clean. The uglier part is ending up with
> something new that is more part of jpeglib than of fltk. Which is
> probably why this hasn't been done yet, at least in public.
>
>
> Bernd
>
>
>
I wouldn't think that the library would need to be changed... I think the
library allows you to do what you want to achieve, as-is. I meant to use
jdatasrc.c as a possible quide for your class.
Don.
Here is a quick modfication of code from jdatasrc.c, that you would add to your
modified class, then just call jpeg_blob_src() in place of jpeg_stdio_src() in
the constructor... never tested or compiled, or really thought out for that
matter.
// most comments striped
#include "jinclude.h"
#include "jpeglib.h"
#include "jerror.h"
typedef struct {
struct jpeg_source_mgr pub; /* public fields */
void *blob; /* address of blob */
size_t size; /* size into blob */
size_t pos; /* index into blob */
JOCTET * buffer; /* start of buffer */
boolean start_of_file; /* have we gotten any data yet? */
} my_source_mgr;
typedef my_source_mgr * my_src_ptr;
#define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */
static void init_source (j_decompress_ptr cinfo)
{
my_src_ptr src = (my_src_ptr) cinfo->src;
src->start_of_file = TRUE;
}
static boolean fill_input_buffer (j_decompress_ptr cinfo)
{
my_src_ptr src = (my_src_ptr) cinfo->src;
size_t nbytes;
nbytes = MAX(src->size - src->pos, INPUT_BUF_SIZE);
src->size -= nbytes;
if (nbytes <= 0) {
if (src->start_of_file) /* Treat empty input file as fatal error */
ERREXIT(cinfo, JERR_INPUT_EMPTY);
WARNMS(cinfo, JWRN_JPEG_EOF);
/* Insert a fake EOI marker */
src->buffer[0] = (JOCTET) 0xFF;
src->buffer[1] = (JOCTET) JPEG_EOI;
nbytes = 2;
}
src->pub.next_input_byte = src->buffer;
src->pub.bytes_in_buffer = nbytes;
src->start_of_file = FALSE;
return TRUE;
}
static void skip_input_data (j_decompress_ptr cinfo, long num_bytes)
{
my_src_ptr src = (my_src_ptr) cinfo->src;
if (num_bytes > 0) {
while (num_bytes > (long) src->pub.bytes_in_buffer) {
num_bytes -= (long) src->pub.bytes_in_buffer;
(void) fill_input_buffer(cinfo);
/* note we assume that fill_input_buffer will never return FALSE,
* so suspension need not be handled.
*/
}
src->pub.next_input_byte += (size_t) num_bytes;
src->pub.bytes_in_buffer -= (size_t) num_bytes;
}
}
static void term_source (j_decompress_ptr cinfo)
{
/* no work necessary here */
}
extern void jpeg_blob_src (j_decompress_ptr cinfo, void *blob, size_t size)
{
my_src_ptr src;
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->buffer = (JOCTET *)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
INPUT_BUF_SIZE * SIZEOF(JOCTET));
}
src = (my_src_ptr) cinfo->src;
src->pub.init_source = init_source;
src->pub.fill_input_buffer = fill_input_buffer;
src->pub.skip_input_data = skip_input_data;
src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
src->pub.term_source = term_source;
src->blob = blob;
src->size = size;
src->pos = 0;
src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
src->pub.next_input_byte = NULL; /* until buffer loaded */
}
_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk