summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenton Woods <denton.woods@gmail.com>2017-01-21 16:54:19 -0600
committerDenton Woods <denton.woods@gmail.com>2017-01-21 16:54:19 -0600
commit625d54d8f44d16b243f26886d0b9c95cf24c9971 (patch)
tree8f0197b535aa46ff04b69a23f1ebd1d88c2fea02
parent4a2d7822f12c82e6c32b9b51d52c4bdc13ca9375 (diff)
downloaddevil-625d54d8f44d16b243f26886d0b9c95cf24c9971.tar.gz
- Added support for reading .pam files
- Starting support for DXT10 .dds files
-rw-r--r--DevIL/src-IL/include/il_dds.h162
-rw-r--r--DevIL/src-IL/include/il_pnm.h11
-rw-r--r--DevIL/src-IL/src/il_dds.cpp411
-rw-r--r--DevIL/src-IL/src/il_dicom.cpp2
-rw-r--r--DevIL/src-IL/src/il_io.cpp6
-rw-r--r--DevIL/src-IL/src/il_pnm.cpp200
6 files changed, 682 insertions, 110 deletions
diff --git a/DevIL/src-IL/include/il_dds.h b/DevIL/src-IL/include/il_dds.h
index 42018ab1..d7db8e53 100644
--- a/DevIL/src-IL/include/il_dds.h
+++ b/DevIL/src-IL/include/il_dds.h
@@ -52,6 +52,21 @@ typedef struct DDSHEAD
#endif
+#ifdef _WIN32
+#pragma pack(push, dxt10_struct, 1)
+#endif
+typedef struct DXT10HEAD
+{
+ ILuint dxgiFormat;
+ ILuint resourceDimension;
+ ILuint miscFlag;
+ ILuint arraySize;
+ ILuint miscFlags2;
+} IL_PACKSTRUCT DXT10HEAD;
+#ifdef _WIN32
+#pragma pack(pop, dxt10_struct)
+#endif
+
// use cast to struct instead of RGBA_MAKE as struct is
// much
@@ -162,9 +177,145 @@ enum PixFormat
PF_R32F,
PF_G32R32F,
PF_A32B32G32R32F,
+ PF_DX10,
PF_UNKNOWN = 0xFF
};
+// From https://msdn.microsoft.com/en-us/library/windows/desktop/bb173059(v=vs.85).aspx
+typedef enum DXGI_FORMAT
+{
+ DXGI_FORMAT_UNKNOWN = 0,
+ DXGI_FORMAT_R32G32B32A32_TYPELESS = 1,
+ DXGI_FORMAT_R32G32B32A32_FLOAT = 2,
+ DXGI_FORMAT_R32G32B32A32_UINT = 3,
+ DXGI_FORMAT_R32G32B32A32_SINT = 4,
+ DXGI_FORMAT_R32G32B32_TYPELESS = 5,
+ DXGI_FORMAT_R32G32B32_FLOAT = 6,
+ DXGI_FORMAT_R32G32B32_UINT = 7,
+ DXGI_FORMAT_R32G32B32_SINT = 8,
+ DXGI_FORMAT_R16G16B16A16_TYPELESS = 9,
+ DXGI_FORMAT_R16G16B16A16_FLOAT = 10,
+ DXGI_FORMAT_R16G16B16A16_UNORM = 11,
+ DXGI_FORMAT_R16G16B16A16_UINT = 12,
+ DXGI_FORMAT_R16G16B16A16_SNORM = 13,
+ DXGI_FORMAT_R16G16B16A16_SINT = 14,
+ DXGI_FORMAT_R32G32_TYPELESS = 15,
+ DXGI_FORMAT_R32G32_FLOAT = 16,
+ DXGI_FORMAT_R32G32_UINT = 17,
+ DXGI_FORMAT_R32G32_SINT = 18,
+ DXGI_FORMAT_R32G8X24_TYPELESS = 19,
+ DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20,
+ DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21,
+ DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22,
+ DXGI_FORMAT_R10G10B10A2_TYPELESS = 23,
+ DXGI_FORMAT_R10G10B10A2_UNORM = 24,
+ DXGI_FORMAT_R10G10B10A2_UINT = 25,
+ DXGI_FORMAT_R11G11B10_FLOAT = 26,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS = 27,
+ DXGI_FORMAT_R8G8B8A8_UNORM = 28,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29,
+ DXGI_FORMAT_R8G8B8A8_UINT = 30,
+ DXGI_FORMAT_R8G8B8A8_SNORM = 31,
+ DXGI_FORMAT_R8G8B8A8_SINT = 32,
+ DXGI_FORMAT_R16G16_TYPELESS = 33,
+ DXGI_FORMAT_R16G16_FLOAT = 34,
+ DXGI_FORMAT_R16G16_UNORM = 35,
+ DXGI_FORMAT_R16G16_UINT = 36,
+ DXGI_FORMAT_R16G16_SNORM = 37,
+ DXGI_FORMAT_R16G16_SINT = 38,
+ DXGI_FORMAT_R32_TYPELESS = 39,
+ DXGI_FORMAT_D32_FLOAT = 40,
+ DXGI_FORMAT_R32_FLOAT = 41,
+ DXGI_FORMAT_R32_UINT = 42,
+ DXGI_FORMAT_R32_SINT = 43,
+ DXGI_FORMAT_R24G8_TYPELESS = 44,
+ DXGI_FORMAT_D24_UNORM_S8_UINT = 45,
+ DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46,
+ DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47,
+ DXGI_FORMAT_R8G8_TYPELESS = 48,
+ DXGI_FORMAT_R8G8_UNORM = 49,
+ DXGI_FORMAT_R8G8_UINT = 50,
+ DXGI_FORMAT_R8G8_SNORM = 51,
+ DXGI_FORMAT_R8G8_SINT = 52,
+ DXGI_FORMAT_R16_TYPELESS = 53,
+ DXGI_FORMAT_R16_FLOAT = 54,
+ DXGI_FORMAT_D16_UNORM = 55,
+ DXGI_FORMAT_R16_UNORM = 56,
+ DXGI_FORMAT_R16_UINT = 57,
+ DXGI_FORMAT_R16_SNORM = 58,
+ DXGI_FORMAT_R16_SINT = 59,
+ DXGI_FORMAT_R8_TYPELESS = 60,
+ DXGI_FORMAT_R8_UNORM = 61,
+ DXGI_FORMAT_R8_UINT = 62,
+ DXGI_FORMAT_R8_SNORM = 63,
+ DXGI_FORMAT_R8_SINT = 64,
+ DXGI_FORMAT_A8_UNORM = 65,
+ DXGI_FORMAT_R1_UNORM = 66,
+ DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67,
+ DXGI_FORMAT_R8G8_B8G8_UNORM = 68,
+ DXGI_FORMAT_G8R8_G8B8_UNORM = 69,
+ DXGI_FORMAT_BC1_TYPELESS = 70,
+ DXGI_FORMAT_BC1_UNORM = 71,
+ DXGI_FORMAT_BC1_UNORM_SRGB = 72,
+ DXGI_FORMAT_BC2_TYPELESS = 73,
+ DXGI_FORMAT_BC2_UNORM = 74,
+ DXGI_FORMAT_BC2_UNORM_SRGB = 75,
+ DXGI_FORMAT_BC3_TYPELESS = 76,
+ DXGI_FORMAT_BC3_UNORM = 77,
+ DXGI_FORMAT_BC3_UNORM_SRGB = 78,
+ DXGI_FORMAT_BC4_TYPELESS = 79,
+ DXGI_FORMAT_BC4_UNORM = 80,
+ DXGI_FORMAT_BC4_SNORM = 81,
+ DXGI_FORMAT_BC5_TYPELESS = 82,
+ DXGI_FORMAT_BC5_UNORM = 83,
+ DXGI_FORMAT_BC5_SNORM = 84,
+ DXGI_FORMAT_B5G6R5_UNORM = 85,
+ DXGI_FORMAT_B5G5R5A1_UNORM = 86,
+ DXGI_FORMAT_B8G8R8A8_UNORM = 87,
+ DXGI_FORMAT_B8G8R8X8_UNORM = 88,
+ DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89,
+ DXGI_FORMAT_B8G8R8A8_TYPELESS = 90,
+ DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91,
+ DXGI_FORMAT_B8G8R8X8_TYPELESS = 92,
+ DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93,
+ DXGI_FORMAT_BC6H_TYPELESS = 94,
+ DXGI_FORMAT_BC6H_UF16 = 95,
+ DXGI_FORMAT_BC6H_SF16 = 96,
+ DXGI_FORMAT_BC7_TYPELESS = 97,
+ DXGI_FORMAT_BC7_UNORM = 98,
+ DXGI_FORMAT_BC7_UNORM_SRGB = 99,
+ DXGI_FORMAT_AYUV = 100,
+ DXGI_FORMAT_Y410 = 101,
+ DXGI_FORMAT_Y416 = 102,
+ DXGI_FORMAT_NV12 = 103,
+ DXGI_FORMAT_P010 = 104,
+ DXGI_FORMAT_P016 = 105,
+ DXGI_FORMAT_420_OPAQUE = 106,
+ DXGI_FORMAT_YUY2 = 107,
+ DXGI_FORMAT_Y210 = 108,
+ DXGI_FORMAT_Y216 = 109,
+ DXGI_FORMAT_NV11 = 110,
+ DXGI_FORMAT_AI44 = 111,
+ DXGI_FORMAT_IA44 = 112,
+ DXGI_FORMAT_P8 = 113,
+ DXGI_FORMAT_A8P8 = 114,
+ DXGI_FORMAT_B4G4R4A4_UNORM = 115,
+ DXGI_FORMAT_P208 = 130,
+ DXGI_FORMAT_V208 = 131,
+ DXGI_FORMAT_V408 = 132,
+ DXGI_FORMAT_FORCE_UINT = 0xffffffff
+} DXGI_FORMAT;
+
+// From https://msdn.microsoft.com/en-us/library/windows/desktop/bb172411(v=vs.85).aspx
+typedef enum D3D10_RESOURCE_DIMENSION
+{
+ D3D10_RESOURCE_DIMENSION_UNKNOWN = 0,
+ D3D10_RESOURCE_DIMENSION_BUFFER = 1,
+ D3D10_RESOURCE_DIMENSION_TEXTURE1D = 2,
+ D3D10_RESOURCE_DIMENSION_TEXTURE2D = 3,
+ D3D10_RESOURCE_DIMENSION_TEXTURE3D = 4
+} D3D10_RESOURCE_DIMENSION;
+
#define CUBEMAP_SIDES 6
#ifdef __cplusplus
@@ -175,16 +326,17 @@ extern "C" {
ILboolean iLoadDdsInternal(void);
ILboolean iIsValidDds(void);
ILboolean iCheckDds(DDSHEAD *Head);
-void AdjustVolumeTexture(DDSHEAD *Head, ILuint CompFormat);
-ILboolean ReadData();
-ILboolean AllocImage(ILuint CompFormat);
-ILboolean DdsDecompress(ILuint CompFormat);
-ILboolean ReadMipmaps(ILuint CompFormat);
+void AdjustVolumeTexture(DDSHEAD *Head, ILuint CompFormat, ILboolean IsDXT10);
+ILboolean ReadData(ILuint CompFormat, ILboolean IsDXT10);
+ILboolean AllocImage(ILuint CompFormat, ILboolean IsDXT10);
+ILboolean DdsDecompress(ILuint CompFormat, ILboolean IsDXT10);
+ILboolean ReadMipmaps(ILuint CompFormat, ILboolean IsDXT10);
ILuint DecodePixelFormat(ILuint *CompFormat);
void DxtcReadColor(ILushort Data, Color8888* Out);
void DxtcReadColors(const ILubyte* Data, Color8888* Out);
ILboolean DecompressARGB(ILuint CompFormat);
ILboolean DecompressARGB16(ILuint CompFormat);
+ILboolean DecompressARGBDX10(ILuint CompFormat);
ILboolean DecompressDXT1(ILimage *lImage, ILubyte *lCompData);
ILboolean DecompressDXT2(ILimage *lImage, ILubyte *lCompData);
ILboolean DecompressDXT3(ILimage *lImage, ILubyte *lCompData);
diff --git a/DevIL/src-IL/include/il_pnm.h b/DevIL/src-IL/include/il_pnm.h
index cce04a87..4ac1d0f2 100644
--- a/DevIL/src-IL/include/il_pnm.h
+++ b/DevIL/src-IL/include/il_pnm.h
@@ -15,6 +15,10 @@
#define PPMPGM_H
#include "il_internal.h"
+#include <string>
+
+using namespace std;
+
#define IL_PBM_ASCII 0x0001
#define IL_PGM_ASCII 0x0002
@@ -22,14 +26,19 @@
#define IL_PBM_BINARY 0x0004
#define IL_PGM_BINARY 0x0005
#define IL_PPM_BINARY 0x0006
+#define IL_PAM 0x0007
+
+enum PamTuples { PAM_BW = 1, PAM_GRAY, PAM_RGB, PAM_BW_ALPHA, PAM_GRAY_ALPHA, PAM_RGB_ALPHA };
typedef struct PPMINFO
{
ILenum Type;
ILuint Width;
ILuint Height;
+ ILuint Depth;
ILuint MaxColour;
ILubyte Bpp;
+ ILubyte TuplType;
} PPMINFO;
ILboolean iIsValidPnm(void);
@@ -39,8 +48,10 @@ ILboolean iSavePnmInternal(void);
ILimage *ilReadAsciiPpm(PPMINFO *Info);
ILimage *ilReadBinaryPpm(PPMINFO *Info);
ILimage *ilReadBitPbm(PPMINFO *Info);
+ILboolean ilReadPam(void);
ILboolean iGetWord(ILboolean);
void PbmMaximize(ILimage *Image);
+ILint DecodeTupleType(string &TupleStr);
#endif//PPMPGM_H
diff --git a/DevIL/src-IL/src/il_dds.cpp b/DevIL/src-IL/src/il_dds.cpp
index 580faed1..daaec723 100644
--- a/DevIL/src-IL/src/il_dds.cpp
+++ b/DevIL/src-IL/src/il_dds.cpp
@@ -4,7 +4,7 @@
// Copyright (C) 2000-2017 by Denton Woods
// Last modified: 02/28/2009
//
-// Filename: src-IL/src/il_dds.c
+// Filename: src-IL/src/il_dds.cpp
//
// Description: Reads from a DirectDraw Surface (.dds) file.
//
@@ -30,7 +30,9 @@
// Global variables
+//@TODO: Move these out of global space
static DDSHEAD Head; // Image header
+static DXT10HEAD HeadDXT10; // DirectX 10 extension header
static ILubyte *CompData = NULL; // Compressed data
static ILuint CompSize; // Compressed size
//static ILuint CompFormat; // Compressed format
@@ -134,6 +136,19 @@ ILboolean iGetDdsHead(DDSHEAD *Header)
}
+// Internal function used to get the DirectX 10 DDS header extension (24 bytes)
+ILboolean iGetDXT10Head(DXT10HEAD *Header)
+{
+ Header->dxgiFormat = GetLittleUInt();
+ Header->resourceDimension = GetLittleUInt();
+ Header->miscFlag = GetLittleUInt();
+ Header->arraySize = GetLittleUInt();
+ Header->miscFlags2 = GetLittleUInt();
+
+ return IL_TRUE;
+}
+
+
// Internal function to get the header and check it.
ILboolean iIsValidDds()
{
@@ -167,6 +182,19 @@ ILboolean iCheckDds(DDSHEAD *Head)
}
+// Internal function used to check if the HEADER is a valid DirectX 10 extension header.
+ILboolean iCheckDxt10(DXT10HEAD *Head)
+{
+ if (Head->resourceDimension < 2 && Head->resourceDimension > 4)
+ return IL_FALSE;
+ if (Head->dxgiFormat > DXGI_FORMAT_V408)
+ return IL_FALSE;
+ if (Head->arraySize > 1) //@TODO: Support texture arrays
+ return IL_FALSE;
+ return IL_TRUE;
+}
+
+
//! Reads a .dds file
ILboolean ilLoadDds(ILconst_string FileName)
{
@@ -281,18 +309,21 @@ ILubyte iCompFormatToChannelCount(ILenum Format)
}
-ILboolean iLoadDdsCubemapInternal(ILuint CompFormat)
+ILboolean iLoadDdsCubemapInternal(ILuint CompFormat, ILboolean IsDXT10)
{
ILuint i;
ILubyte Bpp, Channels, Bpc;
ILimage *startImage;
+ if (IsDXT10) //@TODO: Get this working with the DirectX 10 textures
+ return IL_FALSE;
+
CompData = NULL;
Bpp = iCompFormatToBpp(CompFormat);
Channels = iCompFormatToChannelCount(CompFormat);
Bpc = iCompFormatToBpc(CompFormat);
- if (CompFormat == PF_LUMINANCE && Head.RGBBitCount == 16 && Head.RBitMask == 0xFFFF) { //@TODO: This is a HACK.
+ if (CompFormat == PF_LUMINANCE && Head.RGBBitCount == 16 && Head.RBitMask == 0xFFFF) { //@TODO: This is a HACK.
Bpc = 2; Bpp = 2;
}
@@ -328,10 +359,10 @@ ILboolean iLoadDdsCubemapInternal(ILuint CompFormat)
ilActiveFace(i);
}
- if (!ReadData())
+ if (!ReadData(CompFormat, IsDXT10))
return IL_FALSE;
- if (!AllocImage(CompFormat)) {
+ if (!AllocImage(CompFormat, IsDXT10)) {
if (CompData) {
ifree(CompData);
CompData = NULL;
@@ -341,7 +372,7 @@ ILboolean iLoadDdsCubemapInternal(ILuint CompFormat)
Image->CubeFlags = CubemapDirections[i];
- if (!DdsDecompress(CompFormat)) {
+ if (!DdsDecompress(CompFormat, IsDXT10)) {
if (CompData) {
ifree(CompData);
CompData = NULL;
@@ -349,7 +380,7 @@ ILboolean iLoadDdsCubemapInternal(ILuint CompFormat)
return IL_FALSE;
}
- if (!ReadMipmaps(CompFormat)) {
+ if (!ReadMipmaps(CompFormat, IsDXT10)) {
if (CompData) {
ifree(CompData);
CompData = NULL;
@@ -371,8 +402,9 @@ ILboolean iLoadDdsCubemapInternal(ILuint CompFormat)
ILboolean iLoadDdsInternal()
{
- ILuint BlockSize = 0;
- ILuint CompFormat;
+ ILuint BlockSize = 0;
+ ILuint CompFormat;
+ ILboolean IsDXT10 = IL_FALSE;
CompData = NULL;
Image = NULL;
@@ -396,6 +428,25 @@ ILboolean iLoadDdsInternal()
ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
}
+
+ if (CompFormat == PF_DX10) {
+ IsDXT10 = IL_TRUE;
+ if (!iGetDXT10Head(&HeadDXT10)) {
+ ilSetError(IL_INVALID_FILE_HEADER);
+ return IL_FALSE;
+ }
+ if (!iCheckDxt10(&HeadDXT10)) {
+ ilSetError(IL_INVALID_FILE_HEADER);
+ return IL_FALSE;
+ }
+
+ CompFormat = HeadDXT10.dxgiFormat;
+ }
+ else
+ {
+ }
+
+ // Needed for DXT10?
Check16BitComponents(&Head);
// Microsoft bug, they're not following their own documentation.
@@ -408,7 +459,7 @@ ILboolean iLoadDdsInternal()
Image = iCurImage;
if (Head.ddsCaps1 & DDS_COMPLEX) {
if (Head.ddsCaps2 & DDS_CUBEMAP) {
- if (!iLoadDdsCubemapInternal(CompFormat))
+ if (!iLoadDdsCubemapInternal(CompFormat, IsDXT10))
return IL_FALSE;
return IL_TRUE;
}
@@ -417,18 +468,18 @@ ILboolean iLoadDdsInternal()
Width = Head.Width;
Height = Head.Height;
Depth = Head.Depth;
- AdjustVolumeTexture(&Head, CompFormat);
+ AdjustVolumeTexture(&Head, CompFormat, IsDXT10);
- if (!ReadData())
+ if (!ReadData(CompFormat, IsDXT10))
return IL_FALSE;
- if (!AllocImage(CompFormat)) {
+ if (!AllocImage(CompFormat, IsDXT10)) {
if (CompData) {
ifree(CompData);
CompData = NULL;
}
return IL_FALSE;
}
- if (!DdsDecompress(CompFormat)) {
+ if (!DdsDecompress(CompFormat, IsDXT10)) {
if (CompData) {
ifree(CompData);
CompData = NULL;
@@ -436,7 +487,7 @@ ILboolean iLoadDdsInternal()
return IL_FALSE;
}
- if (!ReadMipmaps(CompFormat)) {
+ if (!ReadMipmaps(CompFormat, IsDXT10)) {
if (CompData) {
ifree(CompData);
CompData = NULL;
@@ -487,6 +538,10 @@ ILuint DecodePixelFormat(ILuint *CompFormat)
BlockSize *= 16;
break;
+ case IL_MAKEFOURCC('D', 'X', '1', '0'):
+ *CompFormat = PF_DX10;
+ break;
+
case IL_MAKEFOURCC('A', 'T', 'I', '1'):
*CompFormat = PF_ATI1N;
BlockSize *= 8;
@@ -565,12 +620,147 @@ ILuint DecodePixelFormat(ILuint *CompFormat)
}
+// From https://msdn.microsoft.com/en-us/windows/uwp/gaming/complete-code-for-ddstextureloader
+//
+//--------------------------------------------------------------------------------------
+// Return the BPP for a particular format.
+//--------------------------------------------------------------------------------------
+static size_t BitsPerPixel(_In_ DXGI_FORMAT fmt)
+{
+ switch (fmt)
+ {
+ case DXGI_FORMAT_R32G32B32A32_TYPELESS:
+ case DXGI_FORMAT_R32G32B32A32_FLOAT:
+ case DXGI_FORMAT_R32G32B32A32_UINT:
+ case DXGI_FORMAT_R32G32B32A32_SINT:
+ return 128;
+
+ case DXGI_FORMAT_R32G32B32_TYPELESS:
+ case DXGI_FORMAT_R32G32B32_FLOAT:
+ case DXGI_FORMAT_R32G32B32_UINT:
+ case DXGI_FORMAT_R32G32B32_SINT:
+ return 96;
+
+ case DXGI_FORMAT_R16G16B16A16_TYPELESS:
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ case DXGI_FORMAT_R16G16B16A16_UNORM:
+ case DXGI_FORMAT_R16G16B16A16_UINT:
+ case DXGI_FORMAT_R16G16B16A16_SNORM:
+ case DXGI_FORMAT_R16G16B16A16_SINT:
+ case DXGI_FORMAT_R32G32_TYPELESS:
+ case DXGI_FORMAT_R32G32_FLOAT:
+ case DXGI_FORMAT_R32G32_UINT:
+ case DXGI_FORMAT_R32G32_SINT:
+ case DXGI_FORMAT_R32G8X24_TYPELESS:
+ case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
+ case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
+ case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
+ return 64;
+
+ case DXGI_FORMAT_R10G10B10A2_TYPELESS:
+ case DXGI_FORMAT_R10G10B10A2_UNORM:
+ case DXGI_FORMAT_R10G10B10A2_UINT:
+ case DXGI_FORMAT_R11G11B10_FLOAT:
+ case DXGI_FORMAT_R8G8B8A8_TYPELESS:
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+ case DXGI_FORMAT_R8G8B8A8_UINT:
+ case DXGI_FORMAT_R8G8B8A8_SNORM:
+ case DXGI_FORMAT_R8G8B8A8_SINT:
+ case DXGI_FORMAT_R16G16_TYPELESS:
+ case DXGI_FORMAT_R16G16_FLOAT:
+ case DXGI_FORMAT_R16G16_UNORM:
+ case DXGI_FORMAT_R16G16_UINT:
+ case DXGI_FORMAT_R16G16_SNORM:
+ case DXGI_FORMAT_R16G16_SINT:
+ case DXGI_FORMAT_R32_TYPELESS:
+ case DXGI_FORMAT_D32_FLOAT:
+ case DXGI_FORMAT_R32_FLOAT:
+ case DXGI_FORMAT_R32_UINT:
+ case DXGI_FORMAT_R32_SINT:
+ case DXGI_FORMAT_R24G8_TYPELESS:
+ case DXGI_FORMAT_D24_UNORM_S8_UINT:
+ case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
+ case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
+ case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
+ case DXGI_FORMAT_R8G8_B8G8_UNORM:
+ case DXGI_FORMAT_G8R8_G8B8_UNORM:
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ case DXGI_FORMAT_B8G8R8X8_UNORM:
+ case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
+ case DXGI_FORMAT_B8G8R8A8_TYPELESS:
+ case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
+ case DXGI_FORMAT_B8G8R8X8_TYPELESS:
+ case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
+ return 32;
+
+ case DXGI_FORMAT_R8G8_TYPELESS:
+ case DXGI_FORMAT_R8G8_UNORM:
+ case DXGI_FORMAT_R8G8_UINT:
+ case DXGI_FORMAT_R8G8_SNORM:
+ case DXGI_FORMAT_R8G8_SINT:
+ case DXGI_FORMAT_R16_TYPELESS:
+ case DXGI_FORMAT_R16_FLOAT:
+ case DXGI_FORMAT_D16_UNORM:
+ case DXGI_FORMAT_R16_UNORM:
+ case DXGI_FORMAT_R16_UINT:
+ case DXGI_FORMAT_R16_SNORM:
+ case DXGI_FORMAT_R16_SINT:
+ case DXGI_FORMAT_B5G6R5_UNORM:
+ case DXGI_FORMAT_B5G5R5A1_UNORM:
+ case DXGI_FORMAT_B4G4R4A4_UNORM:
+ return 16;
+
+ case DXGI_FORMAT_R8_TYPELESS:
+ case DXGI_FORMAT_R8_UNORM:
+ case DXGI_FORMAT_R8_UINT:
+ case DXGI_FORMAT_R8_SNORM:
+ case DXGI_FORMAT_R8_SINT:
+ case DXGI_FORMAT_A8_UNORM:
+ return 8;
+
+ case DXGI_FORMAT_R1_UNORM:
+ return 1;
+
+ case DXGI_FORMAT_BC1_TYPELESS:
+ case DXGI_FORMAT_BC1_UNORM:
+ case DXGI_FORMAT_BC1_UNORM_SRGB:
+ case DXGI_FORMAT_BC4_TYPELESS:
+ case DXGI_FORMAT_BC4_UNORM:
+ case DXGI_FORMAT_BC4_SNORM:
+ return 4;
+
+ case DXGI_FORMAT_BC2_TYPELESS:
+ case DXGI_FORMAT_BC2_UNORM:
+ case DXGI_FORMAT_BC2_UNORM_SRGB:
+ case DXGI_FORMAT_BC3_TYPELESS:
+ case DXGI_FORMAT_BC3_UNORM:
+ case DXGI_FORMAT_BC3_UNORM_SRGB:
+ case DXGI_FORMAT_BC5_TYPELESS:
+ case DXGI_FORMAT_BC5_UNORM:
+ case DXGI_FORMAT_BC5_SNORM:
+ case DXGI_FORMAT_BC6H_TYPELESS:
+ case DXGI_FORMAT_BC6H_UF16:
+ case DXGI_FORMAT_BC6H_SF16:
+ case DXGI_FORMAT_BC7_TYPELESS:
+ case DXGI_FORMAT_BC7_UNORM:
+ case DXGI_FORMAT_BC7_UNORM_SRGB:
+ return 8;
+
+ default:
+ return 0;
+ }
+}
+
+
// The few volume textures that I have don't have consistent LinearSize
// entries, even though the DDS_LINEARSIZE flag is set.
-void AdjustVolumeTexture(DDSHEAD *Head, ILuint CompFormat)
+void AdjustVolumeTexture(DDSHEAD *Head, ILuint CompFormat, ILboolean IsDXT10)
{
if (Head->Depth <= 1)
return;
+ if (IsDXT10)
+ return;
// All volume textures I've seem so far didn't have the DDS_COMPLEX flag set,
// even though this is normally required. But because noone does set it,
@@ -627,7 +817,7 @@ void AdjustVolumeTexture(DDSHEAD *Head, ILuint CompFormat)
// Reads the compressed data
-ILboolean ReadData()
+ILboolean ReadData(ILuint CompFormat, ILboolean IsDXT10)
{
ILuint Bps;
ILint y, z;
@@ -653,8 +843,15 @@ ILboolean ReadData()
}
}
else {
- Bps = Width * Head.RGBBitCount / 8;
+ if (IsDXT10)
+ Bps = Head.LinearSize; //@TODO: Head.RGBBitCount is always 0 from the texconv.exe tool?
+ else
+ Bps = Width * Head.RGBBitCount / 8;
CompSize = Bps * Height * Depth;
+ if (CompSize == 0) {
+ ilSetError(IL_INVALID_FILE_HEADER);
+ return IL_FALSE;
+ }
CompData = (ILubyte*)ialloc(CompSize);
if (CompData == NULL) {
@@ -678,85 +875,110 @@ ILboolean ReadData()
}
-ILboolean AllocImage(ILuint CompFormat)
+ILboolean AllocImage(ILuint CompFormat, ILboolean IsDXT10)
{
ILubyte channels = 4;
ILenum format = IL_RGBA;
- switch (CompFormat)
+ if (!IsDXT10)
{
- case PF_RGB:
- if (!ilTexImage(Width, Height, Depth, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL))
- return IL_FALSE;
- break;
- case PF_ARGB:
- if (!ilTexImage(Width, Height, Depth, 4, IL_RGBA, Has16BitComponents ? IL_UNSIGNED_SHORT : IL_UNSIGNED_BYTE, NULL))
- return IL_FALSE;
- break;
+ switch (CompFormat)
+ {
+ case PF_RGB:
+ if (!ilTexImage(Width, Height, Depth, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL))
+ return IL_FALSE;
+ break;
+ case PF_ARGB:
+ if (!ilTexImage(Width, Height, Depth, 4, IL_RGBA, Has16BitComponents ? IL_UNSIGNED_SHORT : IL_UNSIGNED_BYTE, NULL))
+ return IL_FALSE;
+ break;
- case PF_LUMINANCE:
- if (Head.RGBBitCount == 16 && Head.RBitMask == 0xFFFF) { //HACK
- if (!ilTexImage(Width, Height, Depth, 1, IL_LUMINANCE, IL_UNSIGNED_SHORT, NULL))
+ case PF_LUMINANCE:
+ if (Head.RGBBitCount == 16 && Head.RBitMask == 0xFFFF) { //HACK
+ if (!ilTexImage(Width, Height, Depth, 1, IL_LUMINANCE, IL_UNSIGNED_SHORT, NULL))
+ return IL_FALSE;
+ }
+ else
+ if (!ilTexImage(Width, Height, Depth, 1, IL_LUMINANCE, IL_UNSIGNED_BYTE, NULL))
+ return IL_FALSE;
+ break;
+
+ case PF_LUMINANCE_ALPHA:
+ if (!ilTexImage(Width, Height, Depth, 2, IL_LUMINANCE_ALPHA, IL_UNSIGNED_BYTE, NULL))
return IL_FALSE;
- }
- else
+ break;
+
+ case PF_ATI1N:
+ //right now there's no OpenGL api to use the compressed 3dc data, so
+ //throw it away (I don't know how DirectX works, though)?
if (!ilTexImage(Width, Height, Depth, 1, IL_LUMINANCE, IL_UNSIGNED_BYTE, NULL))
return IL_FALSE;
- break;
-
- case PF_LUMINANCE_ALPHA:
- if (!ilTexImage(Width, Height, Depth, 2, IL_LUMINANCE_ALPHA, IL_UNSIGNED_BYTE, NULL))
- return IL_FALSE;
- break;
+ break;
- case PF_ATI1N:
- //right now there's no OpenGL api to use the compressed 3dc data, so
- //throw it away (I don't know how DirectX works, though)?
- if (!ilTexImage(Width, Height, Depth, 1, IL_LUMINANCE, IL_UNSIGNED_BYTE, NULL))
- return IL_FALSE;
- break;
+ case PF_3DC:
+ //right now there's no OpenGL api to use the compressed 3dc data, so
+ //throw it away (I don't know how DirectX works, though)?
+ if (!ilTexImage(Width, Height, Depth, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL))
+ return IL_FALSE;
+ break;
- case PF_3DC:
- //right now there's no OpenGL api to use the compressed 3dc data, so
- //throw it away (I don't know how DirectX works, though)?
- if (!ilTexImage(Width, Height, Depth, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL))
- return IL_FALSE;
- break;
+ case PF_A16B16G16R16:
+ if (!ilTexImage(Width, Height, Depth, iCompFormatToChannelCount(CompFormat),
+ ilGetFormatBpp(iCompFormatToChannelCount(CompFormat)), IL_UNSIGNED_SHORT, NULL))
+ return IL_FALSE;
+ break;
- case PF_A16B16G16R16:
- if (!ilTexImage(Width, Height, Depth, iCompFormatToChannelCount(CompFormat),
- ilGetFormatBpp(iCompFormatToChannelCount(CompFormat)), IL_UNSIGNED_SHORT, NULL))
- return IL_FALSE;
- break;
+ case PF_R16F:
+ case PF_G16R16F:
+ case PF_A16B16G16R16F:
+ case PF_R32F:
+ case PF_G32R32F:
+ case PF_A32B32G32R32F:
+ if (!ilTexImage(Width, Height, Depth, iCompFormatToChannelCount(CompFormat),
+ ilGetFormatBpp(iCompFormatToChannelCount(CompFormat)), IL_FLOAT, NULL))
+ return IL_FALSE;
+ break;
- case PF_R16F:
- case PF_G16R16F:
- case PF_A16B16G16R16F:
- case PF_R32F:
- case PF_G32R32F:
- case PF_A32B32G32R32F:
- if (!ilTexImage(Width, Height, Depth, iCompFormatToChannelCount(CompFormat),
- ilGetFormatBpp(iCompFormatToChannelCount(CompFormat)), IL_FLOAT, NULL))
- return IL_FALSE;
- break;
+ default:
+ if (CompFormat == PF_RXGB) {
+ channels = 3; //normal map
+ format = IL_RGB;
+ }
- default:
- if (CompFormat == PF_RXGB) {
- channels = 3; //normal map
- format = IL_RGB;
- }
+ if (!ilTexImage(Width, Height, Depth, channels, format, IL_UNSIGNED_BYTE, NULL))
+ return IL_FALSE;
+ if (ilGetInteger(IL_KEEP_DXTC_DATA) == IL_TRUE && CompData) {
+ iCurImage->DxtcData = (ILubyte*)ialloc(Head.LinearSize);
+ if (iCurImage->DxtcData == NULL)
+ return IL_FALSE;
+ iCurImage->DxtcFormat = CompFormat - PF_DXT1 + IL_DXT1;
+ iCurImage->DxtcSize = Head.LinearSize;
+ memcpy(iCurImage->DxtcData, CompData, iCurImage->DxtcSize);
+ }
+ break;
+ }
+ }
+ else
+ {
+ switch (CompFormat)
+ {
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ if (!ilTexImage(Width, Height, Depth, 4, IL_RGBA, Has16BitComponents ? IL_UNSIGNED_SHORT : IL_UNSIGNED_BYTE, NULL))
+ return IL_FALSE;
+ break;
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ if (!ilTexImage(Width, Height, Depth, 4, IL_BGRA, Has16BitComponents ? IL_UNSIGNED_SHORT : IL_UNSIGNED_BYTE, NULL))
+ return IL_FALSE;
+ break;
+ case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
+ if (!ilTexImage(Width, Height, Depth, 4, IL_BGRA, Has16BitComponents ? IL_UNSIGNED_SHORT : IL_UNSIGNED_BYTE, NULL))
+ return IL_FALSE;
+ break;
- if (!ilTexImage(Width, Height, Depth, channels, format, IL_UNSIGNED_BYTE, NULL))
+ default:
+ ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
- if (ilGetInteger(IL_KEEP_DXTC_DATA) == IL_TRUE && CompData) {
- iCurImage->DxtcData = (ILubyte*)ialloc(Head.LinearSize);
- if (iCurImage->DxtcData == NULL)
- return IL_FALSE;
- iCurImage->DxtcFormat = CompFormat - PF_DXT1 + IL_DXT1;
- iCurImage->DxtcSize = Head.LinearSize;
- memcpy(iCurImage->DxtcData, CompData, iCurImage->DxtcSize);
- }
- break;
+ }
}
Image->Origin = IL_ORIGIN_UPPER_LEFT;
@@ -779,8 +1001,13 @@ ILboolean AllocImage(ILuint CompFormat)
*
* @TODO: don't use globals, clean this function (and this file) up
*/
-ILboolean DdsDecompress(ILuint CompFormat)
+ILboolean DdsDecompress(ILuint CompFormat, ILboolean IsDXT10)
{
+ if (IsDXT10)
+ { //@TODO: Put in compressed formats
+ return DecompressARGBDX10(CompFormat);
+ }
+
switch (CompFormat)
{
case PF_ARGB:
@@ -833,7 +1060,7 @@ ILboolean DdsDecompress(ILuint CompFormat)
}
-ILboolean ReadMipmaps(ILuint CompFormat)
+ILboolean ReadMipmaps(ILuint CompFormat, ILboolean IsDXT10)
{
ILuint i, CompFactor=0;
ILubyte Bpp, Channels, Bpc;
@@ -843,6 +1070,9 @@ ILboolean ReadMipmaps(ILuint CompFormat)
ILboolean isCompressed = IL_FALSE;
+ if (IsDXT10) //@TODO: Add in mipmap support
+ return IL_TRUE;
+
Bpp = iCompFormatToBpp(CompFormat);
Channels = iCompFormatToChannelCount(CompFormat);
Bpc = iCompFormatToBpc(CompFormat);
@@ -945,7 +1175,7 @@ ILboolean ReadMipmaps(ILuint CompFormat)
Head.LinearSize >>= 1;
}
- if (!ReadData())
+ if (!ReadData(CompFormat, IsDXT10))
goto mip_fail;
if (ilGetInteger(IL_KEEP_DXTC_DATA) == IL_TRUE && isCompressed == IL_TRUE && CompData) {
@@ -957,7 +1187,7 @@ ILboolean ReadMipmaps(ILuint CompFormat)
memcpy(Image->DxtcData, CompData, Image->DxtcSize);
}
- if (!DdsDecompress(CompFormat))
+ if (!DdsDecompress(CompFormat, IsDXT10))
goto mip_fail;
}
@@ -1681,6 +1911,14 @@ void CorrectPreMult()
}
+ILboolean DecompressARGBDX10(ILuint CompFormat)
+{
+ //@TODO: Will certainly fail if iCurImage->SizeOfData != "Compressed" Size
+ memcpy(iCurImage->Data, CompData, iCurImage->SizeOfData);
+ return IL_TRUE;
+}
+
+
ILboolean DecompressARGB(ILuint CompFormat)
{
ILuint ReadI = 0, TempBpp, i;
@@ -1989,7 +2227,8 @@ ILAPI ILboolean ILAPIENTRY ilDxtcDataToSurface()
case IL_DXT5: CompFormat = PF_DXT5; break;
}
CompData = iCurImage->DxtcData;
- DdsDecompress(CompFormat); //globals suck...fix this
+ DdsDecompress(CompFormat, IL_FALSE); //@TODO: globals suck...fix this
+ //@TODO: Should we ever expect this to be IL_TRUE?
//@TODO: origin should be set in Decompress()...
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
diff --git a/DevIL/src-IL/src/il_dicom.cpp b/DevIL/src-IL/src/il_dicom.cpp
index 4d2f55dd..c8074a60 100644
--- a/DevIL/src-IL/src/il_dicom.cpp
+++ b/DevIL/src-IL/src/il_dicom.cpp
@@ -427,7 +427,7 @@ ILboolean GetUID(ILubyte *UID)
return IL_FALSE;
ValLen = GetLittleUShort();
- if (ValLen > 64)
+ if (ValLen > 64) // Addresses this vulnerability: https://vuldb.com/?id.51054
return IL_FALSE;
if (iread(UID, ValLen, 1) != 1)
return IL_FALSE;
diff --git a/DevIL/src-IL/src/il_io.cpp b/DevIL/src-IL/src/il_io.cpp
index e5af3cac..cc40de5a 100644
--- a/DevIL/src-IL/src/il_io.cpp
+++ b/DevIL/src-IL/src/il_io.cpp
@@ -125,7 +125,7 @@ ILenum ILAPIENTRY ilTypeFromExt(ILconst_string FileName)
else if (!iStrCmp(Ext, IL_TEXT("pix")))
Type = IL_PIX;
else if (!iStrCmp(Ext, IL_TEXT("pbm")) || !iStrCmp(Ext, IL_TEXT("pgm")) ||
- !iStrCmp(Ext, IL_TEXT("pnm")) || !iStrCmp(Ext, IL_TEXT("ppm")))
+ !iStrCmp(Ext, IL_TEXT("pnm")) || !iStrCmp(Ext, IL_TEXT("ppm")) || !iStrCmp(Ext, IL_TEXT("pam")))
Type = IL_PNM;
else if (!iStrCmp(Ext, IL_TEXT("psd")) || !iStrCmp(Ext, IL_TEXT("pdd")))
Type = IL_PSD;
@@ -2058,6 +2058,10 @@ ILboolean ILAPIENTRY ilLoadImage(ILconst_string FileName)
bRet = ilLoadPnm(FileName);
goto finish;
}
+ if (!iStrCmp(Ext, IL_TEXT("pam"))) {
+ bRet = ilLoadPnm(FileName);
+ goto finish;
+ }
#endif
#ifndef IL_NO_PSD
diff --git a/DevIL/src-IL/src/il_pnm.cpp b/DevIL/src-IL/src/il_pnm.cpp
index fdbf679a..794f6e55 100644
--- a/DevIL/src-IL/src/il_pnm.cpp
+++ b/DevIL/src-IL/src/il_pnm.cpp
@@ -17,11 +17,17 @@
#include "il_pnm.h"
#include <limits.h> // for maximum values
#include <ctype.h>
+#include <string>
#include "il_bits.h"
+using namespace std;
+
+
// According to the ppm specs, it's 70, but PSP
// likes to output longer lines.
#define MAX_BUFFER 180
+
+//@TODO: Get rid of these globals
static ILbyte LineBuffer[MAX_BUFFER];
static ILbyte SmallBuff[MAX_BUFFER];
@@ -38,7 +44,8 @@ ILboolean ilIsValidPnm(ILconst_string FileName)
if ( !iCheckExtension(FileName, IL_TEXT("pbm"))
&& !iCheckExtension(FileName, IL_TEXT("pgm"))
&& !iCheckExtension(FileName, IL_TEXT("ppm"))
- && !iCheckExtension(FileName, IL_TEXT("pnm"))) {
+ && !iCheckExtension(FileName, IL_TEXT("pnm"))
+ && !iCheckExtension(FileName, IL_TEXT("pam"))) {
ilSetError(IL_INVALID_EXTENSION);
return bPnm;
}
@@ -107,6 +114,7 @@ ILboolean iCheckPnm(char Header[2])
case '4':
case '5':
case '6':
+ case '7':
return IL_TRUE;
}
@@ -179,7 +187,8 @@ ILboolean iLoadPnmInternal()
return IL_FALSE;
}
- switch( SmallBuff[1] ) {
+ switch (SmallBuff[1])
+ {
case '1':
Info.Type = IL_PBM_ASCII;
break;
@@ -202,6 +211,9 @@ ILboolean iLoadPnmInternal()
case '6':
Info.Type = IL_PPM_BINARY;
break;
+ case '7':
+ //Info.Type = IL_PAM;
+ return ilReadPam();
default:
ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
@@ -225,29 +237,40 @@ ILboolean iLoadPnmInternal()
}
// Retrieve the maximum colour component value
- if (Info.Type != IL_PBM_ASCII && Info.Type != IL_PBM_BINARY) {
+ if (Info.Type != IL_PBM_ASCII && Info.Type != IL_PBM_BINARY)
+ {
if (iGetWord(IL_TRUE) == IL_FALSE)
return IL_FALSE;
- if ((Info.MaxColour = atoi((const char*)SmallBuff)) == 0) {
+ if ((Info.MaxColour = atoi((const char*)SmallBuff)) == 0)
+ {
ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
}
- } else {
+ }
+ else
+ {
Info.MaxColour = 1;
}
if (Info.Type == IL_PBM_ASCII || Info.Type == IL_PBM_BINARY ||
- Info.Type == IL_PGM_ASCII || Info.Type == IL_PGM_BINARY) {
- if (Info.Type == IL_PGM_ASCII) {
+ Info.Type == IL_PGM_ASCII || Info.Type == IL_PGM_BINARY)
+ {
+ if (Info.Type == IL_PGM_ASCII)
+ {
Info.Bpp = Info.MaxColour < 256 ? 1 : 2;
- } else {
+ }
+ else
+ {
Info.Bpp = 1;
}
- } else {
+ }
+ else
+ {
Info.Bpp = 3;
}
- switch (Info.Type) {
+ switch (Info.Type)
+ {
case IL_PBM_ASCII:
case IL_PGM_ASCII:
case IL_PPM_ASCII:
@@ -260,18 +283,22 @@ ILboolean iLoadPnmInternal()
case IL_PPM_BINARY:
PmImage = ilReadBinaryPpm(&Info);
break;
+ /*case IL_PAM:
+ PmImage = ilReadPam(&Info);*/
default:
return IL_FALSE;
}
- if (PmImage == NULL) {
+ if (PmImage == NULL)
+ {
iCurImage->Format = ilGetFormatBpp(iCurImage->Bpp);
ilSetError(IL_FILE_READ_ERROR);
return IL_FALSE;
}
// Is this conversion needed? Just 0's and 1's shows up as all black
- if (Info.Type == IL_PBM_ASCII) {
+ if (Info.Type == IL_PBM_ASCII)
+ {
PbmMaximize(PmImage);
}
@@ -363,7 +390,7 @@ ILimage *ilReadAsciiPpm(PPMINFO *Info)
ILimage *ilReadBinaryPpm(PPMINFO *Info)
{
- ILuint Size;
+ ILuint Size;
Size = Info->Width * Info->Height * Info->Bpp;
@@ -382,7 +409,7 @@ ILimage *ilReadBinaryPpm(PPMINFO *Info)
ILuint size = itell();
iseek(size-Size,IL_SEEK_SET);
*/
- if (iread(iCurImage->Data, 1, Size ) != Size) {
+ if (iread(iCurImage->Data, 1, Size) != Size) {
ilCloseImage(iCurImage);
return NULL;
}
@@ -413,6 +440,143 @@ ILimage *ilReadBitPbm(PPMINFO *Info)
}
+ILboolean ilReadPam()
+{
+ PPMINFO Info;
+ string TempStr;
+ ILuint Size;
+
+ memset(&Info, 0, sizeof(PPMINFO));
+
+ while (!ieof())
+ {
+ if (iGetWord(IL_FALSE) == IL_FALSE)
+ return IL_FALSE;
+ if (!strncmp((const char*)SmallBuff, "ENDHDR", 6))
+ break;
+
+ TempStr = (char*)SmallBuff; // Save the first identifier of the line
+ if (iGetWord(IL_FALSE) == IL_FALSE)
+ return IL_FALSE;
+ if (!strncmp(TempStr.c_str(), "WIDTH", 5))
+ Info.Width = atoi((const char*)SmallBuff);
+ else if (!strncmp(TempStr.c_str(), "HEIGHT", 6))
+ Info.Height = atoi((const char*)SmallBuff);
+ else if (!strncmp(TempStr.c_str(), "DEPTH", 5))
+ Info.Depth = atoi((const char*)SmallBuff);
+ else if (!strncmp(TempStr.c_str(), "MAXVAL", 6))
+ Info.MaxColour = atoi((const char*)SmallBuff);
+ else if (!strncmp(TempStr.c_str(), "TUPLTYPE", 8))
+ Info.TuplType = DecodeTupleType(string((char*)SmallBuff));
+ }
+
+ //@TODO: Handle other max colors and tuple types
+ if (Info.Width == 0 || Info.Height == 0 || Info.Depth == 0 || Info.Depth > 4 || Info.TuplType == 0)
+ {
+ ilSetError(IL_INVALID_FILE_HEADER);
+ return IL_FALSE;
+ }
+ switch (Info.MaxColour)
+ {
+ case 255:
+ Info.Type = IL_UNSIGNED_BYTE;
+ Size = 1;
+ break;
+ case 65535:
+ Info.Type = IL_UNSIGNED_SHORT;
+ Size = 2;
+ break;
+ default:
+ ilSetError(IL_INVALID_FILE_HEADER);
+ return IL_FALSE;
+ }
+
+ switch (Info.TuplType)
+ {
+ case PAM_GRAY:
+ if (Info.Depth != 1)
+ {
+ ilSetError(IL_INVALID_FILE_HEADER);
+ return IL_FALSE;
+ }
+ if (!ilTexImage(Info.Width, Info.Height, 1, Info.Depth, 0, Info.Type, NULL))
+ return IL_FALSE;
+ Size *= Info.Width * Info.Height * Info.Depth;
+ iCurImage->Format = IL_LUMINANCE;
+ break;
+
+ case PAM_GRAY_ALPHA:
+ if (Info.Depth != 2)
+ {
+ ilSetError(IL_INVALID_FILE_HEADER);
+ return IL_FALSE;
+ }
+ if (!ilTexImage(Info.Width, Info.Height, 1, Info.Depth, 0, Info.Type, NULL))
+ return IL_FALSE;
+ Size *= Info.Width * Info.Height * Info.Depth;
+ iCurImage->Format = IL_LUMINANCE_ALPHA;
+ break;
+
+ case PAM_RGB:
+ if (Info.Depth != 3)
+ {
+ ilSetError(IL_INVALID_FILE_HEADER);
+ return IL_FALSE;
+ }
+ if (!ilTexImage(Info.Width, Info.Height, 1, Info.Depth, 0, Info.Type, NULL))
+ return IL_FALSE;
+ Size *= Info.Width * Info.Height * Info.Depth;
+ iCurImage->Format = IL_RGB;
+ break;
+
+ case PAM_RGB_ALPHA:
+ if (Info.Depth != 4)
+ {
+ ilSetError(IL_INVALID_FILE_HEADER);
+ return IL_FALSE;
+ }
+ if (!ilTexImage(Info.Width, Info.Height, 1, Info.Depth, 0, Info.Type, NULL))
+ return IL_FALSE;
+ Size *= Info.Width * Info.Height * Info.Depth;
+ iCurImage->Format = IL_RGBA;
+ break;
+
+ default:
+ //@TODO: Handle black and white case
+ ilSetError(IL_INVALID_FILE_HEADER);
+ return IL_FALSE;
+ }
+ iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
+
+ if (iread(iCurImage->Data, 1, Size) != Size)
+ {
+ ilCloseImage(iCurImage);
+ return NULL;
+ }
+
+ return IL_TRUE;
+}
+
+
+ILint DecodeTupleType(string &TupleStr)
+{
+ if (TupleStr == "BLACKANDWHITE")
+ return PAM_BW;
+ else if (TupleStr == "GRAYSCALE")
+ return PAM_GRAY;
+ else if (TupleStr == "RGB")
+ return PAM_RGB;
+ else if (TupleStr == "BLACKANDWHITE_ALPHA")
+ return PAM_BW_ALPHA;
+ else if (TupleStr == "GRAYSCALE_ALPHA")
+ return PAM_GRAY_ALPHA;
+ else if (TupleStr == "RGB_ALPHA")
+ return PAM_RGB_ALPHA;
+
+ return 0;
+}
+
+
ILboolean iGetWord(ILboolean final)
{
ILint WordPos = 0;
@@ -423,12 +587,14 @@ ILboolean iGetWord(ILboolean final)
if (ieof())
return IL_FALSE;
- while (Looping) {
- while ((Current = igetc()) != IL_EOF && Current != '\n' && Current != '#' && Current != ' ') {
+ while (Looping)
+ {
+ while ((Current = igetc()) != IL_EOF && Current != '\n' && Current != '#' && Current != ' ')
+ {
if (WordPos >= MAX_BUFFER) // We have hit the maximum line length.
return IL_FALSE;
- if (!isalnum(Current)) {
+ if (!isalnum(Current) && Current != '_') {
if (Started) {
Looping = IL_FALSE;
break;