Code:
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
//Some important definitions & Constants
#define _BLUE 0
#define _GREEN 1
#define _RED 2
//RGB Quad Structure Declaration
struct RGBQUADDEF
{
unsigned char rgbBlue;
unsigned char rgbGreen;
unsigned char rgbRed;
};
int Row=0,Col=0,width=0,height=0;
typedef struct RGBQUADDEF RGBQUAD;
struct BMP
{
//BITMAP FILE HEADER
short BF_TYPE; //Specifies type of File (0)
int BF_SIZE; //Stores Size of File (2)
int BF_OFFBITS; //Specifies offset to Image Data (10)
//BITMAP INFO HEADER
int BI_SIZE; //Size of Info Header (14)
int BI_WIDTH; //Stores Width of Image (pixels) (18)
int BI_HEIGHT; //Stores Height of Image (pixels) (22)
short BI_BITCOUNT; //Specifies number of bits per pixel
int BI_SIZEIMAGE; //Specifies size of Image Data in bytes
int BI_CLRUSED; //Specifies number of colors used in Bitmap
//END OF BITMAP HEADER;
char *szFileName; //File name opened
int **buffer; //buufer storing the integer value picked from file
RGBQUAD *COLORS; //RGBQUAD structure variable
//Not nesessary BMP Header data but can be used in case of some requirement
//short BF_RESERVED1; //Always set to zero (6)
//short BF_RESERVED2; //Always set to zero (8)
//short BI_PLANES; //Stores Number of planes of target device (26)
//int BI_COMPRESSION; //Specifies type of compression
//int BI_XPELSPERMETER;//Specifies Horizontal pixels per meter (target)
//int BI_YPELSPERMETER;//Specifies Vertical pixels per meter (target)
//int BI_CLRIMPORTANT; //Specifies 'important' color for bitmap
};
typedef struct BMP BMPObj;
BMPObj bmpFile;
/* FUNCTION WriteBuffer() */
/* PARAMETERS : Source and Destination FileNames (with Path) */
/* RETURNS : Number of bytes written */
/* CALLS : No user defined function */
/* PURPOSE : To write current buffer to Destination using Source header */
void Offset(char szSource[],char szDestination[],BMPObj* obj)
{
//Local Variable Declarations
unsigned char Header[54];
int iIndex,iBytes=0,jIndex,oldw,oldh,zero=255,xtraw=0,xtrah=0,jIndex1=0;
FILE *fSource=NULL;
FILE *fTarget=NULL;
//TODO:DONE
fSource = fopen(szSource,"r");
if(fSource == NULL)
{
exit(0);
}
//TODO:DONE
fTarget = fopen(szDestination,"w");
if(fTarget==NULL)
{
exit(0);
}
//Copy Header Information
//TODO:
/* if(Row==0)
Row = obj->WIDTH;
if(Col==0)
Col = obj->HEIGHT;*/
//BITMAP INFO HEADER
oldw = obj->BI_WIDTH; //Stores Width of Image (pixels) (18)
oldh = obj->BI_HEIGHT;
obj->BI_WIDTH += Row;
xtraw = (obj->BI_WIDTH%4==0)?0:(4-(obj->BI_WIDTH%4)); //Stores Width of Image (pixels) (18)
obj->BI_WIDTH += xtraw;
obj->BI_HEIGHT += Col;
xtrah = (obj->BI_HEIGHT%4==0)?0:(4-(obj->BI_HEIGHT%4)); //Stores Width of Image (pixels) (18)
obj->BI_HEIGHT += xtrah;
//Stores Height of Image (pixels) (22)
obj->BI_SIZEIMAGE = obj->BI_WIDTH * obj->BI_HEIGHT *3; //Specifies size of Image Data in bytes
obj->BF_SIZE =obj->BI_SIZEIMAGE + 54;
// fseek ( f1, obj->BF_OFFBITS, SEEK_SET ) ;
fread ( &Header, 54, 1, fSource ) ;
fwrite ( &Header, 54, 1, fTarget ) ;
fseek ( fTarget, 2, SEEK_SET ) ;
fwrite ( &obj->BF_SIZE, sizeof(int), 1, fTarget ) ;
fseek ( fTarget, 18, SEEK_SET ) ;
fwrite ( &obj->BI_WIDTH, sizeof(int), 1, fTarget ) ;
fseek ( fTarget, 22, SEEK_SET ) ;
fwrite ( &obj->BI_HEIGHT, sizeof(int), 1, fTarget ) ;
fseek ( fTarget, 34, SEEK_SET ) ;
fwrite ( &obj->BI_SIZEIMAGE, sizeof(int), 1, fTarget ) ;
fseek ( fTarget, 54, SEEK_SET ) ;
printf("old height = %d,old width = %d,new height = %d,new width = %d\n",oldh,oldw,obj->BI_HEIGHT,obj->BI_WIDTH);
//printf("imagesize=%d,filesize=%d\n",obj->BI_SIZEIMAGE,obj->BF_SIZE);
iBytes=0;
//Copy Buffer to Target/Destination File
for(iIndex=0;iIndex<oldh;iIndex++)
{
// if(iIndex%oldw==0)
for(jIndex=0; jIndex< Row; jIndex++)
{
//To be written 3 bytes a time for 24-bit images
fwrite ( &zero, sizeof(char), 1, fTarget ) ;
fwrite ( &zero, sizeof(char), 1, fTarget ) ;
fwrite ( &zero, sizeof(char), 1, fTarget ) ;
}
// if(iIndex%(oldw+Row)==0)
for(jIndex=0; jIndex< oldw; jIndex++){
//To be written 3 bytes a time for 24-bit images
fwrite ( (char*)&(obj->buffer[_BLUE][jIndex1]), sizeof(char), 1, fTarget ) ;
fwrite ( (char*)&(obj->buffer[_GREEN][jIndex1]), sizeof(char), 1, fTarget ) ;
fwrite ( (char*)&(obj->buffer[_RED][jIndex1]), sizeof(char), 1, fTarget ) ;
jIndex1++;
}
for(jIndex=0; jIndex< xtraw; jIndex++)
{
//To be written 3 bytes a time for 24-bit images
fwrite ( &zero, sizeof(char), 1, fTarget ) ;
fwrite ( &zero, sizeof(char), 1, fTarget ) ;
fwrite ( &zero, sizeof(char), 1, fTarget ) ;
}
}
for(iIndex=0; iIndex< (Col * (obj->BI_WIDTH)); iIndex++)
{
//To be written 3 bytes a time for 24-bit images
fwrite ( &zero, sizeof(char), 1, fTarget ) ;
fwrite ( &zero, sizeof(char), 1, fTarget ) ;
fwrite ( &zero, sizeof(char), 1, fTarget ) ;
}
fclose(fSource);
fclose(fTarget);
}
/* FUNCTION: ShowProperties() */
/* PARAMETERS : NONE */
/* RETURNS : INTEGER DENOTING SUCCESS */
/* CALLS : NO USER DEFINED FUNCTIONS */
/* PURPOSE : DISPLAYS SOME IMPORTANT VALUES */
int ShowProperties(BMPObj* obj)
{
printf("Properties of File:\n");
printf("---------- -- -----");
printf("Type\t\t: %d\n",obj->BF_TYPE);
printf("Size\t\t: %d\n",obj->BF_SIZE);
printf("Offset\t\t: %d\n",obj->BF_OFFBITS);
printf("Info Header size: %d\n",obj->BI_SIZE);
printf("BitCount\t: %d\n",obj->BI_BITCOUNT);
printf("Width\t\t: %d pixels\n",obj->BI_WIDTH);
printf("Height\t\t: %d pixels\n",obj->BI_HEIGHT);
printf("Image Size\t: %d\n",obj->BI_SIZEIMAGE);
printf("Colors Used\t: %d\n",obj->BI_CLRUSED);
return 0;
}
/* FUNCTION: GetProperties(char []) */
/* PARAMETERS : CHAR ARRAY */
/* RETURNS : INTEGER DENOTING SUCESS */
/* CALLS : NO USER DEFINED FUNCTIONS */
/* PURPOSE : TO GET IMPORTANT PROPERTIES OF FILE */
void GetProperties(char fileName[],BMPObj* obj)
{
int iIndex=0;
FILE *bmpFile=NULL;
bmpFile= fopen(fileName,"rb");
if(bmpFile == NULL)
{
exit(0);
}
iIndex=0;
//Copying Argument Value
// printf("Stored FileName %s",obj->szFileName);
fseek ( bmpFile, 0, SEEK_SET ) ;
fread ( &(obj->BF_TYPE), sizeof(obj->BF_TYPE), 1, bmpFile ) ;
fread ( &(obj->BF_SIZE), sizeof(obj->BF_SIZE), 1, bmpFile ) ;
fseek ( bmpFile, 10, SEEK_SET ) ;
fread ( &(obj->BF_OFFBITS), sizeof(obj->BF_OFFBITS), 1, bmpFile ) ;
fseek ( bmpFile,18,SEEK_SET) ;
fread ( &(obj->BI_WIDTH), sizeof(&obj->BI_WIDTH), 1, bmpFile ) ;
fread ( &(obj->BI_HEIGHT), sizeof(obj->BI_HEIGHT), 1, bmpFile ) ;
fseek ( bmpFile, 28, SEEK_SET ) ;
fread ( &(obj->BI_BITCOUNT), sizeof(obj->BI_BITCOUNT), 1, bmpFile );
fseek ( bmpFile, 34, SEEK_SET) ;
fread ( &(obj->BI_SIZEIMAGE), sizeof(obj->BI_SIZEIMAGE), 1, bmpFile ) ;
fseek ( bmpFile, 46, SEEK_SET ) ;
fread ( &(obj->BI_CLRUSED), sizeof(obj->BI_CLRUSED), 1, bmpFile ) ;
fclose(bmpFile);
// ShowProperties(obj);
}
/* FUNCTION: ReadBuffer() */
/* PARAMETERS : CHAR ARRAY */
/* CALLS : NO USER DEFINED FUNCTIONS */
/* RETURNS : INTEGER DENOTING SUCCESS */
/* PURPOSE : TO FILL IMAGE DATA IN A BUFFER */
int ReadBuffer(char fileName[],BMPObj* obj)
{
//Local Variable Declarations
int jIndex,iIndex=0; //As Indexing Variables
int iByteCount=3; //For varying bitCount
int iColor=0; //Unit of Data being read
int iLoopCount=0;
FILE *bmpFile=NULL;
bmpFile = fopen(fileName,"r");
if(bmpFile == NULL)
{
exit(0);
}
//Allocation of Pointers to buffer
obj->buffer= (int**) malloc(iByteCount);
if(obj->buffer == NULL)
{
exit(0);
}
//3 For R,G,B
//Allocation of Memory to Pointers
for(jIndex=0;jIndex<iByteCount;jIndex++)
{
obj->buffer[jIndex] = (int*) malloc(sizeof(int)*obj->BI_HEIGHT*obj->BI_WIDTH);
if(obj->buffer[jIndex]==NULL)
{
exit(0);
}
}
jIndex=0; iIndex=0;
fseek ( bmpFile, obj->BF_OFFBITS, SEEK_SET) ;
//Note: Image Data copied as it is, without keeping inversion in mind...
//printf("\n Width : %d Height %d = %d",obj->BI_WIDTH,obj->BI_HEIGHT,(obj->BI_WIDTH*obj->BI_HEIGHT));
jIndex=0;
while(jIndex!=(obj->BI_WIDTH*obj->BI_HEIGHT))
{
//TODO:
fread ( (char*)&iColor, sizeof(char), 1, bmpFile ) ;
obj->buffer[_BLUE][jIndex] = iColor; //BLUE COMPONENT
fread ( (char*)&iColor, sizeof(char), 1, bmpFile ) ;
obj->buffer[_GREEN][jIndex]=iColor; //GREEN COMPONENT
fread ((char*)&iColor, sizeof(char), 1, bmpFile ) ;
obj->buffer[_RED][jIndex]=iColor; //RED COMPONENT
jIndex++;
iLoopCount++;
}
//TODO:DONE
fclose(bmpFile);
//bmpFile.close();
return 0;
}
void GetRgnArea(int *Area)
{
*Area = width*height;
//return 0;
}
void IsPtInRgn(Row, Col)
{
if(Row<=width && Col<=height)
printf("\nSpecified pixel is in the associated Bitmap region");
else
printf("\nSpecified pixel is not in the associated Bitmap region");
}
void GetRgnBounds(int *Rect)
{
*Rect = bmpFile.BF_OFFBITS;
}
int main()
{
int iLength,m,Area = 0,Rect=0;
printf("\n Enter the bmp file name with the extension .bmp:\n");
bmpFile.szFileName = (char*) malloc (100);
scanf("%s",bmpFile.szFileName);
iLength = strlen(bmpFile.szFileName);
GetProperties(bmpFile.szFileName,&bmpFile);
width = bmpFile.BI_WIDTH;
height = bmpFile.BI_HEIGHT;
ReadBuffer(bmpFile.szFileName,&bmpFile);
while(1){
printf("\nEnter 1 for project 1");
printf("\nEnter 2 for project 2");
printf("\nEnter 3 for project 3");
printf("\nEnter 4 for project 4");
printf("\nEnter 5 to exit from the project\n");
scanf("%d",&m);
switch(m)
{
case 1:
printf("Enter the offset for width,height\n");
scanf("%d,%d",&Row,&Col);
Offset(bmpFile.szFileName,"changed.bmp",&bmpFile);
break;
case 2:
GetRgnArea(&Area);
printf("The pixels in the given area is : %d\n",Area);
break;
case 3:
GetRgnBounds(&Rect);
printf("\n The bounded region in the associated Bitmap region starts from %d\n",Rect);
break;
case 4:
printf("\nEnter the row,column\n");
scanf("%d,%d",&Row,&Col);
IsPtInRgn(Row, Col);
break;
case 5:
exit(0);
default:break;
}
}
return 0;
}