#include "stdafx.h" #include "bmp_io.h" using namespace std; /* Set BYTE_SWAP to 1 if byte swapping is needed. */ int byte_swap = 1; /******************************************************************************/ int bmp_read(char *filein_name,int *xsize,int *ysize,int **rarray /*,int **garray,int **barray*/) { FILE *filein; // int numbytes; int biBitCount; int psize; int result; /* Open the input file. */ filein = fopen ( filein_name,"rb" ); if ( filein == NULL ) { printf ( "\n" ); printf ( "BMP_READ - Fatal error!\n" ); printf ( " Could not open the input file.\n" ); return 1; } /* Read the header. */ result = bmp_read_header (filein,xsize,ysize,&psize,&biBitCount); if ( result != 0 ) { printf ( "\n" ); printf ( "BMP_READ: Fatal error!\n" ); printf ( " BMP_READ_HEADER failed.\n" ); return 1; } /* Read the palette. */ unsigned char *palette=NULL; if(psize>0) { palette=(unsigned char*)malloc(psize); if(palette==NULL) { write_to_log("BMP_READ: Could not allocate data storage."); return 1; } } result = bmp_read_palette(filein,psize,palette); if ( result != 0 ) { printf ( "\n" ); printf ( "BMP_READ: Fatal error!\n" ); printf ( " BMP_READ_PALETTE failed.\n" ); return 1; } /* Allocate storage. */ // numbytes = ( *xsize ) * ( *ysize ) * sizeof ( int ); //if (garray) // free(garray); //if (barray) // free(barray); //if (rarray) // free(rarray); //*rarray = ( int * ) malloc ( numbytes ); //if ( rarray == NULL ) //{ //printf ( "\n" ); //printf ( "BMP_READ: Fatal error!\n" ); //printf ( " Could not allocate data storage.\n" ); //return 1; //} //*garray = ( int * ) malloc ( numbytes ); //if ( garray == NULL ) { // printf ( "\n" ); // printf ( "BMP_READ: Fatal error!\n" ); // printf ( " Could not allocate data storage.\n" ); // return 1; //} //*barray = ( int * ) malloc ( numbytes ); //if ( barray == NULL ) { // printf ( "\n" ); // printf ( "BMP_READ: Fatal error!\n" ); // printf ( " Could not allocate data storage.\n" ); // return 1; //} /* Read the data. */ result = bmp_read_data(filein,*xsize,*ysize,*rarray,/**garray,*barray,palette*/biBitCount); if ( result != 0 ) { printf ( "\n" ); printf ( "BMP_READ: Fatal error!\n" ); printf ( " BMP_READ_DATA failed.\n" ); return 1; } if (palette) free(palette); //if (garray) // free(garray); //if (barray) // free(barray); //if (rarray) // free(rarray); fclose(filein); return 0; } /******************************************************************************/ int bmp_read_data(FILE *filein, int xsize, int ysize, int *rarray, /*int *garray,int *barray, unsigned char *palette,*/ int biBitCount) { unsigned short int i,j; // int *indexb; // int *indexg; int *indexr; unsigned long int numbyte; indexr = rarray; // indexg = garray; // indexb = barray; numbyte = 0; // unsigned char* pal; // pal=palette; switch(biBitCount) { case 8: { unsigned char divrem = (unsigned char)(xsize%4); unsigned char colorindex; for(j=0; j<ysize; j++) { for(i=0; i<xsize; i++) { colorindex=(unsigned char)fgetc(filein); // int bcolor=(int)*(pal+colorindex*4); // int gcolor=(int)*(pal+colorindex*4+1); // int rcolor=(int)*(pal+colorindex*4+2); //*indexb=bcolor; // *indexb=colorindex; //ignore palette // indexb++; //*indexg=gcolor; // *indexg=colorindex; // indexg++; //*indexr=rcolor; *indexr=colorindex; indexr++; } if ((divrem) != 0) for (i=divrem; i<4; i++) //every line must end on a DWORD (4Bytes) boundary colorindex=(unsigned char)fgetc(filein); } break; } case 24: { unsigned char divrem = (unsigned char)(xsize%(4)); unsigned char colorindex; for(j = 0;j<ysize;j++) { for(i=0;i<xsize;i++) { colorindex=(unsigned char)fgetc(filein); //BLUE colorindex=(unsigned char)fgetc(filein); //GREEN colorindex=(unsigned char)fgetc(filein); //RED *indexr=colorindex; //get only the red channel -> PnG sample indexr++; } if ((divrem) != 0) for (i=divrem; i<4; i++) //every line must end on a DWORD (4Bytes) boundary colorindex=(unsigned char)fgetc(filein); // *indexb=fgetc(filein); // if(*indexb==EOF) // { // printf("BMP_READ_DATA: Failed reading data byte %d.\n",numbyte); // return 1; // } // numbyte=numbyte+1; // indexb=indexb+1; // *indexg=fgetc(filein); // if(*indexg==EOF) // { // printf("BMP_READ_DATA: Failed reading data byte %d.\n",numbyte); // return 1; // } // numbyte=numbyte+1; // indexg=indexg+1; // *indexr=fgetc(filein); // if(*indexr==EOF) // { // printf("BMP_READ_DATA: Failed reading data byte %d.\n",numbyte); // return 1; // } // numbyte=numbyte+1; // indexr=indexr+1; //} } break; } default: return 1; } return 0; } /******************************************************************************/ int bmp_read_header(FILE *filein,int *xsize,int *ysize,int *psize,int *biBitCount) { int c1; int c2; int retval; unsigned long int u_long_int_val; unsigned short int u_short_int_val; /* Header,14 bytes. 16 bytes FileType; Magic number: "BM", 32 bytes FileSize; Size of file in 32 byte integers, 16 bytes Reserved1; Always 0, 16 bytes Reserved2; Always 0, 32 bytes BitmapOffset. Starting position of image data,in bytes. */ c1 = fgetc ( filein ); if ( c1 == EOF ) { return 1; } c2 = fgetc ( filein ); if ( c2 == EOF ) { return 1; } if ( c1 != 'B' || c2 != 'M' ) { return 1; } retval = read_u_long_int ( &u_long_int_val,filein ); if ( retval != 0 ) { return 1; } retval = read_u_short_int ( &u_short_int_val,filein ); if ( retval != 0 ) { return 1; } retval = read_u_short_int ( &u_short_int_val,filein ); if ( retval != 0 ) { return 1; } retval = read_u_long_int ( &u_long_int_val,filein ); if ( retval != 0 ) { return 1; } c1=u_long_int_val; /* The bitmap header is 40 bytes long. 32 bytes unsigned Size; Size of this header,in bytes. 32 bytes Width; Image width,in pixels. 32 bytes Height; Image height,in pixels. (Pos/Neg,origin at bottom,top) 16 bytes Planes; Number of color planes (always 1). 16 bytes BitsPerPixel; 1 to 24. 1,4,8 and 24 legal. 16 and 32 on Win95. 32 bytes unsigned Compression; 0,uncompressed; 1,8 bit RLE; 2,4 bit RLE; 3,bitfields. 32 bytes unsigned SizeOfBitmap; Size of bitmap in bytes. (0 if uncompressed). 32 bytes HorzResolution; Pixels per meter. (Can be zero) 32 bytes VertResolution; Pixels per meter. (Can be zero) 32 bytes unsigned ColorsUsed; Number of colors in palette. (Can be zero). 32 bytes unsigned ColorsImportant. Minimum number of important colors. (Can be zero). */ retval = read_u_long_int ( &u_long_int_val,filein ); if ( retval != 0 ) { return 1; } c2=u_long_int_val; *psize=c1-c2-14; retval = read_u_long_int ( &u_long_int_val,filein ); if ( retval != 0 ) { return 1; } *xsize = ( int ) u_long_int_val; retval = read_u_long_int ( &u_long_int_val,filein ); if ( retval != 0 ) { return 1; } *ysize = ( int ) u_long_int_val; retval = read_u_short_int ( &u_short_int_val,filein ); if ( retval != 0 ) { return 1; } retval = read_u_short_int ( &u_short_int_val,filein ); if ( retval != 0 ) { return 1; } *biBitCount=u_short_int_val; retval = read_u_long_int ( &u_long_int_val,filein ); if ( retval != 0 ) { return 1; } retval = read_u_long_int ( &u_long_int_val,filein ); if ( retval != 0 ) { return 1; } retval = read_u_long_int ( &u_long_int_val,filein ); if ( retval != 0 ) { return 1; } retval = read_u_long_int ( &u_long_int_val,filein ); if ( retval != 0 ) { return 1; } retval = read_u_long_int ( &u_long_int_val,filein ); if ( retval != 0 ) { return 1; } retval = read_u_long_int ( &u_long_int_val,filein ); if ( retval != 0 ) { return 1; } return 0; } /******************************************************************************/ int bmp_read_palette(FILE *filein,int psize,unsigned char *palette) { fread(palette,sizeof(unsigned char),psize,filein); return 0; } /******************************************************************************/ int bmp_write(char *fileout_name,int xsize,int ysize,int *rarray,int *garray,int *barray) { FILE *fileout; int result; /* Open the output file. */ fileout = fopen ( fileout_name,"wb" ); if ( fileout == NULL ) { printf ( "\n" ); printf ( "BMP_WRITE - Fatal error!\n" ); printf ( " Could not open the output file.\n" ); return 1; } /* Write the header. */ result = bmp_write_header ( fileout,xsize,ysize ); if ( result != 0 ) { printf ( "\n" ); printf ( "BMP_WRITE: Fatal error!\n" ); printf ( " BMP_WRITE_HEADER failed.\n" ); return 1; } /* Write the data. */ result = bmp_write_data ( fileout,xsize,ysize,rarray,garray,barray ); if ( result != 0 ) { printf ( "\n" ); printf ( "BMP_WRITE: Fatal error!\n" ); printf ( " BMP_WRITE_DATA failed.\n" ); return 1; } /* Close the file. */ fclose ( fileout ); return 0; } /******************************************************************************/ int bmp_write_data(FILE *fileout,int xsize,int ysize,int *rarray, int *garray,int *barray) { int i; int *indexb; int *indexg; int *indexr; int j; indexr = rarray; indexg = garray; indexb = barray; for ( j = 0; j < ysize; j++ ) { for ( i = 0; i < xsize; i++ ) { fputc ( *indexb,fileout ); fputc ( *indexg,fileout ); fputc ( *indexr,fileout ); indexb = indexb + 1; indexg = indexg + 1; indexr = indexr + 1; } } return 0; } /******************************************************************************/ int bmp_write_header(FILE *fileout,int xsize,int ysize) { int i; unsigned long int u_long_int_val; unsigned short int u_short_int_val; /* Header,14 bytes. 16 bytes FileType; Magic number: "BM", 32 bytes FileSize; Size of file in bytes, 16 bytes Reserved1; Always 0, 16 bytes Reserved2; Always 0, 32 bytes BitmapOffset. Starting position of image data,in bytes. */ fputc ( 'B',fileout ); fputc ( 'M',fileout ); u_long_int_val = 3 * xsize * ysize + 54; write_u_long_int ( u_long_int_val,fileout ); u_short_int_val = 0; write_u_short_int ( u_short_int_val,fileout ); u_short_int_val = 0; write_u_short_int ( u_short_int_val,fileout ); u_long_int_val = 54; write_u_long_int ( u_long_int_val,fileout ); /* The bitmap header is 40 bytes long. 32 bytes unsigned Size; Size of this header,in bytes. 32 bytes Width; Image width,in pixels. 32 bytes Height; Image height,in pixels. (Pos/Neg,origin at bottom,top) 16 bytes Planes; Number of color planes (always 1). 16 bytes BitsPerPixel; 1 to 24. 1,4,8 and 24 legal. 16 and 32 on Win95. 32 bytes unsigned Compression; 0,uncompressed; 1,8 bit RLE; 2,4 bit RLE; 3,bitfields. 32 bytes unsigned SizeOfBitmap; Size of bitmap in bytes. (0 if uncompressed). 32 bytes HorzResolution; Pixels per meter. (Can be zero) 32 bytes VertResolution; Pixels per meter. (Can be zero) 32 bytes unsigned ColorsUsed; Number of colors in palette. (Can be zero). 32 bytes unsigned ColorsImportant. Minimum number of important colors. (Can be zero). */ u_long_int_val = 40; write_u_long_int ( u_long_int_val,fileout ); write_u_long_int ( xsize,fileout ); write_u_long_int ( ysize,fileout ); u_short_int_val = 1; write_u_short_int ( u_short_int_val,fileout ); u_short_int_val = 24; write_u_short_int ( u_short_int_val,fileout ); for ( i = 0; i <= 5; i++ ) { u_long_int_val = 0; write_u_long_int ( u_long_int_val,fileout ); } return 0; } /******************************************************************************/ int read_u_long_int(unsigned long int *u_long_int_val,FILE *filein) { int retval; unsigned short int u_short_int_val_hi; unsigned short int u_short_int_val_lo; if ( byte_swap == 1 ) { retval = read_u_short_int ( &u_short_int_val_lo,filein ); if ( retval != 0 ) { return 1; } retval = read_u_short_int ( &u_short_int_val_hi,filein ); if ( retval != 0 ) { return 1; } } else { retval = read_u_short_int ( &u_short_int_val_hi,filein ); if ( retval != 0 ) { return 1; } retval = read_u_short_int ( &u_short_int_val_lo,filein ); if ( retval != 0 ) { return 1; } } *u_long_int_val = ( u_short_int_val_hi << 16 ) | u_short_int_val_lo; return 0; } /******************************************************************************/ int read_u_short_int(unsigned short int *u_short_int_val,FILE *filein) { int chi; int clo; if ( byte_swap == 1 ) { clo = fgetc ( filein ); if ( clo == EOF ) { return 1; } chi = fgetc ( filein ); if ( chi == EOF ) { return 1; } } else { chi = fgetc ( filein ); if ( chi == EOF ) { return 1; } clo = fgetc ( filein ); if ( clo == EOF ) { return 1; } } *u_short_int_val = (unsigned short)(( chi << 8 ) | clo); return 0; } /******************************************************************************/ int write_u_long_int(unsigned long int u_long_int_val,FILE *fileout) { unsigned short int u_short_int_val_hi; unsigned short int u_short_int_val_lo; u_short_int_val_hi = ( unsigned short ) ( u_long_int_val / 65536 ); u_short_int_val_lo = ( unsigned short ) ( u_long_int_val % 65536 ); if ( byte_swap == 1 ) { write_u_short_int ( u_short_int_val_lo,fileout ); write_u_short_int ( u_short_int_val_hi,fileout ); } else { write_u_short_int ( u_short_int_val_hi,fileout ); write_u_short_int ( u_short_int_val_lo,fileout ); } return 4; } /******************************************************************************/ int write_u_short_int(unsigned short int u_short_int_val,FILE *fileout) { unsigned char chi; unsigned char clo; chi = ( unsigned char ) ( u_short_int_val / 256 ); clo = ( unsigned char ) ( u_short_int_val % 256 ); if ( byte_swap == 1 ) { fputc ( clo,fileout ); fputc ( chi,fileout ); } else { fputc ( chi,fileout ); fputc ( clo,fileout ); } return 2; }