From 129c2b42675711c6b708c6a45cfbbad4d1a52730 Mon Sep 17 00:00:00 2001 From: Brett Gordon Date: Tue, 5 Jul 2016 11:15:00 -0400 Subject: [PATCH] proper (slow) 1bpp mode + boarders + horrible buffer alloc. --- Applications/fview/fview.c | 196 +++++++++++++++++++++---------------- 1 file changed, 112 insertions(+), 84 deletions(-) diff --git a/Applications/fview/fview.c b/Applications/fview/fview.c index e94d6184..a0221033 100644 --- a/Applications/fview/fview.c +++ b/Applications/fview/fview.c @@ -28,10 +28,10 @@ struct bmp_dib { }; struct bmp_palette { - uint8_t zero; uint8_t blue; uint8_t green; uint8_t red; + uint8_t zero; }; struct box { @@ -52,6 +52,7 @@ int16_t *error2; /* error buffer 2 */ int16_t *err_cur; /* ptr to current line's errors */ int16_t *err_next; /* ptr to next line's errors */ int dither=1; /* should we dither? */ +int rsize; /* bmp size of row in bytes */ #ifndef LITTLE_ENDIAN uint16_t swizzle16( uint16_t d ){ @@ -67,14 +68,6 @@ uint32_t swizzle32( uint32_t d ){ } #endif -void println( uint8_t *buf){ - int i; - for( i=0; i<42; i++){ - printf("%.2x ", buf[i] ); - } - printf("\n"); -} - /* scan the tty driver's nodes. Pick the one that gives us the most resolution at 1bpp, and can do a direct WRITE ioctl */ int scan_modes(void) { @@ -140,7 +133,7 @@ void fs_dist( int16_t e, uint16_t i ){ } } -void bpp32( uint16_t no ){ +void bpp32( int no ){ int i,j,k,c,x,e; int erri=1; uint8_t *out = obuf+sizeof(struct box); @@ -153,21 +146,28 @@ void bpp32( uint16_t no ){ for( i=0; i<32; i++){ c=0; for( j=0; j<8; j++ ){ - /* fixme: the following color translation only - works with big endian... add a ifdef for little */ - switch( no ){ - case 16: - p.green = (*(in+1) << 1) & 0xf8; - p.red = (*(in+1) << 6) | *in >> 5; - p.blue = *in << 3 ; - in += 2; - break; - case 32: - in++; - case 24: - p.blue = *in++; - p.green = *in++; - p.red = *in++; + if( in < lbuf + rsize ){ + /* fixme: the following color translation only + works with big endian... add a ifdef for little */ + switch( no ){ + case 16: + p.green = (*(in+1) << 1) & 0xf8; + p.red = (*(in+1) << 6) | *in >> 5; + p.blue = *in << 3 ; + in += 2; + break; + case 32: + in++; + case 24: + p.blue = *in++; + p.green = *in++; + p.red = *in++; + } + } + else{ + p.green = 0; + p.red = 0 ; + p.blue = 0 ; } c = c << 1; x= intensity( &p ); @@ -198,29 +198,49 @@ void bpp( int no ){ uint8_t pix[8]; flip_err(); + memset( err_next, 0, 516 ); + for( i=0; i<32; i++){ c=0; for( j=0; j> 6; - pix[1]= *in >> 4 & 0x3; - pix[2]= *in >> 2 & 0x3; - pix[3]= *in++ & 0x3; - break; - case 4: - pix[0]= *in >> 4; - pix[1]= *in++ & 0xf; - break; - case 8: - pix[0]= *in++; - break; - /* default case should be caught by caller */ + + if( in < lbuf + rsize ){ + switch( no ){ + case 1: + pix[0]= *in >> 7; + pix[1]= *in >> 6 & 1; + pix[2]= *in >> 5 & 1; + pix[3]= *in >> 4 & 1; + pix[4]= *in >> 3 & 1; + pix[5]= *in >> 2 & 1; + pix[6]= *in >> 1 & 1; + pix[7]= *in & 1; + in++; + break; + case 2: + pix[0]= *in >> 6; + pix[1]= *in >> 4 & 0x3; + pix[2]= *in >> 2 & 0x3; + pix[3]= *in++ & 0x3; + break; + case 4: + pix[0]= *in >> 4; + pix[1]= *in++ & 0xf; + break; + case 8: + pix[0]= *in++; + break; + } } - for( k=0; k<8/no; k ++ ){ + else{ + for( k=j; k<8/no; k++ ) pix[k]=0; + } + + for( k=0; k<8/no; k++ ){ c = c << 1; x= intensity( &(pal[ pix[k] ]) ); + if( dither ) x += err_cur[ erri ]/16; if( x > 127 ){ @@ -245,9 +265,9 @@ int main( int argc, char *argv[] ) int fd,ret; struct bmp_header h; struct bmp_dib d; - int rsize; struct box *lbox; int i,j; + int llb; if( argc<2 ) exit_err_mess("usage: fview file"); @@ -298,14 +318,13 @@ int main( int argc, char *argv[] ) if( ret != sizeof(struct bmp_palette)*d.colors ) exit_err_mess("read error loading palette"); + /* Allocate dithering error buffers */ - /* fixme: need to check for malloc errors */ error1 = calloc( 256 + 2, sizeof( int16_t ) ); error2 = calloc( 256 + 2, sizeof( int16_t ) ); if( error1 == NULL | error2 == NULL ) exit_err_mess("cannot alloc dither buffers"); flip_err(); - printf("header: %c%c\n", h.header[0], h.header[1] ); printf("width: %d, height: %d\n", (uint16_t)d.width, (uint16_t)d.height ); @@ -319,8 +338,7 @@ int main( int argc, char *argv[] ) exit_err_mess("unsupported bmp format"); if( d.comp ) exit_err_mess("compression not supported"); - - + /* alloc bmp line buffers */ rsize = (( d.bpp * d.width + 31 ) / 32 ) * 4; @@ -328,23 +346,12 @@ int main( int argc, char *argv[] ) if( lbuf == NULL ) exit_err_mess("cannot malloc line buffer"); - obuf=malloc( disp.width / 8 + sizeof(struct box) ); - if( obuf == NULL ) - exit_err_mess("cannot malloc dev buffer"); - - lbox=(struct box *)obuf; - if( lseek( fd, h.offset, SEEK_SET)<0 ) exit_err_mess("seek error in bitmap file"); - lbox->size = 40; - lbox->x = 0; - lbox->h = 1; - lbox->w = 32; - /* set video mode */ - + disp.mode=scan_modes(); if( disp.mode < 0 ) exit_err_mess("No suitable graphics mode found"); @@ -352,38 +359,59 @@ int main( int argc, char *argv[] ) if( ioctl( 1, GFXIOC_SETMODE, &disp ) < 0 ) exit_err_mess("Cannot set graphics mode"); + obuf=malloc( disp.width / 8 + sizeof(struct box) ); + if( obuf == NULL ) + exit_err_mess("cannot malloc dev buffer"); + + lbox=(struct box *)obuf; + lbox->size = disp.width / 8 + sizeof(struct box); + lbox->x = 0; + lbox->h = 1; + lbox->w = 32; + + + /* calc starting screen Y*/ + if( d.height < disp.height ) + llb = d.height-1; + else llb = disp.height-1; + + /* loop */ for( i=disp.height-1; i>-1; i-- ){ - /* get a line from the file */ - ret=read( fd, lbuf, rsize ); - if( ret < rsize ) { - printf("file read error: %d\n", ret ); - goto leave; + if( i <= llb ){ + /* get a line from the file */ + ret=read( fd, lbuf, rsize ); + + if( ret < rsize ) { + printf("file read error: %d\n", ret ); + goto leave; + } + + /* pixate the transels here */ + switch( d.bpp ){ + case 1: + case 2: + case 4: + case 8: + bpp( d.bpp ); + break; + case 16: + case 24: + case 32: + bpp32( d.bpp ); + break; + default: + printf("unsupported bpp.\n"); + goto leave; + } } - /* pixate the transels here */ - switch( d.bpp ){ - case 1: - /* fixme: fast, but doesn't do palette lookup :( */ - memcpy( obuf+sizeof(struct box), lbuf, 32 ); - break; - case 2: - case 4: - case 8: - bpp( d.bpp ); - break; - case 16: - case 24: - case 32: - bpp32( d.bpp ); - break; - default: - printf("unsupported bpp.\n"); - goto leave; + else{ + memset( obuf+sizeof(struct box), 0, 32 ); } /* output line to video device */ - lbox->y = i; - ret=ioctl( 0, GFXIOC_WRITE, obuf ); + lbox->y = i; + ret=ioctl( 0, GFXIOC_WRITE, obuf ); if( ret < 0 ){ printf("dev write error: %d\n", ret ); goto leave; -- 2.34.1