struct _JPEG_error_mgr
{
- struct jpeg_error_mgr pub;
- jmp_buf setjmp_buffer;
+ struct jpeg_error_mgr pub;
+ jmp_buf setjmp_buffer;
};
+struct jpeg_membuf_src {
+ struct jpeg_source_mgr pub;
+
+ const char *buf;
+ size_t len;
+};
+
+static void
+_eet_jpeg_membuf_src_init(j_decompress_ptr cinfo)
+{
+}
+
+static boolean
+_eet_jpeg_membuf_src_fill(j_decompress_ptr cinfo)
+{
+ static const JOCTET jpeg_eoi[2] = { 0xFF, JPEG_EOI };
+ struct jpeg_membuf_src *src = (struct jpeg_membuf_src *)cinfo->src;
+
+ src->pub.bytes_in_buffer = sizeof(jpeg_eoi);
+ src->pub.next_input_byte = jpeg_eoi;
+
+ return TRUE;
+}
+
+static void
+_eet_jpeg_membuf_src_skip(j_decompress_ptr cinfo, long num_bytes)
+{
+ struct jpeg_membuf_src *src = (struct jpeg_membuf_src *)cinfo->src;
+
+ src->pub.bytes_in_buffer -= num_bytes;
+ src->pub.next_input_byte += num_bytes;
+}
+
+static void
+_eet_jpeg_membuf_src_term(j_decompress_ptr cinfo)
+{
+ free(cinfo->src);
+ cinfo->src = NULL;
+}
+
+static int
+eet_jpeg_membuf_src(j_decompress_ptr cinfo, const void *buf, size_t len)
+{
+ struct jpeg_membuf_src *src;
+
+ src = malloc(sizeof(*src));
+ if (!src) return -1;
+
+ cinfo->src = &src->pub;
+ src->buf = buf;
+ src->len = len;
+ src->pub.init_source = _eet_jpeg_membuf_src_init;
+ src->pub.fill_input_buffer = _eet_jpeg_membuf_src_fill;
+ src->pub.skip_input_data = _eet_jpeg_membuf_src_skip;
+ src->pub.resync_to_restart = jpeg_resync_to_restart;
+ src->pub.term_source = _eet_jpeg_membuf_src_term;
+ src->pub.bytes_in_buffer = src->len;
+ src->pub.next_input_byte = src->buf;
+
+ return 0;
+}
+
+struct jpeg_membuf_dst {
+ struct jpeg_destination_mgr pub;
+
+ void **dst_buf;
+ size_t *dst_len;
+
+ char *buf;
+ size_t len;
+ int failed;
+};
+
+static void
+_eet_jpeg_membuf_dst_init(j_compress_ptr cinfo)
+{
+}
+
+static boolean
+_eet_jpeg_membuf_dst_flush(j_compress_ptr cinfo)
+{
+ struct jpeg_membuf_dst *dst = (struct jpeg_membuf_dst *)cinfo->dest;
+ char *buf;
+
+ if (dst->len >= 0x40000000 ||
+ (buf = realloc(dst->buf, dst->len * 2)) == NULL) {
+ dst->failed = 1;
+ dst->pub.next_output_byte = dst->buf;
+ dst->pub.free_in_buffer = dst->len;
+ return TRUE;
+ }
+
+ dst->pub.next_output_byte =
+ buf + ((char *)dst->pub.next_output_byte - dst->buf);
+ dst->buf = buf;
+ dst->pub.free_in_buffer += dst->len;
+ dst->len *= 2;
+
+ return FALSE;
+}
+
+static void
+_eet_jpeg_membuf_dst_term(j_compress_ptr cinfo)
+{
+ struct jpeg_membuf_dst *dst = (struct jpeg_membuf_dst *)cinfo->dest;
+
+ if (dst->failed) {
+ *dst->dst_buf = NULL;
+ *dst->dst_len = 0;
+ free(dst->buf);
+ } else {
+ *dst->dst_buf = dst->buf;
+ *dst->dst_len = (char *)dst->pub.next_output_byte - dst->buf;
+ }
+ free(dst);
+ cinfo->dest = NULL;
+}
+
+static int
+eet_jpeg_membuf_dst(j_compress_ptr cinfo, void **buf, size_t *len)
+{
+ struct jpeg_membuf_dst *dst;
+
+ dst = malloc(sizeof(*dst));
+ if (!dst) return -1;
+
+ dst->buf = malloc(32768);
+ if (!dst->buf) {
+ free(dst);
+ return -1;
+ }
+ dst->len = 32768;
+
+ cinfo->dest = &dst->pub;
+ dst->pub.init_destination = _eet_jpeg_membuf_dst_init;
+ dst->pub.empty_output_buffer = _eet_jpeg_membuf_dst_flush;
+ dst->pub.term_destination = _eet_jpeg_membuf_dst_term;
+ dst->pub.free_in_buffer = dst->len;
+ dst->pub.next_output_byte = dst->buf;
+ dst->dst_buf = buf;
+ dst->dst_len = len;
+ dst->failed = 0;
+
+ return 0;
+}
+
/*---*/
static void _JPEGFatalErrorHandler(j_common_ptr cinfo);
static int
eet_data_image_jpeg_header_decode(const void *data, int size, unsigned int *w, unsigned int *h)
{
- struct jpeg_decompress_struct cinfo;
+ struct jpeg_decompress_struct cinfo = { 0 };
struct _JPEG_error_mgr jerr;
- FILE *f;
- f = _eet_memfile_read_open(data, (size_t)size);
- if (!f) return 0;
cinfo.err = jpeg_std_error(&(jerr.pub));
jerr.pub.error_exit = _JPEGFatalErrorHandler;
jerr.pub.emit_message = _JPEGErrorHandler2;
jerr.pub.output_message = _JPEGErrorHandler;
- if (setjmp(jerr.setjmp_buffer))
+ if (setjmp(jerr.setjmp_buffer)) return 0;
+ jpeg_create_decompress(&cinfo);
+
+ if (eet_jpeg_membuf_src(&cinfo, data, (size_t)size))
{
jpeg_destroy_decompress(&cinfo);
- _eet_memfile_read_close(f);
return 0;
}
- jpeg_create_decompress(&cinfo);
- jpeg_stdio_src(&cinfo, f);
+
jpeg_read_header(&cinfo, TRUE);
cinfo.do_fancy_upsampling = FALSE;
cinfo.do_block_smoothing = FALSE;
/* head decoding */
*w = cinfo.output_width;
*h = cinfo.output_height;
- if ((*w < 1) || (*h < 1) || (*w > 8192) || (*h > 8192))
- {
- jpeg_destroy_decompress(&cinfo);
- _eet_memfile_read_close(f);
- return 0;
- }
- /* end head decoding */
+
+ free(cinfo.src);
+ cinfo.src = NULL;
+
jpeg_destroy_decompress(&cinfo);
- _eet_memfile_read_close(f);
+
+ if ((*w < 1) || (*h < 1) || (*w > 8192) || (*h > 8192))
+ return 0;
return 1;
}
eet_data_image_jpeg_rgb_decode(const void *data, int size, unsigned int src_x, unsigned int src_y,
unsigned int *d, unsigned int w, unsigned int h, unsigned int row_stride)
{
- struct jpeg_decompress_struct cinfo;
+ struct jpeg_decompress_struct cinfo = { 0 };
struct _JPEG_error_mgr jerr;
unsigned char *ptr, *line[16], *tdata = NULL;
unsigned int *ptr2, *tmp;
unsigned int iw, ih;
int x, y, l, scans;
int i, count, prevy;
- FILE *f;
/* FIXME: handle src_x, src_y and row_stride correctly */
if (!d) return 0;
- f = _eet_memfile_read_open(data, (size_t)size);
- if (!f) return 0;
cinfo.err = jpeg_std_error(&(jerr.pub));
jerr.pub.error_exit = _JPEGFatalErrorHandler;
jerr.pub.emit_message = _JPEGErrorHandler2;
jerr.pub.output_message = _JPEGErrorHandler;
- if (setjmp(jerr.setjmp_buffer))
+ if (setjmp(jerr.setjmp_buffer)) return 0;
+ jpeg_create_decompress(&cinfo);
+
+ if (eet_jpeg_membuf_src(&cinfo, data, (size_t)size))
{
- if (tdata) free(tdata);
jpeg_destroy_decompress(&cinfo);
- _eet_memfile_read_close(f);
return 0;
}
- jpeg_create_decompress(&cinfo);
- jpeg_stdio_src(&cinfo, f);
+
jpeg_read_header(&cinfo, TRUE);
cinfo.dct_method = JDCT_FASTEST;
cinfo.do_fancy_upsampling = FALSE;
ih = cinfo.output_height;
if ((iw != w) || (ih != h))
{
+ free(cinfo.src);
+ cinfo.src = NULL;
+
jpeg_destroy_decompress(&cinfo);
- _eet_memfile_read_close(f);
return 0;
}
/* end head decoding */
/* data decoding */
if (cinfo.rec_outbuf_height > 16)
{
+ free(cinfo.src);
+ cinfo.src = NULL;
+
jpeg_destroy_decompress(&cinfo);
- _eet_memfile_read_close(f);
return 0;
}
tdata = alloca((iw) * 16 * 3);
/* end data decoding */
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
- _eet_memfile_read_close(f);
return 1;
}
eet_data_image_jpeg_alpha_decode(const void *data, int size, unsigned int src_x, unsigned int src_y,
unsigned int *d, unsigned int w, unsigned int h, unsigned int row_stride)
{
- struct jpeg_decompress_struct cinfo;
+ struct jpeg_decompress_struct cinfo = { 0 };
struct _JPEG_error_mgr jerr;
unsigned char *ptr, *line[16], *tdata = NULL;
unsigned int *ptr2, *tmp;
int x, y, l, scans;
int i, count, prevy, iw;
- FILE *f;
-
- f = _eet_memfile_read_open(data, (size_t)size);
- if (!f) return NULL;
-
- if (0)
- {
- char buf[1];
- while (fread(buf, 1, 1, f));
- _eet_memfile_read_close(f);
- return d;
- }
cinfo.err = jpeg_std_error(&(jerr.pub));
jerr.pub.error_exit = _JPEGFatalErrorHandler;
jerr.pub.emit_message = _JPEGErrorHandler2;
jerr.pub.output_message = _JPEGErrorHandler;
- if (setjmp(jerr.setjmp_buffer))
+ if (setjmp(jerr.setjmp_buffer)) return NULL;
+ jpeg_create_decompress(&cinfo);
+
+ if (eet_jpeg_membuf_src(&cinfo, data, (size_t)size))
{
- if (tdata) free(tdata);
jpeg_destroy_decompress(&cinfo);
- _eet_memfile_read_close(f);
return NULL;
}
- jpeg_create_decompress(&cinfo);
- jpeg_stdio_src(&cinfo, f);
+
jpeg_read_header(&cinfo, TRUE);
cinfo.dct_method = JDCT_FASTEST;
cinfo.do_fancy_upsampling = FALSE;
if (w != cinfo.output_width
|| h != cinfo.output_height)
{
+ free(cinfo.src);
+ cinfo.src = NULL;
+
jpeg_destroy_decompress(&cinfo);
- _eet_memfile_read_close(f);
return NULL;
}
/* end head decoding */
/* data decoding */
if (cinfo.rec_outbuf_height > 16)
{
+ free(cinfo.src);
+ cinfo.src = NULL;
+
jpeg_destroy_decompress(&cinfo);
- _eet_memfile_read_close(f);
return NULL;
}
tdata = alloca(w * 16 * 3);
/* end data decoding */
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
- _eet_memfile_read_close(f);
return d;
}
(void) alpha; /* unused */
- f =_eet_memfile_write_open(&d, &sz);
- if (!f) return NULL;
-
buf = alloca(3 * w);
cinfo.err = jpeg_std_error(&(jerr.pub));
if (setjmp(jerr.setjmp_buffer))
{
jpeg_destroy_compress(&cinfo);
- _eet_memfile_write_close(f);
+ /* XXX free buffer in cinfo */
if (d) free(d);
return NULL;
}
jpeg_create_compress(&cinfo);
- jpeg_stdio_dest(&cinfo, f);
+ eet_jpeg_membuf_dst(&cinfo, &d, &sz);
cinfo.image_width = w;
cinfo.image_height = h;
cinfo.input_components = 3;
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);
- _eet_memfile_write_close(f);
*size = sz;
return d;
}
struct _JPEG_error_mgr jerr;
JSAMPROW *jbuf;
struct jpeg_compress_struct cinfo;
- FILE *f;
unsigned char *buf;
- f = _eet_memfile_write_open(&d, &sz);
- if (!f) return NULL;
-
buf = alloca(3 * w);
cinfo.err = jpeg_std_error(&(jerr.pub));
if (setjmp(jerr.setjmp_buffer))
{
jpeg_destroy_compress(&cinfo);
- _eet_memfile_write_close(f);
if (d) free(d);
return NULL;
}
jpeg_create_compress(&cinfo);
- jpeg_stdio_dest(&cinfo, f);
+ eet_jpeg_membuf_dst(&cinfo, &d, &sz);
cinfo.image_width = w;
cinfo.image_height = h;
cinfo.input_components = 3;
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);
- _eet_memfile_write_close(f);
d1 = d;
sz1 = sz;
}
struct _JPEG_error_mgr jerr;
JSAMPROW *jbuf;
struct jpeg_compress_struct cinfo;
- FILE *f;
unsigned char *buf;
- f = _eet_memfile_write_open(&d, &sz);
- if (!f)
- {
- free(d1);
- return NULL;
- }
-
buf = alloca(3 * w);
cinfo.err = jpeg_std_error(&(jerr.pub));
if (setjmp(jerr.setjmp_buffer))
{
jpeg_destroy_compress(&cinfo);
- _eet_memfile_write_close(f);
if (d) free(d);
free(d1);
return NULL;
}
jpeg_create_compress(&cinfo);
- jpeg_stdio_dest(&cinfo, f);
+ eet_jpeg_membuf_dst(&cinfo, &d, &sz);
cinfo.image_width = w;
cinfo.image_height = h;
cinfo.input_components = 1;
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);
- _eet_memfile_write_close(f);
d2 = d;
sz2 = sz;
}
+++ /dev/null
-/*
- * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
- */
-
-#define _GNU_SOURCE
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <stdio.h>
-
-#include "Eet.h"
-#include "Eet_private.h"
-
-FILE *
-_eet_memfile_read_open(const void *data, size_t size)
-{
-#ifdef HAVE_FMEMOPEN
- return fmemopen((void*)data, size, "rb");
-#else
- FILE *f;
-
- f = tmpfile();
- if (!f)
- {
- printf("EET: Error opening tmp file (no fmemopen support fallback):\n");
- perror("tmpfile()");
- return NULL;
- }
- fwrite(data, size, 1, f);
- rewind(f);
- return f;
-#endif
-}
-
-void
-_eet_memfile_read_close(FILE *f)
-{
-#ifdef HAVE_FMEMOPEN
- fclose(f);
-#else
- fclose(f);
-#endif
-}
-
-
-typedef struct _Eet_Memfile_Write_Info Eet_Memfile_Write_Info;
-struct _Eet_Memfile_Write_Info
-{
- FILE *f;
- void **data;
- size_t *size;
-};
-
-#ifndef HAVE_OPEN_MEMSTREAM
-static int _eet_memfile_info_alloc_num = 0;
-static int _eet_memfile_info_num = 0;
-static Eet_Memfile_Write_Info *_eet_memfile_info = NULL;
-#endif
-
-void _eet_memfile_shutdown()
-{
-#ifdef HAVE_OPEN_MEMSTREAM
- return;
-#else
- int i;
-
- for (i = 0; i < _eet_memfile_info_num; i++)
- free(_eet_memfile_info[i].data);
-
- free(_eet_memfile_info);
- _eet_memfile_info = NULL;
-#endif
-}
-
-FILE *
-_eet_memfile_write_open(void **data, size_t *size)
-{
-#ifdef HAVE_OPEN_MEMSTREAM
- return open_memstream((char **)data, size);
-#else
- FILE *f;
-
- _eet_memfile_info_num++;
- if (_eet_memfile_info_num > _eet_memfile_info_alloc_num)
- {
- Eet_Memfile_Write_Info *tmp;
-
- _eet_memfile_info_alloc_num += 16;
- tmp = realloc(_eet_memfile_info,
- _eet_memfile_info_alloc_num *
- sizeof(Eet_Memfile_Write_Info));
- if (!tmp)
- {
- _eet_memfile_info_alloc_num -= 16;
- _eet_memfile_info_num--;
- return NULL;
- }
- _eet_memfile_info = tmp;
- }
- f = tmpfile();
- if (!f)
- {
- _eet_memfile_info_num--;
- return NULL;
- }
- _eet_memfile_info[_eet_memfile_info_num - 1].f = f;
- _eet_memfile_info[_eet_memfile_info_num - 1].data = data;
- _eet_memfile_info[_eet_memfile_info_num - 1].size = size;
- return f;
-#endif
-}
-
-void
-_eet_memfile_write_close(FILE *f)
-{
-#ifdef HAVE_OPEN_MEMSTREAM
- fclose(f);
-#else
- int i;
-
- for (i = 0; i < _eet_memfile_info_num; i++)
- {
- if (_eet_memfile_info[i].f == f)
- {
- int j;
-
- fseek(f, 0, SEEK_END);
- (*(_eet_memfile_info[i].size)) = ftell(f);
- rewind(f);
- (*(_eet_memfile_info[i].data)) = malloc(*(_eet_memfile_info[i].size));
- if (!(*(_eet_memfile_info[i].data)))
- {
- fclose(f);
- (*(_eet_memfile_info[i].size)) = 0;
- return;
- }
- fread((*(_eet_memfile_info[i].data)), (*(_eet_memfile_info[i].size)), 1, f);
- for (j = i + 1; j < _eet_memfile_info_num; j++)
- _eet_memfile_info[j - 1] = _eet_memfile_info[j];
- _eet_memfile_info_num--;
- fclose(f);
- return;
- }
- }
- fclose(f);
-#endif
-}