forked from len0rd/rockbox
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
This commit is contained in:
parent
c91e73e922
commit
a75c72c169
7 changed files with 435 additions and 14 deletions
150
apps/plugins/bench_mem_jpeg.c
Normal file
150
apps/plugins/bench_mem_jpeg.c
Normal file
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
41
apps/plugins/lib/jpeg_mem.h
Normal file
41
apps/plugins/lib/jpeg_mem.h
Normal file
|
@ -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 */
|
29
apps/plugins/lib/pluginlib_jpeg_mem.c
Normal file
29
apps/plugins/lib/pluginlib_jpeg_mem.c
Normal file
|
@ -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"
|
103
apps/plugins/test_mem_jpeg.c
Normal file
103
apps/plugins/test_mem_jpeg.c
Normal file
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue