Files
love-android/jni/devil-1.7.8/src-IL/src/il_blp.c
T

737 lines
21 KiB
C
Executable File

//-----------------------------------------------------------------------------
//
// 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 ilIsValidBlp(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 = ilIsValidBlpF(BlpFile);
icloser(BlpFile);
return bBlp;
}
//! Checks if the ILHANDLE contains a valid BLP file at the current position.
ILboolean ilIsValidBlpF(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 ilIsValidBlpL(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 ilLoadBlp(ILconst_string FileName)
{
ILHANDLE BlpFile;
ILboolean bBlp = IL_FALSE;
BlpFile = iopenr(FileName);
if (BlpFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bBlp;
}
bBlp = ilLoadBlpF(BlpFile);
icloser(BlpFile);
return bBlp;
}
//! Reads an already-opened BLP file
ILboolean ilLoadBlpF(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 ilLoadBlpL(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_JPG
ILubyte *JpegHeader, *JpegData;
ILuint JpegHeaderSize;
#endif//IL_NO_JPG
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_JPG
// 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 (!ilLoadJpegL(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_JPG
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