summaryrefslogtreecommitdiff
path: root/DevIL/src-IL/src/il_ktx.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'DevIL/src-IL/src/il_ktx.cpp')
-rw-r--r--DevIL/src-IL/src/il_ktx.cpp271
1 files changed, 271 insertions, 0 deletions
diff --git a/DevIL/src-IL/src/il_ktx.cpp b/DevIL/src-IL/src/il_ktx.cpp
new file mode 100644
index 00000000..407ebb16
--- /dev/null
+++ b/DevIL/src-IL/src/il_ktx.cpp
@@ -0,0 +1,271 @@
+//-----------------------------------------------------------------------------
+//
+// ImageLib Sources
+// Copyright (C) 2000-2016 by Denton Woods
+// Last modified: 05/15/2016
+//
+// Filename: src-IL/src/il_ktx.c
+//
+// Description: Reads a Khronos Texture .ktx file
+//
+//-----------------------------------------------------------------------------
+
+
+#include "il_internal.h"
+#ifndef IL_NO_KTX
+#include "il_bits.h"
+
+
+ILboolean iIsValidKtx(void);
+ILboolean iLoadKtxInternal();
+
+
+#ifdef _MSC_VER
+#pragma pack(push, packed_struct, 1)
+#endif
+typedef struct KTX_HEAD
+{
+ ILubyte identifier[12];
+ ILuint endianness;
+ ILuint glType;
+ ILuint glTypeSize;
+ ILuint glFormat;
+ ILuint glInternalFormat;
+ ILuint glBaseInternalFormat;
+ ILuint pixelWidth;
+ ILuint pixelHeight;
+ ILuint pixelDepth;
+ ILuint numberOfArrayElements;
+ ILuint numberOfFaces;
+ ILuint numberOfMipmapLevels;
+ ILuint bytesOfKeyValueData;
+} IL_PACKSTRUCT KTX_HEAD;
+#ifdef _MSC_VER
+#pragma pack(pop, packed_struct)
+#endif
+
+
+// From GL/GL.h
+#define I_GL_BYTE 0x1400
+#define I_GL_UNSIGNED_BYTE 0x1401
+#define I_GL_SHORT 0x1402
+#define I_GL_UNSIGNED_SHORT 0x1403
+#define I_GL_INT 0x1404
+#define I_GL_UNSIGNED_INT 0x1405
+#define I_GL_FLOAT 0x1406
+//#define I_GL_2_BYTES 0x1407
+//#define I_GL_3_BYTES 0x1408
+//#define I_GL_4_BYTES 0x1409
+#define I_GL_DOUBLE 0x140A
+#define I_GL_ALPHA 0x1906
+#define I_GL_RGB 0x1907
+#define I_GL_RGBA 0x1908
+#define I_GL_LUMINANCE 0x1909
+#define I_GL_LUMINANCE_ALPHA 0x190A
+
+
+
+ILboolean ilIsValidKtx(ILconst_string FileName)
+{
+ ILHANDLE KtxFile;
+ ILboolean bKtx = IL_FALSE;
+
+ if (!iCheckExtension(FileName, IL_TEXT("ktx"))) {
+ ilSetError(IL_INVALID_EXTENSION);
+ return bKtx;
+ }
+
+ KtxFile = iopenr(FileName);
+ if (KtxFile == NULL) {
+ ilSetError(IL_COULD_NOT_OPEN_FILE);
+ return bKtx;
+ }
+
+ bKtx = ilIsValidKtxF(KtxFile);
+ icloser(KtxFile);
+
+ return bKtx;
+}
+
+
+ILboolean ilIsValidKtxF(ILHANDLE File)
+{
+ ILuint FirstPos;
+ ILboolean bRet;
+
+ iSetInputFile(File);
+ FirstPos = itell();
+ bRet = iIsValidKtx();
+ iseek(FirstPos, IL_SEEK_SET);
+
+ return bRet;
+}
+
+
+ILboolean ilIsValidKtxL(const void *Lump, ILuint Size)
+{
+ iSetInputLump(Lump, Size);
+ return iIsValidKtx();
+}
+
+
+ILboolean iIsValidKtx()
+{
+ ILubyte Signature[8];
+ ILint Read;
+
+ /*Read = iread(Signature, 1, 8);
+ iseek(-Read, IL_SEEK_CUR);*/
+
+ return IL_FALSE;
+}
+
+
+//! Reads a .ktx file
+ILboolean ilLoadKtx(ILconst_string FileName)
+{
+ ILHANDLE KtxFile;
+ ILboolean bKtx = IL_FALSE;
+
+ KtxFile = iopenr(FileName);
+ if (KtxFile == NULL) {
+ ilSetError(IL_COULD_NOT_OPEN_FILE);
+ return bKtx;
+ }
+
+ bKtx = ilLoadKtxF(KtxFile);
+ icloser(KtxFile);
+
+ return bKtx;
+}
+
+
+//! Reads an already-opened .ktx file
+ILboolean ilLoadKtxF(ILHANDLE File)
+{
+ ILuint FirstPos;
+ ILboolean bRet;
+
+ iSetInputFile(File);
+ FirstPos = itell();
+ bRet = iLoadKtxInternal();
+ iseek(FirstPos, IL_SEEK_SET);
+
+ return bRet;
+}
+
+
+//! Reads from a memory "lump" that contains a .ktx
+ILboolean ilLoadKtxL(const void *Lump, ILuint Size)
+{
+ iSetInputLump(Lump, Size);
+ return iLoadKtxInternal();
+}
+
+
+// Note: .Ktx support has not been tested yet!
+// https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/
+ILboolean iLoadKtxInternal()
+{
+ KTX_HEAD Header;
+ ILuint imageSize;
+ ILenum Format;
+ ILubyte Bpp;
+ ILubyte FileIdentifier[12] = {
+ //0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A
+ '«', 'K', 'T', 'X', ' ', '1', '1', '»', '\r', '\n', '\x1A', '\n'
+ };
+
+ if (iCurImage == NULL) {
+ ilSetError(IL_ILLEGAL_OPERATION);
+ return IL_FALSE;
+ }
+
+ /*Header.Width = GetLittleShort();
+ Header.Height = GetLittleShort();
+ Header.Dummy = GetLittleInt();*/
+
+ if (iread(Header.identifier, 1, 12) != 12)
+ return IL_FALSE;
+ Header.endianness = GetLittleUInt();
+ Header.glType = GetLittleUInt();
+ Header.glTypeSize = GetLittleUInt();
+ Header.glFormat = GetLittleUInt();
+ Header.glInternalFormat = GetLittleUInt();
+ Header.glBaseInternalFormat = GetLittleUInt();
+ Header.pixelWidth = GetLittleUInt();
+ Header.pixelHeight = GetLittleUInt();
+ Header.pixelDepth = GetLittleUInt();
+ Header.numberOfArrayElements = GetLittleUInt();
+ Header.numberOfFaces = GetLittleUInt();
+ Header.numberOfMipmapLevels = GetLittleUInt();
+ Header.bytesOfKeyValueData = GetLittleUInt();
+
+
+ if (memcmp(Header.identifier, FileIdentifier, 12) || Header.endianness != 0x04030201) {
+ ilSetError(IL_ILLEGAL_FILE_VALUE);
+ return IL_FALSE;
+ }
+ //@TODO: Additional types
+ if (Header.glType != I_GL_UNSIGNED_BYTE || Header.glTypeSize != 1) {
+ ilSetError(IL_ILLEGAL_FILE_VALUE);
+ return IL_FALSE;
+ }
+ //@TODO: Additional formats
+ if (Header.glFormat <= I_GL_ALPHA || Header.glFormat >= I_GL_LUMINANCE_ALPHA || 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) {
+ ilSetError(IL_ILLEGAL_FILE_VALUE);
+ return IL_FALSE;
+ }
+ //@TODO: Parse this data
+ if (iseek(Header.bytesOfKeyValueData, IL_SEEK_CUR))
+ return IL_FALSE;
+
+ switch (Header.glFormat)
+ {
+ case I_GL_LUMINANCE:
+ Bpp = 1;
+ Format = IL_LUMINANCE;
+ break;
+ case IL_LUMINANCE_ALPHA:
+ Bpp = 2;
+ Format = IL_LUMINANCE_ALPHA;
+ break;
+ case I_GL_RGB:
+ Bpp = 3;
+ Format = IL_RGB;
+ break;
+ case I_GL_RGBA:
+ Bpp = 4;
+ Format = IL_RGBA;
+ break;
+ default:
+ ilSetError(IL_ILLEGAL_FILE_VALUE);
+ return IL_FALSE;
+ }
+
+ //@TODO: More than just RGBA
+ if (!ilTexImage(Header.pixelWidth, Header.pixelHeight, 1, Bpp, Format, IL_UNSIGNED_BYTE, NULL)) {
+ return IL_FALSE;
+ }
+ iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
+
+ imageSize = GetLittleUInt();
+ if (imageSize != Header.pixelWidth * Header.pixelHeight * Bpp) {
+ ilSetError(IL_ILLEGAL_FILE_VALUE);
+ return IL_FALSE;
+ }
+
+ if (iread(iCurImage->Data, Bpp, Header.pixelWidth * Header.pixelHeight) != Header.pixelWidth * Header.pixelHeight)
+ return IL_FALSE;
+
+ return ilFixImage();
+}
+
+
+#endif//IL_NO_KTX