#include "Pixmap.h" #include typedef unsigned short ushort; typedef unsigned long ulong; fstream inf; // global in this file for convenience fstream outf; // output file ushort getShort() { //BMP format uses little-endian integer types // get a 2-byte integer stored in little-endian form char ic; ushort ip; inf.get(ic); ip = ic; //first byte is little one inf.get(ic); ip |= ((ushort)ic << 8); // or in high order byte return ip; } ulong getLong() { //BMP format uses little-endian integer types // get a 4-byte integer stored in little-endian form ulong ip = 0; char ic = 0; unsigned char uc = ic; inf.get(ic); uc = ic; ip = uc; inf.get(ic); uc = ic; ip |=((ulong)uc << 8); inf.get(ic); uc = ic; ip |=((ulong)uc << 16); inf.get(ic); uc = ic; ip |=((ulong)uc << 24); return ip; } int RGBpixmap:: readBMPFile(const char *fname) { // Read into memory an mRGB image from an uncompressed BMP file. // return 0 on failure, 1 on success inf.open(fname, ios::in|ios::binary); //read binary char's if(!inf){ cout << " can't open file: " << fname << endl; return 0;} int k, row, col, numPadBytes, nBytesInRow; // read the file header information char ch1, ch2; inf.get(ch1); inf.get(ch2); //type: always 'BM' ulong fileSize = getLong(); ushort reserved1 = getShort(); // always 0 ushort reserved2= getShort(); // always 0 ulong offBits = getLong(); // offset to image - unreliable ulong headerSize = getLong(); // always 40 ulong numCols = getLong(); // number of columns in image ulong numRows = getLong(); // number of rows in image ushort planes= getShort(); // always 1 ushort bitsPerPixel= getShort(); //8 or 24; allow 24 here ulong compression = getLong(); // must be 0 for uncompressed ulong imageSize = getLong(); // total bytes in image ulong xPels = getLong(); // always 0 ulong yPels = getLong(); // always 0 ulong numLUTentries = getLong(); // 256 for 8 bit, otherwise 0 ulong impColors = getLong(); // always 0 if(bitsPerPixel != 24) { // error - must be a 24 bit uncompressed image cout << "not a 24 bit/pixelimage, or is compressed!\n"; inf.close(); return 0; } //add bytes at end of each row so total # is a multiple of 4 // round up 3*numCols to next mult. of 4 nBytesInRow = ((3 * numCols + 3)/4) * 4; numPadBytes = nBytesInRow - 3 * numCols; // need this many nRows = numRows; // set class's data members nCols = numCols; if (pixel) delete pixel; // in case we read over an old image pixel = new mRGB[nRows * nCols]; //make space for array if(!pixel) return 0; // out of memory! long count = 0; char dum; for(row = 0; row < nRows; row++) { for(col = 0; col < nCols; col++) { char r,g,b; inf.get(b); inf.get(g); inf.get(r); //read bytes pixel[count].r = r; //place them in colors pixel[count].g = g; pixel[count++].b = b; } for(k = 0; k < numPadBytes ; k++) //skip pad bytes at row's end inf >> dum; } inf.close(); return 1; // success } // WRITTEN BY TingJen (it is slow because it writes one // byte at a time! It uses putLong() and putShort() utility: void putLong(unsigned long ip) { outf.put((unsigned char)(ip & 0xff)); outf.put((unsigned char)((ip>>8) & 0xff)); outf.put((unsigned char)((ip>>16) & 0xff)); outf.put((unsigned char)((ip>>24) & 0xff)); } void putShort(unsigned short ip) { outf.put((unsigned char)(ip & 0xff)); outf.put((unsigned char)((ip>>8) & 0xff)); } int RGBpixmap::writeBMPFile(const char *fname) { outf.open(fname, ios::out | ios::binary); if (!outf) { cerr << "can't open file: " << fname << endl; return -1; } outf.put('B'); outf.put('M'); // file type "BM" putLong(0x36L + nRows * nCols * 3); //file size putLong(0L); //reserved putLong(0x36L); // offset to image putLong(40L); // putLong((unsigned long) nCols); //number of columns putLong((unsigned long) nRows); //number of rows putShort(1); // putShort(24); // bits per pixel putLong(0L); // not compressed putLong((unsigned long)nRows * nCols * 3); // total bytes in image putLong(0L); // putLong(0L); // putLong(0L); // numbers of colors : Not used putLong(0L); // int count = 0; int numPadBytes = ((3 * nCols + 3)/4) * 4 - 3 * nCols; for (int y = 0; y < nRows; y ++) { for (int x = 0; x < nCols ; x++) { mRGB &p = pixel[count++]; outf.put(p.b); outf.put(p.g); outf.put(p.r); } for (int k = 0; k < numPadBytes; k ++) // padding outf.put(' '); } outf.close(); return 1; }