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
|
profile_plugin.c
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_LCD_BITMAP
|
#ifdef HAVE_LCD_BITMAP
|
||||||
#if !defined(HAVE_BMP_SCALING) || !defined(HAVE_JPEG)
|
pluginlib_jpeg_mem.c
|
||||||
pluginlib_resize.c
|
pluginlib_resize.c
|
||||||
#endif
|
|
||||||
#ifndef HAVE_JPEG
|
#ifndef HAVE_JPEG
|
||||||
pluginlib_jpeg_load.c
|
pluginlib_jpeg_load.c
|
||||||
#endif
|
#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,-
|
jpeg,viewers/test_core_jpeg,-
|
||||||
jpe,viewers/test_core_jpeg,-
|
jpe,viewers/test_core_jpeg,-
|
||||||
jpg,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,apps/rockpaint,11
|
||||||
bmp,games/sliding_puzzle,11
|
bmp,games/sliding_puzzle,11
|
||||||
mpg,viewers/mpegplayer,4
|
mpg,viewers/mpegplayer,4
|
||||||
|
|
|
@ -36,6 +36,11 @@
|
||||||
#define MEMCPY(d,s,c) memcpy(d,s,c)
|
#define MEMCPY(d,s,c) memcpy(d,s,c)
|
||||||
#define INLINE static inline
|
#define INLINE static inline
|
||||||
#define ENDIAN_SWAP16(n) n /* only for poor little endian machines */
|
#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 ********************/
|
/**************** begin JPEG code ********************/
|
||||||
|
|
||||||
|
@ -51,9 +56,14 @@ typedef uint8_t jpeg_pix_t;
|
||||||
*/
|
*/
|
||||||
struct jpeg
|
struct jpeg
|
||||||
{
|
{
|
||||||
|
#ifdef JPEG_FROM_MEM
|
||||||
|
unsigned char *data;
|
||||||
|
unsigned long len;
|
||||||
|
#else
|
||||||
int fd;
|
int fd;
|
||||||
int buf_left;
|
int buf_left;
|
||||||
unsigned char *buf_index;
|
unsigned char *buf_index;
|
||||||
|
#endif
|
||||||
unsigned long int bitbuf;
|
unsigned long int bitbuf;
|
||||||
int bitbuf_bits;
|
int bitbuf_bits;
|
||||||
int marker_ind;
|
int marker_ind;
|
||||||
|
@ -103,6 +113,10 @@ struct jpeg
|
||||||
struct img_part part;
|
struct img_part part;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef JPEG_FROM_MEM
|
||||||
|
static struct jpeg jpeg;
|
||||||
|
#endif
|
||||||
|
|
||||||
INLINE unsigned range_limit(int value)
|
INLINE unsigned range_limit(int value)
|
||||||
{
|
{
|
||||||
#if CONFIG_CPU == SH7034
|
#if CONFIG_CPU == SH7034
|
||||||
|
@ -811,6 +825,37 @@ struct idct_entry idct_tbl[] = {
|
||||||
|
|
||||||
/* JPEG decoder implementation */
|
/* 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)
|
INLINE void fill_buf(struct jpeg* p_jpeg)
|
||||||
{
|
{
|
||||||
p_jpeg->buf_left = read(p_jpeg->fd, p_jpeg->buf, JPEG_READ_BUF_SIZE);
|
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);
|
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) \
|
#define e_skip_bytes(jpeg, count) \
|
||||||
do {\
|
do {\
|
||||||
if (!skip_bytes((jpeg),(count))) \
|
if (!skip_bytes((jpeg),(count))) \
|
||||||
|
@ -863,12 +915,6 @@ do {\
|
||||||
c; \
|
c; \
|
||||||
})
|
})
|
||||||
|
|
||||||
static void putc(struct jpeg* p_jpeg)
|
|
||||||
{
|
|
||||||
p_jpeg->buf_left++;
|
|
||||||
p_jpeg->buf_index--;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Preprocess the JPEG JFIF file */
|
/* Preprocess the JPEG JFIF file */
|
||||||
static int process_markers(struct jpeg* p_jpeg)
|
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? */
|
if (c != 0xFF) /* no marker? */
|
||||||
{
|
{
|
||||||
|
JDEBUGF("Non-marker data\n");
|
||||||
putc(p_jpeg);
|
putc(p_jpeg);
|
||||||
break; /* exit marker processing */
|
break; /* exit marker processing */
|
||||||
}
|
}
|
||||||
|
|
||||||
c = e_getc(p_jpeg, -1);
|
c = e_getc(p_jpeg, -1);
|
||||||
|
JDEBUGF("marker value %X\n",c);
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case 0xFF: /* Fill byte */
|
case 0xFF: /* Fill byte */
|
||||||
|
@ -896,9 +944,11 @@ static int process_markers(struct jpeg* p_jpeg)
|
||||||
|
|
||||||
case 0xC0: /* SOF Huff - Baseline DCT */
|
case 0xC0: /* SOF Huff - Baseline DCT */
|
||||||
{
|
{
|
||||||
|
JDEBUGF("SOF marker ");
|
||||||
ret |= SOF0;
|
ret |= SOF0;
|
||||||
marker_size = e_getc(p_jpeg, -1) << 8; /* Highbyte */
|
marker_size = e_getc(p_jpeg, -1) << 8; /* Highbyte */
|
||||||
marker_size |= e_getc(p_jpeg, -1); /* Lowbyte */
|
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) */
|
n = e_getc(p_jpeg, -1); /* sample precision (= 8 or 12) */
|
||||||
if (n != 8)
|
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->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) << 8; /* Highbyte */
|
||||||
p_jpeg->x_size |= e_getc(p_jpeg, -1); /* Lowbyte */
|
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;
|
n = (marker_size-2-6)/3;
|
||||||
if (e_getc(p_jpeg, -1) != n || (n != 1 && n != 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 */
|
return(-6); /* Arithmetic coding not supported */
|
||||||
|
|
||||||
case 0xD8: /* Start of Image */
|
case 0xD8: /* Start of Image */
|
||||||
|
JDEBUGF("SOI\n");
|
||||||
|
break;
|
||||||
case 0xD9: /* End of Image */
|
case 0xD9: /* End of Image */
|
||||||
|
JDEBUGF("EOI\n");
|
||||||
|
break;
|
||||||
case 0x01: /* for temp private use arith code */
|
case 0x01: /* for temp private use arith code */
|
||||||
|
JDEBUGF("private\n");
|
||||||
break; /* skip parameterless marker */
|
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) << 8; /* Highbyte */
|
||||||
marker_size |= e_getc(p_jpeg, -1); /* Lowbyte */
|
marker_size |= e_getc(p_jpeg, -1); /* Lowbyte */
|
||||||
marker_size -= 2;
|
marker_size -= 2;
|
||||||
|
JDEBUGF("unhandled marker len %d\n", marker_size);
|
||||||
e_skip_bytes(p_jpeg, marker_size); /* skip segment */
|
e_skip_bytes(p_jpeg, marker_size); /* skip segment */
|
||||||
}
|
}
|
||||||
break;
|
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_hscale = p_jpeg->h_scale[1];
|
||||||
int mcu_vscale = p_jpeg->v_scale[1];
|
int mcu_vscale = p_jpeg->v_scale[1];
|
||||||
#else
|
#else
|
||||||
int mcu_hscale = (p_jpeg->h_scale[0] + p_jpeg->frameheader[0].horizontal_sampling - 1);
|
int mcu_hscale = (p_jpeg->h_scale[0] +
|
||||||
int mcu_vscale = (p_jpeg->v_scale[0] + p_jpeg->frameheader[0].vertical_sampling - 1);
|
p_jpeg->frameheader[0].horizontal_sampling - 1);
|
||||||
|
int mcu_vscale = (p_jpeg->v_scale[0] +
|
||||||
|
p_jpeg->frameheader[0].vertical_sampling - 1);
|
||||||
#endif
|
#endif
|
||||||
unsigned int width = p_jpeg->x_mbl << mcu_hscale;
|
unsigned int width = p_jpeg->x_mbl << mcu_hscale;
|
||||||
unsigned int b_width = width * JPEG_PIX_SZ;
|
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.
|
* Reads a JPEG file and puts the data in rockbox format in *bitmap.
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
#ifndef JPEG_FROM_MEM
|
||||||
int read_jpeg_file(const char* filename,
|
int read_jpeg_file(const char* filename,
|
||||||
struct bitmap *bm,
|
struct bitmap *bm,
|
||||||
int maxsize,
|
int maxsize,
|
||||||
|
@ -1874,6 +1935,7 @@ int read_jpeg_file(const char* filename,
|
||||||
close(fd);
|
close(fd);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int calc_scale(int in_size, int out_size)
|
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;
|
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,
|
int read_jpeg_fd(int fd,
|
||||||
|
#endif
|
||||||
struct bitmap *bm,
|
struct bitmap *bm,
|
||||||
int maxsize,
|
int maxsize,
|
||||||
int format,
|
int format,
|
||||||
|
@ -1898,17 +1981,25 @@ int read_jpeg_fd(int fd,
|
||||||
bool resize = false, dither = false;
|
bool resize = false, dither = false;
|
||||||
struct rowset rset;
|
struct rowset rset;
|
||||||
struct dim src_dim;
|
struct dim src_dim;
|
||||||
struct jpeg *p_jpeg = (struct jpeg*)bm->data;
|
|
||||||
int tmp_size = maxsize;
|
|
||||||
int status;
|
int status;
|
||||||
int bm_size;
|
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));
|
ALIGN_BUFFER(p_jpeg, tmp_size, sizeof(int));
|
||||||
/* not enough memory for our struct jpeg */
|
/* not enough memory for our struct jpeg */
|
||||||
if ((size_t)tmp_size < sizeof(struct jpeg))
|
if ((size_t)tmp_size < sizeof(struct jpeg))
|
||||||
return -1;
|
return -1;
|
||||||
|
#endif
|
||||||
memset(p_jpeg, 0, sizeof(struct jpeg));
|
memset(p_jpeg, 0, sizeof(struct jpeg));
|
||||||
|
#ifdef JPEG_FROM_MEM
|
||||||
|
p_jpeg->data = data;
|
||||||
|
p_jpeg->len = len;
|
||||||
|
#else
|
||||||
p_jpeg->fd = fd;
|
p_jpeg->fd = fd;
|
||||||
|
#endif
|
||||||
status = process_markers(p_jpeg);
|
status = process_markers(p_jpeg);
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
return status;
|
return status;
|
||||||
|
@ -1968,14 +2059,16 @@ int read_jpeg_fd(int fd,
|
||||||
char *buf_start = (char *)bm->data + bm_size;
|
char *buf_start = (char *)bm->data + bm_size;
|
||||||
char *buf_end = (char *)bm->data + maxsize;
|
char *buf_end = (char *)bm->data + maxsize;
|
||||||
maxsize = buf_end - buf_start;
|
maxsize = buf_end - buf_start;
|
||||||
|
#ifndef JPEG_FROM_MEM
|
||||||
ALIGN_BUFFER(buf_start, maxsize, sizeof(uint32_t));
|
ALIGN_BUFFER(buf_start, maxsize, sizeof(uint32_t));
|
||||||
if (maxsize < (int)sizeof(struct jpeg))
|
if (maxsize < (int)sizeof(struct jpeg))
|
||||||
return -1;
|
return -1;
|
||||||
memmove(buf_start, p_jpeg, sizeof(struct jpeg));
|
memmove(buf_start, p_jpeg, sizeof(struct jpeg));
|
||||||
p_jpeg = (struct jpeg *)buf_start;
|
p_jpeg = (struct jpeg *)buf_start;
|
||||||
fix_huff_tables(p_jpeg);
|
|
||||||
buf_start += sizeof(struct jpeg);
|
buf_start += sizeof(struct jpeg);
|
||||||
maxsize = buf_end - buf_start;
|
maxsize = buf_end - buf_start;
|
||||||
|
#endif
|
||||||
|
fix_huff_tables(p_jpeg);
|
||||||
#ifdef HAVE_LCD_COLOR
|
#ifdef HAVE_LCD_COLOR
|
||||||
int decode_buf_size = (p_jpeg->x_mbl << p_jpeg->h_scale[1])
|
int decode_buf_size = (p_jpeg->x_mbl << p_jpeg->h_scale[1])
|
||||||
<< p_jpeg->v_scale[1];
|
<< p_jpeg->v_scale[1];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue