- Main Page
- Data Structures
- Files

- File List

# E:/DevIL/src-IL/src/il_vtf.c

    00001 //-----------------------------------------------------------------------------
    00002 //
    00003 // ImageLib Sources
    00004 // Copyright (C) 2000-2009 by Denton Woods
    00005 // Last modified: 01/30/2009
    00006 //
    00007 // Filename: src-IL/src/il_vtf.c
    00008 //
    00009 // Description: Reads from a Valve Texture Format (.vtf) file.
    00010 //                These are used in Valve's Source games.  VTF specs available
    00011 //                from http://developer.valvesoftware.com/wiki/VTF.
    00012 //
    00013 //-----------------------------------------------------------------------------
    00014
    00015
    00016 #include "il_internal.h"
    00017 #ifndef IL_NO_VTF
    00018 #include "il_vtf.h"
    00019 #include "il_dds.h"
    00020
    00021 // the max and min functions are not present, at least not on Unixes
    00022 #ifndef max
    00023         #define max( a, b ) ( ((a) > (b)) ? (a) : (b) )
    00024 #endif
    00025
    00026 #ifndef min
    00027         #define min( a, b ) ( ((a) < (b)) ? (a) : (b) )
    00028 #endif
    00029
    00030 //@TODO: Get rid of these globals.
    00031 //static VTFHEAD Head;
    00032
    00033
    00035 ILboolean ilIsValidVtf(ILconst_string FileName)
    00036 {
    00037         ILHANDLE        VtfFile;
    00038         ILboolean       bVtf = IL_FALSE;
    00039
    00040         if (!iCheckExtension(FileName, IL_TEXT("vtf"))) {
    00041                 ilSetError(IL_INVALID_EXTENSION);
    00042                 return bVtf;
    00043         }
    00044
    00045         VtfFile = iopenr(FileName);
    00046         if (VtfFile == NULL) {
    00047                 ilSetError(IL_COULD_NOT_OPEN_FILE);
    00048                 return bVtf;
    00049         }
    00050
    00051         bVtf = ilIsValidVtfF(VtfFile);
    00052         icloser(VtfFile);
    00053
    00054         return bVtf;
    00055 }
    00056
    00057
    00059 ILboolean ilIsValidVtfF(ILHANDLE File)
    00060 {
    00061         ILuint          FirstPos;
    00062         ILboolean       bRet;
    00063
    00064         iSetInputFile(File);
    00065         FirstPos = itell();
    00066         bRet = iIsValidVtf();
    00067         iseek(FirstPos, IL_SEEK_SET);
    00068
    00069         return bRet;
    00070 }
    00071
    00072
    00074 ILboolean ilIsValidVtfL(const void *Lump, ILuint Size)
    00075 {
    00076         iSetInputLump(Lump, Size);
    00077         return iIsValidVtf();
    00078 }
    00079
    00080
    00081 // Internal function used to get the VTF header from the current file.
    00082 ILboolean iGetVtfHead(VTFHEAD *Header)
    00083 {
    00084         iread(Header->Signature, 1, 4);
    00085         Header->Version[0] = GetLittleUInt();
    00086         Header->Version[1] = GetLittleUInt();
    00087         Header->HeaderSize = GetLittleUInt();
    00088         Header->Width = GetLittleUShort();
    00089         Header->Height = GetLittleUShort();
    00090         Header->Flags = GetLittleUInt();
    00091         Header->Frames = GetLittleUShort();
    00092         Header->FirstFrame = GetLittleUShort();
    00093         iseek(4, IL_SEEK_CUR);  // Padding
    00094         Header->Reflectivity[0] = GetLittleFloat();
    00095         Header->Reflectivity[1] = GetLittleFloat();
    00096         Header->Reflectivity[2] = GetLittleFloat();
    00097         iseek(4, IL_SEEK_CUR);  // Padding
    00098         Header->BumpmapScale = GetLittleFloat();
    00099         Header->HighResImageFormat = GetLittleUInt();
    00100         Header->MipmapCount = (ILubyte)igetc();
    00101         Header->LowResImageFormat = GetLittleInt();
    00102         Header->LowResImageWidth = (ILubyte)igetc();
    00103         Header->LowResImageHeight = (ILubyte)igetc();
    00104         Header->Depth = GetLittleUShort();
    00105
    00106         iseek(Header->HeaderSize - sizeof(VTFHEAD), IL_SEEK_CUR);
    00107
    00108         return IL_TRUE;
    00109 }
    00110
    00111
    00112 // Internal function to get the header and check it.
    00113 ILboolean iIsValidVtf(void)
    00114 {
    00115         VTFHEAD Header;
    00116
    00117         if (!iGetVtfHead(&Header))
    00118                 return IL_FALSE;
    00119         iseek(-(ILint)sizeof(VTFHEAD), IL_SEEK_CUR);
    00120
    00121         return iCheckVtf(&Header);
    00122 }
    00123
    00124
    00125 //@TODO: Add more checks.
    00126 // Should we check for Frames, MipmapCount and Depth != 0?
    00127
    00128 // Internal function used to check if the HEADER is a valid VTF header.
    00129 ILboolean iCheckVtf(VTFHEAD *Header)
    00130 {
    00131         // The file signature is "VTF\0".
    00132         if ((Header->Signature[0] != 'V') || (Header->Signature[1] != 'T') || (Header->Signature[2] != 'F')
    00133                 || (Header->Signature[3] != 0))
    00134                 return IL_FALSE;
    00135         // Are there other versions available yet?
    00136         if (Header->Version[0] != 7)
    00137                 return IL_FALSE;
    00138         // We have 7.0 through 7.4 as of 12/27/2008.
    00139         if (Header->Version[1] > 4)
    00140                 return IL_FALSE;
    00141         // May change in future version of the specifications.
    00142         //  80 is through version 7.2, and 96/104 are through 7.4.
    00143         //  This must be 16-byte aligned, but something is outputting headers with 104.
    00144         if ((Header->HeaderSize != 80) && (Header->HeaderSize != 96) && (Header->HeaderSize != 104))
    00145                 return IL_FALSE;
    00146
    00147         // 0 is an invalid dimension
    00148         if (Header->Width == 0 || Header->Height == 0)
    00149                 return IL_FALSE;
    00150         // Width and Height must be powers of 2.
    00151         if ((ilNextPower2(Header->Width) != Header->Width) || (ilNextPower2(Header->Height) != Header->Height))
    00152                 return IL_FALSE;
    00153         // It looks like width and height of zero are valid - i.e. no low res image.
    00154         if (Header->LowResImageWidth != 0 && Header->LowResImageHeight != 0) {
    00155                 if ((ilNextPower2(Header->LowResImageWidth) != Header->LowResImageWidth)
    00156                         || (ilNextPower2(Header->LowResImageHeight) != Header->LowResImageHeight))
    00157                         return IL_FALSE;
    00158         }
    00159         // In addition, the LowResImage has to have dimensions no greater than 16.
    00160         if ((Header->LowResImageWidth > 16) || (Header->LowResImageHeight > 16))
    00161                 //|| (Header->LowResImageWidth == 0) || (Header->LowResImageHeight == 0))
    00162                 // It looks like width and height of zero are valid.
    00163                 return IL_FALSE;
    00164         // And the LowResImage has to have dimensions less than or equal to the main image.
    00165         if ((Header->LowResImageWidth > Header->Width) || (Header->LowResImageHeight > Header->Height))
    00166                 return IL_FALSE;
    00167         // The LowResImage must be in DXT1 format, or if it does not exist, it is denoted by all bits set.
    00168         if (Header->LowResImageFormat != IMAGE_FORMAT_DXT1 && Header->LowResImageFormat != 0xFFFFFFFF)
    00169                 return IL_FALSE;
    00170
    00171         return IL_TRUE;
    00172 }
    00173
    00174
    00176 ILboolean ilLoadVtf(ILconst_string FileName)
    00177 {
    00178         ILHANDLE        VtfFile;
    00179         ILboolean       bVtf = IL_FALSE;
    00180
    00181         VtfFile = iopenr(FileName);
    00182         if (VtfFile == NULL) {
    00183                 ilSetError(IL_COULD_NOT_OPEN_FILE);
    00184                 return bVtf;
    00185         }
    00186
    00187         bVtf = ilLoadVtfF(VtfFile);
    00188         icloser(VtfFile);
    00189
    00190         return bVtf;
    00191 }
    00192
    00193
    00195 ILboolean ilLoadVtfF(ILHANDLE File)
    00196 {
    00197         ILuint          FirstPos;
    00198         ILboolean       bRet;
    00199
    00200         iSetInputFile(File);
    00201         FirstPos = itell();
    00202         bRet = iLoadVtfInternal();
    00203         iseek(FirstPos, IL_SEEK_SET);
    00204
    00205         return bRet;
    00206 }
    00207
    00208
    00210 ILboolean ilLoadVtfL(const void *Lump, ILuint Size)
    00211 {
    00212         iSetInputLump(Lump, Size);
    00213         return iLoadVtfInternal();
    00214 }
    00215
    00216
    00217 // Internal function used to load the VTF.
    00218 ILboolean iLoadVtfInternal(void)
    00219 {
    00220         ILboolean       bVtf = IL_TRUE;
    00221         ILimage         *Image, *BaseImage;
    00222         ILenum          Format, Type;
    00223         ILint           Frame, Face, Mipmap;
    00224         ILuint          SizeOfData, Channels, k;
    00225         ILubyte         *CompData = NULL, SwapVal, *Data16Bit, *Temp, NumFaces;
    00226         VTFHEAD         Head;
    00227         ILuint          CurName;
    00228
    00229         if (iCurImage == NULL) {
    00230                 ilSetError(IL_ILLEGAL_OPERATION);
    00231                 return IL_FALSE;
    00232         }
    00233         CurName = ilGetCurName();
    00234
    00235         if (!iGetVtfHead(&Head))
    00236                 return IL_FALSE;
    00237         if (!iCheckVtf(&Head)) {
    00238                 ilSetError(IL_INVALID_FILE_HEADER);
    00239                 return IL_FALSE;
    00240         }
    00241
    00242         if (Head.Flags & TEXTUREFLAGS_ENVMAP) {
    00243                 // If we have a spherical map in addition to the 6 sides of the cubemap, FirstFrame's bits
    00244                 //  are all set.  The only place I found out about this was VTFLib.
    00245                 NumFaces = Head.FirstFrame == 0xFFFF ? 6 : 7;
    00246         }
    00247         else
    00248                 NumFaces = 1;  // This is not an environmental map.
    00249
    00250         // Skip the low resolution image.  This is just a thumbnail.
    00251         //  The block size is 8, and the compression ratio is 6:1.
    00252         SizeOfData = max(Head.LowResImageWidth * Head.LowResImageHeight / 2, 8);
    00253         if (Head.LowResImageWidth == 0 && Head.LowResImageHeight == 0)
    00254                 SizeOfData = 0;  // No low resolution image present.
    00255         iseek(SizeOfData, IL_SEEK_CUR);
    00256
    00257         //@TODO: Make this a helper function that set channels, bpc and format.
    00258         switch (Head.HighResImageFormat)
    00259         {
    00260                 case IMAGE_FORMAT_DXT1:  //@TODO: Should we make DXT1 channels = 3?
    00261                 case IMAGE_FORMAT_DXT1_ONEBITALPHA:
    00262                 case IMAGE_FORMAT_DXT3:
    00263                 case IMAGE_FORMAT_DXT5:
    00264                         Channels = 4;
    00265                         Format = IL_RGBA;
    00266                         Type = IL_UNSIGNED_BYTE;
    00267                         break;
    00268                 case IMAGE_FORMAT_BGR888:
    00269                 case IMAGE_FORMAT_BGR888_BLUESCREEN:
    00270                         Channels = 3;
    00271                         Format = IL_BGR;
    00272                         Type = IL_UNSIGNED_BYTE;
    00273                         break;
    00274                 case IMAGE_FORMAT_BGRA8888:
    00275                         Channels = 4;
    00276                         Format = IL_BGRA;
    00277                         Type = IL_UNSIGNED_BYTE;
    00278                         break;
    00279                 case IMAGE_FORMAT_BGRX8888:
    00280                         Channels = 3;
    00281                         Format = IL_BGR;
    00282                         Type = IL_UNSIGNED_BYTE;
    00283                         break;
    00284                 case IMAGE_FORMAT_RGB888:
    00285                 case IMAGE_FORMAT_RGB888_BLUESCREEN:
    00286                         Channels = 3;
    00287                         Format = IL_RGB;
    00288                         Type = IL_UNSIGNED_BYTE;
    00289                         break;
    00290                 case IMAGE_FORMAT_RGBA8888:
    00291                         Channels = 4;
    00292                         Format = IL_RGBA;
    00293                         Type = IL_UNSIGNED_BYTE;
    00294                         break;
    00295                 case IMAGE_FORMAT_RGBA16161616:  // 16-bit shorts
    00296                         Channels = 4;
    00297                         Format = IL_RGBA;
    00298                         Type = IL_UNSIGNED_SHORT;
    00299                         break;
    00300                 case IMAGE_FORMAT_RGBA16161616F:  // 16-bit floats
    00301                         Channels = 4;
    00302                         Format = IL_RGBA;
    00303                         Type = IL_FLOAT;
    00304                         break;
    00305                 case IMAGE_FORMAT_I8:  // 8-bit luminance data
    00306                         Channels = 1;
    00307                         Format = IL_LUMINANCE;
    00308                         Type = IL_UNSIGNED_BYTE;
    00309                         break;
    00310                 case IMAGE_FORMAT_IA88:  // 8-bit luminance and alpha data
    00311                         Channels = 2;
    00312                         Format = IL_LUMINANCE_ALPHA;
    00313                         Type = IL_UNSIGNED_BYTE;
    00314                         break;
    00315                 case IMAGE_FORMAT_A8:  // 8-bit alpha data
    00316                         Channels = 1;
    00317                         Format = IL_ALPHA;
    00318                         Type = IL_UNSIGNED_BYTE;
    00319                         break;
    00320                 case IMAGE_FORMAT_ARGB8888:
    00321                         Channels = 4;
    00322                         Format = IL_BGRA;
    00323                         Type = IL_UNSIGNED_BYTE;
    00324                         break;
    00325                 case IMAGE_FORMAT_ABGR8888:
    00326                         Channels = 4;
    00327                         Format = IL_RGBA;
    00328                         Type = IL_UNSIGNED_BYTE;
    00329                         break;
    00330                 case IMAGE_FORMAT_RGB565:
    00331                         Channels = 3;
    00332                         Format = IL_RGB;
    00333                         Type = IL_UNSIGNED_BYTE;
    00334                         break;
    00335                 case IMAGE_FORMAT_BGR565:
    00336                         Channels = 3;
    00337                         Format = IL_BGR;
    00338                         Type = IL_UNSIGNED_BYTE;
    00339                         break;
    00340                 case IMAGE_FORMAT_BGRA5551:
    00341                         Channels = 4;
    00342                         Format = IL_BGRA;
    00343                         Type = IL_UNSIGNED_BYTE;
    00344                         break;
    00345                 case IMAGE_FORMAT_BGRX5551:  // Unused alpha channel
    00346                         Channels = 3;
    00347                         Format = IL_BGR;
    00348                         Type = IL_UNSIGNED_BYTE;
    00349                         break;
    00350                 case IMAGE_FORMAT_BGRA4444:
    00351                         Channels = 4;
    00352                         Format = IL_BGRA;
    00353                         Type = IL_UNSIGNED_BYTE;
    00354                         break;
    00355
    00356                 default:
    00357                         ilSetError(IL_FORMAT_NOT_SUPPORTED);
    00358                         return IL_FALSE;
    00359         }
    00360
    00361         if (!ilTexImage(Head.Width, Head.Height, Head.Depth, Channels, Format, Type, NULL))
    00362                 return IL_FALSE;
    00363         // The origin should be in the upper left.
    00364         iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
    00365         // Create any mipmaps.
    00366         VtfInitFacesMipmaps(iCurImage, NumFaces, &Head);
    00367
    00368         // Create our animation chain
    00369         BaseImage = Image = iCurImage;  // Top-level image
    00370         for (Frame = 1; Frame < Head.Frames; Frame++) {
    00371                 Image->Next = ilNewImageFull(Head.Width, Head.Height, Head.Depth, Channels, Format, Type, NULL);
    00372                 if (Image->Next == NULL)
    00373                         return IL_FALSE;
    00374                 Image = Image->Next;
    00375                 // The origin should be in the upper left.
    00376                 Image->Origin = IL_ORIGIN_UPPER_LEFT;
    00377
    00378                 // Create our faces and mipmaps for each frame.
    00379                 VtfInitFacesMipmaps(Image, NumFaces, &Head);
    00380         }
    00381
    00382         // We want to put the smallest mipmap at the end, but it is first in the file, so we count backwards.
    00383         for (Mipmap = Head.MipmapCount - 1; Mipmap >= 0; Mipmap--) {
    00384                 // Frames are in the normal order.
    00385                 for (Frame = 0; Frame < Head.Frames; Frame++) {
    00386                         // @TODO: Cubemap faces are always in the same order?
    00387                         for (Face = 0; Face < NumFaces; Face++) {
    00388                                 //@TODO: Would probably be quicker to do the linked list traversal manually here.
    00389                                 ilBindImage(CurName);
    00390                                 ilActiveImage(Frame);
    00391                                 ilActiveFace(Face);
    00392                                 ilActiveMipmap(Mipmap);
    00393                                 Image = iCurImage;
    00394
    00395                                 switch (Head.HighResImageFormat)
    00396                                 {
    00397                                         // DXT1 compression
    00398                                         case IMAGE_FORMAT_DXT1:
    00399                                         case IMAGE_FORMAT_DXT1_ONEBITALPHA:
    00400                                                 // The block size is 8.
    00401                                                 SizeOfData = max(Image->Width * Image->Height * Image->Depth / 2, 8);
    00402                                                 CompData = ialloc(SizeOfData);  // Gives a 6:1 compression ratio (or 8:1 for DXT1 with alpha)
    00403                                                 iread(CompData, 1, SizeOfData);
    00404                                                 if (ilGetInteger(IL_KEEP_DXTC_DATA) == IL_TRUE) {
    00405                                                         Image->DxtcSize = SizeOfData;
    00406                                                         Image->DxtcData = CompData;
    00407                                                         Image->DxtcFormat = IL_DXT5;
    00408                                                         CompData = NULL;
    00409                                                 }
    00410                                                 bVtf = DecompressDXT1(Image, CompData);
    00411                                                 break;
    00412
    00413                                         // DXT3 compression
    00414                                         case IMAGE_FORMAT_DXT3:
    00415                                                 // The block size is 16.
    00416                                                 SizeOfData = max(Image->Width * Image->Height * Image->Depth, 16);
    00417                                                 CompData = ialloc(SizeOfData);  // Gives a 4:1 compression ratio
    00418                                                 iread(CompData, 1, SizeOfData);
    00419                                                 if (ilGetInteger(IL_KEEP_DXTC_DATA) == IL_TRUE) {
    00420                                                         Image->DxtcSize = SizeOfData;
    00421                                                         Image->DxtcData = CompData;
    00422                                                         Image->DxtcFormat = IL_DXT3;
    00423                                                         CompData = NULL;
    00424                                                 }
    00425                                                 bVtf = DecompressDXT3(Image, CompData);
    00426                                                 break;
    00427
    00428                                         // DXT5 compression
    00429                                         case IMAGE_FORMAT_DXT5:
    00430                                                 // The block size is 16.
    00431                                                 SizeOfData = max(Image->Width * Image->Height * Image->Depth, 16);
    00432                                                 CompData = ialloc(SizeOfData);  // Gives a 4:1 compression ratio
    00433                                                 iread(CompData, 1, SizeOfData);
    00434                                                 if (ilGetInteger(IL_KEEP_DXTC_DATA) == IL_TRUE) {
    00435                                                         Image->DxtcSize = SizeOfData;
    00436                                                         Image->DxtcData = CompData;
    00437                                                         Image->DxtcFormat = IL_DXT5;
    00438                                                         CompData = NULL;
    00439                                                 }
    00440                                                 bVtf = DecompressDXT5(Image, CompData);
    00441                                                 break;
    00442
    00443                                         // Uncompressed BGR(A) data (24-bit and 32-bit)
    00444                                         case IMAGE_FORMAT_BGR888:
    00445                                         case IMAGE_FORMAT_BGRA8888:
    00446                                         // Uncompressed RGB(A) data (24-bit and 32-bit)
    00447                                         case IMAGE_FORMAT_RGB888:
    00448                                         case IMAGE_FORMAT_RGBA8888:
    00449                                         // Uncompressed 16-bit shorts
    00450                                         case IMAGE_FORMAT_RGBA16161616:
    00451                                         // Luminance data only
    00452                                         case IMAGE_FORMAT_I8:
    00453                                         // Luminance and alpha data
    00454                                         case IMAGE_FORMAT_IA88:
    00455                                         // Alpha data only
    00456                                         case IMAGE_FORMAT_A8:
    00457                                         // We will ignore the part about the bluescreen right now.
    00458                                         //   I could not find any information about it.
    00459                                         case IMAGE_FORMAT_RGB888_BLUESCREEN:
    00460                                         case IMAGE_FORMAT_BGR888_BLUESCREEN:
    00461                                                 // Just copy the data over - no compression.
    00462                                                 if (iread(Image->Data, 1, Image->SizeOfData) != Image->SizeOfData)
    00463                                                         bVtf = IL_FALSE;
    00464                                                 else
    00465                                                         bVtf = IL_TRUE;
    00466                                                 break;
    00467
    00468                                         // Uncompressed 24-bit data with an unused alpha channel (we discard it)
    00469                                         case IMAGE_FORMAT_BGRX8888:
    00470                                                 SizeOfData = Image->Width * Image->Height * Image->Depth * 3;
    00471                                                 Temp = CompData = ialloc(SizeOfData / 3 * 4);  // Not compressed data
    00472                                                 if (iread(CompData, 1, SizeOfData / 3 * 4) != SizeOfData / 3 * 4) {
    00473                                                         bVtf = IL_FALSE;
    00474                                                         break;
    00475                                                 }
    00476                                                 for (k = 0; k < SizeOfData; k += 3) {
    00477                                                         Image->Data[k]   = Temp[0];
    00478                                                         Image->Data[k+1] = Temp[1];
    00479                                                         Image->Data[k+2] = Temp[2];
    00480                                                         Temp += 4;
    00481                                                 }
    00482
    00483                                                 break;
    00484
    00485                                         // Uncompressed 16-bit floats (must be converted to 32-bit)
    00486                                         case IMAGE_FORMAT_RGBA16161616F:
    00487                                                 SizeOfData = Image->Width * Image->Height * Image->Depth * Image->Bpp * 2;
    00488                                                 CompData = ialloc(SizeOfData);  // Not compressed data
    00489                                                 if (iread(CompData, 1, SizeOfData) != SizeOfData) {
    00490                                                         bVtf = IL_FALSE;
    00491                                                         break;
    00492                                                 }
    00493                                                 bVtf = iConvFloat16ToFloat32((ILuint*)Image->Data, (ILushort*)CompData, SizeOfData / 2);
    00494                                                 break;
    00495
    00496                                         // Uncompressed 32-bit ARGB and ABGR data.  DevIL does not handle this
    00497                                         //   internally, so we have to swap values.
    00498                                         case IMAGE_FORMAT_ARGB8888:
    00499                                         case IMAGE_FORMAT_ABGR8888:
    00500                                                 if (iread(Image->Data, 1, Image->SizeOfData) != Image->SizeOfData) {
    00501                                                         bVtf = IL_FALSE;
    00502                                                         break;
    00503                                                 }
    00504                                                 else {
    00505                                                         bVtf = IL_TRUE;
    00506                                                 }
    00507                                                 // Swap the data
    00508                                                 for (k = 0; k < Image->SizeOfData; k += 4) {
    00509                                                         SwapVal = Image->Data[k];
    00510                                                         Image->Data[k]   = Image->Data[k+3];
    00511                                                         Image->Data[k+3] = SwapVal;
    00512                                                         SwapVal = Image->Data[k+1];
    00513                                                         Image->Data[k+1] = Image->Data[k+2];
    00514                                                         Image->Data[k+2] = SwapVal;
    00515                                                 }
    00516                                                 break;
    00517
    00518                                         // Uncompressed 16-bit RGB and BGR data.  We have to expand this to 24-bit, since
    00519                                         //   DevIL does not handle this internally.
    00520                                         //   The data is in the file as: gggbbbbb rrrrrrggg
    00521                                         case IMAGE_FORMAT_RGB565:
    00522                                         case IMAGE_FORMAT_BGR565:
    00523                                                 SizeOfData = Image->Width * Image->Height * Image->Depth * 2;
    00524                                                 Data16Bit = CompData = ialloc(SizeOfData);  // Not compressed data
    00525                                                 if (iread(CompData, 1, SizeOfData) != SizeOfData) {
    00526                                                         bVtf = IL_FALSE;
    00527                                                         break;
    00528                                                 }
    00529                                                 for (k = 0; k < Image->SizeOfData; k += 3) {
    00530                                                         Image->Data[k]   =  (Data16Bit[0] & 0x1F) << 3;
    00531                                                         Image->Data[k+1] = ((Data16Bit[1] & 0x07) << 5) | ((Data16Bit[0] & 0xE0) >> 3);
    00532                                                         Image->Data[k+2] =   Data16Bit[1] & 0xF8;
    00533                                                         Data16Bit += 2;
    00534                                                 }
    00535                                                 break;
    00536
    00537                                         // Uncompressed 16-bit BGRA data (1-bit alpha).  We have to expand this to 32-bit,
    00538                                         //   since DevIL does not handle this internally.
    00539                                         //   Something seems strange with this one, but this is how VTFEdit outputs.
    00540                                         //   The data is in the file as: gggbbbbb arrrrrgg
    00541                                         case IMAGE_FORMAT_BGRA5551:
    00542                                                 SizeOfData = Image->Width * Image->Height * Image->Depth * 2;
    00543                                                 Data16Bit = CompData = ialloc(SizeOfData);  // Not compressed data
    00544                                                 if (iread(CompData, 1, SizeOfData) != SizeOfData) {
    00545                                                         bVtf = IL_FALSE;
    00546                                                         break;
    00547                                                 }
    00548                                                 for (k = 0; k < Image->SizeOfData; k += 4) {
    00549                                                         Image->Data[k]   =  (Data16Bit[0] & 0x1F) << 3;
    00550                                                         Image->Data[k+1] = ((Data16Bit[0] & 0xE0) >> 2) | ((Data16Bit[1] & 0x03) << 6);
    00551                                                         Image->Data[k+2] =  (Data16Bit[1] & 0x7C) << 1;
    00552                                                         // 1-bit alpha is either off or on.
    00553                                                         Image->Data[k+3] = ((Data16Bit[0] & 0x80) == 0x80) ? 0xFF : 0x00;
    00554                                                         Data16Bit += 2;
    00555                                                 }
    00556                                                 break;
    00557
    00558                                         // Same as above, but the alpha channel is unused.
    00559                                         case IMAGE_FORMAT_BGRX5551:
    00560                                                 SizeOfData = Image->Width * Image->Height * Image->Depth * 2;
    00561                                                 Data16Bit = CompData = ialloc(SizeOfData);  // Not compressed data
    00562                                                 if (iread(CompData, 1, SizeOfData) != SizeOfData) {
    00563                                                         bVtf = IL_FALSE;
    00564                                                         break;
    00565                                                 }
    00566                                                 for (k = 0; k < Image->SizeOfData; k += 3) {
    00567                                                         Image->Data[k]   =  (Data16Bit[0] & 0x1F) << 3;
    00568                                                         Image->Data[k+1] = ((Data16Bit[0] & 0xE0) >> 2) | ((Data16Bit[1] & 0x03) << 6);
    00569                                                         Image->Data[k+2] =  (Data16Bit[1] & 0x7C) << 1;
    00570                                                         Data16Bit += 2;
    00571                                                 }
    00572                                                 break;
    00573
    00574                                         // Data is reduced to a 4-bits per channel format.
    00575                                         case IMAGE_FORMAT_BGRA4444:
    00576                                                 SizeOfData = Image->Width * Image->Height * Image->Depth * 4;
    00577                                                 Temp = CompData = ialloc(SizeOfData / 2);  // Not compressed data
    00578                                                 if (iread(CompData, 1, SizeOfData / 2) != SizeOfData / 2) {
    00579                                                         bVtf = IL_FALSE;
    00580                                                         break;
    00581                                                 }
    00582                                                 for (k = 0; k < SizeOfData; k += 4) {
    00583                                                         // We double the data here.
    00584                                                         Image->Data[k]   = (Temp[0] & 0x0F) << 4 | (Temp[0] & 0x0F);
    00585                                                         Image->Data[k+1] = (Temp[0] & 0xF0) >> 4 | (Temp[0] & 0xF0);
    00586                                                         Image->Data[k+2] = (Temp[1] & 0x0F) << 4 | (Temp[1] & 0x0F);
    00587                                                         Image->Data[k+3] = (Temp[1] & 0xF0) >> 4 | (Temp[1] & 0xF0);
    00588                                                         Temp += 2;
    00589                                                 }
    00590                                                 break;
    00591                                 }
    00592
    00593                                 ifree(CompData);
    00594                                 CompData = NULL;
    00595                                 if (bVtf == IL_FALSE)  //@TODO: Do we need to do any cleanup here?
    00596                                         return IL_FALSE;
    00597                         }
    00598                 }
    00599         }
    00600
    00601         ilBindImage(CurName);  // Set to parent image first.
    00602         return ilFixImage();
    00603 }
    00604
    00605
    00606 ILuint GetFaceFlag(ILuint FaceNum)
    00607 {
    00608         switch (FaceNum)
    00609         {
    00610                 case 0:
    00611                         return IL_CUBEMAP_POSITIVEX;
    00612                 case 1:
    00613                         return IL_CUBEMAP_NEGATIVEX;
    00614                 case 2:
    00615                         return IL_CUBEMAP_POSITIVEY;
    00616                 case 3:
    00617                         return IL_CUBEMAP_NEGATIVEY;
    00618                 case 4:
    00619                         return IL_CUBEMAP_POSITIVEZ;
    00620                 case 5:
    00621                         return IL_CUBEMAP_NEGATIVEZ;
    00622                 case 6:
    00623                         return IL_SPHEREMAP;
    00624         }
    00625
    00626         return IL_SPHEREMAP;  // Should never reach here!
    00627 }
    00628
    00629
    00630 ILboolean VtfInitFacesMipmaps(ILimage *BaseImage, ILuint NumFaces, VTFHEAD *Header)
    00631 {
    00632         ILimage *Image;
    00633         ILuint  Face;
    00634
    00635         // Initialize mipmaps under the base image.
    00636         VtfInitMipmaps(BaseImage, Header);
    00637         Image = BaseImage;
    00638
    00639         // We have an environment map.
    00640         if (NumFaces != 1) {
    00641                 Image->CubeFlags = IL_CUBEMAP_POSITIVEX;
    00642         }
    00643
    00644         for (Face = 1; Face < NumFaces; Face++) {
    00645                 Image->Faces = ilNewImageFull(Image->Width, Image->Height, Image->Depth, Image->Bpp, Image->Format, Image->Type, NULL);
    00646                 if (Image->Faces == NULL)
    00647                         return IL_FALSE;
    00648                 Image = Image->Faces;
    00649
    00650                 // The origin should be in the upper left.
    00651                 Image->Origin = IL_ORIGIN_UPPER_LEFT;
    00652                 // Set the flags that tell which face this is.
    00653                 Image->CubeFlags = GetFaceFlag(Face);
    00654
    00655                 // Now we can initialize the mipmaps under each face.
    00656                 VtfInitMipmaps(Image, Header);
    00657         }
    00658
    00659         return IL_TRUE;
    00660 }
    00661
    00662
    00663 ILboolean VtfInitMipmaps(ILimage *BaseImage, VTFHEAD *Header)
    00664 {
    00665         ILimage *Image;
    00666         ILuint  Width, Height, Depth, Mipmap;
    00667
    00668         Image = BaseImage;
    00669         Width = BaseImage->Width;  Height = BaseImage->Height;  Depth = BaseImage->Depth;
    00670
    00671         for (Mipmap = 1; Mipmap < Header->MipmapCount; Mipmap++) {
    00672                 // 1 is the smallest dimension possible.
    00673                 Width = (Width >> 1) == 0 ? 1 : (Width >> 1);
    00674                 Height = (Height >> 1) == 0 ? 1 : (Height >> 1);
    00675                 Depth = (Depth >> 1) == 0 ? 1 : (Depth >> 1);
    00676
    00677                 Image->Mipmaps = ilNewImageFull(Width, Height, Depth, BaseImage->Bpp, BaseImage->Format, BaseImage->Type, NULL);
    00678                 if (Image->Mipmaps == NULL)
    00679                         return IL_FALSE;
    00680                 Image = Image->Mipmaps;
    00681
    00682                 // ilNewImage does not set these.
    00683                 Image->Format = BaseImage->Format;
    00684                 Image->Type = BaseImage->Type;
    00685                 // The origin should be in the upper left.
    00686                 Image->Origin = IL_ORIGIN_UPPER_LEFT;
    00687         }
    00688
    00689         return IL_TRUE;
    00690 }
    00691
    00692 #endif//IL_NO_VTF