Move YUV->RGB in JPEG load from before scaler to after scaler. Required change to struct custom_format, so sorted the plugin API as well.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20856 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Andrew Mahone 2009-05-06 04:53:56 +00:00
parent f779160de5
commit eef7945a97
9 changed files with 174 additions and 81 deletions

View file

@ -135,11 +135,18 @@ static const struct plugin_api rockbox_api = {
lcd_blit_mono, lcd_blit_mono,
lcd_blit_grey_phase, lcd_blit_grey_phase,
#endif /* LCD_DEPTH */ #endif /* LCD_DEPTH */
#if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
lcd_blit_pal256,
lcd_pal256_update_pal,
#endif
lcd_puts_style, lcd_puts_style,
lcd_puts_scroll_style, lcd_puts_scroll_style,
#ifdef HAVE_LCD_INVERT #ifdef HAVE_LCD_INVERT
lcd_set_invert_display, lcd_set_invert_display,
#endif /* HAVE_LCD_INVERT */ #endif /* HAVE_LCD_INVERT */
#if defined(HAVE_LCD_MODES)
lcd_set_mode,
#endif
#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
lcd_activation_set_hook, lcd_activation_set_hook,
&button_queue, &button_queue,
@ -571,6 +578,11 @@ static const struct plugin_api rockbox_api = {
#endif #endif
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
read_bmp_file, read_bmp_file,
read_bmp_fd,
#ifdef HAVE_JPEG
read_jpeg_file,
read_jpeg_fd,
#endif
screen_dump_set_hook, screen_dump_set_hook,
#endif #endif
show_logo, show_logo,
@ -632,24 +644,6 @@ static const struct plugin_api rockbox_api = {
appsversion, appsversion,
/* new stuff at the end, sort into place next time /* new stuff at the end, sort into place next time
the API gets incompatible */ the API gets incompatible */
#if defined(HAVE_LCD_MODES)
lcd_set_mode,
#endif
#if defined(HAVE_LCD_MODES)
#if HAVE_LCD_MODES & LCD_MODE_PAL256
lcd_blit_pal256,
lcd_pal256_update_pal,
#endif
#endif
#ifdef HAVE_LCD_BITMAP
#ifdef HAVE_JPEG
read_jpeg_file,
read_jpeg_fd,
#endif
read_bmp_fd,
#endif
}; };
int plugin_load(const char* plugin, const void* parameter) int plugin_load(const char* plugin, const void* parameter)

View file

@ -129,12 +129,12 @@ void* plugin_get_buffer(size_t *buffer_size);
#define PLUGIN_MAGIC 0x526F634B /* RocK */ #define PLUGIN_MAGIC 0x526F634B /* RocK */
/* increase this every time the api struct changes */ /* increase this every time the api struct changes */
#define PLUGIN_API_VERSION 149 #define PLUGIN_API_VERSION 150
/* update this to latest version if a change to the api struct breaks /* update this to latest version if a change to the api struct breaks
backwards compatibility (and please take the opportunity to sort in any backwards compatibility (and please take the opportunity to sort in any
new function which are "waiting" at the end of the function table) */ new function which are "waiting" at the end of the function table) */
#define PLUGIN_MIN_API_VERSION 147 #define PLUGIN_MIN_API_VERSION 150
/* plugin return codes */ /* plugin return codes */
enum plugin_status { enum plugin_status {
@ -220,12 +220,20 @@ struct plugin_api {
int bx, int by, int bwidth, int bheight, int bx, int by, int bwidth, int bheight,
int stride); int stride);
#endif /* LCD_DEPTH */ #endif /* LCD_DEPTH */
#if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
void (*lcd_blit_pal256)(unsigned char *src, int src_x, int src_y, int x, int y,
int width, int height);
void (*lcd_pal256_update_pal)(fb_data *palette);
#endif
void (*lcd_puts_style)(int x, int y, const unsigned char *str, int style); void (*lcd_puts_style)(int x, int y, const unsigned char *str, int style);
void (*lcd_puts_scroll_style)(int x, int y, const unsigned char* string, void (*lcd_puts_scroll_style)(int x, int y, const unsigned char* string,
int style); int style);
#ifdef HAVE_LCD_INVERT #ifdef HAVE_LCD_INVERT
void (*lcd_set_invert_display)(bool yesno); void (*lcd_set_invert_display)(bool yesno);
#endif /* HAVE_LCD_INVERT */ #endif /* HAVE_LCD_INVERT */
#if defined(HAVE_LCD_MODES)
void (*lcd_set_mode)(int mode);
#endif
#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
void (*lcd_activation_set_hook)(void (*enable_hook)(void)); void (*lcd_activation_set_hook)(void (*enable_hook)(void));
@ -723,6 +731,14 @@ struct plugin_api {
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
int (*read_bmp_file)(const char* filename, struct bitmap *bm, int maxsize, int (*read_bmp_file)(const char* filename, struct bitmap *bm, int maxsize,
int format, const struct custom_format *cformat); int format, const struct custom_format *cformat);
int (*read_bmp_fd)(int fd, struct bitmap *bm, int maxsize,
int format, const struct custom_format *cformat);
#ifdef HAVE_JPEG
int (*read_jpeg_file)(const char* filename, struct bitmap *bm, int maxsize,
int format, const struct custom_format *cformat);
int (*read_jpeg_fd)(int fd, struct bitmap *bm, int maxsize,
int format, const struct custom_format *cformat);
#endif
void (*screen_dump_set_hook)(void (*hook)(int fh)); void (*screen_dump_set_hook)(void (*hook)(int fh));
#endif #endif
int (*show_logo)(void); int (*show_logo)(void);
@ -791,29 +807,6 @@ struct plugin_api {
const char *appsversion; const char *appsversion;
/* new stuff at the end, sort into place next time /* new stuff at the end, sort into place next time
the API gets incompatible */ the API gets incompatible */
#if defined(HAVE_LCD_MODES)
void (*lcd_set_mode)(int mode);
#endif
#if defined(HAVE_LCD_MODES)
#if HAVE_LCD_MODES & LCD_MODE_PAL256
void (*lcd_blit_pal256)(unsigned char *src, int src_x, int src_y, int x, int y,
int width, int height);
void (*lcd_pal256_update_pal)(fb_data *palette);
#endif
#endif
#ifdef HAVE_LCD_BITMAP
#ifdef HAVE_JPEG
int (*read_jpeg_file)(const char* filename, struct bitmap *bm, int maxsize,
int format, const struct custom_format *cformat);
int (*read_jpeg_fd)(int fd, struct bitmap *bm, int maxsize,
int format, const struct custom_format *cformat);
#endif
int (*read_bmp_fd)(int fd, struct bitmap *bm, int maxsize,
int format, const struct custom_format *cformat);
#endif
}; };
/* plugin header */ /* plugin header */

View file

@ -48,13 +48,6 @@
#define COMPONENT_SHIFT 15 #define COMPONENT_SHIFT 15
#define MATRIX_SHIFT 7 #define MATRIX_SHIFT 7
static inline int clamp_component(int x)
{
if ((unsigned)x > YUV_WHITE)
x = x < 0 ? 0 : YUV_WHITE;
return x;
}
static inline int clamp_component_bits(int x, int bits) static inline int clamp_component_bits(int x, int bits)
{ {
if ((unsigned)x > (1u << bits) - 1) if ((unsigned)x > (1u << bits) - 1)

View file

@ -634,13 +634,43 @@ static void output_row_transposed(uint32_t row, void * row_in,
#endif #endif
} }
#ifdef HAVE_LCD_COLOR
static void output_row_transposed_fromyuv(uint32_t row, void * row_in,
struct scaler_context *ctx)
{
pix_t *dest = (pix_t*)ctx->bm->data + row;
pix_t *end = dest + ctx->bm->height * ctx->bm->width;
struct uint32_rgb *qp = (struct uint32_rgb*)row_in;
for (; dest < end; dest += ctx->bm->height)
{
unsigned r, g, b, y, u, v;
y = SC_MUL(qp->b + ctx->round, ctx->divisor);
u = SC_MUL(qp->g + ctx->round, ctx->divisor);
v = SC_MUL(qp->r + ctx->round, ctx->divisor);
qp++;
yuv_to_rgb(y, u, v, &r, &g, &b);
r = (31 * r + (r >> 3) + 127) >> 8;
g = (63 * g + (g >> 2) + 127) >> 8;
b = (31 * b + (b >> 3) + 127) >> 8;
*dest = LCD_RGBPACK_LCD(r, g, b);
}
}
#endif
static unsigned int get_size(struct bitmap *bm) static unsigned int get_size(struct bitmap *bm)
{ {
return bm->width * bm->height * sizeof(pix_t); return bm->width * bm->height * sizeof(pix_t);
} }
const struct custom_format format_transposed = { const struct custom_format format_transposed = {
#ifdef HAVE_LCD_COLOR
.output_row = {
output_row_transposed,
output_row_transposed_fromyuv
},
#else
.output_row = output_row_transposed, .output_row = output_row_transposed,
#endif
.get_size = get_size .get_size = get_size
}; };

View file

@ -603,7 +603,7 @@ int read_bmp_fd(int fd,
{ {
if (resize_on_load(bm, dither, &src_dim, &rset, if (resize_on_load(bm, dither, &src_dim, &rset,
bitmap + totalsize, maxsize - totalsize, bitmap + totalsize, maxsize - totalsize,
cformat, store_part_bmp, &ba)) cformat, IF_PIX_FMT(0,) store_part_bmp, &ba))
return totalsize; return totalsize;
else else
return 0; return 0;

View file

@ -28,6 +28,8 @@
#ifndef _JPEG_COMMON_H #ifndef _JPEG_COMMON_H
#define _JPEG_COMMON_H #define _JPEG_COMMON_H
#include "bmp.h"
#define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */ #define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */
#define JPEG_READ_BUF_SIZE 16 #define JPEG_READ_BUF_SIZE 16
struct derived_tbl struct derived_tbl
@ -51,6 +53,55 @@ struct derived_tbl
#define QUANT_TABLE_LENGTH 64 #define QUANT_TABLE_LENGTH 64
/*
* Conversion of full 0-255 range YCrCb to RGB:
* |R| |1.000000 -0.000001 1.402000| |Y'|
* |G| = |1.000000 -0.334136 -0.714136| |Pb|
* |B| |1.000000 1.772000 0.000000| |Pr|
* Scaled (yields s15-bit output):
* |R| |128 0 179| |Y |
* |G| = |128 -43 -91| |Cb - 128|
* |B| |128 227 0| |Cr - 128|
*/
#define YFAC 128
#define RVFAC 179
#define GUFAC (-43)
#define GVFAC (-91)
#define BUFAC 227
#define COMPONENT_SHIFT 15
struct uint8_yuv {
uint8_t y;
uint8_t u;
uint8_t v;
};
union uint8_rgbyuv {
struct uint8_yuv yuv;
struct uint8_rgb rgb;
};
static inline int clamp_component(int x)
{
if ((unsigned)x > 255)
x = x < 0 ? 0 : 255;
return x;
}
#include <debug.h>
static inline void yuv_to_rgb(int y, int u, int v, unsigned *r, unsigned *g, unsigned *b)
{
int rv, guv, bu;
y = y * YFAC + (YFAC >> 1);
u = u - 128;
v = v - 128;
rv = RVFAC * v;
guv = GUFAC * u + GVFAC * v;
bu = BUFAC * u;
*r = clamp_component((y + rv) / YFAC);
*g = clamp_component((y + guv) / YFAC);
*b = clamp_component((y + bu) / YFAC);
}
/* for type of Huffman table */ /* for type of Huffman table */
#define DC_LEN 28 #define DC_LEN 28
#define AC_LEN 178 #define AC_LEN 178

View file

@ -153,13 +153,6 @@ INLINE unsigned range_limit(int value)
#endif #endif
} }
static inline int clamp_component(int x)
{
if ((unsigned)x > 255)
x = x < 0 ? 0 : 255;
return x;
}
/* IDCT implementation */ /* IDCT implementation */
@ -1810,27 +1803,8 @@ static struct img_part *store_row_jpeg(void *jpeg_args)
unsigned int xp; unsigned int xp;
int yp; int yp;
unsigned char *row = out; unsigned char *row = out;
if (p_jpeg->blocks > 1) { if (p_jpeg->blocks == 1)
for (yp = 0; yp < height; yp++, row += b_width)
{ {
unsigned char *px = row;
for (xp = 0; xp < 1U << p_jpeg->h_scale[1];
xp++, px += JPEG_PIX_SZ)
{
int y, u, v, rv, guv, bu;
y = px[0] * YFAC + (YFAC >> 1);
u = px[1] - 128;
v = px[2] - 128;
rv = RVFAC * v;
guv = GUFAC * u + GVFAC * v;
bu = BUFAC * u;
struct uint8_rgb *rgb = (struct uint8_rgb *)px;
rgb->red = clamp_component((y + rv) / YFAC);
rgb->green = clamp_component((y + guv) / YFAC);
rgb->blue = clamp_component((y + bu) / YFAC);
}
}
} else {
for (yp = 0; yp < height; yp++, row += b_width) for (yp = 0; yp < height; yp++, row += b_width)
{ {
unsigned char *px = row; unsigned char *px = row;
@ -2003,7 +1977,7 @@ int read_jpeg_fd(int fd,
rset.rowstop = bm->height; rset.rowstop = bm->height;
rset.rowstep = 1; rset.rowstep = 1;
if (resize_on_load(bm, dither, &src_dim, &rset, buf_start, maxsize, cformat, if (resize_on_load(bm, dither, &src_dim, &rset, buf_start, maxsize, cformat,
store_row_jpeg, p_jpeg)) IF_PIX_FMT(p_jpeg->blocks == 1 ? 0 : 1,) store_row_jpeg, p_jpeg))
return bm_size; return bm_size;
else else
return 0; return 0;

View file

@ -59,6 +59,7 @@
#undef DEBUGF #undef DEBUGF
#define DEBUGF(...) #define DEBUGF(...)
#endif #endif
#include <jpeg_load.h>
#if CONFIG_CPU == SH7034 #if CONFIG_CPU == SH7034
/* 16*16->32 bit multiplication is a single instrcution on the SH1 */ /* 16*16->32 bit multiplication is a single instrcution on the SH1 */
@ -516,6 +517,35 @@ static inline bool scale_v_linear(struct rowset *rset,
} }
#endif /* HAVE_UPSCALER */ #endif /* HAVE_UPSCALER */
#if defined(HAVE_LCD_COLOR) && (defined(HAVE_JPEG) || defined(PLUGIN))
void output_row_native_fromyuv(uint32_t row, void * row_in,
struct scaler_context *ctx)
{
int col;
int fb_width = BM_WIDTH(ctx->bm->width,FORMAT_NATIVE,0);
uint8_t dy = DITHERY(row);
struct uint32_rgb *qp = (struct uint32_rgb *)row_in;
SDEBUGF("output_row: y: %lu in: %p\n",row, row_in);
fb_data *dest = (fb_data *)ctx->bm->data + fb_width * row;
int delta = 127;
unsigned r, g, b, y, u, v;
for (col = 0; col < ctx->bm->width; col++) {
if (ctx->dither)
delta = DITHERXDY(col,dy);
y = SC_MUL(qp->b + ctx->round, ctx->divisor);
u = SC_MUL(qp->g + ctx->round, ctx->divisor);
v = SC_MUL(qp->r + ctx->round, ctx->divisor);
qp++;
yuv_to_rgb(y, u, v, &r, &g, &b);
r = (31 * r + (r >> 3) + delta) >> 8;
g = (63 * g + (g >> 2) + delta) >> 8;
b = (31 * b + (b >> 3) + delta) >> 8;
*dest++ = LCD_RGBPACK_LCD(r, g, b);
}
}
#endif
#if !defined(PLUGIN) || LCD_DEPTH > 1 #if !defined(PLUGIN) || LCD_DEPTH > 1
void output_row_native(uint32_t row, void * row_in, void output_row_native(uint32_t row, void * row_in,
struct scaler_context *ctx) struct scaler_context *ctx)
@ -614,7 +644,14 @@ unsigned int get_size_native(struct bitmap *bm)
} }
const struct custom_format format_native = { const struct custom_format format_native = {
#if defined(HAVE_LCD_COLOR) && (defined(HAVE_JPEG) || defined(PLUGIN))
.output_row = {
output_row_native,
output_row_native_fromyuv
},
#else
.output_row = output_row_native, .output_row = output_row_native,
#endif
.get_size = get_size_native .get_size = get_size_native
}; };
#endif #endif
@ -622,6 +659,7 @@ const struct custom_format format_native = {
int resize_on_load(struct bitmap *bm, bool dither, struct dim *src, int resize_on_load(struct bitmap *bm, bool dither, struct dim *src,
struct rowset *rset, unsigned char *buf, unsigned int len, struct rowset *rset, unsigned char *buf, unsigned int len,
const struct custom_format *format, const struct custom_format *format,
IF_PIX_FMT(int format_index,)
struct img_part* (*store_part)(void *args), struct img_part* (*store_part)(void *args),
void *args) void *args)
{ {
@ -683,10 +721,19 @@ int resize_on_load(struct bitmap *bm, bool dither, struct dim *src,
ctx.src = src; ctx.src = src;
ctx.dither = dither; ctx.dither = dither;
#if !defined(PLUGIN) #if !defined(PLUGIN)
#if defined(HAVE_LCD_COLOR) && defined(HAVE_JPEG)
ctx.output_row = format_index ? output_row_native_fromyuv
: output_row_native;
#else
ctx.output_row = output_row_native; ctx.output_row = output_row_native;
#endif
if (format) if (format)
#endif #endif
#if defined(HAVE_LCD_COLOR) && (defined(HAVE_JPEG) || defined(PLUGIN))
ctx.output_row = format->output_row[format_index];
#else
ctx.output_row = format->output_row; ctx.output_row = format->output_row;
#endif
#ifdef HAVE_UPSCALER #ifdef HAVE_UPSCALER
if (sw > dw) if (sw > dw)
{ {

View file

@ -143,8 +143,18 @@ struct scaler_context {
bool (*h_scaler)(void*,struct scaler_context*, bool); bool (*h_scaler)(void*,struct scaler_context*, bool);
}; };
#if defined(HAVE_LCD_COLOR) && (defined(HAVE_JPEG) || defined(PLUGIN))
#define IF_PIX_FMT(...) __VA_ARGS__
#else
#define IF_PIX_FMT(...)
#endif
struct custom_format { struct custom_format {
#if defined(HAVE_LCD_COLOR)
void (*output_row[2])(uint32_t,void*,struct scaler_context*);
#else
void (*output_row)(uint32_t,void*,struct scaler_context*); void (*output_row)(uint32_t,void*,struct scaler_context*);
#endif
unsigned int (*get_size)(struct bitmap *bm); unsigned int (*get_size)(struct bitmap *bm);
}; };
@ -161,6 +171,7 @@ int resize_on_load(struct bitmap *bm, bool dither,
struct dim *src, struct rowset *tmp_row, struct dim *src, struct rowset *tmp_row,
unsigned char *buf, unsigned int len, unsigned char *buf, unsigned int len,
const struct custom_format *cformat, const struct custom_format *cformat,
IF_PIX_FMT(int format_index,)
struct img_part* (*store_part)(void *args), struct img_part* (*store_part)(void *args),
void *args); void *args);