// // Author: Matthias Gude // // Modified by Volker Blanz, 25.4.2001 // #include #include #include #include #include "LA.h" #include "Namen.h" #include "bmp.h" // from ioutil: WORDX readWord(FILE *f) { BYTEX buf[2]; fread((void*)buf, 1, 2, f); return (((WORDX)buf[1])<<8) | buf[0]; } DWORDX readDWord(FILE *f) { BYTEX buf[4]; fread((void*)buf, 1, 4, f); return (((WORDX)buf[3])<<24) | (((WORDX)buf[2])<<16) | (((WORDX)buf[1])<<8) | buf[0]; } void writeWord(WORDX w, FILE *f) { BYTEX buf[2]; buf[0]=(BYTEX)(w&0x00FF); buf[1]=(BYTEX)(w&0xFF00)>>8; fwrite(buf, 1, 2, f); } void writeDWord(DWORDX w, FILE *f) { BYTEX buf[4]; buf[0]=(BYTEX)(w&0x000000FF); buf[1]=(BYTEX)((w&0x0000FF00)>>8); buf[2]=(BYTEX)((w&0x00FF0000)>>16); buf[3]=(BYTEX)((w&0xFF000000)>>24); fwrite(buf, 1, 4, f); } /**********************************************************************/ bool checkMagicKey(FILE *f) { char magic[2]; fread(magic, 2, 1, f); return (strncmp(magic, MAGICKEY, 2)==0); } void readFileHeader(FILE *f, BITMAPFILEHEADERX *h) { h->bfSize=readDWord(f); h->bfReserved1=readWord(f); h->bfReserved2=readWord(f); h->bfOffBits=readDWord(f); } void readInfoHeader(FILE *f, BITMAPINFOHEADERX *h) { h->biSize=readDWord(f); h->biWidth=readDWord(f); h->biHeight=readDWord(f); h->biPlanes=readWord(f); h->biBitCount=readWord(f); h->biCompression=readDWord(f); h->biSizeImage=readDWord(f); h->biXPelsPerMeter=readDWord(f); h->biYPelsPerMeter=readDWord(f); h->biClrUsed=readDWord(f); h->biClrImportant=readDWord(f); } void readData(FMatrix &r, FMatrix &g, FMatrix &b, FILE *f, BITMAPINFOHEADERX bi) { int i, j; int rest; int w = bi.biWidth; int h = bi.biHeight; int nbits = bi.biBitCount; int comp = bi.biCompression; int ncols = bi.biClrUsed; RGBQUADX *colormap; DWORDX *buffer; double factor = 1.0 / 255.0; if (!(nbits==1 || nbits==4 || nbits==8 || nbits==24) || bi.biPlanes!=1 || comp>BI_RLE4 ) { return; // weird BMP image } if (!(comp==BI_RGB || (nbits==4 && comp==BI_RLE4) || (nbits==8 && comp==BI_RLE8))) { return; // weird compression type } /* read image data */ buffer = new DWORDX[w*h*3]; switch(nbits) { case 1: { //cerr << "Sorry, 1 bit Images not supported yet!" << endl; return; } case 4: { BYTEX tmp; BYTEX idx[2]; int k; if(comp==BI_RLE4) { //cerr << "Sorry, compressed Images not supported yet!\n" << endl; return; } /* read colormap */ colormap = new RGBQUADX[ncols]; fread(colormap, sizeof(RGBQUADX), ncols, f); rest = ((int)(w/2.+0.5))%4; for(i=0; i>4; idx[1] = (tmp & 0x0F); for(k=0; k<2 && j+k>16); g.m[y][x] = (float) factor * ((buffer[w*y+x] & 0x0000FF00)>>8); b.m[y][x] = (float) factor * (buffer[w*y+x] & 0x000000FF); #endif #ifdef _WIN32 b.m[y][x] = (float) factor * ((buffer[w*y+x] & 0x00FF0000)>>16); g.m[y][x] = (float) factor * ((buffer[w*y+x] & 0x0000FF00)>>8); r.m[y][x] = (float) factor * (buffer[w*y+x] & 0x000000FF); #endif } } delete [] buffer; } void printFileHeader(BITMAPFILEHEADERX h) { h=h; /* cout << "BitmapFileHeader" << endl; cout << "\tSize.............." << h.bfSize << endl; cout << "\tReserved1........." << h.bfReserved1 << endl; cout << "\tReserved2........." << h.bfReserved2 << endl; cout << "\tOffsetBits........" << h.bfOffBits << endl; */ } void printInfoHeader(BITMAPINFOHEADERX h) { h=h; /* cout << "BitmapInfoHeader\n"; cout << "\tSize.............." << h.biSize << endl; cout << "\tWidth............." << h.biWidth << endl; cout << "\tHeight............" << h.biHeight << endl; cout << "\tPlanes............" << h.biPlanes << endl; cout << "\tBitCount.........." << h.biBitCount << endl; cout << "\tCompression......." << h.biCompression << endl; cout << "\tSizeImage........." << h.biSizeImage << endl; cout << "\tXPelsPerMeter....." << h.biXPelsPerMeter << endl; cout << "\tYPelsPerMeter....." << h.biYPelsPerMeter << endl; cout << "\tColorsUsed........" << h.biClrUsed << endl; cout << "\tColorsImportant..." << h.biClrImportant << endl; */ } bool loadBMP(FMatrix& r, FMatrix& g, FMatrix& b, const char* fname) { FILE *f; BITMAPFILEHEADERX fheader; BITMAPINFOHEADERX iheader; char ffname[60]; sprintf(ffname,"%s%s",PFAD,fname); //printf("%s%s\n",PFAD,fname); f = fopen(ffname, "rb"); if(!f) { cerr << "unable to open " << ffname << "!" << endl; return false; } if(!checkMagicKey(f)) { cerr << ffname << " is not a bitmap-file." << endl; return false; } readFileHeader(f, &fheader); //printFileHeader(fheader); readInfoHeader(f, &iheader); /* 0 means all colors are used */ if ( iheader.biClrUsed == 0 ) { iheader.biClrUsed = 1 << iheader.biBitCount; } if ( iheader.biClrImportant == 0 ) { iheader.biClrImportant = iheader.biClrUsed; } //printInfoHeader(iheader); /* ckeck and set size if necessary */ if(r.width() != (int)iheader.biWidth || r.height() != (int)iheader.biHeight) { if (r.allocated()) r.free_FMatrix(); r.alloc_FMatrix(0,iheader.biHeight -1, 0,iheader.biWidth -1); } if(g.width() != (int)iheader.biWidth || g.height() != (int)iheader.biHeight) { if (g.allocated()) g.free_FMatrix(); g.alloc_FMatrix(0,iheader.biHeight -1, 0,iheader.biWidth -1); } if(b.width() != (int)iheader.biWidth || b.height() != (int)iheader.biHeight) { if (b.allocated()) b.free_FMatrix(); b.alloc_FMatrix(0,iheader.biHeight -1, 0,iheader.biWidth -1); } readData(r, g, b, f, iheader); fclose(f); return true; } bool saveBMP(FMatrix& r, FMatrix& g, FMatrix& b, const char* fname) { FILE *f = fopen(fname, "wb"); BITMAPFILEHEADERX fheader; BITMAPINFOHEADERX iheader; int x, y; int w = r.width(); int h = r.height(); int rest = w%4; float factor = 255.0; if(w != g.width() || w != b.width() || h != g.height() || h != b.height()) { //cerr << "Failure in saveBMP(): "; //cerr << "all three images must have the same size!" << endl; } /* fill Fileheader */ fheader.bfSize = 2 + /* magickey */ sizeof(BITMAPFILEHEADERX) + sizeof(BITMAPINFOHEADERX) + h * (3*w + rest); fheader.bfReserved1 = fheader.bfReserved2 = 0; fheader.bfOffBits = 54; /* fill infoheader */ iheader.biSize = 40; iheader.biWidth = w; iheader.biHeight = h; iheader.biPlanes = 1; iheader.biBitCount = 24; iheader.biCompression = BI_RGB; iheader.biSizeImage = (3*w+rest)*h; iheader.biXPelsPerMeter = 2952; iheader.biYPelsPerMeter = 2952; iheader.biClrUsed = 0; iheader.biClrImportant = 0; /* write magickey */ fwrite((void*)MAGICKEY, 2, 1, f); /* write fileheader */ writeDWord(fheader.bfSize, f); writeWord(fheader.bfReserved1, f); writeWord(fheader.bfReserved2, f); writeDWord(fheader.bfOffBits, f); /* write infoheader */ writeDWord(iheader.biSize, f); writeDWord(iheader.biWidth, f); writeDWord(iheader.biHeight, f); writeWord(iheader.biPlanes, f); writeWord(iheader.biBitCount, f); writeDWord(iheader.biCompression, f); writeDWord(iheader.biSizeImage, f); writeDWord(iheader.biXPelsPerMeter, f); writeDWord(iheader.biYPelsPerMeter, f); writeDWord(iheader.biClrUsed, f); writeDWord(iheader.biClrImportant, f); /* write imagedata */ for(y=r.nrl; y<=r.nrh; ++y) { for(x=r.ncl; x<=r.nch; ++x) { fputc((BYTEX)(factor * b.m[y][x]), f); fputc((BYTEX)(factor * g.m[y][x]), f); fputc((BYTEX)(factor * r.m[y][x]), f); } for(x=0; x