Make scaler output truly pluggable, add an 8-bit greyscale output to

pluginlib for use with greylib, and add source for a test scaled bmp
viewer using greylib.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19593 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Andrew Mahone 2008-12-26 07:05:13 +00:00
parent f7fa7e5ad5
commit 9058620849
17 changed files with 88 additions and 42 deletions

View file

@ -861,7 +861,7 @@ static int load_bitmap(int fd)
get_albumart_size(bmp); get_albumart_size(bmp);
rc = read_bmp_fd(fd, bmp, free, FORMAT_NATIVE|FORMAT_DITHER| rc = read_bmp_fd(fd, bmp, free, FORMAT_NATIVE|FORMAT_DITHER|
FORMAT_RESIZE|FORMAT_KEEP_ASPECT); FORMAT_RESIZE|FORMAT_KEEP_ASPECT, NULL);
return rc + (rc > 0 ? sizeof(struct bitmap) : 0); return rc + (rc > 0 ? sizeof(struct bitmap) : 0);
} }
#endif #endif

View file

@ -52,7 +52,7 @@ static bool load_backdrop(const char* filename, fb_data* backdrop_buffer)
/* load the image */ /* load the image */
bm.data=(char*)backdrop_buffer; bm.data=(char*)backdrop_buffer;
ret = read_bmp_file(filename, &bm, sizeof(main_backdrop), ret = read_bmp_file(filename, &bm, sizeof(main_backdrop),
FORMAT_NATIVE | FORMAT_DITHER); FORMAT_NATIVE | FORMAT_DITHER, NULL);
if ((ret > 0) && (bm.width == LCD_WIDTH) && (bm.height == LCD_HEIGHT)) if ((ret > 0) && (bm.width == LCD_WIDTH) && (bm.height == LCD_HEIGHT))
{ {
@ -114,7 +114,7 @@ static bool load_remote_backdrop(const char* filename, fb_remote_data* backdrop_
/* load the image */ /* load the image */
bm.data=(char*)backdrop_buffer; bm.data=(char*)backdrop_buffer;
ret = read_bmp_file(filename, &bm, sizeof(main_backdrop), ret = read_bmp_file(filename, &bm, sizeof(main_backdrop),
FORMAT_NATIVE | FORMAT_DITHER | FORMAT_REMOTE); FORMAT_NATIVE | FORMAT_DITHER | FORMAT_REMOTE, NULL);
if ((ret > 0) && (bm.width == LCD_REMOTE_WIDTH) && (bm.height == LCD_REMOTE_HEIGHT)) if ((ret > 0) && (bm.width == LCD_REMOTE_WIDTH) && (bm.height == LCD_REMOTE_HEIGHT))
{ {

View file

@ -222,7 +222,7 @@ static void load_icons(const char* filename, enum Iconset iconset,
char path[MAX_PATH]; char path[MAX_PATH];
snprintf(path, sizeof(path), "%s/%s.bmp", ICON_DIR, filename); snprintf(path, sizeof(path), "%s/%s.bmp", ICON_DIR, filename);
size_read = read_bmp_file(path, bmp, IMG_BUFSIZE, bmpformat); size_read = read_bmp_file(path, bmp, IMG_BUFSIZE, bmpformat, NULL);
if (size_read > 0) if (size_read > 0)
{ {
*loaded_ok = true; *loaded_ok = true;

View file

@ -416,7 +416,7 @@ static bool load_bitmap(struct wps_data *wps_data,
int ret = read_bmp_file(filename, bm, int ret = read_bmp_file(filename, bm,
wps_data->img_buf_free, wps_data->img_buf_free,
format); format,NULL);
if (ret > 0) if (ret > 0)
{ {

View file

@ -132,12 +132,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 130 #define PLUGIN_API_VERSION 131
/* 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 130 #define PLUGIN_MIN_API_VERSION 131
/* plugin return codes */ /* plugin return codes */
enum plugin_status { enum plugin_status {
@ -714,7 +714,7 @@ struct plugin_api {
#endif #endif
#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); int format, const struct custom_format *cformat);
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);

View file

@ -92,6 +92,7 @@ test_sampr,apps
test_scanrate,apps test_scanrate,apps
test_touchscreen,apps test_touchscreen,apps
test_viewports,apps test_viewports,apps
test_greylib_bitmap_scale,viewers
text_editor,apps text_editor,apps
vbrfix,viewers vbrfix,viewers
video,viewers video,viewers

View file

@ -106,6 +106,7 @@ void grey_ub_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
int stride, int x, int y, int width, int height); int stride, int x, int y, int width, int height);
void grey_ub_gray_bitmap(const unsigned char *src, int x, int y, int width, void grey_ub_gray_bitmap(const unsigned char *src, int x, int y, int width,
int height); int height);
extern const struct custom_format format_grey;
/* Text */ /* Text */
void grey_putsxyofs(int x, int y, int ofs, const unsigned char *str); void grey_putsxyofs(int x, int y, int ofs, const unsigned char *str);

View file

@ -669,3 +669,22 @@ void grey_ub_gray_bitmap(const unsigned char *src, int x, int y, int width,
{ {
grey_ub_gray_bitmap_part(src, 0, 0, width, x, y, width, height); grey_ub_gray_bitmap_part(src, 0, 0, width, x, y, width, height);
} }
static void output_row_grey(uint32_t row, void * row_in, struct scaler_context *ctx)
{
int col;
uint32_t *qp = (uint32_t*)row_in;
uint8_t *dest = (uint8_t*)ctx->bm->data + ctx->bm->width * row;
for (col = 0; col < ctx->bm->width; col++)
*dest++ = ((*qp++) + ctx->round) * (uint64_t)ctx->divisor >> 32;
}
static unsigned int get_size_grey(struct bitmap *bm)
{
return bm->width * bm->height;
}
const struct custom_format format_grey = {
.output_row = output_row_grey,
.get_size = get_size_grey
};

View file

@ -636,7 +636,7 @@ bool create_albumart_cache(bool force)
input_bmp.data = (char *)input_bmp_buffer; input_bmp.data = (char *)input_bmp_buffer;
ret = rb->read_bmp_file(arlbumart_file, &input_bmp, ret = rb->read_bmp_file(arlbumart_file, &input_bmp,
sizeof(fb_data)*MAX_IMG_WIDTH*MAX_IMG_HEIGHT, sizeof(fb_data)*MAX_IMG_WIDTH*MAX_IMG_HEIGHT,
FORMAT_NATIVE); FORMAT_NATIVE, NULL);
if (ret <= 0) { if (ret <= 0) {
rb->splash(HZ, "Could not read bmp"); rb->splash(HZ, "Could not read bmp");
continue; /* skip missing/broken files */ continue; /* skip missing/broken files */

View file

@ -2967,7 +2967,7 @@ static int load_bitmap( const char *file )
bm.data = (char*)save_buffer; bm.data = (char*)save_buffer;
ret = rb->read_bmp_file( file, &bm, ROWS*COLS*sizeof( fb_data ), ret = rb->read_bmp_file( file, &bm, ROWS*COLS*sizeof( fb_data ),
FORMAT_NATIVE ); FORMAT_NATIVE, NULL );
if((bm.width > COLS ) || ( bm.height > ROWS )) if((bm.width > COLS ) || ( bm.height > ROWS ))
return -1; return -1;

View file

@ -340,7 +340,8 @@ static bool load_resize_bitmap(void)
rc = rb->read_bmp_file( filename, &main_bitmap, rc = rb->read_bmp_file( filename, &main_bitmap,
sizeof(img_buf), sizeof(img_buf),
FORMAT_NATIVE|FORMAT_RESIZE|FORMAT_DITHER); FORMAT_NATIVE|FORMAT_RESIZE|FORMAT_DITHER,
NULL);
if( rc > 0 ) if( rc > 0 )
{ {
puzzle_bmp_ptr = (const fb_data *)img_buf; puzzle_bmp_ptr = (const fb_data *)img_buf;

View file

@ -78,7 +78,7 @@ enum plugin_status plugin_start(const struct plugin_api* api, const void* parame
output_bmp.data = (char*)output_bmp_data; output_bmp.data = (char*)output_bmp_data;
int ret = rb->read_bmp_file("/test.bmp", &input_bmp, sizeof(input_bmp_data), int ret = rb->read_bmp_file("/test.bmp", &input_bmp, sizeof(input_bmp_data),
FORMAT_NATIVE); FORMAT_NATIVE, NULL);
if (ret < 0) { if (ret < 0) {
rb->splash(HZ, "Could not load /test.bmp"); rb->splash(HZ, "Could not load /test.bmp");

View file

@ -25,6 +25,7 @@ wav,viewers/mp3_encoder,-
wav,viewers/wavplay,9 wav,viewers/wavplay,9
wav,viewers/wavview,10 wav,viewers/wavview,10
wav,viewers/test_codec,- wav,viewers/test_codec,-
bmp,viewers/test_greylib_bitmap_scale,-
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

View file

@ -147,7 +147,8 @@ const unsigned short vi_pattern[4] = {
int read_bmp_file(const char* filename, int read_bmp_file(const char* filename,
struct bitmap *bm, struct bitmap *bm,
int maxsize, int maxsize,
int format) int format,
const struct custom_format *cformat)
{ {
int fd, ret; int fd, ret;
fd = open(filename, O_RDONLY); fd = open(filename, O_RDONLY);
@ -161,7 +162,7 @@ int read_bmp_file(const char* filename,
BDEBUGF("read_bmp_file: '%s' remote: %d resize: %d keep_aspect: %d\n", BDEBUGF("read_bmp_file: '%s' remote: %d resize: %d keep_aspect: %d\n",
filename, !!(format & FORMAT_REMOTE), !!(format & FORMAT_RESIZE), filename, !!(format & FORMAT_REMOTE), !!(format & FORMAT_RESIZE),
!!(format & FORMAT_KEEP_ASPECT)); !!(format & FORMAT_KEEP_ASPECT));
ret = read_bmp_fd(fd, bm, maxsize, format); ret = read_bmp_fd(fd, bm, maxsize, format, cformat);
close(fd); close(fd);
return ret; return ret;
} }
@ -349,7 +350,8 @@ static inline int rgbcmp(struct uint8_rgb rgb1, struct uint8_rgb rgb2)
int read_bmp_fd(int fd, int read_bmp_fd(int fd,
struct bitmap *bm, struct bitmap *bm,
int maxsize, int maxsize,
int format) int format,
const struct custom_format *cformat)
{ {
struct bmp_header bmph; struct bmp_header bmph;
int padded_width; int padded_width;
@ -473,7 +475,10 @@ int read_bmp_fd(int fd,
rset.rowstop = -1; rset.rowstop = -1;
} }
totalsize = BM_SIZE(bm->width,bm->height,format,remote); if (cformat)
totalsize = cformat->get_size(bm);
else
totalsize = BM_SIZE(bm->width,bm->height,format,remote);
/* Check if this fits the buffer */ /* Check if this fits the buffer */
if (totalsize > maxsize) { if (totalsize > maxsize) {
@ -565,10 +570,15 @@ int read_bmp_fd(int fd,
}; };
#if LCD_DEPTH > 1 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1) #if LCD_DEPTH > 1 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)
if (resize) if (resize || cformat)
return resize_on_load(bm, dither, &src_dim, &rset, {
bitmap + totalsize, maxsize - totalsize, if (resize_on_load(bm, dither, &src_dim, &rset,
store_part_bmp, &ba); bitmap + totalsize, maxsize - totalsize,
cformat, store_part_bmp, &ba))
return totalsize;
else
return 0;
}
int fb_width = BM_WIDTH(bm->width,bm->format,remote); int fb_width = BM_WIDTH(bm->width,bm->format,remote);
#endif /* LCD_DEPTH */ #endif /* LCD_DEPTH */

View file

@ -24,6 +24,7 @@
#include "config.h" #include "config.h"
#include "lcd.h" #include "lcd.h"
#include "inttypes.h" #include "inttypes.h"
#include "resize.h"
#ifdef HAVE_REMOTE_LCD #ifdef HAVE_REMOTE_LCD
#include "lcd-remote.h" #include "lcd-remote.h"
#endif #endif
@ -202,10 +203,12 @@ extern const unsigned short vi_pattern[4];
int read_bmp_file(const char* filename, int read_bmp_file(const char* filename,
struct bitmap *bm, struct bitmap *bm,
int maxsize, int maxsize,
int format); int format,
const struct custom_format *cformat);
int read_bmp_fd(int fd, int read_bmp_fd(int fd,
struct bitmap *bm, struct bitmap *bm,
int maxsize, int maxsize,
int format); int format,
const struct custom_format *cformat);
#endif #endif

View file

@ -114,23 +114,6 @@ int recalc_dimension(struct dim *dst, struct dim *src)
return false; \ return false; \
} }
/* struct which containers various parameters shared between vertical scaler,
horizontal scaler, and row output
*/
struct scaler_context {
uint32_t divisor;
uint32_t round;
struct bitmap *bm;
struct dim *src;
unsigned char *buf;
bool dither;
int len;
void *args;
struct img_part* (*store_part)(void *);
void (*output_row)(uint32_t,void*,struct scaler_context*);
bool (*h_scaler)(void*,struct scaler_context*, bool);
};
/* Set up rounding and scale factors for horizontal area scaler */ /* Set up rounding and scale factors for horizontal area scaler */
static inline void scale_h_area_setup(struct scaler_context *ctx) static inline void scale_h_area_setup(struct scaler_context *ctx)
{ {
@ -610,6 +593,7 @@ void output_row_native(uint32_t row, void * row_in, struct scaler_context *ctx)
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,
struct img_part* (*store_part)(void *args), struct img_part* (*store_part)(void *args),
void *args) void *args)
{ {
@ -669,7 +653,10 @@ int resize_on_load(struct bitmap *bm, bool dither, struct dim *src,
ctx.bm = bm; ctx.bm = bm;
ctx.src = src; ctx.src = src;
ctx.dither = dither; ctx.dither = dither;
ctx.output_row = output_row_native; if (format)
ctx.output_row = format->output_row;
else
ctx.output_row = output_row_native;
#ifdef HAVE_UPSCALER #ifdef HAVE_UPSCALER
if (sw > dw) if (sw > dw)
{ {
@ -693,5 +680,5 @@ int resize_on_load(struct bitmap *bm, bool dither, struct dim *src,
cpu_boost(false); cpu_boost(false);
if (!ret) if (!ret)
return 0; return 0;
return BM_SIZE(bm->width,bm->height,bm->format,0); return 1;
} }

View file

@ -20,7 +20,6 @@
****************************************************************************/ ****************************************************************************/
#ifndef _RESIZE_H_ #ifndef _RESIZE_H_
#define _RESIZE_H_ #define _RESIZE_H_
#include "config.h" #include "config.h"
#include "lcd.h" #include "lcd.h"
#include "inttypes.h" #include "inttypes.h"
@ -65,11 +64,35 @@ struct uint32_rgb {
}; };
#endif #endif
/* struct which contains various parameters shared between vertical scaler,
horizontal scaler, and row output
*/
struct scaler_context {
uint32_t divisor;
uint32_t round;
struct bitmap *bm;
struct dim *src;
unsigned char *buf;
bool dither;
int len;
void *args;
struct img_part* (*store_part)(void *);
void (*output_row)(uint32_t,void*,struct scaler_context*);
bool (*h_scaler)(void*,struct scaler_context*, bool);
};
struct custom_format {
void (*output_row)(uint32_t,void*,struct scaler_context*);
unsigned int (*get_size)(struct bitmap *bm);
};
struct rowset;
int recalc_dimension(struct dim *dst, struct dim *src); int recalc_dimension(struct dim *dst, struct dim *src);
int resize_on_load(struct bitmap *bm, bool dither, 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,
struct img_part* (*store_part)(void *args), struct img_part* (*store_part)(void *args),
void *args); void *args);
#endif /* _RESIZE_H_ */ #endif /* _RESIZE_H_ */