/* This is the splitting program. Given the input bitmap file name (24-bit uncompressed bmp) and the splitting factor on the command line, this program will output files 0000.bmp, 0001.bmp, etc. The split files will all be the same size. For a "1" split, the images will have both dimensions cut in half. For a "2" split, the dimensions will be cut in 4 pieces, etc. */ #define DEFAULTNUMLEVELS 1 #include #include #include #include typedef unsigned short int16; typedef unsigned long int32; 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)); void writeImage(unsigned short startx, unsigned short starty, unsigned char *pBitmap, int32 width, int32 height, unsigned char scalingFactor, unsigned char i, SBMPFileHeader *pFileHeader, SBMPInfoHeader *pInfoHeader) { static unsigned short fileIndex = 0; char filenamestr[256]; sprintf(filenamestr, "%.4d.bmp\0", fileIndex++); ofstream output(filenamestr, ios::out | ios::binary); output.write(pFileHeader, sizeof(SBMPFileHeader)); output.write(pInfoHeader, sizeof(SBMPInfoHeader)); for(unsigned short y = starty; y < starty + (height >> i); y += scalingFactor) { unsigned short count = 0; for(unsigned short x = startx; x < startx + (width >> i); x += scalingFactor) { output.write(&pBitmap[y * ((pInfoHeader->biBitCount >> 3) * width) + x *(pInfoHeader->biBitCount >> 3)], pInfoHeader->biBitCount >> 3); } } } int main(int argc, char* argv[]) { SBMPFileHeader BMPFileHeader; SBMPInfoHeader BMPInfoHeader; int32 width, height; unsigned char *pBitmap; unsigned char numLevels = DEFAULTNUMLEVELS; if(argc < 2) { cerr < "Must specify file name on the command line"; return 1; } if(argc >= 3) { numLevels = atoi(argv[2]); } 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; input.seekg(BMPFileHeader.bfDataOffset); width = BMPInfoHeader.biWidth; height = BMPInfoHeader.biHeight; pBitmap = new unsigned char[BMPInfoHeader.biSizeImage]; input.read(pBitmap, BMPInfoHeader.biSizeImage); BMPFileHeader.bfSize -= BMPFileHeader.bfDataOffset; BMPFileHeader.bfSize >>= 2*numLevels; BMPFileHeader.bfSize += BMPFileHeader.bfDataOffset; BMPInfoHeader.biSizeImage >>= 2*numLevels; BMPInfoHeader.biWidth >>= numLevels; BMPInfoHeader.biHeight >>= numLevels; for(unsigned char i=0; i<=numLevels; i++) { unsigned char scalingFactor = 1 << (numLevels - i); for(unsigned short starty = 0; starty < height - (height >> (i+1)); starty += height >> (i+1)) { for(unsigned short startx = 0; startx < width - (width >> (i+1)); startx += width >> (i+1)) { writeImage(startx, starty, pBitmap, width, height, scalingFactor, i, &BMPFileHeader, &BMPInfoHeader); } } } delete pBitmap; return 0; }