Add DevIL 1.7.8.

This commit is contained in:
rude
2013-09-26 00:20:08 +02:00
parent 6e493fb605
commit c065120c58
487 changed files with 219483 additions and 0 deletions
@@ -0,0 +1,34 @@
/*
* altivec_typeconversion.h
* DevIL
*
* Created by Meloni Dario on 17/04/05.
*
*/
#include "il_internal.h"
#ifdef ALTIVEC_GCC
#ifndef ALTIVEC_COMMON
#define ALTIVEC_COMMON
typedef union {
vector unsigned int vuint;
unsigned int suint[4];
vector unsigned char vuchar;
unsigned char suchar[4];
vector float vf;
float sf[4];
} vector_t;
// Loads 16 byte from the specified address, aligned or not
//vector unsigned char load_unaligned( unsigned char *buffer );
// Fills a vector with the specified value
vector float fill_vector_f( float value );
#define eround(v,x) (((int)((v/x)*10)%10) > 0 ? (v/x) : (v/x)+1)
#define eround16(v) eround(v,16)
#endif
#endif
@@ -0,0 +1,28 @@
/*
* altivec_typeconversion.h
* DevIL
*
* Created by Meloni Dario on 24/04/05.
*
*/
#include "altivec_common.h"
#ifdef ALTIVEC_GCC
// data and newdata may be the same buffer
// Used to convert RGB <-> BGR in various data types
void abc2cba_byte( ILubyte *data, ILuint length, ILubyte *newdata );
void abc2cba_short( ILushort *data, ILuint length, ILushort *newdata );
void abc2cba_int( ILuint *data, ILuint length, ILuint *newdata );
#define abc2cba_float(x,y,z) abc2cba_int(((ILuint*)(x)),y,((ILuint*)(z)))
void abc2cba_double( ILdouble *data, ILuint length, ILdouble *newdata );
// Used to convert RGBA <-> BGRA in various data types
void abcd2cbad_byte( ILubyte *data, ILuint length, ILubyte *newdata );
void abcd2cbad_short( ILushort *data, ILuint length, ILushort *newdata );
void abcd2cbad_int( ILuint *data, ILuint length, ILuint *newdata );
#define abcd2cbad_float(x,y,z) abcd2cbad_int(((ILuint*)(x)),y,((ILuint*)(z)))
void abcd2cbad_double( ILdouble *data, ILuint length, ILdouble *newdata );
#endif
@@ -0,0 +1,41 @@
#ifndef ALLOC_H
#define ALLOC_H
/*#if defined(_WIN32) && defined(_MEM_DEBUG)
void *c_alloc(unsigned long size, unsigned long num, const char *file, unsigned long line);
void *m_alloc(unsigned long size, const char *file, unsigned long line);
void f_ree(void *ptr);
#ifdef malloc
#undef malloc
#endif
#ifdef calloc
#undef calloc
#endif
#ifdef free
#undef free
#endif
#define malloc(size) m_alloc(size, __FILE__, __LINE__)
#define calloc(size, num) c_alloc(size, num, __FILE__, __LINE__)
#define free(addr) f_ree(addr)
#endif//defined(_WIN32) && defined(_MEM_DEBUG)*/
#if defined (__ALLOC_C)
#define __ALLOC_EXTERN
#else
#define __ALLOC_EXTERN extern
#endif
#include <IL/il.h>
__ALLOC_EXTERN mAlloc ialloc_ptr;
__ALLOC_EXTERN mFree ifree_ptr;
#endif//ALLOC_H
+43
View File
@@ -0,0 +1,43 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2002 by Denton Woods
// Last modified: 05/25/2001 <--Y2K Compliant! =]
//
// Filename: src-IL/include/il_bits.h
//
// Description: Implements a file class that reads/writes bits directly.
//
//-----------------------------------------------------------------------------
#ifndef BITS_H
#define BITS_H
#include "il_internal.h"
// Struct for dealing with reading bits from a file
typedef struct BITFILE
{
ILHANDLE File;
ILuint BitPos;
ILint ByteBitOff;
ILubyte Buff;
} BITFILE;
// Functions for reading bits from a file
//BITFILE* bopen(const char *FileName, const char *Mode);
ILint bclose(BITFILE *BitFile);
BITFILE* bfile(ILHANDLE File);
ILint btell(BITFILE *BitFile);
ILint bseek(BITFILE *BitFile, ILuint Offset, ILuint Mode);
ILint bread(void *Buffer, ILuint Size, ILuint Number, BITFILE *BitFile);
//ILint bwrite(void *Buffer, ILuint Size, ILuint Number, BITFILE *BitFile);
// Useful macros for manipulating bits
#define SetBits(var, bits) (var |= bits)
#define ClearBits(var, bits) (var &= ~(bits))
#endif//BITS_H
+107
View File
@@ -0,0 +1,107 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2002 by Denton Woods
// Last modified: 09/01/2003 <--Y2K Compliant! =]
//
// Filename: src-IL/include/il_bmp.h
//
// Description: Reads and writes to a bitmap (.bmp) file.
//
//-----------------------------------------------------------------------------
#ifndef BMP_H
#define BMP_H
#include "il_internal.h"
#ifdef _WIN32
#pragma pack(push, bmp_struct, 1)
#endif
typedef struct BMPHEAD {
ILushort bfType;
ILint bfSize;
ILuint bfReserved;
ILint bfDataOff;
ILint biSize;
ILint biWidth;
ILint biHeight;
ILshort biPlanes;
ILshort biBitCount;
ILint biCompression;
ILint biSizeImage;
ILint biXPelsPerMeter;
ILint biYPelsPerMeter;
ILint biClrUsed;
ILint biClrImportant;
} IL_PACKSTRUCT BMPHEAD;
typedef struct OS2_HEAD
{
// Bitmap file header.
ILushort bfType;
ILuint biSize;
ILshort xHotspot;
ILshort yHotspot;
ILuint DataOff;
// Bitmap core header.
ILuint cbFix;
//2003-09-01: changed cx, cy to ushort according to MSDN
ILushort cx;
ILushort cy;
ILushort cPlanes;
ILushort cBitCount;
} IL_PACKSTRUCT OS2_HEAD;
#ifdef _WIN32
#pragma pack(pop, bmp_struct)
#endif
// Internal functions
ILboolean iGetBmpHead(BMPHEAD * const Header);
ILboolean iGetOS2Head(OS2_HEAD * const Header);
ILboolean iIsValidBmp();
ILboolean iCheckBmp(const BMPHEAD *CONST_RESTRICT Header);
ILboolean iCheckOS2(const OS2_HEAD *CONST_RESTRICT Header);
ILboolean iLoadBitmapInternal();
ILboolean iSaveBitmapInternal();
ILboolean ilReadUncompBmp(BMPHEAD *Info);
ILboolean ilReadRLE8Bmp(BMPHEAD *Info);
ILboolean ilReadRLE4Bmp(BMPHEAD *Info);
ILboolean iGetOS2Bmp(OS2_HEAD *Header);
#ifdef IL_BMP_C
#undef NOINLINE
#undef INLINE
#define INLINE
#endif
#ifndef NOINLINE
INLINE void GetShiftFromMask(const ILuint Mask, ILuint * CONST_RESTRICT ShiftLeft, ILuint * CONST_RESTRICT ShiftRight) {
ILuint Temp, i;
if( Mask == 0 ) {
*ShiftLeft = *ShiftRight = 0;
return;
}
Temp = Mask;
for( i = 0; i < 32; i++, Temp >>= 1 ) {
if( Temp & 1 )
break;
}
*ShiftRight = i;
// Temp is preserved, so use it again:
for( i = 0; i < 8; i++, Temp >>= 1 ) {
if( !(Temp & 1) )
break;
}
*ShiftLeft = 8 - i;
return;
}
#endif
#endif//BMP_H
+52
View File
@@ -0,0 +1,52 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 02/26/2009
//
// Filename: src-IL/include/il_dcx.h
//
// Description: Reads from a .dcx file.
//
//-----------------------------------------------------------------------------
#ifndef DCX_H
#define DCX_H
#include "il_internal.h"
#ifdef _WIN32
#pragma pack(push, packed_struct, 1)
#endif
typedef struct DCXHEAD
{
ILubyte Manufacturer;
ILubyte Version;
ILubyte Encoding;
ILubyte Bpp;
ILushort Xmin, Ymin, Xmax, Ymax;
ILushort HDpi;
ILushort VDpi;
ILubyte ColMap[48];
ILubyte Reserved;
ILubyte NumPlanes;
ILushort Bps;
ILushort PaletteInfo;
ILushort HScreenSize;
ILushort VScreenSize;
ILubyte Filler[54];
} IL_PACKSTRUCT DCXHEAD;
#ifdef _WIN32
#pragma pack(pop, packed_struct)
#endif
// For checking and reading
ILboolean iIsValidDcx(void);
ILboolean iCheckDcx(DCXHEAD *Header);
ILboolean iLoadDcxInternal(void);
ILimage* iUncompressDcx(DCXHEAD *Header);
ILimage* iUncompressDcxSmall(DCXHEAD *Header);
#endif//PCX_H
+221
View File
@@ -0,0 +1,221 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2008 by Denton Woods
// Last modified: 12/27/2008
//
// Filename: src-IL/include/il_dds.h
//
// Description: Reads from a DirectDraw Surface (.dds) file.
//
//-----------------------------------------------------------------------------
#ifndef DDS_H
#define DDS_H
#include "il_internal.h"
#ifdef _WIN32
#pragma pack(push, dds_struct, 1)
#endif
typedef struct DDSHEAD
{
ILbyte Signature[4];
ILuint Size1; // size of the structure (minus MagicNum)
ILuint Flags1; // determines what fields are valid
ILuint Height; // height of surface to be created
ILuint Width; // width of input surface
ILuint LinearSize; // Formless late-allocated optimized surface size
ILuint Depth; // Depth if a volume texture
ILuint MipMapCount; // number of mip-map levels requested
ILuint AlphaBitDepth; // depth of alpha buffer requested
ILuint NotUsed[10];
ILuint Size2; // size of structure
ILuint Flags2; // pixel format flags
ILuint FourCC; // (FOURCC code)
ILuint RGBBitCount; // how many bits per pixel
ILuint RBitMask; // mask for red bit
ILuint GBitMask; // mask for green bits
ILuint BBitMask; // mask for blue bits
ILuint RGBAlphaBitMask; // mask for alpha channel
ILuint ddsCaps1, ddsCaps2, ddsCaps3, ddsCaps4; // direct draw surface capabilities
ILuint TextureStage;
} IL_PACKSTRUCT DDSHEAD;
#ifdef _WIN32
#pragma pack(pop, dds_struct)
#endif
// use cast to struct instead of RGBA_MAKE as struct is
// much
typedef struct Color8888
{
ILubyte r; // change the order of names to change the
ILubyte g; // order of the output ARGB or BGRA, etc...
ILubyte b; // Last one is MSB, 1st is LSB.
ILubyte a;
} Color8888;
typedef struct Color888
{
ILubyte r; // change the order of names to change the
ILubyte g; // order of the output ARGB or BGRA, etc...
ILubyte b; // Last one is MSB, 1st is LSB.
} Color888;
typedef struct Color565
{
unsigned nBlue : 5; // order of names changes
unsigned nGreen : 6; // byte order of output to 32 bit
unsigned nRed : 5;
} Color565;
typedef struct DXTColBlock
{
ILshort col0;
ILshort col1;
// no bit fields - use bytes
ILbyte row[4];
} DXTColBlock;
typedef struct DXTAlphaBlockExplicit
{
ILshort row[4];
} DXTAlphaBlockExplicit;
typedef struct DXTAlphaBlock3BitLinear
{
ILbyte alpha0;
ILbyte alpha1;
ILbyte stuff[6];
} DXTAlphaBlock3BitLinear;
// Defines
//Those 4 were added on 20040516 to make
//the written dds files more standard compliant
#define DDS_CAPS 0x00000001L
#define DDS_HEIGHT 0x00000002L
#define DDS_WIDTH 0x00000004L
#define DDS_RGB 0x00000040L
#define DDS_PIXELFORMAT 0x00001000L
#define DDS_LUMINANCE 0x00020000L
#define DDS_ALPHAPIXELS 0x00000001L
#define DDS_ALPHA 0x00000002L
#define DDS_FOURCC 0x00000004L
#define DDS_PITCH 0x00000008L
#define DDS_COMPLEX 0x00000008L
#define DDS_TEXTURE 0x00001000L
#define DDS_MIPMAPCOUNT 0x00020000L
#define DDS_LINEARSIZE 0x00080000L
#define DDS_VOLUME 0x00200000L
#define DDS_MIPMAP 0x00400000L
#define DDS_DEPTH 0x00800000L
#define DDS_CUBEMAP 0x00000200L
#define DDS_CUBEMAP_POSITIVEX 0x00000400L
#define DDS_CUBEMAP_NEGATIVEX 0x00000800L
#define DDS_CUBEMAP_POSITIVEY 0x00001000L
#define DDS_CUBEMAP_NEGATIVEY 0x00002000L
#define DDS_CUBEMAP_POSITIVEZ 0x00004000L
#define DDS_CUBEMAP_NEGATIVEZ 0x00008000L
#define IL_MAKEFOURCC(ch0, ch1, ch2, ch3) \
((ILint)(ILbyte)(ch0) | ((ILint)(ILbyte)(ch1) << 8) | \
((ILint)(ILbyte)(ch2) << 16) | ((ILint)(ILbyte)(ch3) << 24 ))
enum PixFormat
{
PF_ARGB,
PF_RGB,
PF_DXT1,
PF_DXT2,
PF_DXT3,
PF_DXT4,
PF_DXT5,
PF_3DC,
PF_ATI1N,
PF_LUMINANCE,
PF_LUMINANCE_ALPHA,
PF_RXGB, //Doom3 normal maps
PF_A16B16G16R16,
PF_R16F,
PF_G16R16F,
PF_A16B16G16R16F,
PF_R32F,
PF_G32R32F,
PF_A32B32G32R32F,
PF_UNKNOWN = 0xFF
};
#define CUBEMAP_SIDES 6
// Internal functions
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);
ILuint DecodePixelFormat();
void DxtcReadColor(ILushort Data, Color8888* Out);
void DxtcReadColors(const ILubyte* Data, Color8888* Out);
ILboolean DecompressARGB(ILuint CompFormat);
ILboolean DecompressARGB16(ILuint CompFormat);
ILboolean DecompressDXT1(ILimage *lImage, ILubyte *lCompData);
ILboolean DecompressDXT2(ILimage *lImage, ILubyte *lCompData);
ILboolean DecompressDXT3(ILimage *lImage, ILubyte *lCompData);
ILboolean DecompressDXT4(ILimage *lImage, ILubyte *lCompData);
ILboolean DecompressDXT5(ILimage *lImage, ILubyte *lCompData);
ILboolean Decompress3Dc();
ILboolean DecompressAti1n();
ILboolean DecompressRXGB();
ILboolean iConvFloat16ToFloat32(ILuint* dest, ILushort* src, ILuint size);
ILboolean DecompressFloat(ILuint lCompFormat);
void CorrectPreMult();
void GetBitsFromMask(ILuint Mask, ILuint *ShiftLeft, ILuint *ShiftRight);
ILboolean iSaveDdsInternal(void);
ILboolean WriteHeader(ILimage *Image, ILenum DXTCFormat, ILuint CubeFlags);
ILushort *CompressTo565(ILimage *Image);
ILubyte *CompressTo88(ILimage *Image);
ILuint Compress(ILimage *Image, ILenum DXTCFormat);
ILboolean GetBlock(ILushort *Block, ILushort *Data, ILimage *Image, ILuint XPos, ILuint YPos);
ILboolean GetAlphaBlock(ILubyte *Block, ILubyte *Data, ILimage *Image, ILuint XPos, ILuint YPos);
ILboolean Get3DcBlock(ILubyte *Block, ILubyte *Data, ILimage *Image, ILuint XPos, ILuint YPos, int channel);
void ShortToColor565(ILushort Pixel, Color565 *Colour);
void ShortToColor888(ILushort Pixel, Color888 *Colour);
ILushort Color565ToShort(Color565 *Colour);
ILushort Color888ToShort(Color888 *Colour);
ILuint GenBitMask(ILushort ex0, ILushort ex1, ILuint NumCols, ILushort *In, ILubyte *Alpha, Color888 *OutCol);
void GenAlphaBitMask(ILubyte a0, ILubyte a1, ILubyte *In, ILubyte *Mask, ILubyte *Out);
ILuint RMSAlpha(ILubyte *Orig, ILubyte *Test);
ILuint Distance(Color888 *c1, Color888 *c2);
void ChooseEndpoints(ILushort *Block, ILushort *ex0, ILushort *ex1);
void ChooseAlphaEndpoints(ILubyte *Block, ILubyte *a0, ILubyte *a1);
void CorrectEndDXT1(ILushort *ex0, ILushort *ex1, ILboolean HasAlpha);
void PreMult(ILushort *Data, ILubyte *Alpha);
extern ILuint CubemapDirections[CUBEMAP_SIDES];
#endif//DDS_H
@@ -0,0 +1,276 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2002 by Denton Woods
// Last modified: 05/25/2001 <--Y2K Compliant! =]
//
// Filename: src-IL/include/il_doompal.h
//
// Description: The default Doom palette
//
//-----------------------------------------------------------------------------
#ifndef DOOMPAL_H
#define DOOMPAL_H
#define IL_DOOMPAL_SIZE 768
ILubyte ilDefaultDoomPal[IL_DOOMPAL_SIZE] = {
0, 0, 0,
31, 23, 11,
23, 15, 7,
75, 75, 75,
255, 255, 255,
27, 27, 27,
19, 19, 19,
11, 11, 11,
7, 7, 7,
47, 55, 31,
35, 43, 15,
23, 31, 7,
15, 23, 0,
79, 59, 43,
71, 51, 35,
63, 43, 27,
255, 183, 183,
247, 171, 171,
243, 163, 163,
235, 151, 151,
231, 143, 143,
223, 135, 135,
219, 123, 123,
211, 115, 115,
203, 107, 107,
199, 99, 99,
191, 91, 91,
187, 87, 87,
179, 79, 79,
175, 71, 71,
167, 63, 63,
163, 59, 59,
155, 51, 51,
151, 47, 47,
143, 43, 43,
139, 35, 35,
131, 31, 31,
127, 27, 27,
119, 23, 23,
115, 19, 19,
107, 15, 15,
103, 11, 11,
95, 7, 7,
91, 7, 7,
83, 7, 7,
79, 0, 0,
71, 0, 0,
67, 0, 0,
255, 235, 223,
255, 227, 211,
255, 219, 199,
255, 211, 187,
255, 207, 179,
255, 199, 167,
255, 191, 155,
255, 187, 147,
255, 179, 131,
247, 171, 123,
239, 163, 115,
231, 155, 107,
223, 147, 99,
215, 139, 91,
207, 131, 83,
203, 127, 79,
191, 123, 75,
179, 115, 71,
171, 111, 67,
163, 107, 63,
155, 99, 59,
143, 95, 55,
135, 87, 51,
127, 83, 47,
119, 79, 43,
107, 71, 39,
95, 67, 35,
83, 63, 31,
75, 55, 27,
63, 47, 23,
51, 43, 19,
43, 35, 15,
239, 239, 239,
231, 231, 231,
223, 223, 223,
219, 219, 219,
211, 211, 211,
203, 203, 203,
199, 199, 199,
191, 191, 191,
183, 183, 183,
179, 179, 179,
171, 171, 171,
167, 167, 167,
159, 159, 159,
151, 151, 151,
147, 147, 147,
139, 139, 139,
131, 131, 131,
127, 127, 127,
119, 119, 119,
111, 111, 111,
107, 107, 107,
99, 99, 99,
91, 91, 91,
87, 87, 87,
79, 79, 79,
71, 71, 71,
67, 67, 67,
59, 59, 59,
55, 55, 55,
47, 47, 47,
39, 39, 39,
35, 35, 35,
119, 255, 111,
111, 239, 103,
103, 223, 95,
95, 207, 87,
91, 191, 79,
83, 175, 71,
75, 159, 63,
67, 147, 55,
63, 131, 47,
55, 115, 43,
47, 99, 35,
39, 83, 27,
31, 67, 23,
23, 51, 15,
19, 35, 11,
11, 23, 7,
191, 167, 143,
183, 159, 135,
175, 151, 127,
167, 143, 119,
159, 135, 111,
155, 127, 107,
147, 123, 99,
139, 115, 91,
131, 107, 87,
123, 99, 79,
119, 95, 75,
111, 87, 67,
103, 83, 63,
95, 75, 55,
87, 67, 51,
83, 63, 47,
159, 131, 99,
143, 119, 83,
131, 107, 75,
119, 95, 63,
103, 83, 51,
91, 71, 43,
79, 59, 35,
67, 51, 27,
123, 127, 99,
111, 115, 87,
103, 107, 79,
91, 99, 71,
83, 87, 59,
71, 79, 51,
63, 71, 43,
55, 63, 39,
255, 255, 115,
235, 219, 87,
215, 187, 67,
195, 155, 47,
175, 123, 31,
155, 91, 19,
135, 67, 7,
115, 43, 0,
255, 255, 255,
255, 219, 219,
255, 187, 187,
255, 155, 155,
255, 123, 123,
255, 95, 95,
255, 63, 63,
255, 31, 31,
255, 0, 0,
239, 0, 0,
227, 0, 0,
215, 0, 0,
203, 0, 0,
191, 0, 0,
179, 0, 0,
167, 0, 0,
155, 0, 0,
139, 0, 0,
127, 0, 0,
115, 0, 0,
103, 0, 0,
91, 0, 0,
79, 0, 0,
67, 0, 0,
231, 231, 255,
199, 199, 255,
171, 171, 255,
143, 143, 255,
115, 115, 255,
83, 83, 255,
55, 55, 255,
27, 27, 255,
0, 0, 255,
0, 0, 227,
0, 0, 203,
0, 0, 179,
0, 0, 155,
0, 0, 131,
0, 0, 107,
0, 0, 83,
255, 255, 255,
255, 235, 219,
255, 215, 187,
255, 199, 155,
255, 179, 123,
255, 163, 91,
255, 143, 59,
255, 127, 27,
243, 115, 23,
235, 111, 15,
223, 103, 15,
215, 95, 11,
203, 87, 7,
195, 79, 0,
183, 71, 0,
175, 67, 0,
255, 255, 255,
255, 255, 215,
255, 255, 179,
255, 255, 143,
255, 255, 107,
255, 255, 71,
255, 255, 35,
255, 255, 0,
167, 63, 0,
159, 55, 0,
147, 47, 0,
135, 35, 0,
79, 59, 39,
67, 47, 27,
55, 35, 19,
47, 27, 11,
0, 0, 83,
0, 0, 71,
0, 0, 59,
0, 0, 47,
0, 0, 35,
0, 0, 23,
0, 0, 11,
0, 255, 255,
255, 159, 67,
255, 231, 75,
255, 123, 255,
255, 0, 255,
207, 0, 207,
159, 0, 155,
111, 0, 107,
167, 107, 107
};
#endif//DOOMPAL_H
+150
View File
@@ -0,0 +1,150 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 02/26/2009
//
// Filename: src-IL/include/il_dpx.h
//
// Description: Reads from a Digital Picture Exchange (.dpx) file.
// Specifications for this format were found at
// http://www.cineon.com/ff_draft.php and
// http://www.fileformat.info/format/dpx/.
//
//-----------------------------------------------------------------------------
#ifndef DPX_H
#define DPX_H
#include "il_internal.h"
#ifdef _WIN32
#pragma pack(push, packed_struct, 1)
#endif
typedef struct R32
{
ILubyte r, g, b, a;
} IL_PACKSTRUCT R32;
#ifdef _WIN32
#pragma pack(pop, packed_struct)
#endif
typedef struct DPX_FILE_INFO
{
ILuint MagicNum; /* magic number 0x53445058 (SDPX) or 0x58504453 (XPDS) */
ILuint Offset; /* offset to image data in bytes */
ILbyte Vers[8]; /* which header format version is being used (v1.0)*/
ILuint FileSize; /* file size in bytes */
ILuint DittoKey; /* read time short cut - 0 = same, 1 = new */
ILuint GenHdrSize; /* generic header length in bytes */
ILuint IndHdrSize; /* industry header length in bytes */
ILuint UserDataSize; /* user-defined data length in bytes */
ILbyte FileName[100]; /* image file name */
ILbyte CreateTime[24]; /* file creation date "yyyy:mm:dd:hh:mm:ss:LTZ" */
ILbyte Creator[100]; /* file creator's name */
ILbyte Project[200]; /* project name */
ILbyte Copyright[200]; /* right to use or copyright info */
ILuint Key; /* encryption ( FFFFFFFF = unencrypted ) */
ILbyte Reserved[104]; /* reserved field TBD (need to pad) */
} DPX_FILE_INFO;
typedef struct DPX_IMAGE_ELEMENT
{
ILuint DataSign; /* data sign (0 = unsigned, 1 = signed ) */
/* "Core set images are unsigned" */
ILuint RefLowData; /* reference low data code value */
R32 RefLowQuantity; /* reference low quantity represented */
ILuint RefHighData; /* reference high data code value */
R32 RefHighQuantity;/* reference high quantity represented */
ILubyte Descriptor; /* descriptor for image element */
ILubyte Transfer; /* transfer characteristics for element */
ILubyte Colorimetric; /* colormetric specification for element */
ILubyte BitSize; /* bit size for element */
ILushort Packing; /* packing for element */
ILushort Encoding; /* encoding for element */
ILuint DataOffset; /* offset to data of element */
ILuint EolPadding; /* end of line padding used in element */
ILuint EoImagePadding; /* end of image padding used in element */
ILbyte Description[32];/* description of element */
} DPX_IMAGE_ELEMENT; /* NOTE THERE ARE EIGHT OF THESE */
typedef struct DPX_IMAGE_INFO
{
ILushort Orientation; /* image orientation */
ILushort NumElements; /* number of image elements */
ILuint Width; /* or x value */
ILuint Height; /* or y value, per element */
DPX_IMAGE_ELEMENT ImageElement[8];
ILubyte reserved[52]; /* reserved for future use (padding) */
} DPX_IMAGE_INFO;
typedef struct DPX_IMAGE_ORIENT
{
ILuint XOffset; /* X offset */
ILuint YOffset; /* Y offset */
R32 XCenter; /* X center */
R32 YCenter; /* Y center */
ILuint XOrigSize; /* X original size */
ILuint YOrigSize; /* Y original size */
ILbyte FileName[100]; /* source image file name */
ILbyte CreationTime[24]; /* source image creation date and time */
ILbyte InputDev[32]; /* input device name */
ILbyte InputSerial[32]; /* input device serial number */
ILushort Border[4]; /* border validity (XL, XR, YT, YB) */
ILuint PixelAspect[2]; /* pixel aspect ratio (H:V) */
ILubyte Reserved[28]; /* reserved for future use (padding) */
} DPX_IMAGE_ORIENT;
typedef struct DPX_MOTION_PICTURE_HEAD
{
ILbyte film_mfg_id[2]; /* film manufacturer ID code (2 digits from film edge code) */
ILbyte film_type[2]; /* file type (2 digits from film edge code) */
ILbyte offset[2]; /* offset in perfs (2 digits from film edge code)*/
ILbyte prefix[6]; /* prefix (6 digits from film edge code) */
ILbyte count[4]; /* count (4 digits from film edge code)*/
ILbyte format[32]; /* format (i.e. academy) */
ILuint frame_position; /* frame position in sequence */
ILuint sequence_len; /* sequence length in frames */
ILuint held_count; /* held count (1 = default) */
R32 frame_rate; /* frame rate of original in frames/sec */
R32 shutter_angle; /* shutter angle of camera in degrees */
ILbyte frame_id[32]; /* frame identification (i.e. keyframe) */
ILbyte slate_info[100]; /* slate information */
ILubyte reserved[56]; /* reserved for future use (padding) */
} DPX_MOTION_PICTURE_HEAD;
typedef struct DPX_TELEVISION_HEAD
{
ILuint tim_code; /* SMPTE time code */
ILuint userBits; /* SMPTE user bits */
ILubyte interlace; /* interlace ( 0 = noninterlaced, 1 = 2:1 interlace*/
ILubyte field_num; /* field number */
ILubyte video_signal; /* video signal standard (table 4)*/
ILubyte unused; /* used for byte alignment only */
R32 hor_sample_rate; /* horizontal sampling rate in Hz */
R32 ver_sample_rate; /* vertical sampling rate in Hz */
R32 frame_rate; /* temporal sampling rate or frame rate in Hz */
R32 time_offset; /* time offset from sync to first pixel */
R32 gamma; /* gamma value */
R32 black_level; /* black level code value */
R32 black_gain; /* black gain */
R32 break_point; /* breakpoint */
R32 white_level; /* reference white level code value */
R32 integration_times; /* integration time(s) */
ILubyte reserved[76]; /* reserved for future use (padding) */
} DPX_TELEVISION_HEAD;
// For checking and reading
ILboolean iIsValidDpx(void);
//ILboolean iCheckDpx(DPXHEAD *Header);
ILboolean iLoadDpxInternal(void);
#endif//PCX_H
+377
View File
@@ -0,0 +1,377 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 01/29/2009
//
// Filename: src-IL/include/il_endian.h
//
// Description: Handles Endian-ness
//
//-----------------------------------------------------------------------------
#ifndef IL_ENDIAN_H
#define IL_ENDIAN_H
#include "il_internal.h"
#ifdef WORDS_BIGENDIAN // This is defined by ./configure.
#ifndef __BIG_ENDIAN__
#define __BIG_ENDIAN__ 1
#endif
#endif
#if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __BIG_ENDIAN__) \
|| (defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__))
#undef __LITTLE_ENDIAN__
#define Short(s) iSwapShort(s)
#define UShort(s) iSwapUShort(s)
#define Int(i) iSwapInt(i)
#define UInt(i) iSwapUInt(i)
#define Float(f) iSwapFloat(f)
#define Double(d) iSwapDouble(d)
#define BigShort(s)
#define BigUShort(s)
#define BigInt(i)
#define BigUInt(i)
#define BigFloat(f)
#define BigDouble(d)
#else
#undef __BIG_ENDIAN__
#undef __LITTLE_ENDIAN__ // Not sure if it's defined by any compiler...
#define __LITTLE_ENDIAN__
#define Short(s)
#define UShort(s)
#define Int(i)
#define UInt(i)
#define Float(f)
#define Double(d)
#define BigShort(s) iSwapShort(s)
#define BigUShort(s) iSwapUShort(s)
#define BigInt(i) iSwapInt(i)
#define BigUInt(i) iSwapUInt(i)
#define BigFloat(f) iSwapFloat(f)
#define BigDouble(d) iSwapDouble(d)
#endif
void iSwapUShort(ILushort *s);
void iSwapShort(ILshort *s);
void iSwapUInt(ILuint *i);
void iSwapInt(ILint *i);
void iSwapFloat(ILfloat *f);
void iSwapDouble(ILdouble *d);
ILushort GetLittleUShort();
ILshort GetLittleShort();
ILuint GetLittleUInt();
ILint GetLittleInt();
ILfloat GetLittleFloat();
ILdouble GetLittleDouble();
ILushort GetBigUShort();
ILshort GetBigShort();
ILuint GetBigUInt();
ILint GetBigInt();
ILfloat GetBigFloat();
ILdouble GetBigDouble();
ILubyte SaveLittleUShort(ILushort s);
ILubyte SaveLittleShort(ILshort s);
ILubyte SaveLittleUInt(ILuint i);
ILubyte SaveLittleInt(ILint i);
ILubyte SaveLittleFloat(ILfloat f);
ILubyte SaveLittleDouble(ILdouble d);
ILubyte SaveBigUShort(ILushort s);
ILubyte SaveBigShort(ILshort s);
ILubyte SaveBigUInt(ILuint i);
ILubyte SaveBigInt(ILint i);
ILubyte SaveBigFloat(ILfloat f);
ILubyte SaveBigDouble(ILdouble d);
#ifdef IL_ENDIAN_C
#undef NOINLINE
#undef INLINE
#define INLINE
#endif
#ifndef NOINLINE
INLINE void iSwapUShort(ILushort *s) {
#ifdef USE_WIN32_ASM
__asm {
mov ebx, s
mov al, [ebx+1]
mov ah, [ebx ]
mov [ebx], ax
}
#else
#ifdef GCC_X86_ASM
asm("ror $8,%0"
: "=r" (*s)
: "0" (*s));
#else
*s = ((*s)>>8) | ((*s)<<8);
#endif //GCC_X86_ASM
#endif //USE_WIN32_ASM
}
INLINE void iSwapShort(ILshort *s) {
iSwapUShort((ILushort*)s);
}
INLINE void iSwapUInt(ILuint *i) {
#ifdef USE_WIN32_ASM
__asm {
mov ebx, i
mov eax, [ebx]
bswap eax
mov [ebx], eax
}
#else
#ifdef GCC_X86_ASM
asm("bswap %0;"
: "+r" (*i));
#else
*i = ((*i)>>24) | (((*i)>>8) & 0xff00) | (((*i)<<8) & 0xff0000) | ((*i)<<24);
#endif //GCC_X86_ASM
#endif //USE_WIN32_ASM
}
INLINE void iSwapInt(ILint *i) {
iSwapUInt((ILuint*)i);
}
INLINE void iSwapFloat(ILfloat *f) {
iSwapUInt((ILuint*)f);
}
INLINE void iSwapDouble(ILdouble *d) {
#ifdef GCC_X86_ASM
int *t = (int*)d;
asm("bswap %2 \n"
"bswap %3 \n"
"movl %2,%1 \n"
"movl %3,%0 \n"
: "=g" (t[0]), "=g" (t[1])
: "r" (t[0]), "r" (t[1]));
#else
ILubyte t,*b = (ILubyte*)d;
#define dswap(x,y) t=b[x];b[x]=b[y];b[y]=b[x];
dswap(0,7);
dswap(1,6);
dswap(2,5);
dswap(3,4);
#undef dswap
#endif
}
INLINE ILushort GetLittleUShort() {
ILushort s;
iread(&s, sizeof(ILushort), 1);
#ifdef __BIG_ENDIAN__
iSwapUShort(&s);
#endif
return s;
}
INLINE ILshort GetLittleShort() {
ILshort s;
iread(&s, sizeof(ILshort), 1);
#ifdef __BIG_ENDIAN__
iSwapShort(&s);
#endif
return s;
}
INLINE ILuint GetLittleUInt() {
ILuint i;
iread(&i, sizeof(ILuint), 1);
#ifdef __BIG_ENDIAN__
iSwapUInt(&i);
#endif
return i;
}
INLINE ILint GetLittleInt() {
ILint i;
iread(&i, sizeof(ILint), 1);
#ifdef __BIG_ENDIAN__
iSwapInt(&i);
#endif
return i;
}
INLINE ILfloat GetLittleFloat() {
ILfloat f;
iread(&f, sizeof(ILfloat), 1);
#ifdef __BIG_ENDIAN__
iSwapFloat(&f);
#endif
return f;
}
INLINE ILdouble GetLittleDouble() {
ILdouble d;
iread(&d, sizeof(ILdouble), 1);
#ifdef __BIG_ENDIAN__
iSwapDouble(&d);
#endif
return d;
}
INLINE ILushort GetBigUShort() {
ILushort s;
iread(&s, sizeof(ILushort), 1);
#ifdef __LITTLE_ENDIAN__
iSwapUShort(&s);
#endif
return s;
}
INLINE ILshort GetBigShort() {
ILshort s;
iread(&s, sizeof(ILshort), 1);
#ifdef __LITTLE_ENDIAN__
iSwapShort(&s);
#endif
return s;
}
INLINE ILuint GetBigUInt() {
ILuint i;
iread(&i, sizeof(ILuint), 1);
#ifdef __LITTLE_ENDIAN__
iSwapUInt(&i);
#endif
return i;
}
INLINE ILint GetBigInt() {
ILint i;
iread(&i, sizeof(ILint), 1);
#ifdef __LITTLE_ENDIAN__
iSwapInt(&i);
#endif
return i;
}
INLINE ILfloat GetBigFloat() {
ILfloat f;
iread(&f, sizeof(ILfloat), 1);
#ifdef __LITTLE_ENDIAN__
iSwapFloat(&f);
#endif
return f;
}
INLINE ILdouble GetBigDouble() {
ILdouble d;
iread(&d, sizeof(ILdouble), 1);
#ifdef __LITTLE_ENDIAN__
iSwapDouble(&d);
#endif
return d;
}
INLINE ILubyte SaveLittleUShort(ILushort s) {
#ifdef __BIG_ENDIAN__
iSwapUShort(&s);
#endif
return iwrite(&s, sizeof(ILushort), 1);
}
INLINE ILubyte SaveLittleShort(ILshort s) {
#ifdef __BIG_ENDIAN__
iSwapShort(&s);
#endif
return iwrite(&s, sizeof(ILshort), 1);
}
INLINE ILubyte SaveLittleUInt(ILuint i) {
#ifdef __BIG_ENDIAN__
iSwapUInt(&i);
#endif
return iwrite(&i, sizeof(ILuint), 1);
}
INLINE ILubyte SaveLittleInt(ILint i) {
#ifdef __BIG_ENDIAN__
iSwapInt(&i);
#endif
return iwrite(&i, sizeof(ILint), 1);
}
INLINE ILubyte SaveLittleFloat(ILfloat f) {
#ifdef __BIG_ENDIAN__
iSwapFloat(&f);
#endif
return iwrite(&f, sizeof(ILfloat), 1);
}
INLINE ILubyte SaveLittleDouble(ILdouble d) {
#ifdef __BIG_ENDIAN__
iSwapDouble(&d);
#endif
return iwrite(&d, sizeof(ILdouble), 1);
}
INLINE ILubyte SaveBigUShort(ILushort s) {
#ifdef __LITTLE_ENDIAN__
iSwapUShort(&s);
#endif
return iwrite(&s, sizeof(ILushort), 1);
}
INLINE ILubyte SaveBigShort(ILshort s) {
#ifdef __LITTLE_ENDIAN__
iSwapShort(&s);
#endif
return iwrite(&s, sizeof(ILshort), 1);
}
INLINE ILubyte SaveBigUInt(ILuint i) {
#ifdef __LITTLE_ENDIAN__
iSwapUInt(&i);
#endif
return iwrite(&i, sizeof(ILuint), 1);
}
INLINE ILubyte SaveBigInt(ILint i) {
#ifdef __LITTLE_ENDIAN__
iSwapInt(&i);
#endif
return iwrite(&i, sizeof(ILint), 1);
}
INLINE ILubyte SaveBigFloat(ILfloat f) {
#ifdef __LITTLE_ENDIAN__
iSwapFloat(&f);
#endif
return iwrite(&f, sizeof(ILfloat), 1);
}
INLINE ILubyte SaveBigDouble(ILdouble d) {
#ifdef __LITTLE_ENDIAN__
iSwapDouble(&d);
#endif
return iwrite(&d, sizeof(ILdouble), 1);
}
#endif//NOINLINE
void EndianSwapData(void *_Image);
#endif//ENDIAN_H
+90
View File
@@ -0,0 +1,90 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2008 by Denton Woods
// Last modified: 08/29/2008
//
// Filename: src-IL/include/il_exr.h
//
// Description: Reads from an OpenEXR (.exr) file.
//
//-----------------------------------------------------------------------------
#ifndef EXR_H
#define EXR_H
#include "il_internal.h"
#include <ImfIO.h>
//using namespace Imf; // Using this leads to errors with Microsoft's IStream.
// So it is better to just specify the namespace explicitly.
typedef struct EXRHEAD
{
ILuint MagicNumber; // File signature (0x76, 0x2f, 0x31, 0x01)
ILuint Version; // Treated as two bitfields
} IL_PACKSTRUCT EXRHEAD;
//@TODO: Should I just do these as enums?
#define EXR_UINT 0
#define EXR_HALF 1
#define EXR_FLOAT 2
#define EXR_NO_COMPRESSION 0
#define EXR_RLE_COMPRESSION 1
#define EXR_ZIPS_COMPRESSION 2
#define EXR_ZIP_COMPRESSION 3
#define EXR_PIZ_COMPRESSION 4
#define EXR_PXR24_COMPRESSION 5
#define EXR_B44_COMPRESSION 6
#define EXR_B44A_COMPRESSION 7
#ifdef __cplusplus
extern "C" {
#endif
ILboolean iIsValidExr();
ILboolean iCheckExr(EXRHEAD *Header);
ILboolean iLoadExrInternal();
ILboolean iSaveExrInternal();
#ifdef __cplusplus
}
#endif
class ilIStream : public Imf::IStream
{
public:
ilIStream(/*ILHANDLE Handle*/);
virtual bool read (char c[/*n*/], int n);
// I don't think I need this one, since we are taking care of the file handles ourselves.
//virtual char * readMemoryMapped (int n);
virtual Imf::Int64 tellg ();
virtual void seekg (Imf::Int64 Pos);
virtual void clear ();
protected:
private:
};
class ilOStream : public Imf::OStream
{
public:
ilOStream(/*ILHANDLE Handle*/);
virtual void write (const char c[/*n*/], int n);
// I don't think I need this one, since we are taking care of the file handles ourselves.
//virtual char * readMemoryMapped (int n);
virtual Imf::Int64 tellp ();
virtual void seekp (Imf::Int64 Pos);
protected:
private:
};
#endif//EXR_H
@@ -0,0 +1,79 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 01/04/2009
//
// Filename: src-IL/include/il_files.h
//
// Description: File handling for DevIL
//
//-----------------------------------------------------------------------------
#ifndef FILES_H
#define FILES_H
#if defined (__FILES_C)
#define __FILES_EXTERN
#else
#define __FILES_EXTERN extern
#endif
#include <IL/il.h>
__FILES_EXTERN void ILAPIENTRY iPreserveReadFuncs(void);
__FILES_EXTERN void ILAPIENTRY iRestoreReadFuncs(void);
__FILES_EXTERN void ILAPIENTRY iPreserveWriteFuncs(void);
__FILES_EXTERN void ILAPIENTRY iRestoreWriteFuncs(void);
__FILES_EXTERN fEofProc EofProc;
__FILES_EXTERN fGetcProc GetcProc;
__FILES_EXTERN fReadProc ReadProc;
__FILES_EXTERN fSeekRProc SeekRProc;
__FILES_EXTERN fSeekWProc SeekWProc;
__FILES_EXTERN fTellRProc TellRProc;
__FILES_EXTERN fTellWProc TellWProc;
__FILES_EXTERN fPutcProc PutcProc;
__FILES_EXTERN fWriteProc WriteProc;
__FILES_EXTERN ILHANDLE ILAPIENTRY iDefaultOpen(ILconst_string FileName);
__FILES_EXTERN void ILAPIENTRY iDefaultClose(ILHANDLE Handle);
__FILES_EXTERN ILint ILAPIENTRY iDefaultGetc(ILHANDLE Handle);
__FILES_EXTERN ILint ILAPIENTRY iDefaultRead(void *Buffer, ILuint Size, ILuint Number, ILHANDLE Handle);
__FILES_EXTERN ILint ILAPIENTRY iDefaultSeekR(ILHANDLE Handle, ILint Offset, ILint Mode);
__FILES_EXTERN ILint ILAPIENTRY iDefaultSeekW(ILHANDLE Handle, ILint Offset, ILint Mode);
__FILES_EXTERN ILint ILAPIENTRY iDefaultTellR(ILHANDLE Handle);
__FILES_EXTERN ILint ILAPIENTRY iDefaultTellW(ILHANDLE Handle);
__FILES_EXTERN ILint ILAPIENTRY iDefaultPutc(ILubyte Char, ILHANDLE Handle);
__FILES_EXTERN ILint ILAPIENTRY iDefaultWrite(const void *Buffer, ILuint Size, ILuint Number, ILHANDLE Handle);
__FILES_EXTERN void iSetInputFile(ILHANDLE File);
__FILES_EXTERN void iSetInputLump(const void *Lump, ILuint Size);
__FILES_EXTERN ILboolean (ILAPIENTRY *ieof)(void);
__FILES_EXTERN ILHANDLE (ILAPIENTRY *iopenr)(ILconst_string);
__FILES_EXTERN void (ILAPIENTRY *icloser)(ILHANDLE);
__FILES_EXTERN ILint (ILAPIENTRY *igetc)(void);
__FILES_EXTERN ILuint (ILAPIENTRY *iread)(void *Buffer, ILuint Size, ILuint Number);
__FILES_EXTERN ILint (ILAPIENTRY *iseek)(ILint Offset, ILuint Mode);
__FILES_EXTERN ILuint (ILAPIENTRY *itell)(void);
__FILES_EXTERN void iSetOutputFile(ILHANDLE File);
__FILES_EXTERN void iSetOutputLump(void *Lump, ILuint Size);
__FILES_EXTERN void iSetOutputFake(void);
__FILES_EXTERN void (ILAPIENTRY *iclosew)(ILHANDLE);
__FILES_EXTERN ILHANDLE (ILAPIENTRY *iopenw)(ILconst_string);
__FILES_EXTERN ILint (ILAPIENTRY *iputc)(ILubyte Char);
__FILES_EXTERN ILint (ILAPIENTRY *iseekw)(ILint Offset, ILuint Mode);
__FILES_EXTERN ILuint (ILAPIENTRY *itellw)(void);
__FILES_EXTERN ILint (ILAPIENTRY *iwrite)(const void *Buffer, ILuint Size, ILuint Number);
__FILES_EXTERN ILHANDLE ILAPIENTRY iGetFile(void);
__FILES_EXTERN const ILubyte* ILAPIENTRY iGetLump(void);
__FILES_EXTERN ILuint ILAPIENTRY ilprintf(const char *, ...);
__FILES_EXTERN void ipad(ILuint NumZeros);
__FILES_EXTERN ILboolean iPreCache(ILuint Size);
__FILES_EXTERN void iUnCache(void);
#endif//FILES_H
+71
View File
@@ -0,0 +1,71 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 02/14/2009
//
// Filename: src-IL/include/il_gif.h
//
// Description: Reads from a Graphics Interchange Format (.gif) file.
//
//-----------------------------------------------------------------------------
#ifndef GIF_H
#define GIF_H
#include "il_internal.h"
#define GIF87A 87
#define GIF89A 89
#ifdef _WIN32
#pragma pack(push, gif_struct, 1)
#endif
typedef struct GIFHEAD
{
char Sig[6];
ILushort Width;
ILushort Height;
ILubyte ColourInfo;
ILubyte Background;
ILubyte Aspect;
} IL_PACKSTRUCT GIFHEAD;
typedef struct IMAGEDESC
{
ILubyte Separator;
ILushort OffX;
ILushort OffY;
ILushort Width;
ILushort Height;
ILubyte ImageInfo;
} IL_PACKSTRUCT IMAGEDESC;
typedef struct GFXCONTROL
{
ILubyte Size;
ILubyte Packed;
ILushort Delay;
ILubyte Transparent;
ILubyte Terminator;
ILboolean Used; //this stores if a gfxcontrol was read - it is IL_FALSE (!)
//if a gfxcontrol was read from the file, IL_TRUE otherwise
} IL_PACKSTRUCT GFXCONTROL;
#ifdef _WIN32
#pragma pack(pop, gif_struct)
#endif
// Internal functions
ILboolean iLoadGifInternal(void);
ILboolean ilLoadGifF(ILHANDLE File);
ILboolean iIsValidGif(void);
ILboolean iGetPalette(ILubyte Info, ILpal *Pal, ILboolean UsePrevPal, ILimage *PrevImage);
ILboolean GetImages(ILpal *GlobalPal, GIFHEAD *GifHead);
ILboolean SkipExtensions(GFXCONTROL *Gfx);
ILboolean GifGetData(ILimage *Image, ILubyte *Data, ILuint ImageSize, ILuint Width, ILuint Height, ILuint Stride, ILuint PalOffset, GFXCONTROL *Gfx);
ILboolean RemoveInterlace(ILimage *image);
ILboolean ConvertTransparent(ILimage *Image, ILubyte TransColour);
#endif//GIF_H
+43
View File
@@ -0,0 +1,43 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2004 by Denton Woods (this file by thakis)
// Last modified: 06/09/2004
//
// Filename: src-IL/include/il_hdr.h
//
// Description: Reads a RADIANCE High Dynamic Range Image
//
//-----------------------------------------------------------------------------
#ifndef HDR_H
#define HDR_H
#include "il_internal.h"
#ifdef _WIN32
#pragma pack(push, gif_struct, 1)
#endif
typedef struct HDRHEADER
{
char Signature[10]; //must be "#?RADIANCE"
ILuint Width, Height;
} IL_PACKSTRUCT HDRHEADER;
#ifdef _WIN32
#pragma pack(pop, gif_struct)
#endif
// Internal functions
ILboolean ilIsValidHdrF(ILHANDLE file);
ILboolean iIsValidHdr();
ILboolean iCheckHdr(HDRHEADER *Header);
ILboolean ilLoadHdrF(ILHANDLE file);
ILboolean iLoadHdrInternal();
ILboolean iSaveHdrInternal();
void ReadScanline(ILubyte *scanline, ILuint w);
#endif//HDR_H
+42
View File
@@ -0,0 +1,42 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2008 by Denton Woods
// Last modified: 08/23/2008
//
// Filename: src-IL/include/il_icns.h
//
// Description: Reads from a Mac OS X icon (.icns) file.
//
//-----------------------------------------------------------------------------
#ifndef ICNS_H
#define ICNS_H
#include "il_internal.h"
#ifdef _WIN32
#pragma pack(push, icns_struct, 1)
#endif
typedef struct ICNSHEAD
{
char Head[4]; // Must be 'ICNS'
ILint Size; // Total size of the file (including header)
} IL_PACKSTRUCT ICNSHEAD;
typedef struct ICNSDATA
{
char ID[4]; // Identifier ('it32', 'il32', etc.)
ILint Size; // Total size of the entry (including identifier)
} IL_PACKSTRUCT ICNSDATA;
#ifdef _WIN32
#pragma pack(pop, icns_struct)
#endif
ILboolean iIsValidIcns();
ILboolean iLoadIcnsInternal();
ILboolean iIcnsReadData(ILboolean *BaseCreated, ILboolean IsAlpha, ILint Width, ICNSDATA *Entry, ILimage **Image);
#endif//ICNS_H
+70
View File
@@ -0,0 +1,70 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2002 by Denton Woods
// Last modified: 05/25/2001 <--Y2K Compliant! =]
//
// Filename: src-IL/include/il_icon.h
//
// Description: Reads from a Windows icon (.ico) file.
//
//-----------------------------------------------------------------------------
#ifndef ICON_H
#define ICON_H
#include "il_internal.h"
#ifdef _WIN32
#pragma pack(push, ico_struct, 1)
#endif
typedef struct ICODIR
{
ILshort Reserved; // Reserved (must be 0)
ILshort Type; // Type (1 for icons, 2 for cursors)
ILshort Count; // How many different images?
} IL_PACKSTRUCT ICODIR;
typedef struct ICODIRENTRY
{
ILubyte Width; // Width, in pixels
ILubyte Height; // Height, in pixels
ILubyte NumColours; // Number of colors in image (0 if >=8bpp)
ILubyte Reserved; // Reserved (must be 0)
ILshort Planes; // Colour planes
ILshort Bpp; // Bits per pixel
ILuint SizeOfData; // How many bytes in this resource?
ILuint Offset; // Offset from beginning of the file
} IL_PACKSTRUCT ICODIRENTRY;
typedef struct INFOHEAD
{
ILint Size;
ILint Width;
ILint Height;
ILshort Planes;
ILshort BitCount;
ILint Compression;
ILint SizeImage;
ILint XPixPerMeter;
ILint YPixPerMeter;
ILint ColourUsed;
ILint ColourImportant;
} IL_PACKSTRUCT INFOHEAD;
typedef struct ICOIMAGE
{
INFOHEAD Head;
ILubyte *Pal; // Palette
ILubyte *Data; // XOR mask
ILubyte *AND; // AND mask
} ICOIMAGE;
#ifdef _WIN32
#pragma pack(pop, ico_struct)
#endif
ILboolean iLoadIconInternal();
ILboolean iLoadIconPNG(ICOIMAGE *Icon);
#endif//ICON_H
@@ -0,0 +1,539 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 03/01/2009
//
// Filename: src-IL/include/il_internal.h
//
// Description: Internal stuff for DevIL
//
//-----------------------------------------------------------------------------
#ifndef INTERNAL_H
#define INTERNAL_H
#define _IL_BUILD_LIBRARY
// Local headers
/*#if (defined(_WIN32) || defined(_WIN64)) && !defined(HAVE_CONFIG_H)
#define HAVE_CONFIG_H
#endif*/
#ifdef HAVE_CONFIG_H //if we use autotools, we have HAVE_CONFIG_H defined and we have to look for it like that
#include <config.h>
#else // If we do not use autotools, we have to point to (possibly different) config.h than in the opposite case
#include <IL/config.h>
#endif
// Standard headers
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <IL/il.h>
#include <IL/devil_internal_exports.h>
#include "il_files.h"
#include "il_endian.h"
#ifndef _WIN32
// The Microsoft HD Photo Device Porting Kit has not been ported to anything other
// than Windows yet, so we disable this if Windows is not the current platform.
#define IL_NO_WDP
#endif//_WIN32
// If we do not want support for game image formats, this define removes them all.
#ifdef IL_NO_GAMES
#define IL_NO_BLP
#define IL_NO_DOOM
#define IL_NO_FTX
#define IL_NO_IWI
#define IL_NO_LIF
#define IL_NO_MDL
#define IL_NO_ROT
#define IL_NO_TPL
#define IL_NO_UTX
#define IL_NO_WAL
#endif//IL_NO_GAMES
// If we want to compile without support for formats supported by external libraries,
// this define will remove them all.
#ifdef IL_NO_EXTLIBS
#define IL_NO_EXR
#define IL_NO_JP2
#define IL_NO_JPG
#define IL_NO_LCMS
#define IL_NO_MNG
#define IL_NO_PNG
#define IL_NO_TIF
#define IL_NO_WDP
#undef IL_USE_DXTC_NVIDIA
#undef IL_USE_DXTC_SQUISH
#endif//IL_NO_EXTLIBS
// Windows-specific
#ifdef _WIN32
#ifdef _MSC_VER
#if _MSC_VER > 1000
#pragma once
#pragma intrinsic(memcpy)
#pragma intrinsic(memset)
#pragma intrinsic(strcmp)
#pragma intrinsic(strlen)
#pragma intrinsic(strcpy)
#if _MSC_VER >= 1300
#pragma warning(disable : 4996) // MSVC++ 8/9 deprecation warnings
#endif
#endif // _MSC_VER > 1000
#endif
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <windows.h>
#endif//_WIN32
#ifdef _UNICODE
#define IL_TEXT(s) L##s
#ifndef _WIN32 // At least in Linux, fopen works fine, and wcsicmp is not defined.
#define wcsicmp wcsncasecmp
#define _wcsicmp wcsncasecmp
#define _wfopen fopen
#endif
#define iStrCpy wcscpy
#else
#define IL_TEXT(s) (s)
#define iStrCpy strcpy
#endif
#ifdef IL_INLINE_ASM
#if (defined (_MSC_VER) && defined(_WIN32)) // MSVC++ only
#define USE_WIN32_ASM
#endif
#ifdef _WIN64
#undef USE_WIN32_ASM
//@TODO: Windows 64 compiler cannot use inline ASM, so we need to
// generate some MASM code at some point.
#endif
#ifdef _WIN32_WCE // Cannot use our inline ASM in Windows Mobile.
#undef USE_WIN32_ASM
#endif
#endif
extern ILimage *iCurImage;
#define BIT_0 0x00000001
#define BIT_1 0x00000002
#define BIT_2 0x00000004
#define BIT_3 0x00000008
#define BIT_4 0x00000010
#define BIT_5 0x00000020
#define BIT_6 0x00000040
#define BIT_7 0x00000080
#define BIT_8 0x00000100
#define BIT_9 0x00000200
#define BIT_10 0x00000400
#define BIT_11 0x00000800
#define BIT_12 0x00001000
#define BIT_13 0x00002000
#define BIT_14 0x00004000
#define BIT_15 0x00008000
#define BIT_16 0x00010000
#define BIT_17 0x00020000
#define BIT_18 0x00040000
#define BIT_19 0x00080000
#define BIT_20 0x00100000
#define BIT_21 0x00200000
#define BIT_22 0x00400000
#define BIT_23 0x00800000
#define BIT_24 0x01000000
#define BIT_25 0x02000000
#define BIT_26 0x04000000
#define BIT_27 0x08000000
#define BIT_28 0x10000000
#define BIT_29 0x20000000
#define BIT_30 0x40000000
#define BIT_31 0x80000000
#define NUL '\0' // Easier to type and ?portable?
#if !_WIN32 || _WIN32_WCE
int stricmp(const char *src1, const char *src2);
int strnicmp(const char *src1, const char *src2, size_t max);
#endif//_WIN32
#ifdef _WIN32_WCE
char *strdup(const char *src);
#endif
int iStrCmp(ILconst_string src1, ILconst_string src2);
//
// Some math functions
//
// A fast integer squareroot, completely accurate for x < 289.
// Taken from http://atoms.org.uk/sqrt/
// There is also a version that is accurate for all integers
// < 2^31, if we should need it
int iSqrt(int x);
//
// Useful miscellaneous functions
//
ILboolean iCheckExtension(ILconst_string Arg, ILconst_string Ext);
ILbyte* iFgets(char *buffer, ILuint maxlen);
ILboolean iFileExists(ILconst_string FileName);
ILstring iGetExtension(ILconst_string FileName);
ILstring ilStrDup(ILconst_string Str);
ILuint ilStrLen(ILconst_string Str);
ILuint ilCharStrLen(const char *Str);
// Miscellaneous functions
void ilDefaultStates(void);
ILenum iGetHint(ILenum Target);
ILint iGetInt(ILenum Mode);
void ilRemoveRegistered(void);
ILAPI void ILAPIENTRY ilSetCurImage(ILimage *Image);
ILuint ilDetermineSize(ILenum Type);
//
// Rle compression
//
#define IL_TGACOMP 0x01
#define IL_PCXCOMP 0x02
#define IL_SGICOMP 0x03
#define IL_BMPCOMP 0x04
ILboolean ilRleCompressLine(ILubyte *ScanLine, ILuint Width, ILubyte Bpp, ILubyte *Dest, ILuint *DestWidth, ILenum CompressMode);
ILuint ilRleCompress(ILubyte *Data, ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp, ILubyte *Dest, ILenum CompressMode, ILuint *ScanTable);
void iSetImage0(void);
// DXTC compression
ILuint ilNVidiaCompressDXTFile(ILubyte *Data, ILuint Width, ILuint Height, ILuint Depth, ILenum DxtType);
ILAPI ILubyte* ILAPIENTRY ilNVidiaCompressDXT(ILubyte *Data, ILuint Width, ILuint Height, ILuint Depth, ILenum DxtFormat, ILuint *DxtSize);
ILAPI ILubyte* ILAPIENTRY ilSquishCompressDXT(ILubyte *Data, ILuint Width, ILuint Height, ILuint Depth, ILenum DxtFormat, ILuint *DxtSize);
// Conversion functions
ILboolean ilAddAlpha(void);
ILboolean ilAddAlphaKey(ILimage *Image);
ILboolean iFastConvert(ILenum DestFormat);
ILboolean ilFixCur(void);
ILboolean ilFixImage(void);
ILboolean ilRemoveAlpha(void);
ILboolean ilSwapColours(void);
// Palette functions
ILboolean iCopyPalette(ILpal *Dest, ILpal *Src);
// Miscellaneous functions
char* iGetString(ILenum StringName); // Internal version of ilGetString
//
// Image loading/saving functions
//
ILboolean ilIsValidBlp(ILconst_string FileName);
ILboolean ilIsValidBlpF(ILHANDLE File);
ILboolean ilIsValidBlpL(const void *Lump, ILuint Size);
ILboolean ilLoadBlp(ILconst_string FileName);
ILboolean ilLoadBlpF(ILHANDLE File);
ILboolean ilLoadBlpL(const void *Lump, ILuint Size);
ILboolean ilIsValidBmp(ILconst_string CONST_RESTRICT FileName);
ILboolean ilIsValidBmpF(ILHANDLE File);
ILboolean ilIsValidBmpL(const void *Lump, ILuint Size);
ILboolean ilLoadBmp(ILconst_string FileName);
ILboolean ilLoadBmpF(ILHANDLE File);
ILboolean ilLoadBmpL(const void *Lump, ILuint Size);
ILboolean ilSaveBmp(ILconst_string FileName);
ILuint ilSaveBmpF(ILHANDLE File);
ILuint ilSaveBmpL(void *Lump, ILuint Size);
ILboolean ilSaveCHeader(ILconst_string FileName, char *InternalName);
ILboolean ilLoadCut(ILconst_string FileName);
ILboolean ilLoadCutF(ILHANDLE File);
ILboolean ilLoadCutL(const void *Lump, ILuint Size);
ILboolean ilIsValidDcx(ILconst_string FileName);
ILboolean ilIsValidDcxF(ILHANDLE File);
ILboolean ilIsValidDcxL(const void *Lump, ILuint Size);
ILboolean ilLoadDcx(ILconst_string FileName);
ILboolean ilLoadDcxF(ILHANDLE File);
ILboolean ilLoadDcxL(const void *Lump, ILuint Size);
ILboolean ilIsValidDds(ILconst_string FileName);
ILboolean ilIsValidDdsF(ILHANDLE File);
ILboolean ilIsValidDdsL(const void *Lump, ILuint Size);
ILboolean ilLoadDds(ILconst_string FileName);
ILboolean ilLoadDdsF(ILHANDLE File);
ILboolean ilLoadDdsL(const void *Lump, ILuint Size);
ILboolean ilSaveDds(ILconst_string FileName);
ILuint ilSaveDdsF(ILHANDLE File);
ILuint ilSaveDdsL(void *Lump, ILuint Size);
ILboolean ilIsValidDicom(ILconst_string FileName);
ILboolean ilIsValidDicomF(ILHANDLE File);
ILboolean ilIsValidDicomL(const void *Lump, ILuint Size);
ILboolean ilLoadDicom(ILconst_string FileName);
ILboolean ilLoadDicomF(ILHANDLE File);
ILboolean ilLoadDicomL(const void *Lump, ILuint Size);
ILboolean ilLoadDoom(ILconst_string FileName);
ILboolean ilLoadDoomF(ILHANDLE File);
ILboolean ilLoadDoomL(const void *Lump, ILuint Size);
ILboolean ilLoadDoomFlat(ILconst_string FileName);
ILboolean ilLoadDoomFlatF(ILHANDLE File);
ILboolean ilLoadDoomFlatL(const void *Lump, ILuint Size);
ILboolean ilIsValidDpx(ILconst_string FileName);
ILboolean ilIsValidDpxF(ILHANDLE File);
ILboolean ilIsValidDpxL(const void *Lump, ILuint Size);
ILboolean ilLoadDpx(ILconst_string FileName);
ILboolean ilLoadDpxF(ILHANDLE File);
ILboolean ilLoadDpxL(const void *Lump, ILuint Size);
ILboolean ilIsValidExr(ILconst_string FileName);
ILboolean ilIsValidExrF(ILHANDLE File);
ILboolean ilIsValidExrL(const void *Lump, ILuint Size);
ILboolean ilLoadExr(ILconst_string FileName);
ILboolean ilLoadExrF(ILHANDLE File);
ILboolean ilLoadExrL(const void *Lump, ILuint Size);
ILboolean ilSaveExr(ILconst_string FileName);
ILuint ilSaveExrF(ILHANDLE File);
ILuint ilSaveExrL(void *Lump, ILuint Size);
ILboolean ilIsValidFits(ILconst_string FileName);
ILboolean ilIsValidFitsF(ILHANDLE File);
ILboolean ilIsValidFitsL(const void *Lump, ILuint Size);
ILboolean ilLoadFits(ILconst_string FileName);
ILboolean ilLoadFitsF(ILHANDLE File);
ILboolean ilLoadFitsL(const void *Lump, ILuint Size);
ILboolean ilLoadFtx(ILconst_string FileName);
ILboolean ilLoadFtxF(ILHANDLE File);
ILboolean ilLoadFtxL(const void *Lump, ILuint Size);
ILboolean ilIsValidGif(ILconst_string FileName);
ILboolean ilIsValidGifF(ILHANDLE File);
ILboolean ilIsValidGifL(const void *Lump, ILuint Size);
ILboolean ilLoadGif(ILconst_string FileName);
ILboolean ilLoadGifF(ILHANDLE File);
ILboolean ilLoadGifL(const void *Lump, ILuint Size);
ILboolean ilIsValidHdr(ILconst_string FileName);
ILboolean ilIsValidHdrF(ILHANDLE File);
ILboolean ilIsValidHdrL(const void *Lump, ILuint Size);
ILboolean ilLoadHdr(ILconst_string FileName);
ILboolean ilLoadHdrF(ILHANDLE File);
ILboolean ilLoadHdrL(const void *Lump, ILuint Size);
ILboolean ilSaveHdr(ILconst_string FileName);
ILuint ilSaveHdrF(ILHANDLE File);
ILuint ilSaveHdrL(void *Lump, ILuint Size);
ILboolean ilLoadIcon(ILconst_string FileName);
ILboolean ilLoadIconF(ILHANDLE File);
ILboolean ilLoadIconL(const void *Lump, ILuint Size);
ILboolean ilIsValidIcns(ILconst_string FileName);
ILboolean ilIsValidIcnsF(ILHANDLE File);
ILboolean ilIsValidIcnsL(const void *Lump, ILuint Size);
ILboolean ilLoadIcns(ILconst_string FileName);
ILboolean ilLoadIcnsF(ILHANDLE File);
ILboolean ilLoadIcnsL(const void *Lump, ILuint Size);
ILboolean ilLoadIff(ILconst_string FileName);
ILboolean ilLoadIffF(ILHANDLE File);
ILboolean ilLoadIffL(const void *Lump, ILuint Size);
ILboolean ilIsValidIlbm(ILconst_string FileName);
ILboolean ilIsValidIlbmF(ILHANDLE File);
ILboolean ilIsValidIlbmL(const void *Lump, ILuint Size);
ILboolean ilLoadIlbm(ILconst_string FileName);
ILboolean ilLoadIlbmF(ILHANDLE File);
ILboolean ilLoadIlbmL(const void *Lump, ILuint Size);
ILboolean ilIsValidIwi(ILconst_string FileName);
ILboolean ilIsValidIwiF(ILHANDLE File);
ILboolean ilIsValidIwiL(const void *Lump, ILuint Size);
ILboolean ilLoadIwi(ILconst_string FileName);
ILboolean ilLoadIwiF(ILHANDLE File);
ILboolean ilLoadIwiL(const void *Lump, ILuint Size);
ILboolean ilIsValidJp2(ILconst_string FileName);
ILboolean ilIsValidJp2F(ILHANDLE File);
ILboolean ilIsValidJp2L(const void *Lump, ILuint Size);
ILboolean ilLoadJp2(ILconst_string FileName);
ILboolean ilLoadJp2F(ILHANDLE File);
ILboolean ilLoadJp2L(const void *Lump, ILuint Size);
ILboolean ilLoadJp2LInternal(const void *Lump, ILuint Size, ILimage *Image);
ILboolean ilSaveJp2(ILconst_string FileName);
ILuint ilSaveJp2F(ILHANDLE File);
ILuint ilSaveJp2L(void *Lump, ILuint Size);
ILboolean ilIsValidJpeg(ILconst_string FileName);
ILboolean ilIsValidJpegF(ILHANDLE File);
ILboolean ilIsValidJpegL(const void *Lump, ILuint Size);
ILboolean ilLoadJpeg(ILconst_string FileName);
ILboolean ilLoadJpegF(ILHANDLE File);
ILboolean ilLoadJpegL(const void *Lump, ILuint Size);
ILboolean ilSaveJpeg(ILconst_string FileName);
ILuint ilSaveJpegF(ILHANDLE File);
ILuint ilSaveJpegL(void *Lump, ILuint Size);
ILboolean ilIsValidLif(ILconst_string FileName);
ILboolean ilIsValidLifF(ILHANDLE File);
ILboolean ilIsValidLifL(const void *Lump, ILuint Size);
ILboolean ilLoadLif(ILconst_string FileName);
ILboolean ilLoadLifF(ILHANDLE File);
ILboolean ilLoadLifL(const void *Lump, ILuint Size);
ILboolean ilIsValidMdl(ILconst_string FileName);
ILboolean ilIsValidMdlF(ILHANDLE File);
ILboolean ilIsValidMdlL(const void *Lump, ILuint Size);
ILboolean ilLoadMdl(ILconst_string FileName);
ILboolean ilLoadMdlF(ILHANDLE File);
ILboolean ilLoadMdlL(const void *Lump, ILuint Size);
ILboolean ilLoadMng(ILconst_string FileName);
ILboolean ilLoadMngF(ILHANDLE File);
ILboolean ilLoadMngL(const void *Lump, ILuint Size);
ILboolean ilSaveMng(ILconst_string FileName);
ILuint ilSaveMngF(ILHANDLE File);
ILuint ilSaveMngL(void *Lump, ILuint Size);
ILboolean ilIsValidMp3(ILconst_string FileName);
ILboolean ilIsValidMp3F(ILHANDLE File);
ILboolean ilIsValidMp3L(const void *Lump, ILuint Size);
ILboolean ilLoadMp3(ILconst_string FileName);
ILboolean ilLoadMp3F(ILHANDLE File);
ILboolean ilLoadMp3L(const void *Lump, ILuint Size);
ILboolean ilLoadPcd(ILconst_string FileName);
ILboolean ilLoadPcdF(ILHANDLE File);
ILboolean ilLoadPcdL(const void *Lump, ILuint Size);
ILboolean ilIsValidPcx(ILconst_string FileName);
ILboolean ilIsValidPcxF(ILHANDLE File);
ILboolean ilIsValidPcxL(const void *Lump, ILuint Size);
ILboolean ilLoadPcx(ILconst_string FileName);
ILboolean ilLoadPcxF(ILHANDLE File);
ILboolean ilLoadPcxL(const void *Lump, ILuint Size);
ILboolean ilSavePcx(ILconst_string FileName);
ILuint ilSavePcxF(ILHANDLE File);
ILuint ilSavePcxL(void *Lump, ILuint Size);
ILboolean ilIsValidPic(ILconst_string FileName);
ILboolean ilIsValidPicF(ILHANDLE File);
ILboolean ilIsValidPicL(const void *Lump, ILuint Size);
ILboolean ilLoadPic(ILconst_string FileName);
ILboolean ilLoadPicF(ILHANDLE File);
ILboolean ilLoadPicL(const void *Lump, ILuint Size);
ILboolean ilLoadPix(ILconst_string FileName);
ILboolean ilLoadPixF(ILHANDLE File);
ILboolean ilLoadPixL(const void *Lump, ILuint Size);
ILboolean ilIsValidPng(ILconst_string FileName);
ILboolean ilIsValidPngF(ILHANDLE File);
ILboolean ilIsValidPngL(const void *Lump, ILuint Size);
ILboolean ilLoadPng(ILconst_string FileName);
ILboolean ilLoadPngF(ILHANDLE File);
ILboolean ilLoadPngL(const void *Lump, ILuint Size);
ILboolean ilSavePng(ILconst_string FileName);
ILuint ilSavePngF(ILHANDLE File);
ILuint ilSavePngL(void *Lump, ILuint Size);
ILboolean ilIsValidPnm(ILconst_string FileName);
ILboolean ilIsValidPnmF(ILHANDLE File);
ILboolean ilIsValidPnmL(const void *Lump, ILuint Size);
ILboolean ilLoadPnm(ILconst_string FileName);
ILboolean ilLoadPnmF(ILHANDLE File);
ILboolean ilLoadPnmL(const void *Lump, ILuint Size);
ILboolean ilSavePnm(ILconst_string FileName);
ILuint ilSavePnmF(ILHANDLE File);
ILuint ilSavePnmL(void *Lump, ILuint Size);
ILboolean ilIsValidPsd(ILconst_string FileName);
ILboolean ilIsValidPsdF(ILHANDLE File);
ILboolean ilIsValidPsdL(const void *Lump, ILuint Size);
ILboolean ilLoadPsd(ILconst_string FileName);
ILboolean ilLoadPsdF(ILHANDLE File);
ILboolean ilLoadPsdL(const void *Lump, ILuint Size);
ILboolean ilSavePsd(ILconst_string FileName);
ILuint ilSavePsdF(ILHANDLE File);
ILuint ilSavePsdL(void *Lump, ILuint Size);
ILboolean ilIsValidPsp(ILconst_string FileName);
ILboolean ilIsValidPspF(ILHANDLE File);
ILboolean ilIsValidPspL(const void *Lump, ILuint Size);
ILboolean ilLoadPsp(ILconst_string FileName);
ILboolean ilLoadPspF(ILHANDLE File);
ILboolean ilLoadPspL(const void *Lump, ILuint Size);
ILboolean ilLoadPxr(ILconst_string FileName);
ILboolean ilLoadPxrF(ILHANDLE File);
ILboolean ilLoadPxrL(const void *Lump, ILuint Size);
ILboolean ilLoadRaw(ILconst_string FileName);
ILboolean ilLoadRawF(ILHANDLE File);
ILboolean ilLoadRawL(const void *Lump, ILuint Size);
ILboolean ilSaveRaw(ILconst_string FileName);
ILuint ilSaveRawF(ILHANDLE File);
ILuint ilSaveRawL(void *Lump, ILuint Size);
ILboolean ilLoadRot(ILconst_string FileName);
ILboolean ilLoadRotF(ILHANDLE File);
ILboolean ilLoadRotL(const void *Lump, ILuint Size);
ILboolean ilIsValidRot(ILconst_string FileName);
ILboolean ilIsValidRotF(ILHANDLE File);
ILboolean ilIsValidRotL(const void *Lump, ILuint Size);
ILboolean ilIsValidSgi(ILconst_string FileName);
ILboolean ilIsValidSgiF(ILHANDLE File);
ILboolean ilIsValidSgiL(const void *Lump, ILuint Size);
ILboolean ilLoadSgi(ILconst_string FileName);
ILboolean ilLoadSgiF(ILHANDLE File);
ILboolean ilLoadSgiL(const void *Lump, ILuint Size);
ILboolean ilSaveSgi(ILconst_string FileName);
ILuint ilSaveSgiF(ILHANDLE File);
ILuint ilSaveSgiL(void *Lump, ILuint Size);
ILboolean ilIsValidSun(ILconst_string FileName);
ILboolean ilIsValidSunF(ILHANDLE File);
ILboolean ilIsValidSunL(const void *Lump, ILuint Size);
ILboolean ilLoadSun(ILconst_string FileName);
ILboolean ilLoadSunF(ILHANDLE File);
ILboolean ilLoadSunL(const void *Lump, ILuint Size);
ILboolean ilIsValidTga(ILconst_string FileName);
ILboolean ilIsValidTgaF(ILHANDLE File);
ILboolean ilIsValidTgaL(const void *Lump, ILuint Size);
ILboolean ilLoadTarga(ILconst_string FileName);
ILboolean ilLoadTargaF(ILHANDLE File);
ILboolean ilLoadTargaL(const void *Lump, ILuint Size);
ILboolean ilSaveTarga(ILconst_string FileName);
ILuint ilSaveTargaF(ILHANDLE File);
ILuint ilSaveTargaL(void *Lump, ILuint Size);
ILboolean ilLoadTexture(ILconst_string FileName);
ILboolean ilLoadTextureF(ILHANDLE File);
ILboolean ilLoadTextureL(const void *Lump, ILuint Size);
ILboolean ilIsValidTiff(ILconst_string FileName);
ILboolean ilIsValidTiffF(ILHANDLE File);
ILboolean ilIsValidTiffL(const void *Lump, ILuint Size);
ILboolean ilLoadTiff(ILconst_string FileName);
ILboolean ilLoadTiffF(ILHANDLE File);
ILboolean ilLoadTiffL(const void *Lump, ILuint Size);
ILboolean ilSaveTiff(ILconst_string FileName);
ILuint ilSaveTiffF(ILHANDLE File);
ILuint ilSaveTiffL(void *Lump, ILuint Size);
ILboolean ilIsValidTpl(ILconst_string FileName);
ILboolean ilIsValidTplF(ILHANDLE File);
ILboolean ilIsValidTplL(const void *Lump, ILuint Size);
ILboolean ilLoadTpl(ILconst_string FileName);
ILboolean ilLoadTplF(ILHANDLE File);
ILboolean ilLoadTplL(const void *Lump, ILuint Size);
ILboolean ilLoadUtx(ILconst_string FileName);
ILboolean ilLoadUtxF(ILHANDLE File);
ILboolean ilLoadUtxL(const void *Lump, ILuint Size);
ILboolean ilIsValidVtf(ILconst_string FileName);
ILboolean ilIsValidVtfF(ILHANDLE File);
ILboolean ilIsValidVtfL(const void *Lump, ILuint Size);
ILboolean ilLoadVtf(ILconst_string FileName);
ILboolean ilLoadVtfF(ILHANDLE File);
ILboolean ilLoadVtfL(const void *Lump, ILuint Size);
ILboolean ilSaveVtf(ILconst_string FileName);
ILuint ilSaveVtfF(ILHANDLE File);
ILuint ilSaveVtfL(void *Lump, ILuint Size);ILboolean ilLoadWal(ILconst_string FileName);
ILboolean ilLoadWalF(ILHANDLE File);
ILboolean ilLoadWalL(const void *Lump, ILuint Size);
ILboolean ilLoadWbmp(ILconst_string FileName);
ILboolean ilLoadWbmpF(ILHANDLE File);
ILboolean ilLoadWbmpL(const void *Lump, ILuint Size);
ILboolean ilSaveWbmp(ILconst_string FileName);
ILuint ilSaveWbmpF(ILHANDLE File);
ILuint ilSaveWbmpL(void *Lump, ILuint Size);
ILboolean ilIsValidWdp(ILconst_string FileName);
ILboolean ilIsValidWdpF(ILHANDLE File);
ILboolean ilIsValidWdpL(const void *Lump, ILuint Size);
ILboolean ilLoadWdp(ILconst_string FileName);
ILboolean ilLoadWdpF(ILHANDLE File);
ILboolean ilLoadWdpL(const void *Lump, ILuint Size);
ILboolean ilIsValidXpm(ILconst_string FileName);
ILboolean ilIsValidXpmF(ILHANDLE File);
ILboolean ilIsValidXpmL(const void *Lump, ILuint Size);
ILboolean ilLoadXpm(ILconst_string FileName);
ILboolean ilLoadXpmF(ILHANDLE File);
ILboolean ilLoadXpmL(const void *Lump, ILuint Size);
// OpenEXR is written in C++, so we have to wrap this to avoid linker errors.
/*#ifndef IL_NO_EXR
#ifdef __cplusplus
extern "C" {
#endif
ILboolean ilLoadExr(ILconst_string FileName);
#ifdef __cplusplus
}
#endif
#endif*/
//ILboolean ilLoadExr(ILconst_string FileName);
#ifdef __cplusplus
}
#endif
#endif//INTERNAL_H
+22
View File
@@ -0,0 +1,22 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2008 by Denton Woods
// Last modified: 08/24/2008
//
// Filename: src-IL/src/il_jp2.h
//
// Description: Jpeg-2000 (.jp2) functions
//
//-----------------------------------------------------------------------------
#ifndef JP2_H
#define JP2_H
#include "il_internal.h"
ILboolean iLoadJp2Internal(jas_stream_t *Stream, ILimage *Image);
ILboolean iSaveJp2Internal();
jas_stream_t *iJp2ReadStream();
#endif//JP2_H
+29
View File
@@ -0,0 +1,29 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 03/07/2009
//
// Filename: src-IL/include/il_jpeg.h
//
// Description: Jpeg (.jpg) functions
//
//-----------------------------------------------------------------------------
#ifndef JPEG_H
#define JPEG_H
#include "il_internal.h"
ILboolean iCheckJpg(ILubyte Header[2]);
ILboolean iIsValidJpg(void);
#ifndef IL_USE_IJL
ILboolean iLoadJpegInternal(void);
ILboolean iSaveJpegInternal(void);
#else
ILboolean iLoadJpegInternal(ILconst_string FileName, ILvoid *Lump, ILuint Size);
ILboolean iSaveJpegInternal(ILconst_string FileName, ILvoid *Lump, ILuint Size);
#endif
#endif//JPEG_H
+37
View File
@@ -0,0 +1,37 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2001 by Denton Woods
// Last modified: 05/25/2001 <--Y2K Compliant! =]
//
// Filename: src-IL/include/il_lif.c
//
// Description: Reads a Homeworld image.
//
//-----------------------------------------------------------------------------
#ifndef LIF_H
#define LIF_H
#include "il_internal.h"
typedef struct LIF_HEAD
{
char Id[8]; //"Willy 7"
ILuint Version; // Version Number (260)
ILuint Flags; // Usually 50
ILuint Width;
ILuint Height;
ILuint PaletteCRC; // CRC of palettes for fast comparison.
ILuint ImageCRC; // CRC of the image.
ILuint PalOffset; // Offset to the palette (not used).
ILuint TeamEffect0; // Team effect offset 0
ILuint TeamEffect1; // Team effect offset 1
} LIF_HEAD;
ILboolean iIsValidLif(void);
ILboolean iCheckLif(LIF_HEAD *Header);
ILboolean iLoadLifInternal(void);
#endif//LIF_H
+249
View File
@@ -0,0 +1,249 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2001-2002 by Denton Woods
// Last modified: 05/25/2001 <--Y2K Compliant! =]
//
// Filename: src-IL/include/il_manip.h
//
// Description: Image manipulation
//
//-----------------------------------------------------------------------------
#ifndef MANIP_H
#define MANIP_H
#ifdef _cplusplus
extern "C" {
#endif
ILboolean ilFlipImage(void);
ILboolean ilMirrorImage(void); //@JASON New routine created 03/28/2001
//-----------------------------------------------
// Overflow handler for float-to-half conversion;
// generates a hardware floating-point overflow,
// which may be trapped by the operating system.
//-----------------------------------------------
#ifndef NOINLINE
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4756) // Disables 'named type definition in parentheses' warning
#endif
INLINE ILfloat /*ILAPIENTRY*/ ilFloatToHalfOverflow() {
ILfloat f = 1e10;
ILint j;
for (j = 0; j < 10; j++)
f *= f; // this will overflow before
// the for loop terminates
return f;
}
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
//-----------------------------------------------------
// Float-to-half conversion -- general case, including
// zeroes, denormalized numbers and exponent overflows.
//-----------------------------------------------------
INLINE ILushort ILAPIENTRY ilFloatToHalf(ILuint i) {
//
// Our floating point number, f, is represented by the bit
// pattern in integer i. Disassemble that bit pattern into
// the sign, s, the exponent, e, and the significand, m.
// Shift s into the position where it will go in in the
// resulting half number.
// Adjust e, accounting for the different exponent bias
// of float and half (127 versus 15).
//
register int s = (i >> 16) & 0x00008000;
register int e = ((i >> 23) & 0x000000ff) - (127 - 15);
register int m = i & 0x007fffff;
//
// Now reassemble s, e and m into a half:
//
if (e <= 0)
{
if (e < -10)
{
//
// E is less than -10. The absolute value of f is
// less than HALF_MIN (f may be a small normalized
// float, a denormalized float or a zero).
//
// We convert f to a half zero.
//
return 0;
}
//
// E is between -10 and 0. F is a normalized float,
// whose magnitude is less than HALF_NRM_MIN.
//
// We convert f to a denormalized half.
//
m = (m | 0x00800000) >> (1 - e);
//
// Round to nearest, round "0.5" up.
//
// Rounding may cause the significand to overflow and make
// our number normalized. Because of the way a half's bits
// are laid out, we don't have to treat this case separately;
// the code below will handle it correctly.
//
if (m & 0x00001000)
m += 0x00002000;
//
// Assemble the half from s, e (zero) and m.
//
return s | (m >> 13);
}
else if (e == 0xff - (127 - 15))
{
if (m == 0)
{
//
// F is an infinity; convert f to a half
// infinity with the same sign as f.
//
return s | 0x7c00;
}
else
{
//
// F is a NAN; we produce a half NAN that preserves
// the sign bit and the 10 leftmost bits of the
// significand of f, with one exception: If the 10
// leftmost bits are all zero, the NAN would turn
// into an infinity, so we have to set at least one
// bit in the significand.
//
m >>= 13;
return s | 0x7c00 | m | (m == 0);
}
}
else
{
//
// E is greater than zero. F is a normalized float.
// We try to convert f to a normalized half.
//
//
// Round to nearest, round "0.5" up
//
if (m & 0x00001000)
{
m += 0x00002000;
if (m & 0x00800000)
{
m = 0; // overflow in significand,
e += 1; // adjust exponent
}
}
//
// Handle exponent overflow
//
if (e > 30)
{
ilFloatToHalfOverflow(); // Cause a hardware floating point overflow;
return s | 0x7c00; // if this returns, the half becomes an
} // infinity with the same sign as f.
//
// Assemble the half from s, e and m.
//
return s | (e << 10) | (m >> 13);
}
}
// Taken from OpenEXR
INLINE ILuint ILAPIENTRY ilHalfToFloat (ILushort y) {
int s = (y >> 15) & 0x00000001;
int e = (y >> 10) & 0x0000001f;
int m = y & 0x000003ff;
if (e == 0)
{
if (m == 0)
{
//
// Plus or minus zero
//
return s << 31;
}
else
{
//
// Denormalized number -- renormalize it
//
while (!(m & 0x00000400))
{
m <<= 1;
e -= 1;
}
e += 1;
m &= ~0x00000400;
}
}
else if (e == 31)
{
if (m == 0)
{
//
// Positive or negative infinity
//
return (s << 31) | 0x7f800000;
}
else
{
//
// Nan -- preserve sign and significand bits
//
return (s << 31) | 0x7f800000 | (m << 13);
}
}
//
// Normalized number
//
e = e + (127 - 15);
m = m << 13;
//
// Assemble s, e and m.
//
return (s << 31) | (e << 23) | m;
}
#endif //NOINLINE
#ifdef _cplusplus
}
#endif
#endif//MANIP_H
+28
View File
@@ -0,0 +1,28 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2002 by Denton Woods
// Last modified: 05/25/2001 <--Y2K Compliant! =]
//
// Filename: src-IL/include/il_mdl.h
//
// Description: Reads a Half-Life model file.
//
//-----------------------------------------------------------------------------
#ifndef MD2_H
#define MD2_H
#include "il_internal.h"
typedef struct TEX_HEAD
{
char Name[64];
ILuint Flags;
ILuint Width;
ILuint Height;
ILuint Offset;
} TEX_HEAD;
#endif//MD2_H
+54
View File
@@ -0,0 +1,54 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2002 by Denton Woods
// Last modified: 05/25/2001 <--Y2K Compliant! =]
//
// Filename: src-IL/include/il_pal.h
//
// Description: Loads palettes from different file formats
//
//-----------------------------------------------------------------------------
#ifndef IL_PAL_H
#define IL_PAL_H
#include "il_internal.h"
#define BUFFLEN 256
#define PALBPP 3
#ifdef _MSC_VER
#pragma pack(push, packed_struct, 1)
#endif
typedef struct HALOHEAD
{
ILushort Id; // 'AH'
ILshort Version;
ILshort Size;
ILbyte Filetype;
ILbyte Subtype;
//ILshort Brdid, Grmode;
ILint Ignored;
ILushort MaxIndex; // Colors = maxindex + 1
ILushort MaxRed;
ILushort MaxGreen;
ILushort MaxBlue;
/*ILbyte Signature[8];
ILbyte Filler[12];*/
ILbyte Filler[20]; // Always 0 by PSP 4
} IL_PACKSTRUCT HALOHEAD;
#ifdef _MSC_VER
#pragma pack(pop, packed_struct)
#endif
ILboolean ilLoadJascPal(ILconst_string FileName);
ILboolean ilSaveJascPal(ILconst_string FileName);
char *iFgetw(ILubyte *Buff, ILint MaxLen, FILE *File);
ILboolean ilLoadHaloPal(ILconst_string FileName);
ILboolean ilLoadColPal(ILconst_string FileName);
ILboolean ilLoadActPal(ILconst_string FileName);
ILboolean ilLoadPltPal(ILconst_string FileName);
#endif//IL_PAL_H
+58
View File
@@ -0,0 +1,58 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2002 by Denton Woods
// Last modified: 05/25/2001 <--Y2K Compliant! =]
//
// Filename: src-IL/include/il_pcx.h
//
// Description: Reads and writes from/to a .pcx file.
//
//-----------------------------------------------------------------------------
#ifndef PCX_H
#define PCX_H
#include "il_internal.h"
#ifdef _WIN32
#pragma pack(push, packed_struct, 1)
#endif
typedef struct PCXHEAD
{
ILubyte Manufacturer;
ILubyte Version;
ILubyte Encoding;
ILubyte Bpp;
ILushort Xmin, Ymin, Xmax, Ymax;
ILushort HDpi;
ILushort VDpi;
ILubyte ColMap[48];
ILubyte Reserved;
ILubyte NumPlanes;
ILushort Bps;
ILushort PaletteInfo;
ILushort HScreenSize;
ILushort VScreenSize;
ILubyte Filler[54];
} IL_PACKSTRUCT PCXHEAD;
#ifdef _WIN32
#pragma pack(pop, packed_struct)
#endif
// For checking and reading
ILboolean iIsValidPcx(void);
ILboolean iCheckPcx(PCXHEAD *Header);
ILboolean iLoadPcxInternal(void);
ILboolean iSavePcxInternal(void);
ILboolean iUncompressPcx(PCXHEAD *Header);
ILboolean iUncompressSmall(PCXHEAD *Header);
// For writing
ILuint encput(ILubyte byt, ILubyte cnt);
ILuint encLine(ILubyte *inBuff, ILint inLen, ILubyte Stride);
#endif//PCX_H
+79
View File
@@ -0,0 +1,79 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2002 by Denton Woods
// Last modified: 05/21/2002 <--Y2K Compliant! =]
//
// Filename: src-IL/include/il_pic.h
//
// Description: Softimage Pic (.pic) functions
//
//-----------------------------------------------------------------------------
#ifndef PIC_H
#define PIC_H
#include "il_internal.h"
#ifdef _MSC_VER
#pragma pack(push, packed_struct, 1)
#endif
typedef struct PIC_HEAD
{
ILint Magic; // PIC_MAGIC_NUMBER
ILfloat Version; // Version of format
ILbyte Comment[80]; // Prototype description
ILbyte Id[4]; // 'PICT'
ILshort Width; // Image width, in pixels
ILshort Height; // Image height, in pixels
ILfloat Ratio; // Pixel aspect ratio
ILshort Fields; // Picture field type
ILshort Padding; // Unused
} IL_PACKSTRUCT PIC_HEAD;
typedef struct CHANNEL
{
ILubyte Size;
ILubyte Type;
ILubyte Chan;
void *Next;
} CHANNEL;
#ifdef _MSC_VER
#pragma pack(pop, packed_struct)
#endif
// Data type
#define PIC_UNSIGNED_INTEGER 0x00
#define PIC_SIGNED_INTEGER 0x10 // XXX: Not implemented
#define PIC_SIGNED_FLOAT 0x20 // XXX: Not implemented
// Compression type
#define PIC_UNCOMPRESSED 0x00
#define PIC_PURE_RUN_LENGTH 0x01
#define PIC_MIXED_RUN_LENGTH 0x02
// CHANNEL types (OR'd)
#define PIC_RED_CHANNEL 0x80
#define PIC_GREEN_CHANNEL 0x40
#define PIC_BLUE_CHANNEL 0x20
#define PIC_ALPHA_CHANNEL 0x10
#define PIC_SHADOW_CHANNEL 0x08 // XXX: Not implemented
#define PIC_DEPTH_CHANNEL 0x04 // XXX: Not implemented
#define PIC_AUXILIARY_1_CHANNEL 0x02 // XXX: Not implemented
#define PIC_AUXILIARY_2_CHANNEL 0x01 // XXX: Not implemented
ILboolean iIsValidPic(void);
ILboolean iCheckPic(PIC_HEAD *Header);
ILboolean iLoadPicInternal(void);
ILboolean readScanlines(ILuint *image, ILint width, ILint height, CHANNEL *channel, ILuint alpha);
ILuint readScanline(ILubyte *scan, ILint width, CHANNEL *channel, ILint bytes);
ILboolean channelReadRaw(ILubyte *scan, ILint width, ILint noCol, ILint *off, ILint bytes);
ILboolean channelReadPure(ILubyte *scan, ILint width, ILint noCol, ILint *off, ILint bytes);
ILboolean channelReadMixed(ILubyte *scan, ILint width, ILint noCol, ILint *off, ILint bytes);
#endif//PIC_H
+46
View File
@@ -0,0 +1,46 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2002 by Denton Woods
// Last modified: 05/25/2001 <--Y2K Compliant! =]
//
// Filename: src-IL/include/il_pnm.h
//
// Description: Reads/writes to/from pbm/pgm/ppm formats
//
//-----------------------------------------------------------------------------
#ifndef PPMPGM_H
#define PPMPGM_H
#include "il_internal.h"
#define IL_PBM_ASCII 0x0001
#define IL_PGM_ASCII 0x0002
#define IL_PPM_ASCII 0x0003
#define IL_PBM_BINARY 0x0004
#define IL_PGM_BINARY 0x0005
#define IL_PPM_BINARY 0x0006
typedef struct PPMINFO
{
ILenum Type;
ILuint Width;
ILuint Height;
ILuint MaxColour;
ILubyte Bpp;
} PPMINFO;
ILboolean iIsValidPnm(void);
ILboolean iCheckPnm(char Header[2]);
ILboolean iLoadPnmInternal(void);
ILboolean iSavePnmInternal(void);
ILimage *ilReadAsciiPpm(PPMINFO *Info);
ILimage *ilReadBinaryPpm(PPMINFO *Info);
ILimage *ilReadBitPbm(PPMINFO *Info);
ILboolean iGetWord(ILboolean);
void PbmMaximize(ILimage *Image);
#endif//PPMPGM_H
+56
View File
@@ -0,0 +1,56 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2001 by Denton Woods
// Last modified: 01/23/2001 <--Y2K Compliant! =]
//
// Filename: src-IL/include/il_il_psd.c
//
// Description: Reads from a PhotoShop (.psd) file.
//
//-----------------------------------------------------------------------------
#ifndef PSD_H
#define PSD_H
#include "il_internal.h"
#ifdef _MSC_VER
#pragma pack(push, packed_struct, 1)
#endif
typedef struct PSDHEAD
{
ILubyte Signature[4];
ILushort Version;
ILubyte Reserved[6];
ILushort Channels;
ILuint Height;
ILuint Width;
ILushort Depth;
ILushort Mode;
} IL_PACKSTRUCT PSDHEAD;
#ifdef _MSC_VER
#pragma pack(pop, packed_struct)
#endif
ILushort ChannelNum;
ILboolean iIsValidPsd(void);
ILboolean iCheckPsd(PSDHEAD *Header);
ILboolean iLoadPsdInternal(void);
ILboolean ReadPsd(PSDHEAD *Head);
ILboolean ReadGrey(PSDHEAD *Head);
ILboolean ReadIndexed(PSDHEAD *Head);
ILboolean ReadRGB(PSDHEAD *Head);
ILboolean ReadCMYK(PSDHEAD *Head);
ILuint *GetCompChanLen(PSDHEAD *Head);
ILboolean PsdGetData(PSDHEAD *Head, void *Buffer, ILboolean Compressed);
ILboolean ParseResources(ILuint ResourceSize, ILubyte *Resources);
ILboolean GetSingleChannel(PSDHEAD *Head, ILubyte *Buffer, ILboolean Compressed);
ILboolean iSavePsdInternal(void);
#endif//PSD_H
+250
View File
@@ -0,0 +1,250 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2002 by Denton Woods
// Last modified: 05/02/2002 <--Y2K Compliant! =]
//
// Filename: src-IL/include/il_psp.h
//
// Description: Reads a Paint Shop Pro file.
//
//-----------------------------------------------------------------------------
#ifndef PSP_H
#define PSP_H
#include "il_internal.h"
// Block identifiers
enum PSPBlockID {
PSP_IMAGE_BLOCK = 0, // (0) General Image Attributes Block (main)
PSP_CREATOR_BLOCK, // (1) Creator Data Block (main)
PSP_COLOR_BLOCK, // (2) Color Palette Block (main and sub)
PSP_LAYER_START_BLOCK, // (3) Layer Bank Block (main)
PSP_LAYER_BLOCK, // (4) Layer Block (sub)
PSP_CHANNEL_BLOCK, // (5) Channel Block (sub)
PSP_SELECTION_BLOCK, // (6) Selection Block (main)
PSP_ALPHA_BANK_BLOCK, // (7) Alpha Bank Block (main)
PSP_ALPHA_CHANNEL_BLOCK, // (8) Alpha Channel Block (sub)
PSP_COMPOSITE_IMAGE_BLOCK, // (9) Composite Image Block (sub)
PSP_EXTENDED_DATA_BLOCK, // (10) Extended Data Block (main)
PSP_TUBE_BLOCK, // (11) Picture Tube Data Block (main)
PSP_ADJUSTMENT_EXTENSION_BLOCK, // (12) Adjustment Layer Block (sub)
PSP_VECTOR_EXTENSION_BLOCK, // (13) Vector Layer Block (sub)
PSP_SHAPE_BLOCK, // (14) Vector Shape Block (sub)
PSP_PAINTSTYLE_BLOCK, // (15) Paint Style Block (sub)
PSP_COMPOSITE_IMAGE_BANK_BLOCK, // (16) Composite Image Bank (main)
PSP_COMPOSITE_ATTRIBUTES_BLOCK, // (17) Composite Image Attr. (sub)
PSP_JPEG_BLOCK, // (18) JPEG Image Block (sub)
PSP_LINESTYLE_BLOCK, // (19) Line Style Block (sub)
PSP_TABLE_BANK_BLOCK, // (20) Table Bank Block (main)
PSP_TABLE_BLOCK, // (21) Table Block (sub)
PSP_PAPER_BLOCK, // (22) Vector Table Paper Block (sub)
PSP_PATTERN_BLOCK, // (23) Vector Table Pattern Block (sub)
};
// Bitmap type
enum PSPDIBType {
PSP_DIB_IMAGE = 0, // Layer color bitmap
PSP_DIB_TRANS_MASK, // Layer transparency mask bitmap
PSP_DIB_USER_MASK, // Layer user mask bitmap
PSP_DIB_SELECTION, // Selection mask bitmap
PSP_DIB_ALPHA_MASK, // Alpha channel mask bitmap
PSP_DIB_THUMBNAIL // Thumbnail bitmap
};
// Channel types
enum PSPChannelType {
PSP_CHANNEL_COMPOSITE = 0, // Channel of single channel bitmap
PSP_CHANNEL_RED, // Red channel of 24 bit bitmap
PSP_CHANNEL_GREEN, // Green channel of 24 bit bitmap
PSP_CHANNEL_BLUE // Blue channel of 24 bit bitmap
};
// Possible metrics used to measure resolution
enum PSP_METRIC {
PSP_METRIC_UNDEFINED = 0, // Metric unknown
PSP_METRIC_INCH, // Resolution is in inches
PSP_METRIC_CM // Resolution is in centimeters
};
// Possible types of compression.
enum PSPCompression {
PSP_COMP_NONE = 0, // No compression
PSP_COMP_RLE, // RLE compression
PSP_COMP_LZ77, // LZ77 compression
PSP_COMP_JPEG // JPEG compression (only used by thumbnail and composite image)
};
// Picture tube placement mode.
enum TubePlacementMode {
tpmRandom, // Place tube images in random intervals
tpmConstant // Place tube images in constant intervals
};
// Picture tube selection mode.
enum TubeSelectionMode {
tsmRandom, // Randomly select the next image in tube to display
tsmIncremental, // Select each tube image in turn
tsmAngular, // Select image based on cursor direction
tsmPressure, // Select image based on pressure (from pressure-sensitive pad)
tsmVelocity // Select image based on cursor speed
};
// Extended data field types.
enum PSPExtendedDataID {
PSP_XDATA_TRNS_INDEX = 0 // Transparency index field
};
// Creator field types.
enum PSPCreatorFieldID {
PSP_CRTR_FLD_TITLE = 0, // Image document title field
PSP_CRTR_FLD_CRT_DATE, // Creation date field
PSP_CRTR_FLD_MOD_DATE, // Modification date field
PSP_CRTR_FLD_ARTIST, // Artist name field
PSP_CRTR_FLD_CPYRGHT, // Copyright holder name field
PSP_CRTR_FLD_DESC, // Image document description field
PSP_CRTR_FLD_APP_ID, // Creating app id field
PSP_CRTR_FLD_APP_VER, // Creating app version field
};
// Creator application identifiers.
enum PSPCreatorAppID {
PSP_CREATOR_APP_UNKNOWN = 0, // Creator application unknown
PSP_CREATOR_APP_PAINT_SHOP_PRO // Creator is Paint Shop Pro
};
// Layer types.
enum PSPLayerType {
PSP_LAYER_NORMAL = 0, // Normal layer
PSP_LAYER_FLOATING_SELECTION // Floating selection layer
};
// Truth values.
/*enum PSP_BOOLEAN {
FALSE = 0,
TRUE
};*/
#ifdef _MSC_VER
#pragma pack(push, packed_struct, 1)
#endif
typedef struct PSPRECT
{
ILuint x1,y1,x2,y2;
} IL_PACKSTRUCT PSPRECT;
typedef struct PSPHEAD
{
char FileSig[32];
ILushort MajorVersion;
ILushort MinorVersion;
} IL_PACKSTRUCT PSPHEAD;
typedef struct BLOCKHEAD
{
ILubyte HeadID[4];
ILushort BlockID;
ILuint BlockLen;
} IL_PACKSTRUCT BLOCKHEAD;
typedef struct GENATT_CHUNK
{
ILint Width;
ILint Height;
ILdouble Resolution;
ILubyte ResMetric;
ILushort Compression;
ILushort BitDepth;
ILushort PlaneCount;
ILuint ColourCount;
ILubyte GreyscaleFlag;
ILuint SizeOfImage;
ILint ActiveLayer;
ILushort LayerCount;
ILuint GraphicContents;
} IL_PACKSTRUCT GENATT_CHUNK;
typedef struct LAYERINFO_CHUNK
{
ILubyte LayerType;
PSPRECT ImageRect;
PSPRECT SavedImageRect;
ILubyte Opacity;
ILubyte BlendingMode;
ILubyte LayerFlags;
ILubyte TransProtFlag;
ILubyte LinkID;
PSPRECT MaskRect;
PSPRECT SavedMaskRect;
ILubyte MaskLinked;
ILubyte MaskDisabled;
ILubyte InvertMaskBlend;
ILushort BlendRange;
ILubyte SourceBlend1[4];
ILubyte DestBlend1[4];
ILubyte SourceBlend2[4];
ILubyte DestBlend2[4];
ILubyte SourceBlend3[4];
ILubyte DestBlend3[4];
ILubyte SourceBlend4[4];
ILubyte DestBlend4[4];
ILubyte SourceBlend5[4];
ILubyte DestBlend5[4];
} IL_PACKSTRUCT LAYERINFO_CHUNK;
typedef struct LAYERBITMAP_CHUNK
{
ILushort NumBitmaps;
ILushort NumChannels;
} IL_PACKSTRUCT LAYERBITMAP_CHUNK;
typedef struct CHANNEL_CHUNK
{
ILuint CompLen;
ILuint Length;
ILushort BitmapType;
ILushort ChanType;
} IL_PACKSTRUCT CHANNEL_CHUNK;
typedef struct ALPHAINFO_CHUNK
{
PSPRECT AlphaRect;
PSPRECT AlphaSavedRect;
} IL_PACKSTRUCT ALPHAINFO_CHUNK;
typedef struct ALPHA_CHUNK
{
ILushort BitmapCount;
ILushort ChannelCount;
} IL_PACKSTRUCT ALPHA_CHUNK;
#ifdef _MSC_VER
#pragma pack(pop, packed_struct)
#endif
// Function definitions
ILboolean iLoadPspInternal(void);
ILboolean iCheckPsp(void);
ILboolean iIsValidPsp(void);
ILboolean ReadGenAttributes(void);
ILboolean ParseChunks(void);
ILboolean ReadLayerBlock(ILuint BlockLen);
ILboolean ReadAlphaBlock(ILuint BlockLen);
ILubyte *GetChannel(void);
ILboolean UncompRLE(ILubyte *CompData, ILubyte *Data, ILuint CompLen);
ILboolean ReadPalette(ILuint BlockLen);
ILboolean AssembleImage(void);
ILboolean Cleanup(void);
#endif//PSP_H
+276
View File
@@ -0,0 +1,276 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2002 by Denton Woods
// Last modified: 05/25/2001 <--Y2K Compliant! =]
//
// Filename: src-IL/include/il_q2pal.h
//
// Description: The default Quake2 palette
//
//-----------------------------------------------------------------------------
#ifndef Q2PAL_H
#define Q2PAL_H
#define IL_Q2PAL_SIZE 768
ILubyte ilDefaultQ2Pal[IL_Q2PAL_SIZE] = {
0, 0, 0,
15, 15, 15,
31, 31, 31,
47, 47, 47,
63, 63, 63,
75, 75, 75,
91, 91, 91,
107, 107, 107,
123, 123, 123,
139, 139, 139,
155, 155, 155,
171, 171, 171,
187, 187, 187,
203, 203, 203,
219, 219, 219,
235, 235, 235,
99, 75, 35,
91, 67, 31,
83, 63, 31,
79, 59, 27,
71, 55, 27,
63, 47, 23,
59, 43, 23,
51, 39, 19,
47, 35, 19,
43, 31, 19,
39, 27, 15,
35, 23, 15,
27, 19, 11,
23, 15, 11,
19, 15, 7,
15, 11, 7,
95, 95, 111,
91, 91, 103,
91, 83, 95,
87, 79, 91,
83, 75, 83,
79, 71, 75,
71, 63, 67,
63, 59, 59,
59, 55, 55,
51, 47, 47,
47, 43, 43,
39, 39, 39,
35, 35, 35,
27, 27, 27,
23, 23, 23,
19, 19, 19,
143, 119, 83,
123, 99, 67,
115, 91, 59,
103, 79, 47,
207, 151, 75,
167, 123, 59,
139, 103, 47,
111, 83, 39,
235, 159, 39,
203, 139, 35,
175, 119, 31,
147, 99, 27,
119, 79, 23,
91, 59, 15,
63, 39, 11,
35, 23, 7,
167, 59, 43,
159, 47, 35,
151, 43, 27,
139, 39, 19,
127, 31, 15,
115, 23, 11,
103, 23, 7,
87, 19, 0,
75, 15, 0,
67, 15, 0,
59, 15, 0,
51, 11, 0,
43, 11, 0,
35, 11, 0,
27, 7, 0,
19, 7, 0,
123, 95, 75,
115, 87, 67,
107, 83, 63,
103, 79, 59,
95, 71, 55,
87, 67, 51,
83, 63, 47,
75, 55, 43,
67, 51, 39,
63, 47, 35,
55, 39, 27,
47, 35, 23,
39, 27, 19,
31, 23, 15,
23, 15, 11,
15, 11, 7,
111, 59, 23,
95, 55, 23,
83, 47, 23,
67, 43, 23,
55, 35, 19,
39, 27, 15,
27, 19, 11,
15, 11, 7,
179, 91, 79,
191, 123, 111,
203, 155, 147,
215, 187, 183,
203, 215, 223,
179, 199, 211,
159, 183, 195,
135, 167, 183,
115, 151, 167,
91, 135, 155,
71, 119, 139,
47, 103, 127,
23, 83, 111,
19, 75, 103,
15, 67, 91,
11, 63, 83,
7, 55, 75,
7, 47, 63,
7, 39, 51,
0, 31, 43,
0, 23, 31,
0, 15, 19,
0, 7, 11,
0, 0, 0,
139, 87, 87,
131, 79, 79,
123, 71, 71,
115, 67, 67,
107, 59, 59,
99, 51, 51,
91, 47, 47,
87, 43, 43,
75, 35, 35,
63, 31, 31,
51, 27, 27,
43, 19, 19,
31, 15, 15,
19, 11, 11,
11, 7, 7,
0, 0, 0,
151, 159, 123,
143, 151, 115,
135, 139, 107,
127, 131, 99,
119, 123, 95,
115, 115, 87,
107, 107, 79,
99, 99, 71,
91, 91, 67,
79, 79, 59,
67, 67, 51,
55, 55, 43,
47, 47, 35,
35, 35, 27,
23, 23, 19,
15, 15, 11,
159, 75, 63,
147, 67, 55,
139, 59, 47,
127, 55, 39,
119, 47, 35,
107, 43, 27,
99, 35, 23,
87, 31, 19,
79, 27, 15,
67, 23, 11,
55, 19, 11,
43, 15, 7,
31, 11, 7,
23, 7, 0,
11, 0, 0,
0, 0, 0,
119, 123, 207,
111, 115, 195,
103, 107, 183,
99, 99, 167,
91, 91, 155,
83, 87, 143,
75, 79, 127,
71, 71, 115,
63, 63, 103,
55, 55, 87,
47, 47, 75,
39, 39, 63,
35, 31, 47,
27, 23, 35,
19, 15, 23,
11, 7, 7,
155, 171, 123,
143, 159, 111,
135, 151, 99,
123, 139, 87,
115, 131, 75,
103, 119, 67,
95, 111, 59,
87, 103, 51,
75, 91, 39,
63, 79, 27,
55, 67, 19,
47, 59, 11,
35, 47, 7,
27, 35, 0,
19, 23, 0,
11, 15, 0,
0, 255, 0,
35, 231, 15,
63, 211, 27,
83, 187, 39,
95, 167, 47,
95, 143, 51,
95, 123, 51,
255, 255, 255,
255, 255, 211,
255, 255, 167,
255, 255, 127,
255, 255, 83,
255, 255, 39,
255, 235, 31,
255, 215, 23,
255, 191, 15,
255, 171, 7,
255, 147, 0,
239, 127, 0,
227, 107, 0,
211, 87, 0,
199, 71, 0,
183, 59, 0,
171, 43, 0,
155, 31, 0,
143, 23, 0,
127, 15, 0,
115, 7, 0,
95, 0, 0,
71, 0, 0,
47, 0, 0,
27, 0, 0,
239, 0, 0,
55, 55, 255,
255, 0, 0,
0, 0, 255,
43, 43, 35,
27, 27, 23,
19, 19, 15,
235, 151, 127,
195, 115, 83,
159, 87, 51,
123, 63, 27,
235, 211, 199,
199, 171, 155,
167, 139, 119,
135, 107, 87,
159, 91, 83
};
#endif//Q2PAL_H
@@ -0,0 +1,41 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2002 by Denton Woods
// Last modified: 05/25/2001 <--Y2K Compliant! =]
//
// Filename: src-IL/include/il_register.h
//
// Description: Allows the caller to specify user-defined callback functions
// to open files DevIL does not support, to parse files
// differently, or anything else a person can think up.
//
//-----------------------------------------------------------------------------
#ifndef REGISTER_H
#define REGISTER_H
#include "il_internal.h"
typedef struct iFormatL
{
ILstring Ext;
IL_LOADPROC Load;
struct iFormatL *Next;
} iFormatL;
typedef struct iFormatS
{
ILstring Ext;
IL_SAVEPROC Save;
struct iFormatS *Next;
} iFormatS;
#define I_LOAD_FUNC 0
#define I_SAVE_FUNC 1
ILboolean iRegisterLoad(ILconst_string FileName);
ILboolean iRegisterSave(ILconst_string FileName);
#endif//REGISTER_H
+92
View File
@@ -0,0 +1,92 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2002 by Denton Woods
// Last modified: 05/25/2001 <--Y2K Compliant! =]
//
// Filename: src-IL/include/il_rle.h
//
// Description: Functions for run-length encoding
//
//-----------------------------------------------------------------------------
#ifndef RLE_H
#define RLE_H
#include "il_internal.h"
#define TGA_MAX_RUN 128
#define SGI_MAX_RUN 127
#define BMP_MAX_RUN 127
#ifdef IL_RLE_C
#undef NOINLINE
#undef INLINE
#define INLINE
#endif
#ifndef NOINLINE
INLINE ILuint GetPix(ILubyte *p, ILuint bpp) {
ILuint Pixel;
Pixel = (ILuint)*p++;
while( bpp-- > 1 ) {
Pixel <<= 8;
Pixel |= (ILuint)*p++;
}
return Pixel;
}
INLINE ILint CountDiffPixels(ILubyte *p, ILuint bpp, ILuint pixCnt) {
ILuint pixel;
ILuint nextPixel = 0;
ILint n;
n = 0;
if (pixCnt == 1)
return pixCnt;
pixel = GetPix(p, bpp);
while (pixCnt > 1) {
p += bpp;
nextPixel = GetPix(p, bpp);
if (nextPixel == pixel)
break;
pixel = nextPixel;
++n;
--pixCnt;
}
if (nextPixel == pixel)
return n;
return n + 1;
}
INLINE ILint CountSamePixels(ILubyte *p, ILuint bpp, ILuint pixCnt) {
ILuint pixel;
ILuint nextPixel;
ILint n;
n = 1;
pixel = GetPix(p, bpp);
pixCnt--;
while (pixCnt > 0) {
p += bpp;
nextPixel = GetPix(p, bpp);
if (nextPixel != pixel)
break;
++n;
--pixCnt;
}
return n;
}
#endif
ILuint GetPix(ILubyte *p, ILuint bpp);
ILint CountDiffPixels(ILubyte *p, ILuint bpp, ILuint pixCnt);
ILint CountSamePixels(ILubyte *p, ILuint bpp, ILuint pixCnt);
#endif//RLE_H
+66
View File
@@ -0,0 +1,66 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2002 by Denton Woods
// Last modified: 05/25/2002 <--Y2K Compliant! =]
//
// Filename: src-IL/include/sgi.h
//
// Description: Reads from and writes to SGI graphics files.
//
//-----------------------------------------------------------------------------
#ifndef SGI_H
#define SGI_H
#include "il_internal.h"
typedef struct iSgiHeader
{
ILshort MagicNum; // IRIS image file magic number
ILbyte Storage; // Storage format
ILbyte Bpc; // Number of bytes per pixel channel
ILushort Dim; // Number of dimensions
// 1: single channel, 1 row with XSize pixels
// 2: single channel, XSize*YSize pixels
// 3: ZSize channels, XSize*YSize pixels
ILushort XSize; // X size in pixels
ILushort YSize; // Y size in pixels
ILushort ZSize; // Number of channels
ILint PixMin; // Minimum pixel value
ILint PixMax; // Maximum pixel value
ILint Dummy1; // Ignored
ILbyte Name[80]; // Image name
ILint ColMap; // Colormap ID
ILbyte Dummy[404]; // Ignored
} IL_PACKSTRUCT iSgiHeader;
// Sgi format #define's
#define SGI_VERBATIM 0
#define SGI_RLE 1
#define SGI_MAGICNUM 474
// Sgi colormap types
#define SGI_COLMAP_NORMAL 0
#define SGI_COLMAP_DITHERED 1
#define SGI_COLMAP_SCREEN 2
#define SGI_COLMAP_COLMAP 3
// Internal functions
ILboolean iIsValidSgi(void);
ILboolean iCheckSgi(iSgiHeader *Header);
ILboolean iLoadSgiInternal(void);
ILboolean iSaveSgiInternal(void);
void iExpandScanLine(ILubyte *Dest, ILubyte *Src, ILuint Bpc);
ILint iGetScanLine(ILubyte *ScanLine, iSgiHeader *Head, ILuint Length);
ILint iGetScanLineFast(ILubyte *ScanLine, iSgiHeader *Head, ILuint Length, ILubyte*);
void sgiSwitchData(ILubyte *Data, ILuint SizeOfData);
ILboolean iNewSgi(iSgiHeader *Head);
ILboolean iReadNonRleSgi(iSgiHeader *Head);
ILboolean iReadRleSgi(iSgiHeader *Head);
ILboolean iSaveRleSgi(ILubyte *Data, ILuint w, ILuint h, ILuint numChannels, ILuint bps);
#endif//SGI_H
@@ -0,0 +1,43 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2002 by Denton Woods
// Last modified: 05/25/2001 <--Y2K Compliant! =]
//
// Filename: src-IL/include/il_stack.h
//
// Description: The main image stack
//
//-----------------------------------------------------------------------------
#ifndef IMAGESTACK_H
#define IMAGESTACK_H
#include "il_internal.h"
// Just a guess...seems large enough
#define I_STACK_INCREMENT 1024
typedef struct iFree
{
ILuint Name;
void *Next;
} iFree;
// Internal functions
ILboolean iEnlargeStack(void);
void iFreeMem(void);
// Globals for il_stack.c
ILuint StackSize = 0;
ILuint LastUsed = 0;
ILuint CurName = 0;
ILimage **ImageStack = NULL;
iFree *FreeNames = NULL;
ILboolean OnExit = IL_FALSE;
ILboolean ParentImage = IL_TRUE;
#endif//IMAGESTACK_H
+399
View File
@@ -0,0 +1,399 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2008 by Denton Woods
// Last modified: 11/07/2008
//
// Filename: src-IL/src/il_states.h
//
// Description: State machine
//
//-----------------------------------------------------------------------------
#ifndef STATES_H
#define STATES_H
#include "il_internal.h"
ILboolean ilAble(ILenum Mode, ILboolean Flag);
#define IL_ATTRIB_STACK_MAX 32
ILuint ilCurrentPos = 0; // Which position on the stack
//
// Various states
//
typedef struct IL_STATES
{
// Origin states
ILboolean ilOriginSet;
ILenum ilOriginMode;
// Format and type states
ILboolean ilFormatSet;
ILboolean ilTypeSet;
ILenum ilFormatMode;
ILenum ilTypeMode;
// File mode states
ILboolean ilOverWriteFiles;
// Palette states
ILboolean ilAutoConvPal;
// Load fail states
ILboolean ilDefaultOnFail;
// Key colour states
ILboolean ilUseKeyColour;
// Alpha blend states
ILboolean ilBlitBlend;
// Compression states
ILenum ilCompression;
// Interlace states
ILenum ilInterlace;
// Quantization states
ILenum ilQuantMode;
ILuint ilNeuSample;
ILuint ilQuantMaxIndexs;
// DXTC states
ILboolean ilKeepDxtcData;
ILboolean ilUseNVidiaDXT;
ILboolean ilUseSquishDXT;
//
// Format-specific states
//
ILboolean ilTgaCreateStamp;
ILuint ilJpgQuality;
ILboolean ilPngInterlace;
ILboolean ilTgaRle;
ILboolean ilBmpRle;
ILboolean ilSgiRle;
ILenum ilJpgFormat;
ILboolean ilJpgProgressive;
ILenum ilDxtcFormat;
ILenum ilPcdPicNum;
ILint ilPngAlphaIndex; // this index should be treated as an alpha key (most formats use this rather than having alpha in the palette), -1 for none
// currently only used when writing out .png files and should obviously be set to -1 most of the time
ILenum ilVtfCompression;
//
// Format-specific strings
//
char* ilTgaId;
char* ilTgaAuthName;
char* ilTgaAuthComment;
char* ilPngAuthName;
char* ilPngTitle;
char* ilPngDescription;
char* ilTifDescription;
char* ilTifHostComputer;
char* ilTifDocumentName;
char* ilTifAuthName;
char* ilCHeader;
} IL_STATES;
IL_STATES ilStates[IL_ATTRIB_STACK_MAX];
typedef struct IL_HINTS
{
// Memory vs. Speed trade-off
ILenum MemVsSpeedHint;
// Compression hints
ILenum CompressHint;
} IL_HINTS;
IL_HINTS ilHints;
#ifndef IL_NO_BLP
#define IL_BLP_EXT "blp "
#else
#define IL_BLP_EXT ""
#endif
#ifndef IL_NO_BMP
#define IL_BMP_EXT "bmp dib "
#else
#define IL_BMP_EXT ""
#endif
#ifndef IL_NO_CHEAD
#define IL_CHEAD_EXT "h "
#else
#define IL_CHEAD_EXT ""
#endif
#ifndef IL_NO_CUT
#define IL_CUT_EXT "cut "
#else
#define IL_CUT_EXT ""
#endif
#ifndef IL_NO_DCX
#define IL_DCX_EXT "dcx "
#else
#define IL_DCX_EXT ""
#endif
#ifndef IL_NO_DCM
#define IL_DCM_EXT "dicom dcm"
#else
#define IL_DCM_EXT ""
#endif
#ifndef IL_NO_DDS
#define IL_DDS_EXT "dds "
#else
#define IL_DDS_EXT ""
#endif
#ifndef IL_NO_DPX
#define IL_DPX_EXT "dds "
#else
#define IL_DPX_EXT ""
#endif
#ifndef IL_NO_EXR
#define IL_EXR_EXT "exr "
#else
#define IL_EXR_EXT ""
#endif
#ifndef IL_NO_FITS
#define IL_FITS_EXT "fit fits "
#else
#define IL_FITS_EXT ""
#endif
#ifndef IL_NO_FTX
#define IL_FTX_EXT "ftx "
#else
#define IL_FTX_EXT ""
#endif
#ifndef IL_NO_GIF
#define IL_GIF_EXT "gif "
#else
#define IL_GIF_EXT ""
#endif
#ifndef IL_NO_HDR
#define IL_HDR_EXT "hdr "
#else
#define IL_HDR_EXT ""
#endif
#ifndef IL_NO_ICNS
#define IL_ICNS_EXT "icns "
#else
#define IL_ICNS_EXT ""
#endif
#ifndef IL_NO_ICO
#define IL_ICO_EXT "ico cur "
#else
#define IL_ICO_EXT ""
#endif
#ifndef IL_NO_IFF
#define IL_IFF_EXT "iff "
#else
#define IL_IFF_EXT ""
#endif
#ifndef IL_NO_IWI
#define IL_IWI_EXT "iwi "
#else
#define IL_IWI_EXT ""
#endif
#ifndef IL_NO_JP2
#define IL_JP2_EXT "jp2 "
#else
#define IL_JP2_EXT ""
#endif
#ifndef IL_NO_JPG
#define IL_JPG_EXT "jpg jpe jpeg "
#else
#define IL_JPG_EXT ""
#endif
#ifndef IL_NO_LIF
#define IL_LIF_EXT "lif "
#else
#define IL_LIF_EXT ""
#endif
#ifndef IL_NO_MDL
#define IL_MDL_EXT "mdl "
#else
#define IL_MDL_EXT ""
#endif
#ifndef IL_NO_MNG
#define IL_MNG_EXT "mng jng "
#else
#define IL_MNG_EXT ""
#endif
#ifndef IL_NO_MP3
#define IL_MP3_EXT "mp3 "
#else
#define IL_MP3_EXT ""
#endif
#ifndef IL_NO_PCD
#define IL_PCD_EXT "pcd "
#else
#define IL_PCD_EXT ""
#endif
#ifndef IL_NO_PCX
#define IL_PCX_EXT "pcx "
#else
#define IL_PCX_EXT ""
#endif
#ifndef IL_NO_PIC
#define IL_PIC_EXT "pic "
#else
#define IL_PIC_EXT ""
#endif
#ifndef IL_NO_PIX
#define IL_PIX_EXT "pix "
#else
#define IL_PIX_EXT ""
#endif
#ifndef IL_NO_PNG
#define IL_PNG_EXT "png "
#else
#define IL_PNG_EXT ""
#endif
#ifndef IL_NO_PNM
#define IL_PNM_EXT "pbm pgm pnm ppm "
#else
#define IL_PNM_EXT ""
#endif
#ifndef IL_NO_PSD
#define IL_PSD_EXT "psd pdd "
#else
#define IL_PSD_EXT ""
#endif
#ifndef IL_NO_PSP
#define IL_PSP_EXT "psp "
#else
#define IL_PSP_EXT ""
#endif
#ifndef IL_NO_PXR
#define IL_PXR_EXT "pxr "
#else
#define IL_PXR_EXT ""
#endif
#ifndef IL_NO_RAW
#define IL_RAW_EXT "raw "
#else
#define IL_RAW_EXT ""
#endif
#ifndef IL_NO_ROT
#define IL_ROT_EXT "rot "
#else
#define IL_ROT_EXT ""
#endif
#ifndef IL_NO_SGI
#define IL_SGI_EXT "sgi bw rgb rgba "
#else
#define IL_SGI_EXT ""
#endif
#ifndef IL_NO_SUN
#define IL_SUN_EXT "sun ras rs im1 im8 im24 im32 "
#else
#define IL_SUN_EXT ""
#endif
#ifndef IL_NO_TEXTURE
#define IL_TEX_EXT "texture "
#else
#define IL_TEX_EXT ""
#endif
#ifndef IL_NO_TGA
#define IL_TGA_EXT "tga vda icb vst "
#else
#define IL_TGA_EXT ""
#endif
#ifndef IL_NO_TIF
#define IL_TIF_EXT "tif tiff "
#else
#define IL_TIF_EXT ""
#endif
#ifndef IL_NO_TPL
#define IL_TPL_EXT "tpl "
#else
#define IL_TPL_EXT ""
#endif
#ifndef IL_NO_UTX
#define IL_UTX_EXT "utx "
#else
#define IL_UTX_EXT ""
#endif
#ifndef IL_NO_VTF
#define IL_VTF_EXT "vtf "
#else
#define IL_VTF_EXT ""
#endif
#ifndef IL_NO_WAL
#define IL_WAL_EXT "wal "
#else
#define IL_WAL_EXT ""
#endif
#ifndef IL_NO_WBMP
#define IL_WBMP_EXT "wbmp "
#else
#define IL_WBMP_EXT ""
#endif
#ifndef IL_NO_WDP
#define IL_WDP_EXT "wdp "
#else
#define IL_WDP_EXT ""
#endif
#ifndef IL_NO_XPM
#define IL_XPM_EXT "xpm "
#else
#define IL_XPM_EXT ""
#endif
#endif//STATES_H
+109
View File
@@ -0,0 +1,109 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2002 by Denton Woods
// Last modified: 05/25/2001 <--Y2K Compliant! =]
//
// Filename: src-IL/include/il_targa.h
//
// Description: Targa (.tga) functions
//
//-----------------------------------------------------------------------------
#ifndef TARGA_H
#define TARGA_H
#include "il_internal.h"
#ifdef _MSC_VER
#pragma pack(push, tga_struct, 1)
#elif defined(MACOSX) || defined(__GNUC__)
#pragma pack(1)
#endif
typedef struct TARGAHEAD
{
ILubyte IDLen;
ILubyte ColMapPresent;
ILubyte ImageType;
ILshort FirstEntry;
ILshort ColMapLen;
ILubyte ColMapEntSize;
ILshort OriginX;
ILshort OriginY;
ILushort Width;
ILushort Height;
ILubyte Bpp;
ILubyte ImageDesc;
} IL_PACKSTRUCT TARGAHEAD;
typedef struct TARGAFOOTER
{
ILuint ExtOff; // Extension Area Offset
ILuint DevDirOff; // Developer Directory Offset
ILbyte Signature[16]; // TRUEVISION-XFILE
ILbyte Reserved; // ASCII period '.'
ILbyte NullChar; // NULL
} IL_PACKSTRUCT TARGAFOOTER;
#if defined(MACOSX) || defined(__GNUC__)
#pragma pack()
#elif _MSC_VER
#pragma pack(pop, tga_struct)
#endif
#define TGA_EXT_LEN 495
typedef struct TARGAEXT
{
// Dev Directory
// We don't mess with this
// Extension Area
ILshort Size; // should be TGA_EXT_LEN
ILbyte AuthName[41]; // the image author's name
ILbyte AuthComments[324]; // author's comments
ILshort Month, Day, Year, Hour, Minute, Second; // internal date of file
ILbyte JobID[41]; // the job description (if any)
ILshort JobHour, JobMin, JobSecs; // the job's time
ILbyte SoftwareID[41]; // the software that created this
ILshort SoftwareVer; // the software version number * 100
ILbyte SoftwareVerByte; // the software version letter
ILint KeyColor; // the transparent colour
} TARGAEXT;
// Different Targa formats
#define TGA_NO_DATA 0
#define TGA_COLMAP_UNCOMP 1
#define TGA_UNMAP_UNCOMP 2
#define TGA_BW_UNCOMP 3
#define TGA_COLMAP_COMP 9
#define TGA_UNMAP_COMP 10
#define TGA_BW_COMP 11
// Targa origins
#define IMAGEDESC_ORIGIN_MASK 0x30
#define IMAGEDESC_TOPLEFT 0x20
#define IMAGEDESC_BOTLEFT 0x00
#define IMAGEDESC_BOTRIGHT 0x10
#define IMAGEDESC_TOPRIGHT 0x30
// Internal functions
ILboolean iIsValidTarga();
ILboolean iGetTgaHead(TARGAHEAD *Header);
ILboolean iCheckTarga(TARGAHEAD *Header);
ILboolean iLoadTargaInternal(void);
ILboolean iSaveTargaInternal(void);
//ILvoid iMakeString(char *Str);
ILboolean iReadBwTga(TARGAHEAD *Header);
ILboolean iReadColMapTga(TARGAHEAD *Header);
ILboolean iReadUnmapTga(TARGAHEAD *Header);
ILboolean iUncompressTgaData(ILimage *Image);
ILboolean i16BitTarga(ILimage *Image);
void iGetDateTime(ILuint *Month, ILuint *Day, ILuint *Yr, ILuint *Hr, ILuint *Min, ILuint *Sec);
#endif//TARGA_H
+100
View File
@@ -0,0 +1,100 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 03/02/2009
//
// Filename: src-IL/include/il_utx.h
//
// Description: Reads from an Unreal and Unreal Tournament Texture (.utx) file.
// Specifications can be found at
// http://wiki.beyondunreal.com/Legacy:Package_File_Format.
//
//-----------------------------------------------------------------------------
#ifndef UTX_H
#define UTX_H
#ifdef __cplusplus
extern "C" {
#endif
#include "il_internal.h"
#include "il_dds.h"
#ifdef __cplusplus
}
#endif
#include <memory>
#include <vector>
#include <string>
using namespace std;
typedef struct UTXHEADER
{
ILuint Signature;
ILushort Version;
ILushort LicenseMode;
ILuint Flags;
ILuint NameCount;
ILuint NameOffset;
ILuint ExportCount;
ILuint ExportOffset;
ILuint ImportCount;
ILuint ImportOffset;
} UTXHEADER;
typedef struct UTXENTRYNAME
{
//char *Name;
string Name;
ILuint Flags;
} UTXENTRYNAME;
typedef struct UTXEXPORTTABLE
{
ILint Class;
ILint Super;
ILint Group;
ILint ObjectName;
ILuint ObjectFlags;
ILint SerialSize;
ILint SerialOffset;
ILboolean ClassImported;
ILboolean SuperImported;
ILboolean GroupImported;
} UTXEXPORTTABLE;
typedef struct UTXIMPORTTABLE
{
ILint ClassPackage;
ILint ClassName;
ILint Package;
ILint ObjectName;
ILboolean PackageImported;
} UTXIMPORTTABLE;
class UTXPALETTE
{
public:
UTXPALETTE() { Pal = NULL; }
~UTXPALETTE() { delete [] Pal; }
ILubyte *Pal;
ILuint Count;
ILuint Name;
};
// Data formats
#define UTX_P8 0x00
#define UTX_DXT1 0x03
ILboolean iLoadUtxInternal(void);
#endif//UTX_H
+132
View File
@@ -0,0 +1,132 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 02/28/2009
//
// Filename: src-IL/include/il_vtf.h
//
// Description: Reads from and writes to a Valve Texture Format (.vtf) file.
// These are used in Valve's Source games. VTF specs available
// from http://developer.valvesoftware.com/wiki/VTF.
//
//-----------------------------------------------------------------------------
#ifndef VTF_H
#define VTF_H
#include "il_internal.h"
#ifdef _MSC_VER
#pragma pack(push, vtf_struct, 1)
#elif defined(MACOSX) || defined(__GNUC__)
#pragma pack(1)
#endif
typedef struct VTFHEAD
{
ILubyte Signature[4]; // File signature ("VTF\0").
ILuint Version[2]; // version[0].version[1] (currently 7.2).
ILuint HeaderSize; // Size of the header struct (16 byte aligned; currently 80 bytes).
ILushort Width; // Width of the largest mipmap in pixels. Must be a power of 2.
ILushort Height; // Height of the largest mipmap in pixels. Must be a power of 2.
ILuint Flags; // VTF flags.
ILushort Frames; // Number of frames, if animated (1 for no animation).
ILushort FirstFrame; // First frame in animation (0 based).
ILubyte Padding0[4]; // reflectivity padding (16 byte alignment).
ILfloat Reflectivity[3]; // reflectivity vector.
ILubyte Padding1[4]; // reflectivity padding (8 byte packing).
ILfloat BumpmapScale; // Bumpmap scale.
ILuint HighResImageFormat; // High resolution image format.
ILubyte MipmapCount; // Number of mipmaps.
ILuint LowResImageFormat; // Low resolution image format (always DXT1).
ILubyte LowResImageWidth; // Low resolution image width.
ILubyte LowResImageHeight; // Low resolution image height.
ILushort Depth; // Depth of the largest mipmap in pixels.
// Must be a power of 2. Can be 0 or 1 for a 2D texture (v7.2 only).
} IL_PACKSTRUCT VTFHEAD;
#if defined(MACOSX) || defined(__GNUC__)
#pragma pack()
#elif _MSC_VER
#pragma pack(pop, vtf_struct)
#endif
enum
{
IMAGE_FORMAT_NONE = -1,
IMAGE_FORMAT_RGBA8888 = 0,
IMAGE_FORMAT_ABGR8888,
IMAGE_FORMAT_RGB888,
IMAGE_FORMAT_BGR888,
IMAGE_FORMAT_RGB565,
IMAGE_FORMAT_I8,
IMAGE_FORMAT_IA88,
IMAGE_FORMAT_P8,
IMAGE_FORMAT_A8,
IMAGE_FORMAT_RGB888_BLUESCREEN,
IMAGE_FORMAT_BGR888_BLUESCREEN,
IMAGE_FORMAT_ARGB8888,
IMAGE_FORMAT_BGRA8888,
IMAGE_FORMAT_DXT1,
IMAGE_FORMAT_DXT3,
IMAGE_FORMAT_DXT5,
IMAGE_FORMAT_BGRX8888,
IMAGE_FORMAT_BGR565,
IMAGE_FORMAT_BGRX5551,
IMAGE_FORMAT_BGRA4444,
IMAGE_FORMAT_DXT1_ONEBITALPHA,
IMAGE_FORMAT_BGRA5551,
IMAGE_FORMAT_UV88,
IMAGE_FORMAT_UVWQ8888,
IMAGE_FORMAT_RGBA16161616F,
IMAGE_FORMAT_RGBA16161616,
IMAGE_FORMAT_UVLX8888
};
enum
{
TEXTUREFLAGS_POINTSAMPLE = 0x00000001,
TEXTUREFLAGS_TRILINEAR = 0x00000002,
TEXTUREFLAGS_CLAMPS = 0x00000004,
TEXTUREFLAGS_CLAMPT = 0x00000008,
TEXTUREFLAGS_ANISOTROPIC = 0x00000010,
TEXTUREFLAGS_HINT_DXT5 = 0x00000020,
TEXTUREFLAGS_NOCOMPRESS = 0x00000040,
TEXTUREFLAGS_NORMAL = 0x00000080,
TEXTUREFLAGS_NOMIP = 0x00000100,
TEXTUREFLAGS_NOLOD = 0x00000200,
TEXTUREFLAGS_MINMIP = 0x00000400,
TEXTUREFLAGS_PROCEDURAL = 0x00000800,
TEXTUREFLAGS_ONEBITALPHA = 0x00001000,
TEXTUREFLAGS_EIGHTBITALPHA = 0x00002000,
TEXTUREFLAGS_ENVMAP = 0x00004000,
TEXTUREFLAGS_RENDERTARGET = 0x00008000,
TEXTUREFLAGS_DEPTHRENDERTARGET = 0x00010000,
TEXTUREFLAGS_NODEBUGOVERRIDE = 0x00020000,
TEXTUREFLAGS_SINGLECOPY = 0x00040000,
TEXTUREFLAGS_ONEOVERMIPLEVELINALPHA = 0x00080000,
TEXTUREFLAGS_PREMULTCOLORBYONEOVERMIPLEVEL = 0x00100000,
TEXTUREFLAGS_NORMALTODUDV = 0x00200000,
TEXTUREFLAGS_ALPHATESTMIPGENERATION = 0x00400000,
TEXTUREFLAGS_NODEPTHBUFFER = 0x00800000,
TEXTUREFLAGS_NICEFILTERED = 0x01000000,
TEXTUREFLAGS_CLAMPU = 0x02000000
};
// Internal functions
ILboolean iIsValidVtf(void);
ILboolean iGetVtfHead(VTFHEAD *Header);
ILboolean iCheckVtf(VTFHEAD *Header);
ILboolean iLoadVtfInternal(void);
ILboolean VtfInitFacesMipmaps(ILimage *BaseImage, ILuint NumFaces, VTFHEAD *Header);
ILboolean VtfInitMipmaps(ILimage *BaseImage, VTFHEAD *Header);
ILboolean VtfReadData(void);
ILboolean VtfDecompressDXT1(ILimage *Image);
ILboolean VtfDecompressDXT5(ILimage *Image);
ILboolean iSaveVtfInternal(void);
#endif//VTF_H
+188
View File
@@ -0,0 +1,188 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2008 by Denton Woods
// Last modified: 09/26/2008
//
// Filename: src-IL/include/il_hdr.h
//
// Description: Reads a Microsoft HD Photo (.wdp)
//
//-----------------------------------------------------------------------------
#ifndef WDP_H
#define WDP_H
#include "il_internal.h"
//
// Structures
//
typedef struct WDPHEAD
{
ILubyte Encoding[2];
ILubyte UniqueID;
ILubyte Version;
ILuint Offset;
} WDPHEAD;
typedef struct WDPIFD
{
ILushort Tag;
ILushort Type;
ILuint Count;
ILuint ValOff;
ILuint NextOff;
} WDPIFD;
typedef struct WDPGUID
{
ILuint First;
ILushort Second;
ILushort Third;
ILuint Fourth;
ILuint Fifth;
} WDPGUID;
typedef struct WDPIMGHEAD
{
ILuint GDISignature[2];
ILuint Codec;
ILubyte Flags[2];
ILubyte Format;
ILuint Width, Height; // Can either be short or 32-bit int
ILuint VertTiles, HorzTiles; // 12-bits each
ILushort *TileWidth, *TileHeight; // 8 or 16-bits each
ILubyte *TileStretch; // 8-bits each
ILubyte ExtraPixels[3];
} WDPIMGHEAD;
typedef struct WDPIMGPLANE
{
ILubyte Flags1;
ILubyte Color;
ILubyte Bayer;
ILubyte ShiftBits;
ILubyte Mantissa;
ILubyte Expbias;
ILubyte Flags2;
ILubyte NumChannels;
} WDPIMGPLANE;
typedef struct WDPDCQUANT
{
ILubyte ChMode;
ILubyte DcQuant;
ILubyte DcQuantY;
ILubyte DcQuantUV;
ILubyte DcQuantChan;
} WDPDCQUANT;
typedef struct WDPTILE
{
ILuint StartCode;
ILubyte HashAndType;
} WDPTILE;
//
// Image header defines
//
// Codec and sub-codec
#define WDP_CODEC 0xF0
#define WDP_SUBCODEC 0x0F
// First set of flags
#define WDP_TILING_FLAG 0x80
#define WDP_BITSTREAM_FMT 0x40
#define WDP_ORIENTATION 0x38
#define WDP_INDEXTABLE 0x04
#define WDP_OVERLAP 0x03
// Second set of flags
#define WDP_SHORT_HEADER 0x80
#define WDP_LONG_WORD 0x40
#define WDP_WINDOWING 0x20
#define WDP_TRIM_FLEXBITS 0x10
#define WDP_TILE_STRETCH 0x08
#define WDP_ALPHACHANNEL 0x01
// Format and bit-depth
#define WDP_FORMAT 0xF0
#define WDP_BITDEPTH 0x0F
#define WDP_Y_ONLY 0x00
#define WDP_YUV_420 0x01
#define WDP_YUV_422 0x02
#define WDP_YUV_444 0x03
#define WDP_CMYK 0x04
#define WDP_BAYER 0x05
#define WDP_N_CHANNEL 0x06
#define WDP_RGB 0x07
#define WDP_RGBE 0x08
// Bitdepth
#define WDP_BD_1_WHITE 0x00
#define WDP_BD_8 0x01
#define WDP_BD_16 0x02
#define WDP_BD_16S 0x03
#define WDP_BD_16F 0x04
#define WDP_BD_32 0x05
#define WDP_BD_32S 0x06
#define WDP_BD_32F 0x07
#define WDP_BD_5 0x08
#define WDP_BD_10 0x09
#define WDP_BD_565 0x0A
#define WDP_BD_1_BLACK 0x0F
//
// Image plane header defines
//
// First set of flags
#define WDP_CLR_FMT 0xE0
#define WDP_NO_SCALED 0x10
#define WDP_BANDS_PRESENT 0x0F
// Defines for n-channels
#define WDP_NUM_CHANS 0xF0
#define WDP_COLOR_INTERP 0x0F
// Second set of flags
#define WDP_DC_FRAME 0x80
// Channel modes
#define WDP_CH_UNIFORM 0x00
#define WDP_CH_SEPARATE 0x01
#define WDP_CH_INDEPENDENT 0x02
// Tile types
#define WDP_TILE_HASH 0xF8
#define WDP_TILE_TYPE 0x03
#define WDP_SPATIAL_TILE 0x00
#define WDP_DC_TILE 0x01
#define WDP_LOWPASS_TILE 0x02
#define WDP_HIGHPASS_TILE 0x03
#define WDP_FLEXBITS_TILE 0x04
// Bands present
#define WDP_SB_ALL 0x00
#define WDP_SB_NO_FLEXBITS 0x01
#define WDP_SB_NO_HIGHPASS 0x02
#define WDP_SB_DC_ONLY 0x03
#define WDP_SB_ISOLATED 0x04
//
// Internal functions
//
ILboolean iIsValidWdp();
ILboolean iCheckWdp(WDPHEAD *Header);
ILboolean iLoadWdpInternal();
ILuint VLWESC();
#endif//WDP_H
+120
View File
@@ -0,0 +1,120 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
1 VERSIONINFO
FILEVERSION 0,1,7,8
PRODUCTVERSION 0,1,7,8
FILEFLAGSMASK 0x0L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "DevIL: A portable image library in development"
VALUE "CompanyName", "Abysmal Software"
VALUE "FileDescription", "DevIL: A portable image library in development"
VALUE "FileVersion", "1.7.8"
VALUE "InternalName", "Developer's Image Library (DevIL)"
VALUE "LegalCopyright", "Copyright © 2000-2008"
VALUE "LegalTrademarks", "Under LGPL License"
VALUE "OriginalFilename", "DevIL.dll"
VALUE "PrivateBuild", "Open Source"
VALUE "ProductName", "Developer's Image Library (DevIL)"
VALUE "ProductVersion", "1.7.8 Unicode"
VALUE "SpecialBuild", "Unicode"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON1 ICON "resources\\IL Logo.ico"
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDC_OPENIL "Developer's Image Library, Version 1.7.8"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
File diff suppressed because it is too large Load Diff
+123
View File
@@ -0,0 +1,123 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
///////////////// FILEVERSION 0,1,7,8////////////////////////////////////////
//
// Version
//
1 VERSIONINFO
FILEVERSION 0,1,7,8
PRODUCTVERSION 0,1,7,8
FILEFLAGSMASK 0x0L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "DevIL: A portable image library in development"
VALUE "CompanyName", "Abysmal Software"
VALUE "FileDescription", "DevIL: A portable image library in development"
VALUE "FileVersion", "1.7.8"
VALUE "InternalName", "Developer's Image Library (DevIL)"
VALUE "LegalCopyright", "Copyright © 2000-2008"
VALUE "LegalTrademarks", "Under LGPL License"
VALUE "OriginalFilename", "DevIL.dll"
VALUE "PrivateBuild", "Open Source"
VALUE "ProductName", "Developer's Image Library (DevIL)"
VALUE "ProductVersion", "1.7.8 Ansi"
VALUE "SpecialBuild", "Ansi"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON1 ICON "resources\\IL Logo.ico"
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.\0"
END
3 TEXTINCLUDE
BEGIN
"\r\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDC_OPENIL "Developer's Image Library, Version 1.7.8"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
File diff suppressed because it is too large Load Diff
+200
View File
@@ -0,0 +1,200 @@
; To remove an export, add a semicolon at the beginning of the line to comment it out.
EXPORTS
ilActiveFace
ilActiveImage
ilActiveLayer
ilActiveMipmap
ilApplyProfile
ilApplyPal
ilBindImage
ilBlit
ilClampNTSC
ilClearColour
ilClearImage
ilCloneCurImage
ilCompressDXT
ilCompressFunc
ilConvertImage
ilConvertPal
ilCopyImage
ilCopyPixels
ilCreateSubImage
ilDefaultImage
ilDeleteImage
ilDeleteImages
ilDetermineType
ilDetermineTypeF
ilDetermineTypeL
ilDisable
ilDxtcDataToImage
ilDxtcDataToSurface
ilEnable
ilFormatFunc
ilGenImage
ilGenImages
ilGetAlpha
ilGetBoolean
ilGetBooleanv
ilGetBppFormat
ilGetBppPal
ilGetBpcType
ilGetClear
ilGetCurImage
ilGetCurName
ilGetData
ilGetDXTCData
ilGetError
ilGetFormatBpp
ilGetInteger
ilGetIntegerv
ilGetLumpPos
ilGetPalBaseType
ilGetPalette
ilGetString
ilGetTypeBpc
ilHint
ilInit
ilInitImage
ilImageToDxtcData
ilIsDisabled
ilIsEnabled
ilIsImage
ilIsValid
ilIsValidF
ilIsValidL
ilKeyColour
ilLoad
ilLoadF
ilLoadImage
ilLoadL
ilLoadPal
ilModAlpha
ilNewImageFull
ilNextPower2
ilOriginFunc
ilOverlayImage
ilPopAttrib
ilPushAttrib
ilRegisterFormat
ilRegisterLoad
ilRegisterMipNum
ilRegisterNumFaces
ilRegisterNumImages
ilRegisterOrigin
ilRegisterPal
ilRegisterSave
ilRegisterType
ilRemoveLoad
ilRemoveSave
ilReplaceCurImage
ilResetMemory
ilResetRead
ilResetWrite
ilSave
ilSaveF
ilSaveImage
ilSaveL
ilSavePal
ilSaveData
ilSetAlpha
ilSetData
ilSetDuration
ilSetError
ilSetInteger
ilSetMemory
ilSetPal
ilSetRead
ilSetPixels
ilSetString
ilSetWrite
ilShutDown
ilSurfaceToDxtcData
ilTexImage
ilTexImageDxtc
ilTypeFromExt
ilTypeFunc
ilLoadData
ilLoadDataF
ilLoadDataL
;ilLoadFromJpegStruct
;ilSaveFromJpegStruct
; Internal but exported functions
iBindImageTemp
ilClearImage_
ilConvertBuffer
ilCloseImage
ilClosePal
iConvertImage
iConvertPal
iCopyPal
ilCopyImageAttr
ilCopyImage_
iGetFlipped
ilIsValidPal
ilNewImage
ilResizeImage
ilSetCurImage
ilTexImage_
ilTexSubImage_
ialloc
ifree
; Export the API of the included libjpeg so that applications
; can use both libraries without linking to two separate copies.
;jpeg_std_error
;jpeg_CreateCompress
;jpeg_CreateDecompress
;jpeg_destroy_compress
;jpeg_destroy_decompress
;jpeg_stdio_dest
;jpeg_stdio_src
;jpeg_set_defaults
;jpeg_set_colorspace
;jpeg_default_colorspace
;jpeg_set_quality
;jpeg_set_linear_quality
;jpeg_add_quant_table
;jpeg_quality_scaling
;jpeg_simple_progression
;jpeg_suppress_tables
;jpeg_alloc_quant_table
;jpeg_alloc_huff_table
;jpeg_start_compress
;jpeg_write_scanlines
;jpeg_finish_compress
;jpeg_write_raw_data
;jpeg_write_marker
;jpeg_write_m_header
;jpeg_write_m_byte
;jpeg_write_tables
;jpeg_read_header
;jpeg_start_decompress
;jpeg_read_scanlines
;jpeg_finish_decompress
;jpeg_read_raw_data
;jpeg_has_multiple_scans
;jpeg_start_output
;jpeg_finish_output
;jpeg_input_complete
;jpeg_new_colormap
;jpeg_consume_input
;jpeg_calc_output_dimensions
;jpeg_save_markers
;jpeg_set_marker_processor
;jpeg_read_coefficients
;jpeg_write_coefficients
;jpeg_copy_critical_parameters
;jpeg_abort_compress
;jpeg_abort_decompress
;jpeg_abort
;jpeg_destroy
;jpeg_resync_to_restart
;jpeg_copy_key_exif_parameters
;jpeg_extract_exif_entries
;jpeg_init_exif_field
;jpeg_build_exif_marker
;jpeg_init_exif_field_table
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

+123
View File
@@ -0,0 +1,123 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
///////////////// FILEVERSION 0,1,7,8////////////////////////////////////////
//
// Version
//
1 VERSIONINFO
FILEVERSION 0,1,7,8
PRODUCTVERSION 0,1,7,8
FILEFLAGSMASK 0x0L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "DevIL: A portable image library in development"
VALUE "CompanyName", "Abysmal Software"
VALUE "FileDescription", "DevIL: A portable image library in development"
VALUE "FileVersion", "1.7.8"
VALUE "InternalName", "Developer's Image Library (DevIL)"
VALUE "LegalCopyright", "Copyright © 2000-2008"
VALUE "LegalTrademarks", "Under LGPL License"
VALUE "OriginalFilename", "DevIL.dll"
VALUE "PrivateBuild", "Open Source"
VALUE "ProductName", "Developer's Image Library (DevIL)"
VALUE "ProductVersion", "1.7.8 Unicode"
VALUE "SpecialBuild", "Unicode"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON1 ICON "resources\\IL Logo.ico"
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.\0"
END
3 TEXTINCLUDE
BEGIN
"\r\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDC_OPENIL "Developer's Image Library, Version 1.7.8"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
File diff suppressed because it is too large Load Diff
+549
View File
@@ -0,0 +1,549 @@
# Microsoft Developer Studio Project File - Name="IL" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** NICHT BEARBEITEN **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=IL - WIN32 DEBUG
!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE
!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl
!MESSAGE
!MESSAGE NMAKE /f "IL.mak".
!MESSAGE
!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben
!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
!MESSAGE
!MESSAGE NMAKE /f "IL.mak" CFG="IL - WIN32 DEBUG"
!MESSAGE
!MESSAGE Für die Konfiguration stehen zur Auswahl:
!MESSAGE
!MESSAGE "IL - Win32 Debug" (basierend auf "Win32 (x86) Dynamic-Link Library")
!MESSAGE "IL - Win32 Dynamic" (basierend auf "Win32 (x86) Dynamic-Link Library")
!MESSAGE "IL - Win32 Release" (basierend auf "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName "IL"
# PROP Scc_LocalPath "..\.."
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "IL - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "../../lib/debug"
# PROP BASE Intermediate_Dir "../src/obj/debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "../../lib/debug"
# PROP Intermediate_Dir "../src/obj/debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "IL_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../projects/msvc/extlibs/" /I "../include" /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "IL_EXPORTS" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo /o"../src/obj/debug/DevIL.bsc"
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /def:".\il.def" /out:"C:\path\devil.dll" /pdbtype:sept /libpath:"../../projects/msvc/extlibs"
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "IL - Win32 Dynamic"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "../../lib"
# PROP BASE Intermediate_Dir "../src/obj/dynamic"
# PROP BASE Ignore_Export_Lib 0
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "../../lib"
# PROP Intermediate_Dir "../src/obj/dynamic"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "IL_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O1 /I "../include" /I "../../extlibs/" /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "IL_EXPORTS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo /o"../src/obj/dynamic/DevIL.bsc"
# ADD BSC32 /nologo /o"../src/obj/dynamic/DevIL.bsc"
LINK32=link.exe
# ADD BASE LINK32 delayimp.lib user32.lib gdi32.lib comdlg32.lib shell32.lib /nologo /dll /machine:I386 /def:".\il.def" /out:"../../lib/DevIL-l.dll" /OPT:NOWIN98 /delayload:libpng3.dll /delayload:lcms108.dll
# SUBTRACT BASE LINK32 /pdb:none
# ADD LINK32 delayimp.lib user32.lib gdi32.lib comdlg32.lib shell32.lib /nologo /dll /machine:I386 /def:".\il.def" /out:"../../lib/DevIL-l.dll" /libpath:"../../extlibs/lib" /OPT:NOWIN98 /delayload:lcms108.dll /delayload:libpng.dll
# SUBTRACT LINK32 /pdb:none
# Begin Special Build Tool
TargetName=DevIL-l
SOURCE="$(InputPath)"
PostBuild_Cmds=..\..\projects\msvc\insdll.bat ..\..\lib\$(TargetName).dll
# End Special Build Tool
!ELSEIF "$(CFG)" == "IL - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "../../lib"
# PROP BASE Intermediate_Dir "../src/obj"
# PROP BASE Ignore_Export_Lib 0
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "../../lib"
# PROP Intermediate_Dir "../src/obj"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "IL_EXPORTS" /D "IL_STATIC_LIB" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O1 /I "../../projects/msvc/extlibs/" /I "../include" /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "IL_EXPORTS" /YX /FD /c
# SUBTRACT CPP /X
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /i "..\include" /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo /o"../src/obj/DevIL.bsc"
# ADD BSC32 /nologo /o"../src/obj/DevIL.bsc"
LINK32=link.exe
# ADD BASE LINK32 user32.lib gdi32.lib comdlg32.lib shell32.lib /nologo /dll /machine:I386 /def:".\il.def" /out:"../../lib/DevIL.dll" /OPT:NOWIN98
# SUBTRACT BASE LINK32 /pdb:none
# ADD LINK32 user32.lib gdi32.lib comdlg32.lib shell32.lib /nologo /dll /machine:I386 /def:".\il.def" /out:"../../lib/DevIL.dll" /libpath:"../../projects/msvc/extlibs" /OPT:NOWIN98
# SUBTRACT LINK32 /pdb:none
# Begin Special Build Tool
SOURCE="$(InputPath)"
PostBuild_Cmds=copy ..\..\lib\DevIL.dll "C:\path\DevIL.dll"
# End Special Build Tool
!ENDIF
# Begin Target
# Name "IL - Win32 Debug"
# Name "IL - Win32 Dynamic"
# Name "IL - Win32 Release"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\il.def
!IF "$(CFG)" == "IL - Win32 Debug"
# PROP Exclude_From_Build 1
!ELSEIF "$(CFG)" == "IL - Win32 Dynamic"
# PROP BASE Exclude_From_Build 1
# PROP Exclude_From_Build 1
!ELSEIF "$(CFG)" == "IL - Win32 Release"
# PROP BASE Exclude_From_Build 1
# PROP Exclude_From_Build 1
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\src\il_alloc.c
# End Source File
# Begin Source File
SOURCE=..\src\il_bits.c
# End Source File
# Begin Source File
SOURCE=..\src\il_bmp.c
# End Source File
# Begin Source File
SOURCE=..\src\il_convbuff.c
# End Source File
# Begin Source File
SOURCE=..\src\il_convert.c
# End Source File
# Begin Source File
SOURCE=..\src\il_cut.c
# End Source File
# Begin Source File
SOURCE=..\src\il_dcx.c
# End Source File
# Begin Source File
SOURCE="..\src\il_dds-save.c"
# End Source File
# Begin Source File
SOURCE=..\src\il_dds.c
# End Source File
# Begin Source File
SOURCE=..\src\il_devil.c
# End Source File
# Begin Source File
SOURCE=..\src\il_doom.c
# End Source File
# Begin Source File
SOURCE=..\src\il_endian.c
# End Source File
# Begin Source File
SOURCE=..\src\il_error.c
# End Source File
# Begin Source File
SOURCE=..\src\il_fastconv.c
# End Source File
# Begin Source File
SOURCE=..\src\il_files.c
# End Source File
# Begin Source File
SOURCE=..\src\il_gif.c
# End Source File
# Begin Source File
SOURCE=..\src\il_hdr.c
# End Source File
# Begin Source File
SOURCE=..\src\il_header.c
# End Source File
# Begin Source File
SOURCE=..\src\il_icon.c
# End Source File
# Begin Source File
SOURCE=..\src\il_internal.c
# End Source File
# Begin Source File
SOURCE=..\src\il_io.c
# End Source File
# Begin Source File
SOURCE=..\src\il_jpeg.c
# End Source File
# Begin Source File
SOURCE=..\src\il_lif.c
# End Source File
# Begin Source File
SOURCE=..\src\il_main.c
# End Source File
# Begin Source File
SOURCE=..\src\il_manip.c
# End Source File
# Begin Source File
SOURCE=..\src\il_mdl.c
# End Source File
# Begin Source File
SOURCE=..\src\il_mng.c
# End Source File
# Begin Source File
SOURCE=..\src\il_neuquant.c
# End Source File
# Begin Source File
SOURCE=..\src\il_pal.c
# End Source File
# Begin Source File
SOURCE=..\src\il_pcd.c
# End Source File
# Begin Source File
SOURCE=..\src\il_pcx.c
# End Source File
# Begin Source File
SOURCE=..\src\il_pic.c
# End Source File
# Begin Source File
SOURCE=..\src\il_pix.c
# End Source File
# Begin Source File
SOURCE=..\src\il_png.c
# End Source File
# Begin Source File
SOURCE=..\src\il_pnm.c
# End Source File
# Begin Source File
SOURCE=..\src\il_profiles.c
# End Source File
# Begin Source File
SOURCE=..\src\il_psd.c
# End Source File
# Begin Source File
SOURCE=..\src\il_psp.c
# End Source File
# Begin Source File
SOURCE=..\src\il_pxr.c
# End Source File
# Begin Source File
SOURCE=..\src\il_quantizer.c
# End Source File
# Begin Source File
SOURCE=..\src\il_raw.c
# End Source File
# Begin Source File
SOURCE=..\src\il_rawdata.c
# End Source File
# Begin Source File
SOURCE=..\src\il_register.c
# End Source File
# Begin Source File
SOURCE=..\src\il_rle.c
# End Source File
# Begin Source File
SOURCE=..\src\il_sgi.c
# End Source File
# Begin Source File
SOURCE=..\src\il_stack.c
# End Source File
# Begin Source File
SOURCE=..\src\il_states.c
# End Source File
# Begin Source File
SOURCE=..\src\il_targa.c
# End Source File
# Begin Source File
SOURCE=..\src\il_tiff.c
# End Source File
# Begin Source File
SOURCE=..\src\il_utility.c
# End Source File
# Begin Source File
SOURCE=..\src\il_wal.c
# End Source File
# Begin Source File
SOURCE=..\src\il_xpm.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=..\..\include\IL\config.h
# End Source File
# Begin Source File
SOURCE=..\..\include\IL\devil_internal_exports.h
# End Source File
# Begin Source File
SOURCE=..\..\include\il\il.h
# End Source File
# Begin Source File
SOURCE=..\include\il_alloc.h
# End Source File
# Begin Source File
SOURCE=..\include\il_bits.h
# End Source File
# Begin Source File
SOURCE=..\include\il_bmp.h
# End Source File
# Begin Source File
SOURCE=..\include\il_dcx.h
# End Source File
# Begin Source File
SOURCE=..\include\il_dds.h
# End Source File
# Begin Source File
SOURCE=..\include\il_doompal.h
# End Source File
# Begin Source File
SOURCE=..\include\il_endian.h
# End Source File
# Begin Source File
SOURCE=..\include\il_files.h
# End Source File
# Begin Source File
SOURCE=..\include\il_gif.h
# End Source File
# Begin Source File
SOURCE=..\include\il_hdr.h
# End Source File
# Begin Source File
SOURCE=..\include\il_icon.h
# End Source File
# Begin Source File
SOURCE=..\include\il_internal.h
# End Source File
# Begin Source File
SOURCE=..\include\il_jpeg.h
# End Source File
# Begin Source File
SOURCE=..\include\il_lif.h
# End Source File
# Begin Source File
SOURCE=..\include\il_manip.h
# End Source File
# Begin Source File
SOURCE=..\include\il_mdl.h
# End Source File
# Begin Source File
SOURCE=..\include\il_pal.h
# End Source File
# Begin Source File
SOURCE=..\include\il_pcx.h
# End Source File
# Begin Source File
SOURCE=..\include\il_pic.h
# End Source File
# Begin Source File
SOURCE=..\include\il_pnm.h
# End Source File
# Begin Source File
SOURCE=..\include\il_psd.h
# End Source File
# Begin Source File
SOURCE=..\include\il_psp.h
# End Source File
# Begin Source File
SOURCE=..\include\il_q2pal.h
# End Source File
# Begin Source File
SOURCE=..\include\il_register.h
# End Source File
# Begin Source File
SOURCE=..\include\il_rle.h
# End Source File
# Begin Source File
SOURCE=..\include\il_sgi.h
# End Source File
# Begin Source File
SOURCE=..\include\il_stack.h
# End Source File
# Begin Source File
SOURCE=..\include\il_states.h
# End Source File
# Begin Source File
SOURCE=..\include\il_targa.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# Begin Source File
SOURCE=".\resources\IL Logo.ico"
# End Source File
# Begin Source File
SOURCE=.\IL.rc
# End Source File
# End Group
# Begin Group "Text Files"
# PROP Default_Filter "txt"
# Begin Source File
SOURCE=..\..\AUTHORS
# End Source File
# Begin Source File
SOURCE=..\..\BUGS
# End Source File
# Begin Source File
SOURCE=..\..\ChangeLog
# End Source File
# Begin Source File
SOURCE=..\..\CREDITS
# End Source File
# Begin Source File
SOURCE=..\..\libraries.txt
# End Source File
# Begin Source File
SOURCE="..\..\MSVC++.txt"
# End Source File
# Begin Source File
SOURCE=..\..\README.unix
# End Source File
# Begin Source File
SOURCE=..\..\README.win
# End Source File
# End Group
# End Target
# End Project
+120
View File
@@ -0,0 +1,120 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////// FILEVERSION 0,1,7,8//////////////////////////////////////
//
// Version
//
1 VERSIONINFO
FILEVERSION 0,1,7,8
PRODUCTVERSION 0,1,7,8
FILEFLAGSMASK 0x0L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "DevIL: A portable image library in development"
VALUE "CompanyName", "Abysmal Software"
VALUE "FileDescription", "DevIL: A portable image library in development"
VALUE "FileVersion", "1.7.8"
VALUE "InternalName", "Developer's Image Library (DevIL)"
VALUE "LegalCopyright", "Copyright © 2000-2008"
VALUE "LegalTrademarks", "Under LGPL License"
VALUE "OriginalFilename", "DevIL.dll"
VALUE "PrivateBuild", "Open Source"
VALUE "ProductName", "Developer's Image Library (DevIL)"
VALUE "ProductVersion", "1.7.8 Ansi"
VALUE "SpecialBuild", "Ansi"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON1 ICON "resources\\IL Logo.ico"
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.\0"
END
3 TEXTINCLUDE
BEGIN
"\r\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDC_OPENIL "Developer's Image Library, Version 1.7.8"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
File diff suppressed because it is too large Load Diff
+200
View File
@@ -0,0 +1,200 @@
; To remove an export, add a semicolon at the beginning of the line to comment it out.
EXPORTS
ilActiveFace
ilActiveImage
ilActiveLayer
ilActiveMipmap
ilApplyProfile
ilApplyPal
ilBindImage
ilBlit
ilClampNTSC
ilClearColour
ilClearImage
ilCloneCurImage
ilCompressDXT
ilCompressFunc
ilConvertImage
ilConvertPal
ilCopyImage
ilCopyPixels
ilCreateSubImage
ilDefaultImage
ilDeleteImage
ilDeleteImages
ilDetermineType
ilDetermineTypeF
ilDetermineTypeL
ilDisable
ilDxtcDataToImage
ilDxtcDataToSurface
ilEnable
ilFormatFunc
ilGenImage
ilGenImages
ilGetAlpha
ilGetBoolean
ilGetBooleanv
ilGetBppFormat
ilGetBppPal
ilGetBpcType
ilGetClear
ilGetCurImage
ilGetCurName
ilGetData
ilGetDXTCData
ilGetError
ilGetFormatBpp
ilGetInteger
ilGetIntegerv
ilGetLumpPos
ilGetPalBaseType
ilGetPalette
ilGetString
ilGetTypeBpc
ilHint
ilInit
ilInitImage
ilImageToDxtcData
ilIsDisabled
ilIsEnabled
ilIsImage
ilIsValid
ilIsValidF
ilIsValidL
ilKeyColour
ilLoad
ilLoadF
ilLoadImage
ilLoadL
ilLoadPal
ilModAlpha
ilNewImageFull
ilNextPower2
ilOriginFunc
ilOverlayImage
ilPopAttrib
ilPushAttrib
ilRegisterFormat
ilRegisterLoad
ilRegisterMipNum
ilRegisterNumFaces
ilRegisterNumImages
ilRegisterOrigin
ilRegisterPal
ilRegisterSave
ilRegisterType
ilRemoveLoad
ilRemoveSave
ilReplaceCurImage
ilResetMemory
ilResetRead
ilResetWrite
ilSave
ilSaveF
ilSaveImage
ilSaveL
ilSavePal
ilSaveData
ilSetAlpha
ilSetData
ilSetDuration
ilSetError
ilSetInteger
ilSetMemory
ilSetPal
ilSetRead
ilSetPixels
ilSetString
ilSetWrite
ilShutDown
ilSurfaceToDxtcData
ilTexImage
ilTexImageDxtc
ilTypeFromExt
ilTypeFunc
ilLoadData
ilLoadDataF
ilLoadDataL
;ilLoadFromJpegStruct
;ilSaveFromJpegStruct
; Internal but exported functions
iBindImageTemp
ilClearImage_
ilConvertBuffer
ilCloseImage
ilClosePal
iConvertImage
iConvertPal
iCopyPal
ilCopyImageAttr
ilCopyImage_
iGetFlipped
ilIsValidPal
ilNewImage
ilResizeImage
ilSetCurImage
ilTexImage_
ilTexSubImage_
ialloc
ifree
; Export the API of the included libjpeg so that applications
; can use both libraries without linking to two separate copies.
;jpeg_std_error
;jpeg_CreateCompress
;jpeg_CreateDecompress
;jpeg_destroy_compress
;jpeg_destroy_decompress
;jpeg_stdio_dest
;jpeg_stdio_src
;jpeg_set_defaults
;jpeg_set_colorspace
;jpeg_default_colorspace
;jpeg_set_quality
;jpeg_set_linear_quality
;jpeg_add_quant_table
;jpeg_quality_scaling
;jpeg_simple_progression
;jpeg_suppress_tables
;jpeg_alloc_quant_table
;jpeg_alloc_huff_table
;jpeg_start_compress
;jpeg_write_scanlines
;jpeg_finish_compress
;jpeg_write_raw_data
;jpeg_write_marker
;jpeg_write_m_header
;jpeg_write_m_byte
;jpeg_write_tables
;jpeg_read_header
;jpeg_start_decompress
;jpeg_read_scanlines
;jpeg_finish_decompress
;jpeg_read_raw_data
;jpeg_has_multiple_scans
;jpeg_start_output
;jpeg_finish_output
;jpeg_input_complete
;jpeg_new_colormap
;jpeg_consume_input
;jpeg_calc_output_dimensions
;jpeg_save_markers
;jpeg_set_marker_processor
;jpeg_read_coefficients
;jpeg_write_coefficients
;jpeg_copy_critical_parameters
;jpeg_abort_compress
;jpeg_abort_decompress
;jpeg_abort
;jpeg_destroy
;jpeg_resync_to_restart
;jpeg_copy_key_exif_parameters
;jpeg_extract_exif_entries
;jpeg_init_exif_field
;jpeg_build_exif_marker
;jpeg_init_exif_field_table
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

@@ -0,0 +1,40 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Last modified: 17/04/2005
// by Meloni Dario
//
// Description: Common altivec function.
//
//-----------------------------------------------------------------------------
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif //HAVE_CONFIG_H
#ifdef ALTIVEC_GCC
#include "altivec_common.h"
// from http://developer.apple.com/hardware/ve/alignment.html
/*vector unsigned char load_unaligned( unsigned char *buffer ) {
vector unsigned char MSQ, LSQ;
vector unsigned char mask;
MSQ = vec_ld(0, buffer); // most significant quadword
LSQ = vec_ld(15, buffer); // least significant quadword
mask = vec_lvsl(0, buffer); // create the permute mask
return vec_perm(MSQ, LSQ, mask);// align the data
}*/
vector float fill_vector_f( float value ) {
vector_t vec;
vec.sf[0] = value;
vector float temp = vec_ld(0,vec.sf);
return vec_splat(temp,0);
}
inline unsigned int round16( unsigned int v ) {
return ((int)((v/16)*10)%10) > 0 ? (v/16) : (v/16)+1;
}
#endif
@@ -0,0 +1,230 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif //HAVE_CONFIG_H
#ifdef ALTIVEC_GCC
#include "altivec_typeconversion.h"
static inline void abc2cba_internal( register const vector unsigned char p[4], unsigned char *data, register unsigned int length, unsigned char *newdata ) {
register vector unsigned char d0,d1,d2,t0,t1,t2;
length = eround16(length);
if( length >= 3 ) {
length -= 3;
d2 = vec_ld(32,data);
d1 = vec_ld(16,data);
d0 = vec_ld(0,data);
while( length >= 3 ) {
t0 = vec_perm(d0,d1,p[0]);
t1 = vec_perm(d1,d0,p[1]);
t2 = vec_perm(d2,d1,p[2]);
t1 = vec_perm(t1,d2,p[3]);
vec_st(t0,0,newdata);
vec_st(t1,16,newdata);
vec_st(t2,32,newdata);
length -= 3;
data += 16*3;
newdata += 16*3;
d2 = vec_ld(32,data);
d1 = vec_ld(16,data);
d0 = vec_ld(0,data);
}
t0 = vec_perm(d0,d1,p[0]);
t1 = vec_perm(d1,d0,p[1]);
t2 = vec_perm(d2,d1,p[2]);
t1 = vec_perm(t1,d2,p[3]);
vec_st(t0,0,newdata);
vec_st(t1,16,newdata);
vec_st(t2,32,newdata);
}
if( length == 2 ) {
d0 = vec_ld(0,data);
d1 = vec_ld(16,data);
t0 = vec_perm(d0,d1,p[0]);
t1 = vec_perm(d1,d0,p[1]);
vec_st(t0,0,newdata);
vec_st(t1,16,newdata);
} else if( length == 1 ) {
d0 = vec_ld(0,data);
t0 = vec_perm(d0,d0,p[0]);
vec_st(t0,0,newdata);
}
}
static inline void abcd2cbad_internal( register const vector unsigned char p, unsigned char *data, unsigned int length, unsigned char *newdata ) {
register vector unsigned char d0,d1,d2,z;
z = vec_splat_u8(0);
length = eround16(length);
if( length >= 3 ) {
length -= 3;
d2 = vec_ld(32,data);
d1 = vec_ld(16,data);
d0 = vec_ld(0,data);
while( length >= 3 ) {
d0 = vec_perm(d0,z,p);
d1 = vec_perm(d1,z,p);
d2 = vec_perm(d2,z,p);
vec_st(d0,0,newdata);
vec_st(d1,16,newdata);
vec_st(d2,32,newdata);
length -= 3;
data += 16*3;
newdata += 16*3;
d2 = vec_ld(32,data);
d1 = vec_ld(16,data);
d0 = vec_ld(0,data);
}
d0 = vec_perm(d0,z,p);
d1 = vec_perm(d1,z,p);
d2 = vec_perm(d2,z,p);
vec_st(d0,0,newdata);
vec_st(d1,16,newdata);
vec_st(d2,32,newdata);
}
if( length == 2 ) {
d0 = vec_ld(0,data);
d1 = vec_ld(16,data);
d0 = vec_perm(d0,z,p);
d1 = vec_perm(d1,z,p);
vec_st(d0,0,newdata);
vec_st(d1,16,newdata);
} else if( length == 1 ) {
d0 = vec_ld(0,data);
d0 = vec_perm(d0,d0,z);
vec_st(d0,0,newdata);
}
}
// Format conversion function
void abc2cba_byte( ILubyte *data, ILuint length, ILubyte *newdata ) {
const vector unsigned char p[4] =
{ (vector unsigned char)(0x02,0x01,0x00,0x05,0x04,0x03,0x08,0x07,0x06,0x0B,0x0A,0x09,0x0E,0x0D,0x0C,0x11),
(vector unsigned char)(0x00,0x10,0x04,0x03,0x02,0x07,0x06,0x05,0x0A,0x09,0x08,0x0D,0x0C,0x0B,0x0E,0x0F),
(vector unsigned char)(0x1E,0x03,0x02,0x01,0x06,0x05,0x04,0x09,0x08,0x07,0x0C,0x0B,0x0A,0x0F,0x0E,0x0D),
(vector unsigned char)(0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x10,0x0F)};
abc2cba_internal(p,data,length,newdata);
}
void abc2cba_short( ILushort *data, ILuint length, ILushort *newdata ) {
const vector unsigned char p[4] =
{ (vector unsigned char)(0x04,0x05,0x02,0x03,0x00,0x01,0x0A,0x0B,0x08,0x09,0x06,0x07,0x10,0x11,0x0E,0x0F),
(vector unsigned char)(0x1C,0x1D,0x06,0x07,0x04,0x05,0x02,0x03,0x0C,0x0D,0x0A,0x0B,0x08,0x09,0x0E,0x0F),
(vector unsigned char)(0x00,0x01,0x1E,0x1F,0x08,0x09,0x06,0x07,0x04,0x05,0x0E,0x0F,0x0C,0x0D,0x0A,0x0B),
(vector unsigned char)(0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x12,0x13)};
abc2cba_internal(p,(ILubyte*)data,length,(ILubyte*)newdata);
}
void abc2cba_int( ILuint *data, ILuint length, ILuint *newdata ) {
const vector unsigned char p[4] =
{ (vector unsigned char)(0x08,0x09,0x0A,0x0B,0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03,0x14,0x15,0x16,0x17),
(vector unsigned char)(0x00,0x01,0x02,0x03,0x1C,0x1D,0x1E,0x1F,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F),
(vector unsigned char)(0x18,0x19,0x1A,0x1B,0x0C,0x0D,0x0E,0x0F,0x08,0x09,0x0A,0x0B,0x04,0x05,0x06,0x07),
(vector unsigned char)(0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x10,0x11,0x12,0x13,0x0C,0x0D,0x0E,0x0F)};
abc2cba_internal(p,(ILubyte*)data,length,(ILubyte*)newdata);
}
void abc2cba_double( ILdouble *data, ILuint length, ILdouble *newdata ) {
const vector unsigned char p[4] =
{ (vector unsigned char)(0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F),
(vector unsigned char)(0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F),
(vector unsigned char)(0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F),
(vector unsigned char)(0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F)};
abc2cba_internal(p,(ILubyte*)data,length,(ILubyte*)newdata);
}
void abcd2cbad_byte( ILubyte *data, ILuint length, ILubyte *newdata ) {
const vector unsigned char p = (vector unsigned char)(0x02,0x01,0x00,0x03,0x06,0x05,0x04,0x07,0x0A,0x09,0x08,0x0B, 0x0E,0x0D,0x0C,0x0F);
abcd2cbad_internal(p,data,length,newdata);
}
void abcd2cbad_short( ILushort *data, ILuint length, ILushort *newdata ) {
const vector unsigned char p = (vector unsigned char)(0x04,0x05,0x02,0x03,0x00,0x01,0x06,0x07,0x0C,0x0D,0x0A,0x0B,0x08,0x09,0x0E,0x0F);
abcd2cbad_internal(p,(ILubyte*)data,length,(ILubyte*)newdata);
}
void abcd2cbad_int( ILuint *data, ILuint length, ILuint *newdata ) {
const vector unsigned char p = (vector unsigned char)(0x08,0x09,0x0A,0x0B,0x04,0x05,0x06,0x07,0x00,0x01,0x02,0x03,0x0C,0x0D,0x0E,0x0F);
abcd2cbad_internal(p,(ILubyte*)data,length,(ILubyte*)newdata);
}
void abcd2cbad_double( ILdouble *tdata, ILuint length, ILdouble *tnewdata ) {
register ILubyte *data = (ILubyte*)tdata;
register ILubyte *newdata = (ILubyte*)tnewdata;
const vector unsigned char p = (vector unsigned char)(0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F);
register vector unsigned char d0,d1,d2,d3,t0,t1,t2,t3;
length = eround16(length);
if( length >= 4 ) {
length -= 4;
d3 = vec_ld(48,data);
d2 = vec_ld(32,data);
d1 = vec_ld(16,data);
d0 = vec_ld(0,data);
while( length >= 4 ) {
t0 = vec_perm(d0,d1,p);
t1 = vec_perm(d1,d0,p);
t2 = vec_perm(d2,d3,p);
t3 = vec_perm(d3,d2,p);
vec_st(t0,0,newdata);
vec_st(t1,16,newdata);
vec_st(t2,32,newdata);
vec_st(t3,48,newdata);
length -= 4;
data += 16*4;
newdata += 16*4;
d3 = vec_ld(48,data);
d2 = vec_ld(32,data);
d1 = vec_ld(16,data);
d0 = vec_ld(0,data);
}
t0 = vec_perm(d0,d1,p);
t1 = vec_perm(d1,d0,p);
t2 = vec_perm(d2,d3,p);
t3 = vec_perm(d3,d2,p);
vec_st(d0,0,newdata);
vec_st(d1,16,newdata);
vec_st(d2,32,newdata);
vec_st(d3,48,newdata);
}
if( length == 2 ) {
d0 = vec_ld(0,data);
d1 = vec_ld(16,data);
t0 = vec_perm(d0,d1,p);
t1 = vec_perm(d1,d0,p);
vec_st(t0,0,newdata);
vec_st(t1,16,newdata);
}
}
#endif
+287
View File
@@ -0,0 +1,287 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Last modified: 08/17/2008
//
// Filename: src-IL/src/il_alloc.c
//
// Description: Memory allocation functions
//
//-----------------------------------------------------------------------------
#define __ALLOC_C
// Memory leak detection
#ifdef _WIN32
#ifdef _DEBUG
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#ifndef _WIN32_WCE // Does not have this header.
#include <crtdbg.h>
#endif
#endif
#endif//_WIN32
#include "il_internal.h"
#include <stdlib.h>
#include <math.h>
#ifdef MM_MALLOC
#include <mm_malloc.h>
#endif
static void ILAPIENTRY DefaultFreeFunc(const void * CONST_RESTRICT Ptr);
static void* ILAPIENTRY DefaultAllocFunc(const ILsizei Size);
static mAlloc ialloc_ptr = DefaultAllocFunc;
static mFree ifree_ptr = DefaultFreeFunc;
/*** Vector Allocation/Deallocation Function ***/
#ifdef VECTORMEM
void *vec_malloc(const ILsizei size)
{
const ILsizei _size = size % 16 > 0 ? size + 16 - (size % 16) : size; // align size value
#ifdef MM_MALLOC
return _mm_malloc(_size,16);
#else
#ifdef VALLOC
return valloc( _size );
#else
#ifdef POSIX_MEMALIGN
char *buffer;
return posix_memalign((void**)&buffer, 16, _size) == 0 ? buffer : NULL;
#else
#ifdef MEMALIGN
return memalign( 16, _size );
#else
// Memalign hack from ffmpeg for MinGW
void *ptr;
int diff;
ptr = malloc(_size+16+1);
diff= ((-(int)ptr - 1)&15) + 1;
ptr = (void*)(((char*)ptr)+diff);
((char*)ptr)[-1]= diff;
return ptr;
#endif //MEMALIGN
#endif //POSIX_MEMALIGN
#endif //VALLOC
#endif //MM_MALLOC
}
void *ivec_align_buffer(void *buffer, const ILsizei size)
{
if( (ILsizei)buffer % 16 != 0 ) {
void *aligned_buffer = vec_malloc( size );
memcpy( aligned_buffer, buffer, size );
ifree( buffer );
return aligned_buffer;
}
return buffer;
}
#endif
/*** Allocation/Deallocation Function ***/
void* ILAPIENTRY ialloc(const ILsizei Size)
{
void *Ptr = ialloc_ptr(Size);
if (Ptr == NULL)
ilSetError(IL_OUT_OF_MEMORY);
return Ptr;
}
void ILAPIENTRY ifree(const void * CONST_RESTRICT Ptr)
{
if (Ptr == NULL)
return;
ifree_ptr(Ptr);
return;
}
void* ILAPIENTRY icalloc(const ILsizei Size, const ILsizei Num)
{
void *Ptr = ialloc(Size * Num);
if (Ptr == NULL)
return Ptr;
imemclear(Ptr, Size * Num);
return Ptr;
}
/*** Default Allocation/Deallocation Function ***/
static void* ILAPIENTRY DefaultAllocFunc(const ILsizei Size)
{
#ifdef VECTORMEM
return (void*)vec_malloc(Size);
#else
return malloc(Size);
#endif //VECTORMEM
}
static void ILAPIENTRY DefaultFreeFunc(const void * CONST_RESTRICT ptr)
{
if (ptr)
{
#ifdef MM_MALLOC
_mm_free((void*)ptr);
#else
#if defined(VECTORMEM) & !defined(POSIX_MEMALIGN) & !defined(VALLOC) & !defined(MEMALIGN) & !defined(MM_MALLOC)
free(((char*)Ptr) - ((char*)Ptr)[-1]);
#else
free((void*)ptr);
#endif //OTHERS...
#endif //MM_MALLOC
}
}
/*** Manipulate Allocation/Deallocation Function ***/
void ILAPIENTRY ilResetMemory() // Deprecated
{
ialloc_ptr = DefaultAllocFunc;
ifree_ptr = DefaultFreeFunc;
}
void ILAPIENTRY ilSetMemory(mAlloc AllocFunc, mFree FreeFunc)
{
ialloc_ptr = AllocFunc == NULL ? DefaultAllocFunc : AllocFunc;
ifree_ptr = FreeFunc == NULL ? DefaultFreeFunc : FreeFunc;
}
/*#if defined(_WIN32) && defined(_MEM_DEBUG)
#include <windows.h>
int bAtexit = 0;
typedef struct ALLOC_INFO
{
unsigned long address;
unsigned long size;
char file[64];
unsigned long line;
struct ALLOC_INFO *Next;
} ALLOC_INFO;
ALLOC_INFO *AllocList;
void AddTrack(unsigned long addr, unsigned long size, const char *file, unsigned long line)
{
ALLOC_INFO *Temp;
if (AllocList == NULL) {
AllocList = (ALLOC_INFO*)malloc(sizeof(ALLOC_INFO)); // Just assume it succeeds.
AllocList->address = addr;
AllocList->size = size;
AllocList->line = line;
strncpy(AllocList->file, file, 63);
AllocList->Next = NULL;
}
else {
Temp = AllocList;
AllocList = (ALLOC_INFO*)malloc(sizeof(ALLOC_INFO)); // Just assume it succeeds.
AllocList->address = addr;
AllocList->size = size;
AllocList->line = line;
strncpy(AllocList->file, file, 63);
AllocList->Next = Temp;
}
return;
}
void RemoveTrack(unsigned long addr)
{
ALLOC_INFO *Temp, *Prev;
Temp = AllocList;
Prev = NULL;
if (Temp == NULL)
return;
while (Temp != NULL) {
if (Temp->address == addr) {
if (Prev == NULL) {
AllocList = Temp->Next;
free(Temp);
}
else {
Prev->Next = Temp->Next;
free(Temp);
}
break;
}
Prev = Temp;
Temp = Temp->Next;
}
return;
}
void DumpUnfreed(void)
{
unsigned long TotalSize = 0;
char buf[1024];
ALLOC_INFO *i = AllocList;
OutputDebugString("DevIL Unfreed Information:\n");
while (i != NULL) {
sprintf(buf, "%s(%d) : %d bytes unfreed at %d\n", i->file, i->line, i->size, i->address);
OutputDebugString(buf);
TotalSize += i->size;
AllocList = i->Next;
free(i);
i = AllocList;
}
sprintf(buf, "-----------------------------------------------------------\n");
OutputDebugString(buf);
sprintf(buf, "Total Unfreed: %d bytes\n\n\n", TotalSize);
OutputDebugString(buf);
}
void AddToAtexit()
{
if (bAtexit)
return;
atexit(DumpUnfreed);
bAtexit = 1;
}
void *c_alloc(unsigned long size, unsigned long num, const char *file, unsigned long line)
{
void *ptr;
ptr = calloc(size, num);
if (!ptr)
return NULL;
AddToAtexit();
AddTrack((unsigned long)ptr, size * num, file, line);
return ptr;
}
void *m_alloc(unsigned long size, const char *file, unsigned long line)
{
void *ptr;
ptr = malloc(size);
if (!ptr)
return NULL;
AddToAtexit();
AddTrack((unsigned long)ptr, size, file, line);
return ptr;
}
void f_ree(void *ptr)
{
RemoveTrack((unsigned long)ptr);
free(ptr);
return;
}
#endif//defined(_WIN32) && defined(_MEM_DEBUG)*/
+185
View File
@@ -0,0 +1,185 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2008 by Denton Woods
// Last modified: 08/14/2004
//
// Filename: src-IL/src/il_bits.c
//
// Description: Implements a file class that reads/writes bits directly.
//
//-----------------------------------------------------------------------------
#include "il_internal.h"
#include "il_bits.h"
// Opens a BITFILE just like fopen opens a FILE.
/*BITFILE *bopen(const char *FileName, const char *Mode)
{
BITFILE *ToReturn = NULL;
if (FileName != NULL) {
ToReturn = (BITFILE*)ialloc(sizeof(BITFILE));
if (ToReturn != NULL) {
iopenr((char*)FileName);
ToReturn->File = iGetFile();
ToReturn->BitPos = 0;
ToReturn->ByteBitOff = 8;
ToReturn->Buff = 0;
}
}
return ToReturn;
}*/
// Converts a FILE to a BITFILE.
BITFILE *bfile(ILHANDLE File)
{
BITFILE *ToReturn = NULL;
if (File != NULL) {
ToReturn = (BITFILE*)ialloc(sizeof(BITFILE));
if (ToReturn != NULL) {
ToReturn->File = File;
ToReturn->BitPos = itell() << 3;
ToReturn->ByteBitOff = 8;
ToReturn->Buff = 0;
}
}
return ToReturn;
}
// Closes an open BITFILE and frees memory for it.
ILint bclose(BITFILE *BitFile)
{
if (BitFile == NULL || BitFile->File == NULL)
return IL_EOF;
// Removed 01-26-2008. The file will get closed later by
// the calling function.
//icloser(BitFile->File);
ifree(BitFile);
return 0;
}
// Returns the current bit position of a BITFILE.
ILint btell(BITFILE *BitFile)
{
return BitFile->BitPos;
}
// Seeks in a BITFILE just like fseek for FILE.
ILint bseek(BITFILE *BitFile, ILuint Offset, ILuint Mode)
{
ILint KeepPos, Len;
if (BitFile == NULL || BitFile->File == NULL)
return 1;
switch (Mode)
{
case IL_SEEK_SET:
if (!iseek(Offset >> 3, Mode)) {
BitFile->BitPos = Offset;
BitFile->ByteBitOff = BitFile->BitPos % 8;
}
break;
case IL_SEEK_CUR:
if (!iseek(Offset >> 3, Mode)) {
BitFile->BitPos += Offset;
BitFile->ByteBitOff = BitFile->BitPos % 8;
}
break;
case IL_SEEK_END:
KeepPos = itell();
iseek(0, IL_SEEK_END);
Len = itell();
iseek(0, IL_SEEK_SET);
if (!iseek(Offset >> 3, Mode)) {
BitFile->BitPos = (Len << 3) + Offset;
BitFile->ByteBitOff = BitFile->BitPos % 8;
}
break;
default:
return 1;
}
return 0;
}
// hehe, "bread". It reads data into Buffer from the BITFILE, just like fread for FILE.
ILint bread(void *Buffer, ILuint Size, ILuint Number, BITFILE *BitFile)
{
// Note that this function is somewhat useless: In binary image
// formats, there are some pad bits after each scanline. This
// function does not take that into account, so you must use bseek to
// skip the calculated value of bits.
ILuint BuffPos = 0, Count = Size * Number;
while (BuffPos < Count) {
if (BitFile->ByteBitOff < 0 || BitFile->ByteBitOff > 7) {
BitFile->ByteBitOff = 7;
if (iread(&BitFile->Buff, 1, 1) != 1) // Reached eof or error...
return BuffPos;
}
*((ILubyte*)(Buffer) + BuffPos) = (ILubyte)!!(BitFile->Buff & (1 << BitFile->ByteBitOff));
BuffPos++;
BitFile->ByteBitOff--;
}
return BuffPos;
}
// Reads bits and puts the first bit in the file as the highest in the return value.
ILuint breadVal(ILuint NumBits, BITFILE *BitFile)
{
ILuint BuffPos = 0;
ILuint Buffer = 0;
// Only returning up to 32 bits at one time
if (NumBits > 32) {
ilSetError(IL_INTERNAL_ERROR);
return 0;
}
while (BuffPos < NumBits) {
Buffer <<= 1;
if (BitFile->ByteBitOff < 0 || BitFile->ByteBitOff > 7) {
BitFile->ByteBitOff = 7;
if (iread(&BitFile->Buff, 1, 1) != 1) // Reached eof or error...
return BuffPos;
}
Buffer = Buffer + (ILubyte)!!(BitFile->Buff & (1 << BitFile->ByteBitOff));
BuffPos++;
BitFile->ByteBitOff--;
}
return BuffPos;
}
// Not implemented yet.
/*ILint bwrite(void *Buffer, ILuint Size, ILuint Number, BITFILE *BitFile)
{
return 0;
}*/
+736
View File
@@ -0,0 +1,736 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 02/14/2009
//
// Filename: src-IL/src/il_blp.c
//
// Description: Reads from a Blizzard Texture (.blp).
// Specifications were found at http://www.wowwiki.com/BLP_files
// for BLP2 and from
// http://web.archive.org/web/20080117120549/magos.thejefffiles.com/War3ModelEditor/MagosBlpFormat.txt
// for BLP1.
//
//-----------------------------------------------------------------------------
//@TODO: Add support for the BLP1 format as well.
#include "il_internal.h"
#ifndef IL_NO_BLP
#include "il_dds.h"
typedef struct BLP1HEAD
{
ILubyte Sig[4];
ILuint Compression; // Texture type: 0 = JPG, 1 = Paletted
ILuint Flags; // #8 - Uses alpha channel (?)
ILuint Width; // Image width in pixels
ILuint Height; // Image height in pixels
ILuint PictureType; // 3 - Uncompressed index list + alpha list
// 4 - Uncompressed index list + alpha list
// 5 - Uncompressed index list
ILuint PictureSubType; // 1 - ???
ILuint MipOffsets[16]; // The file offsets of each mipmap, 0 for unused
ILuint MipLengths[16]; // The length of each mipmap data block
} BLP1HEAD;
typedef struct BLP2HEAD
{
ILubyte Sig[4]; // "BLP2" signature
ILuint Type; // Texture type: 0 = JPG, 1 = DXTC
ILubyte Compression; // Compression mode: 1 = raw, 2 = DXTC
ILubyte AlphaBits; // 0, 1, or 8
ILubyte AlphaType; // 0, 1, 7 or 8
ILubyte HasMips; // 0 = no mips levels, 1 = has mips (number of levels determined by image size)
ILuint Width; // Image width in pixels
ILuint Height; // Image height in pixels
ILuint MipOffsets[16]; // The file offsets of each mipmap, 0 for unused
ILuint MipLengths[16]; // The length of each mipmap data block
} BLP2HEAD;
// Data formats
#define BLP_TYPE_JPG 0
#define BLP_TYPE_DXTC_RAW 1
#define BLP_RAW 1
#define BLP_DXTC 2
#define BLP_RAW_PLUS_ALPHA1 3
#define BLP_RAW_PLUS_ALPHA2 4
#define BLP_RAW_NO_ALPHA 5
ILboolean iIsValidBlp2(void);
ILboolean iCheckBlp2(BLP2HEAD *Header);
ILboolean iLoadBlpInternal(void);
ILboolean iLoadBlp1(void);
ILboolean iCheckBlp1(BLP1HEAD *Header);
ILboolean iGetBlp1Head(BLP1HEAD *Header);
//! Checks if the file specified in FileName is a valid BLP file.
ILboolean ilIsValidBlp(ILconst_string FileName)
{
ILHANDLE BlpFile;
ILboolean bBlp = IL_FALSE;
if (!iCheckExtension(FileName, IL_TEXT("blp"))) {
ilSetError(IL_INVALID_EXTENSION);
return bBlp;
}
BlpFile = iopenr(FileName);
if (BlpFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bBlp;
}
bBlp = ilIsValidBlpF(BlpFile);
icloser(BlpFile);
return bBlp;
}
//! Checks if the ILHANDLE contains a valid BLP file at the current position.
ILboolean ilIsValidBlpF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iIsValidBlp2();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Checks if Lump is a valid BLP lump.
ILboolean ilIsValidBlpL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iIsValidBlp2();
}
// Internal function used to get the BLP header from the current file.
ILboolean iGetBlp2Head(BLP2HEAD *Header)
{
ILuint i;
iread(Header->Sig, 1, 4);
Header->Type = GetLittleUInt();
Header->Compression = igetc();
Header->AlphaBits = igetc();
Header->AlphaType = igetc();
Header->HasMips = igetc();
Header->Width = GetLittleUInt();
Header->Height = GetLittleUInt();
for (i = 0; i < 16; i++)
Header->MipOffsets[i] = GetLittleUInt();
for (i = 0; i < 16; i++)
Header->MipLengths[i] = GetLittleUInt();
return IL_TRUE;
}
// Internal function to get the header and check it.
ILboolean iIsValidBlp2(void)
{
BLP2HEAD Header;
if (!iGetBlp2Head(&Header))
return IL_FALSE;
iseek(-148, IL_SEEK_CUR);
return iCheckBlp2(&Header);
}
// Internal function used to check if the HEADER is a valid BLP header.
ILboolean iCheckBlp2(BLP2HEAD *Header)
{
// The file signature is 'BLP2'.
if (strncmp(Header->Sig, "BLP2", 4))
return IL_FALSE;
// Valid types are JPEG and DXTC. JPEG is not common, though.
// WoW only uses DXTC.
if (Header->Type != BLP_TYPE_JPG && Header->Type != BLP_TYPE_DXTC_RAW)
return IL_FALSE;
// For BLP_TYPE_DXTC_RAW, we can have RAW and DXTC compression.
if (Header->Compression != BLP_RAW && Header->Compression != BLP_DXTC)
return IL_FALSE;
// Alpha bits can only be 0, 1 and 8.
if (Header->AlphaBits != 0 && Header->AlphaBits != 1 && Header->AlphaBits != 8)
return IL_FALSE;
// Alpha type can only be 0, 1, 7 and 8.
if (Header->AlphaType != 0 && Header->AlphaType != 1 && Header->AlphaType != 7 && Header->AlphaType != 8)
return IL_FALSE;
// Width or height of 0 makes no sense.
if (Header->Width == 0 || Header->Height == 0)
return IL_FALSE;
return IL_TRUE;
}
//! Reads a BLP file
ILboolean ilLoadBlp(ILconst_string FileName)
{
ILHANDLE BlpFile;
ILboolean bBlp = IL_FALSE;
BlpFile = iopenr(FileName);
if (BlpFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bBlp;
}
bBlp = ilLoadBlpF(BlpFile);
icloser(BlpFile);
return bBlp;
}
//! Reads an already-opened BLP file
ILboolean ilLoadBlpF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iLoadBlpInternal();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Reads from a memory "lump" that contains a BLP
ILboolean ilLoadBlpL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iLoadBlpInternal();
}
// Internal function used to load the BLP.
ILboolean iLoadBlpInternal(void)
{
BLP2HEAD Header;
ILubyte *CompData;
ILimage *Image;
ILuint Mip, j, x, CompSize, AlphaSize, AlphaOff;
ILint y;
ILboolean BaseCreated = IL_FALSE;
ILubyte *DataAndAlpha = NULL, *Palette = NULL, AlphaMask; //, *JpegHeader, *JpegData;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
if (!iGetBlp2Head(&Header)) {
ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
}
if (!iCheckBlp2(&Header)) {
goto check_blp1;
}
//@TODO: Remove this!
if (Header.Type != BLP_TYPE_DXTC_RAW)
return IL_FALSE;
switch (Header.Compression)
{
case BLP_RAW:
for (Mip = 0; Mip < 16; Mip++) { // Possible maximum of 16 mipmaps
if (BaseCreated) {
if (Header.HasMips == 0) // Does not have mipmaps, so we are done.
break;
if (Image->Width == 1 && Image->Height == 1) // Already at the smallest mipmap (1x1), so we are done.
break;
if (Header.MipOffsets[Mip] == 0 || Header.MipLengths == 0) // No more mipmaps in the file.
break;
}
switch (Header.AlphaBits)
{
case 0:
if (!BaseCreated) { // Have not created the base image yet, so use ilTexImage.
if (!ilTexImage(Header.Width, Header.Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL))
return IL_FALSE;
Image = iCurImage;
BaseCreated = IL_TRUE;
Image->Pal.Palette = (ILubyte*)ialloc(256 * 4); // 256 entries of ARGB8888 values (1024).
if (Image->Pal.Palette == NULL)
return IL_FALSE;
Image->Pal.PalSize = 1024;
Image->Pal.PalType = IL_PAL_BGRA32; //@TODO: Find out if this is really BGRA data.
if (iread(Image->Pal.Palette, 1, 1024) != 1024) // Read in the palette.
return IL_FALSE;
}
else {
Image->Mipmaps = ilNewImageFull(Image->Width >> 1, Image->Height >> 1, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL);
if (Image->Mipmaps == NULL)
return IL_FALSE;
// Copy the palette from the first image before we change our Image pointer.
iCopyPalette(&Image->Mipmaps->Pal, &Image->Pal);
// Move to the next mipmap in the linked list.
Image = Image->Mipmaps;
}
// The origin should be in the upper left.
Image->Origin = IL_ORIGIN_UPPER_LEFT;
// These two should be the same (tells us how much data is in the file for this mipmap level).
if (Header.MipLengths[Mip] != Image->SizeOfData) {
ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
}
// Finally read in the image data.
iseek(Header.MipOffsets[Mip], IL_SEEK_SET);
if (iread(Image->Data, 1, Image->SizeOfData) != Image->SizeOfData)
return IL_FALSE;
break;
case 1:
if (!BaseCreated) { // Have not created the base image yet, so use ilTexImage.
if (!ilTexImage(Header.Width, Header.Height, 1, 4, IL_BGRA, IL_UNSIGNED_BYTE, NULL))
return IL_FALSE;
Image = iCurImage;
BaseCreated = IL_TRUE;
Palette = (ILubyte*)ialloc(256 * 4);
if (Palette == NULL)
return IL_FALSE;
// Read in the palette.
if (iread(Palette, 1, 1024) != 1024) {
ifree(Palette);
return IL_FALSE;
}
// We only allocate this once and reuse this buffer with every mipmap (since successive ones are smaller).
DataAndAlpha = (ILubyte*)ialloc(Image->Width * Image->Height);
if (DataAndAlpha == NULL) {
ifree(DataAndAlpha);
ifree(Palette);
return IL_FALSE;
}
}
else {
Image->Mipmaps = ilNewImageFull(Image->Width >> 1, Image->Height >> 1, 1, 4, IL_BGRA, IL_UNSIGNED_BYTE, NULL);
if (Image->Mipmaps == NULL)
return IL_FALSE;
// Move to the next mipmap in the linked list.
Image = Image->Mipmaps;
}
// The origin should be in the upper left.
Image->Origin = IL_ORIGIN_UPPER_LEFT;
// Determine the size of the alpha data following the color indices.
AlphaSize = Image->Width * Image->Height / 8;
if (AlphaSize == 0)
AlphaSize = 1; // Should never be 0.
// These two should be the same (tells us how much data is in the file for this mipmap level).
if (Header.MipLengths[Mip] != Image->SizeOfData / 4 + AlphaSize) {
ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
}
// Seek to the data and read it.
iseek(Header.MipOffsets[Mip], IL_SEEK_SET);
if (iread(DataAndAlpha, Image->Width * Image->Height, 1) != 1) {
ifree(DataAndAlpha);
ifree(Palette);
return IL_FALSE;
}
// Convert the color-indexed data to BGRX.
for (j = 0; j < Image->Width * Image->Height; j++) {
Image->Data[j*4] = Palette[DataAndAlpha[j]*4];
Image->Data[j*4+1] = Palette[DataAndAlpha[j]*4+1];
Image->Data[j*4+2] = Palette[DataAndAlpha[j]*4+2];
}
// Read in the alpha list.
if (iread(DataAndAlpha, AlphaSize, 1) != 1) {
ifree(DataAndAlpha);
ifree(Palette);
return IL_FALSE;
}
AlphaMask = 0x01; // Lowest bit
AlphaOff = 0;
// The really strange thing about this alpha data is that it is upside-down when compared to the
// regular color-indexed data, so we have to flip it.
for (y = Image->Height - 1; y >= 0; y--) {
for (x = 0; x < Image->Width; x++) {
if (AlphaMask == 0) { // Shifting it past the highest bit makes it 0, since we only have 1 byte.
AlphaOff++; // Move along the alpha buffer.
AlphaMask = 0x01; // Reset the alpha mask.
}
// This is just 1-bit alpha, so it is either on or off.
Image->Data[Image->Bps * y + x * 4 + 3] = DataAndAlpha[AlphaOff] & AlphaMask ? 0xFF : 0x00;
AlphaMask <<= 1;
}
}
break;
default:
//@TODO: Accept any other alpha values?
ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
}
}
// Done, so we can finally free these two.
ifree(DataAndAlpha);
ifree(Palette);
break;
case BLP_DXTC:
for (Mip = 0; Mip < 16; Mip++) { // Possible maximum of 16 mipmaps
//@TODO: Other formats
//if (Header.AlphaBits == 0)
// if (!ilTexImage(Header.Width, Header.Height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL))
// return IL_FALSE;
if (!BaseCreated) { // Have not created the base image yet, so use ilTexImage.
if (!ilTexImage(Header.Width, Header.Height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL))
return IL_FALSE;
Image = iCurImage;
BaseCreated = IL_TRUE;
}
else {
if (Header.HasMips == 0) // Does not have mipmaps, so we are done.
break;
if (Image->Width == 1 && Image->Height == 1) // Already at the smallest mipmap (1x1), so we are done.
break;
if (Header.MipOffsets[Mip] == 0 || Header.MipLengths[Mip] == 0) // No more mipmaps in the file.
break;
//@TODO: Other formats
// ilNewImageFull automatically changes widths and heights of 0 to 1, so we do not have to worry about it.
Image->Mipmaps = ilNewImageFull(Image->Width >> 1, Image->Height >> 1, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL);
if (Image->Mipmaps == NULL)
return IL_FALSE;
Image = Image->Mipmaps;
}
// The origin should be in the upper left.
Image->Origin = IL_ORIGIN_UPPER_LEFT;
//@TODO: Only do the allocation once.
CompData = (ILubyte*)ialloc(Header.MipLengths[Mip]);
if (CompData == NULL)
return IL_FALSE;
// Read in the compressed mipmap data.
iseek(Header.MipOffsets[Mip], IL_SEEK_SET);
if (iread(CompData, 1, Header.MipLengths[Mip]) != Header.MipLengths[Mip]) {
ifree(CompData);
return IL_FALSE;
}
switch (Header.AlphaBits)
{
case 0: // DXT1 without alpha
case 1: // DXT1 with alpha
// Check to make sure that the MipLength reported is the size needed, so that
// DecompressDXT1 does not crash.
CompSize = ((Image->Width + 3) / 4) * ((Image->Height + 3) / 4) * 8;
if (CompSize != Header.MipLengths[Mip]) {
ilSetError(IL_INVALID_FILE_HEADER);
ifree(CompData);
return IL_FALSE;
}
if (!DecompressDXT1(Image, CompData)) {
ifree(CompData);
return IL_FALSE;
}
break;
case 8:
// Check to make sure that the MipLength reported is the size needed, so that
// DecompressDXT3/5 do not crash.
CompSize = ((Image->Width + 3) / 4) * ((Image->Height + 3) / 4) * 16;
if (CompSize != Header.MipLengths[Mip]) {
ifree(CompData);
ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
}
switch (Header.AlphaType)
{
case 0: // All three of
case 1: // these refer to
case 8: // DXT3...
if (!DecompressDXT3(Image, CompData)) {
ifree(CompData);
return IL_FALSE;
}
break;
case 7: // DXT5 compression
if (!DecompressDXT5(Image, CompData)) {
ifree(CompData);
return IL_FALSE;
}
break;
//default: // Should already be checked by iCheckBlp2.
}
break;
//default: // Should already be checked by iCheckBlp2.
}
//@TODO: Save DXTC data.
ifree(CompData);
}
break;
//default:
}
return ilFixImage();
check_blp1:
iseek(-148, IL_SEEK_CUR); // Go back the size of the BLP2 header, since we tried reading it.
return iLoadBlp1();
}
ILboolean iGetBlp1Head(BLP1HEAD *Header)
{
ILuint i;
iread(Header->Sig, 1, 4);
Header->Compression = GetLittleUInt();
Header->Flags = GetLittleUInt();
Header->Width = GetLittleUInt();
Header->Height = GetLittleUInt();
Header->PictureType = GetLittleUInt();
Header->PictureSubType = GetLittleUInt();
for (i = 0; i < 16; i++)
Header->MipOffsets[i] = GetLittleUInt();
for (i = 0; i < 16; i++)
Header->MipLengths[i] = GetLittleUInt();
return IL_TRUE;
}
ILboolean iCheckBlp1(BLP1HEAD *Header)
{
// The file signature is 'BLP1'.
if (strncmp(Header->Sig, "BLP1", 4))
return IL_FALSE;
// Valid types are JPEG and RAW. JPEG is not common, though.
if (Header->Compression != BLP_TYPE_JPG && Header->Compression != BLP_RAW)
return IL_FALSE;
//@TODO: Find out what Flags is for.
// PictureType determines whether this has an alpha list.
if (Header->PictureType != BLP_RAW_PLUS_ALPHA1 && Header->PictureType != BLP_RAW_PLUS_ALPHA2
&& Header->PictureType != BLP_RAW_NO_ALPHA)
return IL_FALSE;
// Width or height of 0 makes no sense.
if (Header->Width == 0 || Header->Height == 0)
return IL_FALSE;
return IL_TRUE;
}
ILboolean iLoadBlp1()
{
BLP1HEAD Header;
ILubyte *DataAndAlpha, *Palette;
ILuint i;
ILimage *Image = iCurImage;
ILboolean BaseCreated = IL_FALSE;
#ifndef IL_NO_JPG
ILubyte *JpegHeader, *JpegData;
ILuint JpegHeaderSize;
#endif//IL_NO_JPG
if (!iGetBlp1Head(&Header))
return IL_FALSE;
if (!iCheckBlp1(&Header)) {
ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
}
//@TODO: Remove this.
i = 0;
switch (Header.Compression)
{
case BLP_TYPE_JPG:
#ifdef IL_NO_JPG
// We can only do the Jpeg decoding if we do not have IL_NO_JPEG defined.
return IL_FALSE;
#else
JpegHeaderSize = GetLittleUInt();
JpegHeader = (ILubyte*)ialloc(JpegHeaderSize);
if (JpegHeader == NULL)
return IL_FALSE;
// Read the shared Jpeg header.
if (iread(JpegHeader, 1, JpegHeaderSize) != JpegHeaderSize) {
ifree(JpegHeader);
return IL_FALSE;
}
//for (i = 0; i < 16; i++) { // Possible maximum of 16 mipmaps
//@TODO: Check return value?
iseek(Header.MipOffsets[i], IL_SEEK_SET);
JpegData = (ILubyte*)ialloc(JpegHeaderSize + Header.MipLengths[i]);
if (JpegData == NULL) {
ifree(JpegHeader);
return IL_FALSE;
}
memcpy(JpegData, JpegHeader, JpegHeaderSize);
if (iread(JpegData + JpegHeaderSize, Header.MipLengths[i], 1) != 1)
return IL_FALSE;
// Just send the data straight to the Jpeg loader.
if (!ilLoadJpegL(JpegData, JpegHeaderSize + Header.MipLengths[i]))
return IL_FALSE;
// The image data is in BGR(A) order, even though it is Jpeg-compressed.
if (Image->Format == IL_RGBA)
Image->Format = IL_BGRA;
if (Image->Format == IL_RGB)
Image->Format = IL_BGR;
ifree(JpegData);
//}
ifree(JpegHeader);
#endif//IL_NO_JPG
break;
case BLP_RAW:
switch (Header.PictureType)
{
// There is no alpha list, so we just read like a normal indexed image.
case BLP_RAW_NO_ALPHA:
for (i = 0; i < 16; i++) { // Possible maximum of 16 mipmaps
if (!BaseCreated) { // Have not created the base image yet, so use ilTexImage.
if (!ilTexImage(Header.Width, Header.Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL))
return IL_FALSE;
Image = iCurImage;
BaseCreated = IL_TRUE;
// We have a BGRA palette.
Image->Pal.Palette = (ILubyte*)ialloc(256 * 4);
if (Image->Pal.Palette == NULL)
return IL_FALSE;
Image->Pal.PalSize = 1024;
Image->Pal.PalType = IL_PAL_BGRA32;
// Read in the palette ...
if (iread(Image->Pal.Palette, 1, 1024) != 1024)
return IL_FALSE;
}
else {
if (Image->Width == 1 && Image->Height == 1) // Already at the smallest mipmap (1x1), so we are done.
break;
if (Header.MipOffsets[i] == 0 || Header.MipLengths[i] == 0) // No more mipmaps in the file.
break;
Image->Mipmaps = ilNewImageFull(Image->Width >> 1, Image->Height >> 1, 1, 1, IL_COLOR_INDEX, IL_UNSIGNED_BYTE, NULL);
if (Image->Mipmaps == NULL)
return IL_FALSE;
// Copy the palette from the first image before we change our Image pointer.
Image->Mipmaps->Pal.Palette = (ILubyte*)ialloc(256 * 4);
if (Image->Mipmaps->Pal.Palette == NULL)
return IL_FALSE;
Image->Mipmaps->Pal.PalSize = 1024;
Image->Mipmaps->Pal.PalType = IL_PAL_BGRA32;
memcpy(Image->Mipmaps->Pal.Palette, Image->Pal.Palette, 1024);
// Move to the next mipmap in the linked list.
Image = Image->Mipmaps;
}
// The origin should be in the upper left.
Image->Origin = IL_ORIGIN_UPPER_LEFT;
// Seek to the data and read it.
iseek(Header.MipOffsets[i], IL_SEEK_SET);
if (iread(Image->Data, 1, Image->SizeOfData) != Image->SizeOfData)
return IL_FALSE;
}
break;
// These cases are identical and have an alpha list following the image data.
case BLP_RAW_PLUS_ALPHA1:
case BLP_RAW_PLUS_ALPHA2:
// Create the image.
if (!ilTexImage(Header.Width, Header.Height, 1, 4, IL_BGRA, IL_UNSIGNED_BYTE, NULL))
return IL_FALSE;
DataAndAlpha = (ILubyte*)ialloc(Header.Width * Header.Height);
Palette = (ILubyte*)ialloc(256 * 4);
if (DataAndAlpha == NULL || Palette == NULL) {
ifree(DataAndAlpha);
ifree(Palette);
return IL_FALSE;
}
// Read in the data and the palette.
if (iread(Palette, 1, 1024) != 1024) {
ifree(Palette);
return IL_FALSE;
}
// Seek to the data and read it.
iseek(Header.MipOffsets[i], IL_SEEK_SET);
if (iread(DataAndAlpha, Header.Width * Header.Height, 1) != 1) {
ifree(DataAndAlpha);
ifree(Palette);
return IL_FALSE;
}
// Convert the color-indexed data to BGRX.
for (i = 0; i < Header.Width * Header.Height; i++) {
Image->Data[i*4] = Palette[DataAndAlpha[i]*4];
Image->Data[i*4+1] = Palette[DataAndAlpha[i]*4+1];
Image->Data[i*4+2] = Palette[DataAndAlpha[i]*4+2];
}
// Read in the alpha list.
if (iread(DataAndAlpha, Header.Width * Header.Height, 1) != 1) {
ifree(DataAndAlpha);
ifree(Palette);
return IL_FALSE;
}
// Finally put the alpha data into the image data.
for (i = 0; i < Header.Width * Header.Height; i++) {
Image->Data[i*4+3] = DataAndAlpha[i];
}
ifree(DataAndAlpha);
ifree(Palette);
break;
}
break;
//default: // Should already be checked by iCheckBlp1.
}
// Set the origin (always upper left).
Image->Origin = IL_ORIGIN_UPPER_LEFT;
return ilFixImage();
}
#endif//IL_NO_BLP
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+148
View File
@@ -0,0 +1,148 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2008 by Denton Woods
// Last modified: 10/10/2006
//
// Filename: src-IL/src/il_cut.c
//
// Description: Reads a Dr. Halo .cut file
//
//-----------------------------------------------------------------------------
#include "il_internal.h"
#ifndef IL_NO_CUT
#include "il_manip.h"
#include "il_pal.h"
#include "il_bits.h"
// Wrap it just in case...
#ifdef _MSC_VER
#pragma pack(push, packed_struct, 1)
#endif
typedef struct CUT_HEAD
{
ILushort Width;
ILushort Height;
ILint Dummy;
} IL_PACKSTRUCT CUT_HEAD;
#ifdef _MSC_VER
#pragma pack(pop, packed_struct)
#endif
ILboolean iLoadCutInternal();
//! Reads a .cut file
ILboolean ilLoadCut(ILconst_string FileName)
{
ILHANDLE CutFile;
ILboolean bCut = IL_FALSE;
CutFile = iopenr(FileName);
if (CutFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bCut;
}
bCut = ilLoadCutF(CutFile);
icloser(CutFile);
return bCut;
}
//! Reads an already-opened .cut file
ILboolean ilLoadCutF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iLoadCutInternal();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Reads from a memory "lump" that contains a .cut
ILboolean ilLoadCutL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iLoadCutInternal();
}
// Note: .Cut support has not been tested yet!
// A .cut can only have 1 bpp.
// We need to add support for the .pal's PSP outputs with these...
ILboolean iLoadCutInternal()
{
CUT_HEAD Header;
ILuint Size, i = 0, j;
ILubyte Count, Run;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
Header.Width = GetLittleShort();
Header.Height = GetLittleShort();
Header.Dummy = GetLittleInt();
if (Header.Width == 0 || Header.Height == 0) {
ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
}
if (!ilTexImage(Header.Width, Header.Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) { // always 1 bpp
return IL_FALSE;
}
iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
Size = Header.Width * Header.Height;
while (i < Size) {
Count = igetc();
if (Count == 0) { // end of row
igetc(); // Not supposed to be here, but
igetc(); // PSP is putting these two bytes here...WHY?!
continue;
}
if (Count & BIT_7) { // rle-compressed
ClearBits(Count, BIT_7);
Run = igetc();
for (j = 0; j < Count; j++) {
iCurImage->Data[i++] = Run;
}
}
else { // run of pixels
for (j = 0; j < Count; j++) {
iCurImage->Data[i++] = igetc();
}
}
}
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; // Not sure
/*iCurImage->Pal.Palette = SharedPal.Palette;
iCurImage->Pal.PalSize = SharedPal.PalSize;
iCurImage->Pal.PalType = SharedPal.PalType;*/
return ilFixImage();
}
/* ?????????
void ilPopToast() {
ILstring flipCode = IL_TEXT("#flipCode and www.flipCode.com rule you all.");
flipCode[0] = flipCode[0];
}
*/
#endif//IL_NO_CUT
+486
View File
@@ -0,0 +1,486 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 03/07/2009
//
// Filename: src-IL/src/il_dcx.c
//
// Description: Reads from a .dcx file.
//
//-----------------------------------------------------------------------------
#include "il_internal.h"
#ifndef IL_NO_DCX
#include "il_dcx.h"
#include "il_manip.h"
//! Checks if the file specified in FileName is a valid .dcx file.
ILboolean ilIsValidDcx(ILconst_string FileName)
{
ILHANDLE DcxFile;
ILboolean bDcx = IL_FALSE;
if (!iCheckExtension(FileName, IL_TEXT("dcx"))) {
ilSetError(IL_INVALID_EXTENSION);
return bDcx;
}
DcxFile = iopenr(FileName);
if (DcxFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bDcx;
}
bDcx = ilIsValidDcxF(DcxFile);
icloser(DcxFile);
return bDcx;
}
//! Checks if the ILHANDLE contains a valid .dcx file at the current position.
ILboolean ilIsValidDcxF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iIsValidDcx();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Checks if Lump is a valid .dcx lump.
ILboolean ilIsValidDcxL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iIsValidDcx();
}
// Internal function obtain the .dcx header from the current file.
ILboolean iGetDcxHead(DCXHEAD *Head)
{
Head->Xmin = GetLittleUShort();
Head->Ymin = GetLittleUShort();
Head->Xmax = GetLittleUShort();
Head->Ymax = GetLittleUShort();
Head->HDpi = GetLittleUShort();
Head->VDpi = GetLittleUShort();
Head->Bps = GetLittleUShort();
Head->PaletteInfo = GetLittleUShort();
Head->HScreenSize = GetLittleUShort();
Head->VScreenSize = GetLittleUShort();
return IL_TRUE;
}
// Internal function to get the header and check it.
ILboolean iIsValidDcx()
{
ILuint Signature;
if (iread(&Signature, 1, 4) != 4)
return IL_FALSE;
iseek(-4, IL_SEEK_CUR);
return (Signature == 987654321);
}
// Internal function used to check if the HEADER is a valid .dcx header.
// Should we also do a check on Header->Bpp?
ILboolean iCheckDcx(DCXHEAD *Header)
{
ILuint Test, i;
// There are other versions, but I am not supporting them as of yet.
// Got rid of the Reserved check, because I've seen some .dcx files with invalid values in it.
if (Header->Manufacturer != 10 || Header->Version != 5 || Header->Encoding != 1/* || Header->Reserved != 0*/)
return IL_FALSE;
// See if the padding size is correct
Test = Header->Xmax - Header->Xmin + 1;
/*if (Header->Bpp >= 8) {
if (Test & 1) {
if (Header->Bps != Test + 1)
return IL_FALSE;
}
else {
if (Header->Bps != Test) // No padding
return IL_FALSE;
}
}*/
for (i = 0; i < 54; i++) {
if (Header->Filler[i] != 0)
return IL_FALSE;
}
return IL_TRUE;
}
//! Reads a .dcx file
ILboolean ilLoadDcx(ILconst_string FileName)
{
ILHANDLE DcxFile;
ILboolean bDcx = IL_FALSE;
DcxFile = iopenr(FileName);
if (DcxFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bDcx;
}
bDcx = ilLoadDcxF(DcxFile);
icloser(DcxFile);
return bDcx;
}
//! Reads an already-opened .dcx file
ILboolean ilLoadDcxF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iLoadDcxInternal();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Reads from a memory "lump" that contains a .dcx
ILboolean ilLoadDcxL(const void *Lump, ILuint Size) {
iSetInputLump(Lump, Size);
return iLoadDcxInternal();
}
// Internal function used to load the .dcx.
ILboolean iLoadDcxInternal()
{
DCXHEAD Header;
ILuint Signature, i, Entries[1024], Num = 0;
ILimage *Image, *Base;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
if (!iIsValidDcx())
return IL_FALSE;
iread(&Signature, 1, 4);
do {
if (iread(&Entries[Num], 1, 4) != 4)
return IL_FALSE;
Num++;
} while (Entries[Num-1] != 0);
for (i = 0; i < Num; i++) {
iseek(Entries[i], IL_SEEK_SET);
iGetDcxHead(&Header);
/*if (!iCheckDcx(&Header)) {
ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
}*/
Image = iUncompressDcx(&Header);
if (Image == NULL)
return IL_FALSE;
if (i == 0) {
ilTexImage(Image->Width, Image->Height, 1, Image->Bpp, Image->Format, Image->Type, Image->Data);
Base = iCurImage;
Base->Origin = IL_ORIGIN_UPPER_LEFT;
ilCloseImage(Image);
}
else {
iCurImage->Next = Image;
iCurImage = iCurImage->Next;
}
}
return ilFixImage();
}
// Internal function to uncompress the .dcx (all .dcx files are rle compressed)
ILimage *iUncompressDcx(DCXHEAD *Header)
{
ILubyte ByteHead, Colour, *ScanLine = NULL /* Only one plane */;
ILuint c, i, x, y;//, Read = 0;
ILimage *Image = NULL;
if (Header->Bpp < 8) {
/*ilSetError(IL_FORMAT_NOT_SUPPORTED);
return IL_FALSE;*/
return iUncompressDcxSmall(Header);
}
Image = ilNewImage(Header->Xmax - Header->Xmin + 1, Header->Ymax - Header->Ymin + 1, 1, Header->NumPlanes, 1);
if (Image == NULL)
return NULL;
/*if (!ilTexImage(Header->Xmax - Header->Xmin + 1, Header->Ymax - Header->Ymin + 1, 1, Header->NumPlanes, 0, IL_UNSIGNED_BYTE, NULL)) {
return IL_FALSE;
}*/
Image->Origin = IL_ORIGIN_UPPER_LEFT;
ScanLine = (ILubyte*)ialloc(Header->Bps);
if (ScanLine == NULL)
goto dcx_error;
switch (Image->Bpp)
{
case 1:
Image->Format = IL_COLOUR_INDEX;
Image->Pal.PalType = IL_PAL_RGB24;
Image->Pal.PalSize = 256 * 3; // Need to find out for sure...
Image->Pal.Palette = (ILubyte*)ialloc(Image->Pal.PalSize);
if (Image->Pal.Palette == NULL)
goto dcx_error;
break;
//case 2: // No 16-bit images in the dcx format!
case 3:
Image->Format = IL_RGB;
Image->Pal.Palette = NULL;
Image->Pal.PalSize = 0;
Image->Pal.PalType = IL_PAL_NONE;
break;
case 4:
Image->Format = IL_RGBA;
Image->Pal.Palette = NULL;
Image->Pal.PalSize = 0;
Image->Pal.PalType = IL_PAL_NONE;
break;
default:
ilSetError(IL_ILLEGAL_FILE_VALUE);
goto dcx_error;
}
/*StartPos = itell();
Compressed = (ILubyte*)ialloc(Image->SizeOfData * 4 / 3);
iread(Compressed, 1, Image->SizeOfData * 4 / 3);
for (y = 0; y < Image->Height; y++) {
for (c = 0; c < Image->Bpp; c++) {
x = 0;
while (x < Header->Bps) {
ByteHead = Compressed[Read++];
if ((ByteHead & 0xC0) == 0xC0) {
ByteHead &= 0x3F;
Colour = Compressed[Read++];
for (i = 0; i < ByteHead; i++) {
ScanLine[x++] = Colour;
}
}
else {
ScanLine[x++] = ByteHead;
}
}
for (x = 0; x < Image->Width; x++) { // 'Cleverly' ignores the pad bytes ;)
Image->Data[y * Image->Bps + x * Image->Bpp + c] = ScanLine[x];
}
}
}
ifree(Compressed);
iseek(StartPos + Read, IL_SEEK_SET);*/
//changed 2003-09-01
if (iGetHint(IL_MEM_SPEED_HINT) == IL_FASTEST)
iPreCache(iCurImage->SizeOfData);
//TODO: because the .pcx-code was broken this
//code is probably broken, too
for (y = 0; y < Image->Height; y++) {
for (c = 0; c < Image->Bpp; c++) {
x = 0;
while (x < Header->Bps) {
if (iread(&ByteHead, 1, 1) != 1) {
iUnCache();
goto dcx_error;
}
if ((ByteHead & 0xC0) == 0xC0) {
ByteHead &= 0x3F;
if (iread(&Colour, 1, 1) != 1) {
iUnCache();
goto dcx_error;
}
for (i = 0; i < ByteHead; i++) {
ScanLine[x++] = Colour;
}
}
else {
ScanLine[x++] = ByteHead;
}
}
for (x = 0; x < Image->Width; x++) { // 'Cleverly' ignores the pad bytes ;)
Image->Data[y * Image->Bps + x * Image->Bpp + c] = ScanLine[x];
}
}
}
iUnCache();
ifree(ScanLine);
// Read in the palette
if (Image->Bpp == 1) {
ByteHead = igetc(); // the value 12, because it signals there's a palette for some reason...
// We should do a check to make certain it's 12...
if (ByteHead != 12)
iseek(-1, IL_SEEK_CUR);
if (iread(Image->Pal.Palette, 1, Image->Pal.PalSize) != Image->Pal.PalSize) {
ilCloseImage(Image);
return NULL;
}
}
return Image;
dcx_error:
ifree(ScanLine);
ilCloseImage(Image);
return NULL;
}
ILimage *iUncompressDcxSmall(DCXHEAD *Header)
{
ILuint i = 0, j, k, c, d, x, y, Bps;
ILubyte HeadByte, Colour, Data = 0, *ScanLine = NULL;
ILimage *Image;
Image = ilNewImage(Header->Xmax - Header->Xmin + 1, Header->Ymax - Header->Ymin + 1, 1, Header->NumPlanes, 1);
if (Image == NULL)
return NULL;
/*if (!ilTexImage(Header->Xmax - Header->Xmin + 1, Header->Ymax - Header->Ymin + 1, 1, 1, 0, IL_UNSIGNED_BYTE, NULL)) {
return IL_FALSE;
}*/
Image->Origin = IL_ORIGIN_UPPER_LEFT;
switch (Header->NumPlanes)
{
case 1:
Image->Format = IL_LUMINANCE;
break;
case 4:
Image->Format = IL_COLOUR_INDEX;
break;
default:
ilSetError(IL_ILLEGAL_FILE_VALUE);
ilCloseImage(Image);
return NULL;
}
if (Header->NumPlanes == 1) {
for (j = 0; j < Image->Height; j++) {
i = 0;
while (i < Image->Width) {
if (iread(&HeadByte, 1, 1) != 1)
goto file_read_error;
if (HeadByte >= 192) {
HeadByte -= 192;
if (iread(&Data, 1, 1) != 1)
goto file_read_error;
for (c = 0; c < HeadByte; c++) {
k = 128;
for (d = 0; d < 8 && i < Image->Width; d++) {
Image->Data[j * Image->Width + i++] = (!!(Data & k) == 1 ? 255 : 0);
k >>= 1;
}
}
}
else {
k = 128;
for (c = 0; c < 8 && i < Image->Width; c++) {
Image->Data[j * Image->Width + i++] = (!!(HeadByte & k) == 1 ? 255 : 0);
k >>= 1;
}
}
}
if (Data != 0)
igetc(); // Skip pad byte if last byte not a 0
}
}
else { // 4-bit images
Bps = Header->Bps * Header->NumPlanes * 2;
Image->Pal.Palette = (ILubyte*)ialloc(16 * 3); // Size of palette always (48 bytes).
Image->Pal.PalSize = 16 * 3;
Image->Pal.PalType = IL_PAL_RGB24;
ScanLine = (ILubyte*)ialloc(Bps);
if (Image->Pal.Palette == NULL || ScanLine == NULL) {
ifree(ScanLine);
ilCloseImage(Image);
return NULL;
}
memcpy(Image->Pal.Palette, Header->ColMap, 16 * 3);
imemclear(Image->Data, Image->SizeOfData); // Since we do a += later.
for (y = 0; y < Image->Height; y++) {
for (c = 0; c < Header->NumPlanes; c++) {
x = 0;
while (x < Bps) {
if (iread(&HeadByte, 1, 1) != 1)
goto file_read_error;
if ((HeadByte & 0xC0) == 0xC0) {
HeadByte &= 0x3F;
if (iread(&Colour, 1, 1) != 1)
goto file_read_error;
for (i = 0; i < HeadByte; i++) {
k = 128;
for (j = 0; j < 8; j++) {
ScanLine[x++] = !!(Colour & k);
k >>= 1;
}
}
}
else {
k = 128;
for (j = 0; j < 8; j++) {
ScanLine[x++] = !!(HeadByte & k);
k >>= 1;
}
}
}
for (x = 0; x < Image->Width; x++) { // 'Cleverly' ignores the pad bytes. ;)
Image->Data[y * Image->Width + x] += ScanLine[x] << c;
}
}
}
ifree(ScanLine);
}
return Image;
file_read_error:
ifree(ScanLine);
ilCloseImage(Image);
return NULL;
}
#endif//IL_NO_DCX
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+606
View File
@@ -0,0 +1,606 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 02/14/2009
//
// Filename: src-IL/src/il_dicom.c
//
// Description: Reads from a Digital Imaging and Communications in Medicine
// (DICOM) file. Specifications can be found at
// http://en.wikipedia.org/wiki/Dicom.
//
//-----------------------------------------------------------------------------
#include "il_internal.h"
#ifndef IL_NO_DICOM
typedef struct DICOMHEAD
{
ILubyte Signature[4];
ILuint Version;
ILuint Width;
ILuint Height;
ILuint Depth;
ILuint Samples;
ILuint BitsAllocated;
ILuint BitsStored;
ILuint DataLen;
ILboolean BigEndian;
ILenum Encoding;
// For DevIL use only
ILenum Format;
ILenum Type;
} DICOMHEAD;
ILboolean iIsValidDicom(void);
ILboolean iCheckDicom(DICOMHEAD *Header);
ILboolean iLoadDicomInternal(void);
ILboolean iGetDicomHead(DICOMHEAD *Header);
ILboolean SkipElement(DICOMHEAD *Header, ILushort GroupNum, ILushort ElementNum);
ILboolean GetNumericValue(DICOMHEAD *Header, ILushort GroupNum, ILuint *Number);
ILboolean GetUID(ILubyte *UID);
ILuint GetGroupNum(DICOMHEAD *Header);
ILuint GetShort(DICOMHEAD *Header, ILushort GroupNum);
ILuint GetInt(DICOMHEAD *Header, ILushort GroupNum);
ILfloat GetFloat(DICOMHEAD *Header, ILushort GroupNum);
//! Checks if the file specified in FileName is a valid DICOM file.
ILboolean ilIsValidDicom(ILconst_string FileName)
{
ILHANDLE DicomFile;
ILboolean bDicom = IL_FALSE;
if (!iCheckExtension(FileName, IL_TEXT("dicom")) && !iCheckExtension(FileName, IL_TEXT("dcm"))) {
ilSetError(IL_INVALID_EXTENSION);
return bDicom;
}
DicomFile = iopenr(FileName);
if (DicomFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bDicom;
}
bDicom = ilIsValidDicomF(DicomFile);
icloser(DicomFile);
return bDicom;
}
//! Checks if the ILHANDLE contains a valid DICOM file at the current position.
ILboolean ilIsValidDicomF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iIsValidDicom();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Checks if Lump is a valid DICOM lump.
ILboolean ilIsValidDicomL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iIsValidDicom();
}
// Internal function to get the header and check it.
ILboolean iIsValidDicom(void)
{
DICOMHEAD Header;
ILuint Pos = itell();
// Clear the header to all 0s to make checks later easier.
memset(&Header, 0, sizeof(DICOMHEAD));
if (!iGetDicomHead(&Header))
return IL_FALSE;
// The length of the header varies, so we just go back to the original position.
iseek(Pos, IL_SEEK_CUR);
return iCheckDicom(&Header);
}
// Internal function used to get the DICOM header from the current file.
ILboolean iGetDicomHead(DICOMHEAD *Header)
{
ILushort GroupNum, ElementNum;
ILboolean ReachedData = IL_FALSE;
ILubyte Var2, UID[65];
// Signature should be "DICM" at position 128.
iseek(128, IL_SEEK_SET);
if (iread(Header->Signature, 1, 4) != 4)
return IL_FALSE;
//@TODO: What about the case when we are reading an image with Big Endian data?
do {
GroupNum = GetGroupNum(Header);
ElementNum = GetShort(Header, GroupNum);;
switch (GroupNum)
{
case 0x02:
switch (ElementNum)
{
/*case 0x01: // Version number
if (!GetNumericValue(&Header->Version))
return IL_FALSE;
if (Header->Version != 0x0100)
return IL_FALSE;
break;*/
case 0x10:
//@TODO: Look at pg. 60 of 07_05pu.pdf (PS 3.5) for more UIDs.
if (!GetUID(UID))
return IL_FALSE;
if (!strncmp(UID, "1.2.840.10008.1.2.2", 64)) // Explicit big endian
Header->BigEndian = IL_TRUE;
else if (!strncmp(UID, "1.2.840.10008.1.2.1", 64)) // Explicit little endian
Header->BigEndian = IL_FALSE;
else if (!strncmp(UID, "1.2.840.10008.1.2", 64)) // Implicit little endian
Header->BigEndian = IL_FALSE;
else
return IL_FALSE; // Unrecognized UID.
break;
default:
if (!SkipElement(Header, GroupNum, ElementNum)) // We do not understand this entry, so we just skip it.
return IL_FALSE;
}
break;
case 0x28:
switch (ElementNum)
{
case 0x02: // Samples per pixel
if (!GetNumericValue(Header, GroupNum, &Header->Samples))
return IL_FALSE;
break;
case 0x08: // Number of frames, or depth
if (!GetNumericValue(Header, GroupNum, &Header->Depth))
return IL_FALSE;
break;
case 0x10: // The number of rows
if (!GetNumericValue(Header, GroupNum, &Header->Height))
return IL_FALSE;
break;
case 0x11: // The number of columns
if (!GetNumericValue(Header, GroupNum, &Header->Width))
return IL_FALSE;
break;
case 0x100: // Bits allocated per sample
if (!GetNumericValue(Header, GroupNum, &Header->BitsAllocated))
return IL_FALSE;
break;
case 0x101: // Bits stored per sample - Do we really need this information?
if (!GetNumericValue(Header, GroupNum, &Header->BitsStored))
return IL_FALSE;
break;
default:
if (!SkipElement(Header, GroupNum, ElementNum)) // We do not understand this entry, so we just skip it.
return IL_FALSE;
}
break;
case 0x7FE0:
switch (ElementNum)
{
case 0x10: // This element is the actual pixel data. We are done with the header here.
if (igetc() != 'O') // @TODO: Can we assume that this is always 'O'?
return IL_FALSE;
Var2 = igetc();
if (Var2 != 'B' && Var2 != 'W' && Var2 != 'F') // 'OB', 'OW' and 'OF' accepted for this element.
return IL_FALSE;
GetLittleUShort(); // Skip the 2 reserved bytes.
Header->DataLen = GetInt(Header, GroupNum);//GetLittleUInt();
ReachedData = IL_TRUE;
break;
default:
if (!SkipElement(Header, GroupNum, ElementNum)) // We do not understand this entry, so we just skip it.
return IL_FALSE;
}
break;
default:
if (!SkipElement(Header, GroupNum, ElementNum)) // We do not understand this entry, so we just skip it.
return IL_FALSE;
}
} while (!ieof() && !ReachedData);
if (ieof())
return IL_FALSE;
// Some DICOM images do not have the depth (number of frames) field.
if (Header->Depth == 0)
Header->Depth = 1;
switch (Header->BitsAllocated)
{
case 8:
Header->Type = IL_UNSIGNED_BYTE;
break;
case 16:
Header->Type = IL_UNSIGNED_SHORT;
break;
case 32:
Header->Type = IL_FLOAT; //@TODO: Is this ever an integer?
break;
default: //@TODO: Any other types we can deal with?
return IL_FALSE;
}
// Cannot handle more than 4 channels in an image.
if (Header->Samples > 4)
return IL_FALSE;
Header->Format = ilGetFormatBpp(Header->Samples);
return IL_TRUE;
}
ILboolean SkipElement(DICOMHEAD *Header, ILushort GroupNum, ILushort ElementNum)
{
ILubyte VR1, VR2;
ILuint ValLen;
// 2 byte character string telling what type this element is ('OB', 'UI', etc.)
VR1 = igetc();
VR2 = igetc();
if ((VR1 == 'O' && VR2 == 'B') || (VR1 == 'O' && VR2 == 'W') || (VR1 == 'O' && VR2 == 'F') ||
(VR1 == 'S' && VR2 == 'Q') || (VR1 == 'U' && VR2 == 'T') || (VR1 == 'U' && VR2 == 'N')) {
// These all have a different format than the other formats, since they can be up to 32 bits long.
GetLittleUShort(); // Values reserved, we do not care about them.
ValLen = GetInt(Header, GroupNum);//GetLittleUInt(); // Length of the rest of the element
if (ValLen % 2) // This length must be even, according to the specs.
return IL_FALSE;
if (ElementNum != 0x00) // Element numbers of 0 tell the size of the full group, so we do not skip this.
// @TODO: We could use this to skip groups that we do not care about.
if (iseek(ValLen, IL_SEEK_CUR))
return IL_FALSE;
}
else {
// These have a length of 16 bits.
ValLen = GetShort(Header, GroupNum);//GetLittleUShort();
//if (ValLen % 2) // This length must be even, according to the specs.
// ValLen++; // Add the extra byte to seek.
//if (ElementNum != 0x00) // Element numbers of 0 tell the size of the full group, so we do not skip this.
// @TODO: We could use this to skip groups that we do not care about.
if (iseek(ValLen, IL_SEEK_CUR))
return IL_FALSE;
}
return IL_TRUE;
}
ILuint GetGroupNum(DICOMHEAD *Header)
{
ILushort GroupNum;
iread(&GroupNum, 1, 2);
// The 0x02 group is always little endian.
if (GroupNum == 0x02) {
UShort(&GroupNum);
return GroupNum;
}
// Now we have to swizzle it if it is not 0x02.
if (Header->BigEndian)
BigUShort(&GroupNum);
else
UShort(&GroupNum);
return GroupNum;
}
ILuint GetShort(DICOMHEAD *Header, ILushort GroupNum)
{
ILushort Num;
iread(&Num, 1, 2);
// The 0x02 group is always little endian.
if (GroupNum == 0x02) {
UShort(&Num);
return Num;
}
// Now we have to swizzle it if it is not 0x02.
if (Header->BigEndian)
BigUShort(&Num);
else
UShort(&Num);
return Num;
}
ILuint GetInt(DICOMHEAD *Header, ILushort GroupNum)
{
ILuint Num;
iread(&Num, 1, 4);
// The 0x02 group is always little endian.
if (GroupNum == 0x02) {
UInt(&Num);
return Num;
}
// Now we have to swizzle it if it is not 0x02.
if (Header->BigEndian)
BigUInt(&Num);
else
UInt(&Num);
return Num;
}
ILfloat GetFloat(DICOMHEAD *Header, ILushort GroupNum)
{
ILfloat Num;
iread(&Num, 1, 4);
// The 0x02 group is always little endian.
if (GroupNum == 0x02) {
Float(&Num);
return Num;
}
// Now we have to swizzle it if it is not 0x02.
if (Header->BigEndian)
BigFloat(&Num);
else
Float(&Num);
return Num;
}
ILboolean GetNumericValue(DICOMHEAD *Header, ILushort GroupNum, ILuint *Number)
{
ILubyte VR1, VR2;
ILushort ValLen;
// 2 byte character string telling what type this element is ('OB', 'UI', etc.)
VR1 = igetc();
VR2 = igetc();
if (VR1 == 'U' && VR2 == 'S') { // Unsigned short
ValLen = GetShort(Header, GroupNum);//GetLittleUShort();
if (ValLen != 2) // Must always be 2 for short ('US')
return IL_FALSE;
*((ILushort*)Number) = GetShort(Header, GroupNum);//GetLittleUShort();
return IL_TRUE;
}
if (VR1 == 'U' && VR2 == 'L') { // Unsigned long
ValLen = GetInt(Header, GroupNum);//GetLittleUInt();
if (ValLen != 4) // Must always be 4 for long ('UL')
return IL_FALSE;
*Number = GetInt(Header, GroupNum);
return IL_TRUE;
}
if (VR1 == 'S' && VR2 == 'S') { // Signed short
ValLen = GetShort(Header, GroupNum);
if (ValLen != 2) // Must always be 2 for short ('US')
return IL_FALSE;
*((ILshort*)Number) = GetShort(Header, GroupNum);
return IL_TRUE;
}
if (VR1 == 'S' && VR2 == 'L') { // Signed long
ValLen = GetInt(Header, GroupNum);
if (ValLen != 4) // Must always be 4 for long ('UL')
return IL_FALSE;
*((ILint*)Number) = GetInt(Header, GroupNum);
return IL_TRUE;
}
return IL_FALSE;
}
ILboolean GetUID(ILubyte *UID)
{
ILubyte VR1, VR2;
ILushort ValLen;
// 2 byte character string telling what type this element is ('OB', 'UI', etc.)
VR1 = igetc();
VR2 = igetc();
if (VR1 != 'U' || VR2 != 'I') // 'UI' == UID
return IL_FALSE;
ValLen = GetLittleUShort();
if (iread(UID, ValLen, 1) != 1)
return IL_FALSE;
UID[64] = 0; // Just to make sure that our string is terminated.
return IL_TRUE;
}
// Internal function used to check if the HEADER is a valid DICOM header.
ILboolean iCheckDicom(DICOMHEAD *Header)
{
// Always has the signature "DICM" at position 0x80.
if (strncmp(Header->Signature, "DICM", 4))
return IL_FALSE;
// Does not make sense to have any dimension = 0.
if (Header->Width == 0 || Header->Height == 0 || Header->Depth == 0)
return IL_FALSE;
// We can only deal with images that have byte-aligned data.
//@TODO: Take care of any others?
if (Header->BitsAllocated % 8)
return IL_FALSE;
// Check for an invalid format being set (or not set at all).
if (ilGetBppFormat(Header->Format) == 0)
return IL_FALSE;
// Check for an invalid type being set (or not set at all).
if (ilGetBpcType(Header->Type) == 0)
return IL_FALSE;
return IL_TRUE;
}
//! Reads a DICOM file
ILboolean ilLoadDicom(ILconst_string FileName)
{
ILHANDLE DicomFile;
ILboolean bDicom = IL_FALSE;
DicomFile = iopenr(FileName);
if (DicomFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bDicom;
}
bDicom = ilLoadDicomF(DicomFile);
icloser(DicomFile);
return bDicom;
}
//! Reads an already-opened DICOM file
ILboolean ilLoadDicomF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iLoadDicomInternal();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Reads from a memory "lump" that contains a DICOM
ILboolean ilLoadDicomL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iLoadDicomInternal();
}
// Internal function used to load the DICOM.
ILboolean iLoadDicomInternal(void)
{
DICOMHEAD Header;
ILuint i;
ILushort TempS, *ShortPtr;
ILfloat TempF, *FloatPtr;
ILboolean Swizzle = IL_FALSE;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
// Clear the header to all 0s to make checks later easier.
memset(&Header, 0, sizeof(DICOMHEAD));
if (!iGetDicomHead(&Header)) {
ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
}
if (!iCheckDicom(&Header))
return IL_FALSE;
if (!ilTexImage(Header.Width, Header.Height, Header.Depth, ilGetBppFormat(Header.Format), Header.Format, Header.Type, NULL))
return IL_FALSE;
//@TODO: Find out if the origin is always in the upper left.
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
// Header.DataLen may be larger than SizeOfData, since it has to be padded with a NULL if it is not an even length,
// so we just test to make sure it is at least large enough.
//@TODO: Do this check before ilTexImage call.
if (Header.DataLen < iCurImage->SizeOfData) {
ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
}
// We may have to swap the order of the data.
#ifdef __BIG_ENDIAN__
if (!Header.BigEndian) {
if (Header.Format == IL_RGB)
Header.Format = IL_BGR;
else if (Header.Format == IL_RGBA)
Swizzle = IL_TRUE;
}
#else // Little endian
if (Header.BigEndian) {
if (Header.Format == IL_RGB)
Header.Format = IL_BGR;
if (Header.Format == IL_RGBA)
Swizzle = IL_TRUE;
}
#endif
switch (Header.Type)
{
case IL_UNSIGNED_BYTE:
if (iread(iCurImage->Data, iCurImage->SizeOfData, 1) != 1)
return IL_FALSE;
// Swizzle the data from ABGR to RGBA.
if (Swizzle) {
for (i = 0; i < iCurImage->SizeOfData; i += 4) {
iSwapUInt((ILuint*)(iCurImage->Data + i));
}
}
break;
case IL_UNSIGNED_SHORT:
for (i = 0; i < iCurImage->SizeOfData; i += 2) {
*((ILushort*)(iCurImage->Data + i)) = GetShort(&Header, 0);//GetLittleUShort();
}
// Swizzle the data from ABGR to RGBA.
if (Swizzle) {
ShortPtr = (ILushort*)iCurImage->Data;
for (i = 0; i < iCurImage->SizeOfData / 2; i += 4) {
TempS = ShortPtr[i];
ShortPtr[i] = ShortPtr[i+3];
ShortPtr[i+3] = TempS;
}
}
break;
case IL_FLOAT:
for (i = 0; i < iCurImage->SizeOfData; i += 4) {
*((ILfloat*)(iCurImage->Data + i)) = GetFloat(&Header, 0);//GetLittleFloat();
}
// Swizzle the data from ABGR to RGBA.
if (Swizzle) {
FloatPtr = (ILfloat*)iCurImage->Data;
for (i = 0; i < iCurImage->SizeOfData / 4; i += 4) {
TempF = FloatPtr[i];
FloatPtr[i] = FloatPtr[i+3];
FloatPtr[i+3] = TempF;
}
}
break;
}
return ilFixImage();
}
#endif//IL_NO_DICOM
+272
View File
@@ -0,0 +1,272 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 03/07/2009
//
// Filename: src-IL/src/il_doom.c
//
// Description: Reads Doom textures and flats
//
//-----------------------------------------------------------------------------
#include "il_internal.h"
#ifndef IL_NO_DOOM
#include "il_manip.h"
#include "il_pal.h"
#include "il_doompal.h"
ILboolean iLoadDoomInternal(void);
ILboolean iLoadDoomFlatInternal(void);
//
// READ A DOOM IMAGE
//
//! Reads a Doom file
ILboolean ilLoadDoom(ILconst_string FileName)
{
ILHANDLE DoomFile;
ILboolean bDoom = IL_FALSE;
// Not sure of any kind of specified extension...maybe .lmp?
/*if (!iCheckExtension(FileName, "")) {
ilSetError(IL_INVALID_EXTENSION);
return NULL;
}*/
DoomFile = iopenr(FileName);
if (DoomFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bDoom;
}
bDoom = ilLoadDoomF(DoomFile);
icloser(DoomFile);
return bDoom;
}
//! Reads an already-opened Doom file
ILboolean ilLoadDoomF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iLoadDoomInternal();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Reads from a memory "lump" that contains a Doom texture
ILboolean ilLoadDoomL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iLoadDoomInternal();
}
// From the DTE sources (mostly by Denton Woods with corrections by Randy Heit)
ILboolean iLoadDoomInternal()
{
ILshort width, height, graphic_header[2], column_loop, row_loop;
ILint column_offset, pointer_position, first_pos;
ILubyte post, topdelta, length;
ILubyte *NewData;
ILuint i;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
first_pos = itell(); // Needed to go back to the offset table
width = GetLittleShort();
height = GetLittleShort();
graphic_header[0] = GetLittleShort(); // Not even used
graphic_header[1] = GetLittleShort(); // Not even used
if (!ilTexImage(width, height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) {
return IL_FALSE;
}
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
iCurImage->Pal.Palette = (ILubyte*)ialloc(IL_DOOMPAL_SIZE);
if (iCurImage->Pal.Palette == NULL) {
return IL_FALSE;
}
iCurImage->Pal.PalSize = IL_DOOMPAL_SIZE;
iCurImage->Pal.PalType = IL_PAL_RGB24;
memcpy(iCurImage->Pal.Palette, ilDefaultDoomPal, IL_DOOMPAL_SIZE);
// 247 is always the transparent colour (usually cyan)
memset(iCurImage->Data, 247, iCurImage->SizeOfData);
for (column_loop = 0; column_loop < width; column_loop++) {
column_offset = GetLittleInt();
pointer_position = itell();
iseek(first_pos + column_offset, IL_SEEK_SET);
while (1) {
if (iread(&topdelta, 1, 1) != 1)
return IL_FALSE;
if (topdelta == 255)
break;
if (iread(&length, 1, 1) != 1)
return IL_FALSE;
if (iread(&post, 1, 1) != 1)
return IL_FALSE; // Skip extra byte for scaling
for (row_loop = 0; row_loop < length; row_loop++) {
if (iread(&post, 1, 1) != 1)
return IL_FALSE;
if (row_loop + topdelta < height)
iCurImage->Data[(row_loop+topdelta) * width + column_loop] = post;
}
iread(&post, 1, 1); // Skip extra scaling byte
}
iseek(pointer_position, IL_SEEK_SET);
}
// Converts palette entry 247 (cyan) to transparent.
if (ilGetBoolean(IL_CONV_PAL) == IL_TRUE) {
NewData = (ILubyte*)ialloc(iCurImage->SizeOfData * 4);
if (NewData == NULL) {
return IL_FALSE;
}
for (i = 0; i < iCurImage->SizeOfData; i++) {
NewData[i * 4] = iCurImage->Pal.Palette[iCurImage->Data[i]];
NewData[i * 4] = iCurImage->Pal.Palette[iCurImage->Data[i]];
NewData[i * 4] = iCurImage->Pal.Palette[iCurImage->Data[i]];
NewData[i * 4 + 3] = iCurImage->Data[i] != 247 ? 255 : 0;
}
if (!ilTexImage(iCurImage->Width, iCurImage->Height, iCurImage->Depth,
4, IL_RGBA, iCurImage->Type, NewData)) {
ifree(NewData);
return IL_FALSE;
}
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
ifree(NewData);
}
return ilFixImage();
}
//
// READ A DOOM FLAT
//
//! Reads a Doom flat file
ILboolean ilLoadDoomFlat(ILconst_string FileName)
{
ILHANDLE FlatFile;
ILboolean bFlat = IL_FALSE;
// Not sure of any kind of specified extension...maybe .lmp?
/*if (!iCheckExtension(FileName, "")) {
ilSetError(IL_INVALID_EXTENSION);
return NULL;
}*/
FlatFile = iopenr(FileName);
if (FlatFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bFlat;
}
bFlat = ilLoadDoomF(FlatFile);
icloser(FlatFile);
return bFlat;
}
//! Reads an already-opened Doom flat file
ILboolean ilLoadDoomFlatF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iLoadDoomFlatInternal();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Reads from a memory "lump" that contains a Doom flat
ILboolean ilLoadDoomFlatL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iLoadDoomFlatInternal();
}
// Basically just ireads 4096 bytes and copies the palette
ILboolean iLoadDoomFlatInternal()
{
ILubyte *NewData;
ILuint i;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
if (!ilTexImage(64, 64, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) {
return IL_FALSE;
}
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
iCurImage->Pal.Palette = (ILubyte*)ialloc(IL_DOOMPAL_SIZE);
if (iCurImage->Pal.Palette == NULL) {
return IL_FALSE;
}
iCurImage->Pal.PalSize = IL_DOOMPAL_SIZE;
iCurImage->Pal.PalType = IL_PAL_RGB24;
memcpy(iCurImage->Pal.Palette, ilDefaultDoomPal, IL_DOOMPAL_SIZE);
if (iread(iCurImage->Data, 1, 4096) != 4096)
return IL_FALSE;
if (ilGetBoolean(IL_CONV_PAL) == IL_TRUE) {
NewData = (ILubyte*)ialloc(iCurImage->SizeOfData * 4);
if (NewData == NULL) {
return IL_FALSE;
}
for (i = 0; i < iCurImage->SizeOfData; i++) {
NewData[i * 4] = iCurImage->Pal.Palette[iCurImage->Data[i]];
NewData[i * 4] = iCurImage->Pal.Palette[iCurImage->Data[i]];
NewData[i * 4] = iCurImage->Pal.Palette[iCurImage->Data[i]];
NewData[i * 4 + 3] = iCurImage->Data[i] != 247 ? 255 : 0;
}
if (!ilTexImage(iCurImage->Width, iCurImage->Height, iCurImage->Depth,
4, IL_RGBA, iCurImage->Type, NewData)) {
ifree(NewData);
return IL_FALSE;
}
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
ifree(NewData);
}
return ilFixImage();
}
#endif
+325
View File
@@ -0,0 +1,325 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 02/26/2009
//
// Filename: src-IL/src/il_dpx.c
//
// Description: Reads from a Digital Picture Exchange (.dpx) file.
// Specifications for this format were found at
// http://www.cineon.com/ff_draft.php and
// http://www.fileformat.info/format/dpx/.
//
//-----------------------------------------------------------------------------
#include "il_internal.h"
#ifndef IL_NO_DPX
#include "il_dpx.h"
#include "il_bits.h"
ILboolean iLoadDpxInternal(void);
//! Reads a DPX file
ILboolean ilLoadDpx(ILconst_string FileName)
{
ILHANDLE DpxFile;
ILboolean bDpx = IL_FALSE;
DpxFile = iopenr(FileName);
if (DpxFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bDpx;
}
bDpx = ilLoadDpxF(DpxFile);
icloser(DpxFile);
return bDpx;
}
//! Reads an already-opened DPX file
ILboolean ilLoadDpxF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iLoadDpxInternal();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Reads from a memory "lump" that contains a DPX
ILboolean ilLoadDpxL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iLoadDpxInternal();
}
ILboolean DpxGetFileInfo(DPX_FILE_INFO *FileInfo)
{
//if (iread(FileInfo, 768, 1) != 1)
// return IL_FALSE;
FileInfo->MagicNum = GetBigUInt();
FileInfo->Offset = GetBigUInt();
iread(FileInfo->Vers, 8, 1);
FileInfo->FileSize = GetBigUInt();
FileInfo->DittoKey = GetBigUInt();
FileInfo->GenHdrSize = GetBigUInt();
FileInfo->IndHdrSize = GetBigUInt();
FileInfo->UserDataSize = GetBigUInt();
iread(FileInfo->FileName, 100, 1);
iread(FileInfo->CreateTime, 24, 1);
iread(FileInfo->Creator, 100, 1);
iread(FileInfo->Project, 200, 1);
if (iread(FileInfo->Copyright, 200, 1) != 1)
return IL_FALSE;
FileInfo->Key = GetBigUInt();
iseek(104, IL_SEEK_CUR); // Skip reserved section.
return IL_TRUE;
}
ILboolean GetImageElement(DPX_IMAGE_ELEMENT *ImageElement)
{
ImageElement->DataSign = GetBigUInt();
ImageElement->RefLowData = GetBigUInt();
iread(&ImageElement->RefLowQuantity, 1, 4);
ImageElement->RefHighData = GetBigUInt();
iread(&ImageElement->RefHighQuantity, 1, 4);
ImageElement->Descriptor = igetc();
ImageElement->Transfer = igetc();
ImageElement->Colorimetric = igetc();
ImageElement->BitSize = igetc();
ImageElement->Packing = GetBigUShort();
ImageElement->Encoding = GetBigUShort();
ImageElement->DataOffset = GetBigUInt();
ImageElement->EolPadding = GetBigUInt();
ImageElement->EoImagePadding = GetBigUInt();
if (iread(ImageElement->Description, 32, 1) != 1)
return IL_FALSE;
return IL_TRUE;
}
ILboolean DpxGetImageInfo(DPX_IMAGE_INFO *ImageInfo)
{
ILuint i;
//if (iread(ImageInfo, sizeof(DPX_IMAGE_INFO), 1) != 1)
// return IL_FALSE;
ImageInfo->Orientation = GetBigUShort();
ImageInfo->NumElements = GetBigUShort();
ImageInfo->Width = GetBigUInt();
ImageInfo->Height = GetBigUInt();
for (i = 0; i < 8; i++) {
GetImageElement(&ImageInfo->ImageElement[i]);
}
iseek(52, IL_SEEK_CUR); // Skip padding bytes.
return IL_TRUE;
}
ILboolean DpxGetImageOrient(DPX_IMAGE_ORIENT *ImageOrient)
{
ImageOrient->XOffset = GetBigUInt();
ImageOrient->YOffset = GetBigUInt();
iread(&ImageOrient->XCenter, 4, 1);
iread(&ImageOrient->YCenter, 4, 1);
ImageOrient->XOrigSize = GetBigUInt();
ImageOrient->YOrigSize = GetBigUInt();
iread(ImageOrient->FileName, 100, 1);
iread(ImageOrient->CreationTime, 24, 1);
iread(ImageOrient->InputDev, 32, 1);
if (iread(ImageOrient->InputSerial, 32, 1) != 1)
return IL_FALSE;
ImageOrient->Border[0] = GetBigUShort();
ImageOrient->Border[1] = GetBigUShort();
ImageOrient->Border[2] = GetBigUShort();
ImageOrient->Border[3] = GetBigUShort();
ImageOrient->PixelAspect[0] = GetBigUInt();
ImageOrient->PixelAspect[1] = GetBigUInt();
iseek(28, IL_SEEK_CUR); // Skip reserved bytes.
return IL_TRUE;
}
// Internal function used to load the DPX.
ILboolean iLoadDpxInternal(void)
{
DPX_FILE_INFO FileInfo;
DPX_IMAGE_INFO ImageInfo;
DPX_IMAGE_ORIENT ImageOrient;
// BITFILE *File;
ILuint i, NumElements, CurElem = 0;
ILushort Val, *ShortData;
ILubyte Data[8];
ILenum Format = 0;
ILubyte NumChans = 0;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
if (!DpxGetFileInfo(&FileInfo))
return IL_FALSE;
if (!DpxGetImageInfo(&ImageInfo))
return IL_FALSE;
if (!DpxGetImageOrient(&ImageOrient))
return IL_FALSE;
iseek(ImageInfo.ImageElement[CurElem].DataOffset, IL_SEEK_SET);
//@TODO: Deal with different origins!
switch (ImageInfo.ImageElement[CurElem].Descriptor)
{
case 6: // Luminance data
Format = IL_LUMINANCE;
NumChans = 1;
break;
case 50: // RGB data
Format = IL_RGB;
NumChans = 3;
break;
case 51: // RGBA data
Format = IL_RGBA;
NumChans = 4;
break;
default:
ilSetError(IL_FORMAT_NOT_SUPPORTED);
return IL_FALSE;
}
// These are all on nice word boundaries.
switch (ImageInfo.ImageElement[CurElem].BitSize)
{
case 8:
case 16:
case 32:
if (!ilTexImage(ImageInfo.Width, ImageInfo.Height, 1, NumChans, Format, IL_UNSIGNED_BYTE, NULL))
return IL_FALSE;
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
if (iread(iCurImage->Data, iCurImage->SizeOfData, 1) != 1)
return IL_FALSE;
goto finish;
}
// The rest of these do not end on word boundaries.
if (ImageInfo.ImageElement[CurElem].Packing == 1) {
// Here we have it padded out to a word boundary, so the extra bits are filler.
switch (ImageInfo.ImageElement[CurElem].BitSize)
{
case 10:
//@TODO: Support other formats!
/*if (Format != IL_RGB) {
ilSetError(IL_FORMAT_NOT_SUPPORTED);
return IL_FALSE;
}*/
switch (Format)
{
case IL_LUMINANCE:
if (!ilTexImage(ImageInfo.Width, ImageInfo.Height, 1, 1, IL_LUMINANCE, IL_UNSIGNED_SHORT, NULL))
return IL_FALSE;
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
ShortData = (ILushort*)iCurImage->Data;
NumElements = iCurImage->SizeOfData / 2;
for (i = 0; i < NumElements;) {
iread(Data, 1, 2);
Val = ((Data[0] << 2) + ((Data[1] & 0xC0) >> 6)) << 6; // Use the first 10 bits of the word-aligned data.
ShortData[i++] = Val | ((Val & 0x3F0) >> 4); // Fill in the lower 6 bits with a copy of the higher bits.
}
break;
case IL_RGB:
if (!ilTexImage(ImageInfo.Width, ImageInfo.Height, 1, 3, IL_RGB, IL_UNSIGNED_SHORT, NULL))
return IL_FALSE;
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
ShortData = (ILushort*)iCurImage->Data;
NumElements = iCurImage->SizeOfData / 2;
for (i = 0; i < NumElements;) {
iread(Data, 1, 4);
Val = ((Data[0] << 2) + ((Data[1] & 0xC0) >> 6)) << 6; // Use the first 10 bits of the word-aligned data.
ShortData[i++] = Val | ((Val & 0x3F0) >> 4); // Fill in the lower 6 bits with a copy of the higher bits.
Val = (((Data[1] & 0x3F) << 4) + ((Data[2] & 0xF0) >> 4)) << 6; // Use the next 10 bits.
ShortData[i++] = Val | ((Val & 0x3F0) >> 4); // Same fill
Val = (((Data[2] & 0x0F) << 6) + ((Data[3] & 0xFC) >> 2)) << 6; // And finally use the last 10 bits (ignores the last 2 bits).
ShortData[i++] = Val | ((Val & 0x3F0) >> 4); // Same fill
}
break;
case IL_RGBA: // Is this even a possibility? There is a ton of wasted space here!
if (!ilTexImage(ImageInfo.Width, ImageInfo.Height, 1, 4, IL_RGBA, IL_UNSIGNED_SHORT, NULL))
return IL_FALSE;
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
ShortData = (ILushort*)iCurImage->Data;
NumElements = iCurImage->SizeOfData / 2;
for (i = 0; i < NumElements;) {
iread(Data, 1, 8);
Val = (Data[0] << 2) + ((Data[1] & 0xC0) >> 6); // Use the first 10 bits of the word-aligned data.
ShortData[i++] = (Val << 6) | ((Val & 0x3F0) >> 4); // Fill in the lower 6 bits with a copy of the higher bits.
Val = ((Data[1] & 0x3F) << 4) + ((Data[2] & 0xF0) >> 4); // Use the next 10 bits.
ShortData[i++] = (Val << 6) | ((Val & 0x3F0) >> 4); // Same fill
Val = ((Data[2] & 0x0F) << 6) + ((Data[3] & 0xFC) >> 2); // Use the next 10 bits.
ShortData[i++] = (Val << 6) | ((Val & 0x3F0) >> 4); // Same fill
Val = ((Data[3] & 0x03) << 8) + Data[4]; // And finally use the last 10 relevant bits (skips 3 whole bytes worth of padding!).
ShortData[i++] = (Val << 6) | ((Val & 0x3F0) >> 4); // Last fill
}
break;
}
break;
//case 1:
//case 12:
default:
ilSetError(IL_FORMAT_NOT_SUPPORTED);
return IL_FALSE;
}
}
else if (ImageInfo.ImageElement[0].Packing == 0) {
// Here we have the data packed so that it is never aligned on a word boundary.
/*File = bfile(iGetFile());
if (File == NULL)
return IL_FALSE; //@TODO: Error?
ShortData = (ILushort*)iCurImage->Data;
NumElements = iCurImage->SizeOfData / 2;
for (i = 0; i < NumElements; i++) {
//bread(&Val, 1, 10, File);
Val = breadVal(10, File);
ShortData[i] = (Val << 6) | (Val >> 4);
}
bclose(File);*/
ilSetError(IL_FORMAT_NOT_SUPPORTED);
return IL_FALSE;
}
else {
ilSetError(IL_ILLEGAL_FILE_VALUE);
return IL_FALSE; //@TODO: Take care of this in an iCheckDpx* function.
}
finish:
return ilFixImage();
}
#endif//IL_NO_DPX
+278
View File
@@ -0,0 +1,278 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Last modified: 12/06/2006
//
// Filename: src-IL/src/il_endian.c
//
// Description: Takes care of endian issues
//
//-----------------------------------------------------------------------------
#define IL_ENDIAN_C
#include "il_endian.h"
void EndianSwapData(void *_Image)
{
ILuint i;
ILubyte *temp, *s, *d;
ILushort *ShortS, *ShortD;
ILuint *IntS, *IntD;
ILfloat *FltS, *FltD;
ILdouble *DblS, *DblD;
ILimage *Image = (ILimage*)_Image;
switch (Image->Type) {
case IL_BYTE:
case IL_UNSIGNED_BYTE:
switch (Image->Bpp) {
case 3:
temp = (ILubyte*)ialloc(Image->SizeOfData);
if (temp == NULL)
return;
s = Image->Data;
d = temp;
for( i = Image->Width * Image->Height; i > 0; i-- ) {
*d++ = *(s+2);
*d++ = *(s+1);
*d++ = *s;
s += 3;
}
ifree(Image->Data);
Image->Data = temp;
break;
case 4:
temp = (ILubyte*)ialloc(Image->SizeOfData);
if (temp == NULL)
return;
s = Image->Data;
d = temp;
for (i = Image->Width * Image->Height; i > 0; i--) {
*d++ = *(s+3);
*d++ = *(s+2);
*d++ = *(s+1);
*d++ = *s;
s += 4;
}
ifree(Image->Data);
Image->Data = temp;
break;
}
break;
case IL_SHORT:
case IL_UNSIGNED_SHORT:
switch (Image->Bpp) {
case 3:
temp = (ILubyte*)ialloc(Image->SizeOfData);
if (temp == NULL)
return;
ShortS = (ILushort*)Image->Data;
ShortD = (ILushort*)temp;
for (i = Image->Width * Image->Height; i > 0; i--) {
*ShortD = *ShortS++; iSwapUShort(ShortD++);
*ShortD = *ShortS++; iSwapUShort(ShortD++);
*ShortD = *ShortS++; iSwapUShort(ShortD++);
}
ifree(Image->Data);
Image->Data = temp;
break;
case 4:
temp = (ILubyte*)ialloc(Image->SizeOfData);
if (temp == NULL)
return;
ShortS = (ILushort*)Image->Data;
ShortD = (ILushort*)temp;
for (i = Image->Width * Image->Height; i > 0; i--) {
*ShortD = *ShortS++; iSwapUShort(ShortD++);
*ShortD = *ShortS++; iSwapUShort(ShortD++);
*ShortD = *ShortS++; iSwapUShort(ShortD++);
*ShortD = *ShortS++; iSwapUShort(ShortD++);
}
ifree(Image->Data);
Image->Data = temp;
break;
}
break;
case IL_INT:
case IL_UNSIGNED_INT:
switch (Image->Bpp)
{
case 3:
temp = (ILubyte*)ialloc(Image->SizeOfData);
if (temp == NULL)
return;
IntS = (ILuint*)Image->Data;
IntD = (ILuint*)temp;
for (i = Image->Width * Image->Height; i > 0; i--) {
*IntD = *IntS++; iSwapUInt(IntD++);
*IntD = *IntS++; iSwapUInt(IntD++);
*IntD = *IntS++; iSwapUInt(IntD++);
}
ifree(Image->Data);
Image->Data = temp;
break;
case 4:
temp = (ILubyte*)ialloc(Image->SizeOfData);
if (temp == NULL)
return;
IntS = (ILuint*)Image->Data;
IntD = (ILuint*)temp;
for (i = Image->Width * Image->Height; i > 0; i--) {
*IntD = *IntS++; iSwapUInt(IntD++);
*IntD = *IntS++; iSwapUInt(IntD++);
*IntD = *IntS++; iSwapUInt(IntD++);
*IntD = *IntS++; iSwapUInt(IntD++);
}
ifree(Image->Data);
Image->Data = temp;
break;
}
break;
case IL_FLOAT:
switch (Image->Bpp)
{
case 3:
temp = (ILubyte*)ialloc(Image->SizeOfData);
if (temp == NULL)
return;
FltS = (ILfloat*)Image->Data;
FltD = (ILfloat*)temp;
for (i = Image->Width * Image->Height; i > 0; i--) {
*FltD = *FltS++; iSwapFloat(FltD++);
*FltD = *FltS++; iSwapFloat(FltD++);
*FltD = *FltS++; iSwapFloat(FltD++);
}
ifree(Image->Data);
Image->Data = temp;
break;
case 4:
temp = (ILubyte*)ialloc(Image->SizeOfData);
if (temp == NULL)
return;
FltS = (ILfloat*)Image->Data;
FltD = (ILfloat*)temp;
for (i = Image->Width * Image->Height; i > 0; i--) {
*FltD = *FltS++; iSwapFloat(FltD++);
*FltD = *FltS++; iSwapFloat(FltD++);
*FltD = *FltS++; iSwapFloat(FltD++);
*FltD = *FltS++; iSwapFloat(FltD++);
}
ifree(Image->Data);
Image->Data = temp;
break;
}
break;
case IL_DOUBLE:
switch (Image->Bpp)
{
case 3:
temp = (ILubyte*)ialloc(Image->SizeOfData);
if (temp == NULL)
return;
DblS = (ILdouble*)Image->Data;
DblD = (ILdouble*)temp;
for (i = Image->Width * Image->Height; i > 0; i--) {
*DblD = *DblS++; iSwapDouble(DblD++);
*DblD = *DblS++; iSwapDouble(DblD++);
*DblD = *DblS++; iSwapDouble(DblD++);
}
ifree(Image->Data);
Image->Data = temp;
break;
case 4:
temp = (ILubyte*)ialloc(Image->SizeOfData);
if (temp == NULL)
return;
DblS = (ILdouble*)Image->Data;
DblD = (ILdouble*)temp;
for (i = Image->Width * Image->Height; i > 0; i--) {
*DblD = *DblS++; iSwapDouble(DblD++);
*DblD = *DblS++; iSwapDouble(DblD++);
*DblD = *DblS++; iSwapDouble(DblD++);
*DblD = *DblS++; iSwapDouble(DblD++);
}
ifree(Image->Data);
Image->Data = temp;
break;
}
break;
}
if( iCurImage->Format == IL_COLOUR_INDEX ) {
switch (iCurImage->Pal.PalType) {
case IL_PAL_RGB24:
case IL_PAL_BGR24:
temp = (ILubyte*)ialloc(Image->Pal.PalSize);
if (temp == NULL)
return;
s = Image->Pal.Palette;
d = temp;
for (i = Image->Pal.PalSize / 3; i > 0; i--) {
*d++ = *(s+2);
*d++ = *(s+1);
*d++ = *s;
s += 3;
}
ifree(Image->Pal.Palette);
Image->Pal.Palette = temp;
break;
case IL_PAL_RGBA32:
case IL_PAL_RGB32:
case IL_PAL_BGRA32:
case IL_PAL_BGR32:
temp = (ILubyte*)ialloc(Image->Pal.PalSize);
if (temp == NULL)
return;
s = Image->Pal.Palette;
d = temp;
for (i = Image->Pal.PalSize / 4; i > 0; i--) {
*d++ = *(s+3);
*d++ = *(s+2);
*d++ = *(s+1);
*d++ = *s;
s += 4;
}
ifree(Image->Pal.Palette);
Image->Pal.Palette = temp;
break;
}
}
return;
}
+56
View File
@@ -0,0 +1,56 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2008 by Denton Woods
// Last modified: 06/02/2007
//
// Filename: src-IL/src/il_error.c
//
// Description: The error functions
//
//-----------------------------------------------------------------------------
#include "il_internal.h"
#define IL_ERROR_STACK_SIZE 32 // Needed elsewhere?
ILenum ilErrorNum[IL_ERROR_STACK_SIZE];
ILint ilErrorPlace = (-1);
// Sets the current error
// If you go past the stack size for this, it cycles the errors, almost like a LRU algo.
ILAPI void ILAPIENTRY ilSetError(ILenum Error)
{
ILuint i;
ilErrorPlace++;
if (ilErrorPlace >= IL_ERROR_STACK_SIZE) {
for (i = 0; i < IL_ERROR_STACK_SIZE - 2; i++) {
ilErrorNum[i] = ilErrorNum[i+1];
}
ilErrorPlace = IL_ERROR_STACK_SIZE - 1;
}
ilErrorNum[ilErrorPlace] = Error;
return;
}
//! Gets the last error on the error stack
ILenum ILAPIENTRY ilGetError(void)
{
ILenum ilReturn;
if (ilErrorPlace >= 0) {
ilReturn = ilErrorNum[ilErrorPlace];
ilErrorPlace--;
}
else
ilReturn = IL_NO_ERROR;
return ilReturn;
}
+435
View File
@@ -0,0 +1,435 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 03/07/2009
//
// Filename: src-IL/src/il_exr.cpp
//
// Description: Reads from an OpenEXR (.exr) file using the OpenEXR library.
//
//-----------------------------------------------------------------------------
#include "il_internal.h"
#ifndef IL_NO_EXR
#ifndef HAVE_CONFIG_H // We are probably on a Windows box .
//#define OPENEXR_DLL
#define HALF_EXPORTS
#endif //HAVE_CONFIG_H
#include "il_exr.h"
#include <ImfRgba.h>
#include <ImfArray.h>
#include <ImfRgbaFile.h>
//#include <ImfTiledRgbaFile.h>
//#include <ImfInputFile.h>
//#include <ImfTiledInputFile.h>
//#include <ImfPreviewImage.h>
//#include <ImfChannelList.h>
#if (defined(_WIN32) || defined(_WIN64)) && defined(IL_USE_PRAGMA_LIBS)
#if defined(_MSC_VER) || defined(__BORLANDC__)
#ifndef _DEBUG
#pragma comment(lib, "openexr.lib")
#else
#pragma comment(lib, "openexr-d.lib")
#endif
#endif
#endif
//! Checks if the file specified in FileName is a valid EXR file.
ILboolean ilIsValidExr(ILconst_string FileName)
{
ILHANDLE ExrFile;
ILboolean bExr = IL_FALSE;
if (!iCheckExtension(FileName, IL_TEXT("exr"))) {
ilSetError(IL_INVALID_EXTENSION);
return bExr;
}
ExrFile = iopenr(FileName);
if (ExrFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bExr;
}
bExr = ilIsValidExrF(ExrFile);
icloser(ExrFile);
return bExr;
}
//! Checks if the ILHANDLE contains a valid EXR file at the current position.
ILboolean ilIsValidExrF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iIsValidExr();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Checks if Lump is a valid EXR lump.
ILboolean ilIsValidExrL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iIsValidExr();
}
// Internal function used to get the EXR header from the current file.
ILboolean iGetExrHead(EXRHEAD *Header)
{
Header->MagicNumber = GetLittleUInt();
Header->Version = GetLittleUInt();
return IL_TRUE;
}
// Internal function to get the header and check it.
ILboolean iIsValidExr()
{
EXRHEAD Head;
if (!iGetExrHead(&Head))
return IL_FALSE;
iseek(-8, IL_SEEK_CUR);
return iCheckExr(&Head);
}
// Internal function used to check if the HEADER is a valid EXR header.
ILboolean iCheckExr(EXRHEAD *Header)
{
// The file magic number (signature) is 0x76, 0x2f, 0x31, 0x01
if (Header->MagicNumber != 0x01312F76)
return IL_FALSE;
// The only valid version so far is version 2. The upper value has
// to do with tiling.
if (Header->Version != 0x002 && Header->Version != 0x202)
return IL_FALSE;
return IL_TRUE;
}
// Nothing to do here in the constructor.
ilIStream::ilIStream() : Imf::IStream("N/A")
{
return;
}
bool ilIStream::read(char c[], int n)
{
if (iread(c, 1, n) != n)
return false;
return true;
}
//@TODO: Make this work with 64-bit values.
Imf::Int64 ilIStream::tellg()
{
Imf::Int64 Pos;
// itell only returns a 32-bit value!
Pos = itell();
return Pos;
}
// Note that there is no return value here, even though there probably should be.
//@TODO: Make this work with 64-bit values.
void ilIStream::seekg(Imf::Int64 Pos)
{
// iseek only uses a 32-bit value!
iseek((ILint)Pos, IL_SEEK_SET); // I am assuming this is seeking from the beginning.
return;
}
void ilIStream::clear()
{
return;
}
//! Reads an .exr file.
ILboolean ilLoadExr(ILconst_string FileName)
{
ILHANDLE ExrFile;
ILboolean bExr = IL_FALSE;
ExrFile = iopenr(FileName);
if (ExrFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bExr;
}
bExr = ilLoadExrF(ExrFile);
icloser(ExrFile);
return bExr;
}
//! Reads an already-opened .exr file
ILboolean ilLoadExrF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iLoadExrInternal();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Reads from a memory "lump" that contains an .exr
ILboolean ilLoadExrL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iLoadExrInternal();
}
using namespace Imath;
using namespace Imf;
using namespace std;
ILboolean iLoadExrInternal()
{
Array<Rgba> pixels;
Box2i dataWindow;
float pixelAspectRatio;
ILfloat *FloatData;
ilIStream File;
RgbaInputFile in(File);
Rgba a;
dataWindow = in.dataWindow();
pixelAspectRatio = in.pixelAspectRatio();
int dw, dh, dx, dy;
dw = dataWindow.max.x - dataWindow.min.x + 1;
dh = dataWindow.max.y - dataWindow.min.y + 1;
dx = dataWindow.min.x;
dy = dataWindow.min.y;
pixels.resizeErase (dw * dh);
in.setFrameBuffer (pixels - dx - dy * dw, 1, dw);
try
{
in.readPixels (dataWindow.min.y, dataWindow.max.y);
}
catch (const exception &e)
{
// If some of the pixels in the file cannot be read,
// print an error message, and return a partial image
// to the caller.
ilSetError(IL_LIB_EXR_ERROR); // Could I use something a bit more descriptive based on e?
e; // Prevent the compiler from yelling at us about this being unused.
return IL_FALSE;
}
//if (ilTexImage(dw, dh, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL) == IL_FALSE)
//if (ilTexImage(dw, dh, 1, 4, IL_RGBA, IL_UNSIGNED_SHORT, NULL) == IL_FALSE)
if (ilTexImage(dw, dh, 1, 4, IL_RGBA, IL_FLOAT, NULL) == IL_FALSE)
return IL_FALSE;
// Determine where the origin is in the original file.
if (in.lineOrder() == INCREASING_Y)
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
else
iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
// Better to access FloatData instead of recasting everytime.
FloatData = (ILfloat*)iCurImage->Data;
for (int i = 0; i < dw * dh; i++)
{
// Too much data lost
//iCurImage->Data[i * 4 + 0] = (ILubyte)(pixels[i].r.bits() >> 8);
//iCurImage->Data[i * 4 + 1] = (ILubyte)(pixels[i].g.bits() >> 8);
//iCurImage->Data[i * 4 + 2] = (ILubyte)(pixels[i].b.bits() >> 8);
//iCurImage->Data[i * 4 + 3] = (ILubyte)(pixels[i].a.bits() >> 8);
// The images look kind of washed out with this.
//((ILshort*)(iCurImage->Data))[i * 4 + 0] = pixels[i].r.bits();
//((ILshort*)(iCurImage->Data))[i * 4 + 1] = pixels[i].g.bits();
//((ILshort*)(iCurImage->Data))[i * 4 + 2] = pixels[i].b.bits();
//((ILshort*)(iCurImage->Data))[i * 4 + 3] = pixels[i].a.bits();
// This gives the best results, since no data is lost.
FloatData[i * 4] = pixels[i].r;
FloatData[i * 4 + 1] = pixels[i].g;
FloatData[i * 4 + 2] = pixels[i].b;
FloatData[i * 4 + 3] = pixels[i].a;
}
// Converts the image to predefined type, format and/or origin if needed.
return ilFixImage();
}
// Nothing to do here in the constructor.
ilOStream::ilOStream() : Imf::OStream("N/A")
{
return;
}
void ilOStream::write(const char c[], int n)
{
iwrite(c, 1, n); //@TODO: Throw an exception here.
return;
}
//@TODO: Make this work with 64-bit values.
Imf::Int64 ilOStream::tellp()
{
Imf::Int64 Pos;
// itellw only returns a 32-bit value!
Pos = itellw();
return Pos;
}
// Note that there is no return value here, even though there probably should be.
//@TODO: Make this work with 64-bit values.
void ilOStream::seekp(Imf::Int64 Pos)
{
// iseekw only uses a 32-bit value!
iseekw((ILint)Pos, IL_SEEK_SET); // I am assuming this is seeking from the beginning.
return;
}
//! Writes a Exr file
ILboolean ilSaveExr(const ILstring FileName)
{
ILHANDLE ExrFile;
ILuint ExrSize;
if (ilGetBoolean(IL_FILE_MODE) == IL_FALSE) {
if (iFileExists(FileName)) {
ilSetError(IL_FILE_ALREADY_EXISTS);
return IL_FALSE;
}
}
ExrFile = iopenw(FileName);
if (ExrFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return IL_FALSE;
}
ExrSize = ilSaveExrF(ExrFile);
iclosew(ExrFile);
if (ExrSize == 0)
return IL_FALSE;
return IL_TRUE;
}
//! Writes a Exr to an already-opened file
ILuint ilSaveExrF(ILHANDLE File)
{
ILuint Pos;
iSetOutputFile(File);
Pos = itellw();
if (iSaveExrInternal() == IL_FALSE)
return 0; // Error occurred
return itellw() - Pos; // Return the number of bytes written.
}
//! Writes a Exr to a memory "lump"
ILuint ilSaveExrL(void *Lump, ILuint Size)
{
ILuint Pos = itellw();
iSetOutputLump(Lump, Size);
if (iSaveExrInternal() == IL_FALSE)
return 0; // Error occurred
return itellw() - Pos; // Return the number of bytes written.
}
ILboolean iSaveExrInternal()
{
Imath::Box2i DataWindow(Imath::V2i(0, 0), Imath::V2i(iCurImage->Width-1, iCurImage->Height-1));
Imf::LineOrder Order;
if (iCurImage->Origin == IL_ORIGIN_LOWER_LEFT)
Order = DECREASING_Y;
else
Order = INCREASING_Y;
Imf::Header Head(iCurImage->Width, iCurImage->Height, DataWindow, 1, Imath::V2f (0, 0), 1, Order);
ilOStream File;
Imf::RgbaOutputFile Out(File, Head);
ILimage *TempImage = iCurImage;
//@TODO: Can we always assume that Rgba is packed the same?
Rgba *HalfData = (Rgba*)ialloc(TempImage->Width * TempImage->Height * sizeof(Rgba));
if (HalfData == NULL)
return IL_FALSE;
if (iCurImage->Format != IL_RGBA || iCurImage->Type != IL_FLOAT) {
TempImage = iConvertImage(iCurImage, IL_RGBA, IL_FLOAT);
if (TempImage == NULL) {
ifree(HalfData);
return IL_FALSE;
}
}
ILuint Offset = 0;
ILfloat *FloatPtr = (ILfloat*)TempImage->Data;
for (unsigned int y = 0; y < TempImage->Height; y++) {
for (unsigned int x = 0; x < TempImage->Width; x++) {
HalfData[y * TempImage->Width + x].r = FloatPtr[Offset];
HalfData[y * TempImage->Width + x].g = FloatPtr[Offset + 1];
HalfData[y * TempImage->Width + x].b = FloatPtr[Offset + 2];
HalfData[y * TempImage->Width + x].a = FloatPtr[Offset + 3];
Offset += 4; // 4 floats
}
}
Out.setFrameBuffer(HalfData, 1, TempImage->Width);
Out.writePixels(TempImage->Height); //@TODO: Do each scanline separately to keep from using so much memory.
// Free our half data.
ifree(HalfData);
// Destroy our temporary image if we used one.
if (TempImage != iCurImage)
ilCloseImage(TempImage);
return IL_TRUE;
}
#endif //IL_NO_EXR
+290
View File
@@ -0,0 +1,290 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2008 by Denton Woods
// Last modified: 07/07/2006
//
// Filename: src-IL/src/il_fastconv.c
//
// Description: Converts between several image formats
//
//-----------------------------------------------------------------------------
#include "il_internal.h"
#ifdef ALTIVEC_GCC
#include "altivec_typeconversion.h"
#endif
ILboolean iFastConvert(ILenum DestFormat)
{
ILubyte *BytePtr = iCurImage->Data;
ILushort *ShortPtr = (ILushort*)iCurImage->Data;
ILuint *IntPtr = (ILuint*)iCurImage->Data;
ILfloat *FloatPtr = (ILfloat*)iCurImage->Data;
ILdouble *DblPtr = (ILdouble*)iCurImage->Data;
#ifndef ALTIVEC_GCC
ILuint SizeOfData, i=0;
ILubyte TempByte = 0;
ILushort TempShort = 0;
ILuint TempInt = 0;
ILfloat TempFloat = 0;
ILdouble TempDbl = 0;
#endif
switch (DestFormat)
{
case IL_RGB:
case IL_BGR:
if (iCurImage->Format != IL_RGB && iCurImage->Format != IL_BGR)
return IL_FALSE;
switch (iCurImage->Type)
{
case IL_BYTE:
case IL_UNSIGNED_BYTE:
#ifdef ALTIVEC_GCC
abc2cba_byte(BytePtr,iCurImage->SizeOfData,BytePtr);
#else
SizeOfData = iCurImage->SizeOfData / 3;
#ifdef USE_WIN32_ASM
__asm
{
mov ebx, BytePtr
mov ecx, SizeOfData
L1:
mov al,[ebx+0]
xchg al,[ebx+2]
mov [ebx+0],al
add ebx,3
loop L1
}
#else
for (i = 0; i < SizeOfData; i++) {
TempByte = BytePtr[0];
BytePtr[0] = BytePtr[2];
BytePtr[2] = TempByte;
BytePtr += 3;
}
#endif//USE_WIN32_ASM
#endif
return IL_TRUE;
case IL_SHORT:
case IL_UNSIGNED_SHORT:
#ifdef ALTIVEC_GCC
abc2cba_short(ShortPtr,iCurImage->SizeOfData,ShortPtr);
#else
SizeOfData = iCurImage->SizeOfData / 6; // 3*2
#ifdef USE_WIN32_ASM
__asm
{
mov ebx, ShortPtr
mov ecx, SizeOfData
L2:
mov ax,[ebx+0]
xchg ax,[ebx+4]
mov [ebx+0],ax
add ebx,6
loop L2
}
#else
for (i = 0; i < SizeOfData; i++) {
TempShort = ShortPtr[0];
ShortPtr[0] = ShortPtr[2];
ShortPtr[2] = TempShort;
ShortPtr += 3;
}
#endif//USE_WIN32_ASM
#endif
return IL_TRUE;
case IL_INT:
case IL_UNSIGNED_INT:
#ifdef ALTIVEC_GCC
abc2cba_int(IntPtr,iCurImage->SizeOfData,IntPtr);
#else
SizeOfData = iCurImage->SizeOfData / 12; // 3*4
#ifdef USE_WIN32_ASM
__asm
{
mov ebx, IntPtr
mov ecx, SizeOfData
L3:
mov eax,[ebx+0]
xchg eax,[ebx+8]
mov [ebx+0],ax
add ebx,12
loop L3
}
#else
for (i = 0; i < SizeOfData; i++) {
TempInt = IntPtr[0];
IntPtr[0] = IntPtr[2];
IntPtr[2] = TempInt;
IntPtr += 3;
}
#endif//USE_WIN32_ASM
#endif
return IL_TRUE;
case IL_FLOAT:
#ifdef ALTIVEC_GCC
abc2cba_float(FloatPtr,iCurImage->SizeOfData,FloatPtr);
#else
SizeOfData = iCurImage->SizeOfData / 12; // 3*4
for (i = 0; i < SizeOfData; i++) {
TempFloat = FloatPtr[0];
FloatPtr[0] = FloatPtr[2];
FloatPtr[2] = TempFloat;
FloatPtr += 3;
}
#endif
return IL_TRUE;
case IL_DOUBLE:
#ifdef ALTIVEC_GCC
abc2cba_double(DblPtr,iCurImage->SizeOfData,DblPtr);
#else
SizeOfData = iCurImage->SizeOfData / 24; // 3*8
for (i = 0; i < SizeOfData; i++) {
TempDbl = DblPtr[0];
DblPtr[0] = DblPtr[2];
DblPtr[2] = TempDbl;
DblPtr += 3;
}
#endif
return IL_TRUE;
}
break;
case IL_RGBA:
case IL_BGRA:
if (iCurImage->Format != IL_RGBA && iCurImage->Format != IL_BGRA)
return IL_FALSE;
switch (iCurImage->Type)
{
case IL_BYTE:
case IL_UNSIGNED_BYTE:
#ifdef ALTIVEC_GCC
abcd2cbad_byte(BytePtr,iCurImage->SizeOfData,BytePtr);
#else
SizeOfData = iCurImage->SizeOfData / 4;
#ifdef USE_WIN32_ASM
__asm
{
mov ebx, BytePtr
mov ecx, SizeOfData
L4:
mov eax,[ebx]
bswap eax
ror eax,8
mov [ebx], eax
add ebx,4
loop L4
}
#else
for (i = 0; i < SizeOfData; i++) {
TempByte = BytePtr[0];
BytePtr[0] = BytePtr[2];
BytePtr[2] = TempByte;
BytePtr += 4;
}
#endif//USE_WIN32_ASM
#endif
return IL_TRUE;
case IL_SHORT:
case IL_UNSIGNED_SHORT:
#ifdef ALTIVEC_GCC
abcd2cbad_short(ShortPtr,iCurImage->SizeOfData,ShortPtr);
#else
SizeOfData = iCurImage->SizeOfData / 8; // 4*2
#ifdef USE_WIN32_ASM
__asm
{
mov ebx, ShortPtr
mov ecx, SizeOfData
L5:
mov ax,[ebx+0]
xchg ax,[ebx+4]
mov [ebx+0],ax
add ebx,8
loop L5
}
#else
for (i = 0; i < SizeOfData; i++) {
TempShort = ShortPtr[0];
ShortPtr[0] = ShortPtr[2];
ShortPtr[2] = TempShort;
ShortPtr += 4;
}
#endif//USE_WIN32_ASM
#endif
return IL_TRUE;
case IL_INT:
case IL_UNSIGNED_INT:
#ifdef ALTIVEC_GCC
abcd2cbad_int(IntPtr,iCurImage->SizeOfData,IntPtr);
#else
SizeOfData = iCurImage->SizeOfData / 16; // 4*4
#ifdef USE_WIN32_ASM
__asm
{
mov ebx, IntPtr
mov ecx, SizeOfData
L6:
mov eax,[ebx+0]
xchg eax,[ebx+8]
mov [ebx+0],ax
add ebx,16
loop L6
}
#else
for (i = 0; i < SizeOfData; i++) {
TempInt = IntPtr[0];
IntPtr[0] = IntPtr[2];
IntPtr[2] = TempInt;
IntPtr += 4;
}
#endif//USE_WIN32_ASM
#endif
return IL_TRUE;
case IL_FLOAT:
#ifdef ALTIVEC_GCC
abcd2cbad_float(FloatPtr,iCurImage->SizeOfData,FloatPtr);
#else
SizeOfData = iCurImage->SizeOfData / 16; // 4*4
for (i = 0; i < SizeOfData; i++) {
TempFloat = FloatPtr[0];
FloatPtr[0] = FloatPtr[2];
FloatPtr[2] = TempFloat;
FloatPtr += 4;
}
#endif
return IL_TRUE;
case IL_DOUBLE:
#ifdef ALTIVEC_GCC
abcd2cbad_double(DblPtr,iCurImage->SizeOfData,DblPtr);
#else
SizeOfData = iCurImage->SizeOfData / 32; // 4*8
for (i = 0; i < SizeOfData; i++) {
TempDbl = DblPtr[0];
DblPtr[0] = DblPtr[2];
DblPtr[2] = TempDbl;
DblPtr += 4;
}
#endif
return IL_TRUE;
}
}
return IL_FALSE;
}
+773
View File
@@ -0,0 +1,773 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 01/04/2009
//
// Filename: src-IL/src/il_files.c
//
// Description: File handling for DevIL
//
//-----------------------------------------------------------------------------
#define __FILES_C
#include "il_internal.h"
#include <stdarg.h>
// All specific to the next set of functions
ILboolean ILAPIENTRY iEofFile(void);
ILboolean ILAPIENTRY iEofLump(void);
ILint ILAPIENTRY iGetcFile(void);
ILint ILAPIENTRY iGetcLump(void);
ILuint ILAPIENTRY iReadFile(void *Buffer, ILuint Size, ILuint Number);
ILuint ILAPIENTRY iReadLump(void *Buffer, const ILuint Size, const ILuint Number);
ILint ILAPIENTRY iSeekRFile(ILint Offset, ILuint Mode);
ILint ILAPIENTRY iSeekRLump(ILint Offset, ILuint Mode);
ILint ILAPIENTRY iSeekWFile(ILint Offset, ILuint Mode);
ILint ILAPIENTRY iSeekWLump(ILint Offset, ILuint Mode);
ILuint ILAPIENTRY iTellRFile(void);
ILuint ILAPIENTRY iTellRLump(void);
ILuint ILAPIENTRY iTellWFile(void);
ILuint ILAPIENTRY iTellWLump(void);
ILint ILAPIENTRY iPutcFile(ILubyte Char);
ILint ILAPIENTRY iPutcLump(ILubyte Char);
ILint ILAPIENTRY iWriteFile(const void *Buffer, ILuint Size, ILuint Number);
ILint ILAPIENTRY iWriteLump(const void *Buffer, ILuint Size, ILuint Number);
ILHANDLE FileRead = NULL, FileWrite = NULL;
const void *ReadLump = NULL;
void *WriteLump = NULL;
ILuint ReadLumpPos = 0, ReadLumpSize = 0, ReadFileStart = 0, WriteFileStart = 0;
ILuint WriteLumpPos = 0, WriteLumpSize = 0;
fGetcProc GetcProcCopy;
fReadProc ReadProcCopy;
fSeekRProc SeekProcCopy;
fTellRProc TellProcCopy;
ILHANDLE (ILAPIENTRY *iopenCopy)(ILconst_string);
void (ILAPIENTRY *icloseCopy)(ILHANDLE);
fPutcProc PutcProcCopy;
fSeekWProc SeekWProcCopy;
fTellWProc TellWProcCopy;
fWriteProc WriteProcCopy;
ILHANDLE (ILAPIENTRY *iopenwCopy)(ILconst_string);
void (ILAPIENTRY *iclosewCopy)(ILHANDLE);
ILboolean UseCache = IL_FALSE;
ILubyte *Cache = NULL;
ILuint CacheSize, CachePos, CacheStartPos, CacheBytesRead;
// "Fake" size functions
// Definitions are in il_size.c.
ILint ILAPIENTRY iSizeSeek(ILint Offset, ILuint Mode);
ILuint ILAPIENTRY iSizeTell(void);
ILint ILAPIENTRY iSizePutc(ILubyte Char);
ILint ILAPIENTRY iSizeWrite(const void *Buffer, ILuint Size, ILuint Number);
// Just preserves the current read functions and replaces
// the current read functions with the default read funcs.
void ILAPIENTRY iPreserveReadFuncs()
{
// Create backups
GetcProcCopy = GetcProc;
ReadProcCopy = ReadProc;
SeekProcCopy = SeekRProc;
TellProcCopy = TellRProc;
iopenCopy = iopenr;
icloseCopy = icloser;
// Set the standard procs to read
ilResetRead();
return;
}
// Restores the read functions - must be used after iPreserveReadFuncs().
void ILAPIENTRY iRestoreReadFuncs()
{
GetcProc = GetcProcCopy;
ReadProc = ReadProcCopy;
SeekRProc = SeekProcCopy;
TellRProc = TellProcCopy;
iopenr = iopenCopy;
icloser = icloseCopy;
return;
}
// Just preserves the current read functions and replaces
// the current read functions with the default read funcs.
void ILAPIENTRY iPreserveWriteFuncs()
{
// Create backups
PutcProcCopy = PutcProc;
SeekWProcCopy = SeekWProc;
TellWProcCopy = TellWProc;
WriteProcCopy = WriteProc;
iopenwCopy = iopenw;
iclosewCopy = iclosew;
// Set the standard procs to write
ilResetWrite();
return;
}
// Restores the read functions - must be used after iPreserveReadFuncs().
void ILAPIENTRY iRestoreWriteFuncs()
{
PutcProc = PutcProcCopy;
SeekWProc = SeekWProcCopy;
TellWProc = TellWProcCopy;
WriteProc = WriteProcCopy;
iopenw = iopenwCopy;
iclosew = iclosewCopy;
return;
}
// Next 7 functions are the default read functions
ILHANDLE ILAPIENTRY iDefaultOpenR(ILconst_string FileName)
{
#ifndef _UNICODE
return (ILHANDLE)fopen((char*)FileName, "rb");
#else
// Windows has a different function, _wfopen, to open UTF16 files,
// whereas Linux just uses fopen for its UTF8 files.
#ifdef _WIN32
return (ILHANDLE)_wfopen(FileName, L"rb");
#else
return (ILHANDLE)fopen((char*)FileName, "rb");
#endif
#endif//UNICODE
}
void ILAPIENTRY iDefaultCloseR(ILHANDLE Handle)
{
fclose((FILE*)Handle);
return;
}
ILboolean ILAPIENTRY iDefaultEof(ILHANDLE Handle)
{
ILuint OrigPos, FileSize;
// Find out the filesize for checking for the end of file
OrigPos = itell();
iseek(0, IL_SEEK_END);
FileSize = itell();
iseek(OrigPos, IL_SEEK_SET);
if (itell() >= FileSize)
return IL_TRUE;
return IL_FALSE;
}
ILint ILAPIENTRY iDefaultGetc(ILHANDLE Handle)
{
ILint Val;
if (!UseCache) {
Val = fgetc((FILE*)Handle);
if (Val == IL_EOF)
ilSetError(IL_FILE_READ_ERROR);
}
else {
Val = 0;
if (iread(&Val, 1, 1) != 1)
return IL_EOF;
}
return Val;
}
ILint ILAPIENTRY iDefaultRead(void *Buffer, ILuint Size, ILuint Number, ILHANDLE Handle)
{
return (ILint)fread(Buffer, Size, Number, (FILE*)Handle);
}
ILint ILAPIENTRY iDefaultRSeek(ILHANDLE Handle, ILint Offset, ILint Mode)
{
return fseek((FILE*)Handle, Offset, Mode);
}
ILint ILAPIENTRY iDefaultWSeek(ILHANDLE Handle, ILint Offset, ILint Mode)
{
return fseek((FILE*)Handle, Offset, Mode);
}
ILint ILAPIENTRY iDefaultRTell(ILHANDLE Handle)
{
return ftell((FILE*)Handle);
}
ILint ILAPIENTRY iDefaultWTell(ILHANDLE Handle)
{
return ftell((FILE*)Handle);
}
ILHANDLE ILAPIENTRY iDefaultOpenW(ILconst_string FileName)
{
#ifndef _UNICODE
return (ILHANDLE)fopen((char*)FileName, "wb");
#else
// Windows has a different function, _wfopen, to open UTF16 files,
// whereas Linux just uses fopen.
#ifdef _WIN32
return (ILHANDLE)_wfopen(FileName, L"wb");
#else
return (ILHANDLE)fopen((char*)FileName, "wb");
#endif
#endif//UNICODE
}
void ILAPIENTRY iDefaultCloseW(ILHANDLE Handle)
{
fclose((FILE*)Handle);
return;
}
ILint ILAPIENTRY iDefaultPutc(ILubyte Char, ILHANDLE Handle)
{
return fputc(Char, (FILE*)Handle);
}
ILint ILAPIENTRY iDefaultWrite(const void *Buffer, ILuint Size, ILuint Number, ILHANDLE Handle)
{
return (ILint)fwrite(Buffer, Size, Number, (FILE*)Handle);
}
void ILAPIENTRY ilResetRead()
{
ilSetRead(iDefaultOpenR, iDefaultCloseR, iDefaultEof, iDefaultGetc,
iDefaultRead, iDefaultRSeek, iDefaultRTell);
return;
}
void ILAPIENTRY ilResetWrite()
{
ilSetWrite(iDefaultOpenW, iDefaultCloseW, iDefaultPutc,
iDefaultWSeek, iDefaultWTell, iDefaultWrite);
return;
}
//! Allows you to override the default file-reading functions.
void ILAPIENTRY ilSetRead(fOpenRProc Open, fCloseRProc Close, fEofProc Eof, fGetcProc Getc, fReadProc Read, fSeekRProc Seek, fTellRProc Tell)
{
iopenr = Open;
icloser = Close;
EofProc = Eof;
GetcProc = Getc;
ReadProc = Read;
SeekRProc = Seek;
TellRProc = Tell;
return;
}
//! Allows you to override the default file-writing functions.
void ILAPIENTRY ilSetWrite(fOpenRProc Open, fCloseRProc Close, fPutcProc Putc, fSeekWProc Seek, fTellWProc Tell, fWriteProc Write)
{
iopenw = Open;
iclosew = Close;
PutcProc = Putc;
WriteProc = Write;
SeekWProc = Seek;
TellWProc = Tell;
return;
}
// Tells DevIL that we're reading from a file, not a lump
void iSetInputFile(ILHANDLE File)
{
ieof = iEofFile;
igetc = iGetcFile;
iread = iReadFile;
iseek = iSeekRFile;
itell = iTellRFile;
FileRead = File;
ReadFileStart = itell();
}
// Tells DevIL that we're reading from a lump, not a file
void iSetInputLump(const void *Lump, ILuint Size)
{
ieof = iEofLump;
igetc = iGetcLump;
iread = iReadLump;
iseek = iSeekRLump;
itell = iTellRLump;
ReadLump = Lump;
ReadLumpPos = 0;
ReadLumpSize = Size;
}
// Tells DevIL that we're writing to a file, not a lump
void iSetOutputFile(ILHANDLE File)
{
// Helps with ilGetLumpPos().
WriteLump = NULL;
WriteLumpPos = 0;
WriteLumpSize = 0;
iputc = iPutcFile;
iseekw = iSeekWFile;
itellw = iTellWFile;
iwrite = iWriteFile;
FileWrite = File;
}
// This is only called by ilDetermineSize. Associates iputc, etc. with
// "fake" writing functions in il_size.c.
void iSetOutputFake(void)
{
iputc = iSizePutc;
iseekw = iSizeSeek;
itellw = iSizeTell;
iwrite = iSizeWrite;
return;
}
// Tells DevIL that we're writing to a lump, not a file
void iSetOutputLump(void *Lump, ILuint Size)
{
// In this case, ilDetermineSize is currently trying to determine the
// output buffer size. It already has the write functions it needs.
if (Lump == NULL)
return;
iputc = iPutcLump;
iseekw = iSeekWLump;
itellw = iTellWLump;
iwrite = iWriteLump;
WriteLump = Lump;
WriteLumpPos = 0;
WriteLumpSize = Size;
}
ILuint ILAPIENTRY ilGetLumpPos()
{
if (WriteLump)
return WriteLumpPos;
return 0;
}
ILuint ILAPIENTRY ilprintf(const char *Line, ...)
{
char Buffer[2048]; // Hope this is large enough
va_list VaLine;
ILuint i;
va_start(VaLine, Line);
vsprintf(Buffer, Line, VaLine);
va_end(VaLine);
i = ilCharStrLen(Buffer);
iwrite(Buffer, 1, i);
return i;
}
// To pad zeros where needed...
void ipad(ILuint NumZeros)
{
ILuint i = 0;
for (; i < NumZeros; i++)
iputc(0);
return;
}
//
// The rest of the functions following in this file are quite
// self-explanatory, except where commented.
//
// Next 12 functions are the default write functions
ILboolean ILAPIENTRY iEofFile(void)
{
return EofProc((FILE*)FileRead);
}
ILboolean ILAPIENTRY iEofLump(void)
{
if (ReadLumpSize)
return (ReadLumpPos >= ReadLumpSize);
return IL_FALSE;
}
ILint ILAPIENTRY iGetcFile(void)
{
if (!UseCache) {
return GetcProc(FileRead);
}
if (CachePos >= CacheSize) {
iPreCache(CacheSize);
}
CacheBytesRead++;
return Cache[CachePos++];
}
ILint ILAPIENTRY iGetcLump(void)
{
// If ReadLumpSize is 0, don't even check to see if we've gone past the bounds.
if (ReadLumpSize > 0) {
if (ReadLumpPos + 1 > ReadLumpSize) {
ReadLumpPos--;
ilSetError(IL_FILE_READ_ERROR);
return IL_EOF;
}
}
return *((ILubyte*)ReadLump + ReadLumpPos++);
}
ILuint ILAPIENTRY iReadFile(void *Buffer, ILuint Size, ILuint Number)
{
ILuint TotalBytes = 0, BytesCopied;
ILuint BuffSize = Size * Number;
ILuint NumRead;
if (!UseCache) {
NumRead = ReadProc(Buffer, Size, Number, FileRead);
if (NumRead != Number)
ilSetError(IL_FILE_READ_ERROR);
return NumRead;
}
/*if (Cache == NULL || CacheSize == 0) { // Shouldn't happen, but we check anyway.
return ReadProc(Buffer, Size, Number, FileRead);
}*/
if (BuffSize < CacheSize - CachePos) {
memcpy(Buffer, Cache + CachePos, BuffSize);
CachePos += BuffSize;
CacheBytesRead += BuffSize;
if (Size != 0)
BuffSize /= Size;
return BuffSize;
}
else {
while (TotalBytes < BuffSize) {
// If loop through more than once, after first, CachePos is 0.
if (TotalBytes + CacheSize - CachePos > BuffSize)
BytesCopied = BuffSize - TotalBytes;
else
BytesCopied = CacheSize - CachePos;
memcpy((ILubyte*)Buffer + TotalBytes, Cache + CachePos, BytesCopied);
TotalBytes += BytesCopied;
CachePos += BytesCopied;
if (TotalBytes < BuffSize) {
iPreCache(CacheSize);
}
}
}
// DW: Changed on 12-27-2008. Was causing the position to go too far if the
// cache was smaller than the buffer.
//CacheBytesRead += TotalBytes;
CacheBytesRead = CachePos;
if (Size != 0)
TotalBytes /= Size;
if (TotalBytes != Number)
ilSetError(IL_FILE_READ_ERROR);
return TotalBytes;
}
ILuint ILAPIENTRY iReadLump(void *Buffer, const ILuint Size, const ILuint Number)
{
ILuint i, ByteSize = IL_MIN( Size*Number, ReadLumpSize-ReadLumpPos);
for (i = 0; i < ByteSize; i++) {
*((ILubyte*)Buffer + i) = *((ILubyte*)ReadLump + ReadLumpPos + i);
if (ReadLumpSize > 0) { // ReadLumpSize is too large to care about apparently
if (ReadLumpPos + i > ReadLumpSize) {
ReadLumpPos += i;
if (i != Number)
ilSetError(IL_FILE_READ_ERROR);
return i;
}
}
}
ReadLumpPos += i;
if (Size != 0)
i /= Size;
if (i != Number)
ilSetError(IL_FILE_READ_ERROR);
return i;
}
ILboolean iPreCache(ILuint Size)
{
// Reading from a memory lump, so don't cache.
if (iread == iReadLump) {
//iUnCache(); // DW: Removed 06-10-2002.
return IL_TRUE;
}
if (Cache) {
ifree(Cache);
}
if (Size == 0) {
Size = 1;
}
Cache = (ILubyte*)ialloc(Size);
if (Cache == NULL) {
return IL_FALSE;
}
UseCache = IL_FALSE;
CacheStartPos = itell();
CacheSize = iread(Cache, 1, Size);
if (CacheSize != Size)
ilGetError(); // Get rid of the IL_FILE_READ_ERROR.
//2003-09-09: uncommented the following line to prevent
//an infinite loop in ilPreCache()
CacheSize = Size;
CachePos = 0;
UseCache = IL_TRUE;
CacheBytesRead = 0;
return IL_TRUE;
}
void iUnCache()
{
//changed 2003-09-01:
//make iUnCache smart enough to return if
//no cache is used
if (!UseCache)
return;
if (iread == iReadLump)
return;
CacheSize = 0;
CachePos = 0;
if (Cache) {
ifree(Cache);
Cache = NULL;
}
UseCache = IL_FALSE;
iseek(CacheStartPos + CacheBytesRead, IL_SEEK_SET);
return;
}
ILint ILAPIENTRY iSeekRFile(ILint Offset, ILuint Mode)
{
if (Mode == IL_SEEK_SET)
Offset += ReadFileStart; // This allows us to use IL_SEEK_SET in the middle of a file.
return SeekRProc(FileRead, Offset, Mode);
}
// Returns 1 on error, 0 on success
ILint ILAPIENTRY iSeekRLump(ILint Offset, ILuint Mode)
{
switch (Mode)
{
case IL_SEEK_SET:
if (Offset > (ILint)ReadLumpSize)
return 1;
ReadLumpPos = Offset;
break;
case IL_SEEK_CUR:
if (ReadLumpPos + Offset > ReadLumpSize)
return 1;
ReadLumpPos += Offset;
break;
case IL_SEEK_END:
if (Offset > 0)
return 1;
// Should we use >= instead?
if (abs(Offset) > (ILint)ReadLumpSize) // If ReadLumpSize == 0, too bad
return 1;
ReadLumpPos = ReadLumpSize + Offset;
break;
default:
return 1;
}
return 0;
}
ILuint ILAPIENTRY iTellRFile(void)
{
return TellRProc(FileRead);
}
ILuint ILAPIENTRY iTellRLump(void)
{
return ReadLumpPos;
}
ILHANDLE ILAPIENTRY iGetFile(void)
{
return FileRead;
}
const ILubyte* ILAPIENTRY iGetLump(void) {
return (ILubyte*)ReadLump;
}
// Next 4 functions are the default write functions
ILint ILAPIENTRY iPutcFile(ILubyte Char)
{
return PutcProc(Char, FileWrite);
}
ILint ILAPIENTRY iPutcLump(ILubyte Char)
{
if (WriteLumpPos >= WriteLumpSize)
return IL_EOF; // IL_EOF
*((ILubyte*)(WriteLump) + WriteLumpPos++) = Char;
return Char;
}
ILint ILAPIENTRY iWriteFile(const void *Buffer, ILuint Size, ILuint Number)
{
ILuint NumWritten;
NumWritten = WriteProc(Buffer, Size, Number, FileWrite);
if (NumWritten != Number) {
ilSetError(IL_FILE_WRITE_ERROR);
return 0;
}
return NumWritten;
}
ILint ILAPIENTRY iWriteLump(const void *Buffer, ILuint Size, ILuint Number)
{
ILuint SizeBytes = Size * Number;
ILuint i = 0;
for (; i < SizeBytes; i++) {
if (WriteLumpSize > 0) {
if (WriteLumpPos + i >= WriteLumpSize) { // Should we use > instead?
ilSetError(IL_FILE_WRITE_ERROR);
WriteLumpPos += i;
return i;
}
}
*((ILubyte*)WriteLump + WriteLumpPos + i) = *((ILubyte*)Buffer + i);
}
WriteLumpPos += SizeBytes;
return SizeBytes;
}
ILint ILAPIENTRY iSeekWFile(ILint Offset, ILuint Mode)
{
if (Mode == IL_SEEK_SET)
Offset += WriteFileStart; // This allows us to use IL_SEEK_SET in the middle of a file.
return SeekWProc(FileWrite, Offset, Mode);
}
// Returns 1 on error, 0 on success
ILint ILAPIENTRY iSeekWLump(ILint Offset, ILuint Mode)
{
switch (Mode)
{
case IL_SEEK_SET:
if (Offset > (ILint)WriteLumpSize)
return 1;
WriteLumpPos = Offset;
break;
case IL_SEEK_CUR:
if (WriteLumpPos + Offset > WriteLumpSize)
return 1;
WriteLumpPos += Offset;
break;
case IL_SEEK_END:
if (Offset > 0)
return 1;
// Should we use >= instead?
if (abs(Offset) > (ILint)WriteLumpSize) // If WriteLumpSize == 0, too bad
return 1;
WriteLumpPos = WriteLumpSize + Offset;
break;
default:
return 1;
}
return 0;
}
ILuint ILAPIENTRY iTellWFile(void)
{
return TellWProc(FileWrite);
}
ILuint ILAPIENTRY iTellWLump(void)
{
return WriteLumpPos;
}
+472
View File
@@ -0,0 +1,472 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 02/14/2009
//
// Filename: src-IL/src/il_fits.c
//
// Description: Reads from a Flexible Image Transport System (.fits) file.
// Specifications were found at
// http://www.fileformat.info/format/fits.
//
//-----------------------------------------------------------------------------
#include "il_internal.h"
#ifndef IL_NO_FITS
typedef struct FITSHEAD
{
ILboolean IsSimple;
ILint BitsPixel;
ILint NumAxes; // Number of dimensions / axes
ILint Width;
ILint Height;
ILint Depth;
ILint NumChans;
// Not in the header, but it keeps everything together.
ILenum Type;
ILenum Format;
} FITSHEAD;
enum {
CARD_READ_FAIL = -1,
CARD_END = 1,
CARD_SIMPLE,
CARD_NOT_SIMPLE,
CARD_BITPIX,
CARD_NUMAXES,
CARD_AXIS,
CARD_SKIP
};
ILboolean iIsValidFits(void);
ILboolean iCheckFits(FITSHEAD *Header);
ILboolean iLoadFitsInternal(void);
ILenum GetCardImage(FITSHEAD *Header);
ILboolean GetCardInt(char *Buffer, ILint *Val);
//! Checks if the file specified in FileName is a valid FITS file.
ILboolean ilIsValidFits(ILconst_string FileName)
{
ILHANDLE FitsFile;
ILboolean bFits = IL_FALSE;
if (!iCheckExtension(FileName, IL_TEXT("fits")) && !iCheckExtension(FileName, IL_TEXT("fit"))) {
ilSetError(IL_INVALID_EXTENSION);
return bFits;
}
FitsFile = iopenr(FileName);
if (FitsFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bFits;
}
bFits = ilIsValidFitsF(FitsFile);
icloser(FitsFile);
return bFits;
}
//! Checks if the ILHANDLE contains a valid FITS file at the current position.
ILboolean ilIsValidFitsF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iIsValidFits();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Checks if Lump is a valid FITS lump.
ILboolean ilIsValidFitsL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iIsValidFits();
}
// Internal function used to get the FITS header from the current file.
ILboolean iGetFitsHead(FITSHEAD *Header)
{
ILenum CardKey;
//@TODO: Use something other than memset?
memset(Header, 0, sizeof(Header)); // Clear the header to all 0s first.
do {
CardKey = GetCardImage(Header);
if (CardKey == CARD_END) // End of the header
break;
if (CardKey == CARD_READ_FAIL)
return IL_FALSE;
if (CardKey == CARD_NOT_SIMPLE)
return IL_FALSE;
} while (!ieof());
// The header should never reach the end of the file.
if (ieof())
return IL_FALSE; // Error needed?
// The header must always be a multiple of 2880, so we skip the padding bytes (spaces).
iseek((2880 - (itell() % 2880)) % 2880, IL_SEEK_CUR);
switch (Header->BitsPixel)
{
case 8:
Header->Type = IL_UNSIGNED_BYTE;
break;
case 16:
Header->Type = IL_SHORT;
break;
case 32:
Header->Type = IL_INT;
break;
case -32:
Header->Type = IL_FLOAT;
break;
case -64:
Header->Type = IL_DOUBLE;
break;
default:
ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
}
switch (Header->NumAxes)
{
case 1: // Just a 1D image
Header->Format = IL_LUMINANCE;
Header->Height = 1;
Header->Depth = 1;
Header->NumChans = 1;
break;
case 2: // Assuming it is a 2D image (width+height)
Header->Format = IL_LUMINANCE;
Header->Depth = 1;
Header->NumChans = 1;
break;
case 3:
// We cannot deal with more than 3 channels in an image.
Header->Format = IL_LUMINANCE;
Header->NumChans = 1;
break;
default:
ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
}
return IL_TRUE;
}
// Internal function to get the header and check it.
ILboolean iIsValidFits(void)
{
FITSHEAD Header;
ILuint Pos = itell();
if (!iGetFitsHead(&Header))
return IL_FALSE;
// The length of the header varies, so we just go back to the original position.
iseek(Pos, IL_SEEK_CUR);
return iCheckFits(&Header);
}
// Internal function used to check if the HEADER is a valid FITS header.
ILboolean iCheckFits(FITSHEAD *Header)
{
switch (Header->BitsPixel)
{
case 8: // These are the only values accepted.
case 16:
case 32:
case -32:
case -64:
break;
default:
return IL_FALSE;
}
switch (Header->NumAxes)
{
case 1: // Just a 1D image
case 2: // Assuming it is a 2D image (width+height)
case 3: // 3D image (with depth)
break;
default:
return IL_FALSE;
}
// Possibility that one of these values is returned as <= 0 by atoi, which we cannot use.
if (Header->Width <= 0 || Header->Height <= 0 || Header->Depth <= 0) {
ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
}
return IL_TRUE;
}
//! Reads a FITS file
ILboolean ilLoadFits(ILconst_string FileName)
{
ILHANDLE FitsFile;
ILboolean bFits = IL_FALSE;
FitsFile = iopenr(FileName);
if (FitsFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bFits;
}
bFits = ilLoadFitsF(FitsFile);
icloser(FitsFile);
return bFits;
}
//! Reads an already-opened FITS file
ILboolean ilLoadFitsF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iLoadFitsInternal();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Reads from a memory "lump" that contains a FITS
ILboolean ilLoadFitsL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iLoadFitsInternal();
}
// Internal function used to load the FITS.
ILboolean iLoadFitsInternal(void)
{
FITSHEAD Header;
ILuint i, NumPix;
ILfloat MaxF = 0.0f;
ILdouble MaxD = 0.0f;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
if (!iGetFitsHead(&Header))
return IL_FALSE;
if (!iCheckFits(&Header))
return IL_FALSE;
if (!ilTexImage(Header.Width, Header.Height, Header.Depth, Header.NumChans, Header.Format, Header.Type, NULL))
return IL_FALSE;
/*if (iread(iCurImage->Data, 1, iCurImage->SizeOfData) != iCurImage->SizeOfData)
return IL_FALSE;*/
NumPix = Header.Width * Header.Height * Header.Depth;
//@TODO: Do some checks while reading to see if we have hit the end of the file.
switch (Header.Type)
{
case IL_UNSIGNED_BYTE:
if (iread(iCurImage->Data, 1, iCurImage->SizeOfData) != iCurImage->SizeOfData)
return IL_FALSE;
break;
case IL_SHORT:
for (i = 0; i < NumPix; i++) {
((ILshort*)iCurImage->Data)[i] = GetBigShort();
}
break;
case IL_INT:
for (i = 0; i < NumPix; i++) {
((ILint*)iCurImage->Data)[i] = GetBigInt();
}
break;
case IL_FLOAT:
for (i = 0; i < NumPix; i++) {
((ILfloat*)iCurImage->Data)[i] = GetBigFloat();
if (((ILfloat*)iCurImage->Data)[i] > MaxF)
MaxF = ((ILfloat*)iCurImage->Data)[i];
}
// Renormalize to [0..1].
for (i = 0; i < NumPix; i++) {
// Change all negative numbers to 0.
if (((ILfloat*)iCurImage->Data)[i] < 0.0f)
((ILfloat*)iCurImage->Data)[i] = 0.0f;
// Do the renormalization now, dividing by the maximum value.
((ILfloat*)iCurImage->Data)[i] = ((ILfloat*)iCurImage->Data)[i] / MaxF;
}
break;
case IL_DOUBLE:
for (i = 0; i < NumPix; i++) {
((ILdouble*)iCurImage->Data)[i] = GetBigDouble();
if (((ILdouble*)iCurImage->Data)[i] > MaxD)
MaxD = ((ILdouble*)iCurImage->Data)[i];
}
// Renormalize to [0..1].
for (i = 0; i < NumPix; i++) {
// Change all negative numbers to 0.
if (((ILdouble*)iCurImage->Data)[i] < 0.0f)
((ILdouble*)iCurImage->Data)[i] = 0.0f;
// Do the renormalization now, dividing by the maximum value.
((ILdouble*)iCurImage->Data)[i] = ((ILdouble*)iCurImage->Data)[i] / MaxD;
} break;
}
return ilFixImage();
}
//@TODO: NAXISx have to come in order. Check this!
ILenum GetCardImage(FITSHEAD *Header)
{
char Buffer[80];
if (iread(Buffer, 1, 80) != 80) // Each card image is exactly 80 bytes long.
return CARD_READ_FAIL;
//@TODO: Use something other than !strncmp?
if (!strncmp(Buffer, "END ", 4))
return CARD_END;
else if (!strncmp(Buffer, "SIMPLE ", 7)) {
// The true value 'T' is always in the 30th position.
if (Buffer[29] != 'T') {
// We cannot support FITS files that do not correspond to the standard.
Header->IsSimple = IL_FALSE; //@TODO: Does this even need to be set? Should exit loading anyway.
ilSetError(IL_FORMAT_NOT_SUPPORTED);
return CARD_NOT_SIMPLE;
}
Header->IsSimple = IL_TRUE;
return CARD_SIMPLE;
}
else if (!strncmp(Buffer, "BITPIX ", 7)) {
// The specs state that BITPIX has to come after SIMPLE.
if (Header->IsSimple != IL_TRUE) {
ilSetError(IL_INVALID_FILE_HEADER);
return CARD_READ_FAIL;
}
if (GetCardInt(Buffer, &Header->BitsPixel) != IL_TRUE)
return CARD_READ_FAIL;
//@TODO: Should I do this check from the calling function? Does it really matter?
if (Header->BitsPixel == 0) {
ilSetError(IL_FORMAT_NOT_SUPPORTED);
return CARD_READ_FAIL;
}
return CARD_BITPIX;
}
// Needs the space after NAXIS so that it does not get this confused with NAXIS1, NAXIS2, etc.
else if (!strncmp(Buffer, "NAXIS ", 6)) {
if (GetCardInt(Buffer, &Header->NumAxes) != IL_TRUE)
return CARD_READ_FAIL;
//@TODO: Should I do this check from the calling function? Does it really matter?
if (Header->NumAxes < 1 || Header->NumAxes > 3) {
ilSetError(IL_FORMAT_NOT_SUPPORTED);
return CARD_READ_FAIL;
}
return CARD_NUMAXES;
}
else if (!strncmp(Buffer, "NAXIS1 ", 7)) {
if (Header->NumAxes == 0) { // Has not been initialized, and it has to come first.
ilSetError(IL_INVALID_FILE_HEADER);
return CARD_READ_FAIL;
}
// First one will always be the width.
if (GetCardInt(Buffer, &Header->Width) != IL_TRUE)
return CARD_READ_FAIL;
return CARD_AXIS;
}
else if (!strncmp(Buffer, "NAXIS2 ", 7)) {
if (Header->NumAxes == 0) { // Has not been initialized, and it has to come first.
ilSetError(IL_INVALID_FILE_HEADER);
return CARD_READ_FAIL;
}
// Cannot have a 2nd axis for 0 or 1.
if (Header->NumAxes == 0 || Header->NumAxes == 1) {
ilSetError(IL_INVALID_FILE_HEADER);
return CARD_READ_FAIL;
}
//@TODO: We are assuming that this is the height right now. Could it just be a
// 1D image with multiple bytes per pixel?
if (GetCardInt(Buffer, &Header->Height) != IL_TRUE)
return CARD_READ_FAIL;
return CARD_AXIS;
}
else if (!strncmp(Buffer, "NAXIS3 ", 7)) {
if (Header->NumAxes == 0) { // Has not been initialized, and it has to come first.
ilSetError(IL_INVALID_FILE_HEADER);
return CARD_READ_FAIL;
}
// Cannot have a 3rd axis for 0, 1 and 2.
if (Header->NumAxes < 3) {
ilSetError(IL_INVALID_FILE_HEADER);
return CARD_READ_FAIL;
}
if (GetCardInt(Buffer, &Header->Depth) != IL_TRUE)
return CARD_READ_FAIL;
return CARD_AXIS;
}
return CARD_SKIP; // This is a card that we do not recognize, so skip it.
}
ILboolean GetCardInt(char *Buffer, ILint *Val)
{
ILuint i;
char ValString[22];
if (Buffer[7] != '=' && Buffer[8] != '=')
return IL_FALSE;
for (i = 9; i < 30; i++) {
if (Buffer[i] != ' ' && Buffer[i] != 0) // Right-aligned with ' ' or 0, so skip.
break;
}
if (i == 30) // Did not find the integer in positions 10 - 30.
return IL_FALSE;
//@TODO: Safest way to do this?
memcpy(ValString, &Buffer[i], 30-i);
ValString[30-i] = 0; // Terminate the string.
//@TODO: Check the return somehow?
*Val = atoi(ValString);
return IL_TRUE;
}
#endif//IL_NO_FITS
+101
View File
@@ -0,0 +1,101 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 02/12/2009
//
// Filename: src-IL/src/il_ftx.c
//
// Description: Reads from a Heavy Metal: FAKK2 (.ftx) file.
//
//-----------------------------------------------------------------------------
#include "il_internal.h"
#ifndef IL_NO_FTX
ILboolean iLoadFtxInternal(void);
//! Reads a FTX file
ILboolean ilLoadFtx(ILconst_string FileName)
{
ILHANDLE FtxFile;
ILboolean bFtx = IL_FALSE;
FtxFile = iopenr(FileName);
if (FtxFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bFtx;
}
bFtx = ilLoadFtxF(FtxFile);
icloser(FtxFile);
return bFtx;
}
//! Reads an already-opened FTX file
ILboolean ilLoadFtxF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iLoadFtxInternal();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Reads from a memory "lump" that contains a FTX
ILboolean ilLoadFtxL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iLoadFtxInternal();
}
// Internal function used to load the FTX.
ILboolean iLoadFtxInternal(void)
{
ILuint Width, Height, HasAlpha;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
Width = GetLittleUInt();
Height = GetLittleUInt();
HasAlpha = GetLittleUInt(); // Kind of backwards from what I would think...
//@TODO: Right now, it appears that all images are in RGBA format. See if I can find specs otherwise
// or images that load incorrectly like this.
//if (HasAlpha == 0) { // RGBA format
if (!ilTexImage(Width, Height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL))
return IL_FALSE;
//}
//else if (HasAlpha == 1) { // RGB format
// if (!ilTexImage(Width, Height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL))
// return IL_FALSE;
//}
//else { // Unknown format
// ilSetError(IL_INVALID_FILE_HEADER);
// return IL_FALSE;
//}
// The origin will always be in the upper left.
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
// All we have to do for this format is read the raw, uncompressed data.
if (iread(iCurImage->Data, 1, iCurImage->SizeOfData) != iCurImage->SizeOfData)
return IL_FALSE;
return ilFixImage();
}
#endif//IL_NO_FTX
+755
View File
@@ -0,0 +1,755 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2008 by Denton Woods
// Last modified: 03/07/2009
//
// Filename: src-IL/src/il_gif.c
//
// Description: Reads from a Graphics Interchange Format (.gif) file.
//
// The LZW decompression code is based on code released to the public domain
// by Javier Arevalo and can be found at
// http://www.programmersheaven.com/zone10/cat452
//
//-----------------------------------------------------------------------------
#include "il_internal.h"
#ifndef IL_NO_GIF
#include "il_gif.h"
ILenum GifType;
//! Checks if the file specified in FileName is a valid Gif file.
ILboolean ilIsValidGif(ILconst_string FileName)
{
ILHANDLE GifFile;
ILboolean bGif = IL_FALSE;
if (!iCheckExtension(FileName, IL_TEXT("gif"))) {
ilSetError(IL_INVALID_EXTENSION);
return bGif;
}
GifFile = iopenr(FileName);
if (GifFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bGif;
}
bGif = ilIsValidGifF(GifFile);
icloser(GifFile);
return bGif;
}
//! Checks if the ILHANDLE contains a valid Gif file at the current position.
ILboolean ilIsValidGifF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iIsValidGif();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Checks if Lump is a valid Gif lump.
ILboolean ilIsValidGifL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iIsValidGif();
}
// Internal function to get the header and check it.
ILboolean iIsValidGif()
{
char Header[6];
if (iread(Header, 1, 6) != 6)
return IL_FALSE;
iseek(-6, IL_SEEK_CUR);
if (!strnicmp(Header, "GIF87A", 6))
return IL_TRUE;
if (!strnicmp(Header, "GIF89A", 6))
return IL_TRUE;
return IL_FALSE;
}
//! Reads a Gif file
ILboolean ilLoadGif(ILconst_string FileName)
{
ILHANDLE GifFile;
ILboolean bGif = IL_FALSE;
GifFile = iopenr(FileName);
if (GifFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bGif;
}
bGif = ilLoadGifF(GifFile);
icloser(GifFile);
return bGif;
}
//! Reads an already-opened Gif file
ILboolean ilLoadGifF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iLoadGifInternal();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Reads from a memory "lump" that contains a Gif
ILboolean ilLoadGifL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iLoadGifInternal();
}
// Internal function used to load the Gif.
ILboolean iLoadGifInternal()
{
GIFHEAD Header;
ILpal GlobalPal;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
GlobalPal.Palette = NULL;
GlobalPal.PalSize = 0;
//read header
iread(&Header.Sig, 1, 6);
Header.Width = GetLittleUShort();
Header.Height = GetLittleUShort();
Header.ColourInfo = igetc();
Header.Background = igetc();
Header.Aspect = igetc();
if (!strnicmp(Header.Sig, "GIF87A", 6)) {
GifType = GIF87A;
}
else if (!strnicmp(Header.Sig, "GIF89A", 6)) {
GifType = GIF89A;
}
else {
ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
}
if (!ilTexImage(Header.Width, Header.Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL))
return IL_FALSE;
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
// Check for a global colour map.
if (Header.ColourInfo & (1 << 7)) {
if (!iGetPalette(Header.ColourInfo, &GlobalPal, IL_FALSE, NULL)) {
return IL_FALSE;
}
}
if (!GetImages(&GlobalPal, &Header))
return IL_FALSE;
if (GlobalPal.Palette && GlobalPal.PalSize)
ifree(GlobalPal.Palette);
GlobalPal.Palette = NULL;
GlobalPal.PalSize = 0;
return ilFixImage();
}
ILboolean iGetPalette(ILubyte Info, ILpal *Pal, ILboolean UsePrevPal, ILimage *PrevImage)
{
ILuint PalSize, PalOffset = 0;
// If we have a local palette and have to use the previous frame as well,
// we have to copy the palette from the previous frame, in addition
// to the data, which we copy in GetImages.
// The ld(palettes bpp - 1) is stored in the lower
// 3 bits of Info (weird gif format ... :) )
PalSize = (1 << ((Info & 0x7) + 1)) * 3;
if (UsePrevPal) {
if (PrevImage == NULL) { // Cannot use the previous palette if it does not exist.
ilSetError(IL_ILLEGAL_FILE_VALUE);
return IL_FALSE;
}
PalSize = PalSize + PrevImage->Pal.PalSize;
PalOffset = PrevImage->Pal.PalSize;
}
if (PalSize > 256 * 3) {
ilSetError(IL_ILLEGAL_FILE_VALUE);
return IL_FALSE;
}
Pal->PalSize = PalSize;
Pal->PalType = IL_PAL_RGB24;
//Pal->Palette = (ILubyte*)ialloc(Pal->PalSize);
Pal->Palette = (ILubyte*)ialloc(256 * 3);
if (Pal->Palette == NULL)
return IL_FALSE;
if (UsePrevPal)
memcpy(Pal->Palette, PrevImage->Pal.Palette, PrevImage->Pal.PalSize); // Copy the old palette over.
if (iread(Pal->Palette + PalOffset, 1, Pal->PalSize) != Pal->PalSize) { // Read the new palette.
ifree(Pal->Palette);
Pal->Palette = NULL;
return IL_FALSE;
}
return IL_TRUE;
}
ILboolean GetImages(ILpal *GlobalPal, GIFHEAD *GifHead)
{
IMAGEDESC ImageDesc, OldImageDesc;
GFXCONTROL Gfx;
ILboolean BaseImage = IL_TRUE;
ILimage *Image = iCurImage, *TempImage = NULL, *PrevImage = NULL;
ILuint NumImages = 0, i;
ILint input;
ILuint PalOffset;
OldImageDesc.ImageInfo = 0; // to initialize the data with an harmless value
Gfx.Used = IL_TRUE;
while (!ieof()) {
ILubyte DisposalMethod = 1;
i = itell();
if (!SkipExtensions(&Gfx))
goto error_clean;
i = itell();
if (!Gfx.Used)
DisposalMethod = (Gfx.Packed & 0x1C) >> 2;
//read image descriptor
ImageDesc.Separator = igetc();
if (ImageDesc.Separator != 0x2C) //end of image
break;
ImageDesc.OffX = GetLittleUShort();
ImageDesc.OffY = GetLittleUShort();
ImageDesc.Width = GetLittleUShort();
ImageDesc.Height = GetLittleUShort();
ImageDesc.ImageInfo = igetc();
if (ieof()) {
ilGetError(); // Gets rid of the IL_FILE_READ_ERROR that inevitably results.
break;
}
if (!BaseImage) {
NumImages++;
Image->Next = ilNewImage(iCurImage->Width, iCurImage->Height, 1, 1, 1);
if (Image->Next == NULL)
goto error_clean;
//20040612: DisposalMethod controls how the new images data is to be combined
//with the old image. 0 means that it doesn't matter how they are combined,
//1 means keep the old image, 2 means set to background color, 3 is
//load the image that was in place before the current (this is not implemented
//here! (TODO?))
if (DisposalMethod == 2 || DisposalMethod == 3)
//Note that this is actually wrong, too: If the image has a local
//color table, we should really search for the best fit of the
//background color table and use that index (?). Furthermore,
//we should only memset the part of the image that is not read
//later (if we are sure that no parts of the read image are transparent).
if (!Gfx.Used && Gfx.Packed & 0x1)
memset(Image->Next->Data, Gfx.Transparent, Image->SizeOfData);
else
memset(Image->Next->Data, GifHead->Background, Image->SizeOfData);
else if (DisposalMethod == 1 || DisposalMethod == 0)
memcpy(Image->Next->Data, Image->Data, Image->SizeOfData);
//Interlacing has to be removed after the image was copied (line above)
if (OldImageDesc.ImageInfo & (1 << 6)) { // Image is interlaced.
if (!RemoveInterlace(Image))
goto error_clean;
}
PrevImage = Image;
Image = Image->Next;
Image->Format = IL_COLOUR_INDEX;
Image->Origin = IL_ORIGIN_UPPER_LEFT;
} else {
BaseImage = IL_FALSE;
if (!Gfx.Used && Gfx.Packed & 0x1)
memset(Image->Data, Gfx.Transparent, Image->SizeOfData);
else
memset(Image->Data, GifHead->Background, Image->SizeOfData);
}
Image->OffX = ImageDesc.OffX;
Image->OffY = ImageDesc.OffY;
PalOffset = 0;
// Check to see if the image has its own palette.
if (ImageDesc.ImageInfo & (1 << 7)) {
ILboolean UsePrevPal = IL_FALSE;
if (DisposalMethod == 1 && NumImages != 0) { // Cannot be the first image for this.
PalOffset = PrevImage->Pal.PalSize;
UsePrevPal = IL_TRUE;
}
if (!iGetPalette(ImageDesc.ImageInfo, &Image->Pal, UsePrevPal, PrevImage)) {
goto error_clean;
}
} else {
if (!iCopyPalette(&Image->Pal, GlobalPal)) {
goto error_clean;
}
}
if (!GifGetData(Image, Image->Data + ImageDesc.OffX + ImageDesc.OffY*Image->Width, Image->SizeOfData,
ImageDesc.Width, ImageDesc.Height, Image->Width, PalOffset, &Gfx)) {
memset(Image->Data, 0, Image->SizeOfData); //@TODO: Remove this. For debugging purposes right now.
ilSetError(IL_ILLEGAL_FILE_VALUE);
goto error_clean;
}
// See if there was a valid graphics control extension.
if (!Gfx.Used) {
Gfx.Used = IL_TRUE;
Image->Duration = Gfx.Delay * 10; // We want it in milliseconds.
// See if a transparent colour is defined.
if (Gfx.Packed & 1) {
if (!ConvertTransparent(Image, Gfx.Transparent)) {
goto error_clean;
}
}
}
i = itell();
// Terminates each block.
if((input = igetc()) == IL_EOF)
goto error_clean;
if (input != 0x00)
iseek(-1, IL_SEEK_CUR);
// break;
OldImageDesc = ImageDesc;
}
//Deinterlace last image
if (OldImageDesc.ImageInfo & (1 << 6)) { // Image is interlaced.
if (!RemoveInterlace(Image))
goto error_clean;
}
if (BaseImage) // Was not able to load any images in...
return IL_FALSE;
return IL_TRUE;
error_clean:
Image = iCurImage->Next;
/* while (Image) {
TempImage = Image;
Image = Image->Next;
ilCloseImage(TempImage);
}*/
return IL_FALSE;
}
ILboolean SkipExtensions(GFXCONTROL *Gfx)
{
ILint Code;
ILint Label;
ILint Size;
// DW (06-03-2002): Apparently there can be...
//if (GifType == GIF87A)
// return IL_TRUE; // No extensions in the GIF87a format.
do {
if((Code = igetc()) == IL_EOF)
return IL_FALSE;
if (Code != 0x21) {
iseek(-1, IL_SEEK_CUR);
return IL_TRUE;
}
if((Label = igetc()) == IL_EOF)
return IL_FALSE;
switch (Label)
{
case 0xF9:
Gfx->Size = igetc();
Gfx->Packed = igetc();
Gfx->Delay = GetLittleUShort();
Gfx->Transparent = igetc();
Gfx->Terminator = igetc();
if (ieof())
return IL_FALSE;
Gfx->Used = IL_FALSE;
break;
/*case 0xFE:
break;
case 0x01:
break;*/
default:
do {
if((Size = igetc()) == IL_EOF)
return IL_FALSE;
iseek(Size, IL_SEEK_CUR);
} while (!ieof() && Size != 0);
}
// @TODO: Handle this better.
if (ieof()) {
ilSetError(IL_FILE_READ_ERROR);
return IL_FALSE;
}
} while (1);
return IL_TRUE;
}
#define MAX_CODES 4096
ILint curr_size, clear, ending, newcodes, top_slot, slot, navail_bytes = 0, nbits_left = 0;
ILubyte b1;
ILubyte byte_buff[257];
ILubyte *pbytes;
ILubyte *stack;
ILubyte *suffix;
ILshort *prefix;
ILboolean success;
ILuint code_mask[13] =
{
0L,
0x0001L, 0x0003L,
0x0007L, 0x000FL,
0x001FL, 0x003FL,
0x007FL, 0x00FFL,
0x01FFL, 0x03FFL,
0x07FFL, 0x0FFFL
};
ILint get_next_code(void) {
ILint i, t;
ILuint ret;
//20050102: Tests for IL_EOF were added because this function
//crashed sometimes if igetc() returned IL_EOF
//(for example "table-add-column-before-active.gif" included in the
//mozilla source package)
if (!nbits_left) {
if (navail_bytes <= 0) {
pbytes = byte_buff;
navail_bytes = igetc();
if(navail_bytes == IL_EOF) {
success = IL_FALSE;
return ending;
}
if (navail_bytes) {
for (i = 0; i < navail_bytes; i++) {
if((t = igetc()) == IL_EOF) {
success = IL_FALSE;
return ending;
}
byte_buff[i] = t;
}
}
}
b1 = *pbytes++;
nbits_left = 8;
navail_bytes--;
}
ret = b1 >> (8 - nbits_left);
while (curr_size > nbits_left) {
if (navail_bytes <= 0) {
pbytes = byte_buff;
navail_bytes = igetc();
if(navail_bytes == IL_EOF) {
success = IL_FALSE;
return ending;
}
if (navail_bytes) {
for (i = 0; i < navail_bytes; i++) {
if((t = igetc()) == IL_EOF) {
success = IL_FALSE;
return ending;
}
byte_buff[i] = t;
}
}
}
b1 = *pbytes++;
ret |= b1 << nbits_left;
nbits_left += 8;
navail_bytes--;
}
nbits_left -= curr_size;
return (ret & code_mask[curr_size]);
}
static void cleanUpGifLoadState()
{
ifree(stack);
ifree(suffix);
ifree(prefix);
}
ILboolean GifGetData(ILimage *Image, ILubyte *Data, ILuint ImageSize, ILuint Width, ILuint Height, ILuint Stride, ILuint PalOffset, GFXCONTROL *Gfx)
{
ILubyte *sp;
ILint code, fc, oc;
ILubyte DisposalMethod = 0;
ILint c, size;
ILuint i = 0, Read = 0, j = 0;
ILubyte *DataPtr = Data;
if (!Gfx->Used)
DisposalMethod = (Gfx->Packed & 0x1C) >> 2;
if((size = igetc()) == IL_EOF)
return IL_FALSE;
if (size < 2 || 9 < size) {
return IL_FALSE;
}
stack = (ILubyte*)ialloc(MAX_CODES + 1);
suffix = (ILubyte*)ialloc(MAX_CODES + 1);
prefix = (ILshort*)ialloc(sizeof(*prefix) * (MAX_CODES + 1));
if (!stack || !suffix || !prefix)
{
cleanUpGifLoadState();
return IL_FALSE;
}
curr_size = size + 1;
top_slot = 1 << curr_size;
clear = 1 << size;
ending = clear + 1;
slot = newcodes = ending + 1;
navail_bytes = nbits_left = 0;
oc = fc = 0;
sp = stack;
while ((c = get_next_code()) != ending && Read < Height) {
if (c == clear)
{
curr_size = size + 1;
slot = newcodes;
top_slot = 1 << curr_size;
while ((c = get_next_code()) == clear);
if (c == ending)
break;
if (c >= slot)
c = 0;
oc = fc = c;
if (DisposalMethod == 1 && !Gfx->Used && Gfx->Transparent == c && (Gfx->Packed & 0x1) != 0)
i++;
else if (i < Width)
DataPtr[i++] = c + PalOffset;
if (i == Width)
{
DataPtr += Stride;
i = 0;
Read += 1;
++j;
if (j >= Height) {
cleanUpGifLoadState();
return IL_FALSE;
}
}
}
else
{
code = c;
//BG-2007-01-10: several fixes for incomplete GIFs
if (code >= slot)
{
code = oc;
if (sp >= stack + MAX_CODES) {
cleanUpGifLoadState();
return IL_FALSE;
}
*sp++ = fc;
}
if (code >= MAX_CODES)
return IL_FALSE;
while (code >= newcodes)
{
if (sp >= stack + MAX_CODES)
{
cleanUpGifLoadState();
return IL_FALSE;
}
*sp++ = suffix[code];
code = prefix[code];
}
if (sp >= stack + MAX_CODES) {
cleanUpGifLoadState();
return IL_FALSE;
}
*sp++ = (ILbyte)code;
if (slot < top_slot)
{
fc = code;
suffix[slot] = fc;
prefix[slot++] = oc;
oc = c;
}
if (slot >= top_slot && curr_size < 12)
{
top_slot <<= 1;
curr_size++;
}
while (sp > stack)
{
sp--;
if (DisposalMethod == 1 && !Gfx->Used && Gfx->Transparent == *sp && (Gfx->Packed & 0x1) != 0)
i++;
else if (i < Width)
DataPtr[i++] = *sp + PalOffset;
if (i == Width)
{
i = 0;
Read += 1;
j = (j+1) % Height;
// Needs to start from Data, not Image->Data.
DataPtr = Data + j * Stride;
}
}
}
}
cleanUpGifLoadState();
return IL_TRUE;
}
/*From the GIF spec:
The rows of an Interlaced images are arranged in the following order:
Group 1 : Every 8th. row, starting with row 0. (Pass 1)
Group 2 : Every 8th. row, starting with row 4. (Pass 2)
Group 3 : Every 4th. row, starting with row 2. (Pass 3)
Group 4 : Every 2nd. row, starting with row 1. (Pass 4)
*/
ILboolean RemoveInterlace(ILimage *image)
{
ILubyte *NewData;
ILuint i, j = 0;
NewData = (ILubyte*)ialloc(image->SizeOfData);
if (NewData == NULL)
return IL_FALSE;
//changed 20041230: images with offsety != 0 were not
//deinterlaced correctly before...
for (i = 0; i < image->OffY; i++, j++) {
memcpy(&NewData[i * image->Bps], &image->Data[j * image->Bps], image->Bps);
}
for (i = 0 + image->OffY; i < image->Height; i += 8, j++) {
memcpy(&NewData[i * image->Bps], &image->Data[j * image->Bps], image->Bps);
}
for (i = 4 + image->OffY; i < image->Height; i += 8, j++) {
memcpy(&NewData[i * image->Bps], &image->Data[j * image->Bps], image->Bps);
}
for (i = 2 + image->OffY; i < image->Height; i += 4, j++) {
memcpy(&NewData[i * image->Bps], &image->Data[j * image->Bps], image->Bps);
}
for (i = 1 + image->OffY; i < image->Height; i += 2, j++) {
memcpy(&NewData[i * image->Bps], &image->Data[j * image->Bps], image->Bps);
}
ifree(image->Data);
image->Data = NewData;
return IL_TRUE;
}
// Uses the transparent colour index to make an alpha channel.
ILboolean ConvertTransparent(ILimage *Image, ILubyte TransColour)
{
ILubyte *Palette;
ILuint i, j;
if (!Image->Pal.Palette || !Image->Pal.PalSize) {
ilSetError(IL_INTERNAL_ERROR);
return IL_FALSE;
}
Palette = (ILubyte*)ialloc(Image->Pal.PalSize / 3 * 4);
if (Palette == NULL)
return IL_FALSE;
for (i = 0, j = 0; i < Image->Pal.PalSize; i += 3, j += 4) {
Palette[j ] = Image->Pal.Palette[i ];
Palette[j+1] = Image->Pal.Palette[i+1];
Palette[j+2] = Image->Pal.Palette[i+2];
if (j/4 == TransColour)
Palette[j+3] = 0x00;
else
Palette[j+3] = 0xFF;
}
ifree(Image->Pal.Palette);
Image->Pal.Palette = Palette;
Image->Pal.PalSize = Image->Pal.PalSize / 3 * 4;
Image->Pal.PalType = IL_PAL_RGBA32;
return IL_TRUE;
}
#endif //IL_NO_GIF
+659
View File
@@ -0,0 +1,659 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2008 by Denton Woods (this file by thakis / Denton)
// Last modified: 02/09/2009
//
// Filename: src-IL/src/il_hdr.c
//
// Description: Reads/writes a RADIANCE High Dynamic Range Image
//
//-----------------------------------------------------------------------------
#include "il_internal.h"
#ifndef IL_NO_HDR
#include "il_hdr.h"
#include "il_endian.h"
//! Checks if the file specified in FileName is a valid .hdr file.
ILboolean ilIsValidHdr(ILconst_string FileName)
{
ILHANDLE HdrFile;
ILboolean bHdr = IL_FALSE;
if (!iCheckExtension(FileName, IL_TEXT("hdr"))) {
ilSetError(IL_INVALID_EXTENSION);
return bHdr;
}
HdrFile = iopenr(FileName);
if (HdrFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bHdr;
}
bHdr = ilIsValidHdrF(HdrFile);
icloser(HdrFile);
return bHdr;
}
//! Checks if the ILHANDLE contains a valid .hdr file at the current position.
ILboolean ilIsValidHdrF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iIsValidHdr();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Checks if Lump is a valid .hdr lump.
ILboolean ilIsValidHdrL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iIsValidHdr();
}
// Internal function used to get the .hdr header from the current file.
ILboolean iGetHdrHead(HDRHEADER *Header)
{
ILboolean done = IL_FALSE;
char a, b;
char x[3], y[3]; //changed 20050217: added space for the '\0' char
char buff[81]; // 01-19-2009: Added space for the '\0'.
ILuint count = 0;
iread(Header->Signature, 1, 10);
//skip lines until an empty line is found.
//this marks the end of header information,
//the next line contains the image's dimension.
//TODO: read header contents into variables
//(EXPOSURE, orientation, xyz correction, ...)
if (iread(&a, 1, 1) != 1)
return IL_FALSE;
while (!done) {
if (iread(&b, 1, 1) != 1)
return IL_FALSE;
if (b == '\n' && a == '\n')
done = IL_TRUE;
else
a = b;
}
//read dimensions (note that this assumes a somewhat valid image)
if (iread(&a, 1, 1) != 1)
return IL_FALSE;
while (a != '\n') {
if (count >= 80) { // Line shouldn't be this long at all.
ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
}
buff[count] = a;
if (iread(&a, 1, 1) != 1)
return IL_FALSE;
++count;
}
buff[count] = '\0';
//note that this is not the 100% correct way to load hdr images:
//in a perfect world we would check if there's a +/- X/Y in front
//of width and heigth and mirror + rotate the image after decoding
//according to that. But HDRShop doesn't do that either (and that's
//my reference program :) ) and it's just a rotate and a mirror,
//nothing that really changes the appearance of the loaded image...
//(The code as it is now assumes that y contains "-Y" and x contains
//"+X" after the following line)
// The 2 has to be in the %s format specifier to prevent buffer overruns.
sscanf(buff, "%2s %d %2s %d", y, &Header->Height, x, &Header->Width);
return IL_TRUE;
}
// Internal function to get the header and check it.
ILboolean iIsValidHdr()
{
char Head[10];
ILint Read;
Read = iread(Head, 1, 10);
iseek(-Read, IL_SEEK_CUR); // Go ahead and restore to previous state
if (Read != 10)
return IL_FALSE;
return
strnicmp(Head, "#?RADIANCE", 10) == 0
|| strnicmp(Head, "#?RGBE", 6) == 0;
}
// Internal function used to check if the HEADER is a valid .hdr header.
ILboolean iCheckHdr(HDRHEADER *Header)
{
return
strnicmp(Header->Signature, "#?RADIANCE", 10) == 0
|| strnicmp(Header->Signature, "#?RGBE", 6) == 0;
}
//! Reads a .hdr file
ILboolean ilLoadHdr(ILconst_string FileName)
{
ILHANDLE HdrFile;
ILboolean bHdr = IL_FALSE;
HdrFile = iopenr(FileName);
if (HdrFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bHdr;
}
bHdr = ilLoadHdrF(HdrFile);
icloser(HdrFile);
return bHdr;
}
//! Reads an already-opened .hdr file
ILboolean ilLoadHdrF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iLoadHdrInternal();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Reads from a memory "lump" that contains a .hdr
ILboolean ilLoadHdrL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iLoadHdrInternal();
}
// Internal function used to load the .hdr.
ILboolean iLoadHdrInternal()
{
HDRHEADER Header;
ILfloat *data;
ILubyte *scanline;
ILuint i, j, e, r, g, b;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
if (!iGetHdrHead(&Header)) {
ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
}
if (!iCheckHdr(&Header)) {
//iseek(-(ILint)sizeof(HDRHEAD), IL_SEEK_CUR);
ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
}
// Update the current image with the new dimensions
if (!ilTexImage(Header.Width, Header.Height, 1, 3, IL_RGB, IL_FLOAT, NULL)) {
return IL_FALSE;
}
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
//read image data
if (iGetHint(IL_MEM_SPEED_HINT) == IL_FASTEST)
iPreCache(iCurImage->Width / 8 * iCurImage->Height);
data = (ILfloat*)iCurImage->Data;
scanline = (ILubyte*)ialloc(Header.Width*4);
for (i = 0; i < Header.Height; ++i) {
ReadScanline(scanline, Header.Width);
//convert hdrs internal format to floats
for (j = 0; j < 4*Header.Width; j += 4) {
ILuint *ee;
ILfloat t, *ff;
e = scanline[j + 3];
r = scanline[j + 0];
g = scanline[j + 1];
b = scanline[j + 2];
//t = (float)pow(2.f, ((ILint)e) - 128);
if (e != 0)
e = (e - 1) << 23;
// All this just to avoid stric-aliasing warnings...
// was: t = *(ILfloat*)&e
ee = &e;
ff = (ILfloat*)ee;
t = *ff;
data[0] = (r/255.0f)*t;
data[1] = (g/255.0f)*t;
data[2] = (b/255.0f)*t;
data += 3;
}
}
iUnCache();
ifree(scanline);
return ilFixImage();
}
void ReadScanline(ILubyte *scanline, ILuint w) {
ILubyte *runner;
ILuint r, g, b, e, read, shift;
r = igetc();
g = igetc();
b = igetc();
e = igetc();
//check if the scanline is in the new format
//if so, e, r, g, g are stored separated and are
//rle-compressed independently.
if (r == 2 && g == 2) {
ILuint length = (b << 8) | e;
ILuint j, t, k;
if (length > w)
length = w; //fix broken files
for (k = 0; k < 4; ++k) {
runner = scanline + k;
j = 0;
while (j < length) {
t = igetc();
if (t > 128) { //Run?
ILubyte val = igetc();
t &= 127;
//copy current byte
while (t > 0 && j < length) {
*runner = val;
runner += 4;
--t;
++j;
}
}
else { //No Run.
//read new bytes
while (t > 0 && j < length) {
*runner = igetc();
runner += 4;
--t;
++j;
}
}
}
}
return; //done decoding a scanline in separated format
}
//if we come here, we are dealing with old-style scanlines
shift = 0;
read = 0;
runner = scanline;
while (read < w) {
if (read != 0) {
r = igetc();
g = igetc();
b = igetc();
e = igetc();
}
//if all three mantissas are 1, then this is a rle
//count dword
if (r == 1 && g == 1 && b == 1) {
ILuint length = e;
ILuint j;
for (j = length << shift; j > 0 && read < w; --j) {
memcpy(runner, runner - 4, 4);
runner += 4;
++read;
}
//if more than one rle count dword is read
//consecutively, they are higher order bytes
//of the first read value. shift keeps track of
//that.
shift += 8;
}
else {
runner[0] = r;
runner[1] = g;
runner[2] = b;
runner[3] = e;
shift = 0;
runner += 4;
++read;
}
}
}
//! Writes a Hdr file
ILboolean ilSaveHdr(const ILstring FileName)
{
ILHANDLE HdrFile;
ILuint HdrSize;
if (ilGetBoolean(IL_FILE_MODE) == IL_FALSE) {
if (iFileExists(FileName)) {
ilSetError(IL_FILE_ALREADY_EXISTS);
return IL_FALSE;
}
}
HdrFile = iopenw(FileName);
if (HdrFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return IL_FALSE;
}
HdrSize = ilSaveHdrF(HdrFile);
iclosew(HdrFile);
if (HdrSize == 0)
return IL_FALSE;
return IL_TRUE;
}
//! Writes a Hdr to an already-opened file
ILuint ilSaveHdrF(ILHANDLE File)
{
ILuint Pos;
iSetOutputFile(File);
Pos = itellw();
if (iSaveHdrInternal() == IL_FALSE)
return 0; // Error occurred
return itellw() - Pos; // Return the number of bytes written.
}
//! Writes a Hdr to a memory "lump"
ILuint ilSaveHdrL(void *Lump, ILuint Size)
{
ILuint Pos;
iSetOutputLump(Lump, Size);
Pos = itellw();
if (iSaveHdrInternal() == IL_FALSE)
return 0; // Error occurred
return itellw() - Pos; // Return the number of bytes written.
}
//
// Much of the saving code is based on the code by Bruce Walter,
// available at http://www.graphics.cornell.edu/online/formats/rgbe/.
//
// The actual source code file is
// http://www.graphics.cornell.edu/online/formats/rgbe/rgbe.c
//
/* standard conversion from float pixels to rgbe pixels */
/* note: you can remove the "inline"s if your compiler complains about it */
//static INLINE void
static void
float2rgbe(unsigned char rgbe[4], float red, float green, float blue)
{
float v;
int e;
v = red;
if (green > v) v = green;
if (blue > v) v = blue;
if (v < 1e-32) {
rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0;
}
else {
v = (float)(frexp(v,&e) * 256.0/v);
rgbe[0] = (unsigned char) (red * v);
rgbe[1] = (unsigned char) (green * v);
rgbe[2] = (unsigned char) (blue * v);
rgbe[3] = (unsigned char) (e + 128);
}
}
typedef struct {
ILuint valid; /* indicate which fields are valid */
ILbyte programtype[16]; /* listed at beginning of file to identify it
* after "#?". defaults to "RGBE" */
ILfloat gamma; /* image has already been gamma corrected with
* given gamma. defaults to 1.0 (no correction) */
ILfloat exposure; /* a value of 1.0 in an image corresponds to
* <exposure> watts/steradian/m^2.
* defaults to 1.0 */
} rgbe_header_info;
/* flags indicating which fields in an rgbe_header_info are valid */
#define RGBE_VALID_PROGRAMTYPE 0x01
#define RGBE_VALID_GAMMA 0x02
#define RGBE_VALID_EXPOSURE 0x04
/* offsets to red, green, and blue components in a data (float) pixel */
#define RGBE_DATA_RED 0
#define RGBE_DATA_GREEN 1
#define RGBE_DATA_BLUE 2
/* number of floats per pixel */
#define RGBE_DATA_SIZE 3
/* default minimal header. modify if you want more information in header */
ILboolean RGBE_WriteHeader(ILuint width, ILuint height, rgbe_header_info *info)
{
char *programtype = "RGBE";
if (info && (info->valid & RGBE_VALID_PROGRAMTYPE))
programtype = info->programtype;
if (ilprintf("#?%s\n",programtype) < 0)
return IL_FALSE;
/* The #? is to identify file type, the programtype is optional. */
if (info && (info->valid & RGBE_VALID_GAMMA)) {
if (ilprintf("GAMMA=%g\n",info->gamma) < 0)
return IL_FALSE;
}
if (info && (info->valid & RGBE_VALID_EXPOSURE)) {
if (ilprintf("EXPOSURE=%g\n",info->exposure) < 0)
return IL_FALSE;
}
if (ilprintf("FORMAT=32-bit_rle_rgbe\n\n") < 0)
return IL_FALSE;
if (ilprintf("-Y %d +X %d\n", height, width) < 0)
return IL_FALSE;
return IL_TRUE;
}
/* simple write routine that does not use run length encoding */
/* These routines can be made faster by allocating a larger buffer and
fread-ing and iwrite-ing the data in larger chunks */
int RGBE_WritePixels(float *data, int numpixels)
{
unsigned char rgbe[4];
while (numpixels-- > 0) {
float2rgbe(rgbe,data[RGBE_DATA_RED],data[RGBE_DATA_GREEN],data[RGBE_DATA_BLUE]);
data += RGBE_DATA_SIZE;
if (iwrite(rgbe, sizeof(rgbe), 1) < 1)
return IL_FALSE;
}
return IL_TRUE;
}
/* The code below is only needed for the run-length encoded files. */
/* Run length encoding adds considerable complexity but does */
/* save some space. For each scanline, each channel (r,g,b,e) is */
/* encoded separately for better compression. */
ILboolean RGBE_WriteBytes_RLE(ILubyte *data, ILuint numbytes)
{
#define MINRUNLENGTH 4
ILuint cur, beg_run, run_count, old_run_count, nonrun_count;
ILubyte buf[2];
cur = 0;
while (cur < numbytes) {
beg_run = cur;
/* find next run of length at least 4 if one exists */
run_count = old_run_count = 0;
while((run_count < MINRUNLENGTH) && (beg_run < numbytes)) {
beg_run += run_count;
old_run_count = run_count;
run_count = 1;
// 01-25-2009: Moved test for beg_run + run_count first so that it is
// tested first. This keeps it from going out of bounds by 1.
while((beg_run + run_count < numbytes) && (run_count < 127) &&
(data[beg_run] == data[beg_run + run_count]))
run_count++;
}
/* if data before next big run is a short run then write it as such */
if ((old_run_count > 1)&&(old_run_count == beg_run - cur)) {
buf[0] = 128 + old_run_count; /*write short run*/
buf[1] = data[cur];
if (iwrite(buf,sizeof(buf[0])*2,1) < 1)
return IL_FALSE;
cur = beg_run;
}
/* write out bytes until we reach the start of the next run */
while(cur < beg_run) {
nonrun_count = beg_run - cur;
if (nonrun_count > 128)
nonrun_count = 128;
buf[0] = nonrun_count;
if (iwrite(buf,sizeof(buf[0]),1) < 1)
return IL_FALSE;
if (iwrite(&data[cur],sizeof(data[0])*nonrun_count,1) < 1)
return IL_FALSE;
cur += nonrun_count;
}
/* write out next run if one was found */
if (run_count >= MINRUNLENGTH) {
buf[0] = 128 + run_count;
buf[1] = data[beg_run];
if (iwrite(buf,sizeof(buf[0])*2,1) < 1)
return IL_FALSE;
cur += run_count;
}
}
return IL_TRUE;
#undef MINRUNLENGTH
}
// Internal function used to save the Hdr.
ILboolean iSaveHdrInternal()
{
ILimage *TempImage;
rgbe_header_info stHeader;
unsigned char rgbe[4];
ILubyte *buffer;
ILfloat *data;
ILuint i;
ILboolean bRet;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
stHeader.exposure = 0;
stHeader.gamma = 0;
stHeader.programtype[0] = 0;
stHeader.valid = 0;
if (iCurImage->Format != IL_UNSIGNED_BYTE) {
TempImage = iConvertImage(iCurImage, IL_RGB, IL_FLOAT);
if (TempImage == NULL)
return IL_FALSE;
}
else
TempImage = iCurImage;
if (!RGBE_WriteHeader(TempImage->Width, TempImage->Height, &stHeader))
return IL_FALSE;
if (TempImage->Origin == IL_ORIGIN_LOWER_LEFT)
iFlipBuffer(TempImage->Data, TempImage->Depth, TempImage->Bps, TempImage->Height);
data = (ILfloat*)TempImage->Data;
if ((TempImage->Width < 8)||(TempImage->Width > 0x7fff)) {
/* run length encoding is not allowed so write flat*/
bRet = RGBE_WritePixels(data,TempImage->Width*TempImage->Height);
if (iCurImage != TempImage)
ilCloseImage(TempImage);
return bRet;
}
buffer = (ILubyte*)ialloc(sizeof(ILubyte)*4*TempImage->Width);
if (buffer == NULL) {
/* no buffer space so write flat */
bRet = RGBE_WritePixels(data,TempImage->Width*TempImage->Height);
if (iCurImage != TempImage)
ilCloseImage(TempImage);
return bRet;
}
while(TempImage->Height-- > 0) {
rgbe[0] = 2;
rgbe[1] = 2;
rgbe[2] = TempImage->Width >> 8;
rgbe[3] = TempImage->Width & 0xFF;
if (iwrite(rgbe, sizeof(rgbe), 1) < 1) {
free(buffer);
if (iCurImage != TempImage)
ilCloseImage(TempImage);
return IL_FALSE;
}
for(i=0;i<TempImage->Width;i++) {
float2rgbe(rgbe,data[RGBE_DATA_RED],data[RGBE_DATA_GREEN],data[RGBE_DATA_BLUE]);
buffer[i] = rgbe[0];
buffer[i+TempImage->Width] = rgbe[1];
buffer[i+2*TempImage->Width] = rgbe[2];
buffer[i+3*TempImage->Width] = rgbe[3];
data += RGBE_DATA_SIZE;
}
/* write out each of the four channels separately run length encoded */
/* first red, then green, then blue, then exponent */
for(i=0;i<4;i++) {
if (RGBE_WriteBytes_RLE(&buffer[i*TempImage->Width],TempImage->Width) != IL_TRUE) {
ifree(buffer);
if (iCurImage != TempImage)
ilCloseImage(TempImage);
return IL_FALSE;
}
}
}
ifree(buffer);
if (iCurImage != TempImage)
ilCloseImage(TempImage);
return IL_TRUE;
}
#endif//IL_NO_HDR
+135
View File
@@ -0,0 +1,135 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2008 by Denton Woods
// Last modified: 10/10/2006
//
// Filename: src-IL/src/il_header.c
//
// Description: Generates a C-style header file for the current image.
//
//-----------------------------------------------------------------------------
#ifndef IL_NO_CHEAD
#include "il_internal.h"
// Just a guess...let's see what's purty!
#define MAX_LINE_WIDTH 14
//! Generates a C-style header file for the current image.
ILboolean ilSaveCHeader(ILconst_string FileName, char *InternalName)
{
FILE *HeadFile;
ILuint i = 0, j;
ILimage *TempImage;
const char *Name;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
Name = iGetString(IL_CHEAD_HEADER_STRING);
if (Name == NULL)
Name = InternalName;
if (FileName == NULL || Name == NULL ||
ilStrLen(FileName) < 1 || ilCharStrLen(Name) < 1) {
ilSetError(IL_INVALID_VALUE);
return IL_FALSE;
}
if (!iCheckExtension(FileName, IL_TEXT("h"))) {
ilSetError(IL_INVALID_EXTENSION);
return IL_FALSE;
}
if (ilGetBoolean(IL_FILE_MODE) == IL_FALSE) {
if (iFileExists(FileName)) {
ilSetError(IL_FILE_ALREADY_EXISTS);
return IL_FALSE;
}
}
if (iCurImage->Bpc > 1) {
TempImage = iConvertImage(iCurImage, iCurImage->Format, IL_UNSIGNED_BYTE);
if (TempImage == NULL)
return IL_FALSE;
} else {
TempImage = iCurImage;
}
#ifndef _UNICODE
HeadFile = fopen(FileName, "wb");
#else
#ifdef _WIN32
HeadFile = _wfopen(FileName, L"rb");
#else
HeadFile = fopen((char*)FileName, "rb");
#endif
#endif//_UNICODE
if (HeadFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return IL_FALSE;
}
fprintf(HeadFile, "//#include <il/il.h>\n");
fprintf(HeadFile, "// C Image Header:\n\n\n");
fprintf(HeadFile, "// IMAGE_BPP is in bytes per pixel, *not* bits\n");
fprintf(HeadFile, "#define IMAGE_BPP %d\n",iCurImage->Bpp);
fprintf(HeadFile, "#define IMAGE_WIDTH %d\n", iCurImage->Width);
fprintf(HeadFile, "#define IMAGE_HEIGHT %d\n", iCurImage->Height);
fprintf(HeadFile, "#define IMAGE_DEPTH %d\n\n\n", iCurImage->Depth);
fprintf(HeadFile, "#define IMAGE_TYPE 0x%X\n", iCurImage->Type);
fprintf(HeadFile, "#define IMAGE_FORMAT 0x%X\n\n\n", iCurImage->Format);
fprintf(HeadFile, "ILubyte %s[] = {\n", Name);
for (; i < TempImage->SizeOfData; i += MAX_LINE_WIDTH) {
fprintf(HeadFile, "\t");
for (j = 0; j < MAX_LINE_WIDTH; j++) {
if (i + j >= TempImage->SizeOfData - 1) {
fprintf(HeadFile, "%4d", TempImage->Data[i+j]);
break;
}
else
fprintf(HeadFile, "%4d,", TempImage->Data[i+j]);
}
fprintf(HeadFile, "\n");
}
if (TempImage != iCurImage)
ilCloseImage(TempImage);
fprintf(HeadFile, "};\n");
if (iCurImage->Pal.Palette && iCurImage->Pal.PalSize && iCurImage->Pal.PalType != IL_PAL_NONE) {
fprintf(HeadFile, "\n\n");
fprintf(HeadFile, "#define IMAGE_PALSIZE %u\n\n", iCurImage->Pal.PalSize);
fprintf(HeadFile, "#define IMAGE_PALTYPE 0x%X\n\n", iCurImage->Pal.PalType);
fprintf(HeadFile, "ILubyte %sPal[] = {\n", Name);
for (i = 0; i < iCurImage->Pal.PalSize; i += MAX_LINE_WIDTH) {
fprintf(HeadFile, "\t");
for (j = 0; j < MAX_LINE_WIDTH; j++) {
if (i + j >= iCurImage->Pal.PalSize - 1) {
fprintf(HeadFile, " %4d", iCurImage->Pal.Palette[i+j]);
break;
}
else
fprintf(HeadFile, " %4d,", iCurImage->Pal.Palette[i+j]);
}
fprintf(HeadFile, "\n");
}
fprintf(HeadFile, "};\n");
}
fclose(HeadFile);
return IL_TRUE;
}
#endif//IL_NO_CHEAD
+362
View File
@@ -0,0 +1,362 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2001-2009 by Denton Woods
// Last modified: 03/07/2009
//
// Filename: src-IL/src/il_icns.c
//
// Description: Reads from a Mac OS X icon (.icns) file.
// Credit for the format of .icns files goes to
// http://www.macdisk.com/maciconen.php3 and
// http://ezix.org/project/wiki/MacOSXIcons
//
//-----------------------------------------------------------------------------
//@TODO: Put ilSetError calls in when errors occur.
//@TODO: Should we clear the alpha channel just in case there isn't one in the file?
//@TODO: Checks on iread
#include "il_internal.h"
#ifndef IL_NO_ICNS
#include "il_icns.h"
#ifndef IL_NO_JP2
#if defined(_WIN32) && defined(IL_USE_PRAGMA_LIBS)
#if defined(_MSC_VER) || defined(__BORLANDC__)
#ifndef _DEBUG
#pragma comment(lib, "libjasper.lib")
#else
#pragma comment(lib, "libjasper-d.lib")
#endif
#endif
#endif
#endif//IL_NO_JP2
//! Checks if the file specified in FileName is a valid .icns file.
ILboolean ilIsValidIcns(ILconst_string FileName)
{
ILHANDLE IcnsFile;
ILboolean bIcns = IL_FALSE;
if (!iCheckExtension(FileName, IL_TEXT("icns"))) {
ilSetError(IL_INVALID_EXTENSION);
return bIcns;
}
IcnsFile = iopenr(FileName);
if (IcnsFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bIcns;
}
bIcns = ilIsValidIcnsF(IcnsFile);
icloser(IcnsFile);
return bIcns;
}
//! Checks if the ILHANDLE contains a valid .icns file at the current position.
ILboolean ilIsValidIcnsF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iIsValidIcns();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Checks if Lump is a valid .icns lump.
ILboolean ilIsValidIcnsL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iIsValidIcns();
}
// Internal function to get the header and check it.
ILboolean iIsValidIcns()
{
ICNSHEAD Header;
iread(Header.Head, 1, 4);
iseek(-4, IL_SEEK_CUR); // Go ahead and restore to previous state
if (strncmp(Header.Head, "icns", 4)) // First 4 bytes have to be 'icns'.
return IL_FALSE;
return IL_TRUE;
}
//! Reads an icon file.
ILboolean ilLoadIcns(ILconst_string FileName)
{
ILHANDLE IcnsFile;
ILboolean bIcns = IL_FALSE;
IcnsFile = iopenr(FileName);
if (IcnsFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bIcns;
}
bIcns = ilLoadIcnsF(IcnsFile);
icloser(IcnsFile);
return bIcns;
}
//! Reads an already-opened icon file.
ILboolean ilLoadIcnsF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iLoadIcnsInternal();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Reads from a memory "lump" that contains an icon.
ILboolean ilLoadIcnsL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iLoadIcnsInternal();
}
// Internal function used to load the icon.
ILboolean iLoadIcnsInternal()
{
ICNSHEAD Header;
ICNSDATA Entry;
ILimage *Image = NULL;
ILboolean BaseCreated = IL_FALSE;
if (iCurImage == NULL)
{
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
iread(Header.Head, 4, 1);
Header.Size = GetBigInt();
if (strncmp(Header.Head, "icns", 4)) // First 4 bytes have to be 'icns'.
return IL_FALSE;
while ((ILint)itell() < Header.Size && !ieof())
{
iread(Entry.ID, 4, 1);
Entry.Size = GetBigInt();
if (!strncmp(Entry.ID, "it32", 4)) // 128x128 24-bit
{
if (iIcnsReadData(&BaseCreated, IL_FALSE, 128, &Entry, &Image) == IL_FALSE)
goto icns_error;
}
else if (!strncmp(Entry.ID, "t8mk", 4)) // 128x128 alpha mask
{
if (iIcnsReadData(&BaseCreated, IL_TRUE, 128, &Entry, &Image) == IL_FALSE)
goto icns_error;
}
else if (!strncmp(Entry.ID, "ih32", 4)) // 48x48 24-bit
{
if (iIcnsReadData(&BaseCreated, IL_FALSE, 48, &Entry, &Image) == IL_FALSE)
goto icns_error;
}
else if (!strncmp(Entry.ID, "h8mk", 4)) // 48x48 alpha mask
{
if (iIcnsReadData(&BaseCreated, IL_TRUE, 48, &Entry, &Image) == IL_FALSE)
goto icns_error;
}
else if (!strncmp(Entry.ID, "il32", 4)) // 32x32 24-bit
{
if (iIcnsReadData(&BaseCreated, IL_FALSE, 32, &Entry, &Image) == IL_FALSE)
goto icns_error;
}
else if (!strncmp(Entry.ID, "l8mk", 4)) // 32x32 alpha mask
{
if (iIcnsReadData(&BaseCreated, IL_TRUE, 32, &Entry, &Image) == IL_FALSE)
goto icns_error;
}
else if (!strncmp(Entry.ID, "is32", 4)) // 16x16 24-bit
{
if (iIcnsReadData(&BaseCreated, IL_FALSE, 16, &Entry, &Image) == IL_FALSE)
goto icns_error;
}
else if (!strncmp(Entry.ID, "s8mk", 4)) // 16x16 alpha mask
{
if (iIcnsReadData(&BaseCreated, IL_TRUE, 16, &Entry, &Image) == IL_FALSE)
goto icns_error;
}
#ifndef IL_NO_JP2
else if (!strncmp(Entry.ID, "ic09", 4)) // 512x512 JPEG2000 encoded - Uses JasPer
{
if (iIcnsReadData(&BaseCreated, IL_FALSE, 512, &Entry, &Image) == IL_FALSE)
goto icns_error;
}
else if (!strncmp(Entry.ID, "ic08", 4)) // 256x256 JPEG2000 encoded - Uses JasPer
{
if (iIcnsReadData(&BaseCreated, IL_FALSE, 256, &Entry, &Image) == IL_FALSE)
goto icns_error;
}
#endif//IL_NO_JP2
else // Not a valid format or one that we can use
{
iseek(Entry.Size - 8, IL_SEEK_CUR);
}
}
return ilFixImage();
icns_error:
return IL_FALSE;
}
ILboolean iIcnsReadData(ILboolean *BaseCreated, ILboolean IsAlpha, ILint Width, ICNSDATA *Entry, ILimage **Image)
{
ILint Position = 0, RLEPos = 0, Channel, i;
ILubyte RLERead, *Data = NULL;
ILimage *TempImage = NULL;
ILboolean ImageAlreadyExists = IL_FALSE;
// The .icns format stores the alpha and RGB as two separate images, so this
// checks to see if one exists for that particular size. Unfortunately,
// there is no guarantee that they are in any particular order.
if (*BaseCreated && iCurImage != NULL)
{
TempImage = iCurImage;
while (TempImage != NULL)
{
if ((ILuint)Width == TempImage->Width)
{
ImageAlreadyExists = IL_TRUE;
break;
}
TempImage = TempImage->Next;
}
}
Data = ialloc(Entry->Size - 8);
if (Data == NULL)
return IL_FALSE;
if (!ImageAlreadyExists)
{
if (!*BaseCreated) // Create base image
{
ilTexImage(Width, Width, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL);
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
*Image = iCurImage;
*BaseCreated = IL_TRUE;
}
else // Create next image in list
{
(*Image)->Next = ilNewImage(Width, Width, 1, 4, 1);
*Image = (*Image)->Next;
(*Image)->Format = IL_RGBA;
(*Image)->Origin = IL_ORIGIN_UPPER_LEFT;
}
TempImage = *Image;
}
if (IsAlpha) // Alpha is never compressed.
{
iread(Data, Entry->Size - 8, 1); // Size includes the header
if (Entry->Size - 8 != Width * Width)
{
ifree(Data);
return IL_FALSE;
}
for (i = 0; i < Width * Width; i++)
{
TempImage->Data[(i * 4) + 3] = Data[i];
}
}
else if (Width == 256 || Width == 512) // JPEG2000 encoded - uses JasPer
{
#ifndef IL_NO_JP2
iread(Data, Entry->Size - 8, 1); // Size includes the header
if (ilLoadJp2LInternal(Data, Entry->Size - 8, TempImage) == IL_FALSE)
{
ifree(Data);
ilSetError(IL_LIB_JP2_ERROR);
return IL_TRUE;
}
#else // Cannot handle this size.
ilSetError(IL_LIB_JP2_ERROR); //@TODO: Handle this better...just skip the data.
return IL_FALSE;
#endif//IL_NO_JP2
}
else // RGB data
{
iread(Data, Entry->Size - 8, 1); // Size includes the header
if (Width == 128)
RLEPos += 4; // There are an extra 4 bytes here of zeros.
//@TODO: Should we check to make sure they are all 0?
if (Entry->Size - 8 == Width * Width * 4) // Uncompressed
{
//memcpy(TempImage->Data, Data, Entry->Size);
for (i = 0; i < Width * Width; i++, Position += 4)
{
TempImage->Data[i * 4 + 0] = Data[Position+1];
TempImage->Data[i * 4 + 1] = Data[Position+2];
TempImage->Data[i * 4 + 2] = Data[Position+3];
}
}
else // RLE decoding
{
for (Channel = 0; Channel < 3; Channel++)
{
Position = 0;
while (Position < Width * Width)
{
RLERead = Data[RLEPos];
RLEPos++;
if (RLERead >= 128)
{
for (i = 0; i < RLERead - 125 && (Position + i) < Width * Width; i++)
{
TempImage->Data[Channel + (Position + i) * 4] = Data[RLEPos];
}
RLEPos++;
Position += RLERead - 125;
}
else
{
for (i = 0; i < RLERead + 1 && (Position + i) < Width * Width; i++)
{
TempImage->Data[Channel + (Position + i) * 4] = Data[RLEPos + i];
}
RLEPos += RLERead + 1;
Position += RLERead + 1;
}
}
}
}
}
ifree(Data);
return IL_TRUE;
}
#endif//IL_NO_ICNS
+674
View File
@@ -0,0 +1,674 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2001-2009 by Denton Woods
// Last modified: 03/07/2009
//
// Filename: src-IL/src/il_icon.c
//
// Description: Reads from a Windows icon (.ico) file.
//
//-----------------------------------------------------------------------------
#include "il_internal.h"
#ifndef IL_NO_ICO
#include "il_icon.h"
#ifndef IL_NO_PNG
#include <png.h>
#endif
//! Reads an icon file.
ILboolean ilLoadIcon(ILconst_string FileName)
{
ILHANDLE IconFile;
ILboolean bIcon = IL_FALSE;
IconFile = iopenr(FileName);
if (IconFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bIcon;
}
bIcon = ilLoadIconF(IconFile);
icloser(IconFile);
return bIcon;
}
//! Reads an already-opened icon file.
ILboolean ilLoadIconF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iLoadIconInternal();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Reads from a memory "lump" that contains an icon.
ILboolean ilLoadIconL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iLoadIconInternal();
}
// Internal function used to load the icon.
ILboolean iLoadIconInternal()
{
ICODIR IconDir;
ICODIRENTRY *DirEntries = NULL;
ICOIMAGE *IconImages = NULL;
ILimage *Image = NULL;
ILint i;
ILuint Size, PadSize, ANDPadSize, j, k, l, m, x, w, CurAndByte, AndBytes;
ILboolean BaseCreated = IL_FALSE;
ILubyte PNGTest[3];
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
IconDir.Reserved = GetLittleShort();
IconDir.Type = GetLittleShort();
IconDir.Count = GetLittleShort();
if (ieof())
goto file_read_error;
DirEntries = (ICODIRENTRY*)ialloc(sizeof(ICODIRENTRY) * IconDir.Count);
IconImages = (ICOIMAGE*)ialloc(sizeof(ICOIMAGE) * IconDir.Count);
if (DirEntries == NULL || IconImages == NULL) {
ifree(DirEntries);
ifree(IconImages);
return IL_FALSE;
}
// Make it easier for file_read_error.
for (i = 0; i < IconDir.Count; i++)
imemclear(&IconImages[i], sizeof(ICOIMAGE));
for (i = 0; i < IconDir.Count; ++i) {
DirEntries[i].Width = (ILubyte)igetc();
DirEntries[i].Height = (ILubyte)igetc();
DirEntries[i].NumColours = (ILubyte)igetc();
DirEntries[i].Reserved = (ILubyte)igetc();
DirEntries[i].Planes = GetLittleShort();
DirEntries[i].Bpp = GetLittleShort();
DirEntries[i].SizeOfData = GetLittleUInt();
DirEntries[i].Offset = GetLittleUInt();
if (ieof())
goto file_read_error;
}
for (i = 0; i < IconDir.Count; i++) {
iseek(DirEntries[i].Offset, IL_SEEK_SET);
// 08-22-2008: Adding test for compressed PNG data
igetc(); // Skip the first character...seems to vary.
iread(PNGTest, 3, 1);
if (!strnicmp((char*)PNGTest, "PNG", 3)) // Characters 'P', 'N', 'G' for PNG header
{
#ifdef IL_NO_PNG
ilSetError(IL_FORMAT_NOT_SUPPORTED); // Cannot handle these without libpng.
goto file_read_error;
#else
iseek(DirEntries[i].Offset, IL_SEEK_SET);
if (!iLoadIconPNG(&IconImages[i]))
goto file_read_error;
#endif
}
else
{
// Need to go back the 4 bytes that were just read.
iseek(DirEntries[i].Offset, IL_SEEK_SET);
IconImages[i].Head.Size = GetLittleInt();
IconImages[i].Head.Width = GetLittleInt();
IconImages[i].Head.Height = GetLittleInt();
IconImages[i].Head.Planes = GetLittleShort();
IconImages[i].Head.BitCount = GetLittleShort();
IconImages[i].Head.Compression = GetLittleInt();
IconImages[i].Head.SizeImage = GetLittleInt();
IconImages[i].Head.XPixPerMeter = GetLittleInt();
IconImages[i].Head.YPixPerMeter = GetLittleInt();
IconImages[i].Head.ColourUsed = GetLittleInt();
IconImages[i].Head.ColourImportant = GetLittleInt();
if (ieof())
goto file_read_error;
if (IconImages[i].Head.BitCount < 8) {
if (IconImages[i].Head.ColourUsed == 0) {
switch (IconImages[i].Head.BitCount)
{
case 1:
IconImages[i].Head.ColourUsed = 2;
break;
case 4:
IconImages[i].Head.ColourUsed = 16;
break;
}
}
IconImages[i].Pal = (ILubyte*)ialloc(IconImages[i].Head.ColourUsed * 4);
if (IconImages[i].Pal == NULL)
goto file_read_error; // @TODO: Rename the label.
if (iread(IconImages[i].Pal, IconImages[i].Head.ColourUsed * 4, 1) != 1)
goto file_read_error;
}
else if (IconImages[i].Head.BitCount == 8) {
IconImages[i].Pal = (ILubyte*)ialloc(256 * 4);
if (IconImages[i].Pal == NULL)
goto file_read_error;
if (iread(IconImages[i].Pal, 1, 256 * 4) != 256*4)
goto file_read_error;
}
else {
IconImages[i].Pal = NULL;
}
PadSize = (4 - ((IconImages[i].Head.Width*IconImages[i].Head.BitCount + 7) / 8) % 4) % 4; // Has to be DWORD-aligned.
ANDPadSize = (4 - ((IconImages[i].Head.Width + 7) / 8) % 4) % 4; // AND is 1 bit/pixel
Size = ((IconImages[i].Head.Width*IconImages[i].Head.BitCount + 7) / 8 + PadSize)
* (IconImages[i].Head.Height / 2);
IconImages[i].Data = (ILubyte*)ialloc(Size);
if (IconImages[i].Data == NULL)
goto file_read_error;
if (iread(IconImages[i].Data, 1, Size) != Size)
goto file_read_error;
Size = (((IconImages[i].Head.Width + 7) /8) + ANDPadSize) * (IconImages[i].Head.Height / 2);
IconImages[i].AND = (ILubyte*)ialloc(Size);
if (IconImages[i].AND == NULL)
goto file_read_error;
if (iread(IconImages[i].AND, 1, Size) != Size)
goto file_read_error;
}
}
for (i = 0; i < IconDir.Count; i++) {
if (IconImages[i].Head.BitCount != 1 && IconImages[i].Head.BitCount != 4 &&
IconImages[i].Head.BitCount != 8 && IconImages[i].Head.BitCount != 24 &&
IconImages[i].Head.BitCount != 32)
continue;
if (!BaseCreated) {
if (IconImages[i].Head.Size == 0) // PNG compressed icon
ilTexImage(IconImages[i].Head.Width, IconImages[i].Head.Height, 1, 4, IL_BGRA, IL_UNSIGNED_BYTE, NULL);
else
ilTexImage(IconImages[i].Head.Width, IconImages[i].Head.Height / 2, 1, 4, IL_BGRA, IL_UNSIGNED_BYTE, NULL);
iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
Image = iCurImage;
BaseCreated = IL_TRUE;
}
else {
if (IconImages[i].Head.Size == 0) // PNG compressed icon
Image->Next = ilNewImage(IconImages[i].Head.Width, IconImages[i].Head.Height, 1, 4, 1);
else
Image->Next = ilNewImage(IconImages[i].Head.Width, IconImages[i].Head.Height / 2, 1, 4, 1);
Image = Image->Next;
Image->Format = IL_BGRA;
}
Image->Type = IL_UNSIGNED_BYTE;
j = 0; k = 0; l = 128; CurAndByte = 0; x = 0;
w = IconImages[i].Head.Width;
PadSize = (4 - ((w*IconImages[i].Head.BitCount + 7) / 8) % 4) % 4; // Has to be DWORD-aligned.
ANDPadSize = (4 - ((w + 7) / 8) % 4) % 4; // AND is 1 bit/pixel
AndBytes = (w + 7) / 8;
if (IconImages[i].Head.BitCount == 1) {
for (; j < Image->SizeOfData; k++) {
for (m = 128; m && x < w; m >>= 1) {
Image->Data[j] = IconImages[i].Pal[!!(IconImages[i].Data[k] & m) * 4];
Image->Data[j+1] = IconImages[i].Pal[!!(IconImages[i].Data[k] & m) * 4 + 1];
Image->Data[j+2] = IconImages[i].Pal[!!(IconImages[i].Data[k] & m) * 4 + 2];
Image->Data[j+3] = (IconImages[i].AND[CurAndByte] & l) != 0 ? 0 : 255;
j += 4;
l >>= 1;
++x;
}
if (l == 0 || x == w) {
l = 128;
CurAndByte++;
if (x == w) {
CurAndByte += ANDPadSize;
k += PadSize;
x = 0;
}
}
}
}
else if (IconImages[i].Head.BitCount == 4) {
for (; j < Image->SizeOfData; j += 8, k++) {
Image->Data[j] = IconImages[i].Pal[((IconImages[i].Data[k] & 0xF0) >> 4) * 4];
Image->Data[j+1] = IconImages[i].Pal[((IconImages[i].Data[k] & 0xF0) >> 4) * 4 + 1];
Image->Data[j+2] = IconImages[i].Pal[((IconImages[i].Data[k] & 0xF0) >> 4) * 4 + 2];
Image->Data[j+3] = (IconImages[i].AND[CurAndByte] & l) != 0 ? 0 : 255;
l >>= 1;
++x;
if(x < w) {
Image->Data[j+4] = IconImages[i].Pal[(IconImages[i].Data[k] & 0x0F) * 4];
Image->Data[j+5] = IconImages[i].Pal[(IconImages[i].Data[k] & 0x0F) * 4 + 1];
Image->Data[j+6] = IconImages[i].Pal[(IconImages[i].Data[k] & 0x0F) * 4 + 2];
Image->Data[j+7] = (IconImages[i].AND[CurAndByte] & l) != 0 ? 0 : 255;
l >>= 1;
++x;
}
else
j -= 4;
if (l == 0 || x == w) {
l = 128;
CurAndByte++;
if (x == w) {
CurAndByte += ANDPadSize;
k += PadSize;
x = 0;
}
}
}
}
else if (IconImages[i].Head.BitCount == 8) {
for (; j < Image->SizeOfData; j += 4, k++) {
Image->Data[j] = IconImages[i].Pal[IconImages[i].Data[k] * 4];
Image->Data[j+1] = IconImages[i].Pal[IconImages[i].Data[k] * 4 + 1];
Image->Data[j+2] = IconImages[i].Pal[IconImages[i].Data[k] * 4 + 2];
if (IconImages[i].AND == NULL) // PNG Palette
{
Image->Data[j+3] = IconImages[i].Pal[IconImages[i].Data[k] * 4 + 3];
}
else
{
Image->Data[j+3] = (IconImages[i].AND[CurAndByte] & l) != 0 ? 0 : 255;
}
l >>= 1;
++x;
if (l == 0 || x == w) {
l = 128;
CurAndByte++;
if (x == w) {
CurAndByte += ANDPadSize;
k += PadSize;
x = 0;
}
}
}
}
else if (IconImages[i].Head.BitCount == 24) {
for (; j < Image->SizeOfData; j += 4, k += 3) {
Image->Data[j] = IconImages[i].Data[k];
Image->Data[j+1] = IconImages[i].Data[k+1];
Image->Data[j+2] = IconImages[i].Data[k+2];
Image->Data[j+3] = (IconImages[i].AND[CurAndByte] & l) != 0 ? 0 : 255;
l >>= 1;
++x;
if (l == 0 || x == w) {
l = 128;
CurAndByte++;
if (x == w) {
CurAndByte += ANDPadSize;
k += PadSize;
x = 0;
}
}
}
}
else if (IconImages[i].Head.BitCount == 32) {
for (; j < Image->SizeOfData; j += 4, k += 4) {
Image->Data[j] = IconImages[i].Data[k];
Image->Data[j+1] = IconImages[i].Data[k+1];
Image->Data[j+2] = IconImages[i].Data[k+2];
//If the icon has 4 channels, use 4th channel for alpha...
//(for Windows XP style icons with true alpha channel
Image->Data[j+3] = IconImages[i].Data[k+3];
}
}
}
for (i = 0; i < IconDir.Count; i++) {
ifree(IconImages[i].Pal);
ifree(IconImages[i].Data);
ifree(IconImages[i].AND);
}
ifree(IconImages);
ifree(DirEntries);
return ilFixImage();
file_read_error:
if (IconImages) {
for (i = 0; i < IconDir.Count; i++) {
if (IconImages[i].Pal)
ifree(IconImages[i].Pal);
if (IconImages[i].Data)
ifree(IconImages[i].Data);
if (IconImages[i].AND)
ifree(IconImages[i].AND);
}
ifree(IconImages);
}
if (DirEntries)
ifree(DirEntries);
return IL_FALSE;
}
#ifndef IL_NO_PNG
// 08-22-2008: Copying a lot of this over from il_png.c for the moment.
// @TODO: Make .ico and .png use the same functions.
png_structp ico_png_ptr = NULL;
png_infop ico_info_ptr = NULL;
ILint ico_color_type;
#define GAMMA_CORRECTION 1.0 // Doesn't seem to be doing anything...
ILint ico_readpng_init();
ILboolean ico_readpng_get_image(ICOIMAGE *Icon, ILdouble display_exponent);
void ico_readpng_cleanup();
#endif
ILboolean iLoadIconPNG(ICOIMAGE *Icon)
{
#ifndef IL_NO_PNG
ILint init;
init = ico_readpng_init();
if (init)
return IL_FALSE;
if (!ico_readpng_get_image(Icon, GAMMA_CORRECTION))
return IL_FALSE;
ico_readpng_cleanup();
Icon->Head.Size = 0; // Easiest way to tell that this is a PNG.
// In the normal routine, it will not be 0.
return IL_TRUE;
#else
Icon;
return IL_FALSE;
#endif
}
#ifndef IL_NO_PNG
static void ico_png_read(png_structp png_ptr, png_bytep data, png_size_t length)
{
(void)png_ptr;
iread(data, 1, (ILuint)length);
return;
}
static void ico_png_error_func(png_structp png_ptr, png_const_charp message)
{
message;
ilSetError(IL_LIB_PNG_ERROR);
/*
changed 20040224
From the libpng docs:
"Errors handled through png_error() are fatal, meaning that png_error()
should never return to its caller. Currently, this is handled via
setjmp() and longjmp()"
*/
//return;
longjmp(png_jmpbuf(png_ptr), 1);
}
static void ico_png_warn_func(png_structp png_ptr, png_const_charp message)
{
png_ptr; message;
return;
}
ILint ico_readpng_init()
{
ico_png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, ico_png_error_func, ico_png_warn_func);
if (!ico_png_ptr)
return 4; /* out of memory */
ico_info_ptr = png_create_info_struct(ico_png_ptr);
if (!ico_info_ptr) {
png_destroy_read_struct(&ico_png_ptr, NULL, NULL);
return 4; /* out of memory */
}
/* we could create a second info struct here (end_info), but it's only
* useful if we want to keep pre- and post-IDAT chunk info separated
* (mainly for PNG-aware image editors and converters) */
/* setjmp() must be called in every function that calls a PNG-reading
* libpng function */
if (setjmp(png_jmpbuf(ico_png_ptr))) {
png_destroy_read_struct(&ico_png_ptr, &ico_info_ptr, NULL);
return 2;
}
png_set_read_fn(ico_png_ptr, NULL, ico_png_read);
png_set_error_fn(ico_png_ptr, NULL, ico_png_error_func, ico_png_warn_func);
// png_set_sig_bytes(ico_png_ptr, 8); /* we already read the 8 signature bytes */
png_read_info(ico_png_ptr, ico_info_ptr); /* read all PNG info up to image data */
/* alternatively, could make separate calls to png_get_image_width(),
* etc., but want bit_depth and ico_color_type for later [don't care about
* compression_type and filter_type => NULLs] */
/* OK, that's all we need for now; return happy */
return 0;
}
ILboolean ico_readpng_get_image(ICOIMAGE *Icon, ILdouble display_exponent)
{
png_bytepp row_pointers = NULL;
png_uint_32 width, height; // Changed the type to fix AMD64 bit problems, thanks to Eric Werness
ILdouble screen_gamma = 1.0;
ILuint i, channels;
ILenum format;
png_colorp palette;
ILint num_palette, j, bit_depth;
#if _WIN32 || DJGPP
ILdouble image_gamma;
#endif
display_exponent;
/* setjmp() must be called in every function that calls a PNG-reading
* libpng function */
if (setjmp(png_jmpbuf(ico_png_ptr))) {
png_destroy_read_struct(&ico_png_ptr, &ico_info_ptr, NULL);
return IL_FALSE;
}
png_get_IHDR(ico_png_ptr, ico_info_ptr, (png_uint_32*)&width, (png_uint_32*)&height,
&bit_depth, &ico_color_type, NULL, NULL, NULL);
// Expand low-bit-depth grayscale images to 8 bits
if (ico_color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
png_set_gray_1_2_4_to_8(ico_png_ptr);
}
// Expand RGB images with transparency to full alpha channels
// so the data will be available as RGBA quartets.
// But don't expand paletted images, since we want alpha palettes!
if (png_get_valid(ico_png_ptr, ico_info_ptr, PNG_INFO_tRNS) && !(png_get_valid(ico_png_ptr, ico_info_ptr, PNG_INFO_PLTE)))
png_set_tRNS_to_alpha(ico_png_ptr);
//refresh information (added 20040224)
png_get_IHDR(ico_png_ptr, ico_info_ptr, (png_uint_32*)&width, (png_uint_32*)&height,
&bit_depth, &ico_color_type, NULL, NULL, NULL);
if (bit_depth < 8) { // Expanded earlier for grayscale, now take care of palette and rgb
bit_depth = 8;
png_set_packing(ico_png_ptr);
}
// Perform gamma correction.
// @TODO: Determine if we should call png_set_gamma if image_gamma is 1.0.
#if _WIN32 || DJGPP
screen_gamma = 2.2;
if (png_get_gAMA(ico_png_ptr, ico_info_ptr, &image_gamma))
png_set_gamma(ico_png_ptr, screen_gamma, image_gamma);
#else
screen_gamma = screen_gamma;
#endif
//fix endianess
#ifdef __LITTLE_ENDIAN__
if (bit_depth == 16)
png_set_swap(ico_png_ptr);
#endif
png_read_update_info(ico_png_ptr, ico_info_ptr);
channels = (ILint)png_get_channels(ico_png_ptr, ico_info_ptr);
// added 20040224: update ico_color_type so that it has the correct value
// in iLoadPngInternal (globals rule...)
ico_color_type = png_get_color_type(ico_png_ptr, ico_info_ptr);
// Determine internal format
switch (ico_color_type)
{
case PNG_COLOR_TYPE_PALETTE:
Icon->Head.BitCount = 8;
format = IL_COLOUR_INDEX;
break;
case PNG_COLOR_TYPE_RGB:
Icon->Head.BitCount = 24;
format = IL_RGB;
break;
case PNG_COLOR_TYPE_RGB_ALPHA:
Icon->Head.BitCount = 32;
format = IL_RGBA;
break;
default:
ilSetError(IL_ILLEGAL_FILE_VALUE);
png_destroy_read_struct(&ico_png_ptr, &ico_info_ptr, NULL);
return IL_FALSE;
}
if (ico_color_type & PNG_COLOR_MASK_COLOR)
png_set_bgr(ico_png_ptr);
Icon->Head.Width = width;
Icon->Head.Height = height;
Icon->Data = ialloc(width * height * Icon->Head.BitCount / 8);
if (Icon->Data == NULL)
{
png_destroy_read_struct(&ico_png_ptr, &ico_info_ptr, NULL);
return IL_FALSE;
}
// Copy Palette
if (format == IL_COLOUR_INDEX)
{
int chans;
png_bytep trans = NULL;
int num_trans = -1;
if (!png_get_PLTE(ico_png_ptr, ico_info_ptr, &palette, &num_palette)) {
ilSetError(IL_ILLEGAL_FILE_VALUE);
png_destroy_read_struct(&ico_png_ptr, &ico_info_ptr, NULL);
return IL_FALSE;
}
chans = 4;
if (png_get_valid(ico_png_ptr, ico_info_ptr, PNG_INFO_tRNS)) {
png_get_tRNS(ico_png_ptr, ico_info_ptr, &trans, &num_trans, NULL);
}
// @TODO: We may need to keep track of the size of the palette.
Icon->Pal = (ILubyte*)ialloc(num_palette * chans);
for (j = 0; j < num_palette; ++j) {
Icon->Pal[chans*j + 0] = palette[j].blue;
Icon->Pal[chans*j + 1] = palette[j].green;
Icon->Pal[chans*j + 2] = palette[j].red;
if (trans != NULL) {
if (j < num_trans)
Icon->Pal[chans*j + 3] = trans[j];
else
Icon->Pal[chans*j + 3] = 255;
}
}
Icon->AND = NULL; // Transparency information is obtained from libpng.
}
//allocate row pointers
if ((row_pointers = (png_bytepp)ialloc(height * sizeof(png_bytep))) == NULL) {
png_destroy_read_struct(&ico_png_ptr, &ico_info_ptr, NULL);
return IL_FALSE;
}
// Set the individual row_pointers to point at the correct offsets
// Needs to be flipped
for (i = 0; i < height; i++)
row_pointers[height - i - 1] = Icon->Data + i * width * Icon->Head.BitCount / 8;
//row_pointers[i] = Icon->Data + i * width * Icon->Head.BitCount / 8;
// Now we can go ahead and just read the whole image
png_read_image(ico_png_ptr, row_pointers);
/* and we're done! (png_read_end() can be omitted if no processing of
* post-IDAT text/time/etc. is desired) */
//png_read_end(ico_png_ptr, NULL);
ifree(row_pointers);
return IL_TRUE;
}
void ico_readpng_cleanup()
{
if (ico_png_ptr && ico_info_ptr) {
png_destroy_read_struct(&ico_png_ptr, &ico_info_ptr, NULL);
ico_png_ptr = NULL;
ico_info_ptr = NULL;
}
}
#endif//IL_NO_PNG
#endif//IL_NO_ICO
+479
View File
@@ -0,0 +1,479 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Last modified: 03/0/2009
//
// Filename: src-IL/src/il_iff.c
//
// Description: Reads from an .iff file. Contribution from GAIA:
// http://gaia.fdi.ucm.es/grupo/projects/javy/devzone.html#DevILNotes.
//
//-----------------------------------------------------------------------------
#include "il_internal.h"
#ifndef IL_NO_IFF
// Chunk type, data and functions:
typedef struct _iff_chunk {
ILuint tag;
ILuint start;
ILuint size;
ILuint chunkType;
} iff_chunk;
#define CHUNK_STACK_SIZE (32)
static iff_chunk chunkStack[CHUNK_STACK_SIZE];
static int chunkDepth = -1;
iff_chunk iff_begin_read_chunk();
void iff_end_read_chunk();
char *iff_read_data(int size);
ILboolean iLoadIffInternal(void);
/* Define the IFF tags we are looking for in the file. */
const ILuint IFF_TAG_CIMG = ('C' << 24) | ('I' << 16) | ('M' << 8) | ('G');
const ILuint IFF_TAG_FOR4 = ('F' << 24) | ('O' << 16) | ('R' << 8) | ('4');
const ILuint IFF_TAG_TBHD = ('T' << 24) | ('B' << 16) | ('H' << 8) | ('D');
const ILuint IFF_TAG_TBMP = ('T' << 24) | ('B' << 16) | ('M' << 8) | ('P');
const ILuint IFF_TAG_RGBA = ('R' << 24) | ('G' << 16) | ('B' << 8) | ('A');
const ILuint IFF_TAG_CLPZ = ('C' << 24) | ('L' << 16) | ('P' << 8) | ('Z');
const ILuint IFF_TAG_ESXY = ('E' << 24) | ('S' << 16) | ('X' << 8) | ('Y');
const ILuint IFF_TAG_ZBUF = ('Z' << 24) | ('B' << 16) | ('U' << 8) | ('F');
const ILuint IFF_TAG_BLUR = ('B' << 24) | ('L' << 16) | ('U' << 8) | ('R');
const ILuint IFF_TAG_BLRT = ('B' << 24) | ('L' << 16) | ('R' << 8) | ('T');
const ILuint IFF_TAG_HIST = ('H' << 24) | ('I' << 16) | ('S' << 8) | ('T');
// Flags
#define RGB_FLAG (1)
#define ALPHA_FLAG (2)
#define ZBUFFER_FLAG (4)
// Function for decompress the file.
char *iff_decompress_rle(ILuint numBytes, char *compressedData,
ILuint compressedDataSize,
ILuint *compressedStartIndex);
char *iffReadUncompressedTile(ILushort width, ILushort height, ILbyte depth);
char *iff_decompress_tile_rle(ILushort width, ILushort height, ILushort depth,
char *compressedData, ILuint compressedDataSize);
//! Reads an IFF file
ILboolean ilLoadIff(const ILstring FileName)
{
ILHANDLE iffFile;
ILboolean ret = IL_FALSE;
iffFile = iopenr(FileName);
if (iffFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return ret;
}
ret = ilLoadIffF(iffFile);
icloser(iffFile);
return ret;
}
//! Reads an already-opened IFF file
ILboolean ilLoadIffF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iLoadIffInternal();
iseek(FirstPos, IL_SEEK_SET);
// Lbm files can have the .iff extension as well, so if Iff-loading failed,
// try to load it as a Lbm.
if (bRet == IL_FALSE)
return ilLoadIlbmF(File);
return bRet;
}
//! Reads from a memory "lump" that contains an IFF
ILboolean ilLoadIffL(const void *Lump, ILuint Size)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputLump(Lump, Size);
FirstPos = itell();
bRet = iLoadIffInternal();
iseek(FirstPos, IL_SEEK_SET);
// Lbm files can have the .iff extension as well, so if Iff-loading failed,
// try to load it as a Lbm.
if (bRet == IL_FALSE)
return ilLoadIlbmL(Lump, Size);
return IL_TRUE;
}
ILboolean iLoadIffInternal(void)
{
iff_chunk chunkInfo;
// -- Header info.
ILuint width, height;
ILuint flags, compress;
ILushort tiles;
ILenum format;
ILubyte bpp;
ILboolean tileImageDataFound;
// -- Initialize the top of the chunk stack.
chunkDepth = -1;
// -- File should begin with a FOR4 chunk of type CIMG
chunkInfo = iff_begin_read_chunk();
if (chunkInfo.chunkType != IFF_TAG_CIMG) {
ilSetError(IL_ILLEGAL_FILE_VALUE);
return IL_FALSE;
}
/*
* Read the image header
* OK, we have a FOR4 of type CIMG, look for the following tags
* FVER
* TBHD bitmap header, definition of size, etc.
* AUTH
* DATE
*/
while (1) {
chunkInfo = iff_begin_read_chunk();
// -- Right now, the only info we need about the image is in TBHD
// -- so search this level until we find it.
if( chunkInfo.tag == IFF_TAG_TBHD ) {
// -- Header chunk found
width = GetBigUInt();
height = GetBigUInt();
GetBigShort(); // -- Don't support
GetBigShort(); // -- Don't support
flags = GetBigUInt();
GetBigShort(); // -- Don't support
tiles = GetBigUShort();
compress = GetBigUInt();
iff_end_read_chunk();
if( compress > 1 ) {
ilSetError(IL_ILLEGAL_FILE_VALUE);
return IL_FALSE;
}
break;
} else
iff_end_read_chunk();
} /* END find TBHD while loop */
if (!(flags & RGB_FLAG)) {
ilSetError(IL_ILLEGAL_FILE_VALUE);
return IL_FALSE;
}
if (flags & ALPHA_FLAG) {
format = IL_RGBA; bpp = 4;
} else {
format = IL_RGB; bpp = 3;
}
if (!ilTexImage(width, height, 1, bpp, format, IL_UNSIGNED_BYTE, NULL))
return IL_FALSE;
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
tileImageDataFound = IL_FALSE;
while (!tileImageDataFound) {
ILuint tileImage;
ILuint tileZ;
chunkInfo = iff_begin_read_chunk();
/*
* OK, we have a FOR4 of type TBMP, (embedded FOR4)
* look for the following tags
* RGBA color data, RLE compressed tiles of 32 bbp data
* ZBUF z-buffer data, 32 bit float values
* CLPZ depth map specific, clipping planes, 2 float values
* ESXY depth map specific, eye x-y ratios, 2 float values
* HIST
* VERS
* FOR4 <size> BLUR (twice embedded FOR4)
*/
if (chunkInfo.chunkType != IFF_TAG_TBMP) {
iff_end_read_chunk();
continue;
}
tileImageDataFound = IL_TRUE;
tileImage = 0; // Si no RGBA, tileImage = tiles...
if (flags & ZBUFFER_FLAG)
tileZ = 0;
else
tileZ = tiles;
// Read tiles
while ( (tileImage < tiles) || (tileZ < tiles)) {
char *tileData;
ILushort x1, x2, y1, y2, tile_width, tile_height;
ILuint remainingDataSize;
ILushort tile_area;
ILuint tileCompressed;
chunkInfo = iff_begin_read_chunk();
if ((chunkInfo.tag != IFF_TAG_RGBA) && (chunkInfo.tag != IFF_TAG_ZBUF)) {
ilSetError(IL_ILLEGAL_FILE_VALUE);
return IL_FALSE;
}
x1 = GetBigUShort(); y1 = GetBigUShort();
x2 = GetBigUShort(); y2 = GetBigUShort();
remainingDataSize = chunkInfo.size - 4*sizeof(ILushort);
tile_width = x2 - x1 + 1;
tile_height = y2 - y1 + 1;
tile_area = tile_width * tile_height;
if ((ILint)remainingDataSize >= (tile_width * tile_height * bpp))
tileCompressed = 0;
else
tileCompressed = 1;
if (chunkInfo.tag == IFF_TAG_RGBA) {
if (tileCompressed) {
char *data = iff_read_data(remainingDataSize);
if (data) {
tileData = iff_decompress_tile_rle(tile_width, tile_height,
bpp, data, remainingDataSize);
ifree(data);
}
} else {
tileData = iffReadUncompressedTile(tile_width, tile_height, bpp);
}
if (tileData) {
// Dump RGBA data to our data structure
ILushort i;
ILuint base;
base = bpp*(width * y1 + x1);
for (i = 0; i < tile_height; i++) {
memcpy(&iCurImage->Data[base + bpp*i*width],
&tileData[bpp*i*tile_width],
tile_width*bpp*sizeof(char));
}
ifree(tileData);
tileData = NULL;
iff_end_read_chunk();
tileImage++;
} else
return IL_FALSE;
} else if (chunkInfo.tag == IFF_TAG_ZBUF) {
tileZ++;
iff_end_read_chunk();
}
}
}
//ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE); // Why was this here?
return ilFixImage();
}
/*
* IFF Chunking Routines.
*
*/
iff_chunk iff_begin_read_chunk()
{
chunkDepth++;
if (chunkDepth >= CHUNK_STACK_SIZE){
ilSetError(IL_STACK_OVERFLOW);
return chunkStack[0];
}
if (chunkDepth < 0) {
ilSetError(IL_STACK_UNDERFLOW);
return chunkStack[0];
}
chunkStack[chunkDepth].start = itell();
chunkStack[chunkDepth].tag = GetBigInt();
chunkStack[chunkDepth].size = GetBigInt();
if (chunkStack[chunkDepth].tag == IFF_TAG_FOR4) {
// -- We have a form, so read the form type tag as well.
chunkStack[chunkDepth].chunkType = GetBigInt();
} else {
chunkStack[chunkDepth].chunkType = 0;
}
return chunkStack[chunkDepth];
}
void iff_end_read_chunk()
{
ILuint end;
int part;
end = chunkStack[chunkDepth].start + chunkStack[chunkDepth].size + 8;
if (chunkStack[chunkDepth].chunkType != 0) {
end += 4;
}
// Add padding
part = end % 4;
if (part != 0) {
end += 4 - part;
}
iseek(end, IL_SEEK_SET);
chunkDepth--;
}
char * iff_read_data(int size)
{
char *buffer = ialloc(size * sizeof(char));
if (buffer == NULL)
return NULL;
if (iread(buffer, size*sizeof(char), 1) != 1) {
ifree(buffer);
return NULL;
}
return buffer;
}
/*
IFF decompress functions
*/
char *iffReadUncompressedTile(ILushort width, ILushort height, ILbyte depth)
{
char *data = NULL;
char *iniPixel;
char *finPixel;
int i, j;
int tam = width* height * depth * sizeof(char);
data = ialloc(tam);
if (data == NULL)
return NULL;
if (iread(data, tam, 1) != 1) {
ifree(data);
return NULL;
}
iniPixel = data;
for (i = 0; i < tam / depth; i++) {
finPixel = iniPixel + depth;
for (j = 0; j < (depth /2); j++) {
char aux;
aux = *iniPixel;
*(finPixel--) = *iniPixel;
*(iniPixel++) = aux;
}
}
return data;
}
char *iff_decompress_tile_rle(ILushort width, ILushort height, ILushort depth,
char *compressedData, ILuint compressedDataSize)
{
char *channels[4];
char *data;
int i, k, row, column;
ILuint compressedStart = 0;
// Decompress only in RGBA.
if (depth != 4) {
ilSetError(IL_ILLEGAL_FILE_VALUE);
return NULL;
}
for (i = depth-1; i >= 0; --i) {
channels[i] = iff_decompress_rle(width * height, compressedData,
compressedDataSize, &compressedStart);
if (channels[i] == NULL)
return NULL;
}
// Build all the channels from the decompression into an RGBA array.
data = ialloc(width * height * depth * sizeof(char));
if (data == NULL)
return NULL;
for (row = 0; row < height; row++)
for (column = 0; column < width; column++)
for (k = 0; k < depth; k++)
data[depth*(row*width + column) + k] =
channels[k][row*width + column];
ifree(channels[0]); ifree(channels[1]);
ifree(channels[2]); ifree(channels[3]);
return data;
}
char *iff_decompress_rle(ILuint numBytes, char *compressedData,
ILuint compressedDataSize,
ILuint *compressedStartIndex)
{
char *data = ialloc(numBytes * sizeof(char));
unsigned char nextChar, count;
int i;
ILuint byteCount = 0;
if (data == NULL)
return NULL;
memset(data, 0, numBytes*sizeof(char));
while (byteCount < numBytes) {
if (*compressedStartIndex >= compressedDataSize)
break;
nextChar = compressedData[*compressedStartIndex];
(*compressedStartIndex)++;
count = (nextChar & 0x7f) + 1;
if ((byteCount + count) > numBytes) break;
if (nextChar & 0x80) {
// Duplication run
nextChar = compressedData[*compressedStartIndex];
(*compressedStartIndex)++;
// assert ((byteCount + count) <= numBytes);
for (i = 0; i < count; i++) {
data[byteCount]= nextChar;
byteCount++;
}
} else {
// Verbatim run
for (i = 0; i < count; i++) {
data[byteCount] = compressedData[*compressedStartIndex];
(*compressedStartIndex)++;
byteCount++;
}
}
//assert(byteCount <= numBytes);
}
return data;
}
#endif //IL_NO_IFF
+658
View File
@@ -0,0 +1,658 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 03/08/2009
//
// Filename: src-IL/src/il_ilbm.c
//
// Description: IFF ILBM file (.iff, .ilbm, .lbm) functions
// IFF ILBM loader, ported from SDL_Image library (IMG_lbm.c)
// http://www.libsdl.org/cgi/viewvc.cgi/trunk/SDL_image/IMG_lbm.c?view=markup
//
// Handles Amiga ILBM and PBM images (including .lbm files saved by the PC
// version of dpaint)
// Handles ExtraHalfBright and HAM images.
//
// Adapted from SDL_image by Ben Campbell (http://scumways.com) 2009-02-23
//
//-----------------------------------------------------------------------------
// TODO: sort out the .iff extension confusion: .iff is currently handled by
// Maya IFF/CIMG handler (il_iff.c), but it should defer to this one if
// fileturns out to be an ILBM. I think the best solution would be to
// rename the IFF handler to CIMG, and create a new iff handler to act as
// a front end, passing off to either il_ilbm or il_cimg...
// For now, this handler only handles .lbm and .ilbm extenstions (but
// traditionally, .iff is more common).
#include "il_internal.h"
#ifndef IL_NO_ILBM
#include <stdlib.h>
ILboolean iIsValidIlbm(void);
ILboolean iLoadIlbmInternal(void);
static ILboolean load_ilbm(void);
static int isLBM(void );
ILboolean ilIsValidIlbm(ILconst_string FileName)
{
ILHANDLE f;
ILboolean bIlbm = IL_FALSE;
if (!iCheckExtension(FileName, IL_TEXT("iff")) &&
!iCheckExtension(FileName, IL_TEXT("ilbm")) &&
!iCheckExtension(FileName, IL_TEXT("lbm")) &&
!iCheckExtension(FileName, IL_TEXT("ham")) ) {
ilSetError(IL_INVALID_EXTENSION);
return bIlbm;
}
f = iopenr(FileName);
if (f == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bIlbm;
}
bIlbm = ilIsValidIlbmF(f);
icloser(f);
return bIlbm;
}
ILboolean ilIsValidIlbmF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iIsValidIlbm();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
ILboolean ilIsValidIlbmL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iIsValidIlbm();
}
ILboolean iIsValidIlbm()
{
return isLBM() ? IL_TRUE:IL_FALSE;
}
// Reads a file
ILboolean ilLoadIlbm(ILconst_string FileName)
{
ILHANDLE IlbmFile;
ILboolean bIlbm = IL_FALSE;
IlbmFile = iopenr(FileName);
if (IlbmFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bIlbm;
}
bIlbm = ilLoadIlbmF(IlbmFile);
icloser(IlbmFile);
return bIlbm;
}
// Reads an already-opened file
ILboolean ilLoadIlbmF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iLoadIlbmInternal();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
// Reads from a memory "lump"
ILboolean ilLoadIlbmL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iLoadIlbmInternal();
}
ILboolean iLoadIlbmInternal()
{
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
if (!iIsValidIlbm()) {
ilSetError(IL_INVALID_VALUE);
return IL_FALSE;
}
if (!load_ilbm() )
{
return IL_FALSE;
}
return ilFixImage();
}
/* some defines to allow us to use the SDL_image source in as unmodified form
* as possible, so it'll be easy to diff. Yes, it does look evil, but it's
* really just some local syntactic sugar - most things correspond directly
* to DevIL calls. It's not that bad, honest ;-)
* This will make it _much_ easier to track changes to SDL_Image.
* - BenC
*/
#define Sint8 ILbyte
#define Sint16 ILshort
#define Sint32 ILint
#define Uint8 ILubyte
#define Uint16 ILushort
#define Uint32 ILuint
#define SDL_RWops void
#define SDL_RWtell(s) itell()
#define SDL_RWread(s,ptr,size,nmemb) iread(ptr,size,nmemb)
#define SDL_RWseek(s,offset,whence) iseek(offset, IL_ ## whence)
/* use different function names to avoid any possible symbol contamination
* (user might also be linking with libSDL) */
#define SDL_SwapBE32(i) iSDL_SwapBE32(i)
#define SDL_SwapBE16(s) iSDL_SwapBE16(s)
static Uint16 iSDL_SwapBE16( Uint16 s )
{ Uint16 foo = s; iSwapUShort(&foo); return foo; }
static Uint32 iSDL_SwapBE32( Uint32 i )
{ Uint32 foo = i; iSwapUInt(&foo); return foo; }
/* rest of this file is as unchanged as possible from IMG_lbm.c - BenC */
/***************************************************************************/
/* This is a ILBM image file loading framework
Load IFF pictures, PBM & ILBM packing methods, with or without stencil
Written by Daniel Morais ( Daniel AT Morais DOT com ) in September 2001.
24 bits ILBM files support added by Marc Le Douarain (http://www.multimania.com/mavati)
in December 2002.
EHB and HAM (specific Amiga graphic chip modes) support added by Marc Le Douarain
(http://www.multimania.com/mavati) in December 2003.
Stencil and colorkey fixes by David Raulo (david.raulo AT free DOT fr) in February 2004.
Buffer overflow fix in RLE decompression by David Raulo in January 2008.
*/
#define MAXCOLORS 256
/* Structure for an IFF picture ( BMHD = Bitmap Header ) */
/* TODO: SDL_Image seems to get away without any struct
* packing... should it be added? */
typedef struct
{
Uint16 w, h; /* width & height of the bitmap in pixels */
Sint16 x, y; /* screen coordinates of the bitmap */
Uint8 planes; /* number of planes of the bitmap */
Uint8 mask; /* mask type ( 0 => no mask ) */
Uint8 tcomp; /* compression type */
Uint8 pad1; /* dummy value, for padding */
Uint16 tcolor; /* transparent color */
Uint8 xAspect, /* pixel aspect ratio */
yAspect;
Sint16 Lpage; /* width of the screen in pixels */
Sint16 Hpage; /* height of the screen in pixels */
} BMHD;
static int isLBM()
{
SDL_RWops* src = 0;
int start;
int is_LBM;
Uint8 magic[4+4+4];
start = SDL_RWtell(src);
is_LBM = 0;
if ( SDL_RWread( src, magic, sizeof(magic), 1 ) )
{
if ( !memcmp( magic, "FORM", 4 ) &&
( !memcmp( magic + 8, "PBM ", 4 ) ||
!memcmp( magic + 8, "ILBM", 4 ) ) )
{
is_LBM = 1;
}
}
SDL_RWseek(src, start, SEEK_SET);
return( is_LBM );
}
static ILboolean load_ilbm(void)
{
SDL_RWops* src = 0;
struct { Uint8 r; Uint8 g; Uint8 b; } scratch_pal[MAXCOLORS];
ILenum format; /* IL_RGB (ham or 24bit) or IL_COLOUR_INDEX */
int start;
Uint8 id[4], pbm, colormap[MAXCOLORS*3], *MiniBuf, *ptr, count, color, msk;
Uint32 size, bytesloaded, nbcolors;
Uint32 i, j, bytesperline, nbplanes, plane, h;
Uint32 remainingbytes;
Uint32 width;
BMHD bmhd;
char *error;
Uint8 flagHAM,flagEHB;
error = NULL;
MiniBuf = NULL;
start = SDL_RWtell(src);
if ( !SDL_RWread( src, id, 4, 1 ) )
{
error="error reading IFF chunk";
goto done;
}
/* Should be the size of the file minus 4+4 ( 'FORM'+size ) */
if ( !SDL_RWread( src, &size, 4, 1 ) )
{
error="error reading IFF chunk size";
goto done;
}
/* As size is not used here, no need to swap it */
if ( memcmp( id, "FORM", 4 ) != 0 )
{
ilSetError(IL_INVALID_FILE_HEADER);
error="not a IFF file";
goto done;
}
if ( !SDL_RWread( src, id, 4, 1 ) )
{
error="error reading IFF chunk";
goto done;
}
pbm = 0;
/* File format : PBM=Packed Bitmap, ILBM=Interleaved Bitmap */
if ( !memcmp( id, "PBM ", 4 ) ) pbm = 1;
else if ( memcmp( id, "ILBM", 4 ) )
{
ilSetError(IL_INVALID_FILE_HEADER);
error="not a IFF picture";
goto done;
}
nbcolors = 0;
memset( &bmhd, 0, sizeof( BMHD ) );
flagHAM = 0;
flagEHB = 0;
while ( memcmp( id, "BODY", 4 ) != 0 )
{
if ( !SDL_RWread( src, id, 4, 1 ) )
{
error="error reading IFF chunk";
goto done;
}
if ( !SDL_RWread( src, &size, 4, 1 ) )
{
error="error reading IFF chunk size";
goto done;
}
bytesloaded = 0;
size = SDL_SwapBE32( size );
if ( !memcmp( id, "BMHD", 4 ) ) /* Bitmap header */
{
if ( !SDL_RWread( src, &bmhd, sizeof( BMHD ), 1 ) )
{
error="error reading BMHD chunk";
goto done;
}
bytesloaded = sizeof( BMHD );
bmhd.w = SDL_SwapBE16( bmhd.w );
bmhd.h = SDL_SwapBE16( bmhd.h );
bmhd.x = SDL_SwapBE16( bmhd.x );
bmhd.y = SDL_SwapBE16( bmhd.y );
bmhd.tcolor = SDL_SwapBE16( bmhd.tcolor );
bmhd.Lpage = SDL_SwapBE16( bmhd.Lpage );
bmhd.Hpage = SDL_SwapBE16( bmhd.Hpage );
}
if ( !memcmp( id, "CMAP", 4 ) ) /* palette ( Color Map ) */
{
if ( !SDL_RWread( src, &colormap, size, 1 ) )
{
error="error reading CMAP chunk";
goto done;
}
bytesloaded = size;
nbcolors = size / 3;
}
if ( !memcmp( id, "CAMG", 4 ) ) /* Amiga ViewMode */
{
Uint32 viewmodes;
if ( !SDL_RWread( src, &viewmodes, sizeof(viewmodes), 1 ) )
{
error="error reading CAMG chunk";
goto done;
}
bytesloaded = size;
viewmodes = SDL_SwapBE32( viewmodes );
if ( viewmodes & 0x0800 )
flagHAM = 1;
if ( viewmodes & 0x0080 )
flagEHB = 1;
}
if ( memcmp( id, "BODY", 4 ) )
{
if ( size & 1 ) ++size; /* padding ! */
size -= bytesloaded;
/* skip the remaining bytes of this chunk */
if ( size ) SDL_RWseek( src, size, SEEK_CUR );
}
}
/* compute some usefull values, based on the bitmap header */
width = ( bmhd.w + 15 ) & 0xFFFFFFF0; /* Width in pixels modulo 16 */
bytesperline = ( ( bmhd.w + 15 ) / 16 ) * 2;
nbplanes = bmhd.planes;
if ( pbm ) /* File format : 'Packed Bitmap' */
{
bytesperline *= 8;
nbplanes = 1;
}
if ( bmhd.mask & 1 ) ++nbplanes; /* There is a mask ( 'stencil' ) */
/* Allocate memory for a temporary buffer ( used for
decompression/deinterleaving ) */
if ( ( MiniBuf = (void *)malloc( bytesperline * nbplanes ) ) == NULL )
{
ilSetError( IL_OUT_OF_MEMORY );
error="no enough memory for temporary buffer";
goto done;
}
if( bmhd.planes==24 || flagHAM==1 ) {
format = IL_BGR;
} else {
format = IL_COLOUR_INDEX;
}
if( !ilTexImage( width, bmhd.h, 1, (format==IL_COLOUR_INDEX)?1:3, format, IL_UNSIGNED_BYTE, NULL ) )
goto done;
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
#if 0 /* No transparent colour support in DevIL? (TODO: confirm) */
if ( bmhd.mask & 2 ) /* There is a transparent color */
SDL_SetColorKey( Image, SDL_SRCCOLORKEY, bmhd.tcolor );
#endif
/* Update palette informations */
/* There is no palette in 24 bits ILBM file */
if ( nbcolors>0 && flagHAM==0 )
{
int nbrcolorsfinal = 1 << nbplanes;
ptr = &colormap[0];
for ( i=0; i<nbcolors; i++ )
{
scratch_pal[i].r = *ptr++;
scratch_pal[i].g = *ptr++;
scratch_pal[i].b = *ptr++;
}
/* Amiga EHB mode (Extra-Half-Bright) */
/* 6 bitplanes mode with a 32 colors palette */
/* The 32 last colors are the same but divided by 2 */
/* Some Amiga pictures save 64 colors with 32 last wrong colors, */
/* they shouldn't !, and here we overwrite these 32 bad colors. */
if ( (nbcolors==32 || flagEHB ) && (1<<bmhd.planes)==64 )
{
nbcolors = 64;
ptr = &colormap[0];
for ( i=32; i<64; i++ )
{
scratch_pal[i].r = (*ptr++)/2;
scratch_pal[i].g = (*ptr++)/2;
scratch_pal[i].b = (*ptr++)/2;
}
}
/* If nbcolors < 2^nbplanes, repeat the colormap */
/* This happens when pictures have a stencil mask */
if ( nbrcolorsfinal > (1<<bmhd.planes) ) {
nbrcolorsfinal = (1<<bmhd.planes);
}
for ( i=nbcolors; i < (Uint32)nbrcolorsfinal; i++ )
{
scratch_pal[i].r = scratch_pal[i%nbcolors].r;
scratch_pal[i].g = scratch_pal[i%nbcolors].g;
scratch_pal[i].b = scratch_pal[i%nbcolors].b;
}
if ( !pbm )
ilRegisterPal( scratch_pal, 3*nbrcolorsfinal, IL_PAL_RGB24 );
}
/* Get the bitmap */
for ( h=0; h < bmhd.h; h++ )
{
/* uncompress the datas of each planes */
for ( plane=0; plane < nbplanes; plane++ )
{
ptr = MiniBuf + ( plane * bytesperline );
remainingbytes = bytesperline;
if ( bmhd.tcomp == 1 ) /* Datas are compressed */
{
do
{
if ( !SDL_RWread( src, &count, 1, 1 ) )
{
error="error reading BODY chunk";
goto done;
}
if ( count & 0x80 )
{
count ^= 0xFF;
count += 2; /* now it */
if ( ( count > remainingbytes ) || !SDL_RWread( src, &color, 1, 1 ) )
{
if( count>remainingbytes)
ilSetError(IL_ILLEGAL_FILE_VALUE );
error="error reading BODY chunk";
goto done;
}
memset( ptr, color, count );
}
else
{
++count;
if ( ( count > remainingbytes ) || !SDL_RWread( src, ptr, count, 1 ) )
{
if( count>remainingbytes)
ilSetError(IL_ILLEGAL_FILE_VALUE );
error="error reading BODY chunk";
goto done;
}
}
ptr += count;
remainingbytes -= count;
} while ( remainingbytes > 0 );
}
else
{
if ( !SDL_RWread( src, ptr, bytesperline, 1 ) )
{
error="error reading BODY chunk";
goto done;
}
}
}
/* One line has been read, store it ! */
ptr = ilGetData();
if ( nbplanes==24 || flagHAM==1 )
ptr += h * width * 3;
else
ptr += h * width;
if ( pbm ) /* File format : 'Packed Bitmap' */
{
memcpy( ptr, MiniBuf, width );
}
else /* We have to un-interlace the bits ! */
{
if ( nbplanes!=24 && flagHAM==0 )
{
size = ( width + 7 ) / 8;
for ( i=0; i < size; i++ )
{
memset( ptr, 0, 8 );
for ( plane=0; plane < nbplanes; plane++ )
{
color = *( MiniBuf + i + ( plane * bytesperline ) );
msk = 0x80;
for ( j=0; j<8; j++ )
{
if ( ( plane + j ) <= 7 ) ptr[j] |= (Uint8)( color & msk ) >> ( 7 - plane - j );
else ptr[j] |= (Uint8)( color & msk ) << ( plane + j - 7 );
msk >>= 1;
}
}
ptr += 8;
}
}
else
{
Uint32 finalcolor = 0;
size = ( width + 7 ) / 8;
/* 24 bitplanes ILBM : R0...R7,G0...G7,B0...B7 */
/* or HAM (6 bitplanes) or HAM8 (8 bitplanes) modes */
for ( i=0; i<width; i=i+8 )
{
Uint8 maskBit = 0x80;
for ( j=0; j<8; j++ )
{
Uint32 pixelcolor = 0;
Uint32 maskColor = 1;
Uint8 dataBody;
for ( plane=0; plane < nbplanes; plane++ )
{
dataBody = MiniBuf[ plane*size+i/8 ];
if ( dataBody&maskBit )
pixelcolor = pixelcolor | maskColor;
maskColor = maskColor<<1;
}
/* HAM : 12 bits RGB image (4 bits per color component) */
/* HAM8 : 18 bits RGB image (6 bits per color component) */
if ( flagHAM )
{
switch( pixelcolor>>(nbplanes-2) )
{
case 0: /* take direct color from palette */
finalcolor = colormap[ pixelcolor*3 ] + (colormap[ pixelcolor*3+1 ]<<8) + (colormap[ pixelcolor*3+2 ]<<16);
break;
case 1: /* modify only blue component */
finalcolor = finalcolor&0x00FFFF;
finalcolor = finalcolor | (pixelcolor<<(16+(10-nbplanes)));
break;
case 2: /* modify only red component */
finalcolor = finalcolor&0xFFFF00;
finalcolor = finalcolor | pixelcolor<<(10-nbplanes);
break;
case 3: /* modify only green component */
finalcolor = finalcolor&0xFF00FF;
finalcolor = finalcolor | (pixelcolor<<(8+(10-nbplanes)));
break;
}
}
else
{
finalcolor = pixelcolor;
}
#if defined( __LITTLE_ENDIAN__ )
{
*ptr++ = (Uint8)(finalcolor>>16);
*ptr++ = (Uint8)(finalcolor>>8);
*ptr++ = (Uint8)(finalcolor);
}
#else
{
*ptr++ = (Uint8)(finalcolor);
*ptr++ = (Uint8)(finalcolor>>8);
*ptr++ = (Uint8)(finalcolor>>16);
}
#endif
maskBit = maskBit>>1;
}
}
}
}
}
done:
if ( MiniBuf ) free( MiniBuf );
if ( error )
{
/* fprintf(stderr,"il_ilbm.c: '%s'\n",error); */
return IL_FALSE;
}
return IL_TRUE;
}
#endif//IL_NO_ILBM
+271
View File
@@ -0,0 +1,271 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2008 by Denton Woods
// Last modified: 11/08/2008
//
// Filename: src-IL/src/il_internal.c
//
// Description: Internal stuff for DevIL
//
//-----------------------------------------------------------------------------
#include "il_internal.h"
#include <string.h>
#include <stdlib.h>
ILimage *iCurImage = NULL;
/* Siigron: added this for Linux... a #define should work, but for some reason
it doesn't (anyone who knows why?) */
#if !_WIN32 || (_WIN32 && __GNUC__) // Cygwin
int stricmp(const char *src1, const char *src2)
{
return strcasecmp(src1, src2);
}
int strnicmp(const char *src1, const char *src2, size_t max)
{
return strncasecmp(src1, src2, max);
}
#elif _WIN32_WCE
int stricmp(const char *src1, const char *src2)
{
return _stricmp(src1, src2);
}
int strnicmp(const char *src1, const char *src2, size_t max)
{
return _strnicmp(src1, src2, max);
}
#endif /* _WIN32 */
#ifdef _WIN32_WCE
char *strdup(const char *src)
{
return _strdup(src);
}
#endif//_WIN32_WCE
#ifdef _UNICODE
int iStrCmp(ILconst_string src1, ILconst_string src2)
{
return wcsicmp(src1, src2);
}
#else
int iStrCmp(ILconst_string src1, ILconst_string src2)
{
return stricmp(src1, src2);
}
#endif
//! Glut's portability.txt says to use this...
ILstring ilStrDup(ILconst_string Str)
{
ILstring copy;
copy = (ILstring)ialloc((ilStrLen(Str) + 1) * sizeof(ILchar));
if (copy == NULL)
return NULL;
iStrCpy(copy, Str);
return copy;
}
// Because MSVC++'s version is too stupid to check for NULL...
ILuint ilStrLen(ILconst_string Str)
{
ILconst_string eos = Str;
if (Str == NULL)
return 0;
while (*eos++);
return((int)(eos - Str - 1));
}
// Because MSVC++'s version is too stupid to check for NULL...
// Passing NULL to strlen will definitely cause a crash.
ILuint ilCharStrLen(const char *Str)
{
const char *eos = Str;
if (Str == NULL)
return 0;
while (*eos++);
return((int)(eos - Str - 1));
}
// Simple function to test if a filename has a given extension, disregarding case
ILboolean iCheckExtension(ILconst_string Arg, ILconst_string Ext)
{
ILboolean PeriodFound = IL_FALSE;
ILint i, Len;
ILstring Argu = (ILstring)Arg;
if (Arg == NULL || Ext == NULL || !ilStrLen(Arg) || !ilStrLen(Ext)) // if not a good filename/extension, exit early
return IL_FALSE;
Len = ilStrLen(Arg);
Argu += Len; // start at the end
for (i = Len; i >= 0; i--) {
if (*Argu == '.') { // try to find a period
PeriodFound = IL_TRUE;
break;
}
Argu--;
}
if (!PeriodFound) // if no period, no extension
return IL_FALSE;
if (!iStrCmp(Argu+1, Ext)) // extension and ext match?
return IL_TRUE;
return IL_FALSE; // if all else fails, return IL_FALSE
}
ILstring iGetExtension(ILconst_string FileName)
{
ILboolean PeriodFound = IL_FALSE;
ILstring Ext = (ILstring)FileName;
ILint i, Len = ilStrLen(FileName);
if (FileName == NULL || !Len) // if not a good filename/extension, exit early
return NULL;
Ext += Len; // start at the end
for (i = Len; i >= 0; i--) {
if (*Ext == '.') { // try to find a period
PeriodFound = IL_TRUE;
break;
}
Ext--;
}
if (!PeriodFound) // if no period, no extension
return NULL;
return Ext+1;
}
// Checks if the file exists
ILboolean iFileExists(ILconst_string FileName)
{
#if (!defined(_UNICODE) || !defined(_WIN32))
FILE *CheckFile = fopen(FileName, "rb");
#else // Windows uses _wfopen instead.
FILE *CheckFile = _wfopen(FileName, L"rb");
#endif//_UNICODE
if (CheckFile) {
fclose(CheckFile);
return IL_TRUE;
}
return IL_FALSE;
}
// Last time I tried, MSVC++'s fgets() was really really screwy
ILbyte *iFgets(char *buffer, ILuint maxlen)
{
ILuint counter = 0;
ILint temp = '\0';
while ((temp = igetc()) && temp != '\n' && temp != IL_EOF && counter < maxlen) {
buffer[counter] = temp;
counter++;
}
buffer[counter] = '\0';
if (temp == IL_EOF && counter == 0) // Only return NULL if no data was "got".
return NULL;
return (ILbyte*)buffer;
}
// A fast integer squareroot, completely accurate for x < 289.
// Taken from http://atoms.org.uk/sqrt/
// There is also a version that is accurate for all integers
// < 2^31, if we should need it
static int table[] = {
0, 16, 22, 27, 32, 35, 39, 42, 45, 48, 50, 53, 55, 57,
59, 61, 64, 65, 67, 69, 71, 73, 75, 76, 78, 80, 81, 83,
84, 86, 87, 89, 90, 91, 93, 94, 96, 97, 98, 99, 101, 102,
103, 104, 106, 107, 108, 109, 110, 112, 113, 114, 115, 116, 117, 118,
119, 120, 121, 122, 123, 124, 125, 126, 128, 128, 129, 130, 131, 132,
133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 144, 145,
146, 147, 148, 149, 150, 150, 151, 152, 153, 154, 155, 155, 156, 157,
158, 159, 160, 160, 161, 162, 163, 163, 164, 165, 166, 167, 167, 168,
169, 170, 170, 171, 172, 173, 173, 174, 175, 176, 176, 177, 178, 178,
179, 180, 181, 181, 182, 183, 183, 184, 185, 185, 186, 187, 187, 188,
189, 189, 190, 191, 192, 192, 193, 193, 194, 195, 195, 196, 197, 197,
198, 199, 199, 200, 201, 201, 202, 203, 203, 204, 204, 205, 206, 206,
207, 208, 208, 209, 209, 210, 211, 211, 212, 212, 213, 214, 214, 215,
215, 216, 217, 217, 218, 218, 219, 219, 220, 221, 221, 222, 222, 223,
224, 224, 225, 225, 226, 226, 227, 227, 228, 229, 229, 230, 230, 231,
231, 232, 232, 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238,
239, 240, 240, 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246,
246, 247, 247, 248, 248, 249, 249, 250, 250, 251, 251, 252, 252, 253,
253, 254, 254, 255
};
int iSqrt(int x) {
if (x >= 0x10000) {
if (x >= 0x1000000) {
if (x >= 0x10000000) {
if (x >= 0x40000000) {
return (table[x >> 24] << 8);
} else {
return (table[x >> 22] << 7);
}
} else if (x >= 0x4000000) {
return (table[x >> 20] << 6);
} else {
return (table[x >> 18] << 5);
}
} else if (x >= 0x100000) {
if (x >= 0x400000) {
return (table[x >> 16] << 4);
} else {
return (table[x >> 14] << 3);
}
} else if (x >= 0x40000) {
return (table[x >> 12] << 2);
} else {
return (table[x >> 10] << 1);
}
} else if (x >= 0x100) {
if (x >= 0x1000) {
if (x >= 0x4000) {
return (table[x >> 8]);
} else {
return (table[x >> 6] >> 1);
}
} else if (x >= 0x400) {
return (table[x >> 4] >> 2);
} else {
return (table[x >> 2] >> 3);
}
} else if (x >= 0) {
return table[x] >> 4;
}
//hm, x was negative....
return -1;
}
File diff suppressed because it is too large Load Diff
+401
View File
@@ -0,0 +1,401 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 03/04/2009
//
// Filename: src-IL/src/il_iwi.c
//
// Description: Reads from an Infinity Ward Image (.iwi) file from Call of Duty.
//
//-----------------------------------------------------------------------------
#include "il_internal.h"
#ifndef IL_NO_IWI
#include "il_dds.h"
typedef struct IWIHEAD
{
ILuint Signature;
ILubyte Format;
ILubyte Flags;
ILushort Width;
ILushort Height;
} IWIHEAD;
#define IWI_ARGB8 0x01
#define IWI_RGB8 0x02
#define IWI_ARGB4 0x03
#define IWI_A8 0x04
#define IWI_JPG 0x07
#define IWI_DXT1 0x0B
#define IWI_DXT3 0x0C
#define IWI_DXT5 0x0D
ILboolean iIsValidIwi(void);
ILboolean iCheckIwi(IWIHEAD *Header);
ILboolean iLoadIwiInternal(void);
ILboolean IwiInitMipmaps(ILimage *BaseImage, ILuint *NumMips);
ILboolean IwiReadImage(ILimage *BaseImage, IWIHEAD *Header, ILuint NumMips);
ILenum IwiGetFormat(ILubyte Format, ILubyte *Bpp);
//! Checks if the file specified in FileName is a valid IWI file.
ILboolean ilIsValidIwi(ILconst_string FileName)
{
ILHANDLE IwiFile;
ILboolean bIwi = IL_FALSE;
if (!iCheckExtension(FileName, IL_TEXT("iwi"))) {
ilSetError(IL_INVALID_EXTENSION);
return bIwi;
}
IwiFile = iopenr(FileName);
if (IwiFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bIwi;
}
bIwi = ilIsValidIwiF(IwiFile);
icloser(IwiFile);
return bIwi;
}
//! Checks if the ILHANDLE contains a valid IWI file at the current position.
ILboolean ilIsValidIwiF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iIsValidIwi();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Checks if Lump is a valid IWI lump.
ILboolean ilIsValidIwiL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iIsValidIwi();
}
// Internal function used to get the IWI header from the current file.
ILboolean iGetIwiHead(IWIHEAD *Header)
{
Header->Signature = GetLittleUInt();
Header->Format = igetc();
Header->Flags = igetc(); //@TODO: Find out what the flags mean.
Header->Width = GetLittleUShort();
Header->Height = GetLittleUShort();
// @TODO: Find out what is in the rest of the header.
iseek(18, IL_SEEK_CUR);
return IL_TRUE;
}
// Internal function to get the header and check it.
ILboolean iIsValidIwi(void)
{
IWIHEAD Header;
ILuint Pos = itell();
if (!iGetIwiHead(&Header))
return IL_FALSE;
// The length of the header varies, so we just go back to the original position.
iseek(Pos, IL_SEEK_CUR);
return iCheckIwi(&Header);
}
// Internal function used to check if the HEADER is a valid IWI header.
ILboolean iCheckIwi(IWIHEAD *Header)
{
if (Header->Signature != 0x06695749 && Header->Signature != 0x05695749) // 'IWi-' (version 6, and version 5 is the second).
return IL_FALSE;
if (Header->Width == 0 || Header->Height == 0)
return IL_FALSE;
// DXT images must have power-of-2 dimensions.
if (Header->Format == IWI_DXT1 || Header->Format == IWI_DXT3 || Header->Format == IWI_DXT5)
if (Header->Width != ilNextPower2(Header->Width) || Header->Height != ilNextPower2(Header->Height))
return IL_FALSE;
// 0x0B, 0x0C and 0x0D are DXT formats.
if (Header->Format != IWI_ARGB4 && Header->Format != IWI_RGB8 && Header->Format != IWI_ARGB8 && Header->Format != IWI_A8
&& Header->Format != IWI_DXT1 && Header->Format != IWI_DXT3 && Header->Format != IWI_DXT5)
return IL_FALSE;
return IL_TRUE;
}
//! Reads a IWI file
ILboolean ilLoadIwi(ILconst_string FileName)
{
ILHANDLE IwiFile;
ILboolean bIwi = IL_FALSE;
IwiFile = iopenr(FileName);
if (IwiFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bIwi;
}
bIwi = ilLoadIwiF(IwiFile);
icloser(IwiFile);
return bIwi;
}
//! Reads an already-opened IWI file
ILboolean ilLoadIwiF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iLoadIwiInternal();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Reads from a memory "lump" that contains a IWI
ILboolean ilLoadIwiL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iLoadIwiInternal();
}
// Internal function used to load the IWI.
ILboolean iLoadIwiInternal(void)
{
IWIHEAD Header;
ILuint NumMips = 0;
ILboolean HasMipmaps = IL_TRUE;
ILenum Format;
ILubyte Bpp;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
// Read the header and check it.
if (!iGetIwiHead(&Header))
return IL_FALSE;
if (!iCheckIwi(&Header)) {
ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
}
// From a post by Pointy on http://iwnation.com/forums/index.php?showtopic=27903,
// flags ending with 0x3 have no mipmaps.
HasMipmaps = ((Header.Flags & 0x03) == 0x03) ? IL_FALSE : IL_TRUE;
// Create the image, then create the mipmaps, then finally read the image.
Format = IwiGetFormat(Header.Format, &Bpp);
if (!ilTexImage(Header.Width, Header.Height, 1, Bpp, Format, IL_UNSIGNED_BYTE, NULL))
return IL_FALSE;
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
if (HasMipmaps)
if (!IwiInitMipmaps(iCurImage, &NumMips))
return IL_FALSE;
if (!IwiReadImage(iCurImage, &Header, NumMips))
return IL_FALSE;
return ilFixImage();
}
// Helper function to convert IWI formats to DevIL formats and Bpp.
ILenum IwiGetFormat(ILubyte Format, ILubyte *Bpp)
{
switch (Format)
{
case IWI_ARGB8:
*Bpp = 4;
return IL_BGRA;
case IWI_RGB8:
*Bpp = 3;
return IL_BGR;
case IWI_ARGB4:
*Bpp = 4;
return IL_BGRA;
case IWI_A8:
*Bpp = 1;
return IL_ALPHA;
case IWI_DXT1:
*Bpp = 4;
return IL_RGBA;
case IWI_DXT3:
*Bpp = 4;
return IL_RGBA;
case IWI_DXT5:
*Bpp = 4;
return IL_RGBA;
}
return 0; // Will never reach this.
}
// Function to intialize the mipmaps and determine the number of mipmaps.
ILboolean IwiInitMipmaps(ILimage *BaseImage, ILuint *NumMips)
{
ILimage *Image;
ILuint Width, Height, Mipmap;
Image = BaseImage;
Width = BaseImage->Width; Height = BaseImage->Height;
Image->Origin = IL_ORIGIN_UPPER_LEFT;
for (Mipmap = 0; Width != 1 && Height != 1; Mipmap++) {
// 1 is the smallest dimension possible.
Width = (Width >> 1) == 0 ? 1 : (Width >> 1);
Height = (Height >> 1) == 0 ? 1 : (Height >> 1);
Image->Mipmaps = ilNewImageFull(Width, Height, 1, BaseImage->Bpp, BaseImage->Format, BaseImage->Type, NULL);
if (Image->Mipmaps == NULL)
return IL_FALSE;
Image = Image->Mipmaps;
// ilNewImage does not set these.
Image->Format = BaseImage->Format;
Image->Type = BaseImage->Type;
// The origin is in the upper left.
Image->Origin = IL_ORIGIN_UPPER_LEFT;
}
*NumMips = Mipmap;
return IL_TRUE;
}
ILboolean IwiReadImage(ILimage *BaseImage, IWIHEAD *Header, ILuint NumMips)
{
ILimage *Image;
ILuint SizeOfData;
ILubyte *CompData = NULL;
ILint i, j, k, m;
for (i = NumMips; i >= 0; i--) {
Image = BaseImage;
// Go to the ith mipmap level.
// The mipmaps go from smallest to the largest.
for (j = 0; j < i; j++)
Image = Image->Mipmaps;
switch (Header->Format)
{
case IWI_ARGB8: // These are all
case IWI_RGB8: // uncompressed data,
case IWI_A8: // so just read it.
if (iread(Image->Data, 1, Image->SizeOfData) != Image->SizeOfData)
return IL_FALSE;
break;
case IWI_ARGB4: //@TODO: Find some test images for this.
// Data is in ARGB4 format - 4 bits per component.
SizeOfData = Image->Width * Image->Height * 2;
CompData = ialloc(SizeOfData); // Not really compressed - just in ARGB4 format.
if (CompData == NULL)
return IL_FALSE;
if (iread(CompData, 1, SizeOfData) != SizeOfData) {
ifree(CompData);
return IL_FALSE;
}
for (k = 0, m = 0; k < (ILint)Image->SizeOfData; k += 4, m += 2) {
// @TODO: Double the image data into the low and high nibbles for a better range of values.
Image->Data[k+0] = CompData[m] & 0xF0;
Image->Data[k+1] = (CompData[m] & 0x0F) << 4;
Image->Data[k+2] = CompData[m+1] & 0xF0;
Image->Data[k+3] = (CompData[m+1] & 0x0F) << 4;
}
break;
case IWI_DXT1:
// DXT1 data has at least 8 bytes, even for one pixel.
SizeOfData = IL_MAX(Image->Width * Image->Height / 2, 8);
CompData = ialloc(SizeOfData); // Gives a 6:1 compression ratio (or 8:1 for DXT1 with alpha)
if (CompData == NULL)
return IL_FALSE;
if (iread(CompData, 1, SizeOfData) != SizeOfData) {
ifree(CompData);
return IL_FALSE;
}
// Decompress the DXT1 data into Image (ith mipmap).
if (!DecompressDXT1(Image, CompData)) {
ifree(CompData);
return IL_FALSE;
}
// Keep a copy of the DXTC data if the user wants it.
if (ilGetInteger(IL_KEEP_DXTC_DATA) == IL_TRUE) {
Image->DxtcSize = SizeOfData;
Image->DxtcData = CompData;
Image->DxtcFormat = IL_DXT1;
CompData = NULL;
}
break;
case IWI_DXT3:
// DXT3 data has at least 16 bytes, even for one pixel.
SizeOfData = IL_MAX(Image->Width * Image->Height, 16);
CompData = ialloc(SizeOfData); // Gives a 4:1 compression ratio
if (CompData == NULL)
return IL_FALSE;
if (iread(CompData, 1, SizeOfData) != SizeOfData) {
ifree(CompData);
return IL_FALSE;
}
// Decompress the DXT3 data into Image (ith mipmap).
if (!DecompressDXT3(Image, CompData)) {
ifree(CompData);
return IL_FALSE;
}
break;
case IWI_DXT5:
// DXT5 data has at least 16 bytes, even for one pixel.
SizeOfData = IL_MAX(Image->Width * Image->Height, 16);
CompData = ialloc(SizeOfData); // Gives a 4:1 compression ratio
if (CompData == NULL)
return IL_FALSE;
if (iread(CompData, 1, SizeOfData) != SizeOfData) {
ifree(CompData);
return IL_FALSE;
}
// Decompress the DXT5 data into Image (ith mipmap).
if (!DecompressDXT5(Image, CompData)) {
ifree(CompData);
return IL_FALSE;
}
break;
}
ifree(CompData);
}
return IL_TRUE;
}
#endif//IL_NO_IWI
+823
View File
@@ -0,0 +1,823 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 03/07/2009
//
// Filename: src-IL/src/il_jp2.c
//
// Description: Jpeg-2000 (.jp2) functions
//
//-----------------------------------------------------------------------------
#include "il_internal.h"
#ifndef IL_NO_JP2
#include <jasper/jasper.h>
#include "il_jp2.h"
#if defined(_WIN32) && defined(IL_USE_PRAGMA_LIBS)
#if defined(_MSC_VER) || defined(__BORLANDC__)
#ifndef _DEBUG
#pragma comment(lib, "libjasper.lib")
#else
#pragma comment(lib, "libjasper-d.lib")
#endif
#endif
#endif
ILboolean iIsValidJp2(void);
ILboolean JasperInit = IL_FALSE;
//! Checks if the file specified in FileName is a valid .jp2 file.
ILboolean ilIsValidJp2(ILconst_string FileName)
{
ILHANDLE Jp2File;
ILboolean bJp2 = IL_FALSE;
if (!iCheckExtension(FileName, IL_TEXT("jp2")) && !iCheckExtension(FileName, IL_TEXT("jpx")) &&
!iCheckExtension(FileName, IL_TEXT("j2k")) && !iCheckExtension(FileName, IL_TEXT("j2c"))) {
ilSetError(IL_INVALID_EXTENSION);
return bJp2;
}
Jp2File = iopenr(FileName);
if (Jp2File == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bJp2;
}
bJp2 = ilIsValidJp2F(Jp2File);
icloser(Jp2File);
return bJp2;
}
//! Checks if the ILHANDLE contains a valid .jp2 file at the current position.
ILboolean ilIsValidJp2F(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iIsValidJp2();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Checks if Lump is a valid .jp2 lump.
ILboolean ilIsValidJp2L(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iIsValidJp2();
}
// Internal function to get the header and check it.
ILboolean iIsValidJp2(void)
{
ILubyte Signature[4];
iseek(4, IL_SEEK_CUR); // Skip the 4 bytes that tell the size of the signature box.
if (iread(Signature, 1, 4) != 4) {
iseek(-4, IL_SEEK_CUR);
return IL_FALSE; // File read error
}
iseek(-8, IL_SEEK_CUR); // Restore to previous state
// Signature is 'jP\040\040' by the specs (or 0x6A502020).
// http://www.jpeg.org/public/fcd15444-6.pdf
if (Signature[0] != 0x6A || Signature[1] != 0x50 ||
Signature[2] != 0x20 || Signature[3] != 0x20)
return IL_FALSE;
return IL_TRUE;
}
//! Reads a Jpeg2000 file.
ILboolean ilLoadJp2(ILconst_string FileName)
{
ILHANDLE Jp2File;
ILboolean bRet;
Jp2File = iopenr(FileName);
if (Jp2File == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return IL_FALSE;
}
bRet = ilLoadJp2F(Jp2File);
icloser(Jp2File);
return bRet;
}
//! Reads an already-opened Jpeg2000 file.
ILboolean ilLoadJp2F(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
jas_stream_t *Stream;
iSetInputFile(File);
FirstPos = itell();
if (!JasperInit) {
if (jas_init()) {
ilSetError(IL_LIB_JP2_ERROR);
return IL_FALSE;
}
JasperInit = IL_TRUE;
}
Stream = iJp2ReadStream();
if (!Stream)
{
ilSetError(IL_COULD_NOT_OPEN_FILE);
return IL_FALSE;
}
bRet = iLoadJp2Internal(Stream, NULL);
// Close the input stream.
jas_stream_close(Stream);
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Reads from a memory "lump" that contains a Jpeg2000 stream.
ILboolean ilLoadJp2L(const void *Lump, ILuint Size)
{
return ilLoadJp2LInternal(Lump, Size, NULL);
}
//! This is separated so that it can be called for other file types, such as .icns.
ILboolean ilLoadJp2LInternal(const void *Lump, ILuint Size, ILimage *Image)
{
ILboolean bRet;
jas_stream_t *Stream;
if (!JasperInit) {
if (jas_init()) {
ilSetError(IL_LIB_JP2_ERROR);
return IL_FALSE;
}
JasperInit = IL_TRUE;
}
Stream = jas_stream_memopen((char*)Lump, Size);
if (!Stream)
{
ilSetError(IL_COULD_NOT_OPEN_FILE);
return IL_FALSE;
}
bRet = iLoadJp2Internal(Stream, Image);
// Close the input stream.
jas_stream_close(Stream);
return bRet;
}
// Internal function used to load the Jpeg2000 stream.
ILboolean iLoadJp2Internal(jas_stream_t *Stream, ILimage *Image)
{
jas_image_t *Jp2Image = NULL;
jas_matrix_t *origdata;
ILuint x, y, c, Error;
ILimage *TempImage;
// Decode image
Jp2Image = jas_image_decode(Stream, -1, 0);
if (!Jp2Image)
{
ilSetError(IL_ILLEGAL_FILE_VALUE);
jas_stream_close(Stream);
return IL_FALSE;
}
// JasPer likes to buffer a lot, so it may try buffering past the end
// of the file. iread naturally sets IL_FILE_READ_ERROR if it tries
// reading past the end of the file, but this actually is not an error.
Error = ilGetError();
// Put the error back if it is not IL_FILE_READ_ERROR.
if (Error != IL_FILE_READ_ERROR)
ilSetError(Error);
// We're not supporting anything other than 8 bits/component yet.
if (jas_image_cmptprec(Jp2Image, 0) != 8)
{
jas_image_destroy(Jp2Image);
ilSetError(IL_ILLEGAL_FILE_VALUE);
return IL_FALSE;
}
switch (jas_image_numcmpts(Jp2Image))
{
//@TODO: Can we do alpha data? jas_image_cmpttype always returns 0 for this case.
case 1: // Assuming this is luminance data.
if (Image == NULL) {
ilTexImage(jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 1, IL_LUMINANCE, IL_UNSIGNED_BYTE, NULL);
TempImage = iCurImage;
}
else {
ifree(Image->Data); // @TODO: Not really the most efficient way to do this...
ilInitImage(Image, jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 1, IL_LUMINANCE, IL_UNSIGNED_BYTE, NULL);
TempImage = Image;
}
break;
case 2: // Assuming this is luminance-alpha data.
if (Image == NULL) {
ilTexImage(jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 2, IL_LUMINANCE_ALPHA, IL_UNSIGNED_BYTE, NULL);
TempImage = iCurImage;
}
else {
ifree(Image->Data); // @TODO: Not really the most efficient way to do this...
ilInitImage(Image, jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 2, IL_LUMINANCE_ALPHA, IL_UNSIGNED_BYTE, NULL);
TempImage = Image;
}
break;
case 3:
if (Image == NULL) {
ilTexImage(jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL);
TempImage = iCurImage;
}
else {
ifree(Image->Data); // @TODO: Not really the most efficient way to do this...
ilInitImage(Image, jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL);
TempImage = Image;
}
break;
case 4:
if (Image == NULL) {
ilTexImage(jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL);
TempImage = iCurImage;
}
else {
ifree(Image->Data); // @TODO: Not really the most efficient way to do this...
ilInitImage(Image, jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL);
TempImage = Image;
}
break;
default:
jas_image_destroy(Jp2Image);
ilSetError(IL_ILLEGAL_FILE_VALUE);
return IL_FALSE;
}
TempImage->Origin = IL_ORIGIN_UPPER_LEFT;
// JasPer stores the data channels separately.
// I am assuming RGBA format. Is it possible for other formats to be included?
for (c = 0; c < TempImage->Bpp; c++)
{
origdata = jas_matrix_create(TempImage->Height, TempImage->Width);
if (!origdata)
{
ilSetError(IL_LIB_JP2_ERROR);
return IL_FALSE; // @TODO: Error
}
// Have to convert data into an intermediate matrix format.
if (jas_image_readcmpt(Jp2Image, c, 0, 0, TempImage->Width, TempImage->Height, origdata))
{
return IL_FALSE;
}
for (y = 0; y < TempImage->Height; y++)
{
for (x = 0; x < TempImage->Width; x++)
{
TempImage->Data[y * TempImage->Width * TempImage->Bpp + x * TempImage->Bpp + c] = origdata->data_[y * origdata->numcols_ + x];
}
}
jas_matrix_destroy(origdata);
}
jas_image_destroy(Jp2Image);
return ilFixImage();
}
static int iJp2_file_read(jas_stream_obj_t *obj, char *buf, int cnt)
{
obj;
return iread(buf, 1, cnt);
}
static int iJp2_file_write(jas_stream_obj_t *obj, char *buf, int cnt)
{
obj;
return iwrite(buf, 1, cnt);
}
static long iJp2_file_seek(jas_stream_obj_t *obj, long offset, int origin)
{
obj;
// We could just pass origin to iseek, but this is probably more portable.
switch (origin)
{
case SEEK_SET:
return iseek(offset, IL_SEEK_SET);
case SEEK_CUR:
return iseek(offset, IL_SEEK_CUR);
case SEEK_END:
return iseek(offset, IL_SEEK_END);
}
return 0; // Failed
}
static int iJp2_file_close(jas_stream_obj_t *obj)
{
obj;
return 0; // We choose when we want to close the file.
}
static jas_stream_ops_t jas_stream_devilops = {
iJp2_file_read,
iJp2_file_write,
iJp2_file_seek,
iJp2_file_close
};
static jas_stream_t *jas_stream_create(void);
static void jas_stream_destroy(jas_stream_t *stream);
static void jas_stream_initbuf(jas_stream_t *stream, int bufmode, char *buf, int bufsize);
// Modified version of jas_stream_fopen and jas_stream_memopen from jas_stream.c of JasPer
// so that we can use our own file routines.
jas_stream_t *iJp2ReadStream()
{
jas_stream_t *stream;
jas_stream_memobj_t *obj;
if (!(stream = jas_stream_create())) {
return 0;
}
/* A stream associated with a memory buffer is always opened
for both reading and writing in binary mode. */
stream->openmode_ = JAS_STREAM_READ | JAS_STREAM_BINARY;
/* We use buffering whether it is from memory or a file. */
jas_stream_initbuf(stream, JAS_STREAM_FULLBUF, 0, 0);
/* Select the operations for a memory stream. */
stream->ops_ = &jas_stream_devilops;
/* Allocate memory for the underlying memory stream object. */
if (!(obj = jas_malloc(sizeof(jas_stream_memobj_t)))) {
jas_stream_destroy(stream);
return 0;
}
stream->obj_ = (void *) obj;
/* Initialize a few important members of the memory stream object. */
obj->myalloc_ = 0;
obj->buf_ = 0;
// Shouldn't need any of this.
///* If the buffer size specified is nonpositive, then the buffer
//is allocated internally and automatically grown as needed. */
//if (bufsize <= 0) {
// obj->bufsize_ = 1024;
// obj->growable_ = 1;
//} else {
// obj->bufsize_ = bufsize;
// obj->growable_ = 0;
//}
//if (buf) {
// obj->buf_ = (unsigned char *) buf;
//} else {
// obj->buf_ = jas_malloc(obj->bufsize_ * sizeof(char));
// obj->myalloc_ = 1;
//}
//if (!obj->buf_) {
// jas_stream_close(stream);
// return 0;
//}
//if (bufsize > 0 && buf) {
// /* If a buffer was supplied by the caller and its length is positive,
// make the associated buffer data appear in the stream initially. */
// obj->len_ = bufsize;
//} else {
// /* The stream is initially empty. */
// obj->len_ = 0;
//}
//obj->pos_ = 0;
return stream;
}
// The following functions are taken directly from jas_stream.c of JasPer,
// since they are designed to be used within JasPer only.
static void jas_stream_initbuf(jas_stream_t *stream, int bufmode, char *buf,
int bufsize)
{
/* If this function is being called, the buffer should not have been
initialized yet. */
assert(!stream->bufbase_);
if (bufmode != JAS_STREAM_UNBUF) {
/* The full- or line-buffered mode is being employed. */
if (!buf) {
/* The caller has not specified a buffer to employ, so allocate
one. */
if ((stream->bufbase_ = jas_malloc(JAS_STREAM_BUFSIZE +
JAS_STREAM_MAXPUTBACK))) {
stream->bufmode_ |= JAS_STREAM_FREEBUF;
stream->bufsize_ = JAS_STREAM_BUFSIZE;
} else {
/* The buffer allocation has failed. Resort to unbuffered
operation. */
stream->bufbase_ = stream->tinybuf_;
stream->bufsize_ = 1;
}
} else {
/* The caller has specified a buffer to employ. */
/* The buffer must be large enough to accommodate maximum
putback. */
assert(bufsize > JAS_STREAM_MAXPUTBACK);
stream->bufbase_ = JAS_CAST(uchar *, buf);
stream->bufsize_ = bufsize - JAS_STREAM_MAXPUTBACK;
}
} else {
/* The unbuffered mode is being employed. */
/* A buffer should not have been supplied by the caller. */
assert(!buf);
/* Use a trivial one-character buffer. */
stream->bufbase_ = stream->tinybuf_;
stream->bufsize_ = 1;
}
stream->bufstart_ = &stream->bufbase_[JAS_STREAM_MAXPUTBACK];
stream->ptr_ = stream->bufstart_;
stream->cnt_ = 0;
stream->bufmode_ |= bufmode & JAS_STREAM_BUFMODEMASK;
}
static jas_stream_t *jas_stream_create()
{
jas_stream_t *stream;
if (!(stream = jas_malloc(sizeof(jas_stream_t)))) {
return 0;
}
stream->openmode_ = 0;
stream->bufmode_ = 0;
stream->flags_ = 0;
stream->bufbase_ = 0;
stream->bufstart_ = 0;
stream->bufsize_ = 0;
stream->ptr_ = 0;
stream->cnt_ = 0;
stream->ops_ = 0;
stream->obj_ = 0;
stream->rwcnt_ = 0;
stream->rwlimit_ = -1;
return stream;
}
static void jas_stream_destroy(jas_stream_t *stream)
{
/* If the memory for the buffer was allocated with malloc, free
this memory. */
if ((stream->bufmode_ & JAS_STREAM_FREEBUF) && stream->bufbase_) {
jas_free(stream->bufbase_);
stream->bufbase_ = 0;
}
jas_free(stream);
}
jas_stream_t *iJp2WriteStream()
{
jas_stream_t *stream;
jas_stream_memobj_t *obj;
if (!(stream = jas_stream_create())) {
return 0;
}
/* A stream associated with a memory buffer is always opened
for both reading and writing in binary mode. */
stream->openmode_ = JAS_STREAM_WRITE | JAS_STREAM_BINARY;
/* We use buffering whether it is from memory or a file. */
jas_stream_initbuf(stream, JAS_STREAM_FULLBUF, 0, 0);
/* Select the operations for a memory stream. */
stream->ops_ = &jas_stream_devilops;
/* Allocate memory for the underlying memory stream object. */
if (!(obj = jas_malloc(sizeof(jas_stream_memobj_t)))) {
jas_stream_destroy(stream);
return 0;
}
stream->obj_ = (void *) obj;
/* Initialize a few important members of the memory stream object. */
obj->myalloc_ = 0;
obj->buf_ = 0;
return stream;
}
//! Writes a Jp2 file
ILboolean ilSaveJp2(const ILstring FileName)
{
ILHANDLE Jp2File;
ILuint Jp2Size;
if (ilGetBoolean(IL_FILE_MODE) == IL_FALSE) {
if (iFileExists(FileName)) {
ilSetError(IL_FILE_ALREADY_EXISTS);
return IL_FALSE;
}
}
Jp2File = iopenw(FileName);
if (Jp2File == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return IL_FALSE;
}
Jp2Size = ilSaveJp2F(Jp2File);
iclosew(Jp2File);
if (Jp2Size == 0)
return IL_FALSE;
return IL_TRUE;
}
//! Writes a Jp2 to an already-opened file
ILuint ilSaveJp2F(ILHANDLE File)
{
ILuint Pos;
iSetOutputFile(File);
Pos = itellw();
if (iSaveJp2Internal() == IL_FALSE)
return 0; // Error occurred
return itellw() - Pos; // Return the number of bytes written.
}
//! Writes a Jp2 to a memory "lump"
ILuint ilSaveJp2L(void *Lump, ILuint Size)
{
ILuint Pos;
iSetOutputLump(Lump, Size);
Pos = itellw();
if (iSaveJp2Internal() == IL_FALSE)
return 0; // Error occurred
return itellw() - Pos; // Return the number of bytes written.
}
// Function from OpenSceneGraph (originally called getdata in their sources):
// http://openscenegraph.sourcearchive.com/documentation/2.2.0/ReaderWriterJP2_8cpp-source.html
ILint Jp2ConvertData(jas_stream_t *in, jas_image_t *image)
{
int ret;
int numcmpts;
int cmptno;
jas_matrix_t *data[4];
int x;
int y;
int width, height;
width = jas_image_cmptwidth(image, 0);
height = jas_image_cmptheight(image, 0);
numcmpts = jas_image_numcmpts(image);
ret = -1;
data[0] = 0;
data[1] = 0;
data[2] = 0;
data[3] = 0;
for (cmptno = 0; cmptno < numcmpts; ++cmptno) {
if (!(data[cmptno] = jas_matrix_create(1, width))) {
goto done;
}
}
for (y = height - 1; y >= 0; --y)
// for (y = 0; y < height; ++y)
{
for (x = 0; x < width; ++x)
{
for (cmptno = 0; cmptno < numcmpts; ++cmptno)
{
// The sample data is unsigned.
int c;
if ((c = jas_stream_getc(in)) == EOF) {
return -1;
}
jas_matrix_set(data[cmptno], 0, x, c);
}
}
for (cmptno = 0; cmptno < numcmpts; ++cmptno) {
if (jas_image_writecmpt(image, cmptno, 0, y, width, 1,
data[cmptno])) {
goto done;
}
}
}
jas_stream_flush(in);
ret = 0;
done:
for (cmptno = 0; cmptno < numcmpts; ++cmptno) {
if (data[cmptno]) {
jas_matrix_destroy(data[cmptno]);
}
}
return ret;
}
// Internal function used to save the Jp2.
// Since the JasPer documentation is extremely incomplete, I had to look at how OpenSceneGraph uses it:
// http://openscenegraph.sourcearchive.com/documentation/2.2.0/ReaderWriterJP2_8cpp-source.html
//@TODO: Do we need to worry about images with depths > 1?
ILboolean iSaveJp2Internal()
{
jas_image_t *Jp2Image;
jas_image_cmptparm_t cmptparm[4];
jas_stream_t *Mem, *Stream;
ILuint NumChans, i;
ILenum NewFormat, NewType = IL_UNSIGNED_BYTE;
ILimage *TempImage = iCurImage;
if (!JasperInit) {
if (jas_init()) {
ilSetError(IL_LIB_JP2_ERROR);
return IL_FALSE;
}
JasperInit = IL_TRUE;
}
if (iCurImage->Type != IL_UNSIGNED_BYTE) { //@TODO: Support greater than 1 bpc.
NewType = IL_UNSIGNED_BYTE;
}
//@TODO: Do luminance/luminance-alpha/alpha separately.
switch (iCurImage->Format)
{
case IL_LUMINANCE:
NewFormat = IL_LUMINANCE;
NumChans = 1;
break;
case IL_ALPHA:
NewFormat = IL_ALPHA;
NumChans = 1;
break;
case IL_LUMINANCE_ALPHA:
NewFormat = IL_LUMINANCE_ALPHA;
NumChans = 2;
break;
case IL_COLOUR_INDEX: // Assuming the color palette does not have an alpha value.
//@TODO: Check for this in the future.
case IL_RGB:
case IL_BGR:
NewFormat = IL_RGB;
NumChans = 3;
break;
case IL_RGBA:
case IL_BGRA:
NewFormat = IL_RGBA;
NumChans = 4;
break;
}
if (NewType != iCurImage->Type || NewFormat != iCurImage->Format) {
TempImage = iConvertImage(iCurImage, NewFormat, NewType);
if (TempImage == NULL)
return IL_FALSE;
}
// The origin is always in the lower left corner. Flip the buffer if it is not.
if (TempImage->Origin == IL_ORIGIN_UPPER_LEFT)
iFlipBuffer(TempImage->Data, TempImage->Depth, TempImage->Bps, TempImage->Height);
// Have to tell JasPer about each channel. In our case, they all have the same information.
for (i = 0; i < NumChans; i++) {
cmptparm[i].width = iCurImage->Width;
cmptparm[i].height = iCurImage->Height;
cmptparm[i].hstep = 1;
cmptparm[i].vstep = 1;
cmptparm[i].tlx = 0;
cmptparm[i].tly = 0;
cmptparm[i].prec = 8;
cmptparm[i].sgnd = 0; // Unsigned data
}
// Using the unknown color space, since we have not determined the space yet.
// This is done in the following switch statement.
Jp2Image = jas_image_create(NumChans, cmptparm, JAS_CLRSPC_UNKNOWN);
if (Jp2Image == NULL) {
ilSetError(IL_LIB_JP2_ERROR);
return IL_FALSE;
}
switch (NumChans)
{
case 1:
jas_image_setclrspc(Jp2Image, JAS_CLRSPC_SGRAY);
if (NewFormat == IL_LUMINANCE)
jas_image_setcmpttype(Jp2Image, 0, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y));
else // IL_ALPHA
jas_image_setcmpttype(Jp2Image, 0, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_OPACITY));
break;
case 2:
jas_image_setclrspc(Jp2Image, JAS_CLRSPC_SGRAY);
jas_image_setcmpttype(Jp2Image, 0, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y));
jas_image_setcmpttype(Jp2Image, 1, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_OPACITY));
break;
case 3:
jas_image_setclrspc(Jp2Image, JAS_CLRSPC_SRGB);
jas_image_setcmpttype(Jp2Image, 0, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R));
jas_image_setcmpttype(Jp2Image, 1, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G));
jas_image_setcmpttype(Jp2Image, 2, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B));
break;
case 4:
jas_image_setclrspc(Jp2Image, JAS_CLRSPC_SRGB);
jas_image_setcmpttype(Jp2Image, 0, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R));
jas_image_setcmpttype(Jp2Image, 1, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G));
jas_image_setcmpttype(Jp2Image, 2, JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B));
jas_image_setcmpttype(Jp2Image, 3, JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_OPACITY));
break;
}
Mem = jas_stream_memopen((char*)TempImage->Data, TempImage->SizeOfData);
if (Mem == NULL) {
jas_image_destroy(Jp2Image);
ilSetError(IL_LIB_JP2_ERROR);
return IL_FALSE;
}
Stream = iJp2WriteStream();
if (Stream == NULL) {
jas_stream_close(Mem);
jas_image_destroy(Jp2Image);
ilSetError(IL_LIB_JP2_ERROR);
return IL_FALSE;
}
// Puts data in the format that JasPer wants it in.
Jp2ConvertData(Mem, Jp2Image);
// Does all of the encoding.
if (jas_image_encode(Jp2Image, Stream, jas_image_strtofmt("jp2"), NULL)) { //@TODO: Do we want to use any options?
jas_stream_close(Mem);
jas_stream_close(Stream);
jas_image_destroy(Jp2Image);
ilSetError(IL_LIB_JP2_ERROR);
return IL_FALSE;
}
jas_stream_flush(Stream); // Do any final writing.
// Close the memory and output streams.
jas_stream_close(Mem);
jas_stream_close(Stream);
// Destroy the JasPer image.
jas_image_destroy(Jp2Image);
// Destroy our temporary image if we used one.
if (TempImage != iCurImage)
ilCloseImage(TempImage);
return IL_TRUE;
}
#endif//IL_NO_JP2
File diff suppressed because it is too large Load Diff
+198
View File
@@ -0,0 +1,198 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 03/07/2009
//
// Filename: src-IL/src/il_lif.c
//
// Description: Reads a Homeworld image.
//
//-----------------------------------------------------------------------------
#include "il_internal.h"
#ifndef IL_NO_LIF
#include "il_lif.h"
//! Checks if the file specified in FileName is a valid Lif file.
ILboolean ilIsValidLif(ILconst_string FileName)
{
ILHANDLE LifFile;
ILboolean bLif = IL_FALSE;
if (!iCheckExtension(FileName, IL_TEXT("lif"))) {
ilSetError(IL_INVALID_EXTENSION);
return bLif;
}
LifFile = iopenr(FileName);
if (LifFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bLif;
}
bLif = ilIsValidLifF(LifFile);
icloser(LifFile);
return bLif;
}
//! Checks if the ILHANDLE contains a valid Lif file at the current position.
ILboolean ilIsValidLifF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iIsValidLif();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Checks if Lump is a valid Lif lump.
ILboolean ilIsValidLifL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iIsValidLif();
}
// Internal function used to get the Lif header from the current file.
ILboolean iGetLifHead(LIF_HEAD *Header)
{
iread(Header->Id, 1, 8);
Header->Version = GetLittleUInt();
Header->Flags = GetLittleUInt();
Header->Width = GetLittleUInt();
Header->Height = GetLittleUInt();
Header->PaletteCRC = GetLittleUInt();
Header->ImageCRC = GetLittleUInt();
Header->PalOffset = GetLittleUInt();
Header->TeamEffect0 = GetLittleUInt();
Header->TeamEffect1 = GetLittleUInt();
return IL_TRUE;
}
// Internal function to get the header and check it.
ILboolean iIsValidLif()
{
LIF_HEAD Head;
if (!iGetLifHead(&Head))
return IL_FALSE;
iseek(-(ILint)sizeof(LIF_HEAD), IL_SEEK_CUR);
return iCheckLif(&Head);
}
// Internal function used to check if the HEADER is a valid Lif header.
ILboolean iCheckLif(LIF_HEAD *Header)
{
if (Header->Version != 260 || Header->Flags != 50)
return IL_FALSE;
if (stricmp(Header->Id, "Willy 7"))
return IL_FALSE;
return IL_TRUE;
}
//! Reads a .Lif file
ILboolean ilLoadLif(ILconst_string FileName)
{
ILHANDLE LifFile;
ILboolean bLif = IL_FALSE;
LifFile = iopenr(FileName);
if (LifFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bLif;
}
bLif = ilLoadLifF(LifFile);
icloser(LifFile);
return bLif;
}
//! Reads an already-opened .Lif file
ILboolean ilLoadLifF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iLoadLifInternal();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Reads from a memory "lump" that contains a .Lif
ILboolean ilLoadLifL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iLoadLifInternal();
}
ILboolean iLoadLifInternal()
{
LIF_HEAD LifHead;
ILuint i;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
if (!iGetLifHead(&LifHead))
return IL_FALSE;
if (!ilTexImage(LifHead.Width, LifHead.Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) {
return IL_FALSE;
}
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
iCurImage->Pal.Palette = (ILubyte*)ialloc(1024);
if (iCurImage->Pal.Palette == NULL)
return IL_FALSE;
iCurImage->Pal.PalSize = 1024;
iCurImage->Pal.PalType = IL_PAL_RGBA32;
if (iread(iCurImage->Data, LifHead.Width * LifHead.Height, 1) != 1)
return IL_FALSE;
if (iread(iCurImage->Pal.Palette, 1, 1024) != 1024)
return IL_FALSE;
// Each data offset is offset by -1, so we add one.
for (i = 0; i < iCurImage->SizeOfData; i++) {
iCurImage->Data[i]++;
}
return ilFixImage();
}
#endif//IL_NO_LIF
+30
View File
@@ -0,0 +1,30 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2002 by Denton Woods
// Last modified: 02/16/2002 <--Y2K Compliant! =]
//
// Filename: src-IL/src/il_main.c
//
// Description: Startup function
//
//-----------------------------------------------------------------------------
#include "il_internal.h"
/* Only needed for MSVC++ unless extended to actually do something =) */
#if defined(_WIN32) && defined(_MSC_VER)
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
hModule; ul_reason_for_call; lpReserved;
if (ul_reason_for_call == DLL_PROCESS_ATTACH) {
//ilInit();
}
return TRUE;
}
#endif
+948
View File
@@ -0,0 +1,948 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 01/24/2009
//
// Filename: src-IL/src/il_manip.c
//
// Description: Image manipulation
//
//-----------------------------------------------------------------------------
#include "il_internal.h"
#include "il_manip.h"
ILAPI void ILAPIENTRY iFlipBuffer(ILubyte *buff, ILuint depth, ILuint line_size, ILuint line_num)
{
ILubyte *StartPtr, *EndPtr;
ILuint y, d;
const ILuint size = line_num * line_size;
for (d = 0; d < depth; d++) {
StartPtr = buff + d * size;
EndPtr = buff + d * size + size;
for (y = 0; y < (line_num/2); y++) {
EndPtr -= line_size;
iMemSwap(StartPtr, EndPtr, line_size);
StartPtr += line_size;
}
}
}
// Just created for internal use.
ILubyte* iFlipNewBuffer(ILubyte *buff, ILuint depth, ILuint line_size, ILuint line_num)
{
ILubyte *data;
ILubyte *s1, *s2;
ILuint y, d;
const ILuint size = line_num * line_size;
if ((data = (ILubyte*)ialloc(depth*size)) == NULL)
return IL_FALSE;
for (d = 0; d < depth; d++) {
s1 = buff + d * size;
s2 = data + d * size+size;
for (y = 0; y < line_num; y++) {
s2 -= line_size;
memcpy(s2,s1,line_size);
s1 += line_size;
}
}
return data;
}
// Flips an image over its x axis
ILboolean ilFlipImage()
{
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
iCurImage->Origin = (iCurImage->Origin == IL_ORIGIN_LOWER_LEFT) ?
IL_ORIGIN_UPPER_LEFT : IL_ORIGIN_LOWER_LEFT;
iFlipBuffer(iCurImage->Data,iCurImage->Depth,iCurImage->Bps,iCurImage->Height);
return IL_TRUE;
}
// Just created for internal use.
ILubyte* ILAPIENTRY iGetFlipped(ILimage *img)
{
if (img == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return NULL;
}
return iFlipNewBuffer(img->Data,img->Depth,img->Bps,img->Height);
}
//@JASON New routine created 28/03/2001
//! Mirrors an image over its y axis
ILboolean ILAPIENTRY iMirror() {
ILubyte *Data, *DataPtr, *Temp;
ILuint y, d, PixLine;
ILint x, c;
ILushort *ShortPtr, *TempShort;
ILuint *IntPtr, *TempInt;
ILdouble *DblPtr, *TempDbl;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
Data = (ILubyte*)ialloc(iCurImage->SizeOfData);
if (Data == NULL)
return IL_FALSE;
PixLine = iCurImage->Bps / iCurImage->Bpc;
switch (iCurImage->Bpc)
{
case 1:
Temp = iCurImage->Data;
for (d = 0; d < iCurImage->Depth; d++) {
DataPtr = Data + d * iCurImage->SizeOfPlane;
for (y = 0; y < iCurImage->Height; y++) {
for (x = iCurImage->Width - 1; x >= 0; x--) {
for (c = 0; c < iCurImage->Bpp; c++, Temp++) {
DataPtr[y * PixLine + x * iCurImage->Bpp + c] = *Temp;
}
}
}
}
break;
case 2:
TempShort = (ILushort*)iCurImage->Data;
for (d = 0; d < iCurImage->Depth; d++) {
ShortPtr = (ILushort*)(Data + d * iCurImage->SizeOfPlane);
for (y = 0; y < iCurImage->Height; y++) {
for (x = iCurImage->Width - 1; x >= 0; x--) {
for (c = 0; c < iCurImage->Bpp; c++, TempShort++) {
ShortPtr[y * PixLine + x * iCurImage->Bpp + c] = *TempShort;
}
}
}
}
break;
case 4:
TempInt = (ILuint*)iCurImage->Data;
for (d = 0; d < iCurImage->Depth; d++) {
IntPtr = (ILuint*)(Data + d * iCurImage->SizeOfPlane);
for (y = 0; y < iCurImage->Height; y++) {
for (x = iCurImage->Width - 1; x >= 0; x--) {
for (c = 0; c < iCurImage->Bpp; c++, TempInt++) {
IntPtr[y * PixLine + x * iCurImage->Bpp + c] = *TempInt;
}
}
}
}
break;
case 8:
TempDbl = (ILdouble*)iCurImage->Data;
for (d = 0; d < iCurImage->Depth; d++) {
DblPtr = (ILdouble*)(Data + d * iCurImage->SizeOfPlane);
for (y = 0; y < iCurImage->Height; y++) {
for (x = iCurImage->Width - 1; x >= 0; x--) {
for (c = 0; c < iCurImage->Bpp; c++, TempDbl++) {
DblPtr[y * PixLine + x * iCurImage->Bpp + c] = *TempDbl;
}
}
}
}
break;
}
ifree(iCurImage->Data);
iCurImage->Data = Data;
return IL_TRUE;
}
// Should we add type to the parameter list?
// Copies a 1d block of pixels to the buffer pointed to by Data.
ILboolean ilCopyPixels1D(ILuint XOff, ILuint Width, void *Data)
{
ILuint x, c, NewBps, NewOff, PixBpp;
ILubyte *Temp = (ILubyte*)Data, *TempData = iCurImage->Data;
if (ilIsEnabled(IL_ORIGIN_SET)) {
if ((ILenum)ilGetInteger(IL_ORIGIN_MODE) != iCurImage->Origin) {
TempData = iGetFlipped(iCurImage);
if (TempData == NULL)
return IL_FALSE;
}
}
PixBpp = iCurImage->Bpp * iCurImage->Bpc;
if (iCurImage->Width < XOff + Width) {
NewBps = (iCurImage->Width - XOff) * PixBpp;
}
else {
NewBps = Width * PixBpp;
}
NewOff = XOff * PixBpp;
for (x = 0; x < NewBps; x += PixBpp) {
for (c = 0; c < PixBpp; c++) {
Temp[x + c] = TempData[(x + NewOff) + c];
}
}
if (TempData != iCurImage->Data)
ifree(TempData);
return IL_TRUE;
}
// Copies a 2d block of pixels to the buffer pointed to by Data.
ILboolean ilCopyPixels2D(ILuint XOff, ILuint YOff, ILuint Width, ILuint Height, void *Data)
{
ILuint x, y, c, NewBps, DataBps, NewXOff, NewHeight, PixBpp;
ILubyte *Temp = (ILubyte*)Data, *TempData = iCurImage->Data;
if (ilIsEnabled(IL_ORIGIN_SET)) {
if ((ILenum)ilGetInteger(IL_ORIGIN_MODE) != iCurImage->Origin) {
TempData = iGetFlipped(iCurImage);
if (TempData == NULL)
return IL_FALSE;
}
}
PixBpp = iCurImage->Bpp * iCurImage->Bpc;
if (iCurImage->Width < XOff + Width)
NewBps = (iCurImage->Width - XOff) * PixBpp;
else
NewBps = Width * PixBpp;
if (iCurImage->Height < YOff + Height)
NewHeight = iCurImage->Height - YOff;
else
NewHeight = Height;
DataBps = Width * PixBpp;
NewXOff = XOff * PixBpp;
for (y = 0; y < NewHeight; y++) {
for (x = 0; x < NewBps; x += PixBpp) {
for (c = 0; c < PixBpp; c++) {
Temp[y * DataBps + x + c] =
TempData[(y + YOff) * iCurImage->Bps + x + NewXOff + c];
}
}
}
if (TempData != iCurImage->Data)
ifree(TempData);
return IL_TRUE;
}
// Copies a 3d block of pixels to the buffer pointed to by Data.
ILboolean ilCopyPixels3D(ILuint XOff, ILuint YOff, ILuint ZOff, ILuint Width, ILuint Height, ILuint Depth, void *Data)
{
ILuint x, y, z, c, NewBps, DataBps, NewSizePlane, NewH, NewD, NewXOff, PixBpp;
ILubyte *Temp = (ILubyte*)Data, *TempData = iCurImage->Data;
if (ilIsEnabled(IL_ORIGIN_SET)) {
if ((ILenum)ilGetInteger(IL_ORIGIN_MODE) != iCurImage->Origin) {
TempData = iGetFlipped(iCurImage);
if (TempData == NULL)
return IL_FALSE;
}
}
PixBpp = iCurImage->Bpp * iCurImage->Bpc;
if (iCurImage->Width < XOff + Width)
NewBps = (iCurImage->Width - XOff) * PixBpp;
else
NewBps = Width * PixBpp;
if (iCurImage->Height < YOff + Height)
NewH = iCurImage->Height - YOff;
else
NewH = Height;
if (iCurImage->Depth < ZOff + Depth)
NewD = iCurImage->Depth - ZOff;
else
NewD = Depth;
DataBps = Width * PixBpp;
NewSizePlane = NewBps * NewH;
NewXOff = XOff * PixBpp;
for (z = 0; z < NewD; z++) {
for (y = 0; y < NewH; y++) {
for (x = 0; x < NewBps; x += PixBpp) {
for (c = 0; c < PixBpp; c++) {
Temp[z * NewSizePlane + y * DataBps + x + c] =
TempData[(z + ZOff) * iCurImage->SizeOfPlane + (y + YOff) * iCurImage->Bps + x + NewXOff + c];
//TempData[(z + ZOff) * iCurImage->SizeOfPlane + (y + YOff) * iCurImage->Bps + (x + XOff) * iCurImage->Bpp + c];
}
}
}
}
if (TempData != iCurImage->Data)
ifree(TempData);
return IL_TRUE;
}
ILuint ILAPIENTRY ilCopyPixels(ILuint XOff, ILuint YOff, ILuint ZOff, ILuint Width, ILuint Height, ILuint Depth, ILenum Format, ILenum Type, void *Data)
{
void *Converted = NULL;
ILubyte *TempBuff = NULL;
ILuint SrcSize, DestSize;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return 0;
}
DestSize = Width * Height * Depth * ilGetBppFormat(Format) * ilGetBpcType(Type);
if (DestSize == 0) {
return DestSize;
}
if (Data == NULL || Format == IL_COLOUR_INDEX) {
ilSetError(IL_INVALID_PARAM);
return 0;
}
SrcSize = Width * Height * Depth * iCurImage->Bpp * iCurImage->Bpc;
if (Format == iCurImage->Format && Type == iCurImage->Type) {
TempBuff = (ILubyte*)Data;
}
else {
TempBuff = (ILubyte*)ialloc(SrcSize);
if (TempBuff == NULL) {
return 0;
}
}
if (YOff + Height <= 1) {
if (!ilCopyPixels1D(XOff, Width, TempBuff)) {
goto failed;
}
}
else if (ZOff + Depth <= 1) {
if (!ilCopyPixels2D(XOff, YOff, Width, Height, TempBuff)) {
goto failed;
}
}
else {
if (!ilCopyPixels3D(XOff, YOff, ZOff, Width, Height, Depth, TempBuff)) {
goto failed;
}
}
if (Format == iCurImage->Format && Type == iCurImage->Type) {
return DestSize;
}
Converted = ilConvertBuffer(SrcSize, iCurImage->Format, Format, iCurImage->Type, Type, &iCurImage->Pal, TempBuff);
if (Converted == NULL)
goto failed;
memcpy(Data, Converted, DestSize);
ifree(Converted);
if (TempBuff != Data)
ifree(TempBuff);
return DestSize;
failed:
if (TempBuff != Data)
ifree(TempBuff);
ifree(Converted);
return 0;
}
ILboolean ilSetPixels1D(ILint XOff, ILuint Width, void *Data)
{
ILuint c, SkipX = 0, PixBpp;
ILint x, NewWidth;
ILubyte *Temp = (ILubyte*)Data, *TempData = iCurImage->Data;
if (ilIsEnabled(IL_ORIGIN_SET)) {
if ((ILenum)ilGetInteger(IL_ORIGIN_MODE) != iCurImage->Origin) {
TempData = iGetFlipped(iCurImage);
if (TempData == NULL)
return IL_FALSE;
}
}
PixBpp = iCurImage->Bpp * iCurImage->Bpc;
if (XOff < 0) {
SkipX = abs(XOff);
XOff = 0;
}
if (iCurImage->Width < XOff + Width) {
NewWidth = iCurImage->Width - XOff;
}
else {
NewWidth = Width;
}
NewWidth -= SkipX;
for (x = 0; x < NewWidth; x++) {
for (c = 0; c < PixBpp; c++) {
TempData[(x + XOff) * PixBpp + c] = Temp[(x + SkipX) * PixBpp + c];
}
}
if (TempData != iCurImage->Data) {
ifree(iCurImage->Data);
iCurImage->Data = TempData;
}
return IL_TRUE;
}
ILboolean ilSetPixels2D(ILint XOff, ILint YOff, ILuint Width, ILuint Height, void *Data)
{
ILuint c, SkipX = 0, SkipY = 0, NewBps, PixBpp;
ILint x, y, NewWidth, NewHeight;
ILubyte *Temp = (ILubyte*)Data, *TempData = iCurImage->Data;
if (ilIsEnabled(IL_ORIGIN_SET)) {
if ((ILenum)ilGetInteger(IL_ORIGIN_MODE) != iCurImage->Origin) {
TempData = iGetFlipped(iCurImage);
if (TempData == NULL)
return IL_FALSE;
}
}
PixBpp = iCurImage->Bpp * iCurImage->Bpc;
if (XOff < 0) {
SkipX = abs(XOff);
XOff = 0;
}
if (YOff < 0) {
SkipY = abs(YOff);
YOff = 0;
}
if (iCurImage->Width < XOff + Width)
NewWidth = iCurImage->Width - XOff;
else
NewWidth = Width;
NewBps = Width * PixBpp;
if (iCurImage->Height < YOff + Height)
NewHeight = iCurImage->Height - YOff;
else
NewHeight = Height;
NewWidth -= SkipX;
NewHeight -= SkipY;
for (y = 0; y < NewHeight; y++) {
for (x = 0; x < NewWidth; x++) {
for (c = 0; c < PixBpp; c++) {
TempData[(y + YOff) * iCurImage->Bps + (x + XOff) * PixBpp + c] =
Temp[(y + SkipY) * NewBps + (x + SkipX) * PixBpp + c];
}
}
}
if (TempData != iCurImage->Data) {
ifree(iCurImage->Data);
iCurImage->Data = TempData;
}
return IL_TRUE;
}
ILboolean ilSetPixels3D(ILint XOff, ILint YOff, ILint ZOff, ILuint Width, ILuint Height, ILuint Depth, void *Data)
{
ILuint SkipX = 0, SkipY = 0, SkipZ = 0, c, NewBps, NewSizePlane, PixBpp;
ILint x, y, z, NewW, NewH, NewD;
ILubyte *Temp = (ILubyte*)Data, *TempData = iCurImage->Data;
if (ilIsEnabled(IL_ORIGIN_SET)) {
if ((ILenum)ilGetInteger(IL_ORIGIN_MODE) != iCurImage->Origin) {
TempData = iGetFlipped(iCurImage);
if (TempData == NULL)
return IL_FALSE;
}
}
PixBpp = iCurImage->Bpp * iCurImage->Bpc;
if (XOff < 0) {
SkipX = abs(XOff);
XOff = 0;
}
if (YOff < 0) {
SkipY = abs(YOff);
YOff = 0;
}
if (ZOff < 0) {
SkipZ = abs(ZOff);
ZOff = 0;
}
if (iCurImage->Width < XOff + Width)
NewW = iCurImage->Width - XOff;
else
NewW = Width;
NewBps = Width * PixBpp;
if (iCurImage->Height < YOff + Height)
NewH = iCurImage->Height - YOff;
else
NewH = Height;
if (iCurImage->Depth < ZOff + Depth)
NewD = iCurImage->Depth - ZOff;
else
NewD = Depth;
NewSizePlane = NewBps * Height;
NewW -= SkipX;
NewH -= SkipY;
NewD -= SkipZ;
for (z = 0; z < NewD; z++) {
for (y = 0; y < NewH; y++) {
for (x = 0; x < NewW; x++) {
for (c = 0; c < PixBpp; c++) {
TempData[(z + ZOff) * iCurImage->SizeOfPlane + (y + YOff) * iCurImage->Bps + (x + XOff) * PixBpp + c] =
Temp[(z + SkipZ) * NewSizePlane + (y + SkipY) * NewBps + (x + SkipX) * PixBpp + c];
}
}
}
}
if (TempData != iCurImage->Data) {
ifree(iCurImage->Data);
iCurImage->Data = TempData;
}
return IL_TRUE;
}
void ILAPIENTRY ilSetPixels(ILint XOff, ILint YOff, ILint ZOff, ILuint Width, ILuint Height, ILuint Depth, ILenum Format, ILenum Type, void *Data)
{
void *Converted;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return;
}
if (Data == NULL) {
ilSetError(IL_INVALID_PARAM);
return;
}
if (Format == iCurImage->Format && Type == iCurImage->Type) {
Converted = (void*)Data;
}
else {
Converted = ilConvertBuffer(Width * Height * Depth * ilGetBppFormat(Format) * ilGetBpcType(Type), Format, iCurImage->Format, Type, iCurImage->Type, NULL, Data);
if (!Converted)
return;
}
if (YOff + Height <= 1) {
ilSetPixels1D(XOff, Width, Converted);
}
else if (ZOff + Depth <= 1) {
ilSetPixels2D(XOff, YOff, Width, Height, Converted);
}
else {
ilSetPixels3D(XOff, YOff, ZOff, Width, Height, Depth, Converted);
}
if (Format == iCurImage->Format && Type == iCurImage->Type) {
return;
}
if (Converted != Data)
ifree(Converted);
return;
}
// Ripped from Platinum (Denton's sources)
// This could very well easily be changed to a 128x128 image instead...needed?
//! Creates an ugly 64x64 black and yellow checkerboard image.
ILboolean ILAPIENTRY ilDefaultImage()
{
ILubyte *TempData;
ILubyte Yellow[3] = { 18, 246, 243 };
ILubyte Black[3] = { 0, 0, 0 };
ILubyte *ColorPtr = Yellow; // The start color
ILboolean Color = IL_TRUE;
// Loop Variables
ILint v, w, x, y;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
if (!ilTexImage(64, 64, 1, 3, IL_BGR, IL_UNSIGNED_BYTE, NULL)) {
return IL_FALSE;
}
iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
TempData = iCurImage->Data;
for (v = 0; v < 8; v++) {
// We do this because after a "block" line ends, the next row of blocks
// above starts with the ending colour, but the very inner loop switches them.
if (Color) {
Color = IL_FALSE;
ColorPtr = Black;
}
else {
Color = IL_TRUE;
ColorPtr = Yellow;
}
for (w = 0; w < 8; w++) {
for (x = 0; x < 8; x++) {
for (y = 0; y < 8; y++, TempData += iCurImage->Bpp) {
TempData[0] = ColorPtr[0];
TempData[1] = ColorPtr[1];
TempData[2] = ColorPtr[2];
}
// Switch to alternate between black and yellow
if (Color) {
Color = IL_FALSE;
ColorPtr = Black;
}
else {
Color = IL_TRUE;
ColorPtr = Yellow;
}
}
}
}
return IL_TRUE;
}
ILubyte* ILAPIENTRY ilGetAlpha(ILenum Type)
{
ILimage *TempImage;
ILubyte *Alpha;
ILushort *AlphaShort;
ILuint *AlphaInt;
ILdouble *AlphaDbl;
ILuint i, j, Bpc, Size, AlphaOff;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
Bpc = ilGetBpcType(Type);
if (Bpc == 0) {
ilSetError(IL_INVALID_PARAM);
return NULL;
}
if (iCurImage->Type == Type) {
TempImage = iCurImage;
} else {
TempImage = iConvertImage(iCurImage, iCurImage->Format, Type);
if (TempImage == NULL)
return NULL;
}
Size = iCurImage->Width * iCurImage->Height * iCurImage->Depth * TempImage->Bpp;
Alpha = (ILubyte*)ialloc(Size / TempImage->Bpp * Bpc);
if (Alpha == NULL) {
if (TempImage != iCurImage)
ilCloseImage(TempImage);
return NULL;
}
switch (TempImage->Format)
{
case IL_RGB:
case IL_BGR:
case IL_LUMINANCE:
case IL_COLOUR_INDEX: // @TODO: Make IL_COLOUR_INDEX separate.
memset(Alpha, 0xFF, Size / TempImage->Bpp * Bpc);
if (TempImage != iCurImage)
ilCloseImage(TempImage);
return Alpha;
}
// If our format is alpha, just return a copy.
if (TempImage->Format == IL_ALPHA) {
memcpy(Alpha, TempImage->Data, TempImage->SizeOfData);
return Alpha;
}
if (TempImage->Format == IL_LUMINANCE_ALPHA)
AlphaOff = 2;
else
AlphaOff = 4;
switch (TempImage->Type)
{
case IL_BYTE:
case IL_UNSIGNED_BYTE:
for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++)
Alpha[j] = TempImage->Data[i];
break;
case IL_SHORT:
case IL_UNSIGNED_SHORT:
AlphaShort = (ILushort*)Alpha;
for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++)
AlphaShort[j] = ((ILushort*)TempImage->Data)[i];
break;
case IL_INT:
case IL_UNSIGNED_INT:
case IL_FLOAT: // Can throw float in here, because it's the same size.
AlphaInt = (ILuint*)Alpha;
for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++)
AlphaInt[j] = ((ILuint*)TempImage->Data)[i];
break;
case IL_DOUBLE:
AlphaDbl = (ILdouble*)Alpha;
for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++)
AlphaDbl[j] = ((ILdouble*)TempImage->Data)[i];
break;
}
if (TempImage != iCurImage)
ilCloseImage(TempImage);
return Alpha;
}
// sets the Alpha value to a specific value for each pixel in the image
ILboolean ILAPIENTRY ilSetAlpha(ILdouble AlphaValue)
{
ILboolean ret = IL_TRUE;
ILuint i,Size;
ILimage *Image = iCurImage;
ILuint AlphaOff;
if (Image == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
AlphaValue = IL_CLAMP(AlphaValue);
switch (Image->Format)
{
case IL_RGB:
ret = ilConvertImage(IL_RGBA, Image->Type);
case IL_RGBA:
AlphaOff = 4;
break;
case IL_BGR:
ret = ilConvertImage(IL_BGRA, Image->Type);
case IL_BGRA:
AlphaOff = 4;
break;
case IL_LUMINANCE:
ret = ilConvertImage(IL_LUMINANCE_ALPHA, Image->Type);
case IL_LUMINANCE_ALPHA:
AlphaOff = 2;
break;
case IL_ALPHA:
AlphaOff = 1;
case IL_COLOUR_INDEX: //@TODO use palette with alpha
ret = ilConvertImage(IL_RGBA, Image->Type);
AlphaOff = 4;
break;
}
if (ret == IL_FALSE) {
// Error has been set by ilConvertImage.
return IL_FALSE;
}
Size = Image->Width * Image->Height * Image->Depth * Image->Bpp;
switch (iCurImage->Type)
{
case IL_BYTE:
case IL_UNSIGNED_BYTE: {
const ILbyte alpha = (ILubyte)(AlphaValue * IL_MAX_UNSIGNED_BYTE + .5);
for (i = AlphaOff-1; i < Size; i += AlphaOff)
Image->Data[i] = alpha;
break;
}
case IL_SHORT:
case IL_UNSIGNED_SHORT: {
const ILushort alpha = (ILushort)(AlphaValue * IL_MAX_UNSIGNED_SHORT + .5);
for (i = AlphaOff-1; i < Size; i += AlphaOff)
((ILushort*)Image->Data)[i] = alpha;
break;
}
case IL_INT:
case IL_UNSIGNED_INT: {
const ILushort alpha = (ILushort)(AlphaValue * IL_MAX_UNSIGNED_INT + .5);
for (i = AlphaOff-1; i < Size; i += AlphaOff)
((ILuint*)Image->Data)[i] = alpha;
break;
}
case IL_FLOAT: {
const ILfloat alpha = (ILfloat)AlphaValue;
for (i = AlphaOff-1; i < Size; i += AlphaOff)
((ILfloat*)Image->Data)[i] = alpha;
break;
}
case IL_DOUBLE: {
const ILdouble alpha = AlphaValue;
for (i = AlphaOff-1; i < Size; i += AlphaOff)
((ILdouble*)Image->Data)[i] = alpha;
break;
}
}
return IL_TRUE;
}
void ILAPIENTRY ilModAlpha(ILdouble AlphaValue)
{
ILuint AlphaOff = 0;
ILboolean ret = IL_FALSE;
ILuint i,j,Size;
union {
ILubyte alpha_byte;
ILushort alpha_short;
ILuint alpha_int;
ILfloat alpha_float;
ILdouble alpha_double;
} Alpha;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return;
}
switch (iCurImage->Format)
{
case IL_RGB:
ret = ilConvertImage(IL_RGBA,iCurImage->Type);
AlphaOff = 4;
break;
case IL_BGR:
ret = ilConvertImage(IL_BGRA,iCurImage->Type);
AlphaOff = 4;
break;
case IL_LUMINANCE:
ret = ilConvertImage(IL_LUMINANCE_ALPHA,iCurImage->Type);
AlphaOff = 2;
break;
case IL_COLOUR_INDEX:
ret = ilConvertImage(IL_RGBA,iCurImage->Type);
AlphaOff = 4;
break;
}
Size = iCurImage->Width * iCurImage->Height * iCurImage->Depth * iCurImage->Bpp;
if (!ret)
return;
switch (iCurImage->Type)
{
case IL_BYTE:
case IL_UNSIGNED_BYTE:
Alpha.alpha_byte = (ILubyte)(AlphaValue * 0x000000FF + .5);
for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++)
iCurImage->Data[i] = Alpha.alpha_byte;
break;
case IL_SHORT:
case IL_UNSIGNED_SHORT:
Alpha.alpha_short = (ILushort)(AlphaValue * 0x0000FFFF + .5);
for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++)
((ILushort*)iCurImage->Data)[i] = Alpha.alpha_short;
break;
case IL_INT:
case IL_UNSIGNED_INT:
Alpha.alpha_int = (ILuint)(AlphaValue * 0xFFFFFFFF + .5);
for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++)
((ILuint*)iCurImage->Data)[i] = Alpha.alpha_int;
break;
case IL_FLOAT:
Alpha.alpha_float = (ILfloat)AlphaValue;
for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++)
((ILfloat*)iCurImage->Data)[i] = Alpha.alpha_float;
break;
case IL_DOUBLE:
Alpha.alpha_double = AlphaValue;
for (i = AlphaOff-1, j = 0; i < Size; i += AlphaOff, j++)
((ILdouble*)iCurImage->Data)[i] = Alpha.alpha_double;
break;
}
return;
}
//! Clamps data values of unsigned bytes from 16 to 235 for display on an
// NTSC television. Reasoning for this is given at
// http://msdn.microsoft.com/en-us/library/bb174608.aspx.
ILboolean ILAPIENTRY ilClampNTSC(void)
{
ILuint x, y, z, c;
ILuint Offset = 0;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
if (iCurImage->Type != IL_UNSIGNED_BYTE) // Should we set an error here?
return IL_FALSE;
for (z = 0; z < iCurImage->Depth; z++) {
for (y = 0; y < iCurImage->Height; y++) {
for (x = 0; x < iCurImage->Width; x++) {
for (c = 0; c < iCurImage->Bpp; c++) {
iCurImage->Data[Offset + c] = IL_LIMIT(iCurImage->Data[Offset + c], 16, 235);
}
Offset += iCurImage->Bpp;
}
}
}
return IL_TRUE;
}
+218
View File
@@ -0,0 +1,218 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 03/07/2009
//
// Filename: src-IL/src/il_mdl.c
//
// Description: Reads a Half-Life model file (.mdl).
//
//-----------------------------------------------------------------------------
#include "il_internal.h"
#ifndef IL_NO_MDL
#include "il_mdl.h"
ILboolean iLoadMdlInternal(void);
ILboolean iIsValidMdl(void);
//! Checks if the file specified in FileName is a valid MDL file.
ILboolean ilIsValidMdl(ILconst_string FileName)
{
ILHANDLE MdlFile;
ILboolean bMdl = IL_FALSE;
if (!iCheckExtension(FileName, IL_TEXT("mdl"))) {
ilSetError(IL_INVALID_EXTENSION);
return bMdl;
}
MdlFile = iopenr(FileName);
if (MdlFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bMdl;
}
bMdl = ilIsValidMdlF(MdlFile);
icloser(MdlFile);
return bMdl;
}
//! Checks if the ILHANDLE contains a valid MDL file at the current position.
ILboolean ilIsValidMdlF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iIsValidMdl();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Checks if Lump is a valid MDL lump.
ILboolean ilIsValidMdlL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iIsValidMdl();
}
// Internal function to get the header and check it.
ILboolean iIsValidMdl(void)
{
ILuint Id, Version;
Id = GetLittleUInt();
Version = GetLittleUInt();
iseek(-8, IL_SEEK_CUR); // Restore to previous position.
// 0x54534449 == "IDST"
if (Id != 0x54534449 || Version != 10)
return IL_FALSE;
return IL_TRUE;
}
//! Reads a .mdl file
ILboolean ilLoadMdl(ILconst_string FileName)
{
ILHANDLE MdlFile;
ILboolean bMdl = IL_FALSE;
MdlFile = iopenr(FileName);
if (MdlFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bMdl;
}
bMdl = ilLoadMdlF(MdlFile);
icloser(MdlFile);
return bMdl;
}
//! Reads an already-opened .mdl file
ILboolean ilLoadMdlF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iLoadMdlInternal();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Reads from a memory "lump" that contains a .mdl
ILboolean ilLoadMdlL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iLoadMdlInternal();
}
ILboolean iLoadMdlInternal()
{
ILuint Id, Version, NumTex, TexOff, TexDataOff, Position, ImageNum;
ILubyte *TempPal;
TEX_HEAD TexHead;
ILimage *BaseImage=NULL;
ILboolean BaseCreated = IL_FALSE;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
Id = GetLittleUInt();
Version = GetLittleUInt();
// 0x54534449 == "IDST"
if (Id != 0x54534449 || Version != 10) {
ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
}
// Skips the actual model header.
iseek(172, IL_SEEK_CUR);
NumTex = GetLittleUInt();
TexOff = GetLittleUInt();
TexDataOff = GetLittleUInt();
if (NumTex == 0 || TexOff == 0 || TexDataOff == 0) {
ilSetError(IL_ILLEGAL_FILE_VALUE);
return IL_FALSE;
}
iseek(TexOff, IL_SEEK_SET);
for (ImageNum = 0; ImageNum < NumTex; ImageNum++) {
if (iread(TexHead.Name, 1, 64) != 64)
return IL_FALSE;
TexHead.Flags = GetLittleUInt();
TexHead.Width = GetLittleUInt();
TexHead.Height = GetLittleUInt();
TexHead.Offset = GetLittleUInt();
Position = itell();
if (TexHead.Offset == 0) {
ilSetError(IL_ILLEGAL_FILE_VALUE);
return IL_FALSE;
}
if (!BaseCreated) {
ilTexImage(TexHead.Width, TexHead.Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL);
iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
BaseCreated = IL_TRUE;
BaseImage = iCurImage;
//iCurImage->NumNext = NumTex - 1; // Don't count the first image.
}
else {
//iCurImage->Next = ilNewImage(TexHead.Width, TexHead.Height, 1, 1, 1);
iCurImage = iCurImage->Next;
iCurImage->Format = IL_COLOUR_INDEX;
iCurImage->Type = IL_UNSIGNED_BYTE;
}
TempPal = (ILubyte*)ialloc(768);
if (TempPal == NULL) {
iCurImage = BaseImage;
return IL_FALSE;
}
iCurImage->Pal.Palette = TempPal;
iCurImage->Pal.PalSize = 768;
iCurImage->Pal.PalType = IL_PAL_RGB24;
iseek(TexHead.Offset, IL_SEEK_SET);
if (iread(iCurImage->Data, TexHead.Width * TexHead.Height, 1) != 1)
return IL_FALSE;
if (iread(iCurImage->Pal.Palette, 1, 768) != 768)
return IL_FALSE;
if (ilGetBoolean(IL_CONV_PAL) == IL_TRUE) {
ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE);
}
iseek(Position, IL_SEEK_SET);
}
iCurImage = BaseImage;
return ilFixImage();
}
#endif//IL_NO_MDL
+378
View File
@@ -0,0 +1,378 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 03/07/2009
//
// Filename: src-IL/src/il_mng.c
//
// Description: Multiple Network Graphics (.mng) functions
//
//-----------------------------------------------------------------------------
#include "il_internal.h"
#ifndef IL_NO_MNG
#define MNG_SUPPORT_READ
#define MNG_SUPPORT_WRITE
#define MNG_SUPPORT_DISPLAY
#ifdef _WIN32
//#define MNG_USE_SO
#endif
#if defined(_WIN32) && defined(IL_USE_PRAGMA_LIBS)
#if defined(_MSC_VER) || defined(__BORLANDC__)
#ifndef _DEBUG
#pragma comment(lib, "libmng.lib")
#pragma comment(lib, "lcms.lib")
#pragma comment(lib, "libjpeg.lib")
#pragma comment(lib, "zlib.lib")
#else
#pragma comment(lib, "libmng-d.lib")
#pragma comment(lib, "lcms-d.lib")
#pragma comment(lib, "libjpeg-d.lib")
#pragma comment(lib, "zlib-d.lib")
#endif
#endif
#endif
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4142) // Redefinition in jmorecfg.h
#endif
#include <libmng.h>
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
//---------------------------------------------------------------------------------------------
// memory allocation; data must be zeroed
//---------------------------------------------------------------------------------------------
mng_ptr MNG_DECL mymngalloc(mng_size_t size)
{
return (mng_ptr)icalloc(1, size);
}
//---------------------------------------------------------------------------------------------
// memory deallocation
//---------------------------------------------------------------------------------------------
void MNG_DECL mymngfree(mng_ptr p, mng_size_t size)
{
ifree(p);
}
//---------------------------------------------------------------------------------------------
// Stream open:
//---------------------------------------------------------------------------------------------
mng_bool MNG_DECL mymngopenstream(mng_handle mng)
{
return MNG_TRUE;
}
//---------------------------------------------------------------------------------------------
// Stream open for Writing:
//---------------------------------------------------------------------------------------------
mng_bool MNG_DECL mymngopenstreamwrite(mng_handle mng)
{
return MNG_TRUE;
}
//---------------------------------------------------------------------------------------------
// Stream close:
//---------------------------------------------------------------------------------------------
mng_bool MNG_DECL mymngclosestream(mng_handle mng)
{
return MNG_TRUE; // We close the file ourself, mng_cleanup doesnt seem to do it...
}
//---------------------------------------------------------------------------------------------
// feed data to the decoder
//---------------------------------------------------------------------------------------------
mng_bool MNG_DECL mymngreadstream(mng_handle mng, mng_ptr buffer, mng_size_t size, mng_uint32 *bytesread)
{
// read the requested amount of data from the file
*bytesread = iread(buffer, 1, (ILuint)size);
return MNG_TRUE;
}
//---------------------------------------------------------------------------------------------
// callback for writing data
//---------------------------------------------------------------------------------------------
mng_bool MNG_DECL mymngwritedata(mng_handle mng, mng_ptr buffer, mng_size_t size, mng_uint32 *byteswritten)
{
*byteswritten = iwrite(buffer, 1, (ILuint)size);
if (*byteswritten < size) {
ilSetError(IL_FILE_WRITE_ERROR);
return MNG_FALSE;
}
return MNG_TRUE;
}
//---------------------------------------------------------------------------------------------
// the header's been read. set up the display stuff
//---------------------------------------------------------------------------------------------
mng_bool MNG_DECL mymngprocessheader(mng_handle mng, mng_uint32 width, mng_uint32 height)
{
ILuint AlphaDepth;
AlphaDepth = mng_get_alphadepth(mng);
if (AlphaDepth == 0) {
ilTexImage(width, height, 1, 3, IL_BGR, IL_UNSIGNED_BYTE, NULL);
iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
mng_set_canvasstyle(mng, MNG_CANVAS_BGR8);
}
else { // Use alpha channel
ilTexImage(width, height, 1, 4, IL_BGRA, IL_UNSIGNED_BYTE, NULL);
iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
mng_set_canvasstyle(mng, MNG_CANVAS_BGRA8);
}
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
return MNG_TRUE;
}
//---------------------------------------------------------------------------------------------
// return a row pointer for the decoder to fill
//---------------------------------------------------------------------------------------------
mng_ptr MNG_DECL mymnggetcanvasline(mng_handle mng, mng_uint32 line)
{
return (mng_ptr)(iCurImage->Data + iCurImage->Bps * line);
}
//---------------------------------------------------------------------------------------------
// timer
//---------------------------------------------------------------------------------------------
mng_uint32 MNG_DECL mymnggetticks(mng_handle mng)
{
return 0;
}
//---------------------------------------------------------------------------------------------
// Refresh:
//---------------------------------------------------------------------------------------------
mng_bool MNG_DECL mymngrefresh(mng_handle mng, mng_uint32 x, mng_uint32 y, mng_uint32 w, mng_uint32 h)
{
return MNG_TRUE;
}
//---------------------------------------------------------------------------------------------
// interframe delay callback
//---------------------------------------------------------------------------------------------
mng_bool MNG_DECL mymngsettimer(mng_handle mng, mng_uint32 msecs)
{
return MNG_TRUE;
}
// Make this do something different soon!
//---------------------------------------------------------------------------------------------
// Error Callback;
//---------------------------------------------------------------------------------------------
mng_bool MNG_DECL mymngerror(
mng_handle mng, mng_int32 code, mng_int8 severity,
mng_chunkid chunktype, mng_uint32 chunkseq,
mng_int32 extra1, mng_int32 extra2, mng_pchar text
)
{
// error occured;
return MNG_FALSE;
}
ILboolean iLoadMngInternal(void);
// Reads a file
ILboolean ilLoadMng(ILconst_string FileName)
{
ILHANDLE MngFile;
ILboolean bMng = IL_FALSE;
MngFile = iopenr(FileName);
if (MngFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bMng;
}
bMng = ilLoadMngF(MngFile);
icloser(MngFile);
return bMng;
}
// Reads an already-opened file
ILboolean ilLoadMngF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iLoadMngInternal();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
// Reads from a memory "lump"
ILboolean ilLoadMngL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iLoadMngInternal();
}
ILboolean iLoadMngInternal()
{
mng_handle mng;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
mng = mng_initialize(MNG_NULL, mymngalloc, mymngfree, MNG_NULL);
if (mng == MNG_NULL) {
ilSetError(IL_LIB_MNG_ERROR);
return IL_FALSE;
}
// If .mng background is available, use it.
mng_set_usebkgd(mng, MNG_TRUE);
// Set the callbacks.
mng_setcb_errorproc(mng, mymngerror);
mng_setcb_openstream(mng, mymngopenstream);
mng_setcb_closestream(mng, mymngclosestream);
mng_setcb_readdata(mng, (mng_readdata)mymngreadstream);
mng_setcb_gettickcount(mng, mymnggetticks);
mng_setcb_settimer(mng, mymngsettimer);
mng_setcb_processheader(mng, mymngprocessheader);
mng_setcb_getcanvasline(mng, mymnggetcanvasline);
mng_setcb_refresh(mng, mymngrefresh);
mng_read(mng);
mng_display(mng);
return ilFixImage();
}
ILboolean iSaveMngInternal(void);
//! Writes a Mng file
ILboolean ilSaveMng(const ILstring FileName)
{
ILHANDLE MngFile;
ILuint MngSize;
if (ilGetBoolean(IL_FILE_MODE) == IL_FALSE) {
if (iFileExists(FileName)) {
ilSetError(IL_FILE_ALREADY_EXISTS);
return IL_FALSE;
}
}
MngFile = iopenw(FileName);
if (MngFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return IL_FALSE;
}
MngSize = ilSaveMngF(MngFile);
iclosew(MngFile);
if (MngSize == 0)
return IL_FALSE;
return IL_TRUE;
}
//! Writes a Mng to an already-opened file
ILuint ilSaveMngF(ILHANDLE File)
{
ILuint Pos = itellw();
iSetOutputFile(File);
if (iSaveMngInternal() == IL_FALSE)
return 0; // Error occurred
return itellw() - Pos; // Return the number of bytes written.
}
//! Writes a Mng to a memory "lump"
ILuint ilSaveMngL(void *Lump, ILuint Size)
{
ILuint Pos;
iSetOutputLump(Lump, Size);
Pos = itellw();
if (iSaveMngInternal() == IL_FALSE)
return 0; // Error occurred
return itellw() - Pos; // Return the number of bytes written.
}
// Internal function used to save the Mng.
ILboolean iSaveMngInternal()
{
//mng_handle mng;
// Not working yet, so just error out.
ilSetError(IL_INVALID_EXTENSION);
return IL_FALSE;
//if (iCurImage == NULL) {
// ilSetError(IL_ILLEGAL_OPERATION);
// return IL_FALSE;
//}
//mng = mng_initialize(MNG_NULL, mymngalloc, mymngfree, MNG_NULL);
//if (mng == MNG_NULL) {
// ilSetError(IL_LIB_MNG_ERROR);
// return IL_FALSE;
//}
//mng_setcb_openstream(mng, mymngopenstreamwrite);
//mng_setcb_closestream(mng, mymngclosestream);
//mng_setcb_writedata(mng, mymngwritedata);
//// Write File:
// mng_create(mng);
//// Check return value.
//mng_putchunk_mhdr(mng, iCurImage->Width, iCurImage->Height, 1000, 3, 1, 3, 0x0047);
//mng_putchunk_basi(mng, iCurImage->Width, iCurImage->Height, 8, MNG_COLORTYPE_RGB, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 1);
//mng_putchunk_iend(mng);
//mng_putimgdata_ihdr(mng, iCurImage->Width, iCurImage->Height, MNG_COLORTYPE_RGB, 8, 0, 0, 0, 0, mymnggetcanvasline);
//// Now write file:
//mng_write(mng);
//mng_cleanup(&mng);
//return IL_TRUE;
}
#endif//IL_NO_MNG
+280
View File
@@ -0,0 +1,280 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 03/05/2009
//
// Filename: src-IL/src/il_mp3.c
//
// MimeType: Reads from an MPEG-1 Audio Layer 3 (.mp3) file.
//
//-----------------------------------------------------------------------------
#include "il_internal.h"
#ifndef IL_NO_MP3
typedef struct MP3HEAD
{
char Signature[3];
ILubyte VersionMajor;
ILubyte VersionMinor;
ILubyte Flags;
ILuint Length;
} MP3HEAD;
#define MP3_NONE 0
#define MP3_JPG 1
#define MP3_PNG 2
ILboolean iLoadMp3Internal(void);
ILboolean iIsValidMp3(void);
ILboolean iCheckMp3(MP3HEAD *Header);
ILboolean iLoadJpegInternal(void);
ILboolean iLoadPngInternal(void);
//! Checks if the file specified in FileName is a valid MP3 file.
ILboolean ilIsValidMp3(ILconst_string FileName)
{
ILHANDLE Mp3File;
ILboolean bMp3 = IL_FALSE;
if (!iCheckExtension(FileName, IL_TEXT("mp3"))) {
ilSetError(IL_INVALID_EXTENSION);
return bMp3;
}
Mp3File = iopenr(FileName);
if (Mp3File == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bMp3;
}
bMp3 = ilIsValidMp3F(Mp3File);
icloser(Mp3File);
return bMp3;
}
//! Checks if the ILHANDLE contains a valid MP3 file at the current position.
ILboolean ilIsValidMp3F(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iIsValidMp3();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Checks if Lump is a valid MP3 lump.
ILboolean ilIsValidMp3L(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iIsValidMp3();
}
ILuint GetSynchInt()
{
ILuint SynchInt;
SynchInt = GetBigUInt();
SynchInt = ((SynchInt & 0x7F000000) >> 3) | ((SynchInt & 0x7F0000) >> 2)
| ((SynchInt & 0x7F00) >> 1) | (SynchInt & 0x7F);
return SynchInt;
}
// Internal function used to get the MP3 header from the current file.
ILboolean iGetMp3Head(MP3HEAD *Header)
{
if (iread(Header->Signature, 3, 1) != 1)
return IL_FALSE;
Header->VersionMajor = igetc();
Header->VersionMinor = igetc();
Header->Flags = igetc();
Header->Length = GetSynchInt();
return IL_TRUE;
}
// Internal function to get the header and check it.
ILboolean iIsValidMp3(void)
{
MP3HEAD Header;
ILuint Pos = itell();
if (!iGetMp3Head(&Header))
return IL_FALSE;
// The length of the header varies, so we just go back to the original position.
iseek(Pos, IL_SEEK_CUR);
return iCheckMp3(&Header);
}
// Internal function used to check if the HEADER is a valid MP3 header.
ILboolean iCheckMp3(MP3HEAD *Header)
{
if (strncmp(Header->Signature, "ID3", 3))
return IL_FALSE;
if (Header->VersionMajor != 3 && Header->VersionMinor != 4)
return IL_FALSE;
return IL_TRUE;
}
ILuint iFindMp3Pic(MP3HEAD *Header)
{
char ID[4];
ILuint FrameSize;
ILubyte TextEncoding;
ILubyte MimeType[65], Description[65];
ILubyte PicType;
ILuint i;
ILuint Type = MP3_NONE;
do {
if (iread(ID, 4, 1) != 1)
return MP3_NONE;
if (Header->VersionMajor == 3)
FrameSize = GetBigUInt();
else
FrameSize = GetSynchInt();
GetBigUShort(); // Skip the flags.
//@TODO: Support multiple APIC entries in an mp3 file.
if (!strncmp(ID, "APIC", 4)) {
//@TODO: Use TextEncoding properly - UTF16 strings starting with FFFE or FEFF.
TextEncoding = igetc();
// Get the MimeType (read until we hit 0).
for (i = 0; i < 65; i++) {
MimeType[i] = igetc();
if (MimeType[i] == 0)
break;
}
// The MimeType must be terminated by 0 in the file by the specs.
if (MimeType[i] != 0)
return MP3_NONE;
if (!strcmp(MimeType, "image/jpeg"))
Type = MP3_JPG;
else if (!strcmp(MimeType, "image/png"))
Type = MP3_PNG;
else
Type = MP3_NONE;
PicType = igetc(); // Whether this is a cover, band logo, etc.
// Skip the description.
for (i = 0; i < 65; i++) {
Description[i] = igetc();
if (Description[i] == 0)
break;
}
if (Description[i] != 0)
return MP3_NONE;
return Type;
}
else {
iseek(FrameSize, IL_SEEK_CUR);
}
//if (!strncmp(MimeType, "
} while (!ieof() && itell() < Header->Length);
return Type;
}
//! Reads a MP3 file
ILboolean ilLoadMp3(ILconst_string FileName)
{
ILHANDLE Mp3File;
ILboolean bMp3 = IL_FALSE;
Mp3File = iopenr(FileName);
if (Mp3File == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bMp3;
}
bMp3 = ilLoadMp3F(Mp3File);
icloser(Mp3File);
return bMp3;
}
//! Reads an already-opened MP3 file
ILboolean ilLoadMp3F(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iLoadMp3Internal();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Reads from a memory "lump" that contains a MP3
ILboolean ilLoadMp3L(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iLoadMp3Internal();
}
// Internal function used to load the MP3.
ILboolean iLoadMp3Internal(void)
{
MP3HEAD Header;
ILuint Type;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
if (!iGetMp3Head(&Header))
return IL_FALSE;
if (!iCheckMp3(&Header))
return IL_FALSE;
Type = iFindMp3Pic(&Header);
switch (Type)
{
#ifndef IL_NO_JPG
case MP3_JPG:
return iLoadJpegInternal();
#endif//IL_NO_JPG
#ifndef IL_NO_PNG
case MP3_PNG:
return iLoadPngInternal();
#endif//IL_NO_PNG
// Either a picture was not found, or the MIME type was not recognized.
default:
ilSetError(IL_INVALID_FILE_HEADER);
}
return IL_FALSE;
}
#endif//IL_NO_MP3
+462
View File
@@ -0,0 +1,462 @@
/* NeuQuant Neural-Net Quantization Algorithm
* ------------------------------------------
*
* Copyright (c) 1994 Anthony Dekker
*
* NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994.
* See "Kohonen neural networks for optimal colour quantization"
* in "Network: Computation in Neural Systems" Vol. 5 (1994) pp 351-367.
* for a discussion of the algorithm.
* See also http://www.acm.org/~dekker/NEUQUANT.HTML
*
* Any party obtaining a copy of these files from the author, directly or
* indirectly, is granted, free of charge, a full and unrestricted irrevocable,
* world-wide, paid up, royalty-free, nonexclusive right and license to deal
* in this software and documentation files (the "Software"), including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons who receive
* copies from any such party to do so, with the only requirement being
* that this copyright notice remain intact.
*/
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// by Denton Woods
// Last modified: 01/04/2009
//
// Filename: src-IL/src/il_neuquant.c
//
// Description: Heavily modified by Denton Woods.
//
//-----------------------------------------------------------------------------
#include "il_internal.h"
// Function definitions
void initnet(ILubyte *thepic, ILint len, ILint sample);
void unbiasnet();
void inxbuild();
ILubyte inxsearch(ILint b, ILint g, ILint r);
void learn();
// four primes near 500 - assume no image has a length so large
// that it is divisible by all four primes
#define prime1 499
#define prime2 491
#define prime3 487
#define prime4 503
#define minpicturebytes (3*prime4) // minimum size for input image
// Network Definitions
// -------------------
#define netsize 256 // number of colours used
#define maxnetpos (netsizethink-1)
#define netbiasshift 4 // bias for colour values
#define ncycles 100 // no. of learning cycles
// defs for freq and bias
#define intbiasshift 16 // bias for fractions
#define intbias (((ILint) 1)<<intbiasshift)
#define gammashift 10 // gamma = 1024
#define gamma (((ILint) 1)<<gammashift)
#define betashift 10
#define beta (intbias>>betashift)// beta = 1/1024
#define betagamma (intbias<<(gammashift-betashift))
// defs for decreasing radius factor
#define initrad (netsize>>3) // for 256 cols, radius starts
#define radiusbiasshift 6 // at 32.0 biased by 6 bits
#define radiusbias (((ILint) 1)<<radiusbiasshift)
#define initradius (initrad*radiusbias) // and decreases by a
#define radiusdec 30 // factor of 1/30 each cycle
// defs for decreasing alpha factor
#define alphabiasshift 10 // alpha starts at 1.0
#define initalpha (((ILint) 1)<<alphabiasshift)
ILint alphadec; // biased by 10 bits
// radbias and alpharadbias used for radpower calculation
#define radbiasshift 8
#define radbias (((ILint) 1)<<radbiasshift)
#define alpharadbshift (alphabiasshift+radbiasshift)
#define alpharadbias (((ILint) 1)<<alpharadbshift)
// Types and Global Variables
// --------------------------
unsigned char *thepicture; // the input image itself
int lengthcount; // lengthcount = H*W*3
int samplefac; // sampling factor 1..30
typedef int pixel[4]; // BGRc
static pixel network[netsize]; // the network itself
int netindex[256]; // for network lookup - really 256
int bias [netsize]; // bias and freq arrays for learning
int freq [netsize];
int radpower[initrad]; // radpower for precomputation
int netsizethink; // number of colors we want to reduce to, 2-256
// Initialise network in range (0,0,0) to (255,255,255) and set parameters
// -----------------------------------------------------------------------
void initnet(ILubyte *thepic, ILint len, ILint sample)
{
ILint i;
ILint *p;
thepicture = thepic;
lengthcount = len;
samplefac = sample;
for (i=0; i<netsizethink; i++) {
p = network[i];
p[0] = p[1] = p[2] = (i << (netbiasshift+8))/netsize;
freq[i] = intbias/netsizethink; // 1/netsize
bias[i] = 0;
}
return;
}
// Unbias network to give byte values 0..255 and record position i to prepare for sort
// -----------------------------------------------------------------------------------
void unbiasnet()
{
ILint i,j;
for (i=0; i<netsizethink; i++) {
for (j=0; j<3; j++)
network[i][j] >>= netbiasshift;
network[i][3] = i; // record colour no
}
return;
}
// Insertion sort of network and building of netindex[0..255] (to do after unbias)
// -------------------------------------------------------------------------------
void inxbuild()
{
ILint i,j,smallpos,smallval;
ILint *p,*q;
ILint previouscol,startpos;
previouscol = 0;
startpos = 0;
for (i=0; i<netsizethink; i++) {
p = network[i];
smallpos = i;
smallval = p[1]; // index on g
// find smallest in i..netsize-1
for (j=i+1; j<netsizethink; j++) {
q = network[j];
if (q[1] < smallval) { // index on g
smallpos = j;
smallval = q[1]; // index on g
}
}
q = network[smallpos];
// swap p (i) and q (smallpos) entries
if (i != smallpos) {
j = q[0]; q[0] = p[0]; p[0] = j;
j = q[1]; q[1] = p[1]; p[1] = j;
j = q[2]; q[2] = p[2]; p[2] = j;
j = q[3]; q[3] = p[3]; p[3] = j;
}
// smallval entry is now in position i
if (smallval != previouscol) {
netindex[previouscol] = (startpos+i)>>1;
for (j=previouscol+1; j<smallval; j++) netindex[j] = i;
previouscol = smallval;
startpos = i;
}
}
netindex[previouscol] = (startpos+maxnetpos)>>1;
for (j=previouscol+1; j<256; j++) netindex[j] = maxnetpos; // really 256
return;
}
// Search for BGR values 0..255 (after net is unbiased) and return colour index
// ----------------------------------------------------------------------------
ILubyte inxsearch(ILint b, ILint g, ILint r)
{
ILint i,j,dist,a,bestd;
ILint *p;
ILint best;
bestd = 1000; // biggest possible dist is 256*3
best = -1;
i = netindex[g]; // index on g
j = i-1; // start at netindex[g] and work outwards
while ((i<netsizethink) || (j>=0)) {
if (i<netsizethink) {
p = network[i];
dist = p[1] - g; // inx key
if (dist >= bestd) i = netsizethink; // stop iter
else {
i++;
if (dist<0) dist = -dist;
a = p[0] - b; if (a<0) a = -a;
dist += a;
if (dist<bestd) {
a = p[2] - r; if (a<0) a = -a;
dist += a;
if (dist<bestd) {bestd=dist; best=p[3];}
}
}
}
if (j>=0) {
p = network[j];
dist = g - p[1]; // inx key - reverse dif
if (dist >= bestd) j = -1; // stop iter
else {
j--;
if (dist<0) dist = -dist;
a = p[0] - b; if (a<0) a = -a;
dist += a;
if (dist<bestd) {
a = p[2] - r; if (a<0) a = -a;
dist += a;
if (dist<bestd) {bestd=dist; best=p[3];}
}
}
}
}
return (ILubyte)best;
}
// Search for biased BGR values
// ----------------------------
ILint contest(ILint b, ILint g, ILint r)
{
// finds closest neuron (min dist) and updates freq
// finds best neuron (min dist-bias) and returns position
// for frequently chosen neurons, freq[i] is high and bias[i] is negative
// bias[i] = gamma*((1/netsize)-freq[i])
ILint i,dist,a,biasdist,betafreq;
ILint bestpos,bestbiaspos,bestd,bestbiasd;
ILint *p,*f, *n;
bestd = ~(((ILint) 1)<<31);
bestbiasd = bestd;
bestpos = -1;
bestbiaspos = bestpos;
p = bias;
f = freq;
for (i=0; i<netsizethink; i++) {
n = network[i];
dist = n[0] - b; if (dist<0) dist = -dist;
a = n[1] - g; if (a<0) a = -a;
dist += a;
a = n[2] - r; if (a<0) a = -a;
dist += a;
if (dist<bestd) {bestd=dist; bestpos=i;}
biasdist = dist - ((*p)>>(intbiasshift-netbiasshift));
if (biasdist<bestbiasd) {bestbiasd=biasdist; bestbiaspos=i;}
betafreq = (*f >> betashift);
*f++ -= betafreq;
*p++ += (betafreq<<gammashift);
}
freq[bestpos] += beta;
bias[bestpos] -= betagamma;
return(bestbiaspos);
}
// Move neuron i towards biased (b,g,r) by factor alpha
// ----------------------------------------------------
void altersingle(ILint alpha, ILint i, ILint b, ILint g, ILint r)
{
ILint *n;
n = network[i]; // alter hit neuron
*n -= (alpha*(*n - b)) / initalpha;
n++;
*n -= (alpha*(*n - g)) / initalpha;
n++;
*n -= (alpha*(*n - r)) / initalpha;
return;
}
// Move adjacent neurons by precomputed alpha*(1-((i-j)^2/[r]^2)) in radpower[|i-j|]
// ---------------------------------------------------------------------------------
void alterneigh(ILint rad, ILint i, ILint b, ILint g, ILint r)
{
ILint j,k,lo,hi,a;
ILint *p, *q;
lo = i-rad; if (lo<-1) lo=-1;
hi = i+rad; if (hi>netsizethink) hi=netsizethink;
j = i+1;
k = i-1;
q = radpower;
while ((j<hi) || (k>lo)) {
a = (*(++q));
if (j<hi) {
p = network[j];
*p -= (a*(*p - b)) / alpharadbias;
p++;
*p -= (a*(*p - g)) / alpharadbias;
p++;
*p -= (a*(*p - r)) / alpharadbias;
j++;
}
if (k>lo) {
p = network[k];
*p -= (a*(*p - b)) / alpharadbias;
p++;
*p -= (a*(*p - g)) / alpharadbias;
p++;
*p -= (a*(*p - r)) / alpharadbias;
k--;
}
}
return;
}
// Main Learning Loop
// ------------------
void learn()
{
ILint i,j,b,g,r;
ILint radius,rad,alpha,step,delta,samplepixels;
ILubyte *p;
ILubyte *lim;
alphadec = 30 + ((samplefac-1)/3);
p = thepicture;
lim = thepicture + lengthcount;
samplepixels = lengthcount/(3*samplefac);
delta = samplepixels/ncycles;
alpha = initalpha;
radius = initradius;
rad = radius >> radiusbiasshift;
if (rad <= 1) rad = 0;
for (i=0; i<rad; i++)
radpower[i] = alpha*(((rad*rad - i*i)*radbias)/(rad*rad));
// beginning 1D learning: initial radius=rad
if ((lengthcount%prime1) != 0) step = 3*prime1;
else {
if ((lengthcount%prime2) !=0) step = 3*prime2;
else {
if ((lengthcount%prime3) !=0) step = 3*prime3;
else step = 3*prime4;
}
}
i = 0;
while (i < samplepixels) {
b = p[0] << netbiasshift;
g = p[1] << netbiasshift;
r = p[2] << netbiasshift;
j = contest(b,g,r);
altersingle(alpha,j,b,g,r);
if (rad) alterneigh(rad,j,b,g,r); // alter neighbours
p += step;
if (p >= lim) p -= lengthcount;
i++;
if (i%delta == 0) {
alpha -= alpha / alphadec;
radius -= radius / radiusdec;
rad = radius >> radiusbiasshift;
if (rad <= 1) rad = 0;
for (j=0; j<rad; j++)
radpower[j] = alpha*(((rad*rad - j*j)*radbias)/(rad*rad));
}
}
// finished 1D learning: final alpha=alpha/initalpha;
return;
}
ILimage *iNeuQuant(ILimage *Image, ILuint NumCols)
{
ILimage *TempImage, *NewImage;
ILuint sample, i, j;
netsizethink=NumCols;
NewImage = iCurImage;
iCurImage = Image;
TempImage = iConvertImage(iCurImage, IL_BGR, IL_UNSIGNED_BYTE);
iCurImage = NewImage;
sample = ilGetInteger(IL_NEU_QUANT_SAMPLE);
if (TempImage == NULL)
return NULL;
initnet(TempImage->Data, TempImage->SizeOfData, sample);
learn();
unbiasnet();
NewImage = (ILimage*)icalloc(sizeof(ILimage), 1);
if (NewImage == NULL) {
ilCloseImage(TempImage);
return NULL;
}
NewImage->Data = (ILubyte*)ialloc(TempImage->SizeOfData / 3);
if (NewImage->Data == NULL) {
ilCloseImage(TempImage);
ifree(NewImage);
return NULL;
}
ilCopyImageAttr(NewImage, Image);
NewImage->Bpp = 1;
NewImage->Bps = Image->Width;
NewImage->SizeOfPlane = NewImage->Bps * Image->Height;
NewImage->SizeOfData = NewImage->SizeOfPlane;
NewImage->Format = IL_COLOUR_INDEX;
NewImage->Type = IL_UNSIGNED_BYTE;
NewImage->Pal.PalSize = netsizethink * 3;
NewImage->Pal.PalType = IL_PAL_BGR24;
NewImage->Pal.Palette = (ILubyte*)ialloc(256*3);
if (NewImage->Pal.Palette == NULL) {
ilCloseImage(TempImage);
ilCloseImage(NewImage);
return NULL;
}
for (i = 0, j = 0; i < (unsigned)netsizethink; i++, j += 3) {
NewImage->Pal.Palette[j ] = network[i][0];
NewImage->Pal.Palette[j+1] = network[i][1];
NewImage->Pal.Palette[j+2] = network[i][2];
}
inxbuild();
for (i = 0, j = 0; j < TempImage->SizeOfData; i++, j += 3) {
NewImage->Data[i] = inxsearch(
TempImage->Data[j], TempImage->Data[j+1], TempImage->Data[j+2]);
}
ilCloseImage(TempImage);
return NewImage;
}
+227
View File
@@ -0,0 +1,227 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 01/19/2009
//
// Filename: src-IL/src/il_nvidia.cpp
//
// Description: Implements access to the nVidia Texture Tools library.
//
//-----------------------------------------------------------------------------
#include "il_internal.h"
#include "il_dds.h"
#include "il_manip.h"
#include <limits.h>
#ifdef IL_USE_DXTC_NVIDIA
#include <nvtt/nvtt.h>
#include <nvcore/Memory.h>
using namespace nvtt;
#if defined(_WIN32) && defined(IL_USE_PRAGMA_LIBS)
#if defined(_MSC_VER) || defined(__BORLANDC__)
#ifndef _DEBUG
#pragma comment(lib, "nvcore.lib")
#pragma comment(lib, "nvtt.lib")
#else
#pragma comment(lib, "nvcore-d.lib")
#pragma comment(lib, "nvtt-d.lib")
#endif
#endif
#endif
struct ilOutputHandlerMem : public nvtt::OutputHandler
{
ilOutputHandlerMem(ILuint Width, ILuint Height, ILenum DxtType)
{
Width = Width + (4 - (Width % 4)) % 4; // Operates on 4x4 blocks,
Height = Height + (4 - (Height % 4)) % 4; // so gives extra room.
switch (DxtType)
{
case IL_DXT1:
case IL_DXT1A:
Size = Width * Height / 2;
break;
case IL_DXT3:
case IL_DXT5:
Size = Width * Height;
break;
default: // NVTT does not accept DXT2 or DXT4.
// Should error somehow...
break;
}
NewData = (ILubyte*)ialloc(Size);
if (NewData == NULL)
return;
Temp = NewData;
}
virtual void beginImage(int size, int width, int height, int depth, int face, int miplevel)
{
// ignore.
}
virtual bool writeData(const void *data, int size)
{
memcpy(Temp, data, size);
Temp += size;
return true;
}
ILubyte *NewData, *Temp;
ILuint Size;
};
//! Compresses data to a DXT format using nVidia's Texture Tools library.
// The data must be in unsigned byte RGBA format. The alpha channel will be ignored if DxtType is IL_DXT1.
// DxtSize is used to return the size in bytes of the DXTC data returned.
ILAPI ILubyte* ILAPIENTRY ilNVidiaCompressDXT(ILubyte *Data, ILuint Width, ILuint Height, ILuint Depth, ILenum DxtFormat, ILuint *DxtSize)
{
if (Data == NULL) { // We cannot operate on a null pointer.
ilSetError(IL_INVALID_PARAM);
return NULL;
}
// The nVidia Texture Tools library does not support volume textures yet.
if (Depth != 1) {
ilSetError(IL_INVALID_PARAM);
return NULL;
}
InputOptions inputOptions;
inputOptions.setTextureLayout(TextureType_2D, Width, Height);
inputOptions.setMipmapData(Data, Width, Height);
inputOptions.setMipmapGeneration(false, -1); //@TODO: Use this in certain cases.
OutputOptions outputOptions;
ilOutputHandlerMem outputHandler(Width, Height, DxtFormat);
outputOptions.setOutputHeader(false);
outputOptions.setOutputHandler(&outputHandler);
if (outputHandler.NewData == NULL)
return NULL;
CompressionOptions compressionOptions;
switch (DxtFormat)
{
case IL_DXT1:
compressionOptions.setFormat(Format_DXT1);
break;
case IL_DXT1A:
compressionOptions.setFormat(Format_DXT1a);
break;
case IL_DXT3:
compressionOptions.setFormat(Format_DXT1);
break;
case IL_DXT5:
compressionOptions.setFormat(Format_DXT5);
break;
default: // Does not support DXT2 or DXT4.
ilSetError(IL_INVALID_PARAM);
break;
}
Compressor compressor;
compressor.process(inputOptions, compressionOptions, outputOptions);
*DxtSize = outputHandler.Size;
return outputHandler.NewData;
}
//
//
// The following is just a repeat of above, but it works generically on file streams or lumps.
// @TODO: Merge these two together.
//
//
struct ilOutputHandlerFile : public nvtt::OutputHandler
{
ilOutputHandlerFile(ILuint Width, ILuint Height, ILenum DxtType)
{
return;
}
virtual void beginImage(int size, int width, int height, int depth, int face, int miplevel)
{
// ignore.
}
virtual bool writeData(const void *data, int size)
{
if (iwrite(data, 1, size) == size)
return true;
return false;
}
};
//! Compresses data to a DXT format using nVidia's Texture Tools library.
// This version is supposed to be completely internal to DevIL.
// The data must be in unsigned byte RGBA format. The alpha channel will be ignored if DxtType is IL_DXT1.
ILuint ilNVidiaCompressDXTFile(ILubyte *Data, ILuint Width, ILuint Height, ILuint Depth, ILenum DxtFormat)
{
ILuint FilePos = itellw();
// The nVidia Texture Tools library does not support volume textures yet.
if (Depth != 1) {
ilSetError(IL_INVALID_PARAM);
return 0;
}
InputOptions inputOptions;
inputOptions.setTextureLayout(TextureType_2D, Width, Height);
inputOptions.setMipmapData(Data, Width, Height);
inputOptions.setMipmapGeneration(false, -1); //@TODO: Use this in certain cases.
OutputOptions outputOptions;
ilOutputHandlerFile outputHandler(Width, Height, DxtFormat);
outputOptions.setOutputHeader(false);
outputOptions.setOutputHandler(&outputHandler);
CompressionOptions compressionOptions;
switch (DxtFormat)
{
case IL_DXT1:
compressionOptions.setFormat(Format_DXT1);
break;
case IL_DXT1A:
compressionOptions.setFormat(Format_DXT1a);
break;
case IL_DXT3:
compressionOptions.setFormat(Format_DXT1);
break;
case IL_DXT5:
compressionOptions.setFormat(Format_DXT5);
break;
default: // Does not support DXT2 or DXT4.
ilSetError(IL_INVALID_PARAM);
break;
}
Compressor compressor;
compressor.process(inputOptions, compressionOptions, outputOptions);
return itellw() - FilePos; // Return the number of characters written.
}
#else
// Let's have this so that the function is always created and exported, even if it does nothing.
ILAPI ILubyte* ILAPIENTRY ilNVidiaCompressDXT(ILubyte *Data, ILuint Width, ILuint Height, ILuint Depth, ILenum DxtFormat, ILuint *DxtSize)
{
//@TODO: Do we need to set an error message?
return NULL;
}
#endif//IL_NO_DXTC_NVIDIA
File diff suppressed because it is too large Load Diff
+207
View File
@@ -0,0 +1,207 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 03/07/2009
//
// Filename: src-IL/src/il_pcd.c
//
// Description: Reads from a Kodak PhotoCD (.pcd) file.
// Note: The code here is sloppy - I had to convert it from Pascal,
// which I've never even attempted to read before...enjoy! =)
//
//-----------------------------------------------------------------------------
#include "il_internal.h"
#ifndef IL_NO_PCD
#include "il_manip.h"
ILboolean iLoadPcdInternal(void);
//! Reads a .pcd file
ILboolean ilLoadPcd(ILconst_string FileName)
{
ILHANDLE PcdFile;
ILboolean bPcd = IL_FALSE;
PcdFile = iopenr(FileName);
if (PcdFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bPcd;
}
bPcd = ilLoadPcdF(PcdFile);
icloser(PcdFile);
return bPcd;
}
//! Reads an already-opened .pcd file
ILboolean ilLoadPcdF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iLoadPcdInternal();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Reads from a memory "lump" that contains a .pcd file
ILboolean ilLoadPcdL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iLoadPcdInternal();
}
void YCbCr2RGB(ILubyte Y, ILubyte Cb, ILubyte Cr, ILubyte *r, ILubyte *g, ILubyte *b)
{
static const ILdouble c11 = 0.0054980*256;
static const ILdouble c12 = 0.0000000*256;
static const ILdouble c13 = 0.0051681*256;
static const ILdouble c21 = 0.0054980*256;
static const ILdouble c22 =-0.0015446*256;
static const ILdouble c23 =-0.0026325*256;
static const ILdouble c31 = 0.0054980*256;
static const ILdouble c32 = 0.0079533*256;
static const ILdouble c33 = 0.0000000*256;
ILint r1, g1, b1;
r1 = (ILint)(c11*Y + c12*(Cb-156) + c13*(Cr-137));
g1 = (ILint)(c21*Y + c22*(Cb-156) + c23*(Cr-137));
b1 = (ILint)(c31*Y + c32*(Cb-156) + c33*(Cr-137));
if (r1 < 0)
*r = 0;
else if (r1 > 255)
*r = 255;
else
*r = r1;
if (g1 < 0)
*g = 0;
else if (g1 > 255)
*g = 255;
else
*g = g1;
if (b1 < 0)
*b = 0;
else if (b1 > 255)
*b = 255;
else
*b = b1;
return;
}
ILboolean iLoadPcdInternal()
{
ILubyte VertOrientation;
ILuint Width, Height, i, Total, x, CurPos = 0;
ILubyte *Y1=NULL, *Y2=NULL, *CbCr=NULL, r = 0, g = 0, b = 0;
ILuint PicNum;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
iseek(72, IL_SEEK_CUR);
if (iread(&VertOrientation, 1, 1) != 1)
return IL_FALSE;
iseek(-72, IL_SEEK_CUR); // Can't rewind
PicNum = iGetInt(IL_PCD_PICNUM);
switch (PicNum)
{
case 0:
iseek(0x02000, IL_SEEK_CUR);
Width = 192;
Height = 128;
break;
case 1:
iseek(0x0b800, IL_SEEK_CUR);
Width = 384;
Height = 256;
break;
case 2:
iseek(0x30000, IL_SEEK_CUR);
Width = 768;
Height = 512;
break;
default:
ilSetError(IL_INVALID_PARAM);
return IL_FALSE;
}
if (itell() == IL_EOF) // Supposed to have data here.
return IL_FALSE;
Y1 = (ILubyte*)ialloc(Width);
Y2 = (ILubyte*)ialloc(Width);
CbCr = (ILubyte*)ialloc(Width);
if (Y1 == NULL || Y2 == NULL || CbCr == NULL) {
ifree(Y1);
ifree(Y2);
ifree(CbCr);
return IL_FALSE;
}
if (!ilTexImage(Width, Height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL)) {
return IL_FALSE;
}
iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
Total = Height >> 1;
for (i = 0; i < Total; i++) {
iread(Y1, 1, Width);
iread(Y2, 1, Width);
if (iread(CbCr, 1, Width) != Width) { // Only really need to check the last one.
ifree(Y1);
ifree(Y2);
ifree(CbCr);
return IL_FALSE;
}
for (x = 0; x < Width; x++) {
YCbCr2RGB(Y1[x], CbCr[x / 2], CbCr[(Width / 2) + (x / 2)], &r, &g, &b);
iCurImage->Data[CurPos++] = r;
iCurImage->Data[CurPos++] = g;
iCurImage->Data[CurPos++] = b;
}
for (x = 0; x < Width; x++) {
YCbCr2RGB(Y2[x], CbCr[x / 2], CbCr[(Width / 2) + (x / 2)], &r, &g, &b);
iCurImage->Data[CurPos++] = r;
iCurImage->Data[CurPos++] = g;
iCurImage->Data[CurPos++] = b;
}
}
ifree(Y1);
ifree(Y2);
ifree(CbCr);
// Not sure how it is...the documentation is hard to understand
if ((VertOrientation & 0x3F) != 8)
iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
else
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
return ilFixImage();
}
#endif//IL_NO_PCD
+740
View File
@@ -0,0 +1,740 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 03/07/2009
//
// Filename: src-IL/src/il_pcx.c
//
// Description: Reads and writes from/to a .pcx file.
//
//-----------------------------------------------------------------------------
#include "il_internal.h"
#ifndef IL_NO_PCX
#include "il_pcx.h"
#include "il_manip.h"
//! Checks if the file specified in FileName is a valid .pcx file.
ILboolean ilIsValidPcx(ILconst_string FileName)
{
ILHANDLE PcxFile;
ILboolean bPcx = IL_FALSE;
if (!iCheckExtension(FileName, IL_TEXT("pcx"))) {
ilSetError(IL_INVALID_EXTENSION);
return bPcx;
}
PcxFile = iopenr(FileName);
if (PcxFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bPcx;
}
bPcx = ilIsValidPcxF(PcxFile);
icloser(PcxFile);
return bPcx;
}
//! Checks if the ILHANDLE contains a valid .pcx file at the current position.
ILboolean ilIsValidPcxF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iIsValidPcx();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Checks if Lump is a valid .pcx lump.
ILboolean ilIsValidPcxL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iIsValidPcx();
}
// Internal function obtain the .pcx header from the current file.
ILboolean iGetPcxHead(PCXHEAD *Head)
{
Head->Manufacturer = igetc();
Head->Version = igetc();
Head->Encoding = igetc();
Head->Bpp = igetc();
Head->Xmin = GetLittleUShort();
Head->Ymin = GetLittleUShort();
Head->Xmax = GetLittleUShort();
Head->Ymax = GetLittleUShort();
Head->HDpi = GetLittleUShort();
Head->VDpi = GetLittleUShort();
iread(Head->ColMap, 1, 48);
Head->Reserved = igetc();
Head->NumPlanes = igetc();
Head->Bps = GetLittleUShort();
Head->PaletteInfo = GetLittleUShort();
Head->HScreenSize = GetLittleUShort();
Head->VScreenSize = GetLittleUShort();
iread(Head->Filler, 1, 54);
return IL_TRUE;
}
// Internal function to get the header and check it.
ILboolean iIsValidPcx()
{
PCXHEAD Head;
if (!iGetPcxHead(&Head))
return IL_FALSE;
iseek(-(ILint)sizeof(PCXHEAD), IL_SEEK_CUR);
return iCheckPcx(&Head);
}
// Internal function used to check if the HEADER is a valid .pcx header.
// Should we also do a check on Header->Bpp?
ILboolean iCheckPcx(PCXHEAD *Header)
{
ILuint Test;
// Got rid of the Reserved check, because I've seen some .pcx files with invalid values in it.
if (Header->Manufacturer != 10 || Header->Encoding != 1/* || Header->Reserved != 0*/)
return IL_FALSE;
// Try to support all pcx versions, as they only differ in allowed formats...
// Let's hope it works.
if(Header->Version != 5 && Header->Version != 0 && Header->Version != 2 &&
Header->VDpi != 3 && Header->VDpi != 4)
return IL_FALSE;
// See if the padding size is correct
Test = Header->Xmax - Header->Xmin + 1;
if (Header->Bpp >= 8) {
if (Test & 1) {
if (Header->Bps != Test + 1)
return IL_FALSE;
}
else {
if (Header->Bps != Test) // No padding
return IL_FALSE;
}
}
/* for (i = 0; i < 54; i++) { useless check
if (Header->Filler[i] != 0)
return IL_FALSE;
} */
return IL_TRUE;
}
//! Reads a .pcx file
ILboolean ilLoadPcx(ILconst_string FileName)
{
ILHANDLE PcxFile;
ILboolean bPcx = IL_FALSE;
PcxFile = iopenr(FileName);
if (PcxFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bPcx;
}
bPcx = ilLoadPcxF(PcxFile);
icloser(PcxFile);
return bPcx;
}
//! Reads an already-opened .pcx file
ILboolean ilLoadPcxF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iLoadPcxInternal();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Reads from a memory "lump" that contains a .pcx
ILboolean ilLoadPcxL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iLoadPcxInternal();
}
// Internal function used to load the .pcx.
ILboolean iLoadPcxInternal()
{
PCXHEAD Header;
ILboolean bPcx = IL_FALSE;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return bPcx;
}
if (!iGetPcxHead(&Header))
return IL_FALSE;
if (!iCheckPcx(&Header)) {
ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
}
bPcx = iUncompressPcx(&Header);
if (!bPcx)
return IL_FALSE;
return ilFixImage();
}
// Internal function to uncompress the .pcx (all .pcx files are rle compressed)
ILboolean iUncompressPcx(PCXHEAD *Header)
{
//changed decompression loop 2003-09-01
//From the pcx spec: "There should always
//be a decoding break at the end of each scan line.
//But there will not be a decoding break at the end of
//each plane within each scan line."
//This is now handled correctly (hopefully ;) )
ILubyte ByteHead, Colour, *ScanLine /* For all planes */;
ILuint ScanLineSize;
ILuint c, i, x, y;
if (Header->Bpp < 8) {
/*ilSetError(IL_FORMAT_NOT_SUPPORTED);
return IL_FALSE;*/
return iUncompressSmall(Header);
}
if (!ilTexImage(Header->Xmax - Header->Xmin + 1, Header->Ymax - Header->Ymin + 1, 1, Header->NumPlanes, 0, IL_UNSIGNED_BYTE, NULL))
return IL_FALSE;
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
switch (iCurImage->Bpp)
{
case 1:
iCurImage->Format = IL_COLOUR_INDEX;
iCurImage->Pal.PalType = IL_PAL_RGB24;
iCurImage->Pal.PalSize = 256 * 3; // Need to find out for sure...
iCurImage->Pal.Palette = (ILubyte*)ialloc(iCurImage->Pal.PalSize);
if (iCurImage->Pal.Palette == NULL) {
return IL_FALSE;
}
break;
//case 2: // No 16-bit images in the pcx format!
case 3:
iCurImage->Format = IL_RGB;
iCurImage->Pal.Palette = NULL;
iCurImage->Pal.PalSize = 0;
iCurImage->Pal.PalType = IL_PAL_NONE;
break;
case 4:
iCurImage->Format = IL_RGBA;
iCurImage->Pal.Palette = NULL;
iCurImage->Pal.PalSize = 0;
iCurImage->Pal.PalType = IL_PAL_NONE;
break;
default:
ilSetError(IL_ILLEGAL_FILE_VALUE);
return IL_FALSE;
}
ScanLineSize = iCurImage->Bpp*Header->Bps;
ScanLine = (ILubyte*)ialloc(ScanLineSize);
if (ScanLine == NULL) {
return IL_FALSE;
}
//changed 2003-09-01
//having the decoding code twice is error-prone,
//so I made iUnCache() smart enough to grasp
//if iPreCache() wasn't called and call it
//anyways.
if (iGetHint(IL_MEM_SPEED_HINT) == IL_FASTEST)
iPreCache(iCurImage->SizeOfData / 4);
for (y = 0; y < iCurImage->Height; y++) {
x = 0;
//read scanline
while (x < ScanLineSize) {
if (iread(&ByteHead, 1, 1) != 1) {
iUnCache();
goto file_read_error;
}
if ((ByteHead & 0xC0) == 0xC0) {
ByteHead &= 0x3F;
if (iread(&Colour, 1, 1) != 1) {
iUnCache();
goto file_read_error;
}
if (x + ByteHead > ScanLineSize) {
iUnCache();
goto file_read_error;
}
for (i = 0; i < ByteHead; i++) {
ScanLine[x++] = Colour;
}
}
else {
ScanLine[x++] = ByteHead;
}
}
//convert plane-separated scanline into index, rgb or rgba pixels.
//there might be a padding byte at the end of each scanline...
for (x = 0; x < iCurImage->Width; x++) {
for(c = 0; c < iCurImage->Bpp; c++) {
iCurImage->Data[y * iCurImage->Bps + x * iCurImage->Bpp + c] =
ScanLine[x + c * Header->Bps];
}
}
}
iUnCache();
// Read in the palette
if (Header->Version == 5 && iCurImage->Bpp == 1) {
x = itell();
if (iread(&ByteHead, 1, 1) == 0) { // If true, assume that we have a luminance image.
ilGetError(); // Get rid of the IL_FILE_READ_ERROR.
iCurImage->Format = IL_LUMINANCE;
if (iCurImage->Pal.Palette)
ifree(iCurImage->Pal.Palette);
iCurImage->Pal.PalSize = 0;
iCurImage->Pal.PalType = IL_PAL_NONE;
}
else {
if (ByteHead != 12) // Some Quake2 .pcx files don't have this byte for some reason.
iseek(-1, IL_SEEK_CUR);
if (iread(iCurImage->Pal.Palette, 1, iCurImage->Pal.PalSize) != iCurImage->Pal.PalSize)
goto file_read_error;
}
}
ifree(ScanLine);
return IL_TRUE;
file_read_error:
ifree(ScanLine);
//added 2003-09-01
ilSetError(IL_FILE_READ_ERROR);
return IL_FALSE;
}
ILboolean iUncompressSmall(PCXHEAD *Header)
{
ILuint i = 0, j, k, c, d, x, y, Bps;
ILubyte HeadByte, Colour, Data = 0, *ScanLine;
if (!ilTexImage(Header->Xmax - Header->Xmin + 1, Header->Ymax - Header->Ymin + 1, 1, 1, 0, IL_UNSIGNED_BYTE, NULL)) {
return IL_FALSE;
}
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
switch (Header->NumPlanes)
{
case 1:
iCurImage->Format = IL_LUMINANCE;
break;
case 4:
iCurImage->Format = IL_COLOUR_INDEX;
break;
default:
ilSetError(IL_ILLEGAL_FILE_VALUE);
return IL_FALSE;
}
if (Header->NumPlanes == 1 && Header->Bpp == 1) {
for (j = 0; j < iCurImage->Height; j++) {
i = 0; //number of written pixels
while (i < iCurImage->Width) {
if (iread(&HeadByte, 1, 1) != 1)
return IL_FALSE;
if (HeadByte >= 192) {
HeadByte -= 192;
if (iread(&Data, 1, 1) != 1)
return IL_FALSE;
for (c = 0; c < HeadByte; c++) {
k = 128;
for (d = 0; d < 8 && i < iCurImage->Width; d++) {
iCurImage->Data[j * iCurImage->Width + i++] = ((Data & k) != 0 ? 255 : 0);
k >>= 1;
}
}
}
else {
k = 128;
for (c = 0; c < 8 && i < iCurImage->Width; c++) {
iCurImage->Data[j * iCurImage->Width + i++] = ((HeadByte & k) != 0 ? 255 : 0);
k >>= 1;
}
}
}
//if(Data != 0)
//changed 2003-09-01:
//There has to be an even number of bytes per line in a pcx.
//One byte can hold up to 8 bits, so Width/8 bytes
//are needed to hold a 1 bit per pixel image line.
//If Width/8 is even no padding is needed,
//one pad byte has to be read otherwise.
//(let's hope the above is true ;-))
if(!((iCurImage->Width >> 3) & 0x1))
igetc(); // Skip pad byte
}
}
else if (Header->NumPlanes == 4 && Header->Bpp == 1){ // 4-bit images
//changed decoding 2003-09-10 (was buggy)...could need a speedup
Bps = Header->Bps * Header->NumPlanes * 8;
iCurImage->Pal.Palette = (ILubyte*)ialloc(16 * 3); // Size of palette always (48 bytes).
ScanLine = (ILubyte*)ialloc(Bps);
if (iCurImage->Pal.Palette == NULL || ScanLine == NULL) {
ifree(ScanLine);
ifree(iCurImage->Pal.Palette);
return IL_FALSE;
}
memcpy(iCurImage->Pal.Palette, Header->ColMap, 16 * 3);
iCurImage->Pal.PalSize = 16 * 3;
iCurImage->Pal.PalType = IL_PAL_RGB24;
memset(iCurImage->Data, 0, iCurImage->SizeOfData);
if (iGetHint(IL_MEM_SPEED_HINT) == IL_FASTEST)
iPreCache(iCurImage->SizeOfData / 4);
for (y = 0; y < iCurImage->Height; y++) {
x = 0;
while (x < Bps) {
if (iread(&HeadByte, 1, 1) != 1) {
iUnCache();
ifree(ScanLine);
return IL_FALSE;
}
if ((HeadByte & 0xC0) == 0xC0) {
HeadByte &= 0x3F;
if (iread(&Colour, 1, 1) != 1) {
iUnCache();
ifree(ScanLine);
return IL_FALSE;
}
for (i = 0; i < HeadByte; i++) {
k = 128;
for (j = 0; j < 8 && x < Bps; j++) {
ScanLine[x++] = (Colour & k)?1:0;
k >>= 1;
}
}
}
else {
k = 128;
for (j = 0; j < 8 && x < Bps; j++) {
ScanLine[x++] = (HeadByte & k)?1:0;
k >>= 1;
}
}
}
for (x = 0; x < iCurImage->Width; x++) { // 'Cleverly' ignores the pad bytes. ;)
for(c = 0; c < Header->NumPlanes; c++)
iCurImage->Data[y * iCurImage->Width + x] |= ScanLine[x + c*Header->Bps*8] << c;
}
}
iUnCache();
ifree(ScanLine);
}
else {
ilSetError(IL_FORMAT_NOT_SUPPORTED);
return IL_FALSE;
}
return IL_TRUE;
}
//! Writes a .pcx file
ILboolean ilSavePcx(const ILstring FileName)
{
ILHANDLE PcxFile;
ILuint PcxSize;
if (ilGetBoolean(IL_FILE_MODE) == IL_FALSE) {
if (iFileExists(FileName)) {
ilSetError(IL_FILE_ALREADY_EXISTS);
return IL_FALSE;
}
}
PcxFile = iopenw(FileName);
if (PcxFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return IL_FALSE;
}
PcxSize = ilSavePcxF(PcxFile);
iclosew(PcxFile);
if (PcxSize == 0)
return IL_FALSE;
return IL_TRUE;
}
//! Writes a .pcx to an already-opened file
ILuint ilSavePcxF(ILHANDLE File)
{
ILuint Pos;
iSetOutputFile(File);
Pos = itellw();
if (iSavePcxInternal() == IL_FALSE)
return 0; // Error occurred
return itellw() - Pos; // Return the number of bytes written.
}
//! Writes a .pcx to a memory "lump"
ILuint ilSavePcxL(void *Lump, ILuint Size)
{
ILuint Pos;
iSetOutputLump(Lump, Size);
Pos = itellw();
if (iSavePcxInternal() == IL_FALSE)
return 0; // Error occurred
return itellw() - Pos; // Return the number of bytes written.
}
// Internal function used to save the .pcx.
ILboolean iSavePcxInternal()
{
ILuint i, c, PalSize;
ILpal *TempPal;
ILimage *TempImage = iCurImage;
ILubyte *TempData;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
switch (iCurImage->Format)
{
case IL_LUMINANCE:
TempImage = iConvertImage(iCurImage, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE);
if (TempImage == NULL)
return IL_FALSE;
break;
case IL_BGR:
TempImage = iConvertImage(iCurImage, IL_RGB, IL_UNSIGNED_BYTE);
if (TempImage == NULL)
return IL_FALSE;
break;
case IL_BGRA:
TempImage = iConvertImage(iCurImage, IL_RGBA, IL_UNSIGNED_BYTE);
if (TempImage == NULL)
return IL_FALSE;
break;
default:
if (iCurImage->Bpc > 1) {
TempImage = iConvertImage(iCurImage, iCurImage->Format, IL_UNSIGNED_BYTE);
if (TempImage == NULL)
return IL_FALSE;
}
}
if (TempImage->Origin != IL_ORIGIN_UPPER_LEFT) {
TempData = iGetFlipped(TempImage);
if (TempData == NULL) {
if (TempImage != iCurImage) {
ilCloseImage(TempImage);
}
return IL_FALSE;
}
}
else {
TempData = TempImage->Data;
}
iputc(0xA); // Manufacturer - always 10
iputc(0x5); // Version Number - always 5
iputc(0x1); // Encoding - always 1
iputc(0x8); // Bits per channel
SaveLittleUShort(0); // X Minimum
SaveLittleUShort(0); // Y Minimum
SaveLittleUShort((ILushort)(iCurImage->Width - 1));
SaveLittleUShort((ILushort)(iCurImage->Height - 1));
SaveLittleUShort(0);
SaveLittleUShort(0);
// Useless palette info?
for (i = 0; i < 48; i++) {
iputc(0);
}
iputc(0x0); // Reserved - always 0
iputc(iCurImage->Bpp); // Number of planes - only 1 is supported right now
SaveLittleUShort((ILushort)(iCurImage->Width & 1 ? iCurImage->Width + 1 : iCurImage->Width)); // Bps
SaveLittleUShort(0x1); // Palette type - ignored?
// Mainly filler info
for (i = 0; i < 58; i++) {
iputc(0x0);
}
// Output data
for (i = 0; i < TempImage->Height; i++) {
for (c = 0; c < TempImage->Bpp; c++) {
encLine(TempData + TempImage->Bps * i + c, TempImage->Width, (ILubyte)(TempImage->Bpp - 1));
}
}
// Automatically assuming we have a palette...dangerous!
// Also assuming 3 bpp palette
iputc(0xC); // Pad byte must have this value
// If the current image has a palette, take care of it
if (TempImage->Format == IL_COLOUR_INDEX) {
// If the palette in .pcx format, write it directly
if (TempImage->Pal.PalType == IL_PAL_RGB24) {
iwrite(TempImage->Pal.Palette, 1, TempImage->Pal.PalSize);
}
else {
TempPal = iConvertPal(&TempImage->Pal, IL_PAL_RGB24);
if (TempPal == NULL) {
if (TempImage->Origin == IL_ORIGIN_LOWER_LEFT)
ifree(TempData);
if (TempImage != iCurImage)
ilCloseImage(TempImage);
return IL_FALSE;
}
iwrite(TempPal->Palette, 1, TempPal->PalSize);
ifree(TempPal->Palette);
ifree(TempPal);
}
}
// If the palette is not all 256 colours, we have to pad it.
PalSize = 768 - iCurImage->Pal.PalSize;
for (i = 0; i < PalSize; i++) {
iputc(0x0);
}
if (TempImage->Origin == IL_ORIGIN_LOWER_LEFT)
ifree(TempData);
if (TempImage != iCurImage)
ilCloseImage(TempImage);
return IL_TRUE;
}
// Routine used from ZSoft's pcx documentation
ILuint encput(ILubyte byt, ILubyte cnt)
{
if (cnt) {
if ((cnt == 1) && (0xC0 != (0xC0 & byt))) {
if (IL_EOF == iputc(byt))
return(0); /* disk write error (probably full) */
return(1);
}
else {
if (IL_EOF == iputc((ILubyte)((ILuint)0xC0 | cnt)))
return (0); /* disk write error */
if (IL_EOF == iputc(byt))
return (0); /* disk write error */
return (2);
}
}
return (0);
}
// This subroutine encodes one scanline and writes it to a file.
// It returns number of bytes written into outBuff, 0 if failed.
ILuint encLine(ILubyte *inBuff, ILint inLen, ILubyte Stride)
{
ILubyte _this, last;
ILint srcIndex, i;
ILint total;
ILubyte runCount; // max single runlength is 63
total = 0;
runCount = 1;
last = *(inBuff);
// Find the pixel dimensions of the image by calculating
//[XSIZE = Xmax - Xmin + 1] and [YSIZE = Ymax - Ymin + 1].
//Then calculate how many bytes are in a "run"
for (srcIndex = 1; srcIndex < inLen; srcIndex++) {
inBuff += Stride;
_this = *(++inBuff);
if (_this == last) { // There is a "run" in the data, encode it
runCount++;
if (runCount == 63) {
if (! (i = encput(last, runCount)))
return (0);
total += i;
runCount = 0;
}
}
else { // No "run" - _this != last
if (runCount) {
if (! (i = encput(last, runCount)))
return(0);
total += i;
}
last = _this;
runCount = 1;
}
} // endloop
if (runCount) { // finish up
if (! (i = encput(last, runCount)))
return (0);
if (inLen % 2)
iputc(0);
return (total + i);
}
else {
if (inLen % 2)
iputc(0);
}
return (total);
}
#endif//IL_NO_PCX
+426
View File
@@ -0,0 +1,426 @@
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 03/07/2009
//
// Filename: src-IL/src/il_pic.c
//
// Description: Softimage Pic (.pic) functions
// Lots of this code is taken from Paul Bourke's Softimage Pic code at
// http://local.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/
//
//-----------------------------------------------------------------------------
#include "il_internal.h"
#ifndef IL_NO_PIC
#include "il_pic.h"
#include "il_manip.h"
#include <string.h>
//! Checks if the file specified in FileName is a valid .pic file.
ILboolean ilIsValidPic(ILconst_string FileName)
{
ILHANDLE PicFile;
ILboolean bPic = IL_FALSE;
if (!iCheckExtension(FileName, IL_TEXT("pic"))) {
ilSetError(IL_INVALID_EXTENSION);
return bPic;
}
PicFile = iopenr(FileName);
if (PicFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bPic;
}
bPic = ilIsValidPicF(PicFile);
icloser(PicFile);
return bPic;
}
//! Checks if the ILHANDLE contains a valid .pic file at the current position.
ILboolean ilIsValidPicF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iIsValidPic();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Checks if Lump is a valid .pic lump.
ILboolean ilIsValidPicL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iIsValidPic();
}
// Internal function used to get the .pic header from the current file.
ILboolean iGetPicHead(PIC_HEAD *Header)
{
Header->Magic = GetBigInt();
Header->Version = GetBigFloat();
iread(Header->Comment, 1, 80);
iread(Header->Id, 1, 4);
Header->Width = GetBigShort();
Header->Height = GetBigShort();
Header->Ratio = GetBigFloat();
Header->Fields = GetBigShort();
Header->Padding = GetBigShort();
return IL_TRUE;
}
// Internal function to get the header and check it.
ILboolean iIsValidPic()
{
PIC_HEAD Head;
if (!iGetPicHead(&Head))
return IL_FALSE;
iseek(-(ILint)sizeof(PIC_HEAD), IL_SEEK_CUR); // Go ahead and restore to previous state
return iCheckPic(&Head);
}
// Internal function used to check if the header is a valid .pic header.
ILboolean iCheckPic(PIC_HEAD *Header)
{
if (Header->Magic != 0x5380F634)
return IL_FALSE;
if (strncmp((const char*)Header->Id, "PICT", 4))
return IL_FALSE;
if (Header->Width == 0)
return IL_FALSE;
if (Header->Height == 0)
return IL_FALSE;
return IL_TRUE;
}
//! Reads a .pic file
ILboolean ilLoadPic(ILconst_string FileName)
{
ILHANDLE PicFile;
ILboolean bPic = IL_FALSE;
PicFile = iopenr(FileName);
if (PicFile == NULL) {
ilSetError(IL_COULD_NOT_OPEN_FILE);
return bPic;
}
bPic = ilLoadPicF(PicFile);
icloser(PicFile);
return bPic;
}
//! Reads an already-opened .pic file
ILboolean ilLoadPicF(ILHANDLE File)
{
ILuint FirstPos;
ILboolean bRet;
iSetInputFile(File);
FirstPos = itell();
bRet = iLoadPicInternal();
iseek(FirstPos, IL_SEEK_SET);
return bRet;
}
//! Reads from a memory "lump" that contains a .pic
ILboolean ilLoadPicL(const void *Lump, ILuint Size)
{
iSetInputLump(Lump, Size);
return iLoadPicInternal();
}
// Internal function used to load the .pic
ILboolean iLoadPicInternal()
{
ILuint Alpha = IL_FALSE;
ILubyte Chained;
CHANNEL *Channel = NULL, *Channels = NULL, *Prev;
PIC_HEAD Header;
ILboolean Read;
if (iCurImage == NULL) {
ilSetError(IL_ILLEGAL_OPERATION);
return IL_FALSE;
}
if (!iGetPicHead(&Header))
return IL_FALSE;
if (!iCheckPic(&Header)) {
ilSetError(IL_INVALID_FILE_HEADER);
return IL_FALSE;
}
// Read channels
do {
if (Channel == NULL) {
Channel = Channels = (CHANNEL*)ialloc(sizeof(CHANNEL));
if (Channels == NULL)
return IL_FALSE;
}
else {
Channels->Next = (CHANNEL*)ialloc(sizeof(CHANNEL));
if (Channels->Next == NULL) {
// Clean up the list before erroring out.
while (Channel) {
Prev = Channel;
Channel = (CHANNEL*)Channel->Next;
ifree(Prev);
}
return IL_FALSE;
}
Channels = (CHANNEL*)Channels->Next;
}
Channels->Next = NULL;
Chained = igetc();
Channels->Size = igetc();
Channels->Type = igetc();
Channels->Chan = igetc();
if (ieof()) {
Read = IL_FALSE;
goto finish;
}
// See if we have an alpha channel in there
if (Channels->Chan & PIC_ALPHA_CHANNEL)
Alpha = IL_TRUE;
} while (Chained);
if (Alpha) { // Has an alpha channel
if (!ilTexImage(Header.Width, Header.Height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL)) {
Read = IL_FALSE;
goto finish; // Have to destroy Channels first.
}
}
else { // No alpha channel
if (!ilTexImage(Header.Width, Header.Height, 1, 3, IL_RGBA, IL_UNSIGNED_BYTE, NULL)) {
Read = IL_FALSE;
goto finish; // Have to destroy Channels first.
}
}
iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
Read = readScanlines((ILuint*)iCurImage->Data, Header.Width, Header.Height, Channel, Alpha);
finish:
// Destroy channels
while (Channel) {
Prev = Channel;
Channel = (CHANNEL*)Channel->Next;
ifree(Prev);
}
if (Read == IL_FALSE)
return IL_FALSE;
return ilFixImage();
}
ILboolean readScanlines(ILuint *image, ILint width, ILint height, CHANNEL *channel, ILuint alpha)
{
ILint i;
ILuint *scan;
(void)alpha;
for (i = height - 1; i >= 0; i--) {
scan = image + i * width;
if (!readScanline((ILubyte *)scan, width, channel, alpha ? 4 : 3)) {
ilSetError(IL_ILLEGAL_FILE_VALUE);
return IL_FALSE;
}
}
return IL_TRUE;
}
ILuint readScanline(ILubyte *scan, ILint width, CHANNEL *channel, ILint bytes)
{
ILint noCol;
ILint off[4];
ILuint status=0;
while (channel) {
noCol = 0;
if(channel->Chan & PIC_RED_CHANNEL) {
off[noCol] = 0;
noCol++;
}
if(channel->Chan & PIC_GREEN_CHANNEL) {
off[noCol] = 1;
noCol++;
}
if(channel->Chan & PIC_BLUE_CHANNEL) {
off[noCol] = 2;
noCol++;
}
if(channel->Chan & PIC_ALPHA_CHANNEL) {
off[noCol] = 3;
noCol++;
//@TODO: Find out if this is possible.
if (bytes == 3) // Alpha channel in a 24-bit image. Do not know what to do with this.
return 0;
}
switch(channel->Type & 0x0F)
{
case PIC_UNCOMPRESSED:
status = channelReadRaw(scan, width, noCol, off, bytes);
break;
case PIC_PURE_RUN_LENGTH:
status = channelReadPure(scan, width, noCol, off, bytes);
break;
case PIC_MIXED_RUN_LENGTH:
status = channelReadMixed(scan, width, noCol, off, bytes);
break;
}
if (!status)
break;
channel = (CHANNEL*)channel->Next;
}
return status;
}
ILboolean channelReadRaw(ILubyte *scan, ILint width, ILint noCol, ILint *off, ILint bytes)
{
ILint i, j;
for (i = 0; i < width; i++) {
if (ieof())
return IL_FALSE;
for (j = 0; j < noCol; j++)
if (iread(&scan[off[j]], 1, 1) != 1)
return IL_FALSE;
scan += bytes;
}
return IL_TRUE;
}
ILboolean channelReadPure(ILubyte *scan, ILint width, ILint noCol, ILint *off, ILint bytes)
{
ILubyte col[4];
ILint count;
int i, j, k;
for (i = width; i > 0; ) {
count = igetc();
if (count == IL_EOF)
return IL_FALSE;
if (count > width)
count = width;
i -= count;
if (ieof())
return IL_FALSE;
for (j = 0; j < noCol; j++)
if (iread(&col[j], 1, 1) != 1)
return IL_FALSE;
for (k = 0; k < count; k++, scan += bytes) {
for(j = 0; j < noCol; j++)
scan[off[j] + k] = col[j];
}
}
return IL_TRUE;
}
ILboolean channelReadMixed(ILubyte *scan, ILint width, ILint noCol, ILint *off, ILint bytes)
{
ILint count;
int i, j, k;
ILubyte col[4];
for(i = 0; i < width; i += count) {
if (ieof())
return IL_FALSE;
count = igetc();
if (count == IL_EOF)
return IL_FALSE;
if (count >= 128) { // Repeated sequence
if (count == 128) { // Long run
count = GetBigUShort();
if (ieof()) {
ilSetError(IL_FILE_READ_ERROR);
return IL_FALSE;
}
}
else
count -= 127;
// We've run past...
if ((i + count) > width) {
//fprintf(stderr, "ERROR: FF_PIC_load(): Overrun scanline (Repeat) [%d + %d > %d] (NC=%d)\n", i, count, width, noCol);
ilSetError(IL_ILLEGAL_FILE_VALUE);
return IL_FALSE;
}
for (j = 0; j < noCol; j++)
if (iread(&col[j], 1, 1) != 1) {
ilSetError(IL_FILE_READ_ERROR);
return IL_FALSE;
}
for (k = 0; k < count; k++, scan += bytes) {
for (j = 0; j < noCol; j++)
scan[off[j]] = col[j];
}
} else { // Raw sequence
count++;
if ((i + count) > width) {
//fprintf(stderr, "ERROR: FF_PIC_load(): Overrun scanline (Raw) [%d + %d > %d] (NC=%d)\n", i, count, width, noCol);
ilSetError(IL_ILLEGAL_FILE_VALUE);
return IL_FALSE;
}
for (k = count; k > 0; k--, scan += bytes) {
for (j = 0; j < noCol; j++)
if (iread(&scan[off[j]], 1, 1) != 1) {
ilSetError(IL_FILE_READ_ERROR);
return IL_FALSE;
}
}
}
}
return IL_TRUE;
}
#endif//IL_NO_PIC

Some files were not shown because too many files have changed in this diff Show More