summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorAndrew Mahone <andrew.mahone@gmail.com>2009-05-08 03:46:48 +0000
committerAndrew Mahone <andrew.mahone@gmail.com>2009-05-08 03:46:48 +0000
commita75c72c169f64ecb0799934f1da148bdf497b8a9 (patch)
treeb0ad37ce0f6519bb44536a0bf6fc72fc76628542 /apps
parentc91e73e922fc2a229c39a9b686d77d5cba47c95a (diff)
downloadrockbox-a75c72c169f64ecb0799934f1da148bdf497b8a9.zip
rockbox-a75c72c169f64ecb0799934f1da148bdf497b8a9.tar.gz
rockbox-a75c72c169f64ecb0799934f1da148bdf497b8a9.tar.bz2
rockbox-a75c72c169f64ecb0799934f1da148bdf497b8a9.tar.xz
Plugin JPEG decoder for data in memory, along with test_mem_jpeg.c and bench_mem_jpeg.c plugins to test and benchmark it, and a line-length clean up in jpeg_load.c.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20871 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r--apps/plugins/bench_mem_jpeg.c150
-rw-r--r--apps/plugins/lib/SOURCES3
-rw-r--r--apps/plugins/lib/jpeg_mem.h41
-rw-r--r--apps/plugins/lib/pluginlib_jpeg_mem.c29
-rw-r--r--apps/plugins/test_mem_jpeg.c103
-rw-r--r--apps/plugins/viewers.config6
-rw-r--r--apps/recorder/jpeg_load.c117
7 files changed, 435 insertions, 14 deletions
diff --git a/apps/plugins/bench_mem_jpeg.c b/apps/plugins/bench_mem_jpeg.c
new file mode 100644
index 0000000..958e520
--- /dev/null
+++ b/apps/plugins/bench_mem_jpeg.c
@@ -0,0 +1,150 @@
+/*****************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// __ \_/ ___\| |/ /| __ \ / __ \ \/ /
+ * Jukebox | | ( (__) ) \___| ( | \_\ ( (__) ) (
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2009 Andrew Mahone
+ *
+ * In-memory JPEG decode benchmark.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "plugin.h"
+#include "lib/jpeg_mem.h"
+PLUGIN_HEADER
+
+/* a null output plugin to save memory and better isolate decode cost */
+static unsigned int get_size_null(struct bitmap *bm)
+{
+ (void) bm;
+ return 1;
+}
+
+static void output_row_null(uint32_t row, void * row_in,
+ struct scaler_context *ctx)
+{
+ (void) row;
+ (void) row_in;
+ (void) ctx;
+ return;
+}
+
+const struct custom_format format_null = {
+#ifdef HAVE_LCD_COLOR
+ .output_row = {
+ output_row_null,
+ output_row_null
+ },
+#else
+ .output_row = output_row_null,
+#endif
+ .get_size = get_size_null
+};
+
+static char output_buf[256];
+static int output_y = 0;
+static int font_h;
+
+#define lcd_printf(...) \
+do { \
+ rb->snprintf(output_buf, sizeof(output_buf), __VA_ARGS__); \
+ rb->lcd_putsxy(0, output_y, output_buf); \
+ rb->lcd_update_rect(0, output_y, LCD_WIDTH, font_h); \
+ output_y += font_h; \
+} while (0)
+
+/* this is the plugin entry point */
+enum plugin_status plugin_start(const void* parameter)
+{
+ size_t plugin_buf_len;
+ unsigned char * plugin_buf =
+ (unsigned char *)rb->plugin_get_buffer(&plugin_buf_len);
+ static char filename[MAX_PATH];
+ struct bitmap bm = {
+ .width = LCD_WIDTH,
+ .height = LCD_HEIGHT,
+ };
+ int ret;
+
+ if(!parameter) return PLUGIN_ERROR;
+
+ rb->strcpy(filename, parameter);
+ rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
+ rb->lcd_fillrect(0, 0, LCD_WIDTH, LCD_HEIGHT);
+ rb->lcd_set_drawmode(DRMODE_SOLID);
+ rb->lcd_getstringsize("A", NULL, &font_h);
+ int fd = rb->open(filename, O_RDONLY);
+ if (fd < 0)
+ {
+ lcd_printf("file open failed: %d", fd);
+ goto wait;
+ }
+ unsigned long filesize = rb->filesize(fd);
+ if (filesize > plugin_buf_len)
+ {
+ lcd_printf("file too large");
+ goto wait;
+ }
+ plugin_buf_len -= filesize;
+ unsigned char *jpeg_buf = plugin_buf;
+ plugin_buf += filesize;
+ rb->read(fd, jpeg_buf, filesize);
+ rb->close(fd);
+ bm.data = plugin_buf;
+ struct dim jpeg_size;
+ get_jpeg_dim_mem(jpeg_buf, filesize, &jpeg_size);
+ lcd_printf("jpeg file size: %dx%d",jpeg_size.width, jpeg_size.height);
+ bm.width = jpeg_size.width;
+ bm.height = jpeg_size.height;
+ char *size_str[] = { "1/1", "1/2", "1/4", "1/8" };
+ int i;
+ for (i = 0; i < 4; i++)
+ {
+ lcd_printf("timing %s decode", size_str[i]);
+ ret = decode_jpeg_mem(jpeg_buf, filesize, &bm, plugin_buf_len,
+ FORMAT_NATIVE|FORMAT_RESIZE|FORMAT_KEEP_ASPECT,
+ &format_null);
+ if (ret == 1)
+ {
+ long t1, t2;
+ int count = 0;
+ t2 = *(rb->current_tick);
+ while (t2 != (t1 = *(rb->current_tick)));
+ do {
+ decode_jpeg_mem(jpeg_buf, filesize, &bm, plugin_buf_len,
+ FORMAT_NATIVE|FORMAT_RESIZE|FORMAT_KEEP_ASPECT,
+ &format_null);
+ count++;
+ t2 = *(rb->current_tick);
+ } while (t2 - t1 < HZ || count < 10);
+ t2 -= t1;
+ t2 *= 10;
+ t2 += count >> 1;
+ t2 /= count;
+ t1 = t2 / 1000;
+ t2 -= t1 * 1000;
+ lcd_printf("%01d.%03d secs/decode", (int)t1, (int)t2);
+ bm.width >>= 1;
+ bm.height >>= 1;
+ if (!(bm.width && bm.height))
+ break;
+ } else
+ lcd_printf("insufficient memory");
+ }
+
+wait:
+ while (rb->get_action(CONTEXT_STD,1) != ACTION_STD_OK) rb->yield();
+ return PLUGIN_OK;
+}
diff --git a/apps/plugins/lib/SOURCES b/apps/plugins/lib/SOURCES
index 889fb79..21a35d4 100644
--- a/apps/plugins/lib/SOURCES
+++ b/apps/plugins/lib/SOURCES
@@ -27,9 +27,8 @@ playergfx.c
profile_plugin.c
#endif
#ifdef HAVE_LCD_BITMAP
-#if !defined(HAVE_BMP_SCALING) || !defined(HAVE_JPEG)
+pluginlib_jpeg_mem.c
pluginlib_resize.c
-#endif
#ifndef HAVE_JPEG
pluginlib_jpeg_load.c
#endif
diff --git a/apps/plugins/lib/jpeg_mem.h b/apps/plugins/lib/jpeg_mem.h
new file mode 100644
index 0000000..8636f70
--- /dev/null
+++ b/apps/plugins/lib/jpeg_mem.h
@@ -0,0 +1,41 @@
+/***************************************************************************
+* __________ __ ___.
+* Open \______ \ ____ ____ | | _\_ |__ _______ ___
+* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+* \/ \/ \/ \/ \/
+* $Id$
+*
+* Copyright (C) 2009 by Andrew Mahone
+*
+* Header for the in-memory JPEG decoder.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+* KIND, either express or implied.
+*
+****************************************************************************/
+
+#include "plugin.h"
+#include "resize.h"
+#include "bmp.h"
+#include "jpeg_common.h"
+
+#ifndef _JPEG_MEM_H
+#define _JPEG_MEM_H
+
+int get_jpeg_dim_mem(unsigned char *data, unsigned long len,
+ struct dim *size);
+
+int decode_jpeg_mem(unsigned char *data, unsigned long len,
+ struct bitmap *bm,
+ int maxsize,
+ int format,
+ const struct custom_format *cformat);
+
+#endif /* _JPEG_MEM_H */
diff --git a/apps/plugins/lib/pluginlib_jpeg_mem.c b/apps/plugins/lib/pluginlib_jpeg_mem.c
new file mode 100644
index 0000000..4a6c1bb
--- /dev/null
+++ b/apps/plugins/lib/pluginlib_jpeg_mem.c
@@ -0,0 +1,29 @@
+/***************************************************************************
+* __________ __ ___.
+* Open \______ \ ____ ____ | | _\_ |__ _______ ___
+* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+* \/ \/ \/ \/ \/
+* $Id$
+*
+* Copyright (C) 2009 by Andrew Mahone
+*
+* This is a wrapper for the core jpeg_load.c, to provide the from-memory
+* version of the decoder.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+* KIND, either express or implied.
+*
+****************************************************************************/
+
+#include <plugin.h>
+#include "wrappers.h"
+#define JPEG_FROM_MEM
+
+#include "../../recorder/jpeg_load.c"
diff --git a/apps/plugins/test_mem_jpeg.c b/apps/plugins/test_mem_jpeg.c
new file mode 100644
index 0000000..50969c3
--- /dev/null
+++ b/apps/plugins/test_mem_jpeg.c
@@ -0,0 +1,103 @@
+/*****************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// __ \_/ ___\| |/ /| __ \ / __ \ \/ /
+ * Jukebox | | ( (__) ) \___| ( | \_\ ( (__) ) (
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2009 Andrew Mahone
+ *
+ * In-memory JPEG decode test.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "plugin.h"
+#include "lib/grey.h"
+#include "lib/jpeg_mem.h"
+PLUGIN_HEADER
+
+/* different graphics libraries */
+#if LCD_DEPTH < 8
+#define USEGSLIB
+GREY_INFO_STRUCT
+#define MYLCD(fn) grey_ub_ ## fn
+#define MYLCD_UPDATE()
+#define MYXLCD(fn) grey_ub_ ## fn
+#define CFORMAT &format_grey
+#else
+#define MYLCD(fn) rb->lcd_ ## fn
+#define MYLCD_UPDATE() rb->lcd_update();
+#define MYXLCD(fn) xlcd_ ## fn
+#define CFORMAT &format_native
+#endif
+
+/* this is the plugin entry point */
+enum plugin_status plugin_start(const void* parameter)
+{
+ size_t plugin_buf_len;
+ unsigned char * plugin_buf =
+ (unsigned char *)rb->plugin_get_buffer(&plugin_buf_len);
+ static char filename[MAX_PATH];
+ struct bitmap bm = {
+ .width = LCD_WIDTH,
+ .height = LCD_HEIGHT,
+ };
+ int ret;
+
+ if(!parameter) return PLUGIN_ERROR;
+
+ rb->strcpy(filename, parameter);
+
+#ifdef USEGSLIB
+ long greysize;
+ if (!grey_init(plugin_buf, plugin_buf_len, GREY_ON_COP,
+ LCD_WIDTH, LCD_HEIGHT, &greysize))
+ {
+ rb->splash(HZ, "grey buf error");
+ return PLUGIN_ERROR;
+ }
+ plugin_buf += greysize;
+ plugin_buf_len -= greysize;
+#endif
+ int fd = rb->open(filename, O_RDONLY);
+ if (fd < 0)
+ return PLUGIN_ERROR;
+ unsigned long filesize = rb->filesize(fd);
+ if (filesize > plugin_buf_len)
+ return PLUGIN_ERROR;
+ plugin_buf_len -= filesize;
+ unsigned char *jpeg_buf = plugin_buf;
+ plugin_buf += filesize;
+ rb->read(fd, jpeg_buf, filesize);
+ rb->close(fd);
+ bm.data = plugin_buf;
+ ret = decode_jpeg_mem(jpeg_buf, filesize, &bm, plugin_buf_len,
+ FORMAT_NATIVE|FORMAT_RESIZE|FORMAT_KEEP_ASPECT,
+ CFORMAT);
+ if (ret < 1)
+ return PLUGIN_ERROR;
+#ifdef USEGSLIB
+ grey_show(true);
+ grey_ub_gray_bitmap((fb_data *)bm.data, (LCD_WIDTH - bm.width) >> 1,
+ (LCD_HEIGHT - bm.height) >> 1, bm.width, bm.height);
+#else
+ rb->lcd_bitmap((fb_data *)bm.data, (LCD_WIDTH - bm.width) >> 1,
+ (LCD_HEIGHT - bm.height) >> 1, bm.width, bm.height);
+#endif
+ MYLCD_UPDATE();
+ while (rb->get_action(CONTEXT_STD,1) != ACTION_STD_OK) rb->yield();
+#ifdef USEGSLIB
+ grey_release();
+#endif
+ return PLUGIN_OK;
+}
diff --git a/apps/plugins/viewers.config b/apps/plugins/viewers.config
index 09d0455..939a0a5 100644
--- a/apps/plugins/viewers.config
+++ b/apps/plugins/viewers.config
@@ -30,6 +30,12 @@ bmp,viewers/test_greylib_bitmap_scale,-
jpeg,viewers/test_core_jpeg,-
jpe,viewers/test_core_jpeg,-
jpg,viewers/test_core_jpeg,-
+jpeg,viewers/test_mem_jpeg,-
+jpe,viewers/test_mem_jpeg,-
+jpg,viewers/test_mem_jpeg,-
+jpeg,viewers/bench_mem_jpeg,-
+jpe,viewers/bench_mem_jpeg,-
+jpg,viewers/bench_mem_jpeg,-
bmp,apps/rockpaint,11
bmp,games/sliding_puzzle,11
mpg,viewers/mpegplayer,4
diff --git a/apps/recorder/jpeg_load.c b/apps/recorder/jpeg_load.c
index 1d8c9ed..5b16e6f 100644
--- a/apps/recorder/jpeg_load.c
+++ b/apps/recorder/jpeg_load.c
@@ -36,6 +36,11 @@
#define MEMCPY(d,s,c) memcpy(d,s,c)
#define INLINE static inline
#define ENDIAN_SWAP16(n) n /* only for poor little endian machines */
+#ifdef ROCKBOX_DEBUG_JPEG
+#define JDEBUGF DEBUGF
+#else
+#define JDEBUGF(...)
+#endif
/**************** begin JPEG code ********************/
@@ -51,9 +56,14 @@ typedef uint8_t jpeg_pix_t;
*/
struct jpeg
{
+#ifdef JPEG_FROM_MEM
+ unsigned char *data;
+ unsigned long len;
+#else
int fd;
int buf_left;
unsigned char *buf_index;
+#endif
unsigned long int bitbuf;
int bitbuf_bits;
int marker_ind;
@@ -103,6 +113,10 @@ struct jpeg
struct img_part part;
};
+#ifdef JPEG_FROM_MEM
+static struct jpeg jpeg;
+#endif
+
INLINE unsigned range_limit(int value)
{
#if CONFIG_CPU == SH7034
@@ -811,6 +825,37 @@ struct idct_entry idct_tbl[] = {
/* JPEG decoder implementation */
+#ifdef JPEG_FROM_MEM
+INLINE unsigned char *getc(struct jpeg* p_jpeg)
+{
+ if (p_jpeg->len)
+ {
+ p_jpeg->len--;
+ return p_jpeg->data++;
+ } else
+ return NULL;
+}
+
+INLINE bool skip_bytes(struct jpeg* p_jpeg, int count)
+{
+ if (p_jpeg->len >= (unsigned)count)
+ {
+ p_jpeg->len -= count;
+ p_jpeg->data += count;
+ return true;
+ } else {
+ p_jpeg->data += p_jpeg->len;
+ p_jpeg->len = 0;
+ return false;
+ }
+}
+
+INLINE void putc(struct jpeg* p_jpeg)
+{
+ p_jpeg->len++;
+ p_jpeg->data--;
+}
+#else
INLINE void fill_buf(struct jpeg* p_jpeg)
{
p_jpeg->buf_left = read(p_jpeg->fd, p_jpeg->buf, JPEG_READ_BUF_SIZE);
@@ -842,6 +887,13 @@ static bool skip_bytes(struct jpeg* p_jpeg, int count)
return p_jpeg->buf_left >= 0 || skip_bytes_seek(p_jpeg);
}
+static void putc(struct jpeg* p_jpeg)
+{
+ p_jpeg->buf_left++;
+ p_jpeg->buf_index--;
+}
+#endif
+
#define e_skip_bytes(jpeg, count) \
do {\
if (!skip_bytes((jpeg),(count))) \
@@ -863,12 +915,6 @@ do {\
c; \
})
-static void putc(struct jpeg* p_jpeg)
-{
- p_jpeg->buf_left++;
- p_jpeg->buf_index--;
-}
-
/* Preprocess the JPEG JFIF file */
static int process_markers(struct jpeg* p_jpeg)
{
@@ -881,11 +927,13 @@ static int process_markers(struct jpeg* p_jpeg)
{
if (c != 0xFF) /* no marker? */
{
+ JDEBUGF("Non-marker data\n");
putc(p_jpeg);
break; /* exit marker processing */
}
c = e_getc(p_jpeg, -1);
+ JDEBUGF("marker value %X\n",c);
switch (c)
{
case 0xFF: /* Fill byte */
@@ -896,9 +944,11 @@ static int process_markers(struct jpeg* p_jpeg)
case 0xC0: /* SOF Huff - Baseline DCT */
{
+ JDEBUGF("SOF marker ");
ret |= SOF0;
marker_size = e_getc(p_jpeg, -1) << 8; /* Highbyte */
marker_size |= e_getc(p_jpeg, -1); /* Lowbyte */
+ JDEBUGF("len: %d\n", marker_size);
n = e_getc(p_jpeg, -1); /* sample precision (= 8 or 12) */
if (n != 8)
{
@@ -908,6 +958,8 @@ static int process_markers(struct jpeg* p_jpeg)
p_jpeg->y_size |= e_getc(p_jpeg, -1); /* Lowbyte */
p_jpeg->x_size = e_getc(p_jpeg, -1) << 8; /* Highbyte */
p_jpeg->x_size |= e_getc(p_jpeg, -1); /* Lowbyte */
+ JDEBUGF(" dimensions: %dx%d\n", p_jpeg->x_size,
+ p_jpeg->y_size);
n = (marker_size-2-6)/3;
if (e_getc(p_jpeg, -1) != n || (n != 1 && n != 3))
@@ -1013,8 +1065,13 @@ static int process_markers(struct jpeg* p_jpeg)
return(-6); /* Arithmetic coding not supported */
case 0xD8: /* Start of Image */
+ JDEBUGF("SOI\n");
+ break;
case 0xD9: /* End of Image */
+ JDEBUGF("EOI\n");
+ break;
case 0x01: /* for temp private use arith code */
+ JDEBUGF("private\n");
break; /* skip parameterless marker */
@@ -1107,6 +1164,7 @@ static int process_markers(struct jpeg* p_jpeg)
marker_size = e_getc(p_jpeg, -1) << 8; /* Highbyte */
marker_size |= e_getc(p_jpeg, -1); /* Lowbyte */
marker_size -= 2;
+ JDEBUGF("unhandled marker len %d\n", marker_size);
e_skip_bytes(p_jpeg, marker_size); /* skip segment */
}
break;
@@ -1693,8 +1751,10 @@ static struct img_part *store_row_jpeg(void *jpeg_args)
int mcu_hscale = p_jpeg->h_scale[1];
int mcu_vscale = p_jpeg->v_scale[1];
#else
- int mcu_hscale = (p_jpeg->h_scale[0] + p_jpeg->frameheader[0].horizontal_sampling - 1);
- int mcu_vscale = (p_jpeg->v_scale[0] + p_jpeg->frameheader[0].vertical_sampling - 1);
+ int mcu_hscale = (p_jpeg->h_scale[0] +
+ p_jpeg->frameheader[0].horizontal_sampling - 1);
+ int mcu_vscale = (p_jpeg->v_scale[0] +
+ p_jpeg->frameheader[0].vertical_sampling - 1);
#endif
unsigned int width = p_jpeg->x_mbl << mcu_hscale;
unsigned int b_width = width * JPEG_PIX_SZ;
@@ -1855,6 +1915,7 @@ static struct img_part *store_row_jpeg(void *jpeg_args)
* Reads a JPEG file and puts the data in rockbox format in *bitmap.
*
*****************************************************************************/
+#ifndef JPEG_FROM_MEM
int read_jpeg_file(const char* filename,
struct bitmap *bm,
int maxsize,
@@ -1874,6 +1935,7 @@ int read_jpeg_file(const char* filename,
close(fd);
return ret;
}
+#endif
static int calc_scale(int in_size, int out_size)
{
@@ -1889,7 +1951,28 @@ static int calc_scale(int in_size, int out_size)
return scale;
}
+#ifdef JPEG_FROM_MEM
+int get_jpeg_dim_mem(unsigned char *data, unsigned long len,
+ struct dim *size)
+{
+ struct jpeg *p_jpeg = &jpeg;
+ memset(p_jpeg, 0, sizeof(struct jpeg));
+ p_jpeg->data = data;
+ p_jpeg->len = len;
+ int status = process_markers(p_jpeg);
+ if (status < 0)
+ return status;
+ if ((status & (DQT | SOF0)) != (DQT | SOF0))
+ return -(status * 16);
+ size->width = p_jpeg->x_size;
+ size->height = p_jpeg->y_size;
+ return 0;
+}
+
+int decode_jpeg_mem(unsigned char *data, unsigned long len,
+#else
int read_jpeg_fd(int fd,
+#endif
struct bitmap *bm,
int maxsize,
int format,
@@ -1898,17 +1981,25 @@ int read_jpeg_fd(int fd,
bool resize = false, dither = false;
struct rowset rset;
struct dim src_dim;
- struct jpeg *p_jpeg = (struct jpeg*)bm->data;
- int tmp_size = maxsize;
int status;
int bm_size;
+#ifdef JPEG_FROM_MEM
+ struct jpeg *p_jpeg = &jpeg;
+#else
+ struct jpeg *p_jpeg = (struct jpeg*)bm->data;
+ int tmp_size = maxsize;
ALIGN_BUFFER(p_jpeg, tmp_size, sizeof(int));
/* not enough memory for our struct jpeg */
if ((size_t)tmp_size < sizeof(struct jpeg))
return -1;
-
+#endif
memset(p_jpeg, 0, sizeof(struct jpeg));
+#ifdef JPEG_FROM_MEM
+ p_jpeg->data = data;
+ p_jpeg->len = len;
+#else
p_jpeg->fd = fd;
+#endif
status = process_markers(p_jpeg);
if (status < 0)
return status;
@@ -1968,14 +2059,16 @@ int read_jpeg_fd(int fd,
char *buf_start = (char *)bm->data + bm_size;
char *buf_end = (char *)bm->data + maxsize;
maxsize = buf_end - buf_start;
+#ifndef JPEG_FROM_MEM
ALIGN_BUFFER(buf_start, maxsize, sizeof(uint32_t));
if (maxsize < (int)sizeof(struct jpeg))
return -1;
memmove(buf_start, p_jpeg, sizeof(struct jpeg));
p_jpeg = (struct jpeg *)buf_start;
- fix_huff_tables(p_jpeg);
buf_start += sizeof(struct jpeg);
maxsize = buf_end - buf_start;
+#endif
+ fix_huff_tables(p_jpeg);
#ifdef HAVE_LCD_COLOR
int decode_buf_size = (p_jpeg->x_mbl << p_jpeg->h_scale[1])
<< p_jpeg->v_scale[1];