Code/Resource
Windows Develop
Linux-Unix program
Internet-Socket-Network
Web Server
Browser Client
Ftp Server
Ftp Client
Browser Plugins
Proxy Server
Email Server
Email Client
WEB Mail
Firewall-Security
Telnet Server
Telnet Client
ICQ-IM-Chat
Search Engine
Sniffer Package capture
Remote Control
xml-soap-webservice
P2P
WEB(ASP,PHP,...)
TCP/IP Stack
SNMP
Grid Computing
SilverLight
DNS
Cluster Service
Network Security
Communication-Mobile
Game Program
Editor
Multimedia program
Graph program
Compiler program
Compress-Decompress algrithms
Crypt_Decrypt algrithms
Mathimatics-Numerical algorithms
MultiLanguage
Disk/Storage
Java Develop
assembly language
Applications
Other systems
Database system
Embeded-SCM Develop
FlashMX/Flex
source in ebook
Delphi VCL
OS Develop
MiddleWare
MPI
MacOS develop
LabView
ELanguage
Software/Tools
E-Books
Artical/Document
il_blp.c
Package: devil-1.7.99.tar.gz [view]
Upload User: wmy0603
Upload Date: 2022-05-02
Package Size: 1808k
Code Size: 21k
Category:
Compress-Decompress algrithms
Development Platform:
Visual C++
- //-----------------------------------------------------------------------------
- //
- // ImageLib Sources
- // Copyright (C) 2000-2009 by Denton Woods
- // Last modified: 02/14/2009
- //
- // Filename: src-IL/src/il_blp.c
- //
- // Description: Reads from a Blizzard Texture (.blp).
- // Specifications were found at http://www.wowwiki.com/BLP_files
- // for BLP2 and from
- // http://web.archive.org/web/20080117120549/magos.thejefffiles.com/War3ModelEditor/MagosBlpFormat.txt
- // for BLP1.
- //
- //-----------------------------------------------------------------------------
- //@TODO: Add support for the BLP1 format as well.
- #include "il_internal.h"
- #ifndef IL_NO_BLP
- #include "il_dds.h"
- typedef struct BLP1HEAD
- {
- ILubyte Sig[4];
- ILuint Compression; // Texture type: 0 = JPG, 1 = Paletted
- ILuint Flags; // #8 - Uses alpha channel (?)
- ILuint Width; // Image width in pixels
- ILuint Height; // Image height in pixels
- ILuint PictureType; // 3 - Uncompressed index list + alpha list
- // 4 - Uncompressed index list + alpha list
- // 5 - Uncompressed index list
- ILuint PictureSubType; // 1 - ???
- ILuint MipOffsets[16]; // The file offsets of each mipmap, 0 for unused
- ILuint MipLengths[16]; // The length of each mipmap data block
- } BLP1HEAD;
- typedef struct BLP2HEAD
- {
- ILubyte Sig[4]; // "BLP2" signature
- ILuint Type; // Texture type: 0 = JPG, 1 = DXTC
- ILubyte Compression; // Compression mode: 1 = raw, 2 = DXTC
- ILubyte AlphaBits; // 0, 1, or 8
- ILubyte AlphaType; // 0, 1, 7 or 8
- ILubyte HasMips; // 0 = no mips levels, 1 = has mips (number of levels determined by image size)
- ILuint Width; // Image width in pixels
- ILuint Height; // Image height in pixels
- ILuint MipOffsets[16]; // The file offsets of each mipmap, 0 for unused
- ILuint MipLengths[16]; // The length of each mipmap data block
- } BLP2HEAD;
- // Data formats
- #define BLP_TYPE_JPG 0
- #define BLP_TYPE_DXTC_RAW 1
- #define BLP_RAW 1
- #define BLP_DXTC 2
- #define BLP_RAW_PLUS_ALPHA1 3
- #define BLP_RAW_PLUS_ALPHA2 4
- #define BLP_RAW_NO_ALPHA 5
- ILboolean iIsValidBlp2(void);
- ILboolean iCheckBlp2(BLP2HEAD *Header);
- ILboolean iLoadBlpInternal(void);
- ILboolean iLoadBlp1(void);
- ILboolean iCheckBlp1(BLP1HEAD *Header);
- ILboolean iGetBlp1Head(BLP1HEAD *Header);
- //! Checks if the file specified in FileName is a valid BLP file.
- ILboolean ilIsValid_BLP(ILconst_string FileName)
- {
- ILHANDLE BlpFile;
- ILboolean bBlp = IL_FALSE;
- if (!iCheckExtension(FileName, IL_TEXT("blp"))) {
- ilSetError(IL_INVALID_EXTENSION);
- return bBlp;
- }
- BlpFile = iopenr(FileName);
- if (BlpFile == NULL) {
- ilSetError(IL_COULD_NOT_OPEN_FILE);
- return bBlp;
- }
- bBlp = ilIsValidF_BLP(BlpFile);
- icloser(BlpFile);
- return bBlp;
- }
- //! Checks if the ILHANDLE contains a valid BLP file at the current position.
- ILboolean ilIsValidF_BLP(ILHANDLE File)
- {
- ILuint FirstPos;
- ILboolean bRet;
- iSetInputFile(File);
- FirstPos = itell();
- bRet = iIsValidBlp2();
- iseek(FirstPos, IL_SEEK_SET);
- return bRet;
- }
- //! Checks if Lump is a valid BLP lump.
- ILboolean ilIsValidL_BLP(const void *Lump, ILuint Size)
- {
- iSetInputLump(Lump, Size);
- return iIsValidBlp2();
- }
- // Internal function used to get the BLP header from the current file.
- ILboolean iGetBlp2Head(BLP2HEAD *Header)
- {
- ILuint i;
- iread(Header->Sig, 1, 4);
- Header->Type = GetLittleUInt();
- Header->Compression = igetc();
- Header->AlphaBits = igetc();
- Header->AlphaType = igetc();
- Header->HasMips = igetc();
- Header->Width = GetLittleUInt();
- Header->Height = GetLittleUInt();
- for (i = 0; i < 16; i++)
- Header->MipOffsets[i] = GetLittleUInt();
- for (i = 0; i < 16; i++)
- Header->MipLengths[i] = GetLittleUInt();
- return IL_TRUE;
- }
- // Internal function to get the header and check it.
- ILboolean iIsValidBlp2(void)
- {
- BLP2HEAD Header;
- if (!iGetBlp2Head(&Header))
- return IL_FALSE;
- iseek(-148, IL_SEEK_CUR);
- return iCheckBlp2(&Header);
- }
- // Internal function used to check if the HEADER is a valid BLP header.
- ILboolean iCheckBlp2(BLP2HEAD *Header)
- {
- // The file signature is 'BLP2'.
- if (strncmp(Header->Sig, "BLP2", 4))
- return IL_FALSE;
- // Valid types are JPEG and DXTC. JPEG is not common, though.
- // WoW only uses DXTC.
- if (Header->Type != BLP_TYPE_JPG && Header->Type != BLP_TYPE_DXTC_RAW)
- return IL_FALSE;
- // For BLP_TYPE_DXTC_RAW, we can have RAW and DXTC compression.
- if (Header->Compression != BLP_RAW && Header->Compression != BLP_DXTC)
- return IL_FALSE;
- // Alpha bits can only be 0, 1 and 8.
- if (Header->AlphaBits != 0 && Header->AlphaBits != 1 && Header->AlphaBits != 8)
- return IL_FALSE;
- // Alpha type can only be 0, 1, 7 and 8.
- if (Header->AlphaType != 0 && Header->AlphaType != 1 && Header->AlphaType != 7 && Header->AlphaType != 8)
- return IL_FALSE;
- // Width or height of 0 makes no sense.
- if (Header->Width == 0 || Header->Height == 0)
- return IL_FALSE;
- return IL_TRUE;
- }
- //! Reads a BLP file
- ILboolean ilLoad_BLP(ILconst_string FileName)
- {
- ILHANDLE BlpFile;
- ILboolean bBlp = IL_FALSE;
- BlpFile = iopenr(FileName);
- if (BlpFile == NULL) {
- ilSetError(IL_COULD_NOT_OPEN_FILE);
- return bBlp;
- }
- bBlp = ilLoadF_BLP(BlpFile);
- icloser(BlpFile);
- return bBlp;
- }
- //! Reads an already-opened BLP file
- ILboolean ilLoadF_BLP(ILHANDLE File)
- {
- ILuint FirstPos;
- ILboolean bRet;
- iSetInputFile(File);
- FirstPos = itell();
- bRet = iLoadBlpInternal();
- iseek(FirstPos, IL_SEEK_SET);
- return bRet;
- }
- //! Reads from a memory "lump" that contains a BLP
- ILboolean ilLoadL_BLP(const void *Lump, ILuint Size)
- {
- iSetInputLump(Lump, Size);
- return iLoadBlpInternal();
- }
- // Internal function used to load the BLP.
- ILboolean iLoadBlpInternal(void)
- {
- BLP2HEAD Header;
- ILubyte *CompData;
- ILimage *Image;
- ILuint Mip, j, x, CompSize, AlphaSize, AlphaOff;
- ILint y;
- ILboolean BaseCreated = IL_FALSE;
- ILubyte *DataAndAlpha = NULL, *Palette = NULL, AlphaMask; //, *JpegHeader, *JpegData;
- if (iCurImage == NULL) {
- ilSetError(IL_ILLEGAL_OPERATION);
- return IL_FALSE;
- }
- if (!iGetBlp2Head(&Header)) {
- ilSetError(IL_INVALID_FILE_HEADER);
- return IL_FALSE;
- }
- if (!iCheckBlp2(&Header)) {
- goto check_blp1;
- }
- //@TODO: Remove this!
- if (Header.Type != BLP_TYPE_DXTC_RAW)
- return IL_FALSE;
- switch (Header.Compression)
- {
- case BLP_RAW:
- for (Mip = 0; Mip < 16; Mip++) { // Possible maximum of 16 mipmaps
- if (BaseCreated) {
- if (Header.HasMips == 0) // Does not have mipmaps, so we are done.
- break;
- if (Image->Width == 1 && Image->Height == 1) // Already at the smallest mipmap (1x1), so we are done.
- break;
- if (Header.MipOffsets[Mip] == 0 || Header.MipLengths == 0) // No more mipmaps in the file.
- break;
- }
- switch (Header.AlphaBits)
- {
- case 0:
- if (!BaseCreated) { // Have not created the base image yet, so use ilTexImage.
- if (!ilTexImage(Header.Width, Header.Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL))
- return IL_FALSE;
- Image = iCurImage;
- BaseCreated = IL_TRUE;
- Image->Pal.Palette = (ILubyte*)ialloc(256 * 4); // 256 entries of ARGB8888 values (1024).
- if (Image->Pal.Palette == NULL)
- return IL_FALSE;
- Image->Pal.PalSize = 1024;
- Image->Pal.PalType = IL_PAL_BGRA32; //@TODO: Find out if this is really BGRA data.
- if (iread(Image->Pal.Palette, 1, 1024) != 1024) // Read in the palette.
- return IL_FALSE;
- }
- else {
- Image->Mipmaps = ilNewImageFull(Image->Width >> 1, Image->Height >> 1, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL);
- if (Image->Mipmaps == NULL)
- return IL_FALSE;
- // Copy the palette from the first image before we change our Image pointer.
- iCopyPalette(&Image->Mipmaps->Pal, &Image->Pal);
- // Move to the next mipmap in the linked list.
- Image = Image->Mipmaps;
- }
- // The origin should be in the upper left.
- Image->Origin = IL_ORIGIN_UPPER_LEFT;
- // These two should be the same (tells us how much data is in the file for this mipmap level).
- if (Header.MipLengths[Mip] != Image->SizeOfData) {
- ilSetError(IL_INVALID_FILE_HEADER);
- return IL_FALSE;
- }
- // Finally read in the image data.
- iseek(Header.MipOffsets[Mip], IL_SEEK_SET);
- if (iread(Image->Data, 1, Image->SizeOfData) != Image->SizeOfData)
- return IL_FALSE;
- break;
- case 1:
- if (!BaseCreated) { // Have not created the base image yet, so use ilTexImage.
- if (!ilTexImage(Header.Width, Header.Height, 1, 4, IL_BGRA, IL_UNSIGNED_BYTE, NULL))
- return IL_FALSE;
- Image = iCurImage;
- BaseCreated = IL_TRUE;
- Palette = (ILubyte*)ialloc(256 * 4);
- if (Palette == NULL)
- return IL_FALSE;
- // Read in the palette.
- if (iread(Palette, 1, 1024) != 1024) {
- ifree(Palette);
- return IL_FALSE;
- }
- // We only allocate this once and reuse this buffer with every mipmap (since successive ones are smaller).
- DataAndAlpha = (ILubyte*)ialloc(Image->Width * Image->Height);
- if (DataAndAlpha == NULL) {
- ifree(DataAndAlpha);
- ifree(Palette);
- return IL_FALSE;
- }
- }
- else {
- Image->Mipmaps = ilNewImageFull(Image->Width >> 1, Image->Height >> 1, 1, 4, IL_BGRA, IL_UNSIGNED_BYTE, NULL);
- if (Image->Mipmaps == NULL)
- return IL_FALSE;
- // Move to the next mipmap in the linked list.
- Image = Image->Mipmaps;
- }
- // The origin should be in the upper left.
- Image->Origin = IL_ORIGIN_UPPER_LEFT;
- // Determine the size of the alpha data following the color indices.
- AlphaSize = Image->Width * Image->Height / 8;
- if (AlphaSize == 0)
- AlphaSize = 1; // Should never be 0.
- // These two should be the same (tells us how much data is in the file for this mipmap level).
- if (Header.MipLengths[Mip] != Image->SizeOfData / 4 + AlphaSize) {
- ilSetError(IL_INVALID_FILE_HEADER);
- return IL_FALSE;
- }
- // Seek to the data and read it.
- iseek(Header.MipOffsets[Mip], IL_SEEK_SET);
- if (iread(DataAndAlpha, Image->Width * Image->Height, 1) != 1) {
- ifree(DataAndAlpha);
- ifree(Palette);
- return IL_FALSE;
- }
- // Convert the color-indexed data to BGRX.
- for (j = 0; j < Image->Width * Image->Height; j++) {
- Image->Data[j*4] = Palette[DataAndAlpha[j]*4];
- Image->Data[j*4+1] = Palette[DataAndAlpha[j]*4+1];
- Image->Data[j*4+2] = Palette[DataAndAlpha[j]*4+2];
- }
- // Read in the alpha list.
- if (iread(DataAndAlpha, AlphaSize, 1) != 1) {
- ifree(DataAndAlpha);
- ifree(Palette);
- return IL_FALSE;
- }
- AlphaMask = 0x01; // Lowest bit
- AlphaOff = 0;
- // The really strange thing about this alpha data is that it is upside-down when compared to the
- // regular color-indexed data, so we have to flip it.
- for (y = Image->Height - 1; y >= 0; y--) {
- for (x = 0; x < Image->Width; x++) {
- if (AlphaMask == 0) { // Shifting it past the highest bit makes it 0, since we only have 1 byte.
- AlphaOff++; // Move along the alpha buffer.
- AlphaMask = 0x01; // Reset the alpha mask.
- }
- // This is just 1-bit alpha, so it is either on or off.
- Image->Data[Image->Bps * y + x * 4 + 3] = DataAndAlpha[AlphaOff] & AlphaMask ? 0xFF : 0x00;
- AlphaMask <<= 1;
- }
- }
- break;
- default:
- //@TODO: Accept any other alpha values?
- ilSetError(IL_INVALID_FILE_HEADER);
- return IL_FALSE;
- }
- }
- // Done, so we can finally free these two.
- ifree(DataAndAlpha);
- ifree(Palette);
- break;
- case BLP_DXTC:
- for (Mip = 0; Mip < 16; Mip++) { // Possible maximum of 16 mipmaps
- //@TODO: Other formats
- //if (Header.AlphaBits == 0)
- // if (!ilTexImage(Header.Width, Header.Height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL))
- // return IL_FALSE;
- if (!BaseCreated) { // Have not created the base image yet, so use ilTexImage.
- if (!ilTexImage(Header.Width, Header.Height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL))
- return IL_FALSE;
- Image = iCurImage;
- BaseCreated = IL_TRUE;
- }
- else {
- if (Header.HasMips == 0) // Does not have mipmaps, so we are done.
- break;
- if (Image->Width == 1 && Image->Height == 1) // Already at the smallest mipmap (1x1), so we are done.
- break;
- if (Header.MipOffsets[Mip] == 0 || Header.MipLengths[Mip] == 0) // No more mipmaps in the file.
- break;
- //@TODO: Other formats
- // ilNewImageFull automatically changes widths and heights of 0 to 1, so we do not have to worry about it.
- Image->Mipmaps = ilNewImageFull(Image->Width >> 1, Image->Height >> 1, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL);
- if (Image->Mipmaps == NULL)
- return IL_FALSE;
- Image = Image->Mipmaps;
- }
- // The origin should be in the upper left.
- Image->Origin = IL_ORIGIN_UPPER_LEFT;
- //@TODO: Only do the allocation once.
- CompData = (ILubyte*)ialloc(Header.MipLengths[Mip]);
- if (CompData == NULL)
- return IL_FALSE;
- // Read in the compressed mipmap data.
- iseek(Header.MipOffsets[Mip], IL_SEEK_SET);
- if (iread(CompData, 1, Header.MipLengths[Mip]) != Header.MipLengths[Mip]) {
- ifree(CompData);
- return IL_FALSE;
- }
- switch (Header.AlphaBits)
- {
- case 0: // DXT1 without alpha
- case 1: // DXT1 with alpha
- // Check to make sure that the MipLength reported is the size needed, so that
- // DecompressDXT1 does not crash.
- CompSize = ((Image->Width + 3) / 4) * ((Image->Height + 3) / 4) * 8;
- if (CompSize != Header.MipLengths[Mip]) {
- ilSetError(IL_INVALID_FILE_HEADER);
- ifree(CompData);
- return IL_FALSE;
- }
- if (!DecompressDXT1(Image, CompData)) {
- ifree(CompData);
- return IL_FALSE;
- }
- break;
- case 8:
- // Check to make sure that the MipLength reported is the size needed, so that
- // DecompressDXT3/5 do not crash.
- CompSize = ((Image->Width + 3) / 4) * ((Image->Height + 3) / 4) * 16;
- if (CompSize != Header.MipLengths[Mip]) {
- ifree(CompData);
- ilSetError(IL_INVALID_FILE_HEADER);
- return IL_FALSE;
- }
- switch (Header.AlphaType)
- {
- case 0: // All three of
- case 1: // these refer to
- case 8: // DXT3...
- if (!DecompressDXT3(Image, CompData)) {
- ifree(CompData);
- return IL_FALSE;
- }
- break;
- case 7: // DXT5 compression
- if (!DecompressDXT5(Image, CompData)) {
- ifree(CompData);
- return IL_FALSE;
- }
- break;
- //default: // Should already be checked by iCheckBlp2.
- }
- break;
- //default: // Should already be checked by iCheckBlp2.
- }
- //@TODO: Save DXTC data.
- ifree(CompData);
- }
- break;
- //default:
- }
- return ilFixImage();
- check_blp1:
- iseek(-148, IL_SEEK_CUR); // Go back the size of the BLP2 header, since we tried reading it.
- return iLoadBlp1();
- }
- ILboolean iGetBlp1Head(BLP1HEAD *Header)
- {
- ILuint i;
- iread(Header->Sig, 1, 4);
- Header->Compression = GetLittleUInt();
- Header->Flags = GetLittleUInt();
- Header->Width = GetLittleUInt();
- Header->Height = GetLittleUInt();
- Header->PictureType = GetLittleUInt();
- Header->PictureSubType = GetLittleUInt();
- for (i = 0; i < 16; i++)
- Header->MipOffsets[i] = GetLittleUInt();
- for (i = 0; i < 16; i++)
- Header->MipLengths[i] = GetLittleUInt();
- return IL_TRUE;
- }
- ILboolean iCheckBlp1(BLP1HEAD *Header)
- {
- // The file signature is 'BLP1'.
- if (strncmp(Header->Sig, "BLP1", 4))
- return IL_FALSE;
- // Valid types are JPEG and RAW. JPEG is not common, though.
- if (Header->Compression != BLP_TYPE_JPG && Header->Compression != BLP_RAW)
- return IL_FALSE;
- //@TODO: Find out what Flags is for.
- // PictureType determines whether this has an alpha list.
- if (Header->PictureType != BLP_RAW_PLUS_ALPHA1 && Header->PictureType != BLP_RAW_PLUS_ALPHA2
- && Header->PictureType != BLP_RAW_NO_ALPHA)
- return IL_FALSE;
- // Width or height of 0 makes no sense.
- if (Header->Width == 0 || Header->Height == 0)
- return IL_FALSE;
- return IL_TRUE;
- }
- ILboolean iLoadBlp1()
- {
- BLP1HEAD Header;
- ILubyte *DataAndAlpha, *Palette;
- ILuint i;
- ILimage *Image = iCurImage;
- ILboolean BaseCreated = IL_FALSE;
- #ifndef IL_NO_JPEG
- ILubyte *JpegHeader, *JpegData;
- ILuint JpegHeaderSize;
- #endif//IL_NO_JPEG
- if (!iGetBlp1Head(&Header))
- return IL_FALSE;
- if (!iCheckBlp1(&Header)) {
- ilSetError(IL_INVALID_FILE_HEADER);
- return IL_FALSE;
- }
- //@TODO: Remove this.
- i = 0;
- switch (Header.Compression)
- {
- case BLP_TYPE_JPG:
- #ifdef IL_NO_JPEG
- // We can only do the Jpeg decoding if we do not have IL_NO_JPEG defined.
- return IL_FALSE;
- #else
- JpegHeaderSize = GetLittleUInt();
- JpegHeader = (ILubyte*)ialloc(JpegHeaderSize);
- if (JpegHeader == NULL)
- return IL_FALSE;
- // Read the shared Jpeg header.
- if (iread(JpegHeader, 1, JpegHeaderSize) != JpegHeaderSize) {
- ifree(JpegHeader);
- return IL_FALSE;
- }
- //for (i = 0; i < 16; i++) { // Possible maximum of 16 mipmaps
- //@TODO: Check return value?
- iseek(Header.MipOffsets[i], IL_SEEK_SET);
- JpegData = (ILubyte*)ialloc(JpegHeaderSize + Header.MipLengths[i]);
- if (JpegData == NULL) {
- ifree(JpegHeader);
- return IL_FALSE;
- }
- memcpy(JpegData, JpegHeader, JpegHeaderSize);
- if (iread(JpegData + JpegHeaderSize, Header.MipLengths[i], 1) != 1)
- return IL_FALSE;
- // Just send the data straight to the Jpeg loader.
- if (!ilLoadL_JPEG(JpegData, JpegHeaderSize + Header.MipLengths[i]))
- return IL_FALSE;
- // The image data is in BGR(A) order, even though it is Jpeg-compressed.
- if (Image->Format == IL_RGBA)
- Image->Format = IL_BGRA;
- if (Image->Format == IL_RGB)
- Image->Format = IL_BGR;
- ifree(JpegData);
- //}
- ifree(JpegHeader);
- #endif//IL_NO_JPEG
- break;
- case BLP_RAW:
- switch (Header.PictureType)
- {
- // There is no alpha list, so we just read like a normal indexed image.
- case BLP_RAW_NO_ALPHA:
- for (i = 0; i < 16; i++) { // Possible maximum of 16 mipmaps
- if (!BaseCreated) { // Have not created the base image yet, so use ilTexImage.
- if (!ilTexImage(Header.Width, Header.Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL))
- return IL_FALSE;
- Image = iCurImage;
- BaseCreated = IL_TRUE;
- // We have a BGRA palette.
- Image->Pal.Palette = (ILubyte*)ialloc(256 * 4);
- if (Image->Pal.Palette == NULL)
- return IL_FALSE;
- Image->Pal.PalSize = 1024;
- Image->Pal.PalType = IL_PAL_BGRA32;
- // Read in the palette ...
- if (iread(Image->Pal.Palette, 1, 1024) != 1024)
- return IL_FALSE;
- }
- else {
- if (Image->Width == 1 && Image->Height == 1) // Already at the smallest mipmap (1x1), so we are done.
- break;
- if (Header.MipOffsets[i] == 0 || Header.MipLengths[i] == 0) // No more mipmaps in the file.
- break;
- Image->Mipmaps = ilNewImageFull(Image->Width >> 1, Image->Height >> 1, 1, 1, IL_COLOR_INDEX, IL_UNSIGNED_BYTE, NULL);
- if (Image->Mipmaps == NULL)
- return IL_FALSE;
- // Copy the palette from the first image before we change our Image pointer.
- Image->Mipmaps->Pal.Palette = (ILubyte*)ialloc(256 * 4);
- if (Image->Mipmaps->Pal.Palette == NULL)
- return IL_FALSE;
- Image->Mipmaps->Pal.PalSize = 1024;
- Image->Mipmaps->Pal.PalType = IL_PAL_BGRA32;
- memcpy(Image->Mipmaps->Pal.Palette, Image->Pal.Palette, 1024);
- // Move to the next mipmap in the linked list.
- Image = Image->Mipmaps;
- }
- // The origin should be in the upper left.
- Image->Origin = IL_ORIGIN_UPPER_LEFT;
- // Seek to the data and read it.
- iseek(Header.MipOffsets[i], IL_SEEK_SET);
- if (iread(Image->Data, 1, Image->SizeOfData) != Image->SizeOfData)
- return IL_FALSE;
- }
- break;
- // These cases are identical and have an alpha list following the image data.
- case BLP_RAW_PLUS_ALPHA1:
- case BLP_RAW_PLUS_ALPHA2:
- // Create the image.
- if (!ilTexImage(Header.Width, Header.Height, 1, 4, IL_BGRA, IL_UNSIGNED_BYTE, NULL))
- return IL_FALSE;
- DataAndAlpha = (ILubyte*)ialloc(Header.Width * Header.Height);
- Palette = (ILubyte*)ialloc(256 * 4);
- if (DataAndAlpha == NULL || Palette == NULL) {
- ifree(DataAndAlpha);
- ifree(Palette);
- return IL_FALSE;
- }
- // Read in the data and the palette.
- if (iread(Palette, 1, 1024) != 1024) {
- ifree(Palette);
- return IL_FALSE;
- }
- // Seek to the data and read it.
- iseek(Header.MipOffsets[i], IL_SEEK_SET);
- if (iread(DataAndAlpha, Header.Width * Header.Height, 1) != 1) {
- ifree(DataAndAlpha);
- ifree(Palette);
- return IL_FALSE;
- }
- // Convert the color-indexed data to BGRX.
- for (i = 0; i < Header.Width * Header.Height; i++) {
- Image->Data[i*4] = Palette[DataAndAlpha[i]*4];
- Image->Data[i*4+1] = Palette[DataAndAlpha[i]*4+1];
- Image->Data[i*4+2] = Palette[DataAndAlpha[i]*4+2];
- }
- // Read in the alpha list.
- if (iread(DataAndAlpha, Header.Width * Header.Height, 1) != 1) {
- ifree(DataAndAlpha);
- ifree(Palette);
- return IL_FALSE;
- }
- // Finally put the alpha data into the image data.
- for (i = 0; i < Header.Width * Header.Height; i++) {
- Image->Data[i*4+3] = DataAndAlpha[i];
- }
- ifree(DataAndAlpha);
- ifree(Palette);
- break;
- }
- break;
- //default: // Should already be checked by iCheckBlp1.
- }
- // Set the origin (always upper left).
- Image->Origin = IL_ORIGIN_UPPER_LEFT;
- return ilFixImage();
- }
- #endif//IL_NO_BLP