From e3a3a55ab00979be080968f9a4e625cf0f94928f Mon Sep 17 00:00:00 2001 From: Jens Arnold Date: Mon, 17 May 2004 00:45:41 +0000 Subject: Included newest grayscale framework git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4629 a1c6a512-1295-4272-9138-f99709370657 --- apps/plugins/jpeg.c | 253 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 163 insertions(+), 90 deletions(-) (limited to 'apps/plugins/jpeg.c') diff --git a/apps/plugins/jpeg.c b/apps/plugins/jpeg.c index 8f872bdab6..32eedd5d0d 100644 --- a/apps/plugins/jpeg.c +++ b/apps/plugins/jpeg.c @@ -315,10 +315,9 @@ void grayblock(int x, int by, unsigned char* src, int stride) "mov %2,r5 \n" "sub r1,r5 \n" /* r5 = depth - r1 */ + "mov.l .lshrsi3,r1 \n" + "jsr @r1 \n" /* shift r4 right by r5 */ "mov r0,r1 \n" /* last result stored in r1 */ - "mov.l .lshrsi3,r0 \n" - "jsr @r0 \n" /* shift r4 right by r5 */ - "nop \n" "or r1,r0 \n" /* rotated_pattern = r0 | r1 */ "mov.l r0,@-r15 \n" /* push pattern */ @@ -641,8 +640,8 @@ void gray_scroll_left(int count, bool black_border); void gray_scroll_right(int count, bool black_border); void gray_scroll_up8(bool black_border); void gray_scroll_down8(bool black_border); -void gray_scroll_up1(bool black_border); -void gray_scroll_down1(bool black_border); +void gray_scroll_up(int count, bool black_border); +void gray_scroll_down(int count, bool black_border); /* pixel functions */ void gray_drawpixel(int x, int y, int brightness); @@ -686,7 +685,7 @@ void gray_black_display(void) rb->memset(graybuf->data, 0xFF, MULU16(graybuf->depth, graybuf->plane_size)); } -/* Do a lcd_update() to show changes done by rb->lcd_xxx() functions (in areas +/* Do an lcd_update() to show changes done by rb->lcd_xxx() functions (in areas * of the screen not covered by the grayscale overlay). If the grayscale * overlay is running, the update will be done in the next call of the * interrupt routine, otherwise it will be performed right away. See also @@ -704,6 +703,9 @@ void gray_deferred_update(void) * * black_border determines if the pixels scrolled in at the right are black * or white + * + * Scrolling left/right by an even pixel count is almost twice as fast as + * scrolling by an odd pixel count. */ void gray_scroll_left(int count, bool black_border) { @@ -766,6 +768,9 @@ void gray_scroll_left(int count, bool black_border) * * black_border determines if the pixels scrolled in at the left are black * or white + * + * Scrolling left/right by an even pixel count is almost twice as fast as + * scrolling by an odd pixel count. */ void gray_scroll_right(int count, bool black_border) { @@ -792,7 +797,7 @@ void gray_scroll_right(int count, bool black_border) ".sr_loop1: \n" "mov.b @(%2,%0),r1 \n" "mov.b r1,@-%0 \n" - "cmp/hs %1,%0 \n" + "cmp/hi %1,%0 \n" "bt .sr_loop1 \n" : /* outputs */ : /* inputs */ @@ -807,7 +812,7 @@ void gray_scroll_right(int count, bool black_border) ".sr_loop2: \n" "mov.w @(%2,%0),r1 \n" "mov.w r1,@-%0 \n" - "cmp/hs %1,%0 \n" + "cmp/hi %1,%0 \n" "bt .sr_loop2 \n" : /* outputs */ : /* inputs */ @@ -828,6 +833,8 @@ void gray_scroll_right(int count, bool black_border) * * black_border determines if the pixels scrolled in at the bottom are black * or white + * + * Scrolling up/down by 8 pixels is very fast. */ void gray_scroll_up8(bool black_border) { @@ -866,6 +873,8 @@ void gray_scroll_up8(bool black_border) * * black_border determines if the pixels scrolled in at the top are black * or white + * + * Scrolling up/down by 8 pixels is very fast. */ void gray_scroll_down8(bool black_border) { @@ -900,7 +909,7 @@ void gray_scroll_down8(bool black_border) } } -/* Scroll the whole grayscale buffer up by 1 pixel +/* Scroll the whole grayscale buffer up by pixels (<= 7) * * black_border determines if the pixels scrolled in at the bottom are black * or white @@ -909,51 +918,84 @@ void gray_scroll_down8(bool black_border) * left/right or scrolling up/down byte-wise because it involves bit * shifting. That's why it is asm optimized. */ -void gray_scroll_up1(bool black_border) +void gray_scroll_up(int count, bool black_border) { - int filler; + unsigned long filler; - if (graybuf == NULL) + if (graybuf == NULL || (unsigned) count > 7) return; if (black_border) - filler = 1; + filler = 0xFF; else filler = 0; - + /* scroll column by column to minimize flicker */ asm( - "mov #0,r6 \n" /* x = 0; */ + "mov #0,r6 \n" /* x = 0 */ + "mova .su_shifttbl,r0 \n" /* calculate jump destination for */ + "mov.b @(r0,%6),%6 \n" /* shift amount from table */ + "bra .su_cloop \n" /* skip table */ + "add r0,%6 \n" + + ".align 2 \n" + ".su_shifttbl: \n" /* shift jump offset table */ + ".byte .su_shift0 - .su_shifttbl \n" + ".byte .su_shift1 - .su_shifttbl \n" + ".byte .su_shift2 - .su_shifttbl \n" + ".byte .su_shift3 - .su_shifttbl \n" + ".byte .su_shift4 - .su_shifttbl \n" + ".byte .su_shift5 - .su_shifttbl \n" + ".byte .su_shift6 - .su_shifttbl \n" + ".byte .su_shift7 - .su_shifttbl \n" ".su_cloop: \n" /* repeat for every column */ - "mov %1,r7 \n" /* get start address */ - "mov #0,r1 \n" /* current_plane = 0 */ - + "mov %1,r2 \n" /* get start address */ + "mov #0,r3 \n" /* current_plane = 0 */ + ".su_oloop: \n" /* repeat for every bitplane */ - "mov r7,r2 \n" /* get start address */ - "mov #0,r3 \n" /* current_row = 0 */ - "mov %5,r5 \n" /* get filler bit (bit 0) */ - + "mov r2,r4 \n" /* get start address */ + "mov #0,r5 \n" /* current_row = 0 */ + "mov %5,r1 \n" /* get filler bits */ + ".su_iloop: \n" /* repeat for all rows */ - "sub %2,r2 \n" /* address -= width; */ - "mov.b @r2,r4 \n" /* get new byte */ - "shll8 r5 \n" /* shift old lsb to bit 8 */ - "extu.b r4,r4 \n" /* extend byte unsigned */ - "or r5,r4 \n" /* merge old lsb */ - "shlr r4 \n" /* shift right */ - "movt r5 \n" /* save new lsb */ - "mov.b r4,@r2 \n" /* store byte */ - "add #1,r3 \n" /* current_row++; */ - "cmp/hi r3,%3 \n" /* cuurent_row < bheight ? */ + "sub %2,r4 \n" /* address -= width */ + "mov.b @r4,r0 \n" /* get data byte */ + "shll8 r1 \n" /* old data to 2nd byte */ + "extu.b r0,r0 \n" /* extend unsigned */ + "or r1,r0 \n" /* combine old data */ + "jmp @%6 \n" /* jump into shift "path" */ + "extu.b r0,r1 \n" /* store data for next round */ + + ".su_shift6: \n" /* shift right by 0..7 bits */ + "shlr2 r0 \n" + ".su_shift4: \n" + "shlr2 r0 \n" + ".su_shift2: \n" + "bra .su_shift0 \n" + "shlr2 r0 \n" + ".su_shift7: \n" + "shlr2 r0 \n" + ".su_shift5: \n" + "shlr2 r0 \n" + ".su_shift3: \n" + "shlr2 r0 \n" + ".su_shift1: \n" + "shlr r0 \n" + ".su_shift0: \n" + + "mov.b r0,@r4 \n" /* store data */ + "add #1,r5 \n" /* current_row++ */ + "cmp/hi r5,%3 \n" /* current_row < bheight ? */ "bt .su_iloop \n" - - "add %4,r7 \n" /* start_address += plane_size; */ - "add #1,r1 \n" /* current_plane++; */ - "cmp/hi r1,%0 \n" /* current_plane < depth ? */ + + "add %4,r2 \n" /* start_address += plane_size */ + "add #1,r3 \n" /* current_plane++ */ + "cmp/hi r3,%0 \n" /* current_plane < depth ? */ "bt .su_oloop \n" - "add #1,%1 \n" /* start_address++; */ - "add #1,r6 \n" /* x++; */ + "add #1,%1 \n" /* start_address++ */ + "add #1,r6 \n" /* x++ */ "cmp/hi r6,%2 \n" /* x < width ? */ "bt .su_cloop \n" : /* outputs */ @@ -963,67 +1005,100 @@ void gray_scroll_up1(bool black_border) /* %2 */ "r"(graybuf->width), /* %3 */ "r"(graybuf->bheight), /* %4 */ "r"(graybuf->plane_size), - /* %5 */ "r"(filler) + /* %5 */ "r"(filler), + /* %6 */ "r"(count) : /* clobbers */ - "r1", "r2", "r3", "r4", "r5", "r6", "r7" + "r0", "r1", "r2", "r3", "r4", "r5", "r6" ); } -/* Scroll the whole grayscale buffer down by 1 pixel +/* Scroll the whole grayscale buffer down by pixels (<= 7) * * black_border determines if the pixels scrolled in at the top are black * or white * * Scrolling up/down pixel-wise is significantly slower than scrolling * left/right or scrolling up/down byte-wise because it involves bit - * shifting. That's why it is asm optimized. Scrolling down is a bit - * faster than scrolling up, though. + * shifting. That's why it is asm optimized. */ -void gray_scroll_down1(bool black_border) +void gray_scroll_down(int count, bool black_border) { - int filler; + unsigned long filler; - if (graybuf == NULL) + if (graybuf == NULL || (unsigned) count > 7) return; if (black_border) - filler = -1; /* sets bit 31 */ + filler = 0xFF << count; /* calculate filler bits */ else filler = 0; - + /* scroll column by column to minimize flicker */ asm( - "mov #0,r5 \n" /* x = 0; */ + "mov #0,r6 \n" /* x = 0 */ + "mova .sd_shifttbl,r0 \n" /* calculate jump destination for */ + "mov.b @(r0,%6),%6 \n" /* shift amount from table */ + "bra .sd_cloop \n" /* skip table */ + "add r0,%6 \n" + + ".align 2 \n" + ".sd_shifttbl: \n" /* shift jump offset table */ + ".byte .sd_shift0 - .sd_shifttbl \n" + ".byte .sd_shift1 - .sd_shifttbl \n" + ".byte .sd_shift2 - .sd_shifttbl \n" + ".byte .sd_shift3 - .sd_shifttbl \n" + ".byte .sd_shift4 - .sd_shifttbl \n" + ".byte .sd_shift5 - .sd_shifttbl \n" + ".byte .sd_shift6 - .sd_shifttbl \n" + ".byte .sd_shift7 - .sd_shifttbl \n" ".sd_cloop: \n" /* repeat for every column */ - "mov %1,r6 \n" /* get start address */ - "mov #0,r1 \n" /* current_plane = 0 */ - + "mov %1,r2 \n" /* get start address */ + "mov #0,r3 \n" /* current_plane = 0 */ + ".sd_oloop: \n" /* repeat for every bitplane */ - "mov r6,r2 \n" /* get start address */ - "mov #0,r3 \n" /* current_row = 0 */ - "mov %5,r4 \n" /* get filler bit (bit 31) */ - + "mov r2,r4 \n" /* get start address */ + "mov #0,r5 \n" /* current_row = 0 */ + "mov %5,r1 \n" /* get filler bits */ + ".sd_iloop: \n" /* repeat for all rows */ - "shll r4 \n" /* get old msb (again) */ - /* This is possible because the sh1 loads byte data sign-extended, - * so the upper 25 bits of the register are all identical */ - "mov.b @r2,r4 \n" /* get new byte */ - "add #1,r3 \n" /* current_row++; */ - "rotcl r4 \n" /* rotate left, merges previous msb */ - "mov.b r4,@r2 \n" /* store byte */ - "add %2,r2 \n" /* address += width; */ - "cmp/hi r3,%3 \n" /* cuurent_row < bheight ? */ + "shlr8 r1 \n" /* shift right to get residue */ + "mov.b @r4,r0 \n" /* get data byte */ + "jmp @%6 \n" /* jump into shift "path" */ + "extu.b r0,r0 \n" /* extend unsigned */ + + ".sd_shift6: \n" /* shift left by 0..7 bits */ + "shll2 r0 \n" + ".sd_shift4: \n" + "shll2 r0 \n" + ".sd_shift2: \n" + "bra .sd_shift0 \n" + "shll2 r0 \n" + ".sd_shift7: \n" + "shll2 r0 \n" + ".sd_shift5: \n" + "shll2 r0 \n" + ".sd_shift3: \n" + "shll2 r0 \n" + ".sd_shift1: \n" + "shll r0 \n" + ".sd_shift0: \n" + + "or r0,r1 \n" /* combine with last residue */ + "mov.b r1,@r4 \n" /* store data */ + "add %2,r4 \n" /* address += width */ + "add #1,r5 \n" /* current_row++ */ + "cmp/hi r5,%3 \n" /* current_row < bheight ? */ "bt .sd_iloop \n" - - "add %4,r6 \n" /* start_address += plane_size; */ - "add #1,r1 \n" /* current_plane++; */ - "cmp/hi r1,%0 \n" /* current_plane < depth ? */ + + "add %4,r2 \n" /* start_address += plane_size */ + "add #1,r3 \n" /* current_plane++ */ + "cmp/hi r3,%0 \n" /* current_plane < depth ? */ "bt .sd_oloop \n" - "add #1,%1 \n" /* start_address++; */ - "add #1,r5 \n" /* x++ */ - "cmp/hi r5,%2 \n" /* x < width ? */ + "add #1,%1 \n" /* start_address++ */ + "add #1,r6 \n" /* x++ */ + "cmp/hi r6,%2 \n" /* x < width ? */ "bt .sd_cloop \n" : /* outputs */ : /* inputs */ @@ -1032,9 +1107,10 @@ void gray_scroll_down1(bool black_border) /* %2 */ "r"(graybuf->width), /* %3 */ "r"(graybuf->bheight), /* %4 */ "r"(graybuf->plane_size), - /* %5 */ "r"(filler) + /* %5 */ "r"(filler), + /* %6 */ "r"(count) : /* clobbers */ - "r1", "r2", "r3", "r4", "r5", "r6" + "r0", "r1", "r2", "r3", "r4", "r5", "r6" ); } @@ -1438,7 +1514,7 @@ void gray_drawgraymap(unsigned char *src, int x, int y, int nx, int ny, for (yi = y; yi < y + ny; ) { - row = src; + row = src; if (!(yi & 7) && (y + ny - yi > 7)) /* current row byte aligned in fb & at least 8 rows left */ @@ -1449,7 +1525,7 @@ void gray_drawgraymap(unsigned char *src, int x, int y, int nx, int ny, grayblock(xi, yi >> 3, row++, stride); } yi += 8; - src += stride << 3; + src += stride << 3; } else { @@ -1459,7 +1535,7 @@ void gray_drawgraymap(unsigned char *src, int x, int y, int nx, int ny, graybuf->depth + 1) >> 8]); } yi++; - src += stride; + src += stride; } } } @@ -2963,9 +3039,8 @@ int scroll_bmp(struct t_disp* pdisp) { int button; int move; - int i; - /* we're unfortunately slower than key repeat, + /* we're unfortunately slower than key repeat, so empty the button queue, to avoid post-scroll */ while(rb->button_get(false) != BUTTON_NONE); @@ -3014,8 +3089,7 @@ int scroll_bmp(struct t_disp* pdisp) if (move == 8) gray_scroll_down8(false); /* scroll down by 8 pixel */ else - for (i=0; iy -= move; gray_drawgraymap( pdisp->bitmap + pdisp->y * pdisp->stride + pdisp->x, @@ -3032,8 +3106,7 @@ int scroll_bmp(struct t_disp* pdisp) if (move == 8) gray_scroll_up8(false); /* scroll up by 8 pixel */ else - for (i=0; iy += move; gray_drawgraymap( pdisp->bitmap + (pdisp->y + LCD_HEIGHT - move) * pdisp->stride + pdisp->x, @@ -3137,7 +3210,7 @@ int main(char* filename) long time; /* measured ticks */ static struct jpeg jpg; /* too large for stack */ - int status; + int status; int ds, ds_min, ds_max; /* scaling and limits */ buf = rb->plugin_get_mp3_buffer(&buf_size); @@ -3189,17 +3262,17 @@ int main(char* filename) rb->lcd_puts(0, 1, print); rb->lcd_update(); - rb->memset(&jpg, 0, sizeof(jpg)); /* clear info struct */ - /* process markers, unstuffing */ + rb->memset(&jpg, 0, sizeof(jpg)); /* clear info struct */ + /* process markers, unstuffing */ status = process_markers(buf_jpeg, filesize, &jpg); - if (status < 0 || (status & (DQT | SOF0)) != (DQT | SOF0)) + if (status < 0 || (status & (DQT | SOF0)) != (DQT | SOF0)) { /* bad format or minimum components not contained */ rb->splash(HZ*2, true, "unsupported %d", status); return PLUGIN_ERROR; } - if (!(status & DHT)) /* if no Huffman table present: */ - default_huff_tbl(&jpg); /* use default */ - build_lut(&jpg); /* derive Huffman and other lookup-tables */ + if (!(status & DHT)) /* if no Huffman table present: */ + default_huff_tbl(&jpg); /* use default */ + build_lut(&jpg); /* derive Huffman and other lookup-tables */ /* I can correct the buffer now, re-gain what the removed markers took */ buf -= filesize; /* back to before */ -- cgit v1.2.3