From 6aa36c66a356f72efe9b23e895b19acb8e825943 Mon Sep 17 00:00:00 2001 From: Nicolas Pennequin Date: Sun, 6 Apr 2008 22:30:50 +0000 Subject: Commit FS#8308 (Port of imlib2 based smooth scaling) by Jonas Hurrelmann. It could be made smaller by taking out some special cases, but I'm leaving them in for now because size isn't really a concern until we decide to move it into the core (if we ever do). test_resize now allows to choose between both resize methods for comparison. sliding_puzzle is made to use the smooth scaling. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17001 a1c6a512-1295-4272-9138-f99709370657 --- apps/plugins/lib/SOURCES | 1 + apps/plugins/lib/bmp.h | 6 + apps/plugins/lib/bmp_smooth_scale.c | 444 ++++++++++++++++++++++++++++++++++++ apps/plugins/sliding_puzzle.c | 2 +- apps/plugins/test_resize.c | 55 +++-- 5 files changed, 491 insertions(+), 17 deletions(-) create mode 100644 apps/plugins/lib/bmp_smooth_scale.c diff --git a/apps/plugins/lib/SOURCES b/apps/plugins/lib/SOURCES index 6a44c80ffa..d696db8ede 100644 --- a/apps/plugins/lib/SOURCES +++ b/apps/plugins/lib/SOURCES @@ -32,6 +32,7 @@ xlcd_draw.c xlcd_scroll.c #if LCD_DEPTH>1 bmp.c +bmp_smooth_scale.c #endif #endif pluginlib_actions.c diff --git a/apps/plugins/lib/bmp.h b/apps/plugins/lib/bmp.h index 3e14243d30..10f71865f7 100644 --- a/apps/plugins/lib/bmp.h +++ b/apps/plugins/lib/bmp.h @@ -35,4 +35,10 @@ int save_bmp_file( char* filename, struct bitmap *bm, struct plugin_api* rb ); */ void simple_resize_bitmap(struct bitmap *src, struct bitmap *dst); +/** + Advanced image scale from src to dst (bilinear) based on imlib2. + Source and destination dimensions are read from the struct bitmap. + */ +void smooth_resize_bitmap(struct bitmap *src, struct bitmap *dst); + #endif diff --git a/apps/plugins/lib/bmp_smooth_scale.c b/apps/plugins/lib/bmp_smooth_scale.c new file mode 100644 index 0000000000..a500bfa792 --- /dev/null +++ b/apps/plugins/lib/bmp_smooth_scale.c @@ -0,0 +1,444 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Code for the scaling algorithm: + * Imlib2 is (C) Carsten Haitzler and various contributors. The MMX code + * is by Willem Monsuwe . Additional modifications are by + * (C) Daniel M. Duley. + * + * Port to Rockbox + * Copyright (C) 2007 Jonas Hurrelmann (j@outpo.st) + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +/* + * Copyright (C) 2004, 2005 Daniel M. Duley + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* OTHER CREDITS: + * + * This is the normal smoothscale method, based on Imlib2's smoothscale. + * + * Originally I took the algorithm used in NetPBM and Qt and added MMX/3dnow + * optimizations. It ran in about 1/2 the time as Qt. Then I ported Imlib's + * C algorithm and it ran at about the same speed as my MMX optimized one... + * Finally I ported Imlib's MMX version and it ran in less than half the + * time as my MMX algorithm, (taking only a quarter of the time Qt does). + * After further optimization it seems to run at around 1/6th. + * + * Changes include formatting, namespaces and other C++'ings, removal of old + * #ifdef'ed code, and removal of unneeded border calculation code. + * + * Imlib2 is (C) Carsten Haitzler and various contributors. The MMX code + * is by Willem Monsuwe . All other modifications are + * (C) Daniel M. Duley. + */ + +#include "bmp.h" +#include "lcd.h" + +void smooth_resize_bitmap(struct bitmap *src_bmp, struct bitmap *dest_bmp) +{ + fb_data *sptr, *dptr; + int x, y, end; + int val_y = 0, val_x; + const int sw = src_bmp->width; + const int sh = src_bmp->height; + const int dw = dest_bmp->width; + const int dh = dest_bmp->height; + const int inc_x = (sw << 16) / dw; + const int inc_y = (sh << 16) / dh; + const int Cp_x = ((dw << 14) / sw) + 1; + const int Cp_y = ((dh << 14) / sh) + 1; + const int xup_yup = (dw >= sw) + ((dh >= sh) << 1); + const int dow = dw; + const int sow = sw; + fb_data *src = (fb_data*)src_bmp->data; + fb_data *dest = (fb_data*)dest_bmp->data; + int XAP, YAP, INV_YAP, INV_XAP; + int xpoint; + fb_data *ypoint; + + end = dw; + /* scaling up both ways */ + if (xup_yup == 3) { + /* go through every scanline in the output buffer */ + for (y = 0; y < dh; y++) { + /* calculate the source line we'll scan from */ + ypoint = src + ((val_y >> 16) * sw); + YAP = ((val_y >> 16) >= (sh - 1)) ? 0 : (val_y >> 8) - ((val_y >> 8) & 0xffffff00); + INV_YAP = 256 - YAP; + + val_y += inc_y; + val_x = 0; + + dptr = dest + (y * dow); + sptr = ypoint; + if (YAP > 0) { + for (x = 0; x < end; x++) { + int r = 0, g = 0, b = 0; + int rr = 0, gg = 0, bb = 0; + fb_data *pix; + + xpoint = (val_x >> 16); + XAP = ((val_x >> 16) >= (sw - 1)) ? 0 : (val_x >> 8) - ((val_x >> 8) & 0xffffff00); + INV_XAP = 256 - XAP; + val_x += inc_x; + + if (XAP > 0) { + pix = ypoint + xpoint; + r = RGB_UNPACK_RED(*pix) * INV_XAP; + g = RGB_UNPACK_GREEN(*pix) * INV_XAP; + b = RGB_UNPACK_BLUE(*pix) * INV_XAP; + pix++; + r += RGB_UNPACK_RED(*pix) * XAP; + g += RGB_UNPACK_GREEN(*pix) * XAP; + b += RGB_UNPACK_BLUE(*pix) * XAP; + pix += sow; + rr = RGB_UNPACK_RED(*pix) * XAP; + gg = RGB_UNPACK_GREEN(*pix) * XAP; + bb = RGB_UNPACK_BLUE(*pix) * XAP; + pix--; + rr += RGB_UNPACK_RED(*pix) * INV_XAP; + gg += RGB_UNPACK_GREEN(*pix) * INV_XAP; + bb += RGB_UNPACK_BLUE(*pix) * INV_XAP; + r = ((rr * YAP) + (r * INV_YAP)) >> 16; + g = ((gg * YAP) + (g * INV_YAP)) >> 16; + b = ((bb * YAP) + (b * INV_YAP)) >> 16; + *dptr++ = LCD_RGBPACK(r, g, b); + } else { + pix = ypoint + xpoint; + r = RGB_UNPACK_RED(*pix) * INV_YAP; + g = RGB_UNPACK_GREEN(*pix) * INV_YAP; + b = RGB_UNPACK_BLUE(*pix) * INV_YAP; + pix += sow; + r += RGB_UNPACK_RED(*pix) * YAP; + g += RGB_UNPACK_GREEN(*pix) * YAP; + b += RGB_UNPACK_BLUE(*pix) * YAP; + r >>= 8; + g >>= 8; + b >>= 8; + *dptr++ = LCD_RGBPACK(r, g, b); + } + } + } else { + for (x = 0; x < end; x++) { + int r = 0, g = 0, b = 0; + fb_data *pix; + + xpoint = (val_x >> 16); + XAP = ((val_x >> 16) >= (sw - 1)) ? 0 : (val_x >> 8) - ((val_x >> 8) & 0xffffff00); + INV_XAP = 256 - XAP; + val_x += inc_x; + + if (XAP > 0) { + pix = ypoint + xpoint; + r = RGB_UNPACK_RED(*pix) * INV_XAP; + g = RGB_UNPACK_GREEN(*pix) * INV_XAP; + b = RGB_UNPACK_BLUE(*pix) * INV_XAP; + pix++; + r += RGB_UNPACK_RED(*pix) * XAP; + g += RGB_UNPACK_GREEN(*pix) * XAP; + b += RGB_UNPACK_BLUE(*pix) * XAP; + r >>= 8; + g >>= 8; + b >>= 8; + *dptr++ = LCD_RGBPACK(r, g, b); + } else + *dptr++ = sptr[xpoint]; + } + } + } + } + /* if we're scaling down vertically */ + else if (xup_yup == 1) { + /*\ 'Correct' version, with math units prepared for MMXification \ */ + int Cy, j; + fb_data *pix; + int r, g, b, rr, gg, bb; + int yap; + + /* go through every scanline in the output buffer */ + for (y = 0; y < dh; y++) { + ypoint = src + ((val_y >> 16) * sw); + YAP = (((0x100 - ((val_y >> 8) & 0xff)) * Cp_y) >> 8) | (Cp_y << 16); + INV_YAP = 256 - YAP; + val_y += inc_y; + val_x = 0; + + Cy = YAP >> 16; + yap = YAP & 0xffff; + + + dptr = dest + (y * dow); + for (x = 0; x < end; x++) { + xpoint = (val_x >> 16); + XAP = ((val_x >> 16) >= (sw - 1)) ? 0 : (val_x >> 8) - ((val_x >> 8) & 0xffffff00); + INV_XAP = 256 - XAP; + val_x += inc_x; + + pix = ypoint + xpoint; + r = (RGB_UNPACK_RED(*pix) * yap) >> 10; + g = (RGB_UNPACK_GREEN(*pix) * yap) >> 10; + b = (RGB_UNPACK_BLUE(*pix) * yap) >> 10; + pix += sow; + for (j = (1 << 14) - yap; j > Cy; j -= Cy) { + r += (RGB_UNPACK_RED(*pix) * Cy) >> 10; + g += (RGB_UNPACK_GREEN(*pix) * Cy) >> 10; + b += (RGB_UNPACK_BLUE(*pix) * Cy) >> 10; + pix += sow; + } + if (j > 0) { + r += (RGB_UNPACK_RED(*pix) * j) >> 10; + g += (RGB_UNPACK_GREEN(*pix) * j) >> 10; + b += (RGB_UNPACK_BLUE(*pix) * j) >> 10; + } + if (XAP > 0) { + pix = ypoint + xpoint + 1; + rr = (RGB_UNPACK_RED(*pix) * yap) >> 10; + gg = (RGB_UNPACK_GREEN(*pix) * yap) >> 10; + bb = (RGB_UNPACK_BLUE(*pix) * yap) >> 10; + pix += sow; + for (j = (1 << 14) - yap; j > Cy; j -= Cy) { + rr += (RGB_UNPACK_RED(*pix) * Cy) >> 10; + gg += (RGB_UNPACK_GREEN(*pix) * Cy) >> 10; + bb += (RGB_UNPACK_BLUE(*pix) * Cy) >> 10; + pix += sow; + } + if (j > 0) { + rr += (RGB_UNPACK_RED(*pix) * j) >> 10; + gg += (RGB_UNPACK_GREEN(*pix) * j) >> 10; + bb += (RGB_UNPACK_BLUE(*pix) * j) >> 10; + } + r = r * INV_XAP; + g = g * INV_XAP; + b = b * INV_XAP; + r = (r + ((rr * XAP))) >> 12; + g = (g + ((gg * XAP))) >> 12; + b = (b + ((bb * XAP))) >> 12; + } else { + r >>= 4; + g >>= 4; + b >>= 4; + } + *dptr = LCD_RGBPACK(r, g, b); + dptr++; + } + } + } + /* if we're scaling down horizontally */ + else if (xup_yup == 2) { + /*\ 'Correct' version, with math units prepared for MMXification \ */ + int Cx, j; + fb_data *pix; + int r, g, b, rr, gg, bb; + int xap; + + /* go through every scanline in the output buffer */ + for (y = 0; y < dh; y++) { + ypoint = src + ((val_y >> 16) * sw); + YAP = ((val_y >> 16) >= (sh - 1)) ? 0 : (val_y >> 8) - ((val_y >> 8) & 0xffffff00); + INV_YAP = 256 - YAP; + val_y += inc_y; + val_x = 0; + + dptr = dest + (y * dow); + for (x = 0; x < end; x++) { + xpoint = (val_x >> 16); + XAP = (((0x100 - ((val_x >> 8) & 0xff)) * Cp_x) >> 8) | (Cp_x << 16); + INV_XAP = 256 - XAP; + + val_x += inc_x; + + Cx = XAP >> 16; + xap = XAP & 0xffff; + + pix = ypoint + xpoint; + r = (RGB_UNPACK_RED(*pix) * xap) >> 10; + g = (RGB_UNPACK_GREEN(*pix) * xap) >> 10; + b = (RGB_UNPACK_BLUE(*pix) * xap) >> 10; + pix++; + for (j = (1 << 14) - xap; j > Cx; j -= Cx) { + r += (RGB_UNPACK_RED(*pix) * Cx) >> 10; + g += (RGB_UNPACK_GREEN(*pix) * Cx) >> 10; + b += (RGB_UNPACK_BLUE(*pix) * Cx) >> 10; + pix++; + } + if (j > 0) { + r += (RGB_UNPACK_RED(*pix) * j) >> 10; + g += (RGB_UNPACK_GREEN(*pix) * j) >> 10; + b += (RGB_UNPACK_BLUE(*pix) * j) >> 10; + } + if (YAP > 0) { + pix = ypoint + xpoint + sow; + rr = (RGB_UNPACK_RED(*pix) * xap) >> 10; + gg = (RGB_UNPACK_GREEN(*pix) * xap) >> 10; + bb = (RGB_UNPACK_BLUE(*pix) * xap) >> 10; + pix++; + for (j = (1 << 14) - xap; j > Cx; j -= Cx) { + rr += (RGB_UNPACK_RED(*pix) * Cx) >> 10; + gg += (RGB_UNPACK_GREEN(*pix) * Cx) >> 10; + bb += (RGB_UNPACK_BLUE(*pix) * Cx) >> 10; + pix++; + } + if (j > 0) { + rr += (RGB_UNPACK_RED(*pix) * j) >> 10; + gg += (RGB_UNPACK_GREEN(*pix) * j) >> 10; + bb += (RGB_UNPACK_BLUE(*pix) * j) >> 10; + } + r = r * INV_YAP; + g = g * INV_YAP; + b = b * INV_YAP; + r = (r + ((rr * YAP))) >> 12; + g = (g + ((gg * YAP))) >> 12; + b = (b + ((bb * YAP))) >> 12; + } else { + r >>= 4; + g >>= 4; + b >>= 4; + } + *dptr = LCD_RGBPACK(r, g, b); + dptr++; + } + } + } + /* fully optimized (i think) - only change of algorithm can help */ + /* if we're scaling down horizontally & vertically */ + else { + /*\ 'Correct' version, with math units prepared for MMXification \ */ + int Cx, Cy, i, j; + fb_data *pix; + int r, g, b, rx, gx, bx; + int xap, yap; + + for (y = 0; y < dh; y++) { + ypoint = src + ((val_y >> 16) * sw); + YAP = (((0x100 - ((val_y >> 8) & 0xff)) * Cp_y) >> 8) | (Cp_y << 16); + INV_YAP = 256 - YAP; + val_y += inc_y; + val_x = 0; + + Cy = YAP >> 16; + yap = YAP & 0xffff; + + dptr = dest + (y * dow); + for (x = 0; x < end; x++) { + xpoint = (val_x >> 16); + XAP = (((0x100 - ((val_x >> 8) & 0xff)) * Cp_x) >> 8) | (Cp_x << 16); + INV_XAP = 256 - XAP; + val_x += inc_x; + + Cx = XAP >> 16; + xap = XAP & 0xffff; + + sptr = ypoint + xpoint; + + pix = sptr; + sptr += sow; + rx = (RGB_UNPACK_RED(*pix) * xap) >> 9; + gx = (RGB_UNPACK_GREEN(*pix) * xap) >> 9; + bx = (RGB_UNPACK_BLUE(*pix) * xap) >> 9; + pix++; + for (i = (1 << 14) - xap; i > Cx; i -= Cx) { + rx += (RGB_UNPACK_RED(*pix) * Cx) >> 9; + gx += (RGB_UNPACK_GREEN(*pix) * Cx) >> 9; + bx += (RGB_UNPACK_BLUE(*pix) * Cx) >> 9; + pix++; + } + if (i > 0) { + rx += (RGB_UNPACK_RED(*pix) * i) >> 9; + gx += (RGB_UNPACK_GREEN(*pix) * i) >> 9; + bx += (RGB_UNPACK_BLUE(*pix) * i) >> 9; + } + + r = (rx * yap) >> 14; + g = (gx * yap) >> 14; + b = (bx * yap) >> 14; + + for (j = (1 << 14) - yap; j > Cy; j -= Cy) { + pix = sptr; + sptr += sow; + rx = (RGB_UNPACK_RED(*pix) * xap) >> 9; + gx = (RGB_UNPACK_GREEN(*pix) * xap) >> 9; + bx = (RGB_UNPACK_BLUE(*pix) * xap) >> 9; + pix++; + for (i = (1 << 14) - xap; i > Cx; i -= Cx) { + rx += (RGB_UNPACK_RED(*pix) * Cx) >> 9; + gx += (RGB_UNPACK_GREEN(*pix) * Cx) >> 9; + bx += (RGB_UNPACK_BLUE(*pix) * Cx) >> 9; + pix++; + } + if (i > 0) { + rx += (RGB_UNPACK_RED(*pix) * i) >> 9; + gx += (RGB_UNPACK_GREEN(*pix) * i) >> 9; + bx += (RGB_UNPACK_BLUE(*pix) * i) >> 9; + } + + r += (rx * Cy) >> 14; + g += (gx * Cy) >> 14; + b += (bx * Cy) >> 14; + } + if (j > 0) { + pix = sptr; + sptr += sow; + rx = (RGB_UNPACK_RED(*pix) * xap) >> 9; + gx = (RGB_UNPACK_GREEN(*pix) * xap) >> 9; + bx = (RGB_UNPACK_BLUE(*pix) * xap) >> 9; + pix++; + for (i = (1 << 14) - xap; i > Cx; i -= Cx) { + rx += (RGB_UNPACK_RED(*pix) * Cx) >> 9; + gx += (RGB_UNPACK_GREEN(*pix) * Cx) >> 9; + bx += (RGB_UNPACK_BLUE(*pix) * Cx) >> 9; + pix++; + } + if (i > 0) { + rx += (RGB_UNPACK_RED(*pix) * i) >> 9; + gx += (RGB_UNPACK_GREEN(*pix) * i) >> 9; + bx += (RGB_UNPACK_BLUE(*pix) * i) >> 9; + } + + r += (rx * j) >> 14; + g += (gx * j) >> 14; + b += (bx * j) >> 14; + } + + *dptr = LCD_RGBPACK(r >> 5, g >> 5, b >> 5); + dptr++; + } + } + } +} diff --git a/apps/plugins/sliding_puzzle.c b/apps/plugins/sliding_puzzle.c index 2c6e249a00..3c8a175119 100644 --- a/apps/plugins/sliding_puzzle.c +++ b/apps/plugins/sliding_puzzle.c @@ -295,7 +295,7 @@ static bool load_resize_bitmap(void) FORMAT_NATIVE ); if( rc > 0 ) { - simple_resize_bitmap( &temp_bitmap, &main_bitmap ); + smooth_resize_bitmap( &temp_bitmap, &main_bitmap ); puzzle_bmp_ptr = (const fb_data *)img_buf; rb->strcpy( img_buf_path, filename ); return true; diff --git a/apps/plugins/test_resize.c b/apps/plugins/test_resize.c index 8583613d99..c50bc5f91c 100644 --- a/apps/plugins/test_resize.c +++ b/apps/plugins/test_resize.c @@ -36,31 +36,28 @@ const struct button_mapping *plugin_contexts[] #define NB_ACTION_CONTEXTS sizeof(plugin_contexts)/sizeof(plugin_contexts[0]) /* Key assignement */ -#if (CONFIG_KEYPAD == IPOD_1G2G_PAD) \ - || (CONFIG_KEYPAD == IPOD_3G_PAD) \ - || (CONFIG_KEYPAD == IPOD_4G_PAD) \ - || (CONFIG_KEYPAD == SANSA_E200_PAD) #define SIZE_INCREASE PLA_UP #define SIZE_INCREASE_REPEAT PLA_UP_REPEAT #define SIZE_DECREASE PLA_DOWN #define SIZE_DECREASE_REPEAT PLA_DOWN_REPEAT -#else -#define SIZE_INCREASE PLA_RIGHT -#define SIZE_INCREASE_REPEAT PLA_RIGHT_REPEAT -#define SIZE_DECREASE PLA_LEFT -#define SIZE_DECREASE_REPEAT PLA_LEFT_REPEAT -#endif + +#define WIDTH_INCREASE PLA_RIGHT +#define WIDTH_INCREASE_REPEAT PLA_RIGHT_REPEAT +#define WIDTH_DECREASE PLA_LEFT +#define WIDTH_DECREASE_REPEAT PLA_LEFT_REPEAT + #define BUTTON_QUIT PLA_QUIT +#define CHANGE_MODE PLA_MENU -#define MAX_OUTPUT_WIDTH 200 -#define MAX_OUTPUT_HEIGHT 200 +#define MAX_OUTPUT_WIDTH LCD_WIDTH +#define MAX_OUTPUT_HEIGHT LCD_HEIGHT static fb_data *b; static struct bitmap input_bmp; static struct bitmap output_bmp; -static fb_data input_bmp_data[100*100]; +static fb_data input_bmp_data[200*200]; static fb_data output_bmp_data[MAX_OUTPUT_WIDTH*MAX_OUTPUT_HEIGHT]; @@ -93,11 +90,22 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) DEBUGF("input_bmp_data starts at %p\n", input_bmp_data); DEBUGF("output_bmp_data starts at %p\n", output_bmp_data); + int scale_algorithm = 0; + while(1) { rb->lcd_clear_display(); rb->lcd_bitmap(input_bmp_data, 0, 0, input_bmp.width, input_bmp.height); - simple_resize_bitmap(&input_bmp, &output_bmp); + switch ( scale_algorithm ) { + case 0: + smooth_resize_bitmap(&input_bmp, &output_bmp); + rb->lcd_putsxy(0,0,"smooth_resize_bitmap"); + break; + case 1: + simple_resize_bitmap(&input_bmp, &output_bmp); + rb->lcd_putsxy(0,0,"simple_resize_bitmap"); + break; + } rb->lcd_bitmap(output_bmp_data, 0, 100, output_bmp.width, output_bmp.height); @@ -118,8 +126,23 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) case SIZE_DECREASE: case SIZE_DECREASE_REPEAT: - if (output_bmp.width >= 2) output_bmp.width -= 2; - if (output_bmp.height >= 2) output_bmp.height -= 2; + if (output_bmp.width > 2) output_bmp.width -= 2; + if (output_bmp.height > 2) output_bmp.height -= 2; + break; + + case WIDTH_INCREASE: + case WIDTH_INCREASE_REPEAT: + if (output_bmp.width < MAX_OUTPUT_WIDTH - 2) + output_bmp.width += 2; + break; + + case WIDTH_DECREASE: + case WIDTH_DECREASE_REPEAT: + if (output_bmp.width > 2) output_bmp.width -= 2; + break; + + case CHANGE_MODE: + scale_algorithm = (scale_algorithm+1)%2; break; } } -- cgit v1.2.3