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
diff --git a/apps/buffering.c b/apps/buffering.c
index 6160869..1e643c5 100644
--- a/apps/buffering.c
+++ b/apps/buffering.c
@@ -861,7 +861,7 @@
get_albumart_size(bmp);
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);
}
#endif
diff --git a/apps/gui/backdrop.c b/apps/gui/backdrop.c
index 6178894..c95fda9 100644
--- a/apps/gui/backdrop.c
+++ b/apps/gui/backdrop.c
@@ -52,7 +52,7 @@
/* load the image */
bm.data=(char*)backdrop_buffer;
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))
{
@@ -114,7 +114,7 @@
/* load the image */
bm.data=(char*)backdrop_buffer;
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))
{
diff --git a/apps/gui/icon.c b/apps/gui/icon.c
index e11c21c..3e1e793 100644
--- a/apps/gui/icon.c
+++ b/apps/gui/icon.c
@@ -222,7 +222,7 @@
char path[MAX_PATH];
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)
{
*loaded_ok = true;
diff --git a/apps/gui/wps_parser.c b/apps/gui/wps_parser.c
index 307d0bb..acf161b 100644
--- a/apps/gui/wps_parser.c
+++ b/apps/gui/wps_parser.c
@@ -416,7 +416,7 @@
int ret = read_bmp_file(filename, bm,
wps_data->img_buf_free,
- format);
+ format,NULL);
if (ret > 0)
{
diff --git a/apps/plugin.h b/apps/plugin.h
index 20e3a71..81c0696 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -132,12 +132,12 @@
#define PLUGIN_MAGIC 0x526F634B /* RocK */
/* 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
backwards compatibility (and please take the opportunity to sort in any
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 */
enum plugin_status {
@@ -714,7 +714,7 @@
#endif
#ifdef HAVE_LCD_BITMAP
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));
#endif
int (*show_logo)(void);
diff --git a/apps/plugins/CATEGORIES b/apps/plugins/CATEGORIES
index 750d149..09a4476 100644
--- a/apps/plugins/CATEGORIES
+++ b/apps/plugins/CATEGORIES
@@ -92,6 +92,7 @@
test_scanrate,apps
test_touchscreen,apps
test_viewports,apps
+test_greylib_bitmap_scale,viewers
text_editor,apps
vbrfix,viewers
video,viewers
diff --git a/apps/plugins/lib/grey.h b/apps/plugins/lib/grey.h
index 8f8de9d..8c9d40a 100644
--- a/apps/plugins/lib/grey.h
+++ b/apps/plugins/lib/grey.h
@@ -106,6 +106,7 @@
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,
int height);
+extern const struct custom_format format_grey;
/* Text */
void grey_putsxyofs(int x, int y, int ofs, const unsigned char *str);
diff --git a/apps/plugins/lib/grey_draw.c b/apps/plugins/lib/grey_draw.c
index e9812b6..51d340d 100644
--- a/apps/plugins/lib/grey_draw.c
+++ b/apps/plugins/lib/grey_draw.c
@@ -669,3 +669,22 @@
{
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
+};
diff --git a/apps/plugins/pictureflow.c b/apps/plugins/pictureflow.c
index 150d882..0dd9f92 100644
--- a/apps/plugins/pictureflow.c
+++ b/apps/plugins/pictureflow.c
@@ -636,7 +636,7 @@
input_bmp.data = (char *)input_bmp_buffer;
ret = rb->read_bmp_file(arlbumart_file, &input_bmp,
sizeof(fb_data)*MAX_IMG_WIDTH*MAX_IMG_HEIGHT,
- FORMAT_NATIVE);
+ FORMAT_NATIVE, NULL);
if (ret <= 0) {
rb->splash(HZ, "Could not read bmp");
continue; /* skip missing/broken files */
diff --git a/apps/plugins/rockpaint.c b/apps/plugins/rockpaint.c
index 300821b..40d1910 100644
--- a/apps/plugins/rockpaint.c
+++ b/apps/plugins/rockpaint.c
@@ -2967,7 +2967,7 @@
bm.data = (char*)save_buffer;
ret = rb->read_bmp_file( file, &bm, ROWS*COLS*sizeof( fb_data ),
- FORMAT_NATIVE );
+ FORMAT_NATIVE, NULL );
if((bm.width > COLS ) || ( bm.height > ROWS ))
return -1;
diff --git a/apps/plugins/sliding_puzzle.c b/apps/plugins/sliding_puzzle.c
index fa9e093..8a607c9 100644
--- a/apps/plugins/sliding_puzzle.c
+++ b/apps/plugins/sliding_puzzle.c
@@ -340,7 +340,8 @@
rc = rb->read_bmp_file( filename, &main_bitmap,
sizeof(img_buf),
- FORMAT_NATIVE|FORMAT_RESIZE|FORMAT_DITHER);
+ FORMAT_NATIVE|FORMAT_RESIZE|FORMAT_DITHER,
+ NULL);
if( rc > 0 )
{
puzzle_bmp_ptr = (const fb_data *)img_buf;
diff --git a/apps/plugins/test_resize.c b/apps/plugins/test_resize.c
index b0ef787..a608005 100644
--- a/apps/plugins/test_resize.c
+++ b/apps/plugins/test_resize.c
@@ -78,7 +78,7 @@
output_bmp.data = (char*)output_bmp_data;
int ret = rb->read_bmp_file("/test.bmp", &input_bmp, sizeof(input_bmp_data),
- FORMAT_NATIVE);
+ FORMAT_NATIVE, NULL);
if (ret < 0) {
rb->splash(HZ, "Could not load /test.bmp");
diff --git a/apps/plugins/viewers.config b/apps/plugins/viewers.config
index e2babf6..2ec8fe9 100644
--- a/apps/plugins/viewers.config
+++ b/apps/plugins/viewers.config
@@ -25,6 +25,7 @@
wav,viewers/wavplay,9
wav,viewers/wavview,10
wav,viewers/test_codec,-
+bmp,viewers/test_greylib_bitmap_scale,-
bmp,apps/rockpaint,11
bmp,games/sliding_puzzle,11
mpg,viewers/mpegplayer,4
diff --git a/apps/recorder/bmp.c b/apps/recorder/bmp.c
index cc57464..86c057a 100644
--- a/apps/recorder/bmp.c
+++ b/apps/recorder/bmp.c
@@ -147,7 +147,8 @@
int read_bmp_file(const char* filename,
struct bitmap *bm,
int maxsize,
- int format)
+ int format,
+ const struct custom_format *cformat)
{
int fd, ret;
fd = open(filename, O_RDONLY);
@@ -161,7 +162,7 @@
BDEBUGF("read_bmp_file: '%s' remote: %d resize: %d keep_aspect: %d\n",
filename, !!(format & FORMAT_REMOTE), !!(format & FORMAT_RESIZE),
!!(format & FORMAT_KEEP_ASPECT));
- ret = read_bmp_fd(fd, bm, maxsize, format);
+ ret = read_bmp_fd(fd, bm, maxsize, format, cformat);
close(fd);
return ret;
}
@@ -349,7 +350,8 @@
int read_bmp_fd(int fd,
struct bitmap *bm,
int maxsize,
- int format)
+ int format,
+ const struct custom_format *cformat)
{
struct bmp_header bmph;
int padded_width;
@@ -473,7 +475,10 @@
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 */
if (totalsize > maxsize) {
@@ -565,10 +570,15 @@
};
#if LCD_DEPTH > 1 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)
- if (resize)
- return resize_on_load(bm, dither, &src_dim, &rset,
- bitmap + totalsize, maxsize - totalsize,
- store_part_bmp, &ba);
+ if (resize || cformat)
+ {
+ if (resize_on_load(bm, dither, &src_dim, &rset,
+ bitmap + totalsize, maxsize - totalsize,
+ cformat, store_part_bmp, &ba))
+ return totalsize;
+ else
+ return 0;
+ }
int fb_width = BM_WIDTH(bm->width,bm->format,remote);
#endif /* LCD_DEPTH */
diff --git a/apps/recorder/bmp.h b/apps/recorder/bmp.h
index 273e178..c53f295 100644
--- a/apps/recorder/bmp.h
+++ b/apps/recorder/bmp.h
@@ -24,6 +24,7 @@
#include "config.h"
#include "lcd.h"
#include "inttypes.h"
+#include "resize.h"
#ifdef HAVE_REMOTE_LCD
#include "lcd-remote.h"
#endif
@@ -202,10 +203,12 @@
int read_bmp_file(const char* filename,
struct bitmap *bm,
int maxsize,
- int format);
+ int format,
+ const struct custom_format *cformat);
int read_bmp_fd(int fd,
struct bitmap *bm,
int maxsize,
- int format);
+ int format,
+ const struct custom_format *cformat);
#endif
diff --git a/apps/recorder/resize.c b/apps/recorder/resize.c
index 3c1d34f..658cdd8 100644
--- a/apps/recorder/resize.c
+++ b/apps/recorder/resize.c
@@ -114,23 +114,6 @@
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 */
static inline void scale_h_area_setup(struct scaler_context *ctx)
{
@@ -610,6 +593,7 @@
int resize_on_load(struct bitmap *bm, bool dither, struct dim *src,
struct rowset *rset, unsigned char *buf, unsigned int len,
+ const struct custom_format *format,
struct img_part* (*store_part)(void *args),
void *args)
{
@@ -669,7 +653,10 @@
ctx.bm = bm;
ctx.src = src;
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
if (sw > dw)
{
@@ -693,5 +680,5 @@
cpu_boost(false);
if (!ret)
return 0;
- return BM_SIZE(bm->width,bm->height,bm->format,0);
+ return 1;
}
diff --git a/apps/recorder/resize.h b/apps/recorder/resize.h
index 4518307..ca7e632 100644
--- a/apps/recorder/resize.h
+++ b/apps/recorder/resize.h
@@ -20,7 +20,6 @@
****************************************************************************/
#ifndef _RESIZE_H_
#define _RESIZE_H_
-
#include "config.h"
#include "lcd.h"
#include "inttypes.h"
@@ -65,11 +64,35 @@
};
#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 resize_on_load(struct bitmap *bm, bool dither,
struct dim *src, struct rowset *tmp_row,
unsigned char *buf, unsigned int len,
+ const struct custom_format *cformat,
struct img_part* (*store_part)(void *args),
void *args);
#endif /* _RESIZE_H_ */