All pastes #265734 Raw Edit

Unnamed

public c v1 · immutable
·published 2006-12-03 16:33 UTC
rendered paste body
#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))ImageAlpha *LoadTgaAlpha(const char *pFilename){	Err err = errNone;	UInt8 counter = 0;	UInt8 buf[8] = {0};	Int32 i=0,j=0,k=0;	png_byte* row=0;	png_byte* ptr=0;	TwGfxBitmapType *pAlphaBitmapEven=0;	TwGfxBitmapType *pAlphaBitmapOdd=0;	File *file = 0;	ImageAlpha *pImageAlpha = 0;	UInt8 *pAlphaPointerEven=0;	UInt8 *pAlphaPointerOdd=0;	TGA *in=0;	TGAData *data=0;	Int16	yLoopEnd,xLoopEnd;			// values to end looping when reading image data	Int16	xLoopStart,yLoopStart;		// values to start looping when reading image data	Int8	xLoopDelta,yLoopDelta;		// increment(or decrement) for each iteration of the for loop for reading data	Int16	destXCount,destYCount;		// x,y position of pixel being written to TapWave surface	data = (TGAData*)MemPtrNew(sizeof(TGAData));	MemSet(data, sizeof(TGAData), 0);	if (!data)	{		ErrDisplayFileLineMsg("LoadTgaAlpha", 0, "couldn't allocate memory for TGA header");			goto tga_alpha_failed;	}	in = TGAOpen((char*)pFilename, "r");	data->flags = TGA_IMAGE_ID | TGA_IMAGE_DATA | TGA_RGB;	TGAReadImage(in, data);	if (in->last != TGA_OK || in->hdr.depth != 8)	// only supprt 8bpp alpha channels	{		if (data->img_data)			MemPtrFree(data->img_data);		if (data->cmap)			MemPtrFree(data->cmap);		if (data->img_id)			MemPtrFree(data->img_id);		MemPtrFree(data);		TGAClose(in);		goto tga_alpha_failed;	}	// mask 1, for drawing from EVEN columns	pAlphaBitmapEven = (TwGfxBitmapType*)MemPtrNew(sizeof(TwGfxBitmapType));	MemSet(pAlphaBitmapEven, sizeof(TwGfxBitmapType), 0);	pAlphaBitmapEven->size = sizeof(TwGfxBitmapType);	pAlphaBitmapEven->width = in->hdr.width;	pAlphaBitmapEven->height = in->hdr.height;	pAlphaBitmapEven->pixelFormat = twGfxPixelFormat4bpp;	// only need 1/2 bytes per row, so need 0.5 * width bytes but must be rounded up to nearest whole byte	pAlphaBitmapEven->rowBytes = ( (in->hdr.width + 1) / 2 );	// should be aligned to a sizeof(UInt32) boundary	if (pAlphaBitmapEven->rowBytes % sizeof(UInt32) != 0)		pAlphaBitmapEven->rowBytes += (sizeof(UInt32) - (pAlphaBitmapEven->rowBytes % sizeof(UInt32)));	pAlphaBitmapEven->data = (void*)MemPtrNew( pAlphaBitmapEven->rowBytes * pAlphaBitmapEven->height );	MemSet(pAlphaBitmapEven->data, pAlphaBitmapEven->rowBytes * pAlphaBitmapEven->height, 0);	pAlphaPointerEven = (UInt8*)pAlphaBitmapEven->data;	// mask 2, for drawing from EVEN columns	pAlphaBitmapOdd = (TwGfxBitmapType*)MemPtrNew(sizeof(TwGfxBitmapType));	MemSet(pAlphaBitmapOdd, sizeof(TwGfxBitmapType), 0);	pAlphaBitmapOdd->size = sizeof(TwGfxBitmapType);	pAlphaBitmapOdd->width = in->hdr.width;	pAlphaBitmapOdd->height = in->hdr.height;	pAlphaBitmapOdd->pixelFormat = twGfxPixelFormat4bpp;	// needs one extra column, as everythign is offset by one pixel (4bpp)	pAlphaBitmapOdd->rowBytes = ( (in->hdr.width + 2) / 2 );	// should be aligned to a sizeof(UInt32) boundary	if (pAlphaBitmapOdd->rowBytes % sizeof(UInt32) != 0)		pAlphaBitmapOdd->rowBytes += (sizeof(UInt32) - (pAlphaBitmapOdd->rowBytes % sizeof(UInt32)));		pAlphaBitmapOdd->data = (void*)MemPtrNew( pAlphaBitmapOdd->rowBytes * pAlphaBitmapOdd->height );	MemSet(pAlphaBitmapOdd->data, pAlphaBitmapOdd->rowBytes * pAlphaBitmapOdd->height, 0);	pAlphaPointerOdd = (UInt8*)pAlphaBitmapOdd->data;	if (in->hdr.vert == TGA_TOP)	{		yLoopStart = 0;		yLoopEnd = in->hdr.height;		yLoopDelta=1;	}	else	{		yLoopStart = in->hdr.height-1;		yLoopEnd = -1;		yLoopDelta=-1;	}	if (in->hdr.horz == TGA_LEFT)	{		xLoopStart = 0;		xLoopEnd = in->hdr.width;		xLoopDelta=1;	}	else	{		xLoopStart = in->hdr.width-1;		xLoopEnd = -1;		xLoopDelta=-1;	}	for (i=yLoopStart, destYCount=0; i != yLoopEnd; i+=yLoopDelta, ++destYCount)							// go through each row	{   		k = 0;		pAlphaPointerEven = ((UInt8*)pAlphaBitmapEven->data) + (pAlphaBitmapEven->rowBytes * i);		pAlphaPointerOdd = ((UInt8*)pAlphaBitmapOdd->data) + (pAlphaBitmapOdd->rowBytes * i);			for (j=xLoopStart, destXCount=0; j != xLoopEnd; j+=xLoopDelta, ++destXCount)							// go through each coloumn		{				ptr = &data->img_data[((in->hdr.width * destYCount) + destXCount)];			// even passes:			if (k % 2 == 0)			{				*((UInt8*)pAlphaPointerEven) = (((UInt8)round(ptr[0] * 0.12156862745098039215686274509804)) & 0xf) << 4;				*((UInt8*)pAlphaPointerOdd++) |= (((UInt8)round(ptr[0] * 0.12156862745098039215686274509804)) & 0xf);			}			// odd passes:			else			{				*((UInt8*)pAlphaPointerEven++) |= (((UInt8)round(ptr[0] * 0.12156862745098039215686274509804)) & 0xf);				*((UInt8*)pAlphaPointerOdd) = (((UInt8)round(ptr[0] * 0.12156862745098039215686274509804)) & 0xf) << 4;			}			++k;		}	}	// create image	pImageAlpha = MemPtrNew(sizeof(ImageAlpha));	MemSet(pImageAlpha, sizeof(ImageAlpha), 0);	pImageAlpha->width = in->hdr.width;	pImageAlpha->height = in->hdr.height;		// set images alpha bitmap to created bitmap	pImageAlpha->m_pAlphaBitmap[0] = pAlphaBitmapEven;	pImageAlpha->m_pAlphaBitmap[1] = pAlphaBitmapOdd;		// clean up TGA specific stuff	if (data->img_data)		MemPtrFree(data->img_data);	if (data->cmap)		MemPtrFree(data->cmap);	if (data->img_id)		MemPtrFree(data->img_id);	MemPtrFree(data);	TGAClose(in);			// return image		return pImageAlpha;tga_alpha_failed:	FClose(file);	return NULL;}