//--------------------------------------------------------// // // // File: BMPGIF.CPP // // // // Desc: A program to convert image files in the // // BMP and GIF formats to the other format // // // //--------------------------------------------------------// #include "stdlib.h" #include "stdio.h" #include "string.h" #include "conio.h" #include "ctype.h" #include "cstring.h" #include "color.hpp" #include "imgstore.hpp" //--------------------------------------------------------// // General Code // //--------------------------------------------------------// #define UNKNOWN 0 #define BMP2GIF 1 #define GIF2BMP 2 //..................Program globals char InFn[80], // path to the input file OutFn[80]; // path to the output file ImgStore *imgmap; // image bitmap rgb *gblpal, *lclpal; int ncolors, // palette size ngbl, nlcl, cnvdir; // conversion direction //..................Program usage //..................Determine if the passed file exists int file_exists( char *path ) { FILE *f; if( (f=fopen(path,"rb")) != 0 ) { fclose( f ); return 1; } return 0; } //..................Create an image storage buffer ImgStore * istore( int h, int w, int d ){ ImgStore *ist = 0; // attempt to create in order of preference #ifdef __UsarEMXXMS ist = new XmsImgStore( h, w, d ); if( (ist != 0) && (ist->status != imgstoreOKAY) ) { delete ist; ist = new EmsImgStore( h, w, d ); if( (ist != 0) && (ist->status != imgstoreOKAY) ) { delete ist; ist = new CnvImgStore( h, w, d ); if( (ist != 0) && (ist->status != imgstoreOKAY) ) { delete ist; ist = new DskImgStore( h, w, d ); if( (ist != 0) && (ist->status != imgstoreOKAY) ) { delete ist; ist = 0; } } } } #else ist = new CnvImgStore( h, w, d ); if( (ist != 0) && (ist->status != imgstoreOKAY) ) { delete ist; ist = new DskImgStore( h, w, d ); if( (ist != 0) && (ist->status != imgstoreOKAY) ) { delete ist; ist = 0; } } #endif return ist; } //--------------------------------------------------------// // BMP-Specific Code // //--------------------------------------------------------// #include "bmp.hpp" //..................Load the BMP file ImgStore *LoadBMPFile(const string &fn, rgb **pallete){ // open file int ncolors; // palette size ImgStore *retorno= NULL ; FILE *fbmp = fopen( fn.c_str(), "rb" ); if( fbmp == 0 ) return NULL; // read header and check xBITMAPFILEHEADER bmfh; if( fread(&bmfh,sizeof(xBITMAPFILEHEADER),1,fbmp) != 1 ){ fclose(fbmp); return NULL; } if( bmfh.bfType != BMP_SIGNATURE_WORD ){ fclose(fbmp); return NULL; } // determine which format version is used // from structure size field long offset = ftell( fbmp ); long nbytes = 0; fread( &nbytes, sizeof(long), 1, fbmp ); fseek( fbmp, offset, SEEK_SET ); // read bitmap header and palette int width, height, depth, rle; // pre Windows 3.0 version if( nbytes == sizeof(xBITMAPCOREHEADER)){ xBITMAPCOREHEADER bmch; if( fread(&bmch,sizeof(xBITMAPCOREHEADER),1,fbmp) != 1 ){ fclose(fbmp); return NULL; } width = bmch.bcWidth; height = bmch.bcHeight; depth = bmch.bcBitCount; rle = 0; ncolors = 1 << depth; if( ncolors > 0 ) { *pallete = new rgb [ncolors]; if( *pallete == NULL ){ fclose(fbmp); return NULL; } xRGBTRIPLE t; for( int i=0; i 0 ) { *pallete= new rgb [ncolors]; if( *pallete == 0 ){ fclose(fbmp); return NULL; } xRGBQUAD q; for( int i=0; iput( scanline, --n ); } bmp.term( ); } delete scanline; } fclose( fbmp ); return retorno; } //--------------------------------------------------------// // GIF-Specific Code // //--------------------------------------------------------// #if defined(IMG_GIF) #include "gif.hpp" #include "gifcodec.hpp" //..................skip data blocks void skip_blocks( FILE *f ) { int nbytes; while( (nbytes=fgetc(f)) > 0 ) fseek( f, nbytes, SEEK_CUR ); } //..................determine interlaced row number static int currow = -8; static int curpass = 0; static int delta[] = { 8, 8, 4, 2 }; static int origin[] = { 0, 4, 2, 1 }; int row( int nrows ) { currow += delta[curpass]; if( currow >= nrows ) { curpass++; currow = origin[curpass]; } return currow; } //..................process image description void do_image( char *fn, FILE *f ) { GIFIMDESC imd; if( imd.get( f ) ) exit_pgm( "Error reading GIF image descriptor" ); // process local color table lclpal = 0; if( imd.islct() ) { nlcl = imd.ncolors(); lclpal = new rgb [nlcl]; if( lclpal == 0 ) exit_pgm( "No memory for local color table" ); for( int i=0; iput( scanln, n ); } dec.term(); printf( "done\n" ); } //..................process control extension void do_ctl_ext( FILE *f ) { GIFCTLEXT ctl; if( ctl.get( f ) ) exit_pgm( "Error reading GIF control extension" ); skip_blocks( f ); } //..................process comment extension void do_com_ext( FILE *f ) { GIFCOMEXT com; if( com.get( f ) ) exit_pgm( "Error reading GIF comment extension" ); skip_blocks( f ); } //..................process text extension void do_txt_ext( FILE *f ) { GIFTXTEXT txt; if( txt.get( f ) ) exit_pgm( "Error reading GIF text extension" ); skip_blocks( f ); } //..................process application extension void do_app_ext( FILE *f ) { GIFAPPEXT app; if( app.get( f ) ) exit_pgm( "Error reading GIF application extension" ); skip_blocks( f ); } //..................process extension void do_extension( FILE *f ) { char msg[81]; int label = fgetc( f ); switch( label ) { case 0xF9 : // control extension do_ctl_ext( f ); break; case 0xFE : // comment extension do_com_ext( f ); break; case 0x01 : // text extension do_txt_ext( f ); break; case 0xFF : // application extension do_app_ext( f ); break; default : // unknown or invalid if( label < 0 ) exit_pgm( "Error reading GIF extension" ); else { sprintf( msg, "Unknown/invalid GIF extension %02Xh\n", label ); exit_pgm( msg ); } break; } } //..................Load the GIF file void load_gif( char *fn ) { // open the file FILE *fgif = fopen( fn, "rb" ); if( fgif == 0 ) exit_pgm( "GIF file not found" ); // read header GIFHEADER hdr; if( hdr.get( fgif ) ) exit_pgm( "Error reading GIF header" ); if( ! hdr.isvalid() ) exit_pgm( "File is not a valid GIF file" ); // read screen descriptor GIFSCDESC scd; if( scd.get( fgif ) ) exit_pgm( "Error reading GIF screen descriptor" ); // process global color table gblpal = 0; if( scd.isgct() ) { ngbl = scd.ncolors(); gblpal = new rgb [ngbl]; if( gblpal == 0 ) exit_pgm( "No memory for global color table" ); for( int i=0; i 0 ) { if( type == 0x2C ) // image descriptor { do_image( fn, fgif ); break; } else if( type == 0x21 ) // extension do_extension( fgif ); else if( type == 0x3B ) // trailer exit_pgm( "Unexpected GIF trailer" ); else exit_pgm( "Unknown or invalid construct" ); } printf( "done\n" ); } #endif //--------------------------------------------------------// // M A I N // //--------------------------------------------------------// /* int main( int argc, char *argv[] ) { process_args( argc, argv ); if( cnvdir == GIF2BMP ) { load_gif( InFn ); imgpal = lclpal ? lclpal : gblpal; printf( "Writing BMP file '%s'...", OutFn ); WriteBMP( *imgmap, imgpal, OutFn ); printf( "done\n" ); } else { load_bmp( InFn ); printf( "Writing GIF file '%s'...", OutFn ); WriteGIF( *imgmap, imgpal, OutFn ); printf( "done\n" ); } return 0; } */