ILboolean iD3D8CreateMipmaps(IDirect3DTexture8 *Texture, ILimage *Image) { D3DLOCKED_RECT Rect; D3DSURFACE_DESC Desc; ILuint NumMips, Width, Height, i; ILimage *CurImage, *MipImage, *Temp; NumMips = IDirect3DTexture8_GetLevelCount(Texture); Width = Image->Width; Height = Image->Height; CurImage = ilGetCurImage(); MipImage = ilCopyImage_(CurImage); ilSetCurImage(MipImage); if (!iluBuildMipmaps()) { ilCloseImage(MipImage); ilSetCurImage(CurImage); return IL_FALSE; } ilSetCurImage(CurImage); Temp = MipImage->Mipmaps; // Counts the base texture as 1. for (i = 1; i < NumMips && Temp != NULL; i++) { if (FAILED(IDirect3DTexture8_LockRect(Texture, i, &Rect, NULL, 0))) return IL_FALSE; Width = IL_MAX(1, Width / 2); Height = IL_MAX(1, Height / 2); IDirect3DTexture8_GetLevelDesc(Texture, i, &Desc); if (Desc.Width != Width || Desc.Height != Height) { IDirect3DTexture8_UnlockRect(Texture, i); return IL_FALSE; } memcpy(Rect.pBits, Temp->Data, Temp->SizeOfData); IDirect3DTexture8_UnlockRect(Texture, i); Temp = Temp->Next; } ilCloseImage(MipImage); return IL_TRUE; }
ILboolean iD3D9CreateMipmaps(IDirect3DTexture9 *Texture, ILimage *Image) { D3DLOCKED_RECT Rect; D3DSURFACE_DESC Desc; ILuint NumMips, Width, Height, i; ILimage *CurImage, *MipImage, *Temp; ILenum DXTCFormat; ILuint Size; ILubyte *Buffer; ILboolean useDXTC = IL_FALSE; NumMips = IDirect3DTexture9_GetLevelCount(Texture); Width = Image->Width; Height = Image->Height; if (NumMips == 1) return IL_TRUE; CurImage = ilGetCurImage(); MipImage = Image; if (MipImage->NumMips != NumMips-1) { MipImage = ilCopyImage_(Image); ilSetCurImage(MipImage); if (!iluBuildMipmaps()) { ilCloseImage(MipImage); ilSetCurImage(CurImage); return IL_FALSE; } } // ilSetCurImage(CurImage); Temp = MipImage->Mipmaps; if (ilutGetBoolean(ILUT_D3D_USE_DXTC) && FormatsDX9supported[3] && FormatsDX9supported[4] && FormatsDX9supported[5]) useDXTC = IL_TRUE; // Counts the base texture as 1. for (i = 1; i < NumMips && Temp != NULL; i++) { ilSetCurImage(Temp); if (FAILED(IDirect3DTexture9_LockRect(Texture, i, &Rect, NULL, 0))) return IL_FALSE; Width = IL_MAX(1, Width / 2); Height = IL_MAX(1, Height / 2); IDirect3DTexture9_GetLevelDesc(Texture, i, &Desc); if (Desc.Width != Width || Desc.Height != Height) { IDirect3DTexture9_UnlockRect(Texture, i); return IL_FALSE; } if (useDXTC) { if (Temp->DxtcData != NULL && Temp->DxtcSize != 0) { memcpy(Rect.pBits, Temp->DxtcData, Temp->DxtcSize); } else if (ilutGetBoolean(ILUT_D3D_GEN_DXTC)) { DXTCFormat = ilutGetInteger(ILUT_DXTC_FORMAT); Size = ilGetDXTCData(NULL, 0, DXTCFormat); if (Size != 0) { Buffer = (ILubyte*)ialloc(Size); if (Buffer == NULL) { IDirect3DTexture9_UnlockRect(Texture, i); return IL_FALSE; } Size = ilGetDXTCData(Buffer, Size, DXTCFormat); if (Size == 0) { ifree(Buffer); IDirect3DTexture9_UnlockRect(Texture, i); return IL_FALSE; } memcpy(Rect.pBits, Buffer, Size); } else { IDirect3DTexture9_UnlockRect(Texture, i); return IL_FALSE; } } else { IDirect3DTexture9_UnlockRect(Texture, i); return IL_FALSE; } } else memcpy(Rect.pBits, Temp->Data, Temp->SizeOfData); IDirect3DTexture9_UnlockRect(Texture, i); Temp = Temp->Next; } if (MipImage != Image) ilCloseImage(MipImage); ilSetCurImage(CurImage); return IL_TRUE; }
// Internal function used to load the UTX. ILboolean iLoadUtxInternal(void) { UTXHEADER Header; UTXENTRYNAME *NameEntries; UTXEXPORTTABLE *ExportTable; UTXIMPORTTABLE *ImportTable; UTXPALETTE *Palettes; ILimage *Image; ILuint NumPal = 0, i, j = 0; ILint Name; ILubyte Type; ILint Val; ILint Size; ILint Width, Height, PalEntry; ILboolean BaseCreated = IL_FALSE, HasPal; ILuint Pos; ILint Format; ILubyte *CompData = NULL; ILubyte ExtraData[9]; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } if (!GetUtxHead(&Header)) return IL_FALSE; if (!CheckUtxHead(&Header)) return IL_FALSE; // Now we grab the name table. NameEntries = GetUtxNameTable(&Header); if (NameEntries == NULL) return IL_FALSE; // Then we get the export table. ExportTable = GetUtxExportTable(&Header); if (ExportTable == NULL) { UtxDestroyNameEntries(NameEntries, &Header); return IL_FALSE; } // Then the last table is the import table. ImportTable = GetUtxImportTable(&Header); if (ImportTable == NULL) { UtxDestroyNameEntries(NameEntries, &Header); UtxDestroyExportTable(ExportTable, &Header); return IL_FALSE; } for (i = 0; i < Header.ExportCount; i++) { if (!strcmp(NameEntries[ImportTable[ExportTable[i].Class].ObjectName].Name, "Palette")) NumPal++; } if (NumPal == 0) //@TODO: Take care of UTX files without paletted data. return IL_FALSE; Palettes = (UTXPALETTE*)ialloc(NumPal * sizeof(UTXPALETTE)); if (Palettes == NULL) { UtxDestroyNameEntries(NameEntries, &Header); UtxDestroyExportTable(ExportTable, &Header); UtxDestroyImportTable(ImportTable, &Header); return IL_FALSE; } NumPal = 0; for (i = 0; i < Header.ExportCount; i++) { if (!strcmp(NameEntries[ImportTable[ExportTable[i].Class].ObjectName].Name, "Palette")) { //Palettes[i].Name = strdup(NameEntries[ExportTable[i].ObjectName].Name); Palettes[NumPal].Name = i;//ExportTable[i].ObjectName; iseek(ExportTable[NumPal].SerialOffset, IL_SEEK_SET); Name = igetc(); // Skip the 2. Palettes[NumPal].Count = UtxReadCompactInteger(); Palettes[NumPal].Pal = (ILubyte*)ialloc(Palettes[NumPal].Count * 4); if (/*Palettes[NumPal].Name == NULL || */Palettes[NumPal].Pal == NULL) { UtxDestroyNameEntries(NameEntries, &Header); UtxDestroyExportTable(ExportTable, &Header); UtxDestroyImportTable(ImportTable, &Header); UtxDestroyPalettes(Palettes, NumPal); return IL_FALSE; } if (iread(Palettes[NumPal].Pal, Palettes[NumPal].Count * 4, 1) != 1) //@TODO: Deallocations here! return IL_FALSE; NumPal++; } } for (i = 0; i < Header.ExportCount; i++) { if (!strcmp(NameEntries[ImportTable[ExportTable[i].Class].ObjectName].Name, "Texture")) { iseek(ExportTable[i].SerialOffset, IL_SEEK_SET); Width = -1; Height = -1; PalEntry = NumPal; HasPal = IL_FALSE; Format = -1; ++j; j = j; do { Pos = itell(); Name = UtxReadCompactInteger(); if (!strcmp(NameEntries[Name].Name, "None")) break; Type = igetc(); Size = (Type & 0x70) >> 4; if (/*Name == 0 && */Type == 0xA2) igetc(); // Byte is 1 here... switch (Type & 0x0F) { case 1: Val = igetc(); break; case 2: Val = GetLittleUInt(); break; case 3: // Boolean value is in the info byte. igetc(); break; case 4: GetLittleFloat(); break; case 5: case 6: Val = itell(); Val = UtxReadCompactInteger(); break; case 10: Val = igetc(); switch (Size) { case 0: iseek(1, IL_SEEK_CUR); break; case 1: iseek(2, IL_SEEK_CUR); break; case 2: iseek(4, IL_SEEK_CUR); break; case 3: iseek(12, IL_SEEK_CUR); break; } break; default: // Uhm... Val = Val; break; } //@TODO: What should we do if Name >= Header.NameCount? if ((ILuint)Name < Header.NameCount) { if (!strcmp(NameEntries[Name].Name, "Palette")) { Val--; if (HasPal == IL_FALSE) { for (PalEntry = 0; (ILuint)PalEntry < NumPal; PalEntry++) { if (Val == Palettes[PalEntry].Name) { HasPal = IL_TRUE; break; } } } } if (!strcmp(NameEntries[Name].Name, "Format")) if (Format == -1) Format = Val; if (!strcmp(NameEntries[Name].Name, "USize")) if (Width == -1) Width = Val; if (!strcmp(NameEntries[Name].Name, "VSize")) if (Height == -1) Height = Val; } } while (!ieof()); if (Format == -1) Format = UTX_P8; if (Width == -1 || Height == -1 || (PalEntry == NumPal && Format != UTX_DXT1) || (Format != UTX_P8 && Format != UTX_DXT1)) return IL_FALSE; if (BaseCreated == IL_FALSE) { BaseCreated = IL_TRUE; ilTexImage(Width, Height, 1, UtxFormatToBpp(Format), UtxFormatToDevIL(Format), IL_UNSIGNED_BYTE, NULL); Image = iCurImage; } else { Image->Next = ilNewImageFull(Width, Height, 1, UtxFormatToBpp(Format), UtxFormatToDevIL(Format), IL_UNSIGNED_BYTE, NULL); if (Image->Next == NULL) return IL_FALSE; Image = Image->Next; } iseek(5, IL_SEEK_CUR); UtxReadCompactInteger(); switch (Format) { case UTX_P8: Image->Pal.PalSize = Palettes[PalEntry].Count * 4; Image->Pal.Palette = (ILubyte*)ialloc(Image->Pal.PalSize); if (Image->Pal.Palette == NULL) //@TODO: Do all the deallocations needed here! return IL_FALSE; memcpy(Image->Pal.Palette, Palettes[PalEntry].Pal, Image->Pal.PalSize); Image->Pal.PalType = IL_PAL_RGBA32; if (iread(Image->Data, Image->SizeOfData, 1) != 1) return IL_FALSE; //@TODO: Deallocations... break; case UTX_DXT1: // // // HACK!!! // // //igetc(); //ExtraData[0] = igetc(); //if (ExtraData[0] == 0x0C) //iseek(8, IL_SEEK_CUR); // iread(ExtraData+1, 8, 1); //else //iseek(7, IL_SEEK_CUR); // iread(ExtraData+1, 7, 1); //if (igetc() == 0x80) // igetc(); Image->DxtcSize = IL_MAX(Image->Width * Image->Height / 2, 8); CompData = (ILubyte*)ialloc(Image->DxtcSize); if (CompData == NULL) //@TODO: Do all the deallocations needed here! return IL_FALSE; if (iread(CompData, Image->DxtcSize, 1) != 1) { ifree(CompData); return IL_FALSE; //@TODO: Deallocations... } // Keep a copy of the DXTC data if the user wants it. if (ilGetInteger(IL_KEEP_DXTC_DATA) == IL_TRUE) { Image->DxtcData = CompData; Image->DxtcFormat = IL_DXT1; CompData = NULL; } if (DecompressDXT1(Image, CompData) == IL_FALSE) { ifree(CompData); return IL_FALSE; } ifree(CompData); break; } Image->Origin = IL_ORIGIN_UPPER_LEFT; } }