#include #include #include #include "array_utility.h" // Sample program to read a PPM (color) or PGM (grey) image // and write it out as a BMP image char *strstr(); typedef struct { unsigned short int type; // Magic identifier unsigned int size; // File size in bytes unsigned short int reserved1, reserved2; unsigned int offset; // Offset to image data, bytes } FILEHEADER; typedef struct { unsigned int size; // Header size in bytes int width,height; // Width and height of image unsigned short int planes; // Number of color planes unsigned short int bits; // Bits per pixel unsigned int compression; // Compression type unsigned int imagesize; // Image size in bytes int xresolution,yresolution; // Pixels per meter unsigned int ncolors; // Number of colors unsigned int importantcolors; // Important colors } INFOHEADER; float **read_bw_image(), ***read_color_image(); int main(int argc,char **argv) { int i,j, M,N, color, gotindex = 0; unsigned char grey,r,g,b; FILEHEADER fileheader; INFOHEADER infoheader; char fname_in[50], *fname_out, *sp, magic[4]; FILE *fp; float ***img_color, **img_grey; /* Check arguments */ if (argc < 2) { printf("Usage: %s filename\n",argv[0]); printf("Enter filename: "); scanf("%s",&fname_in); } else { strcpy(fname_in,argv[1]); } if ((fp = fopen(fname_in,"r")) == NULL) { fprintf(stderr,"Unable to open BMP file \"%s\"\n",fname_in); exit(-1); } get_header(fp,&N,&M,magic); printf("Input image size width and height: %d %d\n",N,M); if (strcmp(magic, "P5")==0) { color=0; printf("Grey image...\n"); img_grey=read_bw_image(fp,M,N); } else if (strcmp(magic, "P6")==0) { color=1; printf("Color image...\n"); img_color=read_color_image(fp,M,N); } else { printf("invalid magic=%s\n",magic); pause(); } fname_out=fname_in; sp=strstr(fname_in,".p"); if (sp) strcpy(sp,".bmp"); else strncat(fname_out,".bmp",4); if ((fp = fopen(fname_out,"w")) == NULL) { fprintf(stderr,"Unable to open BMP file \"%s\"\n",fname_out); exit(-1); } fileheader.type='M'*256+'B'; fprintf(stderr,"File ID is %d \n",fileheader.type); fileheader.offset=14+40; // fileheader+infoheader if (color) fileheader.size=fileheader.offset+3*M*N; else { fileheader.offset+=1024; fileheader.size=fileheader.offset+1024+M*N; // with color table } infoheader.ncolors=infoheader.importantcolors=256; if (color) infoheader.bits=24; else infoheader.bits=8; fprintf(stderr,"File offset is %d bytes\n",fileheader.offset); fprintf(stderr,"File size (headers + data) is %d bytes\n",fileheader.size); // FILEHEADER struct has 14 bytes, not a multiple of 4 bytes, but some // machines/compilers assume so and pad this struct by 2 bytes to make it 16, // which will unalign the future fwrite() calls. That is why here the components // are written individually. // write the fileheader if (fwrite(&fileheader.type,sizeof(unsigned short int),1,fp) != 1) { fprintf(stderr,"Failed to write BMP fileheader.type\n"); } if (fwrite(&fileheader.size,sizeof(unsigned int),1,fp) != 1) { fprintf(stderr,"Failed to write BMP fileheader.size\n"); } if ( fwrite(&fileheader.reserved1,sizeof(unsigned short int),1,fp) != 1 || fwrite(&fileheader.reserved2,sizeof(unsigned short int),1,fp) != 1) { fprintf(stderr,"Failed to write BMP fileheader.size\n"); } if (fwrite(&fileheader.offset,sizeof(unsigned int),1,fp) !=1) { fprintf(stderr,"Failed to write BMP fileheader.offset\n"); } infoheader.size=40; infoheader.width=N; infoheader.height=M; infoheader.planes=1; infoheader.compression=0; infoheader.imagesize=M*N; // infoheader.xresolution, infoheader.yresolution printf("bits: %d\n",infoheader.bits); // write the information header if (fwrite(&infoheader,sizeof(INFOHEADER),1,fp) != 1) { fprintf(stderr,"Failed to write BMP infoheader\n"); exit(-1); } if (!color) { // colortable is still used for grey level images for (i=0; i=0; i--) { for (j=0; j