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;}