summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenton Woods <denton.woods@gmail.com>2017-01-21 22:39:42 -0600
committerDenton Woods <denton.woods@gmail.com>2017-01-21 22:39:42 -0600
commite7cd401ec8859a788f5847cff793b59e2f929168 (patch)
tree19848c2ff0ecaea2c969199e4f1c6f8a10c8bd91
parentd7a5c33776635e92548c8d5494d1c8060318144c (diff)
downloaddevil-e7cd401ec8859a788f5847cff793b59e2f929168.tar.gz
- Added support for uncompressed KTX mipmaps
-rw-r--r--DevIL/src-IL/src/il_dds.cpp24
-rw-r--r--DevIL/src-IL/src/il_ktx.cpp104
-rw-r--r--DevIL/src-IL/src/il_states.cpp3
3 files changed, 109 insertions, 22 deletions
diff --git a/DevIL/src-IL/src/il_dds.cpp b/DevIL/src-IL/src/il_dds.cpp
index daaec723..46e64344 100644
--- a/DevIL/src-IL/src/il_dds.cpp
+++ b/DevIL/src-IL/src/il_dds.cpp
@@ -409,33 +409,40 @@ ILboolean iLoadDdsInternal()
CompData = NULL;
Image = NULL;
- if (iCurImage == NULL) {
+ if (iCurImage == NULL)
+ {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
- if (!iGetDdsHead(&Head)) {
+ if (!iGetDdsHead(&Head))
+ {
ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
}
- if (!iCheckDds(&Head)) {
+ if (!iCheckDds(&Head))
+ {
ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
}
BlockSize = DecodePixelFormat(&CompFormat);
- if (CompFormat == PF_UNKNOWN) {
+ if (CompFormat == PF_UNKNOWN)
+ {
ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
}
- if (CompFormat == PF_DX10) {
+ if (CompFormat == PF_DX10)
+ {
IsDXT10 = IL_TRUE;
- if (!iGetDXT10Head(&HeadDXT10)) {
+ if (!iGetDXT10Head(&HeadDXT10))
+ {
ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
}
- if (!iCheckDxt10(&HeadDXT10)) {
+ if (!iCheckDxt10(&HeadDXT10))
+ {
ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
}
@@ -1121,7 +1128,8 @@ ILboolean ReadMipmaps(ILuint CompFormat, ILboolean IsDXT10)
}
LastLinear = Head.LinearSize;
- for (i = 0; i < Head.MipMapCount - 1; i++) {
+ for (i = 0; i < Head.MipMapCount - 1; i++)
+ {
Depth = Depth / 2;
Width = Width / 2;
Height = Height / 2;
diff --git a/DevIL/src-IL/src/il_ktx.cpp b/DevIL/src-IL/src/il_ktx.cpp
index c424810a..7871ac7c 100644
--- a/DevIL/src-IL/src/il_ktx.cpp
+++ b/DevIL/src-IL/src/il_ktx.cpp
@@ -19,6 +19,7 @@
ILboolean iIsValidKtx(void);
ILboolean iLoadKtxInternal();
+ILboolean iKtxReadMipmaps(ILboolean Compressed, ILuint NumMips);
#ifdef _MSC_VER
@@ -217,7 +218,6 @@ ILboolean iLoadKtxInternal()
Header.numberOfFaces = GetLittleUInt();
Header.numberOfMipmapLevels = GetLittleUInt();
Header.bytesOfKeyValueData = GetLittleUInt();
- imageSize = GetLittleUInt();
if (memcmp(Header.identifier, FileIdentifier, 12) || Header.endianness != 0x04030201) {
ilSetError(IL_ILLEGAL_FILE_VALUE);
@@ -229,13 +229,15 @@ ILboolean iLoadKtxInternal()
return IL_FALSE;
}
//@TODO: Really needed?
- /*if (Header.glInternalFormat != Header.glFormat || Header.glBaseInternalFormat != Header.glFormat) {
+ /*if (Header.glInternalFormat != Header.glFormat || Header.glBaseInternalFormat != Header.glFormat)
+ {
ilSetError(IL_ILLEGAL_FILE_VALUE);
return IL_FALSE;
}*/
//@TODO: Mipmaps, etc.
- if (Header.numberOfArrayElements != 0 || Header.numberOfFaces != 1 || Header.numberOfMipmapLevels != 1) {
+ if (Header.numberOfArrayElements != 0 || Header.numberOfFaces != 1 /*|| Header.numberOfMipmapLevels != 1*/)
+ {
ilSetError(IL_ILLEGAL_FILE_VALUE);
return IL_FALSE;
}
@@ -289,11 +291,6 @@ ILboolean iLoadKtxInternal()
}
}
- if (!ilTexImage(Header.pixelWidth, Header.pixelHeight, 1, Bpp, Format, Type, NULL)) {
- return IL_FALSE;
- }
- iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
-
if (!Compressed)
{
//@TODO: Additional types
@@ -312,15 +309,28 @@ ILboolean iLoadKtxInternal()
return IL_FALSE;
}
- if (imageSize != Header.pixelWidth * Header.pixelHeight * Bpp * Bpc) {
+ if (!ilTexImage(Header.pixelWidth, Header.pixelHeight, 1, Bpp, Format, Type, NULL))
+ return IL_FALSE;
+
+ if (!iKtxReadMipmaps(Compressed, Header.numberOfMipmapLevels))
+ return IL_FALSE;
+
+ //iCurImage->Origin = IL_ORIGIN_LOWER_LEFT; //@TODO: Correct for all?
+ }
+ else // Compressed formats require different handling
+ {
+ //@TODO: Add support for compressed mipmaps
+ if (Header.numberOfMipmapLevels != 1)
+ {
ilSetError(IL_ILLEGAL_FILE_VALUE);
return IL_FALSE;
}
- if (iread(iCurImage->Data, Bpp*Bpc, Header.pixelWidth * Header.pixelHeight) != Header.pixelWidth * Header.pixelHeight)
+ imageSize = GetLittleUInt();
+
+ if (!ilTexImage(Header.pixelWidth, Header.pixelHeight, 1, Bpp, Format, Type, NULL))
return IL_FALSE;
- }
- else { // Compressed formats require different handling
+
switch (Header.glInternalFormat)
{
case I_GL_ETC1_RGB8_OES:
@@ -359,11 +369,79 @@ ILboolean iLoadKtxInternal()
ifree(FullBuffer);
break;
}
- //return IL_FALSE;
+
+ iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; //@TODO: Correct for all?
}
return ilFixImage();
}
+ILboolean iKtxReadMipmaps(ILboolean Compressed, ILuint NumMips)
+{
+ ILimage *Image = iCurImage;
+ ILuint Width = iCurImage->Width, Height = iCurImage->Height;
+ ILuint imageSize, Padding, Pos;
+
+ for (ILuint Mip = 0; Mip < NumMips; Mip++)
+ {
+ imageSize = GetLittleUInt();
+ Padding = 3 - ((Image->Bps + 3) % 4);
+
+ if (imageSize != Image->SizeOfData + Padding*Image->Height)
+ {
+ ilSetError(IL_ILLEGAL_FILE_VALUE);
+ goto mip_fail;
+ }
+
+ // Note: The KTX spec at https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/
+ // seems to imply dword-alignment of the entire image.
+ if (Image->Bps % 4 == 0) // Required to be dword-aligned
+ {
+ if (iread(Image->Data, 1, Image->SizeOfData) != Image->SizeOfData)
+ return IL_FALSE;
+ }
+ else // Since not dword-aligned, have to read each line separately.
+ {
+ Pos = 0;
+ for (ILuint h = 0; h < Height; h++)
+ {
+ if (iread(&Image->Data[Pos], 1, Image->Bps) != Image->Bps)
+ return IL_FALSE;
+ iseek(Padding, IL_SEEK_CUR);
+ Pos += Image->Bps;
+ }
+
+ }
+
+ Image->Origin = IL_ORIGIN_LOWER_LEFT; //@TODO: Correct for all?
+ Width = Width / 2;
+ Height = Height / 2;
+
+ if (Mip < NumMips - 1)
+ {
+ Image->Mipmaps = ilNewImage(Width, Height, 1, Image->Bpp, Image->Bpc);
+ if (Image->Mipmaps == NULL)
+ goto mip_fail;
+ Image->Mipmaps->Format = Image->Format;
+ Image->Mipmaps->Type = Image->Type;
+ Image = Image->Mipmaps;
+ }
+ }
+
+ return IL_TRUE;
+
+mip_fail:
+ Image = iCurImage;
+ ILimage *StartImage = Image->Mipmaps, *TempImage;
+ while (StartImage) {
+ TempImage = StartImage;
+ StartImage = StartImage->Mipmaps;
+ ifree(TempImage);
+ }
+
+ Image->Mipmaps = NULL;
+ return IL_FALSE;
+}
+
#endif//IL_NO_KTX
diff --git a/DevIL/src-IL/src/il_states.cpp b/DevIL/src-IL/src/il_states.cpp
index 974ebe02..752624bd 100644
--- a/DevIL/src-IL/src/il_states.cpp
+++ b/DevIL/src-IL/src/il_states.cpp
@@ -419,7 +419,8 @@ void ILAPIENTRY ilGetIntegerv(ILenum Mode, ILint *Param)
*Param = 0;
- switch (Mode) {
+ switch (Mode)
+ {
// Integer values
case IL_COMPRESS_MODE:
*Param = ilStates[ilCurrentPos].ilCompression;