/* Given the input bitmap (24-bit uncompressed bmp), this program produces lower resolution versions of the image. The output is coarse0.bmp, coarse1.bmp, etc. */ #include #include #include #include typedef unsigned short int16; typedef unsigned long int32; inline int32 wrapCoord(int32 coord, int32 size) { if(coord >= size) return (size - coord); return coord; } struct SBMPFileHeader { int16 bfType; int32 bfSize; int32 bfReserved; int32 bfDataOffset; } __attribute__ ((packed)); struct SBMPInfoHeader { int32 biSize; int32 biWidth; int32 biHeight; int16 biPlanes; int16 biBitCount; int32 biCompression; int32 biSizeImage; int32 biXPelsPerMeter; int32 biYPelsPerMeter; int32 biClrUsed; int32 biClrImportant; } __attribute__ ((packed)); bool getCoarsePixel(int32 xcoarse, int32 ycoarse, unsigned char numCoarseImages, unsigned char i, char *pBitmap, int32 widthFine, int32 heightFine, int32 inPitch) { int32 xfine, yfine; // Cycle through the fine pixels inside the coarse pixe for(yfine = i + ycoarse * numCoarseImages; yfine != i + (ycoarse+1) * numCoarseImages; yfine++) { for(xfine = i + xcoarse * numCoarseImages; xfine != i + (xcoarse+1) * numCoarseImages; xfine++) { if(pBitmap[inPitch * wrapCoord(yfine, heightFine) + 3 * wrapCoord(xfine, widthFine)] == '\x00') { return true; } } } return false; } int main(int argc, char* argv[]) { SBMPFileHeader BMPFileHeader; SBMPInfoHeader BMPInfoHeader; char *pBitmap; if(argc < 2) { cerr << "Must specify file name on the command line"; return 1; } ifstream input(argv[1]); if(!input.is_open()) { cerr << "Couldn't open input file"; return 1; } input.read(&BMPFileHeader, sizeof(BMPFileHeader)); input.read(&BMPInfoHeader, sizeof(BMPInfoHeader)); BMPInfoHeader.biSizeImage = BMPFileHeader.bfSize - BMPFileHeader.bfDataOffset; if(BMPInfoHeader.biBitCount != 24) { cerr << "Bit depths other than 24-bit aren't supported\n"; return 1; } input.seekg(BMPFileHeader.bfDataOffset); pBitmap = new char[BMPInfoHeader.biSizeImage]; input.read(pBitmap, BMPInfoHeader.biSizeImage); /* The number of coarse images to create (this also controls the size of the resulting images) is hard-coded here. Change this to modify the coarse-coding level. Also change the open commands below. */ unsigned char numCoarseImages = 4; unsigned char i; int32 widthFine, heightFine, widthCoarse, heightCoarse; int32 inPitch, outPitch; ofstream pOut[numCoarseImages]; pOut[0].open("coarse0.bmp"); pOut[1].open("coarse1.bmp"); pOut[2].open("coarse2.bmp"); pOut[3].open("coarse3.bmp"); widthFine = BMPInfoHeader.biWidth; heightFine = BMPInfoHeader.biHeight; widthCoarse = widthFine / numCoarseImages; heightCoarse = heightFine / numCoarseImages; // pitch is always divisible by 4. 3bpp inPitch = (3 * widthFine + 3) & ~3; outPitch = (3 * widthCoarse + 3) & ~3; // Set up the image sizes BMPInfoHeader.biWidth = widthCoarse; BMPInfoHeader.biHeight = heightCoarse; BMPInfoHeader.biSizeImage = outPitch * heightCoarse; BMPFileHeader.bfSize = BMPInfoHeader.biSizeImage - BMPFileHeader.bfDataOffset; for(i=0; i