From 44bf7e76aaa7f9394bab98b65b4f061ba53d3e74 Mon Sep 17 00:00:00 2001 From: Brett Gordon Date: Tue, 5 Jul 2016 23:22:38 -0400 Subject: [PATCH] now should work on different width screens. ? --- Applications/fview/fview.c | 109 +++++++++++++++++++++++++------------ 1 file changed, 74 insertions(+), 35 deletions(-) diff --git a/Applications/fview/fview.c b/Applications/fview/fview.c index a0221033..4ee9a51c 100644 --- a/Applications/fview/fview.c +++ b/Applications/fview/fview.c @@ -1,3 +1,9 @@ +/* + fview - a simple program to display windows .bmp files on fuzix. + This will read the most common formats of 1,2,4,16,24,or 32 bpp. + It only translates to a 1 bpp format, with optional FS dithering +*/ + #include #include #include @@ -47,12 +53,14 @@ struct display disp; /* general struct for noodling */ uint8_t *lbuf; /* bmp line buffer */ uint8_t *obuf; /* output line buffer to tty dev */ struct bmp_palette *pal; /* table of palette entries */ -int16_t *error1; /* error buffer 1 */ -int16_t *error2; /* error buffer 2 */ +int16_t *error1; /* error buffer 1 in 1/16ths of error */ +int16_t *error2; /* error buffer 2 in 1/16ths of error */ 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 pinfo=0; /* just print info from bmp header and quit */ int rsize; /* bmp size of row in bytes */ +int ssize; /* screen size of row in bytes */ #ifndef LITTLE_ENDIAN uint16_t swizzle16( uint16_t d ){ @@ -87,7 +95,7 @@ int scan_modes(void) { break; if( ! (disp.commands & GFX_WRITE) ) continue; if( ! (disp.format & FMT_MONO_WB) ) continue; - if( disp.width != 256 ) continue; + // if( disp.width != 256 ) continue; res = disp.width * disp.height; if( res > maxres ){ maxres = res; @@ -97,12 +105,20 @@ int scan_modes(void) { return ret; } + void exit_err_mess( char *mess ){ fprintf( stderr, mess ); fputc( '\n', stderr ); exit(1); } +void exit_usage(){ + exit_err_mess("usage: fview -dp file"); +} + + +/* This is an aproximation of a RGB -> intensity + formula :) */ uint8_t intensity( struct bmp_palette *p ){ uint16_t c; c = (p->red * 2); @@ -123,6 +139,7 @@ void flip_err( void ){ } } +/* Floyd-Steinberg Dithering */ void fs_dist( int16_t e, uint16_t i ){ /* distribute error */ if( dither ){ @@ -133,6 +150,7 @@ void fs_dist( int16_t e, uint16_t i ){ } } +/* Convert a row of non-paletted modes to 1 bpp screen row */ void bpp32( int no ){ int i,j,k,c,x,e; int erri=1; @@ -142,8 +160,8 @@ void bpp32( int no ){ struct bmp_palette p; flip_err(); - memset( err_next, 0, 516 ); - for( i=0; i<32; i++){ + memset( err_next, 0, (disp.width+2)*sizeof(int) ); + for( i=0; i> 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; + pix[3]= *in & 0x3; break; case 4: pix[0]= *in >> 4; - pix[1]= *in++ & 0xf; + pix[1]= *in & 0xf; break; case 8: - pix[0]= *in++; + pix[0]= *in; break; } + in++; } else{ for( k=j; k<8/no; k++ ) pix[k]=0; @@ -267,26 +285,37 @@ int main( int argc, char *argv[] ) struct bmp_dib d; struct box *lbox; int i,j; - int llb; + int llb; /* screen row last line of bmp (if < screen height ) */ if( argc<2 ) - exit_err_mess("usage: fview file"); + exit_usage; - for( i=1; i<size = disp.width / 8 + sizeof(struct box); + lbox->size = ssize + sizeof(struct box); lbox->x = 0; lbox->h = 1; - lbox->w = 32; - + lbox->w = ssize; /* calc starting screen Y*/ if( d.height < disp.height ) llb = d.height-1; else llb = disp.height-1; - - - /* loop */ + /* Allocate dithering error buffers + we add an extra 2 samples here because dithering requires + a sample behind and in front of our subject pixel + */ + error1 = calloc( disp.width + 2, sizeof( int16_t ) ); + error2 = calloc( disp.width + 2, sizeof( int16_t ) ); + if( error1 == NULL | error2 == NULL ) + exit_err_mess("cannot alloc dither buffers"); + flip_err(); + + + /* loop - for each row of pixels + read a row from bmp file, tranlate to a row of screen data, + and send data to fuzix + */ for( i=disp.height-1; i>-1; i-- ){ 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; @@ -407,7 +446,7 @@ int main( int argc, char *argv[] ) } } else{ - memset( obuf+sizeof(struct box), 0, 32 ); + memset( obuf+sizeof(struct box), 0, ssize ); } /* output line to video device */ lbox->y = i; -- 2.34.1