/*------------------------------------------------------------------- * Original Author: Grenadiac * * Contributing Authors: * * File Description: * * *-----------------------------------------------------------------*/ #include "stdafx.h" #include "HaloBmp2.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif /*------------------------------------------------------------------- * Name: CHaloBmp() * Description: * *-----------------------------------------------------------------*/ CHaloBmp::CHaloBmp() { m_ObjTag = "bitm"; m_Version = 0; } /*------------------------------------------------------------------- * Name: ~CHaloBmp() * Description: * *-----------------------------------------------------------------*/ CHaloBmp::~CHaloBmp() { } /*------------------------------------------------------------------- * Name: writeTGA() * Description: * *-----------------------------------------------------------------*/ void CHaloBmp::writeTGA(UINT *texdata, int height, int width, CFile *pOutFile) { MTarga_Header hdr; hdr.id_length = 0; hdr.colormap_type = 0; hdr.image_type = 2; hdr.colormap_index = 0; hdr.colormap_length = 0; hdr.colormap_size = 0; hdr.x_org = 0; hdr.y_org = 0; hdr.width = width; hdr.height = height; hdr.pixel_size = 32; hdr.attributes = 0; // WRITE that shit, yo! pOutFile->Write(&hdr, sizeof(hdr)); int *datptr = (int *)texdata; //for (int y = 0; y < height; y++) // for (int x = 0; x < width; x++, datptr++) // *datptr = Swap ((int)*datptr); for (int y = height - 1; y >= 0; y--) pOutFile->Write(&(texdata[y * width]), 4 * width); } /*------------------------------------------------------------------- * Name: read_bitm() * Description: * *-----------------------------------------------------------------*/ void CHaloBmp::read_bitm(CFile *pMapFile, INDEX_ITEM *item, int magic, CString Name) { bitm_header_t hdr; bitm_first_t first; // bitm_second_t second; bitm_image_t *pImages = NULL; BOOL bWriteOutput = FALSE; /* Read bmp header from metadata */ pMapFile->Seek(item->offset,0); pMapFile->Read(&hdr, sizeof(hdr)); hdr.offset_to_first -= magic; hdr.image_offset -= magic; /* Read 1st section */ pMapFile->Seek(hdr.offset_to_first,0); pMapFile->Read(&first, sizeof(first)); /* New format - multiple images in the raw data */ pImages = new bitm_image_t[hdr.image_count]; pMapFile->Seek(hdr.image_offset,0); pMapFile->Read(pImages, hdr.image_count*sizeof(bitm_image_t)); for(int i=0; i<hdr.image_count; i++) { if(pImages[i].type == BITM_TYPE_2D) { if(!pImages[i].num_mipmaps) //no mipmaps { //DecodeBitmSurface (texdata, image->width, image->height, -1, image->format, image->flags, imagefile); } else { int sx = pImages[i].width; int sy = pImages[i].height; int offset = 0; for(int y = 0; y < 1; y++)//pImages[i].num_mipmaps; y++) { //DecodeBitmSurface(texdata + offset, sx, sy, -1, image->format, image->flags, imagefile); offset += GetImageSize (pImages[i].format, sx, sy); sx >>= 1; sy >>= 1; } } } } } //////////////////////////////////////////////////////////////////////// // // // DXT Format Converter // // Copyright 2003, Defenderz // // Open for Free Use and Export // // DXT Data Format Copyright Microsoft Inc. // // Notes: // // -Height/Width should be powers of 2 (By default for D3D Textures) // // // // -IData should point to the DXT data, and should point to a buffer // // of size Height*Width/2 // // // // -PData should point to a preallocated storage buffer of size // // Width*Height*4 (Width*Height DWORDs) // // // // -Function will never return a fail code :-) // //////////////////////////////////////////////////////////////////////// #define BIT16BMASK (0x01|0x02|0x04|0x08|0x10) #define BIT16GMASK (0x20|0x40|0x80|0x100|0x200|0x400) #define BIT16RMASK (0x800|0x1000|0x2000|0x4000|0x8000) #define BIT16BSIZE 32 #define BIT16GSIZE 64 #define BIT16RSIZE 32 #define BIT16RDIST 11 #define BIT16GDIST 5 #define BIT16BDIST 0 struct RGB { DWORD R,G,B,T; }; /*------------------------------------------------------------------- * Name: ConvertWORDToRGB() * Description: * *-----------------------------------------------------------------*/ static RGB ConvertWORDToRGB(WORD Color) { //Color = Swap ((short)Color); RGB rc; rc.R = ((Color&BIT16RMASK)>>BIT16RDIST)*0xff/BIT16RSIZE; rc.G = ((Color&BIT16GMASK)>>BIT16GDIST)*0xff/BIT16GSIZE; rc.B = ((Color&BIT16BMASK)>>BIT16BDIST)*0xff/BIT16BSIZE; rc.T = 255; return rc; } /*------------------------------------------------------------------- * Name: RGBToDWORD() * Description: * *-----------------------------------------------------------------*/ static DWORD RGBToDWORD(RGB Color) { return (Color.T<<24)|(Color.R<<16)|(Color.G<<8)|Color.B; } /*------------------------------------------------------------------- * Name: GradientColors() * Description: * *-----------------------------------------------------------------*/ rgba_color_t CHaloBmp::GradientColors (rgba_color_t Col1, rgba_color_t Col2) { rgba_color_t ret; ret.r = ((Col1.r*2 + Col2.r))/3; ret.g = ((Col1.g*2 + Col2.g))/3; ret.b = ((Col1.b*2 + Col2.b))/3; ret.a = 255; return ret; } /*------------------------------------------------------------------- * Name: GradientColorsHalf() * Description: * *-----------------------------------------------------------------*/ rgba_color_t CHaloBmp::GradientColorsHalf (rgba_color_t Col1, rgba_color_t Col2) { rgba_color_t ret; ret.r = (Col1.r/2 + Col2.r/2); ret.g = (Col1.g/2 + Col2.g/2); ret.b = (Col1.b/2 + Col2.b/2); ret.a = 255; return ret; } /*------------------------------------------------------------------- * Name: DecodeDXT1() * Description: * *-----------------------------------------------------------------*/ void CHaloBmp::DecodeDXT1(int Height, int Width, byte* IData, unsigned int* PData) { rgba_color_t Color[4]; int i; int dptr; rgba_color_t CColor; unsigned int CData; unsigned int ChunksPerHLine = Width / 4; bool trans; static rgba_color_t zeroColor = {0, 0, 0, 0}; for (i = 0, dptr = 0; i < (Width * Height); i += 16, dptr += 8) { unsigned short c1, c2; c1 = *(unsigned short *)&IData[dptr]; c2 = *(unsigned short *)&IData[dptr+2]; if(c1 > c2) trans = false; else trans = true; Color[0] = short_to_rgba(c1); Color[1] = short_to_rgba(c2); if (!trans) { Color[2] = GradientColors(Color[0], Color[1]); Color[3] = GradientColors(Color[1], Color[0]); } else { Color[2] = GradientColorsHalf (Color[0], Color[1]); Color[3] = zeroColor; } CData = *(unsigned int *)&(IData[dptr+4]); unsigned int ChunkNum = i / 16; unsigned int XPos = ChunkNum % ChunksPerHLine; unsigned int YPos = (ChunkNum - XPos) / ChunksPerHLine; int sizew, sizeh; sizeh = (Height < 4) ? Height : 4; sizew = (Width < 4) ? Width : 4; for (int x = 0; x < sizeh; x++) { for (int y = 0; y < sizew; y++) { CColor = Color[CData & 0x03]; CData >>= 2; PData[(YPos*4+x)*Width + XPos*4+y] = rgba_to_int(CColor); } } } } /*------------------------------------------------------------------- * Name: ReadHeader() * Description: * *-----------------------------------------------------------------*/ void CHaloBmp::ReadHeader(CFile *pMapFile, INDEX_ITEM *item, int magic, CString Name) { // bitm_header_t hdr; // bitm_first_t first; // //bitm_second_t second; // // /* Read bmp header from metadata */ // pMapFile->Seek(item->offset,0); // pMapFile->Read(&hdr, sizeof(hdr)); // // printf("hdr_offset_to_first = %08X offset to second = %08X\n", hdr.offset_to_first, hdr.offset_to_second); // hdr.offset_to_first -= magic; // //hdr.offset_to_second -= magic; // // /* Read 1st section */ // pMapFile->Seek(hdr.offset_to_first,0); // pMapFile->Read(&first, sizeof(first)); // // /* Read 2nd section */ // //pMapFile->Seek(hdr.offset_to_second,0); // //pMapFile->Read(&second, sizeof(second)); // // /* Dump Info */ // //DumpInfo(second.offset, second.size, Name); } /*================================ * GetImageSize ================================*/ int CHaloBmp::GetImageSize (int format, int width, int height) { int size = 0; if (!width) width = 1; if (!height) height = 1; if (format == BITM_FORMAT_DXT1 || format == BITM_FORMAT_DXT2AND3 || format == BITM_FORMAT_DXT4AND5) { if (width < 4) width = 4; if (height < 4) height = 4; } switch (format) { case BITM_FORMAT_A8: case BITM_FORMAT_Y8: case BITM_FORMAT_AY8: case BITM_FORMAT_P8: size = width * height; break; case BITM_FORMAT_A8Y8: case BITM_FORMAT_R5G6B5: case BITM_FORMAT_A1R5G5B5: case BITM_FORMAT_A4R4G4B4: size = width * height * 2; break; case BITM_FORMAT_X8R8G8B8: case BITM_FORMAT_A8R8G8B8: size = width * height * 4; break; case BITM_FORMAT_DXT1: size = (width >> 2) * (height >> 2) * 8; break; case BITM_FORMAT_DXT2AND3: case BITM_FORMAT_DXT4AND5: size = (width >> 2) * (height >> 2) * 16; break; default: fprintf (stderr, "Unknown format in GetImageSize!\n"); break; } return size; } /*================================ * DecodeBitmSurface ================================*/ void CHaloBmp::DecodeBitmSurface (byte *data, int width, int height, int depth, int format, int flags, UINT *pOutBuf) { if (!width) width = 1; if (!height) height = 1; if((flags & BITM_FLAG_LINEAR)||(m_Version == 7)||(m_Version == 609)) { switch (format) { case BITM_FORMAT_A8: DecodeLinearA8 (width, height, data, pOutBuf); break; case BITM_FORMAT_Y8: DecodeLinearY8 (width, height, data, pOutBuf); break; case BITM_FORMAT_AY8: DecodeLinearAY8 (width, height, data, pOutBuf); break; case BITM_FORMAT_A8Y8: DecodeLinearA8Y8 (width, height, data, pOutBuf); break; case BITM_FORMAT_R5G6B5: DecodeLinearR5G6B5 (width, height, data, pOutBuf); break; case BITM_FORMAT_A1R5G5B5: DecodeLinearA1R5G5B5 (width, height, data, pOutBuf); break; case BITM_FORMAT_A4R4G4B4: DecodeLinearA4R4G4B4 (width, height, data, pOutBuf); break; case BITM_FORMAT_X8R8G8B8: DecodeLinearX8R8G8B8 (width, height, data, pOutBuf); break; case BITM_FORMAT_A8R8G8B8: DecodeLinearA8R8G8B8 (width, height, data, pOutBuf); break; case BITM_FORMAT_DXT1: DecodeDXT1 (height, width, data, pOutBuf); break; case BITM_FORMAT_DXT2AND3: DecodeDXT2And3 (height, width, data, pOutBuf); break; case BITM_FORMAT_DXT4AND5: DecodeDXT4And5 (height, width, data, pOutBuf); break; case BITM_FORMAT_P8: DecodeLinearP8 (width, height, data, pOutBuf); break; default: //fprintf (stderr, "Unknown format %x (%s) (linear)!\n", format, outfile->getpath()); return; break; } } else // Swizzled { switch (format) { case BITM_FORMAT_A8: DecodeSwizzledA8 (width, height, depth, data, pOutBuf); break; case BITM_FORMAT_Y8: DecodeSwizzledY8 (width, height, depth, data, pOutBuf); break; case BITM_FORMAT_AY8: DecodeSwizzledAY8 (width, height, depth, data, pOutBuf); break; case BITM_FORMAT_A8Y8: DecodeSwizzledA8Y8 (width, height, depth, data, pOutBuf); break; case BITM_FORMAT_R5G6B5: DecodeSwizzledR5G6B5 (width, height, depth, data, pOutBuf); break; case BITM_FORMAT_A1R5G5B5: DecodeSwizzledA1R5G5B5 (width, height, depth, data, pOutBuf); break; case BITM_FORMAT_A4R4G4B4: DecodeSwizzledA4R4G4B4 (width, height, depth, data, pOutBuf); break; case BITM_FORMAT_X8R8G8B8: DecodeSwizzledX8R8G8B8 (width, height, depth, data, pOutBuf); break; case BITM_FORMAT_A8R8G8B8: DecodeSwizzledA8R8G8B8 (width, height, depth, data, pOutBuf); break; case BITM_FORMAT_DXT1: DecodeDXT1 (height, width, data, pOutBuf); break; case BITM_FORMAT_DXT2AND3: DecodeDXT2And3 (height, width, data, pOutBuf); break; case BITM_FORMAT_DXT4AND5: DecodeDXT4And5 (height, width, data, pOutBuf); break; case BITM_FORMAT_P8: DecodeSwizzledP8 (width, height, depth, data, pOutBuf); break; default: //fprintf (stderr, "Unknown format %x (%s) (swizzled)!\n", format, outfile->getpath()); return; break; } } } /*================================ * DecodeLinearA8 ================================*/ void CHaloBmp::DecodeLinearA8 (int width, int height, byte *texdata, unsigned int *outdata) { for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) outdata[(y * width) + x] = texdata[(y * width) + x] << 24; } /*================================ * DecodeSwizzledA8 ================================*/ void CHaloBmp::DecodeSwizzledA8 (int width, int height, int depth, byte *texdata, unsigned int *outdata) { Swizzler swz (width, height); for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) outdata[(y * width) + x] = texdata[swz.Swizzle (x, y, depth)] << 24; } /*================================ * DecodeLinearY8 ================================*/ void CHaloBmp::DecodeLinearY8 (int width, int height, byte *texdata, unsigned int *outdata) { rgba_color_t color; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { color.r = color.g = color.b = texdata[(y * width) + x]; color.a = 0; outdata[(y * width) + x] = rgba_to_int (color); } } } /*================================ * DecodeSwizzledY8 ================================*/ void CHaloBmp::DecodeSwizzledY8 (int width, int height, int depth, byte *texdata, unsigned int *outdata) { rgba_color_t color; Swizzler swz (width, height); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { color.r = color.g = color.b = texdata[swz.Swizzle (x, y, depth)]; color.a = 0; outdata[(y * width) + x] = rgba_to_int (color); } } } /*================================ * DecodeLinearAY8 ================================*/ void CHaloBmp::DecodeLinearAY8 (int width, int height, byte *texdata, unsigned int *outdata) { rgba_color_t color; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { color.r = color.g = color.b = color.a = texdata[(y * width) + x]; outdata[(y * width) + x] = rgba_to_int (color); } } } /*================================ * DecodeSwizzledAY8 ================================*/ void CHaloBmp::DecodeSwizzledAY8 (int width, int height, int depth, byte *texdata, unsigned int *outdata) { rgba_color_t color; Swizzler swz (width, height); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { color.r = color.g = color.b = color.a = texdata[swz.Swizzle (x, y, depth)]; outdata[(y * width) + x] = rgba_to_int (color); } } } /*================================ * DecodeLinearA8Y8 ================================*/ void CHaloBmp::DecodeLinearA8Y8 (int width, int height, byte *texdata, unsigned int *outdata) { rgba_color_t color; unsigned short cdata; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { cdata = ((short *)texdata)[(y * width) + x]; color.r = color.g = color.b = cdata >> 8; color.a = cdata & 0xFF; outdata[(y * width) + x] = rgba_to_int (color); } } } /*================================ * DecodeSwizzledA8Y8 ================================*/ void CHaloBmp::DecodeSwizzledA8Y8 (int width, int height, int depth, byte *texdata, unsigned int *outdata) { rgba_color_t color; Swizzler swz (width, height); unsigned short cdata; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { cdata = ((short *)texdata)[swz.Swizzle (x, y, depth)]; color.r = color.g = color.b = cdata >> 8; color.a = cdata & 0xFF; outdata[(y * width) + x] = rgba_to_int (color); } } } /*================================ * DecodeLinearR5G6B5 ================================*/ void CHaloBmp::DecodeLinearR5G6B5 (int width, int height, byte *texdata, unsigned int *outdata) { for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) outdata[(y * width) + x] = rgba_to_int (short_to_rgba (((short *)texdata)[(y * width) + x])); } /*================================ * DecodeSwizzledR5G6B5 ================================*/ void CHaloBmp::DecodeSwizzledR5G6B5 (int width, int height, int depth, byte *texdata, unsigned int *outdata) { Swizzler swz (width, height); for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) outdata[(y * width) + x] = rgba_to_int (short_to_rgba (((short *)texdata)[swz.Swizzle (x, y, depth)])); } /*================================ * DecodeLinearA1R5G5B5 ================================*/ void CHaloBmp::DecodeLinearA1R5G5B5 (int width, int height, byte *texdata, unsigned int *outdata) { rgba_color_t color; unsigned short cdata; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { cdata = ((short *)texdata)[(y * width) + x]; color.a = (cdata >> 15) * 0xFF; color.r = (((cdata >> 10) & 0x1F) * 0xFF) / 31; color.g = (((cdata >> 5) & 0x1F) * 0xFF) / 31; color.b = (((cdata >> 0) & 0x1F) * 0xFF) / 31; outdata[(y * width) + x] = rgba_to_int (color); } } } /*================================ * DecodeSwizzledA1R5G5B5 ================================*/ void CHaloBmp::DecodeSwizzledA1R5G5B5 (int width, int height, int depth, byte *texdata, unsigned int *outdata) { Swizzler swz (width, height); rgba_color_t color; unsigned short cdata; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { cdata = ((short *)texdata)[swz.Swizzle (x, y, depth)]; color.a = (cdata >> 15) * 0xFF; color.r = (((cdata >> 10) & 0x1F) * 0xFF) / 31; color.g = (((cdata >> 5) & 0x1F) * 0xFF) / 31; color.b = (((cdata >> 0) & 0x1F) * 0xFF) / 31; outdata[(y * width) + x] = rgba_to_int (color); } } } /*================================ * DecodeLinearA4R4G4B4 ================================*/ void CHaloBmp::DecodeLinearA4R4G4B4 (int width, int height, byte *texdata, unsigned int *outdata) { rgba_color_t color; unsigned short cdata; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { cdata = ((short *)texdata)[(y * width) + x]; color.a = ((cdata >> 12) * 0xFF) / 15; color.r = (((cdata >> 8) & 0x0F) * 0xFF) / 15; color.g = (((cdata >> 4) & 0x0F) * 0xFF) / 15; color.b = (((cdata >> 0) & 0x0F) * 0xFF) / 15; outdata[(y * width) + x] = rgba_to_int (color); } } } /*================================ * DecodeSwizzledA4R4G4B4 ================================*/ void CHaloBmp::DecodeSwizzledA4R4G4B4 (int width, int height, int depth, byte *texdata, unsigned int *outdata) { Swizzler swz (width, height); rgba_color_t color; unsigned short cdata; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { cdata = ((short *)texdata)[swz.Swizzle (x, y, depth)]; color.a = ((cdata >> 12) * 0xFF) / 15; color.r = (((cdata >> 8) & 0x0F) * 0xFF) / 15; color.g = (((cdata >> 4) & 0x0F) * 0xFF) / 15; color.b = (((cdata >> 0) & 0x0F) * 0xFF) / 15; outdata[(y * width) + x] = rgba_to_int (color); } } } /*================================ * DecodeLinearX8R8G8B8 ================================*/ void CHaloBmp::DecodeLinearX8R8G8B8 (int width, int height, byte *texdata, unsigned int *outdata) { rgba_color_t color; unsigned int cdata; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { cdata = ((int *)texdata)[(y * width) + x]; color.a = 0; color.r = (cdata >> 16) & 0xFF; color.g = (cdata >> 8) & 0xFF; color.b = (cdata >> 0) & 0xFF; outdata[(y * width) + x] = rgba_to_int (color); } } } /*================================ * DecodeSwizzledX8R8G8B8 ================================*/ void CHaloBmp::DecodeSwizzledX8R8G8B8 (int width, int height, int depth, byte *texdata, unsigned int *outdata) { Swizzler swz (width, height); //Swizzler swz (height, width); rgba_color_t color; unsigned int cdata; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { cdata = ((int *)texdata)[(y * width) + x]; //JPC 12/18/03 - removed swizzle call // cdata = ((int *)texdata)[swz.Swizzle (x, y, depth)]; color.a = 0; color.r = (cdata >> 16) & 0xFF; color.g = (cdata >> 8) & 0xFF; color.b = (cdata >> 0) & 0xFF; outdata[(y * width) + x] = rgba_to_int (color); } } } /*================================ * DecodeLinearA8R8G8B8 ================================*/ void CHaloBmp::DecodeLinearA8R8G8B8 (int width, int height, byte *texdata, unsigned int *outdata) { rgba_color_t color; unsigned int cdata; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { cdata = ((int *)texdata)[(y * width) + x]; color.a = (cdata >> 24); color.r = (cdata >> 16) & 0xFF; color.g = (cdata >> 8) & 0xFF; color.b = (cdata >> 0) & 0xFF; outdata[(y * width) + x] = rgba_to_int (color); } } } /*================================ * DecodeSwizzledA8R8G8B8 ================================*/ void CHaloBmp::DecodeSwizzledA8R8G8B8 (int width, int height, int depth, byte *texdata, unsigned int *outdata) { Swizzler swz (width, height); rgba_color_t color; unsigned int cdata; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { cdata = ((int *)texdata)[swz.Swizzle (x, y, depth)]; color.a = (cdata >> 24); color.r = (cdata >> 16) & 0xFF; color.g = (cdata >> 8) & 0xFF; color.b = (cdata >> 0) & 0xFF; outdata[(y * width) + x] = rgba_to_int (color); } } } /*================================ * DecodeLinearP8 ================================*/ void CHaloBmp::DecodeLinearP8 (int width, int height, byte *texdata, unsigned int *outdata) { rgba_color_t color; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { color.a = 0; color.r = color.g = color.b = texdata[(y * width) + x]; outdata[(y * width) + x] = rgba_to_int (color); } } } /*================================ * DecodeSwizzledP8 ================================*/ void CHaloBmp::DecodeSwizzledP8 (int width, int height, int depth, byte *texdata, unsigned int *outdata) { Swizzler swz (width, height); rgba_color_t color; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { color.a = 0; color.r = color.g = color.b = texdata[swz.Swizzle (x, y, depth)]; outdata[(y * width) + x] = rgba_to_int (color); } } } /*================================ * DecodeDXT2And3 ================================*/ void CHaloBmp::DecodeDXT2And3 (int Height, int Width, byte* IData, unsigned int* PData) { rgba_color_t Color[4]; int i; rgba_color_t CColor; unsigned int CData; unsigned int ChunksPerHLine = Width / 4; unsigned short Alpha; if (!ChunksPerHLine) ChunksPerHLine = 1; for (i = 0; i < (Width * Height); i += 16) { Color[0] = short_to_rgba(*(unsigned short *)&IData[i+8]); Color[1] = short_to_rgba(*(unsigned short *)&IData[i+10]); Color[2] = GradientColors(Color[0], Color[1]); Color[3] = GradientColors(Color[1], Color[0]); CData = *(unsigned int *)&IData[i+12]; unsigned int ChunkNum = i / 16; unsigned int XPos = ChunkNum % ChunksPerHLine; unsigned int YPos = (ChunkNum - XPos) / ChunksPerHLine; int sizew, sizeh; sizeh = (Height < 4) ? Height : 4; sizew = (Width < 4) ? Width : 4; for(int x = 0; x < sizeh; x++) { Alpha = *(short *)&IData[i + (2 * x)]; for(int y = 0; y < sizew; y++) { CColor = Color[CData & 0x03]; CData >>= 2; CColor.a = (Alpha & 0x0F) * 16; Alpha >>= 4; PData[(YPos*4+x)*Width + XPos*4+y] = rgba_to_int(CColor); } } } } /*================================ * DecodeDXT4And5 ================================*/ void CHaloBmp::DecodeDXT4And5 (int Height, int Width, byte* IData, unsigned int* PData) { rgba_color_t Color[4]; int i; rgba_color_t CColor; unsigned int CData; unsigned int ChunksPerHLine = Width / 4; unsigned char Alpha[8]; __int64 AlphaDat; if (!ChunksPerHLine) ChunksPerHLine = 1; for (i = 0; i < (Width * Height); i += 16) { Color[0] = short_to_rgba(*(unsigned short *)&IData[i+8]); Color[1] = short_to_rgba(*(unsigned short *)&IData[i+10]); Color[2] = GradientColors(Color[0], Color[1]); Color[3] = GradientColors(Color[1], Color[0]); CData = (int)*(unsigned int *)&IData[i+12]; Alpha[0] = IData[i]; Alpha[1] = IData[i+1]; // Do the alphas if (Alpha[0] > Alpha[1]) { // 8-alpha block: derive the other six alphas. // Bit code 000 = alpha_0, 001 = alpha_1, others are interpolated. Alpha[2] = (6 * Alpha[0] + 1 * Alpha[1] + 3) / 7; // bit code 010 Alpha[3] = (5 * Alpha[0] + 2 * Alpha[1] + 3) / 7; // bit code 011 Alpha[4] = (4 * Alpha[0] + 3 * Alpha[1] + 3) / 7; // bit code 100 Alpha[5] = (3 * Alpha[0] + 4 * Alpha[1] + 3) / 7; // bit code 101 Alpha[6] = (2 * Alpha[0] + 5 * Alpha[1] + 3) / 7; // bit code 110 Alpha[7] = (1 * Alpha[0] + 6 * Alpha[1] + 3) / 7; // bit code 111 } else { // 6-alpha block. // Bit code 000 = alpha_0, 001 = alpha_1, others are interpolated. Alpha[2] = (4 * Alpha[0] + 1 * Alpha[1] + 2) / 5; // Bit code 010 Alpha[3] = (3 * Alpha[0] + 2 * Alpha[1] + 2) / 5; // Bit code 011 Alpha[4] = (2 * Alpha[0] + 3 * Alpha[1] + 2) / 5; // Bit code 100 Alpha[5] = (1 * Alpha[0] + 4 * Alpha[1] + 2) / 5; // Bit code 101 Alpha[6] = 0; // Bit code 110 Alpha[7] = 255; // Bit code 111 } // Byte Alpha // 0 Alpha_0 // 1 Alpha_1 // 2 [0][2] (2 LSBs), [0][1], [0][0] // 3 [1][1] (1 LSB), [1][0], [0][3], [0][2] (1 MSB) // 4 [1][3], [1][2], [1][1] (2 MSBs) // 5 [2][2] (2 LSBs), [2][1], [2][0] // 6 [3][1] (1 LSB), [3][0], [2][3], [2][2] (1 MSB) // 7 [3][3], [3][2], [3][1] (2 MSBs) // [0 // Read an int and a short unsigned int tmpdword; unsigned short tmpword; tmpword = (short)*(unsigned short *)&IData[i + 2]; tmpdword = (int)*(unsigned int *)&IData[i + 4]; AlphaDat = tmpword | ((__int64)tmpdword << 16); unsigned int ChunkNum = i / 16; unsigned int XPos = ChunkNum % ChunksPerHLine; unsigned int YPos = (ChunkNum - XPos) / ChunksPerHLine; int sizew, sizeh; sizeh = (Height < 4) ? Height : 4; sizew = (Width < 4) ? Width : 4; for (int x = 0; x < sizeh; x++) { for (int y = 0; y < sizew; y++) { CColor = Color[CData & 0x03]; CData >>= 2; CColor.a = Alpha[AlphaDat & 0x07]; AlphaDat >>= 3; PData[(YPos*4+x)*Width + XPos*4+y] = rgba_to_int(CColor); } } } } BOOL CHaloBmp::DecompressDXT(bitm_image_t *pHeader, int inbuf_size, BYTE *pInBuf, UINT *pOutBuf) { // for(int i=0; i<hdr.image_count; i++) // { if(pHeader[0].type == BITM_TYPE_2D) { if(!pHeader[0].num_mipmaps) //no mipmaps { DecodeBitmSurface(pInBuf, pHeader[0].width, pHeader[0].height, -1, pHeader[0].format, pHeader[0].flags, pOutBuf); } else { int sx = pHeader[0].width; int sy = pHeader[0].height; int offset = 0; for(int y = 0; y < 1; y++)//pImages[i].num_mipmaps; y++) { DecodeBitmSurface(pInBuf, pHeader[0].width, pHeader[0].height, -1, pHeader[0].format, pHeader[0].flags, pOutBuf); offset += GetImageSize (pHeader[0].format, sx, sy); sx >>= 1; sy >>= 1; } } } // } return(FALSE); }