//========================================================================= //#define PROGRAMMER "BAHN, William" //#define PROG_CODE "bahw" //#define COURSE "ECE-1021" //#define YEAR (2003) //#define TERM "Fall" //#define SECTION (0) //#define ASSIGNMENT "Utility Functions" //#define REVISION (2) //#define TITLE "Windows BMP File Functions" //#define SUBTITLE "Last Modified: 02 DEC 03" //#define EMAIL "wbahn@eas.uccs.edu" //#define FILENAME "bmp.h" //========================================================================= // GENERAL DESCRIPTION // // This file contains many functions useful for working with Windows BMP // files and generic 24-bit images. // REVISION HISTORY // REV 2: 02 DEC 03 // // Added the FillIMAGE() function // REV 1: 28 NOV 03 // // Found and fixed problems with some of the FreeXXX() functions. In some // places they did not assign NULL to the pointers after freeing the // memory associated with them. Depending on use, this caused other // functions to try to free the same memory again. // // Also added the #ifndef directive to prevent multiple inclusions. // REV 0: 09 NOV 03 // // Initial Creation. #ifndef BMPdotH // This directive prevents the prototypes and, most importantly, the // function definitions (which would normally be in a separate .c file) // from being included more than once. // // At the end of the excluded block of code, the identifier is defined. //========================================================================= //== INCLUDE FILES ======================================================== //========================================================================= #include // printf() #include // sqrt() #include // exit() #include "dirtyd.h" // //========================================================================= //== MACRO DEFINITIONS ==================================================== //========================================================================= //========================================================================= //== STRUCTURE DEFINITIONS ================================================ //========================================================================= typedef struct BMP BMP; typedef struct BMPFILEHEADER BMPFILEHEADER; typedef struct BMPINFOHEADER BMPINFOHEADER; typedef struct IMAGE IMAGE; typedef struct COLORTRIPLET COLORTRIPLET; typedef unsigned char UBYTE; //------------------------------------------------------------------------- // BMP STRUCTURE //------------------------------------------------------------------------- struct BMP { BMPFILEHEADER *bf; BMPINFOHEADER *bi; IMAGE *image; }; #define NottaBMP(ptr) (NULL == (ptr)) #define IsaBMP(ptr) (NULL != (ptr)) // BMP Structure functions - primitives BMP *CreateBMP(void); int FreeBMP(BMP *bmp); BMP *NewBMP(void); BMPFILEHEADER *SetBMP_FILE(BMP *bmp, BMPFILEHEADER *bf); BMPINFOHEADER *SetBMP_INFO(BMP *bmp, BMPINFOHEADER *bi); IMAGE *SetBMP_IMAGE(BMP *bmp, IMAGE *image); BMPFILEHEADER *GetBMP_FILE(BMP *bmp); BMPINFOHEADER *GetBMP_INFO(BMP *bmp); IMAGE *GetBMP_IMAGE(BMP *bmp); // BMP structure functions - manipulatives char *GetBMP_Type(BMP *bmp); unsigned long GetBMP_FileSize(BMP *bmp); unsigned int GetBMP_Reserved1(BMP *bmp); unsigned int GetBMP_Reserved2(BMP *bmp); unsigned long GetBMP_Offset(BMP *bmp); unsigned long GetBMP_InfoSize(BMP *bmp); unsigned long GetBMP_Width(BMP *bmp); unsigned long GetBMP_Height(BMP *bmp); unsigned int GetBMP_Planes(BMP *bmp); unsigned int GetBMP_Bits(BMP *bmp); unsigned long GetBMP_Compression(BMP *bmp); unsigned long GetBMP_ImageSize(BMP *bmp); unsigned long GetBMP_Xres(BMP *bmp); unsigned long GetBMP_Yres(BMP *bmp); unsigned long GetBMP_ColorsUsed(BMP *bmp); unsigned long GetBMP_SigColors(BMP *bmp); char *SetBMP_Type(BMP *bmp, char *s); unsigned long SetBMP_FileSize(BMP *bmp, unsigned long Size); unsigned int SetBMP_Reserved1(BMP *bmp, unsigned int res ); unsigned int SetBMP_Reserved2(BMP *bmp, unsigned int res); unsigned long SetBMP_Offset(BMP *bmp, unsigned int offset); unsigned long SetBMP_InfoSize(BMP *bmp, unsigned long Size); unsigned long SetBMP_Width(BMP *bmp, unsigned long Width); unsigned long SetBMP_Height(BMP *bmp, unsigned long Height ); unsigned int SetBMP_Planes(BMP *bmp, unsigned int planes); unsigned int SetBMP_Bits(BMP *bmp, unsigned int bits); unsigned long SetBMP_Compression(BMP *bmp, unsigned long comp); unsigned long SetBMP_ImageSize(BMP *bmp, unsigned long Size); unsigned long SetBMP_Xres(BMP *bmp, unsigned long res); unsigned long SetBMP_Yres(BMP *bmp, unsigned long res); unsigned long SetBMP_ColorsUsed(BMP *bmp, unsigned long num); unsigned long SetBMP_SigColors(BMP *bmp, unsigned long num); unsigned long CalculateBMP_ImageSize(IMAGE *image); int PadBytes(int cols, int bitsperpix, int alignment); BMP *GenerateBMPfromIMAGE(BMP *bmp, IMAGE *image); UBYTE GetBMPPixelComponent(BMP *bmp, int row, int col, int color); void SetBMPPixel(BMP *bmp, int row, int col, UBYTE red, UBYTE green, UBYTE blue); int ImportBMP(BMP *bmp, char *filename); int ExportBMP(BMP *bmp, char *filename); int DisplayBMP_STATS(BMP *bmp); void ConvertToGray(BMP *bmp); //------------------------------------------------------------------------- // BMPFILEHEADER STRUCTURE //------------------------------------------------------------------------- struct BMPFILEHEADER { char bfType[2]; // The characters "BM" unsigned long bfSize; // The size of the file in bytes unsigned int bfReserved1; // Unused - must be zero unsigned int bfReserved2; // Unused - must be zero unsigned long bfOffBits; // Offset to start of Pixel Data }; // BMPFILEHEADER Structure functions - primitives BMPFILEHEADER *CreateBMP_FILE(void); int FreeBMP_FILE(BMPFILEHEADER *bf); char *SetBMP_FILE_Type(BMPFILEHEADER *bf, char *s); unsigned long SetBMP_FILE_Size(BMPFILEHEADER *bf, unsigned long size); unsigned int SetBMP_FILE_Reserved1(BMPFILEHEADER *bf, unsigned int res); unsigned int SetBMP_FILE_Reserved2(BMPFILEHEADER *bf, unsigned int res); unsigned long SetBMP_FILE_OffBits(BMPFILEHEADER *bf, unsigned long off); char *GetBMP_FILE_Type(BMPFILEHEADER *bf); unsigned long GetBMP_FILE_Size(BMPFILEHEADER *bf); unsigned int GetBMP_FILE_Reserved1(BMPFILEHEADER *bf); unsigned int GetBMP_FILE_Reserved2(BMPFILEHEADER *bf); unsigned long GetBMP_FILE_OffBits(BMPFILEHEADER *bf); int ImportBMP_FILE(BMPFILEHEADER *bf, FILE *fp); int ExportBMP_FILE(BMPFILEHEADER *bf, FILE *fp); int DisplayBMP_FILE(BMPFILEHEADER *bf); int CheckBMP_FILE(BMPFILEHEADER *bf); //------------------------------------------------------------------------- // BMPINFOHEADER STRUCTURE //------------------------------------------------------------------------- struct BMPINFOHEADER { unsigned long biSize; // Header Size - Must be at least 40 unsigned long biWidth; // Image width in pixels unsigned long biHeight; // Image height in pixels unsigned int biPlanes; // Must be 1 unsigned int biBitCount; // Bits per pixel - (1,2,4,8,16,24,32} unsigned long biCompression; // Compression type (0 = uncompressed) unsigned long biSizeImage; // Image Size - uncompressed may be zero unsigned long biXPelsPerMeter; // Preferred resolution (pixels/meter) unsigned long biYPelsPerMeter; // Preferred resolution (pixels/meter) unsigned long biClrUsed; // Color Map entries that are used unsigned long biClrImportant; // Number of significant colors }; // BMPINFOHEADER Structure functions - primitives BMPINFOHEADER *CreateBMP_INFO(void); int FreeBMP_INFO(BMPINFOHEADER *bi); unsigned long SetBMP_INFO_Size(BMPINFOHEADER *bi, unsigned long Size); unsigned long SetBMP_INFO_Width(BMPINFOHEADER *bi, unsigned long Width); unsigned long SetBMP_INFO_Height(BMPINFOHEADER *bi, unsigned long Height); unsigned int SetBMP_INFO_Planes(BMPINFOHEADER *bi, unsigned int Planes); unsigned int SetBMP_INFO_BitCount(BMPINFOHEADER *bi, unsigned int Bits); unsigned long SetBMP_INFO_Compression(BMPINFOHEADER *bi, unsigned long Comp); unsigned long SetBMP_INFO_SizeImage(BMPINFOHEADER *bi, unsigned long Size); unsigned long SetBMP_INFO_XPelsPerMeter(BMPINFOHEADER *bi, unsigned long ppm); unsigned long SetBMP_INFO_YPelsPerMeter(BMPINFOHEADER *bi, unsigned long ppm); unsigned long SetBMP_INFO_ClrUsed(BMPINFOHEADER *bi, unsigned long num); unsigned long SetBMP_INFO_ClrImportant(BMPINFOHEADER *bi, unsigned long num); unsigned long GetBMP_INFO_Size(BMPINFOHEADER *bi); unsigned long GetBMP_INFO_Width(BMPINFOHEADER *bi); unsigned long GetBMP_INFO_Height(BMPINFOHEADER *bi); unsigned int GetBMP_INFO_Planes(BMPINFOHEADER *bi); unsigned int GetBMP_INFO_BitCount(BMPINFOHEADER *bi); unsigned long GetBMP_INFO_Compression(BMPINFOHEADER *bi); unsigned long GetBMP_INFO_SizeImage(BMPINFOHEADER *bi); unsigned long GetBMP_INFO_XPelsPerMeter(BMPINFOHEADER *bi); unsigned long GetBMP_INFO_YPelsPerMeter(BMPINFOHEADER *bi); unsigned long GetBMP_INFO_ClrUsed(BMPINFOHEADER *bi); unsigned long GetBMP_INFO_ClrImportant(BMPINFOHEADER *bi); //------------------------------------------------------------------------- // IMAGE STRUCTURE //------------------------------------------------------------------------- struct IMAGE { int Bits; // Number of bits per pixel unsigned long Bytes; // Number of data bytes in image int Rows; // Number of rows int Cols; // Number of cols COLORTRIPLET **Data; // data is an array of row pointers }; // IMAGE functions - primitives IMAGE *CreateIMAGE(void); int FreeIMAGE(IMAGE *image); int SetIMAGE_Bits(IMAGE *image, int Bits); int GetIMAGE_Bits(IMAGE *image); int SetIMAGE_Rows(IMAGE *image, int Rows); int GetIMAGE_Rows(IMAGE *image); int SetIMAGE_Cols(IMAGE *image, int Cols); int GetIMAGE_Cols(IMAGE *image); unsigned long SetIMAGE_Bytes(IMAGE *image, unsigned long Bytes); unsigned long GetIMAGE_Bytes(IMAGE *image); COLORTRIPLET **SetIMAGE_Data(IMAGE *image, COLORTRIPLET **Data); COLORTRIPLET **GetIMAGE_Data(IMAGE *image); // IMAGE functions - manipulatives IMAGE *NewIMAGE(int Rows, int Cols, int Bits); unsigned long CalculateIMAGE_Bytes(IMAGE *image); COLORTRIPLET **NewIMAGE_Data(IMAGE *image); int FreeIMAGE_Data(IMAGE *image); COLORTRIPLET *GetIMAGE_Pixel(IMAGE *image, int row, int col); UBYTE GetIMAGE_PixelComponent(IMAGE *image, int row, int col, int color); void SetIMAGE_Pixel(IMAGE *image, int row, int col, UBYTE red, UBYTE green, UBYTE blue); void FillIMAGE(IMAGE *image, UBYTE r, UBYTE g, UBYTE b); //------------------------------------------------------------------------- // COLORTRIPLE STRUCTURE //------------------------------------------------------------------------- struct COLORTRIPLET { UBYTE red; UBYTE green; UBYTE blue; }; #define RED (2) #define GREEN (1) #define BLUE (0) // COLORTRIPLET functions - primitives COLORTRIPLET *CreateCT(void); int DestroyCT(COLORTRIPLET *color); UBYTE SetCTr(COLORTRIPLET *color, UBYTE red); UBYTE SetCTg(COLORTRIPLET *color, UBYTE green); UBYTE SetCTb(COLORTRIPLET *color, UBYTE blue); UBYTE GetCTr(COLORTRIPLET *color); UBYTE GetCTg(COLORTRIPLET *color); UBYTE GetCTb(COLORTRIPLET *color); // COLORTRIPLET functions - manipulatives COLORTRIPLET *SetCT(COLORTRIPLET *color, UBYTE r, UBYTE g, UBYTE b); UBYTE GetCTgray(COLORTRIPLET *color); UBYTE SetCTgray(COLORTRIPLET *color, UBYTE shade); //== MACRO DEFINITIONS ==================================================== //== TOP LEVEL SUPPORT FUNCTION PROTOTYPES ================================ //== SUPPORT FUNCTIONS ==================================================== //== LOWER LEVEL FUNCTION PROTOTYPES ====================================== //UBYTE GrayScale(COLORTRIPLET *color); UBYTE RMS(UBYTE r, UBYTE g, UBYTE b); BMPFILEHEADER *GetBMP_FILE(BMP *bmp); BMPINFOHEADER *GetBMP_INFO(BMP *bmp); IMAGE *GetBMP_IMAGE(BMP *bmp); IMAGE *CreateBMP_IMAGE(BMP *bmp, int rows, int cols); unsigned long GetBMP_FILE_OffBits(BMPFILEHEADER *bf); unsigned long GetBMP_OffBits(BMP *bmp); void FreeBMP_DATA(IMAGE *image); int ImportBMP_FILE(BMPFILEHEADER *bf, FILE *fp); int ImportBMP_INFO(BMPINFOHEADER *bi, FILE *fp); int ImportBMP_DATA(BMP *bmp, FILE *fp); int ExportBMP_FILE(BMPFILEHEADER *bf, FILE *fp); int ExportBMP_INFO(BMPINFOHEADER *bi, FILE *fp); int ExportBMP_DATA(BMP *bmp, FILE *fp); int CheckBMP_FILE(BMPFILEHEADER *bf); int CheckBMP_INFO(BMPINFOHEADER *bi); int CheckBMP_DATA(BMP *bmp); int DisplayBMP_FILE(BMPFILEHEADER *bf); int DisplayBMP_INFO(BMPINFOHEADER *bi); /* COLORTRIPLET *GetColor(BMP *bmp, int row, int col, COLORTRIPLET *color); COLORTRIPLET *SetColor(BMP *bmp, int row, int col, COLORTRIPLET *color); UBYTE GetColorComponent(BMP *bmp, int row, int col, int color); UBYTE SetColorComponent(BMP *bmp, int r, int c, int color, int mag); COLORTRIPLET *SetColorRGB(BMP *bmp, int row, UBYTE r, UBYTE g, UBYTE b); */ //== TOP LEVEL SUPPORT FUNCTION DEFINITIONS =============================== //== LOWER LEVEL SUPPORT FUNCTION DEFINITIONS ============================= UBYTE RMS(UBYTE red, UBYTE green, UBYTE blue) { unsigned long r, g, b; r = (unsigned long) red; g = (unsigned long) green; b = (unsigned long) blue; return( (UBYTE) sqrt( (double)(r*r + g*g + b*b)/(3.0) ) ); } //========================================================================= //========================================================================= // BMP Structure functions //========================================================================= //========================================================================= /* struct BMP { BMPFILEHEADER *bf; BMPINFOHEADER *bi; IMAGE *image; }; */ //------------------------------------------------------------------------- // BMP Structure functions - primitives //------------------------------------------------------------------------- BMP *CreateBMP(void) { BMP *bmp; bmp = malloc(sizeof(BMP)); if(NULL == bmp) return(NULL); SetBMP_FILE(bmp, NULL); SetBMP_INFO(bmp, NULL); SetBMP_IMAGE(bmp, NULL); return(bmp); } int FreeBMP(BMP *bmp) { int freed; freed = 0; if(NULL == bmp) return(freed); freed += FreeBMP_FILE(GetBMP_FILE(bmp)); SetBMP_FILE(bmp, NULL); freed += FreeBMP_INFO(GetBMP_INFO(bmp)); SetBMP_INFO(bmp, NULL); freed += FreeIMAGE(GetBMP_IMAGE(bmp)); SetBMP_IMAGE(bmp, NULL); free(bmp); // Calling function responsible for setting bmp to NULL return(freed); } BMP *NewBMP(void) { BMP *bmp; bmp = CreateBMP(); if(NULL == bmp) return(NULL); bmp->bf = CreateBMP_FILE(); bmp->bi = CreateBMP_INFO(); bmp->image = CreateIMAGE(); return(bmp); } BMPFILEHEADER *SetBMP_FILE(BMP *bmp, BMPFILEHEADER *bf) { if(NULL == bmp) return(NULL); bmp->bf = bf; return(GetBMP_FILE(bmp)); } BMPINFOHEADER *SetBMP_INFO(BMP *bmp, BMPINFOHEADER *bi) { if(NULL == bmp) return(NULL); bmp->bi = bi; return(GetBMP_INFO(bmp)); } IMAGE *SetBMP_IMAGE(BMP *bmp, IMAGE *image) { if(NULL == bmp) return(NULL); bmp->image = image; return(GetBMP_IMAGE(bmp)); } BMPFILEHEADER *GetBMP_FILE(BMP *bmp) { if(NULL == bmp) return(NULL); return(bmp->bf); } BMPINFOHEADER *GetBMP_INFO(BMP *bmp) { if(NULL == bmp) return(NULL); return(bmp->bi); } IMAGE *GetBMP_IMAGE(BMP *bmp) { if(NULL == bmp) return(NULL); return(bmp->image); } //------------------------------------------------------------------------- // BMP Structure functions - manipulatives //------------------------------------------------------------------------- char *SetBMP_Type(BMP *bmp, char *s) { return(SetBMP_FILE_Type(GetBMP_FILE(bmp), s)); } unsigned long SetBMP_FileSize(BMP *bmp, unsigned long Size) { return(SetBMP_FILE_Size(GetBMP_FILE(bmp), Size)); } unsigned int SetBMP_Reserved1(BMP *bmp, unsigned int res ) { return(SetBMP_FILE_Reserved1(GetBMP_FILE(bmp), res)); } unsigned int SetBMP_Reserved2(BMP *bmp, unsigned int res) { return(SetBMP_FILE_Reserved2(GetBMP_FILE(bmp), res)); } unsigned long SetBMP_Offset(BMP *bmp, unsigned int offset) { return(SetBMP_FILE_OffBits(GetBMP_FILE(bmp), offset)); } unsigned long SetBMP_InfoSize(BMP *bmp, unsigned long Size) { return(SetBMP_INFO_Size(GetBMP_INFO(bmp), Size)); } unsigned long SetBMP_Width(BMP *bmp, unsigned long Width) { return(SetBMP_INFO_Width(GetBMP_INFO(bmp), Width)); } unsigned long SetBMP_Height(BMP *bmp, unsigned long Height ) { return(SetBMP_INFO_Height(GetBMP_INFO(bmp), Height)); } unsigned int SetBMP_Planes(BMP *bmp, unsigned int planes) { return(SetBMP_INFO_Planes(GetBMP_INFO(bmp), planes)); } unsigned int SetBMP_Bits(BMP *bmp, unsigned int bits) { return(SetBMP_INFO_BitCount(GetBMP_INFO(bmp), bits)); } unsigned long SetBMP_Compression(BMP *bmp, unsigned long comp) { return(SetBMP_INFO_Compression(GetBMP_INFO(bmp), comp)); } unsigned long SetBMP_ImageSize(BMP *bmp, unsigned long Size) { return(SetBMP_INFO_SizeImage(GetBMP_INFO(bmp), Size)); } unsigned long SetBMP_Xres(BMP *bmp, unsigned long res) { return(SetBMP_INFO_XPelsPerMeter(GetBMP_INFO(bmp),res)); } unsigned long SetBMP_Yres(BMP *bmp, unsigned long res) { return(SetBMP_INFO_YPelsPerMeter(GetBMP_INFO(bmp), res)); } unsigned long SetBMP_ColorsUsed(BMP *bmp, unsigned long num) { return(SetBMP_INFO_ClrUsed(GetBMP_INFO(bmp), num)); } unsigned long SetBMP_SigColors(BMP *bmp, unsigned long num) { return(SetBMP_INFO_ClrImportant(GetBMP_INFO(bmp), num)); } char *GetBMP_Type(BMP *bmp) { return(GetBMP_FILE_Type(GetBMP_FILE(bmp))); } unsigned long GetBMP_FileSize(BMP *bmp) { return(GetBMP_FILE_Size(GetBMP_FILE(bmp))); } unsigned int GetBMP_Reserved1(BMP *bmp) { return(GetBMP_FILE_Reserved1(GetBMP_FILE(bmp))); } unsigned int GetBMP_Reserved2(BMP *bmp) { return(GetBMP_FILE_Reserved2(GetBMP_FILE(bmp))); } unsigned long GetBMP_Offset(BMP *bmp) { return(GetBMP_FILE_OffBits(GetBMP_FILE(bmp))); } unsigned long GetBMP_InfoSize(BMP *bmp) { return(GetBMP_INFO_Size(GetBMP_INFO(bmp))); } unsigned long GetBMP_Width(BMP *bmp) { return(GetBMP_INFO_Width(GetBMP_INFO(bmp))); } unsigned long GetBMP_Height(BMP *bmp) { return(GetBMP_INFO_Height(GetBMP_INFO(bmp))); } unsigned int GetBMP_Planes(BMP *bmp) { return(GetBMP_INFO_Planes(GetBMP_INFO(bmp))); } unsigned int GetBMP_Bits(BMP *bmp) { return(GetBMP_INFO_BitCount(GetBMP_INFO(bmp))); } unsigned long GetBMP_Compression(BMP *bmp) { return(GetBMP_INFO_Compression(GetBMP_INFO(bmp))); } unsigned long GetBMP_ImageSize(BMP *bmp) { return(GetBMP_INFO_SizeImage(GetBMP_INFO(bmp))); } unsigned long GetBMP_Xres(BMP *bmp) { return(GetBMP_INFO_XPelsPerMeter(GetBMP_INFO(bmp))); } unsigned long GetBMP_Yres(BMP *bmp) { return(GetBMP_INFO_YPelsPerMeter(GetBMP_INFO(bmp))); } unsigned long GetBMP_ColorsUsed(BMP *bmp) { return(GetBMP_INFO_ClrUsed(GetBMP_INFO(bmp))); } unsigned long GetBMP_SigColors(BMP *bmp) { return(GetBMP_INFO_ClrImportant(GetBMP_INFO(bmp))); } UBYTE GetBMPPixelComponent(BMP *bmp, int row, int col, int color) { return(GetIMAGE_PixelComponent(GetBMP_IMAGE(bmp), row, col, color)); } void SetBMPPixel(BMP *bmp, int row, int col, UBYTE red, UBYTE green, UBYTE blue) { SetIMAGE_Pixel(GetBMP_IMAGE(bmp), row, col, red, green, blue); return; } int DisplayBMP_STATS(BMP *bmp) { DisplayBMP_FILE(GetBMP_FILE(bmp)); DisplayBMP_INFO(GetBMP_INFO(bmp)); return(0); } void ConvertToGray(BMP *bmp) { int row, rows; int col, cols; UBYTE red, green, blue, gray; rows = (int) GetBMP_Height(bmp); cols = (int) GetBMP_Width(bmp); for(row = 0; row < rows; row++) { for(col = 0; col < cols; col++) { red = GetBMPPixelComponent(bmp, row, col, RED); green = GetBMPPixelComponent(bmp, row, col, GREEN); blue = GetBMPPixelComponent(bmp, row, col, BLUE); gray = RMS(red, green, blue); SetBMPPixel(bmp, row, col, gray, gray, gray); } } return; } int ImportBMP_DATA(BMP *bmp, FILE *fp) { int row, rows; int col, cols; int i, padbytes; UBYTE red, green, blue, padbyte; fseek(fp, GetBMP_Offset(bmp), SEEK_SET); rows = (int) GetBMP_Height(bmp); cols = (int) GetBMP_Width(bmp); padbytes = PadBytes(cols, GetBMP_Bits(bmp), 4); for(row = 0; row < rows; row++) { for(col = 0; col < cols; col++) { fread(&blue, 1, 1, fp); fread(&green, 1, 1, fp); fread(&red, 1, 1, fp); SetBMPPixel(bmp, row, col, red, green, blue); } for(i = 0; i < padbytes; i++) // Dummy read for Padding Bytes fread(&padbyte, 1, 1, fp); } return(0); } int ExportBMP_DATA(BMP *bmp, FILE *fp) { int row, rows; int col, cols; int i, padbytes; UBYTE red, green, blue, padbyte=0; fseek(fp, GetBMP_Offset(bmp), SEEK_SET); rows = (int) GetBMP_Height(bmp); cols = (int) GetBMP_Width(bmp); padbytes = PadBytes(cols, GetBMP_Bits(bmp), 4); for(row = 0; row < rows; row++) { for(col = 0; col < cols; col++) { red = GetBMPPixelComponent(bmp, row, col, RED); green = GetBMPPixelComponent(bmp, row, col, GREEN); blue = GetBMPPixelComponent(bmp, row, col, BLUE); fwrite(&blue, 1, 1, fp); fwrite(&green, 1, 1, fp); fwrite(&red, 1, 1, fp); } for(i = 0; i < padbytes; i++) // Dummy read for Padding Bytes fwrite(&padbyte, 1, 1, fp); } return(0); } int ImportBMP(BMP *bmp, char *filename) { FILE *fp; int errcode; if(NULL == bmp) return(1); if(NULL == GetBMP_FILE(bmp)) return(2); if(NULL == GetBMP_INFO(bmp)) return(3); if(NULL == GetBMP_IMAGE(bmp)) return(4); fp = fopen(filename, "rb"); if(NULL == fp) return(5); ImportBMP_FILE(GetBMP_FILE(bmp), fp); errcode = CheckBMP_FILE(GetBMP_FILE(bmp)); if(errcode) return(errcode); ImportBMP_INFO(GetBMP_INFO(bmp), fp); errcode = CheckBMP_INFO(GetBMP_INFO(bmp)); if(errcode) return(errcode); SetBMP_IMAGE(bmp, NewIMAGE( (int) GetBMP_Height(bmp), (int) GetBMP_Width(bmp), (int) GetBMP_Bits(bmp)) ); errcode = ImportBMP_DATA(bmp, fp); if(errcode) return(errcode); fclose(fp); return(0); } int ExportBMP(BMP *bmp, char *filename) { FILE *fp; int errcode; if(NULL == bmp) return(1); if(NULL == GetBMP_FILE(bmp)) return(2); if(NULL == GetBMP_INFO(bmp)) return(3); if(NULL == GetBMP_IMAGE(bmp)) return(4); fp = fopen(filename, "wb"); if(NULL == fp) return(5); errcode = CheckBMP_FILE(GetBMP_FILE(bmp)); if(errcode) return(errcode); ExportBMP_FILE(GetBMP_FILE(bmp), fp); errcode = CheckBMP_INFO(GetBMP_INFO(bmp)); if(errcode) return(errcode); ExportBMP_INFO(GetBMP_INFO(bmp), fp); errcode = ExportBMP_DATA(bmp, fp); if(errcode) return(errcode); fclose(fp); return(0); } BMP *GenerateBMPfromIMAGE(BMP *bmp, IMAGE *image) { FreeBMP(bmp); bmp = NewBMP(); SetBMP_Type(bmp, "BM"); SetBMP_Reserved1(bmp, 0); SetBMP_Reserved2(bmp, 0); SetBMP_Offset(bmp, 54); SetBMP_InfoSize(bmp, 40); SetBMP_Width(bmp, GetIMAGE_Cols(image)); SetBMP_Height(bmp, GetIMAGE_Rows(image)); SetBMP_Planes(bmp, 1); SetBMP_Bits(bmp, GetIMAGE_Bits(image)); SetBMP_Compression(bmp, 0); SetBMP_ImageSize(bmp, CalculateBMP_ImageSize(image)); SetBMP_Xres(bmp, 4000); SetBMP_Yres(bmp, 4000); SetBMP_ColorsUsed(bmp, 0); SetBMP_SigColors(bmp, 0); SetBMP_FileSize(bmp, (GetBMP_Offset(bmp) + GetBMP_ImageSize(bmp)) ); SetBMP_IMAGE(bmp, image); return(bmp); } unsigned long CalculateBMP_ImageSize(IMAGE *image) { unsigned long bytes; int padbytes; padbytes = PadBytes(GetIMAGE_Cols(image), GetIMAGE_Bits(image), 4); bytes = GetIMAGE_Cols(image) + padbytes; bytes *= GetIMAGE_Rows(image); bytes *= GetIMAGE_Bits(image); bytes /= 8L; return(bytes); } int PadBytes(int cols, int bitsperpix, int alignment) { unsigned long bytes; bytes = ((unsigned long) (cols*bitsperpix)) / 8L; return( (alignment - (int)(bytes%alignment))%alignment ); } //========================================================================= //========================================================================= // BMPFILEHEADER Structure functions //========================================================================= //========================================================================= //------------------------------------------------------------------------- // BMPFILEHEADER Structure functions - primitives //------------------------------------------------------------------------- BMPFILEHEADER *CreateBMP_FILE(void) { BMPFILEHEADER *bf; bf = (BMPFILEHEADER *) malloc(sizeof(BMPFILEHEADER)); if(NULL == bf) return(NULL); SetBMP_FILE_Type(bf, malloc(2)); SetBMP_FILE_Size(bf, 0); SetBMP_FILE_Reserved1(bf, 0); SetBMP_FILE_Reserved2(bf, 0); return(bf); } int FreeBMP_FILE(BMPFILEHEADER *bf) { int freed; if(NULL == bf) return(FALSE); freed = 0; free(bf); // Calling function responsible for setting bf to NULL freed++; return(freed); } char *SetBMP_FILE_Type(BMPFILEHEADER *bf, char *s) { if(NULL == bf) return(NULL); bf->bfType[0] = s[0]; bf->bfType[1] = s[1]; return(GetBMP_FILE_Type(bf)); } unsigned long SetBMP_FILE_Size(BMPFILEHEADER *bf, unsigned long size) { if(NULL == bf) return(NULL); bf->bfSize = size; return(GetBMP_FILE_Size(bf)); } unsigned int SetBMP_FILE_Reserved1(BMPFILEHEADER *bf, unsigned int res) { if(NULL == bf) return(NULL); bf->bfReserved1 = res; return(GetBMP_FILE_Reserved1(bf)); } unsigned int SetBMP_FILE_Reserved2(BMPFILEHEADER *bf, unsigned int res) { if(NULL == bf) return(NULL); bf->bfReserved2 = res; return(GetBMP_FILE_Reserved2(bf)); } unsigned long SetBMP_FILE_OffBits(BMPFILEHEADER *bf, unsigned long off) { if(NULL == bf) return(NULL); bf->bfOffBits = off; return(GetBMP_FILE_OffBits(bf)); } char *GetBMP_FILE_Type(BMPFILEHEADER *bf) { if(NULL == bf) return(NULL); return(bf->bfType); } unsigned long GetBMP_FILE_Size(BMPFILEHEADER *bf) { if(NULL == bf) return(NULL); return(bf->bfSize); } unsigned int GetBMP_FILE_Reserved1(BMPFILEHEADER *bf) { if(NULL == bf) return(NULL); return(bf->bfReserved1); } unsigned int GetBMP_FILE_Reserved2(BMPFILEHEADER *bf) { if(NULL == bf) return(NULL); return(bf->bfReserved2); } unsigned long GetBMP_FILE_OffBits(BMPFILEHEADER *bf) { if(NULL == bf) return(NULL); return(bf->bfOffBits); } int ImportBMP_FILE(BMPFILEHEADER *bf, FILE *fp) { if(NULL == bf) return(FALSE); fseek(fp, 0, SEEK_SET); // Go to beginning of File Header fread(&(bf->bfType), 1, 2, fp); fread(&(bf->bfSize), 4, 1, fp); fread(&(bf->bfReserved1), 2, 1, fp); fread(&(bf->bfReserved2), 2, 1, fp); fread(&(bf->bfOffBits), 4, 1, fp); return(TRUE); } int ExportBMP_FILE(BMPFILEHEADER *bf, FILE *fp) { if(NULL == bf) return(FALSE); fseek(fp, 0, SEEK_SET); // Go to beginning of File Header fwrite(&(bf->bfType), 1, 2, fp); fwrite(&(bf->bfSize), 4, 1, fp); fwrite(&(bf->bfReserved1), 2, 1, fp); fwrite(&(bf->bfReserved2), 2, 1, fp); fwrite(&(bf->bfOffBits), 4, 1, fp); return(TRUE); } int DisplayBMP_FILE(BMPFILEHEADER *bf) { printf("BMP File Header data:\n"); printf("File Type: .......... %c%c\n", (bf->bfType)[0], (bf->bfType)[1]); printf("File Size: .......... %lu bytes\n", bf->bfSize); printf("Reserved1: .......... %u\n", bf->bfReserved1); printf("Reserved2: .......... %u\n", bf->bfReserved2); printf("Image Data Offset: .. %lu bytes\n", bf->bfOffBits); return(0); } int CheckBMP_FILE(BMPFILEHEADER *bf) { if( 'B' != (bf->bfType)[0] ) return(101); if( 'M' != (bf->bfType)[1] ) return(102); if( 0 != bf->bfReserved1 ) return(103); if( 0 != bf->bfReserved2 ) return(104); return(0); } //------------------------------------------------------------------------- // BMPFILEHEADER Structure functions - manipulatives //------------------------------------------------------------------------- //========================================================================= //========================================================================= // BMPINFOHEADER Structure functions //========================================================================= //========================================================================= //------------------------------------------------------------------------- // BMPINFOHEADER Structure functions - primitives //------------------------------------------------------------------------- //------------------------------------------------------------------------- // BMPINFOHEADER Structure functions - manipulatives //------------------------------------------------------------------------- /* struct BMPINFOHEADER { unsigned long biSize; // Header Size - Must be at least 40 unsigned long biWidth; // Image width in pixels unsigned long biHeight; // Image height in pixels unsigned int biPlanes; // Must be 1 unsigned int biBitCount; // Bits per pixel - (1,2,4,8,16,24,32} unsigned long biCompression; // Compression type (0 = uncompressed) unsigned long biSizeImage; // Image Size - uncompressed may be zero unsigned long biXPelsPerMeter; // Preferred resolution (pixels/meter) unsigned long biYPelsPerMeter; // Preferred resolution (pixels/meter) unsigned long biClrUsed; // Color Map entries that are used unsigned long biClrImportant; // Number of significant colors }; */ BMPINFOHEADER *CreateBMP_INFO(void) { BMPINFOHEADER *bi; bi = (BMPINFOHEADER *) malloc(sizeof(BMPINFOHEADER)); if(NULL == bi) return(NULL); SetBMP_INFO_Size(bi, 0); SetBMP_INFO_Width(bi, 0); SetBMP_INFO_Height(bi, 0); SetBMP_INFO_Planes(bi, 0); SetBMP_INFO_BitCount(bi, 0); SetBMP_INFO_Compression(bi, 0); SetBMP_INFO_SizeImage(bi, 0); SetBMP_INFO_XPelsPerMeter(bi, 0); SetBMP_INFO_XPelsPerMeter(bi, 0); SetBMP_INFO_ClrUsed(bi, 0); SetBMP_INFO_ClrImportant(bi, 0); return(bi); } int FreeBMP_INFO(BMPINFOHEADER *bi) { int freed; freed = 0; if(NULL == bi) return(freed); free(bi); // Calling function responsible for setting bi to NULL freed++; return(freed); } unsigned long SetBMP_INFO_Size(BMPINFOHEADER *bi, unsigned long Size) { if(NULL == bi) return(0); bi->biSize = Size; return(GetBMP_INFO_Size(bi)); } unsigned long SetBMP_INFO_Width(BMPINFOHEADER *bi, unsigned long Width) { if(NULL == bi) return(0); bi->biWidth = Width; return(GetBMP_INFO_Width(bi)); } unsigned long SetBMP_INFO_Height(BMPINFOHEADER *bi, unsigned long Height) { if(NULL == bi) return(0); bi->biHeight = Height; return(GetBMP_INFO_Height(bi)); } unsigned int SetBMP_INFO_Planes(BMPINFOHEADER *bi, unsigned int Planes) { if(NULL == bi) return(0); bi->biPlanes = Planes; return(GetBMP_INFO_Planes(bi)); } unsigned int SetBMP_INFO_BitCount(BMPINFOHEADER *bi, unsigned int Bits) { if(NULL == bi) return(0); bi->biBitCount = Bits; return(GetBMP_INFO_BitCount(bi)); } unsigned long SetBMP_INFO_Compression(BMPINFOHEADER *bi, unsigned long comp) { if(NULL == bi) return(0); bi->biCompression = comp; return(GetBMP_INFO_Compression(bi)); } unsigned long SetBMP_INFO_SizeImage(BMPINFOHEADER *bi, unsigned long size) { if(NULL == bi) return(0); bi->biSizeImage = size; return(GetBMP_INFO_SizeImage(bi)); } unsigned long SetBMP_INFO_XPelsPerMeter(BMPINFOHEADER *bi, unsigned long ppm) { if(NULL == bi) return(0); bi->biXPelsPerMeter = ppm; return(GetBMP_INFO_XPelsPerMeter(bi)); } unsigned long SetBMP_INFO_YPelsPerMeter(BMPINFOHEADER *bi, unsigned long ppm) { if(NULL == bi) return(0); bi->biYPelsPerMeter = ppm; return(GetBMP_INFO_YPelsPerMeter(bi)); } unsigned long SetBMP_INFO_ClrUsed(BMPINFOHEADER *bi, unsigned long num) { if(NULL == bi) return(0); bi->biClrUsed = num; return(GetBMP_INFO_ClrUsed(bi)); } unsigned long SetBMP_INFO_ClrImportant(BMPINFOHEADER *bi, unsigned long num) { if(NULL == bi) return(0); bi->biClrImportant = num; return(GetBMP_INFO_ClrImportant(bi)); } unsigned long GetBMP_INFO_Size(BMPINFOHEADER *bi) { if(NULL == bi) return(0); return(bi->biSize); } unsigned long GetBMP_INFO_Width(BMPINFOHEADER *bi) { if(NULL == bi) return(0); return(bi->biWidth); } unsigned long GetBMP_INFO_Height(BMPINFOHEADER *bi) { if(NULL == bi) return(0); return(bi->biHeight); } unsigned int GetBMP_INFO_Planes(BMPINFOHEADER *bi) { if(NULL == bi) return(0); return(bi->biPlanes); } unsigned int GetBMP_INFO_BitCount(BMPINFOHEADER *bi) { if(NULL == bi) return(0); return(bi->biBitCount); } unsigned long GetBMP_INFO_Compression(BMPINFOHEADER *bi) { if(NULL == bi) return(0); return(bi->biCompression); } unsigned long GetBMP_INFO_SizeImage(BMPINFOHEADER *bi) { if(NULL == bi) return(0); return(bi->biSizeImage); } unsigned long GetBMP_INFO_XPelsPerMeter(BMPINFOHEADER *bi) { if(NULL == bi) return(0); return(bi->biXPelsPerMeter); } unsigned long GetBMP_INFO_YPelsPerMeter(BMPINFOHEADER *bi) { if(NULL == bi) return(0); return(bi->biYPelsPerMeter); } unsigned long GetBMP_INFO_ClrUsed(BMPINFOHEADER *bi) { if(NULL == bi) return(0); return(bi->biClrUsed); } unsigned long GetBMP_INFO_ClrImportant(BMPINFOHEADER *bi) { if(NULL == bi) return(0); return(bi->biClrImportant); } int ImportBMP_INFO(BMPINFOHEADER *bi, FILE *fp) { fseek(fp, 14, SEEK_SET); // Go to beginning of Info Header fread(&(bi->biSize), 4, 1, fp); fread(&(bi->biWidth), 4, 1, fp); fread(&(bi->biHeight), 4, 1, fp); fread(&(bi->biPlanes), 2, 1, fp); fread(&(bi->biBitCount), 2, 1, fp); fread(&(bi->biCompression), 4, 1, fp); fread(&(bi->biSizeImage), 4, 1, fp); fread(&(bi->biXPelsPerMeter), 4, 1, fp); fread(&(bi->biYPelsPerMeter), 4, 1, fp); fread(&(bi->biClrUsed), 4, 1, fp); fread(&(bi->biClrImportant), 4, 1, fp); return(0); } int ExportBMP_INFO(BMPINFOHEADER *bi, FILE *fp) { fseek(fp, 14, SEEK_SET); // Go to beginning of Info Header fwrite(&(bi->biSize), 4, 1, fp); fwrite(&(bi->biWidth), 4, 1, fp); fwrite(&(bi->biHeight), 4, 1, fp); fwrite(&(bi->biPlanes), 2, 1, fp); fwrite(&(bi->biBitCount), 2, 1, fp); fwrite(&(bi->biCompression), 4, 1, fp); fwrite(&(bi->biSizeImage), 4, 1, fp); fwrite(&(bi->biXPelsPerMeter), 4, 1, fp); fwrite(&(bi->biYPelsPerMeter), 4, 1, fp); fwrite(&(bi->biClrUsed), 4, 1, fp); fwrite(&(bi->biClrImportant), 4, 1, fp); return(0); } int CheckBMP_INFO(BMPINFOHEADER *bi) { if( 40 != bi->biSize ) return(201); if( 1 != bi->biPlanes ) return(202); if( 24 != bi->biBitCount ) return(203); if( 0 != bi->biCompression ) return(204); return(0); } int DisplayBMP_INFO(BMPINFOHEADER *bi) { printf("BMP Info Header data:\n"); printf("Info Header Size: ... %lu bytes\n", bi->biSize); printf("Image Width: ........ %lu pixels\n", bi->biWidth); printf("Image Height: ....... %lu pixels\n", bi->biHeight); printf("Image Planes: ....... %u\n", bi->biPlanes); printf("Bits Per Pixel: ..... %u\n", bi->biBitCount); printf("Compression Type: ... %lu\n", bi->biCompression); printf("Image Size: ......... %lu\n", bi->biSizeImage); printf("X Resolution: ....... %lu pixels per meter\n", bi->biXPelsPerMeter); printf("Y Resolution: ....... %lu pixels per meter\n", bi->biYPelsPerMeter); printf("Colors Used: ........ %lu\n", bi->biClrUsed); printf("Significant Colors: . %lu\n", bi->biClrImportant); return(0); } //========================================================================= //========================================================================= // IMAGE structure functions //========================================================================= //========================================================================= // IMAGE functions - primitives IMAGE *CreateIMAGE(void) { IMAGE *image; image = (IMAGE *) malloc(sizeof(IMAGE)); SetIMAGE_Rows(image, 0); SetIMAGE_Cols(image, 0); SetIMAGE_Bits(image, 0); SetIMAGE_Bytes(image, 0); SetIMAGE_Data(image, NULL); return(image); } int FreeIMAGE(IMAGE *image) { if(NULL == image) return(FALSE); if(NULL != GetIMAGE_Data(image)) FreeIMAGE_Data(image); free(image); // Calling function responsible for setting image to NULL return(TRUE); } int SetIMAGE_Bits(IMAGE *image, int Bits) { image->Bits = Bits; return(GetIMAGE_Bits(image)); } int GetIMAGE_Bits(IMAGE *image) { return(image->Bits); } int SetIMAGE_Rows(IMAGE *image, int Rows) { image->Rows = Rows; return(GetIMAGE_Rows(image)); } int GetIMAGE_Rows(IMAGE *image) { return(image->Rows); } int SetIMAGE_Cols(IMAGE *image, int Cols) { image->Cols = Cols; return(GetIMAGE_Cols(image)); } int GetIMAGE_Cols(IMAGE *image) { return(image->Cols); } unsigned long SetIMAGE_Bytes(IMAGE *image, unsigned long Bytes) { image->Bytes = Bytes; return(GetIMAGE_Bytes(image)); } unsigned long GetIMAGE_Bytes(IMAGE *image) { return(image->Bytes); } COLORTRIPLET **SetIMAGE_Data(IMAGE *image, COLORTRIPLET **Data) { image->Data = Data; return(GetIMAGE_Data(image)); } COLORTRIPLET **GetIMAGE_Data(IMAGE *image) { return(image->Data); } // IMAGE functions - manipulatives IMAGE *NewIMAGE(int Rows, int Cols, int Bits) { IMAGE *image; image = CreateIMAGE(); SetIMAGE_Rows(image, Rows); SetIMAGE_Cols(image, Cols); SetIMAGE_Bits(image, Bits); SetIMAGE_Bytes(image, CalculateIMAGE_Bytes(image)); NewIMAGE_Data(image); return(image); } unsigned long CalculateIMAGE_Bytes(IMAGE *image) { unsigned long Bytes; Bytes = GetIMAGE_Rows(image); Bytes *= GetIMAGE_Cols(image); Bytes *= GetIMAGE_Bits(image); return(Bytes); } COLORTRIPLET **NewIMAGE_Data(IMAGE *image) { int row, rows; size_t bytes; COLORTRIPLET **Data; FreeIMAGE_Data(image); rows = GetIMAGE_Rows(image); bytes = (size_t) ( ( (long) GetIMAGE_Cols(image) * (long) GetIMAGE_Bits(image) ) / 8L); Data = (COLORTRIPLET **) malloc(rows*sizeof(COLORTRIPLET *)); for(row = 0; row < rows; row++) Data[row] = (COLORTRIPLET *) malloc(bytes*sizeof(COLORTRIPLET)); SetIMAGE_Data(image, Data); return(Data); } int FreeIMAGE_Data(IMAGE *image) { int row, rows; int freed; COLORTRIPLET **Data; freed = 0; if(NULL == image) return(freed); Data = GetIMAGE_Data(image); if(NULL == Data) return(freed); rows = GetIMAGE_Rows(image); for(row = 0; row < rows; row++) if(NULL != Data[row]) { free(Data[row]); Data[row] = NULL; freed++; } free(Data); SetIMAGE_Data(image, NULL); freed++; return(freed); } COLORTRIPLET *GetIMAGE_Pixel(IMAGE *image, int row, int col) { return(&(GetIMAGE_Data(image)[row][col])); } UBYTE GetIMAGE_PixelComponent(IMAGE *image, int row, int col, int color) { switch(color) { case RED: return(GetCTr(GetIMAGE_Pixel(image, row, col))); case GREEN: return(GetCTg(GetIMAGE_Pixel(image, row, col))); case BLUE: return(GetCTb(GetIMAGE_Pixel(image, row, col))); } return(0); } void SetIMAGE_Pixel(IMAGE *image, int row, int col, UBYTE red, UBYTE green, UBYTE blue) { COLORTRIPLET *ct; ct = GetIMAGE_Pixel(image, row, col); SetCTr(ct, red); SetCTg(ct, green); SetCTb(ct, blue); return; } void FillIMAGE(IMAGE *image, UBYTE r, UBYTE g, UBYTE b) { int row, rows; int col, cols; rows = (int) GetIMAGE_Rows(image); cols = (int) GetIMAGE_Cols(image); for(row = 0; row < rows; row++) for(col = 0; col < cols; col++) SetIMAGE_Pixel(image, row, col, r, g, b); return; } //========================================================================= //========================================================================= // COLORTRIPLET Structure functions //========================================================================= //========================================================================= // COLORTRIPLET functions - primitives UBYTE SetCTr(COLORTRIPLET *color, UBYTE red) { color->red = red; return(GetCTr(color)); } UBYTE SetCTg(COLORTRIPLET *color, UBYTE green) { color->green = green; return(GetCTr(color)); } UBYTE SetCTb(COLORTRIPLET *color, UBYTE blue) { color->blue = blue; return(GetCTb(color)); } UBYTE GetCTr(COLORTRIPLET *color) { return(color->red); } UBYTE GetCTg(COLORTRIPLET *color) { return(color->green); } UBYTE GetCTb(COLORTRIPLET *color) { return(color->blue); } // COLORTRIPLET functions - manipulatives COLORTRIPLET *SetCT(COLORTRIPLET *color, UBYTE r, UBYTE g, UBYTE b) { SetCTr(color, r); SetCTg(color, g); SetCTb(color, b); return(color); } UBYTE GetCTgray(COLORTRIPLET *color) { return(RMS(GetCTr(color), GetCTg(color), GetCTb(color))); } UBYTE SetCTgray(COLORTRIPLET *color, UBYTE shade) { SetCT(color, shade, shade, shade); return(shade); } #define BMPdotH #endif