extern "C" {
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
}
#include <objgfx40/objgfx40.h>
#include <objgfx40/ogBlit.h>
using namespace std;
static bool
fileExists(const char *file)
{
FILE *f = fopen(file, "rb");
if (!f)
return false;
fclose(f);
return true;
}
ogBlit::ogBlit(ogBlit const & srcBlit, bool doFullCopy = false) : ogSprite() {
// horrible horrible hack. This is required because I can't have
// two constructors with the same parameter list like I can in pascal.
// -- begin hack --
if (doFullCopy) ogSprite::operator=(srcBlit);
// -- end hack --
startX = srcBlit.startX;
startY = srcBlit.startY;
endX = srcBlit.endX;
endY = srcBlit.endY;
totalPixCount = srcBlit.totalPixCount;
blitMaskSize = srcBlit.blitMaskSize;
blitMask = NULL;
if (blitMaskSize != 0) {
blitMask = new uInt8[blitMaskSize];
if ((blitMask != NULL) && (srcBlit.blitMask != NULL))
memcpy(blitMask, srcBlit.blitMask, blitMaskSize);
} // if
return;
} // ogBlit::ogBlit
ogBlit::ogBlit(void) : ogSprite() {
blitMask = NULL;
blitMaskSize = 0;
totalPixCount = 0;
startX = 0;
startY = 0;
endX = 0;
endY = 0;
return;
} // ogBlit::ogBlit
void
ogBlit::BlitSize(ogSurface& src, int32 x1, int32 y1, int32 x2, int32 y2) {
uInt32 aMask;
int32 x,y;
uInt8 zerocount;
uInt8 pixcount;
bool inZeros;
bool found;
// first free the image data or the blitMask data if we already have some
free(image);
delete [] blitMask;
image = NULL;
blitMask = NULL;
imageSize = 0;
blitMaskSize = 0;
aMask = src.ogGetAlphaMasker();
tColour = src.ogGetTransparentColor();
startX = x1;
startY = y1;
endX = x2;
endY = y2;
// start by locating the left-most non-transparent pixel in the region defined
// by (x1,y1) to (x2,y2)
found = false;
while ((!found) && (startX <= x2)) {
for (y = y1; y <= y2; y++)
found |= ((src.ogGetPixel(startX, y) & aMask) != tColour);
if (!found) ++startX;
} // while
// now we look for the top-most non-transparent pixel in the regsion
// defined by (startX,y1) to (x2,y2)
found = false;
while ((!found) && (startY <= y2)) {
for (x = startX; x <= x2; x++)
found |= ((src.ogGetPixel(x,startY) & aMask) != tColour);
if (!found) ++startY;
} // while
found = false;
while ((!found) && (endX >= startX)) {
for (y = startY; y <= y2; y++)
found |= ((src.ogGetPixel(endX,y) & aMask) != tColour);
if (!found) --endX;
} // while
found = false;
while ((!found) && (endY >= startY)) {
for (x = startX; x <= endX; x++)
found |= ((src.ogGetPixel(x,endY) & aMask) != tColour);
if (!found) --endY;
} // while
for (y = startY; y <= endY; y++) {
zerocount = 0;
blitMaskSize++; // save room for xlcount
x = startX;
inZeros = ((src.ogGetPixel(x,y) & aMask) == tColour);
while (x <= endX) {
switch (inZeros) {
case true:
zerocount = 0; // How many zeros?
while ((x <= endX) && ((src.ogGetPixel(x,y) & aMask) == tColour)) {
++x;
if (zerocount == 255) {
zerocount = 0;
blitMaskSize += 2;
} else ++zerocount;
} // while
inZeros = false;
break; // case true
case false:
pixcount = 0;
blitMaskSize += 2;
do {
++x;
if (pixcount == 255) {
blitMaskSize += 2;
pixcount = 0;
} else ++pixcount;
++totalPixCount;
//mjikaboom imageSize += bm;
} while ((x <= endX) && ((src.ogGetPixel(x,y) & aMask) != tColour));
inZeros = true;
break; // case false
} // switch
} // while
} // for
startX -= x1;
startY -= y1;
endX -= x1;
endY -= y1;
blitMask = new uInt8[blitMaskSize]; //(uInt8 *)malloc(blitMaskSize);
// memset(blitMask,0,blitMaskSize);
return;
} // ogBlit::BlitSize
void
ogBlit::GetBlitMask(ogSurface& src, int32 x1, int32 y1,
int32 x2, int32 y2) {
uInt8 * blitMaskPtr;
uInt8 * lineCountPtr;
int32 x, y;
bool inZeros;
uInt8 pixCount, zeroCount;
uInt32 aMask;
uInt32 tmp;
if (x1 > x2) {
tmp = x1;
x1 = x2;
x2 = tmp;
} // if
if (y1 > y2) {
tmp = y1;
y1 = y2;
y2 = tmp;
} // if
// calculate the width/height
width = (x2 - x1)+1;
height = (y2 - y1)+1;
bytesPerPixel = src.ogGetBytesPerPix();
if (bytesPerPixel == 1) {
if (pal != NULL) pal = new ogRGBA8[256];
// note that tPal will check for null, so this check may be unnecessary
if (pal != NULL) src.ogGetPalette(pal);
/* for (tmp = 0; tmp < 256; tmp++)
src.Unpack(tmp,
pal[tmp].red,
pal[tmp].green,
pal[tmp].blue,
pal[tmp].alpha); */
} // if
// compute the size of the blit mask and allocate memory for it
BlitSize(src, x1, y1, x2, y2);
if (blitMask == NULL) return;
blitMaskPtr = blitMask;
aMask = src.ogGetAlphaMasker();
tColour = src.ogGetTransparentColor();
for (y = y1+startY; y <= y1+endY; y++) {
zeroCount = 0;
lineCountPtr = blitMaskPtr;
*lineCountPtr = 0;
++blitMaskPtr;
x = x1+startX;
inZeros = ((src.ogGetPixel(x,y) & aMask) == tColour);
while (x <= x1+endX) {
switch (inZeros) {
case true:
zeroCount = 0;
while ((x <= x1+endX) && ((src.ogGetPixel(x,y) & aMask) == tColour)) {
++x;
if (zeroCount == 255) {
++(*lineCountPtr);
*blitMaskPtr = 255; // offset
++blitMaskPtr; // increment to next byte
*blitMaskPtr = 0; // runcount
++blitMaskPtr; // increment to next byte
*blitMaskPtr = 0; // offset
zeroCount = 0;
} else ++zeroCount;
} // while
inZeros = false; // we are no longer in zeros
break; // case true
case false:
++(*lineCountPtr);
*blitMaskPtr = zeroCount;
++blitMaskPtr;
*blitMaskPtr = 0;
pixCount = 0;
do {
++x;
if (pixCount == 255) {
++(*lineCountPtr);
*blitMaskPtr = 255; // runcount
++blitMaskPtr; // advance pointer
*blitMaskPtr = 0; // offset to next run
++blitMaskPtr; // advance pointer
*blitMaskPtr = 0; // next run count (incremented below)
pixCount = 0;
} else ++pixCount;
++(*blitMaskPtr);
} while ((x <= (x1+endX)) &&
((src.ogGetPixel(x,y) & aMask) != tColour));
++blitMaskPtr;
inZeros = true; // set inZeros to true to toggle
break; // case false
} // switch
} // while
} // for y
return;
} // ogBlit::GetBlitMask
void
ogBlit::Get(ogSurface& src, int32 x1, int32 y1, int32 x2, int32 y2) {
int32 tmp;
if (x1 > x2) {
tmp = x1;
x1 = x2;
x2 = tmp;
} // if
if (y1 > y2) {
tmp = y1;
y1 = y2;
y2 = tmp;
} // if
// get the blit mask
GetBlitMask(src, x1, y1, x2, y2);
// now get the actual blit using the blit mask
GetBlitWithMask(src, x1, y1);
return;
} // ogBlit::Get
void
ogBlit::GetBlitWithMask(ogSurface & src, int32 x, int32 y) {
/*
* getBlitWithMask
*
* Retrieves the data portion of a blit using a predefined mask and
* stores the data in the image pointer. If the source buffer is
* a different pixel format, we will adjust the image pointer
* to accommodate the new data and update the pixel format. The put()
* function will adjust the pixels to the dest buffer as needed.
* Before calling this routine, you must call getBlitMask.
*/
int32 sx, sy;
uInt8 lineCount, offset, pixCount;
uInt32 nsy, ney;
uInt8 *blitMaskPtr;
void *imagePtr;
uInt32 distToEdge, xRight, count;
ogPixelFmt pixFmt;
if (blitMask == NULL) return;
if ( (x + startX > (int32)src.ogGetMaxX()) || (x + endX < 0) ||
(y + startY > (int32)src.ogGetMaxY()) || (y + endY < 0)) return;
blitMaskPtr = blitMask;
// First check to see if the pixel format we got the blitmask from
// is different than what we're dealing with now
// note that the first time through pixelFmtID will be 0, so this
// will get that information
if (src.ogGetPixFmtID() != pixelFmtID) {
free(image);
image = NULL;
imageSize = 0;
src.ogGetPixFmt(pixFmt);
bitDepth = pixFmt.BPP;
RFP = pixFmt.redFieldPosition;
GFP = pixFmt.greenFieldPosition;
BFP = pixFmt.blueFieldPosition;
AFP = pixFmt.alphaFieldPosition;
rShift = 8-pixFmt.redMaskSize;
gShift = 8-pixFmt.greenMaskSize;
bShift = 8-pixFmt.blueMaskSize;
aShift = 8-pixFmt.alphaMaskSize;
bytesPerPixel = src.ogGetBytesPerPix();
pixelFmtID = src.ogGetPixFmtID();
dAlpha = src.ogGetAlpha();
// tColour = src.ogGetTransparentColor(); // done elsewhere
} // if
if (image == NULL) {
imageSize = totalPixCount * bytesPerPixel;
image = malloc(imageSize);
} // if
imagePtr = image;
// If any part of the blit data is out of bounds, we need to fill it with the
// transparent colour
if ( (x + startX < 0) || (x + endX > (int32)src.ogGetMaxX()) ||
(y + startY < 0) || (y + endY > (int32)src.ogGetMaxY())) {
for (count = 0; count < totalPixCount; count++) {
SetPixel(imagePtr, tColour);
(uInt8 *)imagePtr += bytesPerPixel;
} // for count
imagePtr = image; // reset the image pointer
} // if
// first do clipping on the top edge
nsy = startY;
if (y+startY < 0) {
/*
* If we're here then part of the blit is above the top edge of the
* buffer. The distance to the top of the buffer is abs(y+startY).
* So, we need to loop through the blit geometry and advance the
* relative pointers (BlitMaskPtr and ImagePtr)
*/
for (sy = (y+startY); sy<0; sy++) {
++nsy;
lineCount = *blitMaskPtr;
++blitMaskPtr;
while (lineCount > 0) {
++blitMaskPtr;
pixCount = *blitMaskPtr;
++blitMaskPtr;
if (pixCount > 0) (uInt8 *)imagePtr += pixCount*bytesPerPixel;
--lineCount;
} // while
} // for sy
} // if
// Now do clipping on the bottom edge. This is easy.
if (y+endY > (int32)src.ogGetMaxY())
ney = (src.ogGetMaxY()-y);
else
ney = endY;
for (sy = nsy; (uInt32)sy <= ney; sy++) {
sx = x+startX;
lineCount = *blitMaskPtr;
++blitMaskPtr;
while (lineCount > 0) {
offset = *blitMaskPtr;
++blitMaskPtr;
sx += offset;
pixCount = *blitMaskPtr;
++blitMaskPtr;
if (pixCount > 0) {
if (sx <= (int32)src.ogGetMaxX()) {
if ((sx < 0) && (sx+pixCount > 0)) {
pixCount += sx; // remember, sx is negative
(uInt8*)imagePtr -= sx*bytesPerPixel; // remember, sx is negative
sx = 0;
} // if sx<0 && sx+pixcount>0
if (sx+pixCount > (int32)src.ogGetMaxX()+1) {
distToEdge = (src.ogGetMaxX()-sx)+1;
xRight = (pixCount - distToEdge)*bytesPerPixel;
pixCount = distToEdge;
} else xRight = 0; // if sx+pixCount>MaxX
if (sx >= 0)
src.ogCopyLineFrom(sx, y+sy, imagePtr, pixCount*bytesPerPixel);
(uInt8*)imagePtr += xRight; // get any remainter from right edge clip
} // if sx <= MaxX
sx += pixCount;
(uInt8*)imagePtr += pixCount*bytesPerPixel;
} // if pixCount>0
--lineCount;
} // while
} // for
return;
} // ogBlit::GetBlitWithMask
uInt32
ogBlit::GetSize(void) {
return ogSprite::GetSize() +
sizeof(totalPixCount) +
sizeof(blitMaskSize) +
blitMaskSize +
sizeof(startX) +
sizeof(startY) +
sizeof(endX) +
sizeof(endY);
} // ogBlit::GetSize
bool
ogBlit::LoadFrom(const char * filename, uInt32 offset) {
FILE * infile;
uInt32 lresult, tresult, totSize;
uInt32 tmpSize;
char headerIdent[4];
if (!fileExists(filename)) return false;
if ((infile = fopen(filename,"rb")) == NULL) return false;
fseek(infile, offset, SEEK_SET);
// for now just free up the previous image. This will be changed
// later so it doesn't affect the current image (if any) if there
// is a failure loading
free(image);
delete [] pal;
delete [] blitMask;
imageSize = 0;
blitMaskSize = 0;
tresult = 0; // total bytes we've read in so far
lresult = fread(headerIdent, sizeof(headerIdent), 1, infile);
tresult += lresult*sizeof(headerIdent);
if ((headerIdent[0] != 'B') ||
(headerIdent[1] != 'L') ||
(headerIdent[2] != 'T') ||
(headerIdent[3] != (uInt8)0x1A)) {
fclose(infile);
return false;
}
lresult = fread(&totSize, sizeof(totSize), 1, infile);
tresult += lresult*sizeof(totSize);
lresult = fread(&width, sizeof(width), 1, infile);
tresult += lresult*sizeof(width);
lresult = fread(&height, sizeof(height), 1, infile);
tresult += lresult*sizeof(height);
lresult = fread(&bitDepth, sizeof(bitDepth), 1, infile);
tresult += lresult*sizeof(bitDepth);
lresult = fread(&RFP, sizeof(RFP), 1, infile);
tresult += lresult*sizeof(RFP);
lresult = fread(&GFP, sizeof(GFP), 1, infile);
tresult += lresult*sizeof(GFP);
lresult = fread(&BFP, sizeof(BFP), 1, infile);
tresult += lresult*sizeof(BFP);
lresult = fread(&AFP, sizeof(AFP), 1, infile);
tresult += lresult*sizeof(AFP);
lresult = fread(&rShift, sizeof(rShift), 1, infile);
tresult += lresult*sizeof(rShift);
lresult = fread(&gShift, sizeof(gShift), 1, infile);
tresult += lresult*sizeof(gShift);
lresult = fread(&bShift, sizeof(bShift), 1, infile);
tresult += lresult*sizeof(bShift);
lresult = fread(&aShift, sizeof(aShift), 1, infile);
tresult += lresult*sizeof(aShift);
lresult = fread(&tColour, sizeof(tColour), 1, infile);
tresult += lresult*sizeof(tColour);
lresult = fread(&pixelFmtID, sizeof(pixelFmtID), 1, infile);
tresult += lresult*sizeof(pixelFmtID);
lresult = fread(&bytesPerPixel, sizeof(bytesPerPixel), 1, infile);
tresult += lresult*sizeof(bytesPerPixel);
lresult = fread(&dAlpha, sizeof(dAlpha), 1, infile);
tresult += lresult*sizeof(dAlpha);
lresult = fread(&totalPixCount, sizeof(totalPixCount), 1, infile);
tresult += lresult*sizeof(totalPixCount);
lresult = fread(&startX, sizeof(startX), 1, infile);
tresult += lresult*sizeof(startX);
lresult = fread(&startY, sizeof(startY), 1, infile);
tresult += lresult*sizeof(startY);
lresult = fread(&endX, sizeof(endX), 1, infile);
tresult += lresult*sizeof(endX);
lresult = fread(&endY, sizeof(endY), 1, infile);
tresult += lresult*sizeof(endY);
lresult = fread(&blitMaskSize, sizeof(blitMaskSize), 1, infile);
tresult += lresult*sizeof(blitMaskSize);
lresult = fread(&imageSize, sizeof(imageSize), 1, infile);
tresult += lresult*sizeof(imageSize);
blitMask = new uInt8[blitMaskSize];
if (blitMask == NULL) {
fclose(infile);
return false;
}
image = malloc(imageSize);
if (image == NULL) {
fclose(infile);
return false;
}
// read in the blit mask
lresult = fread(blitMask, blitMaskSize, 1, infile);
tresult += lresult*blitMaskSize;
// read in the image data
// it's possible that if we start saving only blit masks this section will be
// blank
lresult = fread(image, 1, imageSize, infile);
tresult += lresult;
if (bitDepth == 8) {
// 8bpp sprites have palettes
if (pal == NULL) pal = new ogRGBA8[256];
if (pal == NULL) {
fclose(infile);
return false;
} // if pal==NULL
lresult = fread(&tmpSize, sizeof(tmpSize), 1, infile);
tresult += lresult*sizeof(tmpSize);
if (tmpSize > sizeof(ogRGBA8)*256) {
fclose(infile);
return false;
}
lresult = fread(pal, tmpSize, 1, infile);
tresult += lresult*tmpSize;
} // if bitDepth == 8
fclose(infile);
return (tresult == totSize);
} // ogBlit::LoadFrom
void
ogBlit::Put(ogSurface& dest, int32 x, int32 y) {
int32 sx, sy;
uInt32 nsy, ney;
uInt8 lineCount, offset, pixCount;
uInt8* blitMaskPtr;
void * imagePtr;
uInt32 distToEdge, xRight, xx;
uInt8 r, g, b, a;
ogPixelFmt pixFmt;
// can we draw anything?
if ((blitMask == NULL) || (image == NULL)) return;
if (!dest.ogAvail()) return;
// see if the blit is oustide the buffer
if ( ((x+startX) > (int32)dest.ogGetMaxX()) || ((x + endX) < 0) ||
((y+startY) > (int32)dest.ogGetMaxY()) || ((y + endY) < 0) ) return;
blitMaskPtr = blitMask;
imagePtr = image;
// first do clipping on the top edge
nsy = startY;
if (y+startY < 0) {
/*
* If we're here then part of the blit is above the top edge of the
* buffer. The distance to the top of the buffer is abs(y+startY).
* So, we need to loop through the blit geometry and advance the
* relative pointers (blitMaskPtr and imagePtr)
*/
for (sy = (y+startY); sy < 0; sy++) {
++nsy;
lineCount = *blitMaskPtr;
++blitMaskPtr;
while (lineCount > 0) {
++blitMaskPtr;
pixCount = *blitMaskPtr;
++blitMaskPtr;
if (pixCount > 0) (uInt8 *)imagePtr += pixCount*bytesPerPixel;
--lineCount;
} // while
} // for sy
} // if
// Now do clipping on the bottom edge. This is easy
// y is guaranteed to be >=0
// I'm going to contradict myself and say that I don't think y is
// guaranteed to be >= 0.
if (y+endY > (int32)dest.ogGetMaxY())
ney = (dest.ogGetMaxY()-y);
else
ney = endY;
dest.ogGetPixFmt(pixFmt);
if ((dest.ogGetPixFmtID() != pixelFmtID) || (dest.ogIsBlending())) {
for (sy = nsy; (uInt32)sy <= ney; sy++) {
sx = x+startX;
lineCount = *blitMaskPtr;
++blitMaskPtr;
while (lineCount > 0) {
offset = *blitMaskPtr;
++blitMaskPtr;
sx += offset;
pixCount = *blitMaskPtr;
++blitMaskPtr;
if (pixCount > 0) {
if (sx <= (int32)dest.ogGetMaxX()) {
if ((sx < 0) && (sx+(int32)pixCount > 0)) {
pixCount += sx; // remember, sx is negative
(uInt8*)imagePtr -= sx*bytesPerPixel; // remember, sx is negative
sx = 0;
} // if sx<0 && sx+pixCount>0
if (sx+pixCount > (int32)dest.ogGetMaxX()) {
distToEdge = (dest.ogGetMaxX()-sx)+1;
xRight = (pixCount-distToEdge)*bytesPerPixel;
pixCount = distToEdge;
} else xRight = 0; // if sx+pixCount>MaxX
if (sx >= 0)
for (xx = 0; xx < pixCount; xx++) {
Unpack(GetPixel((uInt8*)imagePtr+(xx*bytesPerPixel)),
r, g, b, a);
dest.ogSetPixel(sx+xx, sy+y, r, g, b, a);
} // for
(uInt8*)imagePtr += xRight;
} // if sx <= maxX
sx += pixCount;
(uInt8*)imagePtr += pixCount*bytesPerPixel;
} // if pixCount != 0
--lineCount;
} // while
} // for
} else {
for (sy = nsy; (uInt32)sy <= ney; sy++) {
sx = x+startX;
lineCount = *blitMaskPtr;
++blitMaskPtr;
while (lineCount > 0) {
offset = *blitMaskPtr;
++blitMaskPtr;
sx += offset;
pixCount = *blitMaskPtr;
++blitMaskPtr;
if (pixCount > 0) {
if (sx <= (int32)dest.ogGetMaxX()) {
if ((sx < 0) && (sx+pixCount > 0)) {
pixCount += sx; // remember, sx is negative
(uInt8*)imagePtr -= sx*bytesPerPixel; // remember, sx is negative
sx = 0;
} // if sx<0 && sx+pixCount>0
if (sx+pixCount > (int32)dest.ogGetMaxX()+1) {
distToEdge = (dest.ogGetMaxX()-sx)+1;
xRight = (pixCount - distToEdge)*bytesPerPixel;
pixCount = distToEdge;
} else xRight = 0; // if sx+pixCount>MaxX
if (sx >= 0)
dest.ogCopyLineTo(sx, y+sy, imagePtr, pixCount*bytesPerPixel);
(uInt8*)imagePtr += xRight;
} // if sx <= MaxX
sx += pixCount;
(uInt8*)imagePtr += pixCount*bytesPerPixel;
} // if pixCount>0
--lineCount;
} // while
} // for
} // else
return;
} // ogBlit::Put
bool
ogBlit::SaveTo(const char * filename, int32 offset) {
/*
* saveTo
*
* saves a blit to disk. If the file doesn't exit then we will create
* a new one (doing this will ignore any specified offset). If the file
* exists, we will seek to the specified offset and place the bitmap there.
* If offset is -1, then we seek to the end of the file.
*
* This function will fail on files larger than 2GB.
*
*/
FILE * outfile = NULL;
char headerIdent[4];
uInt32 tmpSize;
if (image == NULL) return false;
if ((bitDepth == 8) && (pal == NULL)) return false;
if (!fileExists(filename)) { // file doesn't exist
if ((outfile = fopen(filename,"wb")) == NULL) return false;
} else {
// file exists. Now we check to see where we put it
if (offset==-1) {
if ((outfile = fopen(filename, "ab")) == NULL) return false;
} else {
// we have an existing file and an offset to place the data
if ((outfile = fopen(filename, "wb")) == NULL) return false;
if (offset != 0) fseek(outfile, offset, SEEK_SET);
} // else
} // else
tmpSize = GetSize();
headerIdent[0] = 'B';
headerIdent[1] = 'L';
headerIdent[2] = 'T';
headerIdent[3] = (uInt8)0x1A; // EOF marker
// we store exactly how bit this sucker is inside the header. This includes
// the header information before it, and the size itself
fwrite(headerIdent, sizeof(headerIdent), 1, outfile);
fwrite(&tmpSize, sizeof(tmpSize), 1, outfile);
fwrite(&width, sizeof(width), 1, outfile);
fwrite(&height, sizeof(height), 1, outfile);
fwrite(&bitDepth, sizeof(bitDepth), 1, outfile);
fwrite(&RFP, sizeof(RFP), 1, outfile);
fwrite(&GFP, sizeof(GFP), 1, outfile);
fwrite(&BFP, sizeof(BFP), 1, outfile);
fwrite(&AFP, sizeof(AFP), 1, outfile);
fwrite(&rShift, sizeof(rShift), 1, outfile);
fwrite(&gShift, sizeof(gShift), 1, outfile);
fwrite(&bShift, sizeof(bShift), 1, outfile);
fwrite(&aShift, sizeof(aShift), 1, outfile);
fwrite(&tColour, sizeof(tColour), 1, outfile);
fwrite(&pixelFmtID, sizeof(pixelFmtID), 1, outfile);
fwrite(&bytesPerPixel, sizeof(bytesPerPixel), 1, outfile);
fwrite(&dAlpha, sizeof(dAlpha), 1, outfile);
fwrite(&totalPixCount, sizeof(totalPixCount), 1, outfile);
fwrite(&startX, sizeof(startX), 1, outfile);
fwrite(&startY, sizeof(startY), 1, outfile);
fwrite(&endX, sizeof(endX), 1, outfile);
fwrite(&endY, sizeof(endY), 1, outfile);
fwrite(&blitMaskSize, sizeof(blitMaskSize), 1, outfile);
fwrite(&imageSize, sizeof(imageSize), 1, outfile);
fwrite(blitMask, blitMaskSize, 1, outfile);
fwrite(image, 1, imageSize, outfile);
if (bitDepth == 8) {
tmpSize = sizeof(ogRGBA8)*256;
fwrite(&tmpSize, sizeof(tmpSize), 1, outfile);
fwrite(pal, sizeof(ogRGBA8), 256, outfile);
} // if bitDepth == 8
fclose(outfile);
return true;
} // ogBlit::SaveTo
ogBlit::~ogBlit(void) {
delete [] blitMask;
blitMask = NULL;
blitMaskSize = 0;
return;
} // ogBlit::~ogBlit