1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
|
#include "BMP.h"
// FIXME (nikki#1#): Portrait bug on images of specific sizes
// TODO (nikki#1#): Memory leak checks
// THIS METHOD WRITES A BITMAP FILE FROM THE CHAR ARRAY .
bool BMP::saveBMP(string fileName, string *err)
{
FILE *filePtr;
//open filename in write binary mode
filePtr = fopen(fileName.c_str(),"wb");
// CHECK FILE CAN BE WRITTEN
if (filePtr == NULL) {
*err = "Could not write bitmap image file.\n";
return false;
}
// Write the BitmapFileHeader & BitmapInfoHeader
fwrite(&fileHeader, sizeof(BITMAPFILEHEADER), 1, filePtr);
fwrite(&infoHeader,sizeof(BITMAPINFOHEADER), 1, filePtr);
//move file point to the begging of bitmap data
fseek(filePtr,fileHeader.bfOffBits,SEEK_SET);
// ACTUALLY WRITE THE BITMAP FILE TO DISK
fwrite(imgArray, (infoHeader.biWidth * 3) * infoHeader.biHeight,1, filePtr);
fclose(filePtr);
return true;
}
// CROPS AN IMAGE FROM THE CHAR ARRAY BASED ON X, Y, W, H SUPPLIED
// FROM THE CALLER: Returns the raw array to the caller
unsigned char * BMP::getSubImage(int x, int y, int w, int h)
{
int width = (origWidth * 3);
int p = 0;
int xx = x;
int yy = (origHeight - (h + y)) ;
unsigned char * tmpArray = new unsigned char [(((w+padding)*h)*3)];
for(int m = 0; m < h; m++) {
for(int n = 0; n < w; n++) {
int b = (width*(yy-1)+xx*3-2)-1;
int g = (width*(yy-1)+xx*3-1)-1;
int r = (width*(yy-1)+xx*3)-1;
tmpArray[p] = (char)imgArray[b];
tmpArray[p+1] = (char)imgArray[g];
tmpArray[p+2] = (char)imgArray[r];
p+=3;
xx++;
}
if(xx >= w) xx = x;
yy++;
}
imgArray = tmpArray;
calcHeaders(w, h, 24); // MAKE A CALL TO UPDATE THE BITMAP HEADERS
return tmpArray;
}
// GENERIC METHOD TO UPDATE THE BITMAP HEADERS
void BMP::calcHeaders(int width, int height, int bpp)
{
int headerSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
// int rowSize = (((bpp * width ) + 31) / 32) * 4;
// int pixelArraySize = rowSize * height;
// int fileSize = headerSize + pixelArraySize;
int padding = (4 - (width * 3) % 4) %4;
int padWidth = (width * 3) + padding;
fileHeader.bfOffBits = headerSize;
fileHeader.bfReserved1 = 0;
fileHeader.bfReserved2 = 0;
fileHeader.bfType = 0x4D42;
fileHeader.bfSize = ((width * height) * 3 + headerSize) ;
infoHeader.biSize = sizeof(BITMAPINFOHEADER);
infoHeader.biWidth = width;
infoHeader.biHeight = height;
infoHeader.biPlanes = 1;
infoHeader.biBitCount = bpp;
infoHeader.biCompression = 0;
infoHeader.biSizeImage = ((width * 3) + padding) * height;
infoHeader.biXPelsPerMeter = 0;
infoHeader.biYPelsPerMeter = 0;
infoHeader.biClrUsed = 0;
infoHeader.biClrImportant = 0;
origWidth = width;
origHeight = height;
}
|