Restructure repository to include all source folders
Move git root from Client/ to src/ to track all source code: - Client: Game client source (moved to Client/Client/) - Server: Game server source - GameTools: Development tools - CryptoSource: Encryption utilities - database: Database scripts - Script: Game scripts - rylCoder_16.02.2008_src: Legacy coder tools - GMFont, Game: Additional resources 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Last modified: 17/04/2005
|
||||
// by Meloni Dario
|
||||
//
|
||||
// Description: Common altivec function.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "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,228 @@
|
||||
#include "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
|
||||
252
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_alloc.c
Normal file
252
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_alloc.c
Normal file
@@ -0,0 +1,252 @@
|
||||
|
||||
#define __ALLOC_C
|
||||
#include "il_internal.h"
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef MM_MALLOC
|
||||
#include <mm_malloc.h>
|
||||
#endif
|
||||
|
||||
static ILvoid ILAPIENTRY DefaultFreeFunc(const ILvoid * CONST_RESTRICT Ptr);
|
||||
static ILvoid* ILAPIENTRY DefaultAllocFunc(const ILuint Size);
|
||||
|
||||
static mAlloc ialloc_ptr = DefaultAllocFunc;
|
||||
static mFree ifree_ptr = DefaultFreeFunc;
|
||||
|
||||
/*** Vector Allocation/Deallocation Function ***/
|
||||
#ifdef VECTORMEM
|
||||
ILvoid *vec_malloc( const ILuint size ) {
|
||||
const ILuint _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(&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 += diff;
|
||||
((char*)ptr)[-1]= diff;
|
||||
return ptr;
|
||||
#endif //MEMALIGN
|
||||
#endif //POSIX_MEMALIGN
|
||||
#endif //VALLOC
|
||||
#endif //MM_MALLOC
|
||||
}
|
||||
|
||||
ILvoid *ivec_align_buffer( ILvoid *buffer, const ILuint size ) {
|
||||
if( (size_t)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 ***/
|
||||
ILvoid* ILAPIENTRY ialloc(const ILuint Size) {
|
||||
ILvoid *Ptr = ialloc_ptr(Size);
|
||||
if (Ptr == NULL)
|
||||
ilSetError(IL_OUT_OF_MEMORY);
|
||||
return Ptr;
|
||||
}
|
||||
|
||||
ILvoid ILAPIENTRY ifree(const ILvoid * CONST_RESTRICT Ptr) {
|
||||
ifree_ptr(Ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
ILvoid* ILAPIENTRY icalloc(const ILuint Size, const ILuint Num) {
|
||||
ILvoid *Ptr = ialloc(Size * Num);
|
||||
if (Ptr == NULL)
|
||||
return Ptr;
|
||||
imemclear(Ptr, Size * Num);
|
||||
return Ptr;
|
||||
}
|
||||
|
||||
/*** Default Allocation/Deallocation Function ***/
|
||||
static ILvoid* ILAPIENTRY DefaultAllocFunc(const ILuint Size) {
|
||||
#ifdef VECTORMEM
|
||||
return (ILvoid*)vec_malloc(Size);
|
||||
#else
|
||||
return malloc(Size);
|
||||
#endif //VECTORMEM
|
||||
}
|
||||
|
||||
static ILvoid ILAPIENTRY DefaultFreeFunc(const ILvoid * CONST_RESTRICT ptr) {
|
||||
if( ptr ) {
|
||||
#ifdef MM_MALLOC
|
||||
_mm_free((ILvoid*)ptr);
|
||||
#else
|
||||
#if defined(VECTORMEM) & !defined(POSIX_MEMALIGN) & !defined(VALLOC) & !defined(MEMALIGN) & !defined(MM_MALLOC)
|
||||
free(ptr - ((char*)ptr)[-1]);
|
||||
#else
|
||||
free(ptr);
|
||||
#endif //OTHERS...
|
||||
#endif //MM_MALLOC
|
||||
}
|
||||
}
|
||||
|
||||
/*** Manipulate Allocation/Deallocation Function ***/
|
||||
ILvoid ILAPIENTRY ilResetMemory() { // Deprecated
|
||||
ialloc_ptr = DefaultAllocFunc;
|
||||
ifree_ptr = DefaultFreeFunc;
|
||||
}
|
||||
|
||||
ILvoid 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)*/
|
||||
152
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_bits.c
Normal file
152
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_bits.c
Normal file
@@ -0,0 +1,152 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2002 by Denton Woods
|
||||
// Last modified: 05/25/2001 <--Y2K Compliant! =]
|
||||
//
|
||||
// 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;
|
||||
|
||||
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(ILvoid *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...
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
// Not implemented yet.
|
||||
/*ILint bwrite(ILvoid *Buffer, ILuint Size, ILuint Number, BITFILE *BitFile)
|
||||
{
|
||||
1022
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_bmp.c
Normal file
1022
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_bmp.c
Normal file
File diff suppressed because it is too large
Load Diff
1975
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_convbuff.c
Normal file
1975
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_convbuff.c
Normal file
File diff suppressed because it is too large
Load Diff
1042
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_convert.c
Normal file
1042
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_convert.c
Normal file
File diff suppressed because it is too large
Load Diff
150
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_cut.c
Normal file
150
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_cut.c
Normal file
@@ -0,0 +1,150 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2002 by Denton Woods
|
||||
// Last modified: 03/02/2002 <--Y2K Compliant! =]
|
||||
//
|
||||
// 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 ILvoid *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;*/
|
||||
|
||||
ilFixImage();
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
/* ?????????
|
||||
ILvoid ilPopToast() {
|
||||
ILstring flipCode = IL_TEXT("#flipCode and www.flipCode.com rule you all.");
|
||||
flipCode[0] = flipCode[0];
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#endif//IL_NO_CUT
|
||||
493
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_dcx.c
Normal file
493
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_dcx.c
Normal file
@@ -0,0 +1,493 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2002 by Denton Woods
|
||||
// Last modified: 05/20/2002 <--Y2K Compliant! =]
|
||||
//
|
||||
// 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 ILvoid *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 ILvoid *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;
|
||||
}
|
||||
}
|
||||
|
||||
ilFixImage();
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
// 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
|
||||
1296
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_dds-save.c
Normal file
1296
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_dds-save.c
Normal file
File diff suppressed because it is too large
Load Diff
2869
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_dds.c
Normal file
2869
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_dds.c
Normal file
File diff suppressed because it is too large
Load Diff
1107
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_devil.c
Normal file
1107
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_devil.c
Normal file
File diff suppressed because it is too large
Load Diff
276
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_doom.c
Normal file
276
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_doom.c
Normal file
@@ -0,0 +1,276 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2002 by Denton Woods
|
||||
// Last modified: 05/25/2001 <--Y2K Compliant! =]
|
||||
//
|
||||
// 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(ILvoid);
|
||||
ILboolean iLoadDoomFlatInternal(ILvoid);
|
||||
|
||||
|
||||
//
|
||||
// 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 ILvoid *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);
|
||||
}
|
||||
|
||||
ilFixImage();
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// 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 ILvoid *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);
|
||||
}
|
||||
|
||||
ilFixImage();
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
266
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_endian.c
Normal file
266
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_endian.c
Normal file
@@ -0,0 +1,266 @@
|
||||
|
||||
#define IL_ENDIAN_C
|
||||
|
||||
#include "il_endian.h"
|
||||
|
||||
ILvoid 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
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_error.c
Normal file
56
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_error.c
Normal file
@@ -0,0 +1,56 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2002 by Denton Woods
|
||||
// Last modified: 05/25/2001 <--Y2K Compliant! =]
|
||||
//
|
||||
// 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 ILvoid 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(ILvoid)
|
||||
{
|
||||
ILenum ilReturn;
|
||||
|
||||
if (ilErrorPlace >= 0) {
|
||||
ilReturn = ilErrorNum[ilErrorPlace];
|
||||
ilErrorPlace--;
|
||||
}
|
||||
else
|
||||
ilReturn = IL_NO_ERROR;
|
||||
|
||||
return ilReturn;
|
||||
}
|
||||
290
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_fastconv.c
Normal file
290
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_fastconv.c
Normal file
@@ -0,0 +1,290 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2002 by Denton Woods
|
||||
// Last modified: 06/13/2002 <--Y2K Compliant! =]
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
|
||||
695
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_files.c
Normal file
695
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_files.c
Normal file
@@ -0,0 +1,695 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2002 by Denton Woods
|
||||
// Last modified: 09/01/2003 <--Y2K Compliant! =]
|
||||
//
|
||||
// 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(ILvoid);
|
||||
ILboolean ILAPIENTRY iEofLump(ILvoid);
|
||||
ILint ILAPIENTRY iGetcFile(ILvoid);
|
||||
ILint ILAPIENTRY iGetcLump(ILvoid);
|
||||
ILuint ILAPIENTRY iReadFile(ILvoid *Buffer, ILuint Size, ILuint Number);
|
||||
ILuint ILAPIENTRY iReadLump(ILvoid *Buffer, const ILuint Size, const ILuint Number);
|
||||
ILuint ILAPIENTRY iSeekRFile(ILint Offset, ILuint Mode);
|
||||
ILuint ILAPIENTRY iSeekRLump(ILint Offset, ILuint Mode);
|
||||
ILuint ILAPIENTRY iSeekWFile(ILint Offset, ILuint Mode);
|
||||
ILuint ILAPIENTRY iSeekWLump(ILint Offset, ILuint Mode);
|
||||
ILuint ILAPIENTRY iTellRFile(ILvoid);
|
||||
ILuint ILAPIENTRY iTellRLump(ILvoid);
|
||||
ILuint ILAPIENTRY iTellWFile(ILvoid);
|
||||
ILuint ILAPIENTRY iTellWLump(ILvoid);
|
||||
ILint ILAPIENTRY iPutcFile(ILubyte Char);
|
||||
ILint ILAPIENTRY iPutcLump(ILubyte Char);
|
||||
ILint ILAPIENTRY iWriteFile(const ILvoid *Buffer, ILuint Size, ILuint Number);
|
||||
ILint ILAPIENTRY iWriteLump(const ILvoid *Buffer, ILuint Size, ILuint Number);
|
||||
ILHANDLE FileRead = NULL, FileWrite = NULL;
|
||||
const ILvoid *ReadLump = NULL;
|
||||
ILvoid *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)(ILstring);
|
||||
ILvoid (ILAPIENTRY *icloseCopy)(ILHANDLE);
|
||||
|
||||
ILboolean UseCache = IL_FALSE;
|
||||
ILubyte *Cache = NULL;
|
||||
ILuint CacheSize, CachePos, CacheStartPos, CacheBytesRead;
|
||||
|
||||
|
||||
/*// Just preserves the current read functions and replaces
|
||||
// the current read functions with the default read funcs.
|
||||
ILvoid 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().
|
||||
ILvoid ILAPIENTRY iRestoreReadFuncs()
|
||||
{
|
||||
GetcProc = GetcProcCopy;
|
||||
ReadProc = ReadProcCopy;
|
||||
SeekRProc = SeekProcCopy;
|
||||
TellRProc = TellProcCopy;
|
||||
iopenr = iopenCopy;
|
||||
icloser = icloseCopy;
|
||||
|
||||
return;
|
||||
}*/
|
||||
|
||||
|
||||
// Next 7 functions are the default read functions
|
||||
|
||||
ILHANDLE ILAPIENTRY iDefaultOpenR(ILconst_string FileName)
|
||||
{
|
||||
#ifndef _UNICODE
|
||||
return (ILHANDLE)fopen(FileName, "rb");
|
||||
#else
|
||||
return (ILHANDLE)_wfopen(FileName, L"rb");
|
||||
#endif//UNICODE
|
||||
}
|
||||
|
||||
|
||||
ILvoid 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(ILvoid *Buffer, ILuint Size, ILuint Number, ILHANDLE Handle)
|
||||
{
|
||||
return 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(FileName, "wb");
|
||||
#else
|
||||
return (ILHANDLE)_wfopen(FileName, L"wb");
|
||||
#endif//_UNICODE
|
||||
}
|
||||
|
||||
|
||||
ILvoid ILAPIENTRY iDefaultCloseW(ILHANDLE Handle)
|
||||
{
|
||||
fclose((FILE*)Handle);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ILint ILAPIENTRY iDefaultPutc(ILubyte Char, ILHANDLE Handle)
|
||||
{
|
||||
return fputc(Char, (FILE*)Handle);
|
||||
}
|
||||
|
||||
|
||||
ILint ILAPIENTRY iDefaultWrite(const ILvoid *Buffer, ILuint Size, ILuint Number, ILHANDLE Handle)
|
||||
{
|
||||
return fwrite(Buffer, Size, Number, (FILE*)Handle);
|
||||
}
|
||||
|
||||
|
||||
ILvoid ILAPIENTRY ilResetRead()
|
||||
{
|
||||
ilSetRead(iDefaultOpenR, iDefaultCloseR, iDefaultEof, iDefaultGetc,
|
||||
iDefaultRead, iDefaultRSeek, iDefaultRTell);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ILvoid ILAPIENTRY ilResetWrite()
|
||||
{
|
||||
ilSetWrite(iDefaultOpenW, iDefaultCloseW, iDefaultPutc,
|
||||
iDefaultWSeek, iDefaultWTell, iDefaultWrite);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//! Allows you to override the default file-reading functions.
|
||||
ILvoid 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.
|
||||
ILvoid 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
|
||||
ILvoid 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
|
||||
ILvoid iSetInputLump(const ILvoid *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
|
||||
ILvoid iSetOutputFile(ILHANDLE File)
|
||||
{
|
||||
// Helps with ilGetLumpPos().
|
||||
WriteLump = NULL;
|
||||
WriteLumpPos = 0;
|
||||
WriteLumpSize = 0;
|
||||
|
||||
iputc = iPutcFile;
|
||||
iseekw = iSeekWFile;
|
||||
itellw = iTellWFile;
|
||||
iwrite = iWriteFile;
|
||||
FileWrite = File;
|
||||
}
|
||||
|
||||
|
||||
// Tells DevIL that we're writing to a lump, not a file
|
||||
ILvoid iSetOutputLump(ILvoid *Lump, ILuint Size)
|
||||
{
|
||||
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 = strlen(Buffer);
|
||||
iwrite(Buffer, 1, i);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
// To pad zeros where needed...
|
||||
ILvoid 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(ILvoid)
|
||||
{
|
||||
return EofProc((FILE*)FileRead);
|
||||
}
|
||||
|
||||
|
||||
ILboolean ILAPIENTRY iEofLump(ILvoid)
|
||||
{
|
||||
if (ReadLumpSize)
|
||||
return (ReadLumpPos >= ReadLumpSize);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
ILint ILAPIENTRY iGetcFile(ILvoid)
|
||||
{
|
||||
if (!UseCache) {
|
||||
return GetcProc(FileRead);
|
||||
}
|
||||
if (CachePos >= CacheSize) {
|
||||
iPreCache(CacheSize);
|
||||
}
|
||||
|
||||
CacheBytesRead++;
|
||||
return Cache[CachePos++];
|
||||
}
|
||||
|
||||
|
||||
ILint ILAPIENTRY iGetcLump(ILvoid)
|
||||
{
|
||||
// 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(ILvoid *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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CacheBytesRead += TotalBytes;
|
||||
if (Size != 0)
|
||||
TotalBytes /= Size;
|
||||
if (TotalBytes != Number)
|
||||
ilSetError(IL_FILE_READ_ERROR);
|
||||
return TotalBytes;
|
||||
}
|
||||
|
||||
|
||||
ILuint ILAPIENTRY iReadLump(ILvoid *Buffer, const ILuint Size, const ILuint Number)
|
||||
{
|
||||
ILuint i, ByteSize = Size * Number;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
ILvoid 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;
|
||||
}
|
||||
|
||||
|
||||
ILuint 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
|
||||
ILuint 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(ILvoid)
|
||||
{
|
||||
return TellRProc(FileRead);
|
||||
}
|
||||
|
||||
|
||||
ILuint ILAPIENTRY iTellRLump(ILvoid)
|
||||
{
|
||||
return ReadLumpPos;
|
||||
}
|
||||
|
||||
|
||||
ILHANDLE ILAPIENTRY iGetFile(ILvoid)
|
||||
{
|
||||
return FileRead;
|
||||
}
|
||||
|
||||
|
||||
const ILubyte* ILAPIENTRY iGetLump(ILvoid) {
|
||||
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 ILvoid *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 ILvoid *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;
|
||||
}
|
||||
|
||||
|
||||
ILuint 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
|
||||
ILuint 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(ILvoid)
|
||||
{
|
||||
return TellWProc(FileWrite);
|
||||
}
|
||||
|
||||
|
||||
ILuint ILAPIENTRY iTellWLump(ILvoid)
|
||||
{
|
||||
return WriteLumpPos;
|
||||
}
|
||||
766
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_gif.c
Normal file
766
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_gif.c
Normal file
@@ -0,0 +1,766 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2002 by Denton Woods
|
||||
// Last modified: 06/13/2002 <--Y2K Compliant! =]
|
||||
//
|
||||
// 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 ILvoid *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 ILvoid *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)) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!GetImages(&GlobalPal, &Header))
|
||||
return IL_FALSE;
|
||||
|
||||
if (GlobalPal.Palette && GlobalPal.PalSize)
|
||||
ifree(GlobalPal.Palette);
|
||||
GlobalPal.Palette = NULL;
|
||||
GlobalPal.PalSize = 0;
|
||||
|
||||
ilFixImage();
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
ILboolean iGetPalette(ILubyte Info, ILpal *Pal)
|
||||
{
|
||||
|
||||
// The ld(palettes bpp - 1) is stored in the lower
|
||||
|
||||
// 3 bits of Info (weird gif format ... :) )
|
||||
Pal->PalSize = (1 << ((Info & 0x7) + 1)) * 3;
|
||||
Pal->PalType = IL_PAL_RGB24;
|
||||
Pal->Palette = (ILubyte*)ialloc(Pal->PalSize);
|
||||
if (Pal->Palette == NULL)
|
||||
return IL_FALSE;
|
||||
if (iread(Pal->Palette, 1, Pal->PalSize) != Pal->PalSize) {
|
||||
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;
|
||||
ILuint NumImages = 0, i;
|
||||
|
||||
ILint input;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
//memset(Image->Data, GifHead->Background, Image->SizeOfData);
|
||||
}
|
||||
|
||||
Image->OffX = ImageDesc.OffX;
|
||||
Image->OffY = ImageDesc.OffY;
|
||||
|
||||
// Check to see if the image has its own palette.
|
||||
if (ImageDesc.ImageInfo & (1 << 7)) {
|
||||
if (!iGetPalette(ImageDesc.ImageInfo, &Image->Pal)) {
|
||||
goto error_clean;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!iCopyPalette(&Image->Pal, GlobalPal)) {
|
||||
goto error_clean;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!GifGetData(Image->Data + ImageDesc.OffX + ImageDesc.OffY*Image->Width, Image->SizeOfData,
|
||||
ImageDesc.Width, ImageDesc.Height, Image->Width, &Gfx)) {
|
||||
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(ILubyte *Data, ILuint ImageSize, ILuint Width, ILuint Height, ILuint Stride, GFXCONTROL *Gfx) {
|
||||
ILubyte *sp;
|
||||
ILint code, fc, oc;
|
||||
ILubyte DisposalMethod = 0;
|
||||
ILint c, size;
|
||||
ILuint i = 0, Read = 0, j = 0;
|
||||
|
||||
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) {
|
||||
Data[i++] = c;
|
||||
}
|
||||
}
|
||||
if (i == Width) {
|
||||
Data += Stride;
|
||||
i = 0;
|
||||
Read += 1;
|
||||
|
||||
++j;
|
||||
|
||||
if (j >= Height) {
|
||||
cleanUpGifLoadState();
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
code = c;
|
||||
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) {
|
||||
Data[i++] = *sp;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == Width) {
|
||||
Data += Stride;
|
||||
i = 0;
|
||||
Read += 1;
|
||||
++j;
|
||||
if (j >= Height) {
|
||||
cleanUpGifLoadState();
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
// Assumes that Dest has nothing in it.
|
||||
ILboolean iCopyPalette(ILpal *Dest, ILpal *Src)
|
||||
{
|
||||
if (Src->Palette == NULL || Src->PalSize == 0)
|
||||
return IL_FALSE;
|
||||
|
||||
Dest->Palette = (ILubyte*)ialloc(Src->PalSize);
|
||||
if (Dest->Palette == NULL)
|
||||
return IL_FALSE;
|
||||
|
||||
memcpy(Dest->Palette, Src->Palette, Src->PalSize);
|
||||
|
||||
Dest->PalSize = Src->PalSize;
|
||||
Dest->PalType = Src->PalType;
|
||||
|
||||
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
|
||||
|
||||
349
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_hdr.c
Normal file
349
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_hdr.c
Normal file
@@ -0,0 +1,349 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2004 by Denton Woods (this file by thakis)
|
||||
// Last modified: 09/06/2004
|
||||
//
|
||||
// Filename: src-IL/src/il_bmp.c
|
||||
//
|
||||
// Description: Reads 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 ILvoid *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[80];
|
||||
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') {
|
||||
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)
|
||||
//Furthermore, this crashes if the read strings are longer than 2 chars o_O
|
||||
sscanf(buff, "%s %d %s %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 ILvoid *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(BMPHEAD), 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();
|
||||
}
|
||||
|
||||
ILvoid 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif//IL_NO_HDR
|
||||
135
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_header.c
Normal file
135
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_header.c
Normal file
@@ -0,0 +1,135 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2002 by Denton Woods
|
||||
// Last modified: 02/19/2002 <--Y2K Compliant! =]
|
||||
//
|
||||
// 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, const 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 ||
|
||||
#ifndef _UNICODE
|
||||
strlen(FileName) < 1 || strlen(Name) < 1) {
|
||||
#else
|
||||
wcslen(FileName) < 1 || wcslen(FileName) < 1) {
|
||||
#endif//_UNICODE
|
||||
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 _WIN32_WCE
|
||||
HeadFile = fopen(FileName, "wb");
|
||||
#else
|
||||
HeadFile = _wfopen(FileName, L"wb");
|
||||
#endif//_WIN32_WCE
|
||||
|
||||
|
||||
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
|
||||
394
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_icon.c
Normal file
394
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_icon.c
Normal file
@@ -0,0 +1,394 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2001-2002 by Denton Woods
|
||||
// Last modified: 06/13/2001 <--Y2K Compliant! =]
|
||||
//
|
||||
// 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"
|
||||
|
||||
|
||||
//! 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 ILvoid *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;
|
||||
|
||||
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 = igetc();
|
||||
|
||||
DirEntries[i].Height = igetc();
|
||||
|
||||
DirEntries[i].NumColours = igetc();
|
||||
|
||||
DirEntries[i].Reserved = 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);
|
||||
|
||||
|
||||
|
||||
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) {
|
||||
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 {
|
||||
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];
|
||||
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 winxp 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);
|
||||
|
||||
ilFixImage();
|
||||
|
||||
return IL_TRUE;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
348
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_internal.c
Normal file
348
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_internal.c
Normal file
@@ -0,0 +1,348 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2002 by Denton Woods
|
||||
// Last modified: 05/25/2001 <--Y2K Compliant! =]
|
||||
//
|
||||
// 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 */
|
||||
|
||||
#if _UNICODE //_WIN32_WCE
|
||||
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...
|
||||
char *ilStrDup(const char *Str)
|
||||
{
|
||||
char *copy;
|
||||
|
||||
copy = (char*)ialloc(strlen(Str) + 1);
|
||||
if (copy == NULL)
|
||||
return NULL;
|
||||
strcpy(copy, Str);
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
||||
// Because MSVC++'s version is too stupid to check for NULL...
|
||||
ILuint ilStrLen(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;
|
||||
#ifndef _UNICODE
|
||||
char *Argu = (char*)Arg; // pointer to arg so we don't destroy arg
|
||||
|
||||
if (Arg == NULL || Ext == NULL || !strlen(Arg) || !strlen(Ext)) // if not a good filename/extension, exit early
|
||||
return IL_FALSE;
|
||||
|
||||
Argu += strlen(Arg); // start at the end
|
||||
|
||||
|
||||
for (i = strlen(Arg); 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 (!stricmp(Argu+1, Ext)) // extension and ext match?
|
||||
return IL_TRUE;
|
||||
|
||||
#else
|
||||
wchar_t *Argu = (wchar_t*)Arg;
|
||||
|
||||
if (Arg == NULL || Ext == NULL || !wcslen(Arg) || !wcslen(Ext)) // if not a good filename/extension, exit early
|
||||
return IL_FALSE;
|
||||
|
||||
Argu += wcslen(Arg); // start at the end
|
||||
|
||||
|
||||
for (i = wcslen(Arg); 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 (!wcsicmp(Argu+1, Ext)) // extension and ext match?
|
||||
return IL_TRUE;
|
||||
|
||||
#endif//_WIN32_WCE
|
||||
|
||||
return IL_FALSE; // if all else fails, return IL_FALSE
|
||||
}
|
||||
|
||||
|
||||
ILstring iGetExtension(ILconst_string FileName) {
|
||||
ILboolean PeriodFound = IL_FALSE;
|
||||
#ifndef _UNICODE
|
||||
char *Ext = (char*)FileName;
|
||||
ILint i, Len = strlen(FileName);
|
||||
#else
|
||||
wchar_t *Ext = (wchar_t*)FileName;
|
||||
ILint i, Len = wcslen(FileName);
|
||||
#endif//_UNICODE
|
||||
|
||||
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)
|
||||
{
|
||||
#ifndef _UNICODE
|
||||
FILE *CheckFile = fopen(FileName, "rb");
|
||||
#else
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
1569
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_io.c
Normal file
1569
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_io.c
Normal file
File diff suppressed because it is too large
Load Diff
1920
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_jpeg.c
Normal file
1920
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_jpeg.c
Normal file
File diff suppressed because it is too large
Load Diff
200
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_lif.c
Normal file
200
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_lif.c
Normal file
@@ -0,0 +1,200 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2002 by Denton Woods
|
||||
// Last modified: 05/25/2001 <--Y2K Compliant! =]
|
||||
//
|
||||
// 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 ILvoid *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 ILvoid *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]++;
|
||||
}
|
||||
|
||||
ilFixImage();
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
#endif//IL_NO_LIF
|
||||
30
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_main.c
Normal file
30
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_main.c
Normal 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
|
||||
|
||||
|
||||
882
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_manip.c
Normal file
882
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_manip.c
Normal file
@@ -0,0 +1,882 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Description: Image manipulation
|
||||
#include "il_internal.h"
|
||||
#include <il/il.h>
|
||||
#include "il_manip.h"
|
||||
|
||||
ILAPI ILvoid 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, ILvoid *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, ILvoid *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, ILvoid *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, ILvoid *Data)
|
||||
{
|
||||
ILvoid *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) {
|
||||
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 IL_TRUE;
|
||||
}
|
||||
|
||||
Converted = ilConvertBuffer(SrcSize, iCurImage->Format, Format, iCurImage->Type, Type, 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, ILvoid *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, ILvoid *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, ILvoid *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;
|
||||
}
|
||||
|
||||
|
||||
ILvoid ILAPIENTRY ilSetPixels(ILint XOff, ILint YOff, ILint ZOff, ILuint Width, ILuint Height, ILuint Depth, ILenum Format, ILenum Type, ILvoid *Data)
|
||||
{
|
||||
ILvoid *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 = (ILvoid*)Data;
|
||||
}
|
||||
else {
|
||||
Converted = ilConvertBuffer(Width * Height * Depth * ilGetBppFormat(Format) * ilGetBpcType(Type), Format, iCurImage->Format, iCurImage->Type, Type, 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 (DooMWiz'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 (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 = 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_COLOUR_INDEX: //@TODO use palette with alpha
|
||||
ret = ilConvertImage(IL_RGBA,image->Type);
|
||||
AlphaOff = 4;
|
||||
break;
|
||||
}
|
||||
if( ret == IL_FALSE ) {
|
||||
return IL_FALSE;
|
||||
// error has been set by ilConvertImage
|
||||
}
|
||||
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)
|
||||
((ILushort*)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;
|
||||
}
|
||||
|
||||
ILvoid 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;
|
||||
}
|
||||
}
|
||||
157
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_mdl.c
Normal file
157
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_mdl.c
Normal file
@@ -0,0 +1,157 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2002 by Denton Woods
|
||||
// Last modified: 05/25/2001 <--Y2K Compliant! =]
|
||||
//
|
||||
// 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(ILvoid);
|
||||
|
||||
|
||||
//! 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 ILvoid *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;
|
||||
|
||||
ilFixImage();
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
#endif//IL_NO_MDL
|
||||
349
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_mng.c
Normal file
349
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_mng.c
Normal file
@@ -0,0 +1,349 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2002 by Denton Woods
|
||||
// Last modified: 05/25/2001 <--Y2K Compliant! =]
|
||||
//
|
||||
// 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
|
||||
|
||||
#ifdef _WIN32
|
||||
#if (defined(IL_USE_PRAGMA_LIBS))
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
#pragma comment(lib, "DevIL_libmng.lib")
|
||||
#pragma comment(lib, "DevIL_lcms.lib")
|
||||
#pragma comment(lib, "DevIL_libjpeg.lib")
|
||||
#pragma comment(lib, "DevIL_zlib.lib")
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <libmng.h>
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
// 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, 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, 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(ILvoid);
|
||||
|
||||
// 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 ILvoid *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);
|
||||
|
||||
ilFixImage();
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
ILboolean iSaveMngInternal(ILvoid);
|
||||
|
||||
//! Writes a Mng file
|
||||
ILboolean ilSaveMng(ILconst_string FileName)
|
||||
{
|
||||
ILHANDLE MngFile;
|
||||
ILboolean bMng = IL_FALSE;
|
||||
|
||||
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 bMng;
|
||||
}
|
||||
|
||||
bMng = ilSaveMngF(MngFile);
|
||||
iclosew(MngFile);
|
||||
|
||||
return bMng;
|
||||
}
|
||||
|
||||
|
||||
//! Writes a Mng to an already-opened file
|
||||
ILboolean ilSaveMngF(ILHANDLE File)
|
||||
{
|
||||
iSetOutputFile(File);
|
||||
return iSaveMngInternal();
|
||||
}
|
||||
|
||||
|
||||
//! Writes a Mng to a memory "lump"
|
||||
ILboolean ilSaveMngL(ILvoid *Lump, ILuint Size)
|
||||
{
|
||||
iSetOutputLump(Lump, Size);
|
||||
return iSaveMngInternal();
|
||||
}
|
||||
|
||||
|
||||
// Internal function used to save the Mng.
|
||||
ILboolean iSaveMngInternal()
|
||||
{
|
||||
/*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;
|
||||
}
|
||||
|
||||
|
||||
mng_setcb_openstream(mng, mymngopenstreamwrite);
|
||||
mng_setcb_closestream(mng, mymngclosestream);
|
||||
mng_setcb_writedata(mng, mymngwritedata);
|
||||
|
||||
// Write File:
|
||||
mng_create(mng);
|
||||
|
||||
// Just a single Frame (save a normal PNG):
|
||||
//WritePNG( mng, 0, 1 );
|
||||
|
||||
// Now write file:
|
||||
mng_write(mng);
|
||||
|
||||
mng_cleanup(&mng);*/
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
#endif//IL_NO_MNG
|
||||
462
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_neuquant.c
Normal file
462
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_neuquant.c
Normal 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: 02/02/2002 <--Y2K Compliant! =]
|
||||
//
|
||||
// Filename: src-IL/src/il_neuquant.c
|
||||
//
|
||||
// Description: Heavily modified by Denton Woods.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "il_internal.h"
|
||||
|
||||
|
||||
// Function definitions
|
||||
ILvoid initnet(ILubyte *thepic, ILint len, ILint sample);
|
||||
ILvoid unbiasnet();
|
||||
ILvoid inxbuild();
|
||||
ILubyte inxsearch(ILint b, ILint g, ILint r);
|
||||
ILvoid 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
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
ILvoid 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
|
||||
// -----------------------------------------------------------------------------------
|
||||
|
||||
ILvoid 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)
|
||||
// -------------------------------------------------------------------------------
|
||||
|
||||
ILvoid 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
|
||||
// ----------------------------------------------------
|
||||
|
||||
ILvoid 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|]
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
||||
ILvoid 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
|
||||
// ------------------
|
||||
|
||||
ILvoid 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)
|
||||
{
|
||||
ILimage *TempImage, *NewImage;
|
||||
ILuint sample, i, j;
|
||||
|
||||
netsizethink=iGetInt(IL_MAX_QUANT_INDEXS);
|
||||
|
||||
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;
|
||||
}
|
||||
1096
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_pal.c
Normal file
1096
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_pal.c
Normal file
File diff suppressed because it is too large
Load Diff
206
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_pcd.c
Normal file
206
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_pcd.c
Normal file
@@ -0,0 +1,206 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2002 by Denton Woods
|
||||
// Last modified: 05/19/2002 <--Y2K Compliant! =]
|
||||
//
|
||||
// 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(ILvoid);
|
||||
|
||||
//! 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 ILvoid *Lump, ILuint Size)
|
||||
{
|
||||
iSetInputLump(Lump, Size);
|
||||
return iLoadPcdInternal();
|
||||
}
|
||||
|
||||
|
||||
ILvoid 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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
ilFixImage();
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
#endif//IL_NO_PCD
|
||||
733
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_pcx.c
Normal file
733
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_pcx.c
Normal file
@@ -0,0 +1,733 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2002 by Denton Woods
|
||||
// Last modified: 09/01/2003 <--Y2K Compliant! =]
|
||||
//
|
||||
// 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 ILvoid *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 ILvoid *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);
|
||||
|
||||
ilFixImage();
|
||||
|
||||
return bPcx;
|
||||
}
|
||||
|
||||
|
||||
// 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(ILconst_string FileName) {
|
||||
ILHANDLE PcxFile;
|
||||
ILboolean bPcx = IL_FALSE;
|
||||
|
||||
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 bPcx;
|
||||
}
|
||||
|
||||
bPcx = ilSavePcxF(PcxFile);
|
||||
iclosew(PcxFile);
|
||||
|
||||
return bPcx;
|
||||
}
|
||||
|
||||
|
||||
//! Writes a .pcx to an already-opened file
|
||||
ILboolean ilSavePcxF(ILHANDLE File) {
|
||||
iSetOutputFile(File);
|
||||
return iSavePcxInternal();
|
||||
}
|
||||
|
||||
|
||||
//! Writes a .pcx to a memory "lump"
|
||||
ILboolean ilSavePcxL(ILvoid *Lump, ILuint Size) {
|
||||
iSetOutputLump(Lump, Size);
|
||||
return iSavePcxInternal();
|
||||
}
|
||||
|
||||
|
||||
// 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
|
||||
432
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_pic.c
Normal file
432
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_pic.c
Normal file
@@ -0,0 +1,432 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2002 by Denton Woods
|
||||
// Last modified: 05/21/2002 <--Y2K Compliant! =]
|
||||
//
|
||||
// Filename: src-IL/src/il_pic.c
|
||||
//
|
||||
// Description: Softimage Pic (.pic) functions
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// @TODO: Test these extensively...haven't even been tested yet!!!
|
||||
|
||||
#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 ILvoid *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 = GetLittleInt();
|
||||
|
||||
Header->Version = GetLittleFloat();
|
||||
|
||||
iread(Header->Comment, 1, 80);
|
||||
|
||||
iread(Header->Id, 1, 4);
|
||||
|
||||
Header->Width = GetLittleShort();
|
||||
|
||||
Header->Height = GetLittleShort();
|
||||
|
||||
Header->Ratio = GetLittleFloat();
|
||||
|
||||
Header->Fields = GetLittleShort();
|
||||
|
||||
Header->Padding = GetLittleShort();
|
||||
|
||||
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 ILvoid *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;
|
||||
}
|
||||
|
||||
if (!ilTexImage(Header.Width, Header.Height, 1, 1, 0, IL_UNSIGNED_BYTE, NULL)) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
|
||||
|
||||
// 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);
|
||||
|
||||
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;
|
||||
|
||||
ilFixImage();
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
ILboolean readScanlines(ILuint *image, ILint width, ILint height, CHANNEL *channel, ILuint alpha)
|
||||
{
|
||||
ILint i;
|
||||
ILuint *scan;
|
||||
|
||||
(ILvoid)alpha;
|
||||
|
||||
for (i = height - 1; i >= 0; i--) {
|
||||
scan = image + i * width;
|
||||
|
||||
if (!readScanline((ILubyte *)scan, width, channel, 4)) {
|
||||
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;
|
||||
//#ifndef sgi
|
||||
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++;
|
||||
}
|
||||
/*#else
|
||||
if(channel->channels & PIC_RED_CHANNEL) {
|
||||
off[noCol] = 3;
|
||||
noCol++;
|
||||
}
|
||||
if(channel->channels & PIC_GREEN_CHANNEL) {
|
||||
off[noCol] = 2;
|
||||
noCol++;
|
||||
}
|
||||
if(channel->channels & PIC_BLUE_CHANNEL) {
|
||||
off[noCol] = 1;
|
||||
noCol++;
|
||||
}
|
||||
if(channel->channels & PIC_ALPHA_CHANNEL) {
|
||||
off[noCol] = 0;
|
||||
noCol++;
|
||||
}
|
||||
#endif*/
|
||||
|
||||
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 = GetLittleUShort();
|
||||
if (ieof())
|
||||
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);
|
||||
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]] = 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);
|
||||
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)
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif//IL_NO_PIC
|
||||
164
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_pix.c
Normal file
164
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_pix.c
Normal file
@@ -0,0 +1,164 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2002 by Denton Woods
|
||||
// Last modified: 05/26/2002 <--Y2K Compliant! =]
|
||||
//
|
||||
// Filename: src-IL/src/il_pix.c
|
||||
//
|
||||
// Description: Reads from an Alias | Wavefront .pix file.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "il_internal.h"
|
||||
#ifndef IL_NO_PIX
|
||||
#include "il_manip.h"
|
||||
#include "il_endian.h"
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(push, pix_struct, 1)
|
||||
#endif
|
||||
typedef struct PIXHEAD
|
||||
{
|
||||
ILushort Width;
|
||||
ILushort Height;
|
||||
ILushort OffX;
|
||||
ILushort OffY;
|
||||
ILushort Bpp;
|
||||
} IL_PACKSTRUCT PIXHEAD;
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(pop, pix_struct)
|
||||
#endif
|
||||
|
||||
ILboolean iCheckPix(PIXHEAD *Header);
|
||||
ILboolean iLoadPixInternal(ILvoid);
|
||||
|
||||
|
||||
// Internal function used to get the Pix header from the current file.
|
||||
ILboolean iGetPixHead(PIXHEAD *Header) {
|
||||
Header->Width = GetBigUShort();
|
||||
|
||||
Header->Height = GetBigUShort();
|
||||
|
||||
Header->OffX = GetBigUShort();
|
||||
|
||||
Header->OffY = GetBigUShort();
|
||||
|
||||
Header->Bpp = GetBigUShort();
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Internal function to get the header and check it.
|
||||
ILboolean iIsValidPix()
|
||||
{
|
||||
PIXHEAD Head;
|
||||
|
||||
if (!iGetPixHead(&Head))
|
||||
return IL_FALSE;
|
||||
iseek(-(ILint)sizeof(PIXHEAD), IL_SEEK_CUR);
|
||||
|
||||
return iCheckPix(&Head);
|
||||
}
|
||||
|
||||
|
||||
// Internal function used to check if the HEADER is a valid Pix header.
|
||||
ILboolean iCheckPix(PIXHEAD *Header)
|
||||
{
|
||||
if (Header->Width == 0 || Header->Height == 0)
|
||||
return IL_FALSE;
|
||||
if (Header->Bpp != 24)
|
||||
return IL_FALSE;
|
||||
//if (Header->OffY != Header->Height)
|
||||
// return IL_FALSE;
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
//! Reads a Pix file
|
||||
ILboolean ilLoadPix(ILconst_string FileName)
|
||||
{
|
||||
ILHANDLE PixFile;
|
||||
ILboolean bPix = IL_FALSE;
|
||||
|
||||
PixFile = iopenr(FileName);
|
||||
if (PixFile == NULL) {
|
||||
ilSetError(IL_COULD_NOT_OPEN_FILE);
|
||||
return bPix;
|
||||
}
|
||||
|
||||
bPix = ilLoadPixF(PixFile);
|
||||
icloser(PixFile);
|
||||
|
||||
return bPix;
|
||||
}
|
||||
|
||||
|
||||
//! Reads an already-opened Pix file
|
||||
ILboolean ilLoadPixF(ILHANDLE File)
|
||||
{
|
||||
ILuint FirstPos;
|
||||
ILboolean bRet;
|
||||
|
||||
iSetInputFile(File);
|
||||
FirstPos = itell();
|
||||
bRet = iLoadPixInternal();
|
||||
iseek(FirstPos, IL_SEEK_SET);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
//! Reads from a memory "lump" that contains a Pix
|
||||
ILboolean ilLoadPixL(const ILvoid *Lump, ILuint Size)
|
||||
{
|
||||
iSetInputLump(Lump, Size);
|
||||
return iLoadPixInternal();
|
||||
}
|
||||
|
||||
|
||||
// Internal function used to load the Pix.
|
||||
ILboolean iLoadPixInternal()
|
||||
{
|
||||
PIXHEAD Header;
|
||||
ILuint i, j;
|
||||
ILubyte ByteHead, Colour[3];
|
||||
|
||||
if (iCurImage == NULL) {
|
||||
ilSetError(IL_ILLEGAL_OPERATION);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
if (!iGetPixHead(&Header))
|
||||
return IL_FALSE;
|
||||
if (!iCheckPix(&Header)) {
|
||||
ilSetError(IL_INVALID_FILE_HEADER);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
if (!ilTexImage(Header.Width, Header.Height, 1, 3, IL_BGR, IL_UNSIGNED_BYTE, NULL))
|
||||
return IL_FALSE;
|
||||
|
||||
for (i = 0; i < iCurImage->SizeOfData; ) {
|
||||
ByteHead = igetc();
|
||||
if (iread(Colour, 1, 3) != 3)
|
||||
return IL_FALSE;
|
||||
for (j = 0; j < ByteHead; j++) {
|
||||
iCurImage->Data[i++] = Colour[0];
|
||||
iCurImage->Data[i++] = Colour[1];
|
||||
iCurImage->Data[i++] = Colour[2];
|
||||
}
|
||||
}
|
||||
|
||||
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
|
||||
|
||||
ilFixImage();
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
#endif//IL_NO_PIX
|
||||
713
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_png.c
Normal file
713
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_png.c
Normal file
@@ -0,0 +1,713 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2002 by Denton Woods
|
||||
// Last modified: 02/01/2002 <--Y2K Compliant! =]
|
||||
//
|
||||
// Filename: src-IL/src/il_png.c
|
||||
//
|
||||
// Description: Portable network graphics file (.png) functions
|
||||
//
|
||||
// 20040223 XIX : now may spit out pngs with a transparent index, this is mostly a hack
|
||||
// but the proper way of doing it would be to change the pal stuff to think in argb rather than rgb
|
||||
// which is something of a bigger job.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Most of the comments are left in this file from libpng's excellent example.c
|
||||
|
||||
#include "il_internal.h"
|
||||
#ifndef IL_NO_PNG
|
||||
#include <png.h>
|
||||
#include "il_manip.h"
|
||||
#include <stdlib.h>
|
||||
#if PNG_LIBPNG_VER < 10200
|
||||
#warning DevIL was designed with libpng 1.2.0 or higher in mind. Consider upgrading at www.libpng.org
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
#if (defined(IL_USE_PRAGMA_LIBS))
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
#pragma comment(lib, "DevIL_libpng.lib")
|
||||
#pragma comment(lib, "DevIL_zlib.lib")
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
ILboolean iIsValidPng(ILvoid);
|
||||
ILboolean iLoadPngInternal(ILvoid);
|
||||
ILboolean iSavePngInternal(ILvoid);
|
||||
|
||||
ILint readpng_init(ILvoid);
|
||||
ILboolean readpng_get_image(ILdouble display_exponent);
|
||||
ILvoid readpng_cleanup(ILvoid);
|
||||
|
||||
png_structp png_ptr = NULL;
|
||||
png_infop info_ptr = NULL;
|
||||
ILint color_type;
|
||||
|
||||
#define GAMMA_CORRECTION 1.0 // Doesn't seem to be doing anything...
|
||||
|
||||
|
||||
ILboolean ilIsValidPng(ILconst_string FileName)
|
||||
{
|
||||
ILHANDLE PngFile;
|
||||
ILboolean bPng = IL_FALSE;
|
||||
|
||||
if (!iCheckExtension(FileName, IL_TEXT( "png" ))) {
|
||||
ilSetError(IL_INVALID_EXTENSION);
|
||||
return bPng;
|
||||
}
|
||||
|
||||
PngFile = iopenr(FileName);
|
||||
if (PngFile == NULL) {
|
||||
ilSetError(IL_COULD_NOT_OPEN_FILE);
|
||||
return bPng;
|
||||
}
|
||||
|
||||
bPng = ilIsValidPngF(PngFile);
|
||||
icloser(PngFile);
|
||||
|
||||
return bPng;
|
||||
}
|
||||
|
||||
|
||||
ILboolean ilIsValidPngF(ILHANDLE File)
|
||||
{
|
||||
ILuint FirstPos;
|
||||
ILboolean bRet;
|
||||
|
||||
iSetInputFile(File);
|
||||
FirstPos = itell();
|
||||
bRet = iIsValidPng();
|
||||
iseek(FirstPos, IL_SEEK_SET);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
ILboolean ilIsValidPngL(const ILvoid *Lump, ILuint Size)
|
||||
{
|
||||
iSetInputLump(Lump, Size);
|
||||
return iIsValidPng();
|
||||
}
|
||||
|
||||
|
||||
ILboolean iIsValidPng()
|
||||
{
|
||||
ILubyte Signature[8];
|
||||
ILint Read;
|
||||
|
||||
Read = iread(Signature, 1, 8);
|
||||
iseek(-Read, IL_SEEK_CUR);
|
||||
|
||||
return png_check_sig(Signature, 8);
|
||||
}
|
||||
|
||||
|
||||
// Reads a file
|
||||
ILboolean ilLoadPng(ILconst_string FileName)
|
||||
{
|
||||
ILHANDLE PngFile;
|
||||
ILboolean bPng = IL_FALSE;
|
||||
|
||||
PngFile = iopenr(FileName);
|
||||
if (PngFile == NULL) {
|
||||
ilSetError(IL_COULD_NOT_OPEN_FILE);
|
||||
return bPng;
|
||||
}
|
||||
|
||||
bPng = ilLoadPngF(PngFile);
|
||||
icloser(PngFile);
|
||||
|
||||
return bPng;
|
||||
}
|
||||
|
||||
|
||||
// Reads an already-opened file
|
||||
ILboolean ilLoadPngF(ILHANDLE File)
|
||||
{
|
||||
ILuint FirstPos;
|
||||
ILboolean bRet;
|
||||
|
||||
iSetInputFile(File);
|
||||
FirstPos = itell();
|
||||
bRet = iLoadPngInternal();
|
||||
iseek(FirstPos, IL_SEEK_SET);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
// Reads from a memory "lump"
|
||||
ILboolean ilLoadPngL(const ILvoid *Lump, ILuint Size)
|
||||
{
|
||||
iSetInputLump(Lump, Size);
|
||||
return iLoadPngInternal();
|
||||
}
|
||||
|
||||
|
||||
ILboolean iLoadPngInternal()
|
||||
{
|
||||
png_ptr = NULL;
|
||||
info_ptr = NULL;
|
||||
|
||||
if (iCurImage == NULL) {
|
||||
ilSetError(IL_ILLEGAL_OPERATION);
|
||||
return IL_FALSE;
|
||||
}
|
||||
if (!iIsValidPng()) {
|
||||
ilSetError(IL_INVALID_VALUE);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
if (readpng_init())
|
||||
return IL_FALSE;
|
||||
if (!readpng_get_image(GAMMA_CORRECTION))
|
||||
return IL_FALSE;
|
||||
|
||||
readpng_cleanup();
|
||||
|
||||
ilFixImage();
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
static ILvoid png_read(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
{
|
||||
(ILvoid)png_ptr;
|
||||
iread(data, 1, length);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void png_error_func(png_structp png_ptr, png_const_charp 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 png_warn_func(png_structp png_ptr, png_const_charp message)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ILint readpng_init()
|
||||
{
|
||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, png_error_func, png_warn_func);
|
||||
if (!png_ptr)
|
||||
return 4; /* out of memory */
|
||||
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr) {
|
||||
png_destroy_read_struct(&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(png_ptr))) {
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
png_set_read_fn(png_ptr, NULL, png_read);
|
||||
png_set_error_fn(png_ptr, NULL, png_error_func, png_warn_func);
|
||||
|
||||
// png_set_sig_bytes(png_ptr, 8); /* we already read the 8 signature bytes */
|
||||
|
||||
png_read_info(png_ptr, 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 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;
|
||||
}
|
||||
|
||||
|
||||
/* display_exponent == LUT_exponent * CRT_exponent */
|
||||
|
||||
ILboolean readpng_get_image(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
|
||||
|
||||
/* setjmp() must be called in every function that calls a PNG-reading
|
||||
* libpng function */
|
||||
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
png_get_IHDR(png_ptr, info_ptr, (png_uint_32*)&width, (png_uint_32*)&height,
|
||||
&bit_depth, &color_type, NULL, NULL, NULL);
|
||||
|
||||
// Expand low-bit-depth grayscale images to 8 bits
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
|
||||
png_set_gray_1_2_4_to_8(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(png_ptr, info_ptr, PNG_INFO_tRNS) && !(png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE)))
|
||||
png_set_tRNS_to_alpha(png_ptr);
|
||||
|
||||
//refresh information (added 20040224)
|
||||
png_get_IHDR(png_ptr, info_ptr, (png_uint_32*)&width, (png_uint_32*)&height,
|
||||
&bit_depth, &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(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(png_ptr, info_ptr, &image_gamma))
|
||||
png_set_gamma(png_ptr, screen_gamma, image_gamma);
|
||||
#else
|
||||
screen_gamma = screen_gamma;
|
||||
#endif
|
||||
|
||||
//fix endianess
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
if (bit_depth == 16)
|
||||
png_set_swap(png_ptr);
|
||||
#endif
|
||||
|
||||
|
||||
png_read_update_info(png_ptr, info_ptr);
|
||||
channels = (ILint)png_get_channels(png_ptr, info_ptr);
|
||||
//added 20040224: update color_type so that it has the correct value
|
||||
//in iLoadPngInternal (globals rule...)
|
||||
color_type = png_get_color_type(png_ptr, info_ptr);
|
||||
|
||||
//determine internal format
|
||||
switch(color_type)
|
||||
{
|
||||
case PNG_COLOR_TYPE_PALETTE:
|
||||
format = IL_COLOUR_INDEX;
|
||||
break;
|
||||
case PNG_COLOR_TYPE_GRAY:
|
||||
format = IL_LUMINANCE;
|
||||
break;
|
||||
case PNG_COLOR_TYPE_GRAY_ALPHA:
|
||||
format = IL_LUMINANCE_ALPHA;
|
||||
break;
|
||||
case PNG_COLOR_TYPE_RGB:
|
||||
format = IL_RGB;
|
||||
break;
|
||||
case PNG_COLOR_TYPE_RGB_ALPHA:
|
||||
format = IL_RGBA;
|
||||
break;
|
||||
default:
|
||||
ilSetError(IL_ILLEGAL_FILE_VALUE);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
if (!ilTexImage(width, height, 1, (ILubyte)channels, format, ilGetTypeBpc((ILubyte)(bit_depth >> 3)), NULL)) {
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
return IL_FALSE;
|
||||
}
|
||||
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
|
||||
|
||||
//copy palette
|
||||
if (format == IL_COLOUR_INDEX) {
|
||||
int chans;
|
||||
png_bytep trans = NULL;
|
||||
int num_trans = -1;
|
||||
if (!png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette)) {
|
||||
ilSetError(IL_ILLEGAL_FILE_VALUE);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
chans = 3;
|
||||
iCurImage->Pal.PalType = IL_PAL_RGB24;
|
||||
|
||||
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
|
||||
png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL);
|
||||
iCurImage->Pal.PalType = IL_PAL_RGBA32;
|
||||
chans = 4;
|
||||
}
|
||||
|
||||
iCurImage->Pal.PalSize = num_palette * chans;
|
||||
|
||||
iCurImage->Pal.Palette = (ILubyte*)ialloc(iCurImage->Pal.PalSize);
|
||||
|
||||
for (j = 0; j < num_palette; ++j) {
|
||||
iCurImage->Pal.Palette[chans*j + 0] = palette[j].red;
|
||||
iCurImage->Pal.Palette[chans*j + 1] = palette[j].green;
|
||||
iCurImage->Pal.Palette[chans*j + 2] = palette[j].blue;
|
||||
if (trans!=NULL) {
|
||||
if (j<num_trans)
|
||||
iCurImage->Pal.Palette[chans*j + 3] = trans[j];
|
||||
else
|
||||
iCurImage->Pal.Palette[chans*j + 3] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//allocate row pointers
|
||||
if ((row_pointers = (png_bytepp)ialloc(height * sizeof(png_bytep))) == NULL) {
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
// Set the individual row_pointers to point at the correct offsets */
|
||||
for (i = 0; i < height; i++)
|
||||
row_pointers[i] = iCurImage->Data + i * iCurImage->Bps;
|
||||
|
||||
|
||||
// Now we can go ahead and just read the whole image
|
||||
png_read_image(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(png_ptr, NULL);
|
||||
ifree(row_pointers);
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
ILvoid readpng_cleanup()
|
||||
{
|
||||
if (png_ptr && info_ptr) {
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
png_ptr = NULL;
|
||||
info_ptr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//! Writes a Png file
|
||||
ILboolean ilSavePng(ILconst_string FileName)
|
||||
{
|
||||
ILHANDLE PngFile;
|
||||
ILboolean bPng = IL_FALSE;
|
||||
|
||||
if (ilGetBoolean(IL_FILE_MODE) == IL_FALSE) {
|
||||
if (iFileExists(FileName)) {
|
||||
ilSetError(IL_FILE_ALREADY_EXISTS);
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
PngFile = iopenw(FileName);
|
||||
if (PngFile == NULL) {
|
||||
ilSetError(IL_COULD_NOT_OPEN_FILE);
|
||||
return bPng;
|
||||
}
|
||||
|
||||
bPng = ilSavePngF(PngFile);
|
||||
iclosew(PngFile);
|
||||
|
||||
return bPng;
|
||||
}
|
||||
|
||||
|
||||
//! Writes a Png to an already-opened file
|
||||
ILboolean ilSavePngF(ILHANDLE File)
|
||||
{
|
||||
iSetOutputFile(File);
|
||||
return iSavePngInternal();
|
||||
}
|
||||
|
||||
|
||||
//! Writes a Png to a memory "lump"
|
||||
ILboolean ilSavePngL(ILvoid *Lump, ILuint Size)
|
||||
{
|
||||
iSetOutputLump(Lump, Size);
|
||||
return iSavePngInternal();
|
||||
}
|
||||
|
||||
|
||||
ILvoid png_write(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
{
|
||||
(ILvoid)png_ptr;
|
||||
iwrite(data, 1, length);
|
||||
return;
|
||||
}
|
||||
|
||||
ILvoid flush_data(png_structp png_ptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Internal function used to save the Png.
|
||||
ILboolean iSavePngInternal()
|
||||
{
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
png_text text[3];
|
||||
ILenum PngType;
|
||||
ILuint BitDepth, i, j;
|
||||
ILubyte **RowPtr = NULL;
|
||||
ILimage *Temp = NULL;
|
||||
ILpal *TempPal = NULL;
|
||||
|
||||
//XIX alpha
|
||||
ILubyte transpart[1];
|
||||
ILint trans;
|
||||
|
||||
if (iCurImage == NULL) {
|
||||
ilSetError(IL_ILLEGAL_OPERATION);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
/* Create and initialize the png_struct with the desired error handler
|
||||
* functions. If you want to use the default stderr and longjump method,
|
||||
* you can supply NULL for the last three parameters. We also check that
|
||||
* the library version is compatible with the one used at compile time,
|
||||
* in case we are using dynamically linked libraries. REQUIRED.
|
||||
*/
|
||||
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, png_error_func, png_warn_func);
|
||||
if (png_ptr == NULL) {
|
||||
ilSetError(IL_LIB_PNG_ERROR);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
// Allocate/initialize the image information data. REQUIRED
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (info_ptr == NULL) {
|
||||
ilSetError(IL_LIB_PNG_ERROR);
|
||||
goto error_label;
|
||||
}
|
||||
|
||||
/*// Set error handling. REQUIRED if you aren't supplying your own
|
||||
// error handling functions in the png_create_write_struct() call.
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
// If we get here, we had a problem reading the file
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
ilSetError(IL_LIB_PNG_ERROR);
|
||||
return IL_FALSE;
|
||||
}*/
|
||||
|
||||
// png_init_io(png_ptr, PngFile);
|
||||
png_set_write_fn(png_ptr, NULL, png_write, flush_data);
|
||||
|
||||
switch (iCurImage->Type)
|
||||
{
|
||||
case IL_BYTE:
|
||||
case IL_UNSIGNED_BYTE:
|
||||
Temp = iCurImage;
|
||||
BitDepth = 8;
|
||||
break;
|
||||
case IL_SHORT:
|
||||
case IL_UNSIGNED_SHORT:
|
||||
Temp = iCurImage;
|
||||
BitDepth = 16;
|
||||
break;
|
||||
case IL_INT:
|
||||
case IL_UNSIGNED_INT:
|
||||
Temp = iConvertImage(iCurImage, iCurImage->Format, IL_UNSIGNED_SHORT);
|
||||
if (Temp == NULL) {
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
return IL_FALSE;
|
||||
}
|
||||
BitDepth = 16;
|
||||
break;
|
||||
default:
|
||||
ilSetError(IL_INTERNAL_ERROR);
|
||||
goto error_label;
|
||||
}
|
||||
|
||||
switch (iCurImage->Format)
|
||||
{
|
||||
case IL_COLOUR_INDEX:
|
||||
PngType = PNG_COLOR_TYPE_PALETTE;
|
||||
break;
|
||||
case IL_LUMINANCE:
|
||||
PngType = PNG_COLOR_TYPE_GRAY;
|
||||
break;
|
||||
case IL_LUMINANCE_ALPHA: //added 20050328
|
||||
PngType = PNG_COLOR_TYPE_GRAY_ALPHA;
|
||||
break;
|
||||
case IL_RGB:
|
||||
case IL_BGR:
|
||||
PngType = PNG_COLOR_TYPE_RGB;
|
||||
break;
|
||||
case IL_RGBA:
|
||||
case IL_BGRA:
|
||||
PngType = PNG_COLOR_TYPE_RGB_ALPHA;
|
||||
break;
|
||||
default:
|
||||
ilSetError(IL_INTERNAL_ERROR);
|
||||
goto error_label;
|
||||
}
|
||||
|
||||
// Set the image information here. Width and height are up to 2^31,
|
||||
// bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
|
||||
// the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
|
||||
// PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
|
||||
// or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or
|
||||
// PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
|
||||
// currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED
|
||||
if (iGetInt(IL_PNG_INTERLACE) == IL_TRUE) {
|
||||
png_set_IHDR(png_ptr, info_ptr, iCurImage->Width, iCurImage->Height, BitDepth, PngType,
|
||||
PNG_INTERLACE_ADAM7, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
||||
}
|
||||
else {
|
||||
png_set_IHDR(png_ptr, info_ptr, iCurImage->Width, iCurImage->Height, BitDepth, PngType,
|
||||
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
||||
}
|
||||
|
||||
if (iCurImage->Format == IL_COLOUR_INDEX) {
|
||||
// set the palette if there is one. REQUIRED for indexed-color images.
|
||||
TempPal = iConvertPal(&iCurImage->Pal, IL_PAL_RGB24);
|
||||
png_set_PLTE(png_ptr, info_ptr, (png_colorp)TempPal->Palette,
|
||||
ilGetInteger(IL_PALETTE_NUM_COLS));
|
||||
|
||||
//XIX alpha
|
||||
trans=iGetInt(IL_PNG_ALPHA_INDEX);
|
||||
if ( trans>=0)
|
||||
{
|
||||
transpart[0]=(ILubyte)trans;
|
||||
png_set_tRNS(png_ptr, info_ptr, transpart, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// optional significant bit chunk
|
||||
// if we are dealing with a grayscale image then
|
||||
sig_bit.gray = true_bit_depth;
|
||||
// otherwise, if we are dealing with a color image then
|
||||
sig_bit.red = true_red_bit_depth;
|
||||
sig_bit.green = true_green_bit_depth;
|
||||
sig_bit.blue = true_blue_bit_depth;
|
||||
// if the image has an alpha channel then
|
||||
sig_bit.alpha = true_alpha_bit_depth;
|
||||
png_set_sBIT(png_ptr, info_ptr, sig_bit);*/
|
||||
|
||||
|
||||
/* Optional gamma chunk is strongly suggested if you have any guess
|
||||
* as to the correct gamma of the image.
|
||||
*/
|
||||
//png_set_gAMA(png_ptr, info_ptr, gamma);
|
||||
|
||||
// Optionally write comments into the image.
|
||||
imemclear(text, sizeof(png_text) * 3);
|
||||
text[0].key = "Generated by";
|
||||
text[0].text = "Generated by the Developer's Image Library (DevIL)";
|
||||
text[0].compression = PNG_TEXT_COMPRESSION_NONE;
|
||||
text[1].key = "Author's name";
|
||||
text[1].text = iGetString(IL_PNG_AUTHNAME_STRING);
|
||||
text[1].compression = PNG_TEXT_COMPRESSION_NONE;
|
||||
text[2].key = "Author's comments";
|
||||
text[2].text = iGetString(IL_PNG_AUTHNAME_STRING);
|
||||
text[2].compression = PNG_TEXT_COMPRESSION_NONE;
|
||||
png_set_text(png_ptr, info_ptr, text, 3);
|
||||
|
||||
// Write the file header information. REQUIRED.
|
||||
png_write_info(png_ptr, info_ptr);
|
||||
|
||||
// Free up our user-defined text.
|
||||
if (text[1].text)
|
||||
ifree(text[1].text);
|
||||
if (text[2].text)
|
||||
ifree(text[2].text);
|
||||
|
||||
/* Shift the pixels up to a legal bit depth and fill in
|
||||
* as appropriate to correctly scale the image.
|
||||
*/
|
||||
//png_set_shift(png_ptr, &sig_bit);
|
||||
|
||||
/* pack pixels into bytes */
|
||||
//png_set_packing(png_ptr);
|
||||
|
||||
// swap location of alpha bytes from ARGB to RGBA
|
||||
//png_set_swap_alpha(png_ptr);
|
||||
|
||||
// flip BGR pixels to RGB
|
||||
if (iCurImage->Format == IL_BGR || iCurImage->Format == IL_BGRA)
|
||||
png_set_bgr(png_ptr);
|
||||
|
||||
// swap bytes of 16-bit files to most significant byte first
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
png_set_swap(png_ptr);
|
||||
#endif//__LITTLE_ENDIAN__
|
||||
|
||||
RowPtr = (ILubyte**)ialloc(iCurImage->Height * sizeof(ILubyte*));
|
||||
if (RowPtr == NULL)
|
||||
goto error_label;
|
||||
if (iCurImage->Origin == IL_ORIGIN_UPPER_LEFT) {
|
||||
for (i = 0; i < iCurImage->Height; i++) {
|
||||
RowPtr[i] = Temp->Data + i * Temp->Bps;
|
||||
}
|
||||
}
|
||||
else {
|
||||
j = iCurImage->Height - 1;
|
||||
for (i = 0; i < iCurImage->Height; i++, j--) {
|
||||
RowPtr[i] = Temp->Data + j * Temp->Bps;
|
||||
}
|
||||
}
|
||||
|
||||
// Writes the image.
|
||||
png_write_image(png_ptr, RowPtr);
|
||||
|
||||
// It is REQUIRED to call this to finish writing the rest of the file
|
||||
png_write_end(png_ptr, info_ptr);
|
||||
|
||||
// clean up after the write, and ifree any memory allocated
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
|
||||
ifree(RowPtr);
|
||||
|
||||
if (Temp != iCurImage)
|
||||
ilCloseImage(Temp);
|
||||
ilClosePal(TempPal);
|
||||
|
||||
return IL_TRUE;
|
||||
|
||||
error_label:
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
ifree(RowPtr);
|
||||
if (Temp != iCurImage)
|
||||
ilCloseImage(Temp);
|
||||
ilClosePal(TempPal);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
#endif//IL_NO_PNG
|
||||
682
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_pnm.c
Normal file
682
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_pnm.c
Normal file
@@ -0,0 +1,682 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2002 by Denton Woods
|
||||
// Last modified: 05/21/2002 <--Y2K Compliant! =]
|
||||
//
|
||||
// Filename: src-IL/src/il_pnm.c
|
||||
//
|
||||
// Description: Reads/writes to/from pbm/pgm/ppm formats (enough slashes? =)
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#include "il_internal.h"
|
||||
#ifndef IL_NO_PNM
|
||||
#include "il_pnm.h"
|
||||
#include <limits.h> // for maximum values
|
||||
#include <ctype.h>
|
||||
#include "il_manip.h"
|
||||
#include "il_bits.h"
|
||||
|
||||
// According to the ppm specs, it's 70, but PSP
|
||||
// likes to output longer lines...
|
||||
#define MAX_BUFFER 180
|
||||
static ILbyte LineBuffer[MAX_BUFFER];
|
||||
static ILbyte SmallBuff[MAX_BUFFER];
|
||||
|
||||
// Can't read direct bits from a lump yet
|
||||
ILboolean IsLump = IL_FALSE;
|
||||
|
||||
|
||||
//! Checks if the file specified in FileName is a valid .pnm file.
|
||||
ILboolean ilIsValidPnm(ILconst_string FileName)
|
||||
{
|
||||
ILHANDLE PnmFile;
|
||||
ILboolean bPnm = IL_FALSE;
|
||||
|
||||
if ( !iCheckExtension(FileName, IL_TEXT("pbm"))
|
||||
&& !iCheckExtension(FileName, IL_TEXT("pgm"))
|
||||
&& !iCheckExtension(FileName, IL_TEXT("ppm"))
|
||||
&& !iCheckExtension(FileName, IL_TEXT("pnm"))) {
|
||||
ilSetError(IL_INVALID_EXTENSION);
|
||||
return bPnm;
|
||||
}
|
||||
|
||||
PnmFile = iopenr(FileName);
|
||||
if (PnmFile == NULL) {
|
||||
ilSetError(IL_COULD_NOT_OPEN_FILE);
|
||||
return bPnm;
|
||||
}
|
||||
|
||||
bPnm = ilIsValidPnmF(PnmFile);
|
||||
icloser(PnmFile);
|
||||
|
||||
return bPnm;
|
||||
}
|
||||
|
||||
|
||||
//! Checks if the ILHANDLE contains a valid .pnm file at the current position.
|
||||
ILboolean ilIsValidPnmF(ILHANDLE File)
|
||||
{
|
||||
ILuint FirstPos;
|
||||
ILboolean bRet;
|
||||
|
||||
iSetInputFile(File);
|
||||
FirstPos = itell();
|
||||
bRet = iIsValidPnm();
|
||||
iseek(FirstPos, IL_SEEK_SET);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
//! Checks if Lump is a valid .pnm lump.
|
||||
ILboolean ilIsValidPnmL(const ILvoid *Lump, ILuint Size)
|
||||
{
|
||||
iSetInputLump(Lump, Size);
|
||||
return iIsValidPnm();
|
||||
}
|
||||
|
||||
|
||||
// Internal function to get the header and check it.
|
||||
ILboolean iIsValidPnm()
|
||||
{
|
||||
char Head[2];
|
||||
ILint Read;
|
||||
|
||||
Read = iread(Head, 1, 2);
|
||||
iseek(-Read, IL_SEEK_CUR); // Go ahead and restore to previous state
|
||||
if (Read != 2)
|
||||
return IL_FALSE;
|
||||
|
||||
return iCheckPnm(Head);
|
||||
}
|
||||
|
||||
|
||||
// Internal function used to check if the HEADER is a valid .pnm header.
|
||||
ILboolean iCheckPnm(char Header[2])
|
||||
{
|
||||
if (Header[0] != 'P')
|
||||
return IL_FALSE;
|
||||
switch (Header[1])
|
||||
{
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
// Reads a file
|
||||
ILboolean ilLoadPnm(ILconst_string FileName)
|
||||
{
|
||||
ILHANDLE PnmFile;
|
||||
ILboolean bPnm = IL_FALSE;
|
||||
|
||||
PnmFile = iopenr(FileName);
|
||||
if (PnmFile == NULL) {
|
||||
ilSetError(IL_COULD_NOT_OPEN_FILE);
|
||||
return bPnm;
|
||||
}
|
||||
|
||||
bPnm = ilLoadPnmF(PnmFile);
|
||||
icloser(PnmFile);
|
||||
|
||||
return bPnm;
|
||||
}
|
||||
|
||||
|
||||
// Reads an already-opened file
|
||||
ILboolean ilLoadPnmF(ILHANDLE File)
|
||||
{
|
||||
ILuint FirstPos;
|
||||
ILboolean bRet;
|
||||
|
||||
iSetInputFile(File);
|
||||
FirstPos = itell();
|
||||
bRet = iLoadPnmInternal();
|
||||
iseek(FirstPos, IL_SEEK_SET);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
// Reads from a memory "lump"
|
||||
ILboolean ilLoadPnmL(const ILvoid *Lump, ILuint Size)
|
||||
{
|
||||
iSetInputLump(Lump, Size);
|
||||
return iLoadPnmInternal();
|
||||
}
|
||||
|
||||
|
||||
// Load either a pgm or a ppm
|
||||
ILboolean iLoadPnmInternal()
|
||||
{
|
||||
ILimage *PmImage = NULL;
|
||||
PPMINFO Info;
|
||||
// ILuint LineInc = 0, SmallInc = 0;
|
||||
|
||||
Info.Type = 0;
|
||||
|
||||
if (iCurImage == NULL) {
|
||||
ilSetError(IL_ILLEGAL_OPERATION);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
// Find out what type of pgm/ppm this is
|
||||
if (iGetWord() == IL_FALSE)
|
||||
return IL_FALSE;
|
||||
|
||||
if (SmallBuff[0] != 'P') {
|
||||
ilSetError(IL_INVALID_FILE_HEADER);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
if (SmallBuff[1] == '1') {
|
||||
Info.Type = IL_PBM_ASCII;
|
||||
}
|
||||
else if (SmallBuff[1] == '2') {
|
||||
Info.Type = IL_PGM_ASCII;
|
||||
}
|
||||
else if (SmallBuff[1] == '3') {
|
||||
Info.Type = IL_PPM_ASCII;
|
||||
}
|
||||
else if (SmallBuff[1] == '4') {
|
||||
Info.Type = IL_PBM_BINARY;
|
||||
if (IsLump) {
|
||||
ilSetError(IL_FORMAT_NOT_SUPPORTED);
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
else if (SmallBuff[1] == '5') {
|
||||
Info.Type = IL_PGM_BINARY;
|
||||
}
|
||||
else if (SmallBuff[1] == '6') {
|
||||
Info.Type = IL_PPM_BINARY;
|
||||
}
|
||||
else {
|
||||
ilSetError(IL_INVALID_FILE_HEADER);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
// Retrieve the width and height
|
||||
if (iGetWord() == IL_FALSE)
|
||||
return IL_FALSE;
|
||||
Info.Width = atoi((const char*)SmallBuff);
|
||||
if (Info.Width == 0) {
|
||||
ilSetError(IL_INVALID_FILE_HEADER);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
if (iGetWord() == IL_FALSE)
|
||||
return IL_FALSE;
|
||||
Info.Height = atoi((const char*)SmallBuff);
|
||||
if (Info.Height == 0) {
|
||||
ilSetError(IL_INVALID_FILE_HEADER);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
// Retrieve the maximum colour component value
|
||||
if (Info.Type != IL_PBM_ASCII && Info.Type != IL_PBM_BINARY) {
|
||||
if (iGetWord() == IL_FALSE)
|
||||
return IL_FALSE;
|
||||
if ((Info.MaxColour = atoi((const char*)SmallBuff)) == 0) {
|
||||
ilSetError(IL_INVALID_FILE_HEADER);
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
Info.MaxColour = 1;
|
||||
|
||||
if (Info.Type == IL_PBM_ASCII || Info.Type == IL_PBM_BINARY ||
|
||||
Info.Type == IL_PGM_ASCII || Info.Type == IL_PGM_BINARY) {
|
||||
if (Info.Type == IL_PGM_ASCII) {
|
||||
if (Info.MaxColour < 256)
|
||||
Info.Bpp = 1;
|
||||
else
|
||||
Info.Bpp = 2;
|
||||
}
|
||||
else
|
||||
Info.Bpp = 1;
|
||||
}
|
||||
else {
|
||||
Info.Bpp = 3;
|
||||
}
|
||||
|
||||
switch (Info.Type)
|
||||
{
|
||||
case IL_PBM_ASCII:
|
||||
case IL_PGM_ASCII:
|
||||
case IL_PPM_ASCII:
|
||||
PmImage = ilReadAsciiPpm(&Info);
|
||||
break;
|
||||
case IL_PBM_BINARY:
|
||||
PmImage = ilReadBitPbm(&Info);
|
||||
break;
|
||||
case IL_PGM_BINARY:
|
||||
case IL_PPM_BINARY:
|
||||
PmImage = ilReadBinaryPpm(&Info);
|
||||
break;
|
||||
default:
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
if (PmImage == NULL) {
|
||||
iCurImage->Format = ilGetFormatBpp(iCurImage->Bpp);
|
||||
ilSetError(IL_FILE_READ_ERROR);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
// Is this conversion needed? Just 0's and 1's shows up as all black
|
||||
if (Info.Type == IL_PBM_ASCII) {
|
||||
PbmMaximize(PmImage);
|
||||
}
|
||||
|
||||
if (Info.MaxColour > 255)
|
||||
PmImage->Type = IL_UNSIGNED_SHORT;
|
||||
PmImage->Origin = IL_ORIGIN_UPPER_LEFT;
|
||||
if (Info.Type == IL_PBM_ASCII || Info.Type == IL_PBM_BINARY ||
|
||||
Info.Type == IL_PGM_ASCII || Info.Type == IL_PGM_BINARY)
|
||||
PmImage->Format = IL_LUMINANCE;
|
||||
else
|
||||
PmImage->Format = IL_RGB;
|
||||
PmImage->Origin = IL_ORIGIN_UPPER_LEFT;
|
||||
|
||||
ilFixImage();
|
||||
|
||||
if (PmImage == NULL)
|
||||
return IL_FALSE;
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ILimage *ilReadAsciiPpm(PPMINFO *Info)
|
||||
{
|
||||
ILint LineInc = 0, SmallInc = 0, DataInc = 0, Size;
|
||||
// ILint BytesRead = 0;
|
||||
|
||||
if (Info->MaxColour > 255)
|
||||
Info->Bpp *= 2;
|
||||
|
||||
Size = Info->Width * Info->Height * Info->Bpp;
|
||||
|
||||
if (!ilTexImage(Info->Width, Info->Height, 1, (ILubyte)(Info->Bpp), 0, IL_UNSIGNED_BYTE, NULL)) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
|
||||
if (Info->MaxColour > 255)
|
||||
iCurImage->Type = IL_UNSIGNED_SHORT;
|
||||
|
||||
while (DataInc < Size) { // && !feof(File)) {
|
||||
LineInc = 0;
|
||||
|
||||
if (iFgets((char *)LineBuffer, MAX_BUFFER) == NULL) {
|
||||
//ilSetError(IL_ILLEGAL_FILE_VALUE);
|
||||
//return NULL;
|
||||
//return iCurImage;
|
||||
break;
|
||||
}
|
||||
if (LineBuffer[0] == '#') { // Comment
|
||||
continue;
|
||||
}
|
||||
|
||||
while ((LineBuffer[LineInc] != NUL) && (LineBuffer[LineInc] != '\n')) {
|
||||
|
||||
SmallInc = 0;
|
||||
while (!isalnum(LineBuffer[LineInc])) { // Skip any whitespace
|
||||
LineInc++;
|
||||
}
|
||||
while (isalnum(LineBuffer[LineInc])) {
|
||||
SmallBuff[SmallInc] = LineBuffer[LineInc];
|
||||
SmallInc++;
|
||||
LineInc++;
|
||||
}
|
||||
SmallBuff[SmallInc] = NUL;
|
||||
iCurImage->Data[DataInc] = atoi((const char*)SmallBuff); // Convert from string to colour
|
||||
|
||||
// PSP likes to put whitespace at the end of lines...figures. =/
|
||||
while (!isalnum(LineBuffer[LineInc]) && LineBuffer[LineInc] != NUL) { // Skip any whitespace
|
||||
LineInc++;
|
||||
}
|
||||
|
||||
// We should set some kind of state flag that enables this
|
||||
//Image->Data[DataInc] *= (ILubyte)(255 / Info->MaxColour); // Scales to 0-255
|
||||
if (Info->MaxColour > 255)
|
||||
DataInc++;
|
||||
DataInc++;
|
||||
}
|
||||
}
|
||||
|
||||
// If we read less than what we should have...
|
||||
if (DataInc < Size) {
|
||||
//ilCloseImage(iCurImage);
|
||||
//ilSetCurImage(NULL);
|
||||
ilSetError(IL_ILLEGAL_FILE_VALUE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return iCurImage;
|
||||
}
|
||||
|
||||
|
||||
ILimage *ilReadBinaryPpm(PPMINFO *Info)
|
||||
{
|
||||
ILuint Size;
|
||||
|
||||
Size = Info->Width * Info->Height * Info->Bpp;
|
||||
|
||||
if (!ilTexImage(Info->Width, Info->Height, 1, (ILubyte)(Info->Bpp), 0, IL_UNSIGNED_BYTE, NULL)) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
|
||||
|
||||
if (iread(iCurImage->Data, 1, Size) != Size)
|
||||
return NULL;
|
||||
|
||||
return iCurImage;
|
||||
}
|
||||
|
||||
|
||||
ILimage *ilReadBitPbm(PPMINFO *Info)
|
||||
{
|
||||
ILuint m, j, x, CurrByte;
|
||||
|
||||
if (!ilTexImage(Info->Width, Info->Height, 1, (ILubyte)(Info->Bpp), 0, IL_UNSIGNED_BYTE, NULL)) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
|
||||
|
||||
x = 0;
|
||||
for (j = 0; j < iCurImage->SizeOfData;) {
|
||||
CurrByte = igetc();
|
||||
for (m = 128; m > 0 && x < Info->Width; m >>= 1, ++x, ++j) {
|
||||
iCurImage->Data[j] = (CurrByte & m)?255:0;
|
||||
}
|
||||
if (x == Info->Width)
|
||||
x = 0;
|
||||
}
|
||||
|
||||
return iCurImage;
|
||||
}
|
||||
|
||||
|
||||
ILboolean iGetWord(ILvoid)
|
||||
{
|
||||
ILint WordPos = 0;
|
||||
ILint Current = 0;
|
||||
ILboolean Started = IL_FALSE;
|
||||
ILboolean Looping = IL_TRUE;
|
||||
|
||||
if (ieof())
|
||||
return IL_FALSE;
|
||||
|
||||
while (Looping) {
|
||||
while ((Current = igetc()) != IL_EOF && Current != '\n' && Current != '#' && Current != ' ') {
|
||||
if (Current == IL_EOF)
|
||||
return IL_FALSE;
|
||||
if (!isalnum(Current)) {
|
||||
if (Started) {
|
||||
Looping = IL_FALSE;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Looping)
|
||||
SmallBuff[WordPos++] = Current;
|
||||
}
|
||||
|
||||
SmallBuff[WordPos] = NUL;
|
||||
|
||||
if (!Looping)
|
||||
break;
|
||||
|
||||
if (Current == '#') { // '#' is a comment...read until end of line
|
||||
while ((Current = igetc()) != IL_EOF && Current != '\n');
|
||||
}
|
||||
|
||||
// Get rid of any erroneous spaces
|
||||
while ((Current = igetc()) != IL_EOF) {
|
||||
if (Current != ' ')
|
||||
break;
|
||||
}
|
||||
iseek(-1, IL_SEEK_CUR);
|
||||
|
||||
if (WordPos > 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (Current == -1 || WordPos == 0) {
|
||||
ilSetError(IL_INVALID_FILE_HEADER);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
ILstring FName;
|
||||
|
||||
//! Writes a Pnm file
|
||||
ILboolean ilSavePnm(ILconst_string FileName)
|
||||
{
|
||||
ILHANDLE PnmFile;
|
||||
ILboolean bPnm = IL_FALSE;
|
||||
|
||||
FName = (ILstring)FileName;
|
||||
|
||||
if (ilGetBoolean(IL_FILE_MODE) == IL_FALSE) {
|
||||
if (iFileExists(FileName)) {
|
||||
ilSetError(IL_FILE_ALREADY_EXISTS);
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
PnmFile = iopenw(FileName);
|
||||
if (PnmFile == NULL) {
|
||||
ilSetError(IL_COULD_NOT_OPEN_FILE);
|
||||
return bPnm;
|
||||
}
|
||||
|
||||
bPnm = ilSavePnmF(PnmFile);
|
||||
iclosew(PnmFile);
|
||||
|
||||
return bPnm;
|
||||
}
|
||||
|
||||
|
||||
//! Writes a Pnm to an already-opened file
|
||||
ILboolean ilSavePnmF(ILHANDLE File)
|
||||
{
|
||||
iSetOutputFile(File);
|
||||
return iSavePnmInternal();
|
||||
}
|
||||
|
||||
|
||||
//! Writes a Pnm to a memory "lump"
|
||||
ILboolean ilSavePnmL(ILvoid *Lump, ILuint Size)
|
||||
{
|
||||
FName = NULL;
|
||||
iSetOutputLump(Lump, Size);
|
||||
return iSavePnmInternal();
|
||||
}
|
||||
|
||||
|
||||
// Internal function used to save the Pnm.
|
||||
ILboolean iSavePnmInternal()
|
||||
{
|
||||
ILuint Bpp, MaxVal = UCHAR_MAX, i = 0, j, k;
|
||||
ILenum Type = 0;
|
||||
ILuint LinePos = 0; // Cannot exceed 70 for pnm's!
|
||||
ILboolean Binary;
|
||||
ILimage *TempImage;
|
||||
ILubyte *TempData;
|
||||
|
||||
if (iCurImage == NULL) {
|
||||
ilSetError(IL_ILLEGAL_OPERATION);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
if (iCheckExtension(FName, IL_TEXT("pbm")))
|
||||
Type = IL_PBM_ASCII;
|
||||
else if (iCheckExtension(FName, IL_TEXT("pgm")))
|
||||
Type = IL_PGM_ASCII;
|
||||
else if (iCheckExtension(FName, IL_TEXT("ppm")))
|
||||
Type = IL_PPM_ASCII;
|
||||
else
|
||||
Type = IL_PPM_ASCII;
|
||||
|
||||
/*if (!Type) {
|
||||
ilSetError(IL_INVALID_EXTENSION);
|
||||
return IL_FALSE;
|
||||
}*/
|
||||
|
||||
if (iGetHint(IL_COMPRESSION_HINT) == IL_USE_COMPRESSION) {
|
||||
Type += 3;
|
||||
Binary = IL_TRUE;
|
||||
}
|
||||
else {
|
||||
Binary = IL_FALSE;
|
||||
}
|
||||
|
||||
if (iCurImage->Type == IL_UNSIGNED_BYTE) {
|
||||
MaxVal = UCHAR_MAX;
|
||||
}
|
||||
else if (iCurImage->Type == IL_UNSIGNED_SHORT) {
|
||||
MaxVal = USHRT_MAX;
|
||||
}
|
||||
else {
|
||||
ilSetError(IL_FORMAT_NOT_SUPPORTED);
|
||||
return IL_FALSE;
|
||||
}
|
||||
if (MaxVal > UCHAR_MAX && Type >= IL_PBM_BINARY) { // binary cannot be higher than 255
|
||||
ilSetError(IL_FORMAT_NOT_SUPPORTED);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
switch (Type)
|
||||
{
|
||||
case IL_PBM_ASCII:
|
||||
Bpp = 1;
|
||||
ilprintf("P1\n");
|
||||
TempImage = iConvertImage(iCurImage, IL_LUMINANCE, IL_UNSIGNED_BYTE);
|
||||
break;
|
||||
//case IL_PBM_BINARY: // Don't want to mess with saving bits just yet...
|
||||
//Bpp = 1;
|
||||
//ilprintf("P4\n");
|
||||
//break;
|
||||
case IL_PBM_BINARY:
|
||||
ilSetError(IL_FORMAT_NOT_SUPPORTED);
|
||||
return IL_FALSE;
|
||||
case IL_PGM_ASCII:
|
||||
Bpp = 1;
|
||||
ilprintf("P2\n");
|
||||
TempImage = iConvertImage(iCurImage, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE);
|
||||
break;
|
||||
case IL_PGM_BINARY:
|
||||
Bpp = 1;
|
||||
ilprintf("P5\n");
|
||||
TempImage = iConvertImage(iCurImage, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE);
|
||||
break;
|
||||
case IL_PPM_ASCII:
|
||||
Bpp = 3;
|
||||
ilprintf("P3\n");
|
||||
TempImage = iConvertImage(iCurImage, IL_RGB, IL_UNSIGNED_BYTE);
|
||||
break;
|
||||
case IL_PPM_BINARY:
|
||||
Bpp = 3;
|
||||
ilprintf("P6\n");
|
||||
TempImage = iConvertImage(iCurImage, IL_RGB, IL_UNSIGNED_BYTE);
|
||||
break;
|
||||
default:
|
||||
ilSetError(IL_INTERNAL_ERROR);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
if (TempImage == NULL)
|
||||
return IL_FALSE;
|
||||
|
||||
if (Bpp != TempImage->Bpp) {
|
||||
ilSetError(IL_INVALID_CONVERSION);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
if (TempImage->Origin != IL_ORIGIN_UPPER_LEFT) {
|
||||
TempData = iGetFlipped(TempImage);
|
||||
if (TempData == NULL) {
|
||||
ilCloseImage(TempImage);
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
TempData = TempImage->Data;
|
||||
}
|
||||
|
||||
ilprintf("%d %d\n", TempImage->Width, TempImage->Height);
|
||||
if (Type != IL_PBM_BINARY && Type != IL_PBM_ASCII) // not needed for .pbm's (only 0 and 1)
|
||||
ilprintf("%d\n", MaxVal);
|
||||
|
||||
while (i < TempImage->SizeOfPlane) {
|
||||
for (j = 0; j < Bpp; j++) {
|
||||
if (Binary) {
|
||||
if (Type == IL_PBM_BINARY) {
|
||||
iputc((ILubyte)(TempData[i] > 127 ? 1 : 0));
|
||||
}
|
||||
else {
|
||||
iputc(TempData[i]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (TempImage->Type == IL_UNSIGNED_BYTE)
|
||||
k = TempData[i];
|
||||
else // IL_UNSIGNED_SHORT
|
||||
k = *((ILushort*)TempData + i);
|
||||
if (Type == IL_PBM_ASCII) {
|
||||
LinePos += ilprintf("%d ", TempData[i] > 127 ? 1 : 0);
|
||||
}
|
||||
else {
|
||||
LinePos += ilprintf("%d ", TempData[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (TempImage->Type == IL_UNSIGNED_SHORT)
|
||||
i++;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (LinePos > 65) { // Just a good number =]
|
||||
ilprintf("\n");
|
||||
LinePos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (TempImage->Origin != IL_ORIGIN_UPPER_LEFT)
|
||||
ifree(TempData);
|
||||
ilCloseImage(TempImage);
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Converts a .pbm to something viewable.
|
||||
ILvoid PbmMaximize(ILimage *Image)
|
||||
{
|
||||
ILuint i = 0;
|
||||
for (i = 0; i < Image->SizeOfPlane; i++)
|
||||
if (Image->Data[i] == 1)
|
||||
Image->Data[i] = 0xFF;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#endif//IL_NO_PNM
|
||||
169
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_profiles.c
Normal file
169
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_profiles.c
Normal file
@@ -0,0 +1,169 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2002 by Denton Woods
|
||||
// Last modified: 01/23/2001 <--Y2K Compliant! =]
|
||||
//
|
||||
// Filename: src-IL/src/il_profiles.c
|
||||
//
|
||||
// Description: Colour profile handler
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "il_internal.h"
|
||||
#ifndef IL_NO_LCMS
|
||||
|
||||
#ifdef PACKAGE_NAME
|
||||
#define IL_PACKAGE_NAME PACKAGE_NAME;
|
||||
#undef PACKAGE_NAME
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
#define NON_WINDOWS 1
|
||||
#ifndef LCMS_NODIRINCLUDE
|
||||
#include <lcms.h>
|
||||
#else
|
||||
#include <lcms/lcms.h>
|
||||
#endif
|
||||
|
||||
#else
|
||||
// #ifndef IL_DEBUG
|
||||
// pragma comment(lib, "lcms108.lib")
|
||||
// #else
|
||||
// pragma comment(lib, "debug/lcms108.lib")
|
||||
// #endif
|
||||
#include <lcms.h>
|
||||
#endif//_WIN32
|
||||
|
||||
#ifdef PACKAGE_NAME
|
||||
#undef PACKAGE_NAME
|
||||
#endif
|
||||
|
||||
#ifdef IL_PACKAGE_NAME
|
||||
#define PACKAGE_NAME IL_PACKAGE_NAME
|
||||
#undef IL_PACKAGE_NAME
|
||||
#endif
|
||||
|
||||
#endif//IL_NO_LCMS
|
||||
|
||||
ILboolean ILAPIENTRY ilApplyProfile(ILstring InProfile, ILstring OutProfile)
|
||||
{
|
||||
#ifndef IL_NO_LCMS
|
||||
cmsHPROFILE hInProfile, hOutProfile;
|
||||
cmsHTRANSFORM hTransform;
|
||||
ILubyte *Temp;
|
||||
ILint Format=0;
|
||||
#ifdef _UNICODE
|
||||
char AnsiName[512];
|
||||
#endif//_UNICODE
|
||||
|
||||
if (iCurImage == NULL) {
|
||||
ilSetError(IL_ILLEGAL_OPERATION);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
switch (iCurImage->Type)
|
||||
{
|
||||
case IL_BYTE:
|
||||
case IL_UNSIGNED_BYTE:
|
||||
switch (iCurImage->Format)
|
||||
{
|
||||
case IL_LUMINANCE:
|
||||
Format = TYPE_GRAY_8;
|
||||
break;
|
||||
case IL_RGB:
|
||||
Format = TYPE_RGB_8;
|
||||
break;
|
||||
case IL_BGR:
|
||||
Format = TYPE_BGR_8;
|
||||
break;
|
||||
case IL_RGBA:
|
||||
Format = TYPE_RGBA_8;
|
||||
break;
|
||||
case IL_BGRA:
|
||||
Format = TYPE_BGRA_8;
|
||||
break;
|
||||
default:
|
||||
ilSetError(IL_INTERNAL_ERROR);
|
||||
return IL_FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case IL_SHORT:
|
||||
case IL_UNSIGNED_SHORT:
|
||||
switch (iCurImage->Format)
|
||||
{
|
||||
case IL_LUMINANCE:
|
||||
Format = TYPE_GRAY_16;
|
||||
break;
|
||||
case IL_RGB:
|
||||
Format = TYPE_RGB_16;
|
||||
break;
|
||||
case IL_BGR:
|
||||
Format = TYPE_BGR_16;
|
||||
break;
|
||||
case IL_RGBA:
|
||||
Format = TYPE_RGBA_16;
|
||||
break;
|
||||
case IL_BGRA:
|
||||
Format = TYPE_BGRA_16;
|
||||
break;
|
||||
default:
|
||||
ilSetError(IL_INTERNAL_ERROR);
|
||||
return IL_FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
// These aren't supported right now.
|
||||
case IL_INT:
|
||||
case IL_UNSIGNED_INT:
|
||||
case IL_FLOAT:
|
||||
case IL_DOUBLE:
|
||||
ilSetError(IL_ILLEGAL_OPERATION);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
if (InProfile == NULL) {
|
||||
if (!iCurImage->Profile || !iCurImage->ProfileSize) {
|
||||
ilSetError(IL_INVALID_PARAM);
|
||||
return IL_FALSE;
|
||||
}
|
||||
hInProfile = iCurImage->Profile;
|
||||
}
|
||||
else {
|
||||
#ifndef _UNICODE
|
||||
hInProfile = cmsOpenProfileFromFile(InProfile, "r");
|
||||
#else
|
||||
wcstombs(AnsiName, InProfile, 512);
|
||||
hInProfile = cmsOpenProfileFromFile(AnsiName, "r");
|
||||
#endif//_UNICODE
|
||||
}
|
||||
#ifndef _UNICODE
|
||||
hOutProfile = cmsOpenProfileFromFile(OutProfile, "r");
|
||||
#else
|
||||
wcstombs(AnsiName, OutProfile, 512);
|
||||
hOutProfile = cmsOpenProfileFromFile(AnsiName, "r");
|
||||
#endif//_UNICODE
|
||||
|
||||
hTransform = cmsCreateTransform(hInProfile, Format, hOutProfile, Format, INTENT_PERCEPTUAL, 0);
|
||||
|
||||
Temp = (ILubyte*)ialloc(iCurImage->SizeOfData);
|
||||
if (Temp == NULL) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
cmsDoTransform(hTransform, iCurImage->Data, Temp, iCurImage->SizeOfData / 3);
|
||||
|
||||
ifree(iCurImage->Data);
|
||||
iCurImage->Data = Temp;
|
||||
|
||||
cmsDeleteTransform(hTransform);
|
||||
if (InProfile != NULL)
|
||||
cmsCloseProfile(hInProfile);
|
||||
cmsCloseProfile(hOutProfile);
|
||||
|
||||
#endif//IL_NO_LCMS
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
935
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_psd.c
Normal file
935
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_psd.c
Normal file
@@ -0,0 +1,935 @@
|
||||
|
||||
// Information about the .psd format was taken from Adobe's PhotoShop SDK at
|
||||
// http://partners.adobe.com/asn/developer/gapsdk/PhotoshopSDK.html
|
||||
// Information about the Packbits compression scheme was found at
|
||||
// http://partners.adobe.com/asn/developer/PDFS/TN/TIFF6.pdf
|
||||
|
||||
#include "il_internal.h"
|
||||
#ifndef IL_NO_PSD
|
||||
#include "il_psd.h"
|
||||
|
||||
|
||||
//! Checks if the file specified in FileName is a valid Psd file.
|
||||
ILboolean ilIsValidPsd(ILconst_string FileName)
|
||||
{
|
||||
ILHANDLE PsdFile;
|
||||
ILboolean bPsd = IL_FALSE;
|
||||
|
||||
if (!iCheckExtension(FileName, IL_TEXT("psd")) &&
|
||||
!iCheckExtension(FileName, IL_TEXT("pdd"))) {
|
||||
ilSetError(IL_INVALID_EXTENSION);
|
||||
return bPsd;
|
||||
}
|
||||
|
||||
PsdFile = iopenr(FileName);
|
||||
if (PsdFile == NULL) {
|
||||
ilSetError(IL_COULD_NOT_OPEN_FILE);
|
||||
return bPsd;
|
||||
}
|
||||
|
||||
bPsd = ilIsValidPsdF(PsdFile);
|
||||
icloser(PsdFile);
|
||||
|
||||
return bPsd;
|
||||
}
|
||||
|
||||
|
||||
//! Checks if the ILHANDLE contains a valid Psd file at the current position.
|
||||
ILboolean ilIsValidPsdF(ILHANDLE File)
|
||||
{
|
||||
ILuint FirstPos;
|
||||
ILboolean bRet;
|
||||
|
||||
iSetInputFile(File);
|
||||
FirstPos = itell();
|
||||
bRet = iIsValidPsd();
|
||||
iseek(FirstPos, IL_SEEK_SET);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
//! Checks if Lump is a valid Psd lump.
|
||||
ILboolean ilIsValidPsdL(const ILvoid *Lump, ILuint Size)
|
||||
{
|
||||
iSetInputLump(Lump, Size);
|
||||
return iIsValidPsd();
|
||||
}
|
||||
|
||||
|
||||
// Internal function used to get the Psd header from the current file.
|
||||
ILboolean iGetPsdHead(PSDHEAD *Header)
|
||||
{
|
||||
iread(Header->Signature, 1, 4);
|
||||
Header->Version = GetBigUShort();
|
||||
iread(Header->Reserved, 1, 6);
|
||||
Header->Channels = GetBigUShort();
|
||||
Header->Height = GetBigUInt();
|
||||
Header->Width = GetBigUInt();
|
||||
Header->Depth = GetBigUShort();
|
||||
Header->Mode = GetBigUShort();
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Internal function to get the header and check it.
|
||||
ILboolean iIsValidPsd()
|
||||
{
|
||||
PSDHEAD Head;
|
||||
|
||||
iGetPsdHead(&Head);
|
||||
iseek(-(ILint)sizeof(PSDHEAD), IL_SEEK_CUR);
|
||||
|
||||
return iCheckPsd(&Head);
|
||||
}
|
||||
|
||||
|
||||
// Internal function used to check if the HEADER is a valid Psd header.
|
||||
ILboolean iCheckPsd(PSDHEAD *Header)
|
||||
{
|
||||
ILuint i;
|
||||
|
||||
if (strncmp((char*)Header->Signature, "8BPS", 4))
|
||||
return IL_FALSE;
|
||||
if (Header->Version != 1)
|
||||
return IL_FALSE;
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (Header->Reserved[i] != 0)
|
||||
return IL_FALSE;
|
||||
}
|
||||
if (Header->Channels < 1 || Header->Channels > 24)
|
||||
return IL_FALSE;
|
||||
if (Header->Height < 1 || Header->Width < 1)
|
||||
return IL_FALSE;
|
||||
if (Header->Depth != 1 && Header->Depth != 8 && Header->Depth != 16)
|
||||
return IL_FALSE;
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
//! Reads a Psd file
|
||||
ILboolean ilLoadPsd(ILconst_string FileName)
|
||||
{
|
||||
ILHANDLE PsdFile;
|
||||
ILboolean bPsd = IL_FALSE;
|
||||
|
||||
PsdFile = iopenr(FileName);
|
||||
if (PsdFile == NULL) {
|
||||
ilSetError(IL_COULD_NOT_OPEN_FILE);
|
||||
return bPsd;
|
||||
}
|
||||
|
||||
bPsd = ilLoadPsdF(PsdFile);
|
||||
icloser(PsdFile);
|
||||
|
||||
return bPsd;
|
||||
}
|
||||
|
||||
|
||||
//! Reads an already-opened Psd file
|
||||
ILboolean ilLoadPsdF(ILHANDLE File)
|
||||
{
|
||||
ILuint FirstPos;
|
||||
ILboolean bRet;
|
||||
|
||||
iSetInputFile(File);
|
||||
FirstPos = itell();
|
||||
bRet = iLoadPsdInternal();
|
||||
iseek(FirstPos, IL_SEEK_SET);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
//! Reads from a memory "lump" that contains a Psd
|
||||
ILboolean ilLoadPsdL(const ILvoid *Lump, ILuint Size)
|
||||
{
|
||||
iSetInputLump(Lump, Size);
|
||||
return iLoadPsdInternal();
|
||||
}
|
||||
|
||||
|
||||
// Internal function used to load the Psd.
|
||||
ILboolean iLoadPsdInternal()
|
||||
{
|
||||
PSDHEAD Header;
|
||||
|
||||
if (iCurImage == NULL) {
|
||||
ilSetError(IL_ILLEGAL_OPERATION);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
iGetPsdHead(&Header);
|
||||
if (!iCheckPsd(&Header)) {
|
||||
ilSetError(IL_INVALID_FILE_HEADER);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
if (!ReadPsd(&Header))
|
||||
return IL_FALSE;
|
||||
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
|
||||
|
||||
ilFixImage();
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
ILboolean ReadPsd(PSDHEAD *Head)
|
||||
{
|
||||
switch (Head->Mode)
|
||||
{
|
||||
case 1: // Greyscale
|
||||
return ReadGrey(Head);
|
||||
case 2: // Indexed
|
||||
return ReadIndexed(Head);
|
||||
case 3: // RGB
|
||||
return ReadRGB(Head);
|
||||
case 4: // CMYK
|
||||
return ReadCMYK(Head);
|
||||
}
|
||||
|
||||
ilSetError(IL_FORMAT_NOT_SUPPORTED);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
ILboolean ReadGrey(PSDHEAD *Head)
|
||||
{
|
||||
ILuint ColorMode, ResourceSize, MiscInfo;
|
||||
ILushort Compressed;
|
||||
ILenum Type;
|
||||
ILubyte *Resources = NULL;
|
||||
|
||||
ColorMode = GetBigUInt(); // Skip over the 'color mode data section'
|
||||
iseek(ColorMode, IL_SEEK_CUR);
|
||||
|
||||
ResourceSize = GetBigUInt(); // Read the 'image resources section'
|
||||
Resources = (ILubyte*)ialloc(ResourceSize);
|
||||
if (Resources == NULL) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
if (iread(Resources, 1, ResourceSize) != ResourceSize)
|
||||
goto cleanup_error;
|
||||
|
||||
MiscInfo = GetBigUInt();
|
||||
iseek(MiscInfo, IL_SEEK_CUR);
|
||||
|
||||
Compressed = GetBigUShort();
|
||||
|
||||
ChannelNum = Head->Channels;
|
||||
Head->Channels = 1; // Temporary to read only one channel...some greyscale .psd files have 2.
|
||||
if (Head->Channels != 1) {
|
||||
ilSetError(IL_FORMAT_NOT_SUPPORTED);
|
||||
return IL_FALSE;
|
||||
}
|
||||
switch (Head->Depth)
|
||||
{
|
||||
case 8:
|
||||
Type = IL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case 16:
|
||||
Type = IL_UNSIGNED_SHORT;
|
||||
break;
|
||||
default:
|
||||
ilSetError(IL_FORMAT_NOT_SUPPORTED);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
if (!ilTexImage(Head->Width, Head->Height, 1, 1, IL_LUMINANCE, Type, NULL))
|
||||
goto cleanup_error;
|
||||
if (!PsdGetData(Head, iCurImage->Data, (ILboolean)Compressed))
|
||||
goto cleanup_error;
|
||||
if (!ParseResources(ResourceSize, Resources))
|
||||
goto cleanup_error;
|
||||
ifree(Resources);
|
||||
|
||||
return IL_TRUE;
|
||||
|
||||
cleanup_error:
|
||||
ifree(Resources);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
ILboolean ReadIndexed(PSDHEAD *Head)
|
||||
{
|
||||
ILuint ColorMode, ResourceSize, MiscInfo, i, j, NumEnt;
|
||||
ILushort Compressed;
|
||||
ILubyte *Palette = NULL, *Resources = NULL;
|
||||
|
||||
ColorMode = GetBigUInt(); // Skip over the 'color mode data section'
|
||||
if (ColorMode % 3 != 0) {
|
||||
ilSetError(IL_INVALID_FILE_HEADER);
|
||||
return IL_FALSE;
|
||||
}
|
||||
Palette = (ILubyte*)ialloc(ColorMode);
|
||||
if (Palette == NULL)
|
||||
return IL_FALSE;
|
||||
if (iread(Palette, 1, ColorMode) != ColorMode)
|
||||
goto cleanup_error;
|
||||
|
||||
ResourceSize = GetBigUInt(); // Read the 'image resources section'
|
||||
Resources = (ILubyte*)ialloc(ResourceSize);
|
||||
if (Resources == NULL) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
if (iread(Resources, 1, ResourceSize) != ResourceSize)
|
||||
goto cleanup_error;
|
||||
|
||||
MiscInfo = GetBigUInt();
|
||||
if (ieof())
|
||||
goto cleanup_error;
|
||||
iseek(MiscInfo, IL_SEEK_CUR);
|
||||
|
||||
Compressed = GetBigUShort();
|
||||
if (ieof())
|
||||
goto cleanup_error;
|
||||
|
||||
if (Head->Channels != 1 || Head->Depth != 8) {
|
||||
ilSetError(IL_FORMAT_NOT_SUPPORTED);
|
||||
goto cleanup_error;
|
||||
}
|
||||
ChannelNum = Head->Channels;
|
||||
|
||||
if (!ilTexImage(Head->Width, Head->Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL))
|
||||
goto cleanup_error;
|
||||
|
||||
iCurImage->Pal.Palette = (ILubyte*)ialloc(ColorMode);
|
||||
if (iCurImage->Pal.Palette == NULL) {
|
||||
goto cleanup_error;
|
||||
}
|
||||
iCurImage->Pal.PalSize = ColorMode;
|
||||
iCurImage->Pal.PalType = IL_PAL_RGB24;
|
||||
|
||||
NumEnt = iCurImage->Pal.PalSize / 3;
|
||||
for (i = 0, j = 0; i < iCurImage->Pal.PalSize; i += 3, j++) {
|
||||
iCurImage->Pal.Palette[i ] = Palette[j];
|
||||
iCurImage->Pal.Palette[i+1] = Palette[j+NumEnt];
|
||||
iCurImage->Pal.Palette[i+2] = Palette[j+NumEnt*2];
|
||||
}
|
||||
ifree(Palette);
|
||||
Palette = NULL;
|
||||
|
||||
if (!PsdGetData(Head, iCurImage->Data, (ILboolean)Compressed))
|
||||
goto cleanup_error;
|
||||
|
||||
ParseResources(ResourceSize, Resources);
|
||||
ifree(Resources);
|
||||
Resources = NULL;
|
||||
|
||||
return IL_TRUE;
|
||||
|
||||
cleanup_error:
|
||||
ifree(Palette);
|
||||
ifree(Resources);
|
||||
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
ILboolean ReadRGB(PSDHEAD *Head)
|
||||
{
|
||||
ILuint ColorMode, ResourceSize, MiscInfo;
|
||||
ILushort Compressed;
|
||||
ILenum Format, Type;
|
||||
ILubyte *Resources = NULL;
|
||||
|
||||
ColorMode = GetBigUInt(); // Skip over the 'color mode data section'
|
||||
iseek(ColorMode, IL_SEEK_CUR);
|
||||
|
||||
ResourceSize = GetBigUInt(); // Read the 'image resources section'
|
||||
Resources = (ILubyte*)ialloc(ResourceSize);
|
||||
if (Resources == NULL)
|
||||
return IL_FALSE;
|
||||
if (iread(Resources, 1, ResourceSize) != ResourceSize)
|
||||
goto cleanup_error;
|
||||
|
||||
MiscInfo = GetBigUInt();
|
||||
iseek(MiscInfo, IL_SEEK_CUR);
|
||||
|
||||
Compressed = GetBigUShort();
|
||||
|
||||
ChannelNum = Head->Channels;
|
||||
switch (Head->Channels)
|
||||
{
|
||||
case 3:
|
||||
Format = IL_RGB;
|
||||
break;
|
||||
case 4:
|
||||
Format = IL_RGBA;
|
||||
break;
|
||||
default:
|
||||
// ilSetError(IL_FORMAT_NOT_SUPPORTED);
|
||||
// return IL_FALSE;
|
||||
//drop additional channels. This is not the 100% correct
|
||||
//way of loading the image, but it is better than loading
|
||||
//the image not at all.
|
||||
Format = IL_RGBA;
|
||||
Head->Channels = 4;
|
||||
}
|
||||
switch (Head->Depth)
|
||||
{
|
||||
case 8:
|
||||
Type = IL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case 16:
|
||||
Type = IL_UNSIGNED_SHORT;
|
||||
break;
|
||||
default:
|
||||
ilSetError(IL_FORMAT_NOT_SUPPORTED);
|
||||
return IL_FALSE;
|
||||
}
|
||||
if (!ilTexImage(Head->Width, Head->Height, 1, (ILubyte)Head->Channels, Format, Type, NULL))
|
||||
goto cleanup_error;
|
||||
if (!PsdGetData(Head, iCurImage->Data, (ILboolean)Compressed))
|
||||
goto cleanup_error;
|
||||
if (!ParseResources(ResourceSize, Resources))
|
||||
goto cleanup_error;
|
||||
ifree(Resources);
|
||||
|
||||
return IL_TRUE;
|
||||
|
||||
cleanup_error:
|
||||
ifree(Resources);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
ILboolean ReadCMYK(PSDHEAD *Head)
|
||||
{
|
||||
ILuint ColorMode, ResourceSize, MiscInfo, Size, i, j;
|
||||
ILushort Compressed;
|
||||
ILenum Format, Type;
|
||||
ILubyte *Resources = NULL, *KChannel = NULL;
|
||||
|
||||
ColorMode = GetBigUInt(); // Skip over the 'color mode data section'
|
||||
iseek(ColorMode, IL_SEEK_CUR);
|
||||
|
||||
ResourceSize = GetBigUInt(); // Read the 'image resources section'
|
||||
Resources = (ILubyte*)ialloc(ResourceSize);
|
||||
if (Resources == NULL) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
if (iread(Resources, 1, ResourceSize) != ResourceSize)
|
||||
goto cleanup_error;
|
||||
|
||||
MiscInfo = GetBigUInt();
|
||||
iseek(MiscInfo, IL_SEEK_CUR);
|
||||
|
||||
Compressed = GetBigUShort();
|
||||
|
||||
switch (Head->Channels)
|
||||
{
|
||||
case 4:
|
||||
Format = IL_RGB;
|
||||
ChannelNum = 4;
|
||||
Head->Channels = 3;
|
||||
break;
|
||||
case 5:
|
||||
Format = IL_RGBA;
|
||||
ChannelNum = 5;
|
||||
Head->Channels = 4;
|
||||
break;
|
||||
default:
|
||||
ilSetError(IL_FORMAT_NOT_SUPPORTED);
|
||||
return IL_FALSE;
|
||||
}
|
||||
switch (Head->Depth)
|
||||
{
|
||||
case 8:
|
||||
Type = IL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case 16:
|
||||
Type = IL_UNSIGNED_SHORT;
|
||||
break;
|
||||
default:
|
||||
ilSetError(IL_FORMAT_NOT_SUPPORTED);
|
||||
return IL_FALSE;
|
||||
}
|
||||
if (!ilTexImage(Head->Width, Head->Height, 1, (ILubyte)Head->Channels, Format, Type, NULL))
|
||||
goto cleanup_error;
|
||||
if (!PsdGetData(Head, iCurImage->Data, (ILboolean)Compressed))
|
||||
goto cleanup_error;
|
||||
|
||||
Size = iCurImage->Bpc * iCurImage->Width * iCurImage->Height;
|
||||
KChannel = (ILubyte*)ialloc(Size);
|
||||
if (KChannel == NULL)
|
||||
goto cleanup_error;
|
||||
if (!GetSingleChannel(Head, KChannel, (ILboolean)Compressed))
|
||||
goto cleanup_error;
|
||||
|
||||
if (Format == IL_RGB) {
|
||||
for (i = 0, j = 0; i < iCurImage->SizeOfData; i += 3, j++) {
|
||||
iCurImage->Data[i ] = (iCurImage->Data[i ] * KChannel[j]) >> 8;
|
||||
iCurImage->Data[i+1] = (iCurImage->Data[i+1] * KChannel[j]) >> 8;
|
||||
iCurImage->Data[i+2] = (iCurImage->Data[i+2] * KChannel[j]) >> 8;
|
||||
}
|
||||
}
|
||||
else { // IL_RGBA
|
||||
// The KChannel array really holds the alpha channel on this one.
|
||||
for (i = 0, j = 0; i < iCurImage->SizeOfData; i += 4, j++) {
|
||||
iCurImage->Data[i ] = (iCurImage->Data[i ] * iCurImage->Data[i+3]) >> 8;
|
||||
iCurImage->Data[i+1] = (iCurImage->Data[i+1] * iCurImage->Data[i+3]) >> 8;
|
||||
iCurImage->Data[i+2] = (iCurImage->Data[i+2] * iCurImage->Data[i+3]) >> 8;
|
||||
iCurImage->Data[i+3] = KChannel[j]; // Swap 'K' with alpha channel.
|
||||
}
|
||||
}
|
||||
|
||||
if (!ParseResources(ResourceSize, Resources))
|
||||
goto cleanup_error;
|
||||
|
||||
ifree(Resources);
|
||||
ifree(KChannel);
|
||||
|
||||
return IL_TRUE;
|
||||
|
||||
cleanup_error:
|
||||
ifree(Resources);
|
||||
ifree(KChannel);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
ILuint *GetCompChanLen(PSDHEAD *Head)
|
||||
{
|
||||
ILushort *RleTable;
|
||||
ILuint *ChanLen, c, i, j;
|
||||
|
||||
RleTable = (ILushort*)ialloc(Head->Height * ChannelNum * sizeof(ILushort));
|
||||
ChanLen = (ILuint*)ialloc(ChannelNum * sizeof(ILuint));
|
||||
if (RleTable == NULL || ChanLen == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (iread(RleTable, sizeof(ILushort), Head->Height * ChannelNum) != Head->Height * ChannelNum) {
|
||||
ifree(RleTable);
|
||||
ifree(ChanLen);
|
||||
return NULL;
|
||||
}
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
for (i = 0; i < Head->Height * ChannelNum; i++) {
|
||||
iSwapUShort(&RleTable[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
imemclear(ChanLen, ChannelNum * sizeof(ILuint));
|
||||
for (c = 0; c < ChannelNum; c++) {
|
||||
j = c * Head->Height;
|
||||
for (i = 0; i < Head->Height; i++) {
|
||||
ChanLen[c] += RleTable[i + j];
|
||||
}
|
||||
}
|
||||
|
||||
ifree(RleTable);
|
||||
|
||||
return ChanLen;
|
||||
}
|
||||
|
||||
|
||||
ILboolean PsdGetData(PSDHEAD *Head, ILvoid *Buffer, ILboolean Compressed)
|
||||
{
|
||||
ILuint c, x, y, i, Size;
|
||||
ILubyte *Channel = NULL;
|
||||
ILushort *ShortPtr;
|
||||
ILbyte HeadByte;
|
||||
ILint Run;
|
||||
ILuint *ChanLen = NULL;
|
||||
ILboolean PreCache = IL_FALSE;
|
||||
|
||||
Channel = (ILubyte*)ialloc(Head->Width * Head->Height * iCurImage->Bpc);
|
||||
if (Channel == NULL) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
ShortPtr = (ILushort*)Channel;
|
||||
|
||||
// @TODO: Add support for this in, though I have yet to run across a .psd
|
||||
// file that uses this.
|
||||
if (Compressed && iCurImage->Type == IL_UNSIGNED_SHORT) {
|
||||
ilSetError(IL_FORMAT_NOT_SUPPORTED);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
if (!Compressed) {
|
||||
if (iCurImage->Bpc == 1) {
|
||||
for (c = 0; c < Head->Channels; c++) {
|
||||
i = 0;
|
||||
if (iread(Channel, Head->Width * Head->Height, 1) != 1) {
|
||||
ifree(Channel);
|
||||
return IL_FALSE;
|
||||
}
|
||||
for (y = 0; y < Head->Height * iCurImage->Bps; y += iCurImage->Bps) {
|
||||
for (x = 0; x < iCurImage->Bps; x += iCurImage->Bpp, i++) {
|
||||
iCurImage->Data[y + x + c] = Channel[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // iCurImage->Bpc == 2
|
||||
for (c = 0; c < Head->Channels; c++) {
|
||||
i = 0;
|
||||
if (iread(Channel, Head->Width * Head->Height * 2, 1) != 1) {
|
||||
ifree(Channel);
|
||||
return IL_FALSE;
|
||||
}
|
||||
iCurImage->Bps /= 2;
|
||||
for (y = 0; y < Head->Height * iCurImage->Bps; y += iCurImage->Bps) {
|
||||
for (x = 0; x < iCurImage->Bps; x += iCurImage->Bpp, i++) {
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
iSwapUShort(ShortPtr+i);
|
||||
#endif
|
||||
((ILushort*)iCurImage->Data)[y + x + c] = ShortPtr[i];
|
||||
}
|
||||
}
|
||||
iCurImage->Bps *= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ChanLen = GetCompChanLen(Head);
|
||||
if (iGetHint(IL_MEM_SPEED_HINT) == IL_FASTEST)
|
||||
PreCache = IL_TRUE;
|
||||
|
||||
Size = Head->Width * Head->Height;
|
||||
for (c = 0; c < Head->Channels; c++) {
|
||||
if (PreCache)
|
||||
iPreCache(ChanLen[c]);
|
||||
for (i = 0; i < Size; ) {
|
||||
HeadByte = igetc();
|
||||
|
||||
if (HeadByte >= 0) { // && HeadByte <= 127
|
||||
if (i + HeadByte > Size)
|
||||
goto file_corrupt;
|
||||
if (iread(Channel + i, HeadByte + 1, 1) != 1)
|
||||
goto file_read_error;
|
||||
|
||||
i += HeadByte + 1;
|
||||
}
|
||||
if (HeadByte >= -127 && HeadByte <= -1) {
|
||||
Run = igetc();
|
||||
if (Run == IL_EOF)
|
||||
goto file_read_error;
|
||||
if (i + (-HeadByte + 1) > Size)
|
||||
goto file_corrupt;
|
||||
|
||||
memset(Channel + i, Run, -HeadByte + 1);
|
||||
i += -HeadByte + 1;
|
||||
}
|
||||
if (HeadByte == -128)
|
||||
{ } // Noop
|
||||
}
|
||||
if (PreCache)
|
||||
iUnCache();
|
||||
|
||||
i = 0;
|
||||
for (y = 0; y < Head->Height * iCurImage->Bps; y += iCurImage->Bps) {
|
||||
for (x = 0; x < iCurImage->Bps; x += iCurImage->Bpp, i++) {
|
||||
iCurImage->Data[y + x + c] = Channel[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ifree(ChanLen);
|
||||
}
|
||||
|
||||
ifree(Channel);
|
||||
|
||||
return IL_TRUE;
|
||||
|
||||
file_corrupt:
|
||||
ifree(ChanLen);
|
||||
ifree(Channel);
|
||||
if (PreCache)
|
||||
iUnCache();
|
||||
ilSetError(IL_ILLEGAL_FILE_VALUE);
|
||||
return IL_FALSE;
|
||||
|
||||
file_read_error:
|
||||
ifree(ChanLen);
|
||||
ifree(Channel);
|
||||
if (PreCache)
|
||||
iUnCache();
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
ILboolean ParseResources(ILuint ResourceSize, ILubyte *Resources)
|
||||
{
|
||||
ILushort ID;
|
||||
ILubyte NameLen;
|
||||
ILuint Size;
|
||||
|
||||
if (Resources == NULL) {
|
||||
ilSetError(IL_INTERNAL_ERROR);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
while (ResourceSize) {
|
||||
if (strncmp("8BIM", (const char*)Resources, 4)) {
|
||||
//return IL_FALSE;
|
||||
return IL_TRUE; // 05-30-2002: May not necessarily mean corrupt data...
|
||||
}
|
||||
Resources += 4;
|
||||
|
||||
ID = *((ILushort*)Resources);
|
||||
BigUShort(&ID);
|
||||
Resources += 2;
|
||||
|
||||
NameLen = *Resources++;
|
||||
// NameLen + the byte it occupies must be padded to an even number, so NameLen must be odd.
|
||||
NameLen = NameLen + (NameLen & 1 ? 0 : 1);
|
||||
Resources += NameLen;
|
||||
|
||||
// Get the resource data size.
|
||||
Size = *((ILuint*)Resources);
|
||||
BigUInt(&Size);
|
||||
Resources += 4;
|
||||
|
||||
ResourceSize -= (4 + 2 + 1 + NameLen);
|
||||
|
||||
switch (ID)
|
||||
{
|
||||
case 0x040F: // ICC Profile
|
||||
iCurImage->Profile = (ILubyte*)ialloc(Size);
|
||||
if (iCurImage->Profile == NULL) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
memcpy(iCurImage->Profile, Resources, Size);
|
||||
iCurImage->ProfileSize = Size;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (Size & 1) // Must be an even number.
|
||||
Size++;
|
||||
ResourceSize -= Size;
|
||||
Resources += Size;
|
||||
}
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
ILboolean GetSingleChannel(PSDHEAD *Head, ILubyte *Buffer, ILboolean Compressed)
|
||||
{
|
||||
ILuint i;
|
||||
ILushort *ShortPtr;
|
||||
ILbyte HeadByte;
|
||||
ILint Run;
|
||||
|
||||
ShortPtr = (ILushort*)Buffer;
|
||||
|
||||
if (!Compressed) {
|
||||
if (iCurImage->Bpc == 1) {
|
||||
if (iread(Buffer, Head->Width * Head->Height, 1) != 1)
|
||||
return IL_FALSE;
|
||||
}
|
||||
else { // iCurImage->Bpc == 2
|
||||
if (iread(Buffer, Head->Width * Head->Height * 2, 1) != 1)
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < Head->Width * Head->Height; ) {
|
||||
HeadByte = igetc();
|
||||
|
||||
if (HeadByte >= 0) { // && HeadByte <= 127
|
||||
if (iread(Buffer + i, HeadByte + 1, 1) != 1)
|
||||
return IL_FALSE;
|
||||
i += HeadByte + 1;
|
||||
}
|
||||
if (HeadByte >= -127 && HeadByte <= -1) {
|
||||
Run = igetc();
|
||||
if (Run == IL_EOF)
|
||||
return IL_FALSE;
|
||||
memset(Buffer + i, Run, -HeadByte + 1);
|
||||
i += -HeadByte + 1;
|
||||
}
|
||||
if (HeadByte == -128)
|
||||
{ } // Noop
|
||||
}
|
||||
}
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Writes a Psd file
|
||||
ILboolean ilSavePsd(ILconst_string FileName)
|
||||
{
|
||||
ILHANDLE PsdFile;
|
||||
ILboolean bPsd = IL_FALSE;
|
||||
|
||||
if (ilGetBoolean(IL_FILE_MODE) == IL_FALSE) {
|
||||
if (iFileExists(FileName)) {
|
||||
ilSetError(IL_FILE_ALREADY_EXISTS);
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
PsdFile = iopenw(FileName);
|
||||
if (PsdFile == NULL) {
|
||||
ilSetError(IL_COULD_NOT_OPEN_FILE);
|
||||
return bPsd;
|
||||
}
|
||||
|
||||
bPsd = ilSavePsdF(PsdFile);
|
||||
iclosew(PsdFile);
|
||||
|
||||
return bPsd;
|
||||
}
|
||||
|
||||
|
||||
//! Writes a Psd to an already-opened file
|
||||
ILboolean ilSavePsdF(ILHANDLE File)
|
||||
{
|
||||
iSetOutputFile(File);
|
||||
return iSavePsdInternal();
|
||||
}
|
||||
|
||||
|
||||
//! Writes a Psd to a memory "lump"
|
||||
ILboolean ilSavePsdL(ILvoid *Lump, ILuint Size)
|
||||
{
|
||||
iSetOutputLump(Lump, Size);
|
||||
return iSavePsdInternal();
|
||||
}
|
||||
|
||||
|
||||
// Internal function used to save the Psd.
|
||||
ILboolean iSavePsdInternal()
|
||||
{
|
||||
ILubyte *Signature = (ILubyte*)"8BPS";
|
||||
ILimage *TempImage;
|
||||
ILpal *TempPal;
|
||||
ILuint c, i;
|
||||
ILubyte *TempData;
|
||||
ILushort *ShortPtr;
|
||||
ILenum Format, Type;
|
||||
|
||||
if (iCurImage == NULL) {
|
||||
ilSetError(IL_ILLEGAL_OPERATION);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
Format = iCurImage->Format;
|
||||
Type = iCurImage->Type;
|
||||
|
||||
// All of these comprise the actual signature.
|
||||
iwrite(Signature, 1, 4);
|
||||
SaveBigShort(1);
|
||||
SaveBigInt(0);
|
||||
SaveBigShort(0);
|
||||
|
||||
SaveBigShort(iCurImage->Bpp);
|
||||
SaveBigInt(iCurImage->Height);
|
||||
SaveBigInt(iCurImage->Width);
|
||||
if (iCurImage->Bpc > 2)
|
||||
Type = IL_UNSIGNED_SHORT;
|
||||
|
||||
if (iCurImage->Format == IL_BGR)
|
||||
Format = IL_RGB;
|
||||
else if (iCurImage->Format == IL_BGRA)
|
||||
Format = IL_RGBA;
|
||||
|
||||
if (Format != iCurImage->Format || Type != iCurImage->Type) {
|
||||
TempImage = iConvertImage(iCurImage, Format, Type);
|
||||
if (TempImage == NULL)
|
||||
return IL_FALSE;
|
||||
}
|
||||
else {
|
||||
TempImage = iCurImage;
|
||||
}
|
||||
SaveBigShort((ILushort)(TempImage->Bpc * 8));
|
||||
|
||||
// @TODO: Put the other formats here.
|
||||
switch (TempImage->Format)
|
||||
{
|
||||
case IL_COLOUR_INDEX:
|
||||
SaveBigShort(2);
|
||||
break;
|
||||
case IL_LUMINANCE:
|
||||
SaveBigShort(1);
|
||||
break;
|
||||
case IL_RGB:
|
||||
case IL_RGBA:
|
||||
SaveBigShort(3);
|
||||
break;
|
||||
default:
|
||||
ilSetError(IL_INTERNAL_ERROR);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
if (TempImage->Format == IL_COLOUR_INDEX) {
|
||||
// @TODO: We're currently making a potentially fatal assumption that
|
||||
// iConvertImage was not called if the format is IL_COLOUR_INDEX.
|
||||
TempPal = iConvertPal(&TempImage->Pal, IL_PAL_RGB24);
|
||||
if (TempPal == NULL)
|
||||
return IL_FALSE;
|
||||
SaveBigInt(768);
|
||||
|
||||
// Have to save the palette in a planar format.
|
||||
for (c = 0; c < 3; c++) {
|
||||
for (i = c; i < TempPal->PalSize; i += 3) {
|
||||
iputc(TempPal->Palette[i]);
|
||||
}
|
||||
}
|
||||
|
||||
ifree(TempPal->Palette);
|
||||
}
|
||||
else {
|
||||
SaveBigInt(0); // No colour mode data.
|
||||
}
|
||||
|
||||
SaveBigInt(0); // No image resources.
|
||||
SaveBigInt(0); // No layer information.
|
||||
SaveBigShort(0); // Raw data, no compression.
|
||||
|
||||
// @TODO: Add RLE compression.
|
||||
|
||||
if (TempImage->Origin == IL_ORIGIN_LOWER_LEFT) {
|
||||
TempData = iGetFlipped(TempImage);
|
||||
if (TempData == NULL) {
|
||||
ilCloseImage(TempImage);
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
TempData = TempImage->Data;
|
||||
}
|
||||
|
||||
if (TempImage->Bpc == 1) {
|
||||
for (c = 0; c < TempImage->Bpp; c++) {
|
||||
for (i = c; i < TempImage->SizeOfPlane; i += TempImage->Bpp) {
|
||||
iputc(TempData[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // TempImage->Bpc == 2
|
||||
ShortPtr = (ILushort*)TempData;
|
||||
TempImage->SizeOfPlane /= 2;
|
||||
for (c = 0; c < TempImage->Bpp; c++) {
|
||||
for (i = c; i < TempImage->SizeOfPlane; i += TempImage->Bpp) {
|
||||
SaveBigUShort(ShortPtr[i]);
|
||||
}
|
||||
}
|
||||
TempImage->SizeOfPlane *= 2;
|
||||
}
|
||||
|
||||
if (TempData != TempImage->Data)
|
||||
ifree(TempData);
|
||||
|
||||
if (TempImage != iCurImage)
|
||||
ilCloseImage(TempImage);
|
||||
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
#endif//IL_NO_PSD
|
||||
713
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_psp.c
Normal file
713
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_psp.c
Normal file
@@ -0,0 +1,713 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2002 by Denton Woods
|
||||
// Last modified: 05/04/2002 <--Y2K Compliant! =]
|
||||
//
|
||||
// Filename: src-IL/src/il_psp.c
|
||||
//
|
||||
// Description: Reads a Paint Shop Pro file.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "il_internal.h"
|
||||
#include "il_psp.h"
|
||||
#ifndef IL_NO_PSP
|
||||
|
||||
|
||||
ILubyte PSPSignature[32] = {
|
||||
0x50, 0x61, 0x69, 0x6E, 0x74, 0x20, 0x53, 0x68, 0x6F, 0x70, 0x20, 0x50, 0x72, 0x6F, 0x20, 0x49,
|
||||
0x6D, 0x61, 0x67, 0x65, 0x20, 0x46, 0x69, 0x6C, 0x65, 0x0A, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
ILubyte GenAttHead[4] = {
|
||||
0x7E, 0x42, 0x4B, 0x00
|
||||
};
|
||||
|
||||
|
||||
// Make these global, since they contain most of the image information.
|
||||
GENATT_CHUNK AttChunk;
|
||||
PSPHEAD Header;
|
||||
ILuint NumChannels;
|
||||
ILubyte **Channels = NULL;
|
||||
ILubyte *Alpha = NULL;
|
||||
ILpal Pal;
|
||||
|
||||
|
||||
|
||||
//! Checks if the file specified in FileName is a valid Psp file.
|
||||
ILboolean ilIsValidPsp(ILconst_string FileName)
|
||||
{
|
||||
ILHANDLE PspFile;
|
||||
ILboolean bPsp = IL_FALSE;
|
||||
|
||||
if (!iCheckExtension(FileName, IL_TEXT("psp"))) {
|
||||
ilSetError(IL_INVALID_EXTENSION);
|
||||
return bPsp;
|
||||
}
|
||||
|
||||
PspFile = iopenr(FileName);
|
||||
if (PspFile == NULL) {
|
||||
ilSetError(IL_COULD_NOT_OPEN_FILE);
|
||||
return bPsp;
|
||||
}
|
||||
|
||||
bPsp = ilIsValidPspF(PspFile);
|
||||
icloser(PspFile);
|
||||
|
||||
return bPsp;
|
||||
}
|
||||
|
||||
|
||||
//! Checks if the ILHANDLE contains a valid Psp file at the current position.
|
||||
ILboolean ilIsValidPspF(ILHANDLE File)
|
||||
{
|
||||
ILuint FirstPos;
|
||||
ILboolean bRet;
|
||||
|
||||
iSetInputFile(File);
|
||||
FirstPos = itell();
|
||||
bRet = iIsValidPsp();
|
||||
iseek(FirstPos, IL_SEEK_SET);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
//! Checks if Lump is a valid Psp lump.
|
||||
ILboolean ilIsValidPspL(const ILvoid *Lump, ILuint Size)
|
||||
{
|
||||
iSetInputLump(Lump, Size);
|
||||
return iIsValidPsp();
|
||||
}
|
||||
|
||||
|
||||
// Internal function used to get the Psp header from the current file.
|
||||
ILboolean iGetPspHead()
|
||||
{
|
||||
if (iread(Header.FileSig, 1, 32) != 32)
|
||||
return IL_FALSE;
|
||||
Header.MajorVersion = GetLittleUShort();
|
||||
Header.MinorVersion = GetLittleUShort();
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Internal function to get the header and check it.
|
||||
ILboolean iIsValidPsp()
|
||||
{
|
||||
if (!iGetPspHead())
|
||||
return IL_FALSE;
|
||||
iseek(-(ILint)sizeof(PSPHEAD), IL_SEEK_CUR);
|
||||
|
||||
return iCheckPsp();
|
||||
}
|
||||
|
||||
|
||||
// Internal function used to check if the HEADER is a valid Psp header.
|
||||
ILboolean iCheckPsp()
|
||||
{
|
||||
if (stricmp(Header.FileSig, "Paint Shop Pro Image File\n\x1a"))
|
||||
return IL_FALSE;
|
||||
if (Header.MajorVersion < 3 || Header.MajorVersion > 5)
|
||||
return IL_FALSE;
|
||||
if (Header.MinorVersion != 0)
|
||||
return IL_FALSE;
|
||||
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
//! Reads a PSP file
|
||||
ILboolean ilLoadPsp(ILconst_string FileName)
|
||||
{
|
||||
ILHANDLE PSPFile;
|
||||
ILboolean bPsp = IL_FALSE;
|
||||
|
||||
PSPFile = iopenr(FileName);
|
||||
if (PSPFile == NULL) {
|
||||
ilSetError(IL_COULD_NOT_OPEN_FILE);
|
||||
return bPsp;
|
||||
}
|
||||
|
||||
bPsp = ilLoadPspF(PSPFile);
|
||||
icloser(PSPFile);
|
||||
|
||||
return bPsp;
|
||||
}
|
||||
|
||||
|
||||
//! Reads an already-opened PSP file
|
||||
ILboolean ilLoadPspF(ILHANDLE File)
|
||||
{
|
||||
ILuint FirstPos;
|
||||
ILboolean bRet;
|
||||
|
||||
iSetInputFile(File);
|
||||
FirstPos = itell();
|
||||
bRet = iLoadPspInternal();
|
||||
iseek(FirstPos, IL_SEEK_SET);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
//! Reads from a memory "lump" that contains a PSP
|
||||
ILboolean ilLoadPspL(const ILvoid *Lump, ILuint Size)
|
||||
{
|
||||
iSetInputLump(Lump, Size);
|
||||
return iLoadPspInternal();
|
||||
}
|
||||
|
||||
|
||||
// Internal function used to load the PSP.
|
||||
ILboolean iLoadPspInternal()
|
||||
{
|
||||
if (iCurImage == NULL) {
|
||||
ilSetError(IL_ILLEGAL_OPERATION);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
Channels = NULL;
|
||||
Alpha = NULL;
|
||||
Pal.Palette = NULL;
|
||||
|
||||
if (!iGetPspHead())
|
||||
return IL_FALSE;
|
||||
if (!iCheckPsp()) {
|
||||
ilSetError(IL_INVALID_FILE_HEADER);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
if (!ReadGenAttributes())
|
||||
return IL_FALSE;
|
||||
if (!ParseChunks())
|
||||
return IL_FALSE;
|
||||
if (!AssembleImage())
|
||||
return IL_FALSE;
|
||||
|
||||
Cleanup();
|
||||
ilFixImage();
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
ILboolean ReadGenAttributes()
|
||||
{
|
||||
BLOCKHEAD AttHead;
|
||||
ILint Padding;
|
||||
ILuint ChunkLen;
|
||||
|
||||
if (iread(&AttHead, sizeof(AttHead), 1) != 1)
|
||||
return IL_FALSE;
|
||||
UShort(&AttHead.BlockID);
|
||||
UInt(&AttHead.BlockLen);
|
||||
|
||||
if (AttHead.HeadID[0] != 0x7E || AttHead.HeadID[1] != 0x42 ||
|
||||
AttHead.HeadID[2] != 0x4B || AttHead.HeadID[3] != 0x00) {
|
||||
ilSetError(IL_INVALID_FILE_HEADER);
|
||||
return IL_FALSE;
|
||||
}
|
||||
if (AttHead.BlockID != PSP_IMAGE_BLOCK) {
|
||||
ilSetError(IL_INVALID_FILE_HEADER);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
ChunkLen = GetLittleUInt();
|
||||
if (Header.MajorVersion != 3)
|
||||
ChunkLen -= 4;
|
||||
if (iread(&AttChunk, IL_MIN(sizeof(AttChunk), ChunkLen), 1) != 1)
|
||||
return IL_FALSE;
|
||||
|
||||
// Can have new entries in newer versions of the spec (4.0).
|
||||
Padding = (ChunkLen) - sizeof(AttChunk);
|
||||
if (Padding > 0)
|
||||
iseek(Padding, IL_SEEK_CUR);
|
||||
|
||||
// @TODO: Anything but 24 not supported yet...
|
||||
if (AttChunk.BitDepth != 24 && AttChunk.BitDepth != 8) {
|
||||
ilSetError(IL_INVALID_FILE_HEADER);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
// @TODO; Add support for compression...
|
||||
if (AttChunk.Compression != PSP_COMP_NONE && AttChunk.Compression != PSP_COMP_RLE) {
|
||||
ilSetError(IL_INVALID_FILE_HEADER);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
// @TODO: Check more things in the general attributes chunk here.
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
ILboolean ParseChunks()
|
||||
{
|
||||
BLOCKHEAD Block;
|
||||
ILuint Pos;
|
||||
|
||||
do {
|
||||
if (iread(&Block, 1, sizeof(Block)) != sizeof(Block)) {
|
||||
ilGetError(); // Get rid of the erroneous IL_FILE_READ_ERROR.
|
||||
return IL_TRUE;
|
||||
}
|
||||
if (Header.MajorVersion == 3)
|
||||
Block.BlockLen = GetLittleUInt();
|
||||
else
|
||||
UInt(&Block.BlockLen);
|
||||
|
||||
if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 ||
|
||||
Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00) {
|
||||
return IL_TRUE;
|
||||
}
|
||||
UShort(&Block.BlockID);
|
||||
UInt(&Block.BlockLen);
|
||||
|
||||
Pos = itell();
|
||||
|
||||
switch (Block.BlockID)
|
||||
{
|
||||
case PSP_LAYER_START_BLOCK:
|
||||
if (!ReadLayerBlock(Block.BlockLen))
|
||||
return IL_FALSE;
|
||||
break;
|
||||
|
||||
case PSP_ALPHA_BANK_BLOCK:
|
||||
if (!ReadAlphaBlock(Block.BlockLen))
|
||||
return IL_FALSE;
|
||||
break;
|
||||
|
||||
case PSP_COLOR_BLOCK:
|
||||
if (!ReadPalette(Block.BlockLen))
|
||||
return IL_FALSE;
|
||||
break;
|
||||
|
||||
// Gets done in the next iseek, so this is now commented out.
|
||||
//default:
|
||||
//iseek(Block.BlockLen, IL_SEEK_CUR);
|
||||
}
|
||||
|
||||
// Skip to next block just in case we didn't read the entire block.
|
||||
iseek(Pos + Block.BlockLen, IL_SEEK_SET);
|
||||
|
||||
// @TODO: Do stuff here.
|
||||
|
||||
} while (1);
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
ILboolean ReadLayerBlock(ILuint BlockLen)
|
||||
{
|
||||
BLOCKHEAD Block;
|
||||
LAYERINFO_CHUNK LayerInfo;
|
||||
LAYERBITMAP_CHUNK Bitmap;
|
||||
ILuint ChunkSize, Padding, i, j;
|
||||
ILushort NumChars;
|
||||
|
||||
|
||||
// Layer sub-block header
|
||||
if (iread(&Block, 1, sizeof(Block)) != sizeof(Block))
|
||||
return IL_FALSE;
|
||||
if (Header.MajorVersion == 3)
|
||||
Block.BlockLen = GetLittleUInt();
|
||||
else
|
||||
UInt(&Block.BlockLen);
|
||||
|
||||
if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 ||
|
||||
Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
if (Block.BlockID != PSP_LAYER_BLOCK)
|
||||
return IL_FALSE;
|
||||
|
||||
|
||||
if (Header.MajorVersion == 3) {
|
||||
iseek(256, IL_SEEK_CUR); // We don't care about the name of the layer.
|
||||
iread(&LayerInfo, sizeof(LayerInfo), 1);
|
||||
if (iread(&Bitmap, sizeof(Bitmap), 1) != 1)
|
||||
return IL_FALSE;
|
||||
}
|
||||
else { // Header.MajorVersion >= 4
|
||||
ChunkSize = GetLittleUInt();
|
||||
NumChars = GetLittleUShort();
|
||||
iseek(NumChars, IL_SEEK_CUR); // We don't care about the layer's name.
|
||||
|
||||
ChunkSize -= (2 + 4 + NumChars);
|
||||
|
||||
if (iread(&LayerInfo, IL_MIN(sizeof(LayerInfo), ChunkSize), 1) != 1)
|
||||
return IL_FALSE;
|
||||
|
||||
// Can have new entries in newer versions of the spec (5.0).
|
||||
Padding = (ChunkSize) - sizeof(LayerInfo);
|
||||
if (Padding > 0)
|
||||
iseek(Padding, IL_SEEK_CUR);
|
||||
|
||||
ChunkSize = GetLittleUInt();
|
||||
if (iread(&Bitmap, sizeof(Bitmap), 1) != 1)
|
||||
return IL_FALSE;
|
||||
Padding = (ChunkSize - 4) - sizeof(Bitmap);
|
||||
if (Padding > 0)
|
||||
iseek(Padding, IL_SEEK_CUR);
|
||||
}
|
||||
|
||||
|
||||
Channels = (ILubyte**)ialloc(sizeof(ILubyte*) * Bitmap.NumChannels);
|
||||
if (Channels == NULL) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
NumChannels = Bitmap.NumChannels;
|
||||
|
||||
for (i = 0; i < NumChannels; i++) {
|
||||
Channels[i] = GetChannel();
|
||||
if (Channels[i] == NULL) {
|
||||
for (j = 0; j < i; j++)
|
||||
ifree(Channels[j]);
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
ILboolean ReadAlphaBlock(ILuint BlockLen)
|
||||
{
|
||||
BLOCKHEAD Block;
|
||||
ALPHAINFO_CHUNK AlphaInfo;
|
||||
ALPHA_CHUNK AlphaChunk;
|
||||
ILushort NumAlpha, StringSize;
|
||||
ILuint ChunkSize, Padding;
|
||||
|
||||
if (Header.MajorVersion == 3) {
|
||||
NumAlpha = GetLittleUShort();
|
||||
}
|
||||
else {
|
||||
ChunkSize = GetLittleUInt();
|
||||
NumAlpha = GetLittleUShort();
|
||||
Padding = (ChunkSize - 4 - 2);
|
||||
if (Padding > 0)
|
||||
iseek(Padding, IL_SEEK_CUR);
|
||||
}
|
||||
|
||||
// Alpha channel header
|
||||
if (iread(&Block, 1, sizeof(Block)) != sizeof(Block))
|
||||
return IL_FALSE;
|
||||
if (Header.MajorVersion == 3)
|
||||
Block.BlockLen = GetLittleUInt();
|
||||
else
|
||||
UInt(&Block.BlockLen);
|
||||
|
||||
if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 ||
|
||||
Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
if (Block.BlockID != PSP_ALPHA_CHANNEL_BLOCK)
|
||||
return IL_FALSE;
|
||||
|
||||
|
||||
if (Header.MajorVersion >= 4) {
|
||||
ChunkSize = GetLittleUInt();
|
||||
StringSize = GetLittleUShort();
|
||||
iseek(StringSize, IL_SEEK_CUR);
|
||||
if (iread(&AlphaInfo, sizeof(AlphaInfo), 1) != 1)
|
||||
return IL_FALSE;
|
||||
Padding = (ChunkSize - 4 - 2 - StringSize - sizeof(AlphaInfo));
|
||||
if (Padding > 0)
|
||||
iseek(Padding, IL_SEEK_CUR);
|
||||
|
||||
ChunkSize = GetLittleUInt();
|
||||
if (iread(&AlphaChunk, sizeof(AlphaChunk), 1) != 1)
|
||||
return IL_FALSE;
|
||||
Padding = (ChunkSize - 4 - sizeof(AlphaChunk));
|
||||
if (Padding > 0)
|
||||
iseek(Padding, IL_SEEK_CUR);
|
||||
}
|
||||
else {
|
||||
iseek(256, IL_SEEK_CUR);
|
||||
iread(&AlphaInfo, sizeof(AlphaInfo), 1);
|
||||
if (iread(&AlphaChunk, sizeof(AlphaChunk), 1) != 1)
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*Alpha = (ILubyte*)ialloc(AlphaInfo.AlphaRect.x2 * AlphaInfo.AlphaRect.y2);
|
||||
if (Alpha == NULL) {
|
||||
return IL_FALSE;
|
||||
}*/
|
||||
|
||||
|
||||
Alpha = GetChannel();
|
||||
if (Alpha == NULL)
|
||||
return IL_FALSE;
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
ILubyte *GetChannel()
|
||||
{
|
||||
BLOCKHEAD Block;
|
||||
CHANNEL_CHUNK Channel;
|
||||
ILubyte *CompData, *Data;
|
||||
ILuint ChunkSize, Padding;
|
||||
|
||||
if (iread(&Block, 1, sizeof(Block)) != sizeof(Block))
|
||||
return NULL;
|
||||
if (Header.MajorVersion == 3)
|
||||
Block.BlockLen = GetLittleUInt();
|
||||
else
|
||||
UInt(&Block.BlockLen);
|
||||
|
||||
if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 ||
|
||||
Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00) {
|
||||
ilSetError(IL_ILLEGAL_FILE_VALUE);
|
||||
return NULL;
|
||||
}
|
||||
if (Block.BlockID != PSP_CHANNEL_BLOCK) {
|
||||
ilSetError(IL_ILLEGAL_FILE_VALUE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if (Header.MajorVersion >= 4) {
|
||||
ChunkSize = GetLittleUInt();
|
||||
if (iread(&Channel, sizeof(Channel), 1) != 1)
|
||||
return NULL;
|
||||
|
||||
Padding = (ChunkSize - 4) - sizeof(Channel);
|
||||
if (Padding > 0)
|
||||
iseek(Padding, IL_SEEK_CUR);
|
||||
}
|
||||
else {
|
||||
if (iread(&Channel, sizeof(Channel), 1) != 1)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
CompData = (ILubyte*)ialloc(Channel.CompLen);
|
||||
Data = (ILubyte*)ialloc(AttChunk.Width * AttChunk.Height);
|
||||
if (CompData == NULL || Data == NULL) {
|
||||
ifree(Data);
|
||||
ifree(CompData);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (iread(CompData, 1, Channel.CompLen) != Channel.CompLen) {
|
||||
ifree(CompData);
|
||||
ifree(Data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (AttChunk.Compression)
|
||||
{
|
||||
case PSP_COMP_NONE:
|
||||
ifree(Data);
|
||||
return CompData;
|
||||
break;
|
||||
|
||||
case PSP_COMP_RLE:
|
||||
if (!UncompRLE(CompData, Data, Channel.CompLen)) {
|
||||
ifree(CompData);
|
||||
ifree(Data);
|
||||
return IL_FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ifree(CompData);
|
||||
ifree(Data);
|
||||
ilSetError(IL_INVALID_FILE_HEADER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ifree(CompData);
|
||||
|
||||
return Data;
|
||||
}
|
||||
|
||||
|
||||
ILboolean UncompRLE(ILubyte *CompData, ILubyte *Data, ILuint CompLen)
|
||||
{
|
||||
ILubyte Run, Colour;
|
||||
ILint i, /*x, y,*/ Count/*, Total = 0*/;
|
||||
|
||||
/*for (y = 0; y < AttChunk.Height; y++) {
|
||||
for (x = 0, Count = 0; x < AttChunk.Width; ) {
|
||||
Run = *CompData++;
|
||||
if (Run > 128) {
|
||||
Run -= 128;
|
||||
Colour = *CompData++;
|
||||
memset(Data, Colour, Run);
|
||||
Data += Run;
|
||||
Count += 2;
|
||||
}
|
||||
else {
|
||||
memcpy(Data, CompData, Run);
|
||||
CompData += Run;
|
||||
Data += Run;
|
||||
Count += Run;
|
||||
}
|
||||
x += Run;
|
||||
}
|
||||
|
||||
Total += Count;
|
||||
|
||||
if (Count % 4) { // Has to be on a 4-byte boundary.
|
||||
CompData += (4 - (Count % 4)) % 4;
|
||||
Total += (4 - (Count % 4)) % 4;
|
||||
}
|
||||
|
||||
if (Total >= CompLen)
|
||||
return IL_FALSE;
|
||||
}*/
|
||||
|
||||
for (i = 0, Count = 0; i < (ILint)CompLen; ) {
|
||||
Run = *CompData++;
|
||||
i++;
|
||||
if (Run > 128) {
|
||||
Run -= 128;
|
||||
Colour = *CompData++;
|
||||
i++;
|
||||
memset(Data, Colour, Run);
|
||||
}
|
||||
else {
|
||||
memcpy(Data, CompData, Run);
|
||||
CompData += Run;
|
||||
i += Run;
|
||||
}
|
||||
Data += Run;
|
||||
Count += Run;
|
||||
}
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
ILboolean ReadPalette(ILuint BlockLen)
|
||||
{
|
||||
ILuint ChunkSize, PalCount, Padding;
|
||||
|
||||
if (Header.MajorVersion >= 4) {
|
||||
ChunkSize = GetLittleUInt();
|
||||
PalCount = GetLittleUInt();
|
||||
Padding = (ChunkSize - 4 - 4);
|
||||
if (Padding > 0)
|
||||
iseek(Padding, IL_SEEK_CUR);
|
||||
}
|
||||
else {
|
||||
PalCount = GetLittleUInt();
|
||||
}
|
||||
|
||||
Pal.PalSize = PalCount * 4;
|
||||
Pal.PalType = IL_PAL_BGRA32;
|
||||
Pal.Palette = (ILubyte*)ialloc(Pal.PalSize);
|
||||
if (Pal.Palette == NULL)
|
||||
return IL_FALSE;
|
||||
|
||||
if (iread(Pal.Palette, Pal.PalSize, 1) != 1) {
|
||||
ifree(Pal.Palette);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
ILboolean AssembleImage()
|
||||
{
|
||||
ILuint Size, i, j;
|
||||
|
||||
Size = AttChunk.Width * AttChunk.Height;
|
||||
|
||||
if (NumChannels == 1) {
|
||||
ilTexImage(AttChunk.Width, AttChunk.Height, 1, 1, IL_LUMINANCE, IL_UNSIGNED_BYTE, NULL);
|
||||
for (i = 0; i < Size; i++) {
|
||||
iCurImage->Data[i] = Channels[0][i];
|
||||
}
|
||||
|
||||
if (Pal.Palette) {
|
||||
iCurImage->Format = IL_COLOUR_INDEX;
|
||||
iCurImage->Pal.PalSize = Pal.PalSize;
|
||||
iCurImage->Pal.PalType = Pal.PalType;
|
||||
iCurImage->Pal.Palette = Pal.Palette;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (Alpha) {
|
||||
ilTexImage(AttChunk.Width, AttChunk.Height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL);
|
||||
for (i = 0, j = 0; i < Size; i++, j += 4) {
|
||||
iCurImage->Data[j ] = Channels[0][i];
|
||||
iCurImage->Data[j+1] = Channels[1][i];
|
||||
iCurImage->Data[j+2] = Channels[2][i];
|
||||
iCurImage->Data[j+3] = Alpha[i];
|
||||
}
|
||||
}
|
||||
|
||||
else if (NumChannels == 4) {
|
||||
|
||||
ilTexImage(AttChunk.Width, AttChunk.Height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
for (i = 0, j = 0; i < Size; i++, j += 4) {
|
||||
|
||||
iCurImage->Data[j ] = Channels[0][i];
|
||||
|
||||
iCurImage->Data[j+1] = Channels[1][i];
|
||||
|
||||
iCurImage->Data[j+2] = Channels[2][i];
|
||||
|
||||
iCurImage->Data[j+3] = Channels[3][i];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else if (NumChannels == 3) {
|
||||
ilTexImage(AttChunk.Width, AttChunk.Height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL);
|
||||
for (i = 0, j = 0; i < Size; i++, j += 3) {
|
||||
iCurImage->Data[j ] = Channels[0][i];
|
||||
iCurImage->Data[j+1] = Channels[1][i];
|
||||
iCurImage->Data[j+2] = Channels[2][i];
|
||||
}
|
||||
}
|
||||
else
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
ILboolean Cleanup()
|
||||
{
|
||||
ILuint i;
|
||||
|
||||
if (Channels) {
|
||||
for (i = 0; i < NumChannels; i++) {
|
||||
ifree(Channels[i]);
|
||||
}
|
||||
ifree(Channels);
|
||||
}
|
||||
|
||||
if (Alpha) {
|
||||
ifree(Alpha);
|
||||
}
|
||||
|
||||
Channels = NULL;
|
||||
Alpha = NULL;
|
||||
Pal.Palette = NULL;
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif//IL_NO_PSP
|
||||
120
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_pxr.c
Normal file
120
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_pxr.c
Normal file
@@ -0,0 +1,120 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2002 by Denton Woods
|
||||
// Last modified: 05/26/2002 <--Y2K Compliant! =]
|
||||
//
|
||||
// Filename: src-IL/src/il_pxr.c
|
||||
//
|
||||
// Description: Reads from a Pxrar (.pxr) file.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "il_internal.h"
|
||||
#ifndef IL_NO_PXR
|
||||
#include "il_manip.h"
|
||||
#include "il_endian.h"
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(push, pxr_struct, 1)
|
||||
#endif
|
||||
typedef struct PIXHEAD
|
||||
{
|
||||
ILushort Signature;
|
||||
ILubyte Reserved1[413];
|
||||
ILushort Height;
|
||||
ILushort Width;
|
||||
ILubyte Reserved2[4];
|
||||
ILubyte BppInfo;
|
||||
ILubyte Reserved3[598];
|
||||
} IL_PACKSTRUCT PIXHEAD;
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(pop, pxr_struct)
|
||||
#endif
|
||||
|
||||
ILboolean iLoadPxrInternal(ILvoid);
|
||||
|
||||
|
||||
//! Reads a Pxr file
|
||||
ILboolean ilLoadPxr(ILconst_string FileName)
|
||||
{
|
||||
ILHANDLE PxrFile;
|
||||
ILboolean bPxr = IL_FALSE;
|
||||
|
||||
PxrFile = iopenr(FileName);
|
||||
if (PxrFile == NULL) {
|
||||
ilSetError(IL_COULD_NOT_OPEN_FILE);
|
||||
return bPxr;
|
||||
}
|
||||
|
||||
bPxr = ilLoadPxrF(PxrFile);
|
||||
icloser(PxrFile);
|
||||
|
||||
return bPxr;
|
||||
}
|
||||
|
||||
|
||||
//! Reads an already-opened Pxr file
|
||||
ILboolean ilLoadPxrF(ILHANDLE File)
|
||||
{
|
||||
ILuint FirstPos;
|
||||
ILboolean bRet;
|
||||
|
||||
iSetInputFile(File);
|
||||
FirstPos = itell();
|
||||
bRet = iLoadPxrInternal();
|
||||
iseek(FirstPos, IL_SEEK_SET);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
//! Reads from a memory "lump" that contains a Pxr
|
||||
ILboolean ilLoadPxrL(const ILvoid *Lump, ILuint Size)
|
||||
{
|
||||
iSetInputLump(Lump, Size);
|
||||
return iLoadPxrInternal();
|
||||
}
|
||||
|
||||
|
||||
// Internal function used to load the Pxr.
|
||||
ILboolean iLoadPxrInternal()
|
||||
{
|
||||
ILushort Width, Height;
|
||||
ILubyte Bpp;
|
||||
|
||||
Width = sizeof(PIXHEAD);
|
||||
|
||||
iseek(416, IL_SEEK_SET);
|
||||
Height = GetLittleUShort();
|
||||
Width = GetLittleUShort();
|
||||
iseek(424, IL_SEEK_SET);
|
||||
Bpp = igetc();
|
||||
|
||||
switch (Bpp)
|
||||
{
|
||||
case 0x08:
|
||||
ilTexImage(Width, Height, 1, 1, IL_LUMINANCE, IL_UNSIGNED_BYTE, NULL);
|
||||
break;
|
||||
case 0x0E:
|
||||
ilTexImage(Width, Height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL);
|
||||
break;
|
||||
case 0x0F:
|
||||
ilTexImage(Width, Height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL);
|
||||
break;
|
||||
default:
|
||||
ilSetError(IL_INVALID_FILE_HEADER);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
iseek(1024, IL_SEEK_SET);
|
||||
iread(iCurImage->Data, 1, iCurImage->SizeOfData);
|
||||
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
#endif//IL_NO_PXR
|
||||
640
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_quantizer.c
Normal file
640
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_quantizer.c
Normal file
@@ -0,0 +1,640 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// Color Quantization Demo
|
||||
//
|
||||
// Author: Roman Podobedov
|
||||
// Email: romka@ut.ee
|
||||
// Romka Graphics: www.ut.ee/~romka
|
||||
//
|
||||
// Also in this file implemented Wu's Color Quantizer algorithm (v. 2)
|
||||
// For details see Graphics Gems vol. II, pp. 126-133
|
||||
//
|
||||
// Wu's Color Quantizer Algorithm:
|
||||
// Author: Xiaolin Wu
|
||||
// Dept. of Computer Science
|
||||
// Univ. of Western Ontario
|
||||
// London, Ontario N6A 5B7
|
||||
// wu@csd.uwo.ca
|
||||
// http://www.csd.uwo.ca/faculty/wu/
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// by Denton Woods
|
||||
// Last modified: 02/02/2002 <--Y2K Compliant! =]
|
||||
//
|
||||
// Filename: src-IL/src/il_quantizer.c
|
||||
//
|
||||
// Description: Heavily modified by Denton Woods.
|
||||
//
|
||||
// 20040223 XIX : Modified so it works better with color requests < 256
|
||||
// pallete always has memory space for 256 entries
|
||||
// used so we can quant down to 255 colors then add a transparent color in there.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "il_internal.h"
|
||||
|
||||
#define MAXCOLOR 256
|
||||
#define RED 2
|
||||
#define GREEN 1
|
||||
#define BLUE 0
|
||||
|
||||
typedef struct Box
|
||||
{
|
||||
ILint r0; // min value, exclusive
|
||||
ILint r1; // max value, inclusive
|
||||
ILint g0;
|
||||
ILint g1;
|
||||
ILint b0;
|
||||
ILint b1;
|
||||
ILint vol;
|
||||
} Box;
|
||||
|
||||
/* Histogram is in elements 1..HISTSIZE along each axis,
|
||||
* element 0 is for base or marginal value
|
||||
* NB: these must start out 0!
|
||||
*/
|
||||
|
||||
ILfloat gm2[33][33][33];
|
||||
ILint wt[33][33][33], mr[33][33][33], mg[33][33][33], mb[33][33][33];
|
||||
ILuint size; //image size
|
||||
ILint K; //colour look-up table size
|
||||
ILushort *Qadd;
|
||||
|
||||
|
||||
ILint WindW, WindH, WindD;
|
||||
ILint i;
|
||||
ILubyte *buffer;
|
||||
static ILint Width, Height, Depth, Comp;
|
||||
/*ILint TotalColors;
|
||||
ILint a, b;
|
||||
ILubyte *buf1, *buf2;*/
|
||||
|
||||
ILuint n2(ILint s)
|
||||
{
|
||||
ILint i;
|
||||
ILint res;
|
||||
|
||||
res = 1;
|
||||
for (i = 0; i < s; i++) {
|
||||
res = res*2;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
// Build 3-D color histogram of counts, r/g/b, c^2
|
||||
ILboolean Hist3d(ILubyte *Ir, ILubyte *Ig, ILubyte *Ib, ILint *vwt, ILint *vmr, ILint *vmg, ILint *vmb, ILfloat *m2)
|
||||
{
|
||||
ILint ind, r, g, b;
|
||||
ILint inr, ing, inb, table[2560];
|
||||
ILuint i;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
table[i] = i * i;
|
||||
}
|
||||
Qadd = (ILushort*)ialloc(sizeof(ILushort) * size);
|
||||
if (Qadd == NULL) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
imemclear(Qadd, sizeof(ILushort) * size);
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
r = Ir[i]; g = Ig[i]; b = Ib[i];
|
||||
inr = (r>>3) + 1;
|
||||
ing = (g>>3) + 1;
|
||||
inb = (b>>3) + 1;
|
||||
Qadd[i] = ind = (inr<<10)+(inr<<6)+inr+(ing<<5)+ing+inb;
|
||||
//[inr][ing][inb]
|
||||
vwt[ind]++;
|
||||
vmr[ind] += r;
|
||||
vmg[ind] += g;
|
||||
vmb[ind] += b;
|
||||
m2[ind] += (ILfloat)(table[r]+table[g]+table[b]);
|
||||
}
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
/* At conclusion of the histogram step, we can interpret
|
||||
* wt[r][g][b] = sum over voxel of P(c)
|
||||
* mr[r][g][b] = sum over voxel of r*P(c) , similarly for mg, mb
|
||||
* m2[r][g][b] = sum over voxel of c^2*P(c)
|
||||
* Actually each of these should be divided by 'size' to give the usual
|
||||
* interpretation of P() as ranging from 0 to 1, but we needn't do that here.
|
||||
*/
|
||||
|
||||
/* We now convert histogram into moments so that we can rapidly calculate
|
||||
* the sums of the above quantities over any desired Box.
|
||||
*/
|
||||
|
||||
|
||||
// Compute cumulative moments
|
||||
ILvoid M3d(ILint *vwt, ILint *vmr, ILint *vmg, ILint *vmb, ILfloat *m2)
|
||||
{
|
||||
ILushort ind1, ind2;
|
||||
ILubyte i, r, g, b;
|
||||
ILint line, line_r, line_g, line_b, area[33], area_r[33], area_g[33], area_b[33];
|
||||
ILfloat line2, area2[33];
|
||||
|
||||
for (r = 1; r <= 32; r++) {
|
||||
for (i = 0; i <= 32; i++) {
|
||||
area2[i] = 0.0f;
|
||||
area[i]=area_r[i]=area_g[i]=area_b[i]=0;
|
||||
}
|
||||
for (g = 1; g <= 32; g++) {
|
||||
line2 = 0.0f;
|
||||
line = line_r = line_g = line_b = 0;
|
||||
for (b = 1; b <= 32; b++) {
|
||||
ind1 = (r<<10) + (r<<6) + r + (g<<5) + g + b; // [r][g][b]
|
||||
line += vwt[ind1];
|
||||
line_r += vmr[ind1];
|
||||
line_g += vmg[ind1];
|
||||
line_b += vmb[ind1];
|
||||
line2 += m2[ind1];
|
||||
area[b] += line;
|
||||
area_r[b] += line_r;
|
||||
area_g[b] += line_g;
|
||||
area_b[b] += line_b;
|
||||
area2[b] += line2;
|
||||
ind2 = ind1 - 1089; // [r-1][g][b]
|
||||
vwt[ind1] = vwt[ind2] + area[b];
|
||||
vmr[ind1] = vmr[ind2] + area_r[b];
|
||||
vmg[ind1] = vmg[ind2] + area_g[b];
|
||||
vmb[ind1] = vmb[ind2] + area_b[b];
|
||||
m2[ind1] = m2[ind2] + area2[b];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Compute sum over a Box of any given statistic
|
||||
ILint Vol(Box *cube, ILint mmt[33][33][33])
|
||||
{
|
||||
return( mmt[cube->r1][cube->g1][cube->b1]
|
||||
-mmt[cube->r1][cube->g1][cube->b0]
|
||||
-mmt[cube->r1][cube->g0][cube->b1]
|
||||
+mmt[cube->r1][cube->g0][cube->b0]
|
||||
-mmt[cube->r0][cube->g1][cube->b1]
|
||||
+mmt[cube->r0][cube->g1][cube->b0]
|
||||
+mmt[cube->r0][cube->g0][cube->b1]
|
||||
-mmt[cube->r0][cube->g0][cube->b0] );
|
||||
}
|
||||
|
||||
/* The next two routines allow a slightly more efficient calculation
|
||||
* of Vol() for a proposed subBox of a given Box. The sum of Top()
|
||||
* and Bottom() is the Vol() of a subBox split in the given direction
|
||||
* and with the specified new upper bound.
|
||||
*/
|
||||
|
||||
// Compute part of Vol(cube, mmt) that doesn't depend on r1, g1, or b1
|
||||
// (depending on dir)
|
||||
ILint Bottom(Box *cube, ILubyte dir, ILint mmt[33][33][33])
|
||||
{
|
||||
switch(dir)
|
||||
{
|
||||
case RED:
|
||||
return( -mmt[cube->r0][cube->g1][cube->b1]
|
||||
+mmt[cube->r0][cube->g1][cube->b0]
|
||||
+mmt[cube->r0][cube->g0][cube->b1]
|
||||
-mmt[cube->r0][cube->g0][cube->b0] );
|
||||
break;
|
||||
case GREEN:
|
||||
return( -mmt[cube->r1][cube->g0][cube->b1]
|
||||
+mmt[cube->r1][cube->g0][cube->b0]
|
||||
+mmt[cube->r0][cube->g0][cube->b1]
|
||||
-mmt[cube->r0][cube->g0][cube->b0] );
|
||||
break;
|
||||
case BLUE:
|
||||
return( -mmt[cube->r1][cube->g1][cube->b0]
|
||||
+mmt[cube->r1][cube->g0][cube->b0]
|
||||
+mmt[cube->r0][cube->g1][cube->b0]
|
||||
-mmt[cube->r0][cube->g0][cube->b0] );
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Compute remainder of Vol(cube, mmt), substituting pos for
|
||||
// r1, g1, or b1 (depending on dir)
|
||||
ILint Top(Box *cube, ILubyte dir, ILint pos, ILint mmt[33][33][33])
|
||||
{
|
||||
switch (dir)
|
||||
{
|
||||
case RED:
|
||||
return( mmt[pos][cube->g1][cube->b1]
|
||||
-mmt[pos][cube->g1][cube->b0]
|
||||
-mmt[pos][cube->g0][cube->b1]
|
||||
+mmt[pos][cube->g0][cube->b0] );
|
||||
break;
|
||||
case GREEN:
|
||||
return( mmt[cube->r1][pos][cube->b1]
|
||||
-mmt[cube->r1][pos][cube->b0]
|
||||
-mmt[cube->r0][pos][cube->b1]
|
||||
+mmt[cube->r0][pos][cube->b0] );
|
||||
break;
|
||||
case BLUE:
|
||||
return( mmt[cube->r1][cube->g1][pos]
|
||||
-mmt[cube->r1][cube->g0][pos]
|
||||
-mmt[cube->r0][cube->g1][pos]
|
||||
+mmt[cube->r0][cube->g0][pos] );
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Compute the weighted variance of a Box
|
||||
// NB: as with the raw statistics, this is really the variance * size
|
||||
ILfloat Var(Box *cube)
|
||||
{
|
||||
ILfloat dr, dg, db, xx;
|
||||
|
||||
dr = (ILfloat)Vol(cube, mr);
|
||||
dg = (ILfloat)Vol(cube, mg);
|
||||
db = (ILfloat)Vol(cube, mb);
|
||||
xx = gm2[cube->r1][cube->g1][cube->b1]
|
||||
-gm2[cube->r1][cube->g1][cube->b0]
|
||||
-gm2[cube->r1][cube->g0][cube->b1]
|
||||
+gm2[cube->r1][cube->g0][cube->b0]
|
||||
-gm2[cube->r0][cube->g1][cube->b1]
|
||||
+gm2[cube->r0][cube->g1][cube->b0]
|
||||
+gm2[cube->r0][cube->g0][cube->b1]
|
||||
-gm2[cube->r0][cube->g0][cube->b0];
|
||||
|
||||
return xx - (dr*dr+dg*dg+db*db) / (ILfloat)Vol(cube, wt);
|
||||
}
|
||||
|
||||
/* We want to minimize the sum of the variances of two subBoxes.
|
||||
* The sum(c^2) terms can be ignored since their sum over both subBoxes
|
||||
* is the same (the sum for the whole Box) no matter where we split.
|
||||
* The remaining terms have a minus sign in the variance formula,
|
||||
* so we drop the minus sign and MAXIMIZE the sum of the two terms.
|
||||
*/
|
||||
|
||||
ILfloat Maximize(Box *cube, ILubyte dir, ILint first, ILint last, ILint *cut,
|
||||
ILint whole_r, ILint whole_g, ILint whole_b, ILint whole_w)
|
||||
{
|
||||
ILint half_r, half_g, half_b, half_w;
|
||||
ILint base_r, base_g, base_b, base_w;
|
||||
ILint i;
|
||||
ILfloat temp, max;
|
||||
|
||||
base_r = Bottom(cube, dir, mr);
|
||||
base_g = Bottom(cube, dir, mg);
|
||||
base_b = Bottom(cube, dir, mb);
|
||||
base_w = Bottom(cube, dir, wt);
|
||||
max = 0.0;
|
||||
*cut = -1;
|
||||
|
||||
for (i = first; i < last; ++i) {
|
||||
half_r = base_r + Top(cube, dir, i, mr);
|
||||
half_g = base_g + Top(cube, dir, i, mg);
|
||||
half_b = base_b + Top(cube, dir, i, mb);
|
||||
half_w = base_w + Top(cube, dir, i, wt);
|
||||
// Now half_x is sum over lower half of Box, if split at i
|
||||
if (half_w == 0) { // subBox could be empty of pixels!
|
||||
continue; // never split into an empty Box
|
||||
}
|
||||
else {
|
||||
temp = ((ILfloat)half_r*half_r + (ILfloat)half_g * half_g +
|
||||
(ILfloat)half_b*half_b) / half_w;
|
||||
}
|
||||
|
||||
half_r = whole_r - half_r;
|
||||
half_g = whole_g - half_g;
|
||||
half_b = whole_b - half_b;
|
||||
half_w = whole_w - half_w;
|
||||
if (half_w == 0) { // subBox could be empty of pixels!
|
||||
continue; // never split into an empty Box
|
||||
}
|
||||
else {
|
||||
temp += ((ILfloat)half_r*half_r + (ILfloat)half_g * half_g +
|
||||
(ILfloat)half_b*half_b) / half_w;
|
||||
}
|
||||
|
||||
if (temp > max) {
|
||||
max = temp;
|
||||
*cut = i;
|
||||
}
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
|
||||
ILint Cut(Box *set1, Box *set2)
|
||||
{
|
||||
ILubyte dir;
|
||||
ILint cutr, cutg, cutb;
|
||||
ILfloat maxr, maxg, maxb;
|
||||
ILint whole_r, whole_g, whole_b, whole_w;
|
||||
|
||||
whole_r = Vol(set1, mr);
|
||||
whole_g = Vol(set1, mg);
|
||||
whole_b = Vol(set1, mb);
|
||||
whole_w = Vol(set1, wt);
|
||||
|
||||
maxr = Maximize(set1, RED, set1->r0+1, set1->r1, &cutr, whole_r, whole_g, whole_b, whole_w);
|
||||
maxg = Maximize(set1, GREEN, set1->g0+1, set1->g1, &cutg, whole_r, whole_g, whole_b, whole_w);
|
||||
maxb = Maximize(set1, BLUE, set1->b0+1, set1->b1, &cutb, whole_r, whole_g, whole_b, whole_w);
|
||||
|
||||
if ((maxr >= maxg) && (maxr >= maxb)) {
|
||||
dir = RED;
|
||||
if (cutr < 0)
|
||||
return 0; // can't split the Box
|
||||
}
|
||||
else if ((maxg >= maxr) && (maxg >= maxb))
|
||||
dir = GREEN;
|
||||
else
|
||||
dir = BLUE;
|
||||
|
||||
set2->r1 = set1->r1;
|
||||
set2->g1 = set1->g1;
|
||||
set2->b1 = set1->b1;
|
||||
|
||||
switch (dir)
|
||||
{
|
||||
case RED:
|
||||
set2->r0 = set1->r1 = cutr;
|
||||
set2->g0 = set1->g0;
|
||||
set2->b0 = set1->b0;
|
||||
break;
|
||||
case GREEN:
|
||||
set2->g0 = set1->g1 = cutg;
|
||||
set2->r0 = set1->r0;
|
||||
set2->b0 = set1->b0;
|
||||
break;
|
||||
case BLUE:
|
||||
set2->b0 = set1->b1 = cutb;
|
||||
set2->r0 = set1->r0;
|
||||
set2->g0 = set1->g0;
|
||||
break;
|
||||
}
|
||||
|
||||
set1->vol = (set1->r1-set1->r0) * (set1->g1-set1->g0) * (set1->b1-set1->b0);
|
||||
set2->vol = (set2->r1-set2->r0) * (set2->g1-set2->g0) * (set2->b1-set2->b0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void Mark(struct Box *cube, int label, unsigned char *tag)
|
||||
{
|
||||
ILint r, g, b;
|
||||
|
||||
for (r = cube->r0 + 1; r <= cube->r1; r++) {
|
||||
for (g = cube->g0 + 1; g <= cube->g1; g++) {
|
||||
for (b = cube->b0 + 1; b <= cube->b1; b++) {
|
||||
tag[(r<<10) + (r<<6) + r + (g<<5) + g + b] = label;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ILimage *iQuantizeImage(ILimage *Image, ILuint NumCols)
|
||||
{
|
||||
Box cube[MAXCOLOR];
|
||||
ILubyte *tag = NULL;
|
||||
ILubyte lut_r[MAXCOLOR], lut_g[MAXCOLOR], lut_b[MAXCOLOR];
|
||||
ILint next;
|
||||
ILint weight;
|
||||
ILuint k;
|
||||
ILfloat vv[MAXCOLOR], temp;
|
||||
//ILint color_num;
|
||||
ILubyte *NewData = NULL, *Palette = NULL;
|
||||
ILimage *TempImage = NULL, *NewImage = NULL;
|
||||
ILubyte *Ir = NULL, *Ig = NULL, *Ib = NULL;
|
||||
|
||||
ILint num_alloced_colors; // number of colors we allocated space for in palette, as NumCols but eill not be less than 256
|
||||
|
||||
num_alloced_colors=NumCols;
|
||||
if(num_alloced_colors<256) { num_alloced_colors=256; }
|
||||
|
||||
|
||||
NewImage = iCurImage;
|
||||
iCurImage = Image;
|
||||
TempImage = iConvertImage(iCurImage, IL_RGB, IL_UNSIGNED_BYTE);
|
||||
iCurImage = NewImage;
|
||||
|
||||
|
||||
|
||||
if (TempImage == NULL)
|
||||
return NULL;
|
||||
|
||||
buffer = Image->Data;
|
||||
WindW = Width = Image->Width;
|
||||
WindH = Height = Image->Height;
|
||||
WindD = Depth = Image->Depth;
|
||||
Comp = Image->Bpp;
|
||||
Qadd = NULL;
|
||||
|
||||
//color_num = ImagePrecalculate(Image);
|
||||
|
||||
NewData = (ILubyte*)ialloc(Image->Width * Image->Height * Image->Depth);
|
||||
Palette = (ILubyte*)ialloc(3 * num_alloced_colors);
|
||||
if (!NewData || !Palette) {
|
||||
ifree(NewData);
|
||||
ifree(Palette);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Ir = (ILubyte*)ialloc(Width * Height * Depth);
|
||||
Ig = (ILubyte*)ialloc(Width * Height * Depth);
|
||||
Ib = (ILubyte*)ialloc(Width * Height * Depth);
|
||||
if (!Ir || !Ig || !Ib) {
|
||||
ifree(Ir);
|
||||
ifree(Ig);
|
||||
ifree(Ib);
|
||||
ifree(NewData);
|
||||
ifree(Palette);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size = Width * Height * Depth;
|
||||
|
||||
#ifdef ALTIVEC_GCC
|
||||
register ILuint v_size = size>>4;
|
||||
register ILuint pos = 0;
|
||||
v_size = v_size /3;
|
||||
register vector unsigned char d0,d1,d2;
|
||||
register vector unsigned char red[3],blu[3],green[3];
|
||||
|
||||
register union{
|
||||
vector unsigned char vec;
|
||||
vector unsigned int load;
|
||||
} mask_1, mask_2, mask_3;
|
||||
|
||||
mask_1.load = (vector unsigned int){0xFF0000FF,0x0000FF00,0x00FF0000,0xFF0000FF};
|
||||
mask_2.load = (vector unsigned int){0x00FF0000,0xFF0000FF,0x0000FF00,0x00FF0000};
|
||||
mask_2.load = (vector unsigned int){0x0000FF00,0x00FF0000,0xFF0000FF,0x0000FF00};
|
||||
|
||||
while( v_size >= 0 ) {
|
||||
d0 = vec_ld(pos,TempImage->Data);
|
||||
d1 = vec_ld(pos+16,TempImage->Data);
|
||||
d2 = vec_ld(pos+32,TempImage->Data);
|
||||
|
||||
red[0] = vec_and(d0,mask_1.vec);
|
||||
green[0] = vec_and(d0,mask_2.vec);
|
||||
blu[0] = vec_and(d0,mask_3.vec);
|
||||
|
||||
red[1] = vec_and(d1,mask_3.vec);
|
||||
green[1] = vec_and(d1,mask_1.vec);
|
||||
blu[1] = vec_and(d1,mask_2.vec);
|
||||
|
||||
red[2] = vec_and(d2,mask_2.vec);
|
||||
green[2] = vec_and(d2,mask_3.vec);
|
||||
blu[2] = vec_and(d2,mask_1.vec);
|
||||
|
||||
vec_st(red[0],pos,Ir);
|
||||
vec_st(red[1],pos+16,Ir);
|
||||
vec_st(red[2],pos+32,Ir);
|
||||
|
||||
vec_st(blu[0],pos,Ib);
|
||||
vec_st(blu[1],pos+16,Ib);
|
||||
vec_st(blu[2],pos+32,Ib);
|
||||
|
||||
vec_st(green[0],pos,Ig);
|
||||
vec_st(green[1],pos+16,Ig);
|
||||
vec_st(green[2],pos+32,Ig);
|
||||
|
||||
pos += 48;
|
||||
}
|
||||
size -= pos;
|
||||
#endif
|
||||
|
||||
for (k = 0; k < size; k++) {
|
||||
Ir[k] = TempImage->Data[k * 3];
|
||||
Ig[k] = TempImage->Data[k * 3 + 1];
|
||||
Ib[k] = TempImage->Data[k * 3 + 2];
|
||||
}
|
||||
|
||||
#ifdef ALTIVEC_GCC
|
||||
size = Width * Height * Depth;
|
||||
#endif
|
||||
|
||||
// Set new colors number
|
||||
K = NumCols;
|
||||
|
||||
if (K <= 256) {
|
||||
// Begin Wu's color quantization algorithm
|
||||
|
||||
// May have "leftovers" from a previous run.
|
||||
|
||||
imemclear(gm2, 33 * 33 * 33 * sizeof(ILfloat));
|
||||
imemclear(wt, 33 * 33 * 33 * sizeof(ILint));
|
||||
imemclear(mr, 33 * 33 * 33 * sizeof(ILint));
|
||||
imemclear(mg, 33 * 33 * 33 * sizeof(ILint));
|
||||
imemclear(mb, 33 * 33 * 33 * sizeof(ILint));
|
||||
|
||||
if (!Hist3d(Ir, Ig, Ib, (ILint*)wt, (ILint*)mr, (ILint*)mg, (ILint*)mb, (ILfloat*)gm2))
|
||||
goto error_label;
|
||||
|
||||
M3d((ILint*)wt, (ILint*)mr, (ILint*)mg, (ILint*)mb, (ILfloat*)gm2);
|
||||
|
||||
cube[0].r0 = cube[0].g0 = cube[0].b0 = 0;
|
||||
cube[0].r1 = cube[0].g1 = cube[0].b1 = 32;
|
||||
next = 0;
|
||||
for (i = 1; i < K; ++i) {
|
||||
if (Cut(&cube[next], &cube[i])) { // volume test ensures we won't try to cut one-cell Box */
|
||||
vv[next] = (cube[next].vol>1) ? Var(&cube[next]) : 0.0f;
|
||||
vv[i] = (cube[i].vol>1) ? Var(&cube[i]) : 0.0f;
|
||||
}
|
||||
else {
|
||||
vv[next] = 0.0; // don't try to split this Box again
|
||||
i--; // didn't create Box i
|
||||
}
|
||||
next = 0;
|
||||
temp = vv[0];
|
||||
for (k = 1; (ILint)k <= i; ++k) {
|
||||
if (vv[k] > temp) {
|
||||
temp = vv[k]; next = k;
|
||||
}
|
||||
}
|
||||
|
||||
if (temp <= 0.0) {
|
||||
K = i+1;
|
||||
// Only got K Boxes
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tag = (ILubyte*)ialloc(33 * 33 * 33 * sizeof(ILubyte));
|
||||
if (tag == NULL)
|
||||
goto error_label;
|
||||
for (k = 0; (ILint)k < K; k++) {
|
||||
Mark(&cube[k], k, tag);
|
||||
weight = Vol(&cube[k], wt);
|
||||
if (weight) {
|
||||
lut_r[k] = (ILubyte)(Vol(&cube[k], mr) / weight);
|
||||
lut_g[k] = (ILubyte)(Vol(&cube[k], mg) / weight);
|
||||
lut_b[k] = (ILubyte)(Vol(&cube[k], mb) / weight);
|
||||
}
|
||||
else {
|
||||
// Bogus Box
|
||||
lut_r[k] = lut_g[k] = lut_b[k] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < (ILint)size; i++) {
|
||||
NewData[i] = tag[Qadd[i]];
|
||||
}
|
||||
ifree(tag);
|
||||
ifree(Qadd);
|
||||
|
||||
for (k = 0; k < NumCols; k++) {
|
||||
Palette[k * 3] = lut_b[k];
|
||||
Palette[k * 3 + 1] = lut_g[k];
|
||||
Palette[k * 3 + 2] = lut_r[k];
|
||||
}
|
||||
}
|
||||
else { // If colors more than 256
|
||||
// Begin Octree quantization
|
||||
//Quant_Octree(Image->Width, Image->Height, Image->Bpp, buffer2, NewData, Palette, K);
|
||||
ilSetError(IL_INTERNAL_ERROR); // Can't get much more specific than this.
|
||||
goto error_label;
|
||||
}
|
||||
|
||||
ifree(Ig);
|
||||
ifree(Ib);
|
||||
ifree(Ir);
|
||||
ilCloseImage(TempImage);
|
||||
|
||||
NewImage = (ILimage*)icalloc(sizeof(ILimage), 1);
|
||||
if (NewImage == NULL) {
|
||||
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.Palette = Palette;
|
||||
NewImage->Pal.PalSize = 256 * 3;
|
||||
NewImage->Pal.PalType = IL_PAL_BGR24;
|
||||
NewImage->Data = NewData;
|
||||
|
||||
return NewImage;
|
||||
|
||||
error_label:
|
||||
ifree(NewData);
|
||||
ifree(Palette);
|
||||
ifree(Ig);
|
||||
ifree(Ib);
|
||||
ifree(Ir);
|
||||
ifree(tag);
|
||||
ifree(Qadd);
|
||||
return NULL;
|
||||
}
|
||||
180
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_raw.c
Normal file
180
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_raw.c
Normal file
@@ -0,0 +1,180 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2001 by Denton Woods
|
||||
// Last modified: 05/25/2001 <--Y2K Compliant! =]
|
||||
//
|
||||
// Filename: src-IL/src/il_raw.c
|
||||
//
|
||||
// Description: "Raw" file functions
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "il_internal.h"
|
||||
#ifndef IL_NO_RAW
|
||||
|
||||
|
||||
ILboolean iLoadRawInternal(ILvoid);
|
||||
ILboolean iSaveRawInternal(ILvoid);
|
||||
|
||||
|
||||
//! Reads a raw file
|
||||
ILboolean ilLoadRaw(ILconst_string FileName)
|
||||
{
|
||||
ILHANDLE RawFile;
|
||||
ILboolean bRaw = IL_FALSE;
|
||||
|
||||
// No need to check for raw
|
||||
/*if (!iCheckExtension(FileName, "raw")) {
|
||||
ilSetError(IL_INVALID_EXTENSION);
|
||||
return bRaw;
|
||||
}*/
|
||||
|
||||
RawFile = iopenr(FileName);
|
||||
if (RawFile == NULL) {
|
||||
ilSetError(IL_COULD_NOT_OPEN_FILE);
|
||||
return bRaw;
|
||||
}
|
||||
|
||||
bRaw = ilLoadRawF(RawFile);
|
||||
icloser(RawFile);
|
||||
|
||||
return bRaw;
|
||||
}
|
||||
|
||||
|
||||
//! Reads an already-opened raw file
|
||||
ILboolean ilLoadRawF(ILHANDLE File)
|
||||
{
|
||||
ILuint FirstPos;
|
||||
ILboolean bRet;
|
||||
|
||||
iSetInputFile(File);
|
||||
FirstPos = itell();
|
||||
bRet = iLoadRawInternal();
|
||||
iseek(FirstPos, IL_SEEK_SET);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
//! Reads from a raw memory "lump"
|
||||
ILboolean ilLoadRawL(const ILvoid *Lump, ILuint Size)
|
||||
{
|
||||
iSetInputLump(Lump, Size);
|
||||
return iLoadRawInternal();
|
||||
}
|
||||
|
||||
|
||||
// Internal function to load a raw image
|
||||
ILboolean iLoadRawInternal()
|
||||
{
|
||||
if (iCurImage == NULL) {
|
||||
ilSetError(IL_ILLEGAL_OPERATION);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
iCurImage->Width = GetLittleUInt();
|
||||
|
||||
iCurImage->Height = GetLittleUInt();
|
||||
|
||||
iCurImage->Depth = GetLittleUInt();
|
||||
|
||||
iCurImage->Bpp = igetc();
|
||||
|
||||
if (iread(&iCurImage->Bpc, 1, 1) != 1)
|
||||
return IL_FALSE;
|
||||
|
||||
if (!ilTexImage(iCurImage->Width, iCurImage->Height, iCurImage->Depth, iCurImage->Bpp, 0, ilGetTypeBpc(iCurImage->Bpc), NULL)) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
|
||||
|
||||
// Tries to read the correct amount of data
|
||||
if (iread(iCurImage->Data, 1, iCurImage->SizeOfData) < iCurImage->SizeOfData)
|
||||
return IL_FALSE;
|
||||
|
||||
if (ilIsEnabled(IL_ORIGIN_SET)) {
|
||||
iCurImage->Origin = ilGetInteger(IL_ORIGIN_MODE);
|
||||
}
|
||||
else {
|
||||
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
|
||||
}
|
||||
|
||||
if (iCurImage->Bpp == 1)
|
||||
iCurImage->Format = IL_LUMINANCE;
|
||||
else if (iCurImage->Bpp == 3)
|
||||
iCurImage->Format = IL_RGB;
|
||||
else // 4
|
||||
iCurImage->Format = IL_RGBA;
|
||||
|
||||
ilFixImage();
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
//! Writes a Raw file
|
||||
ILboolean ilSaveRaw(ILconst_string FileName)
|
||||
{
|
||||
ILHANDLE RawFile;
|
||||
ILboolean bRaw = IL_FALSE;
|
||||
|
||||
if (ilGetBoolean(IL_FILE_MODE) == IL_FALSE) {
|
||||
if (iFileExists(FileName)) {
|
||||
ilSetError(IL_FILE_ALREADY_EXISTS);
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
RawFile = iopenw(FileName);
|
||||
if (RawFile == NULL) {
|
||||
ilSetError(IL_COULD_NOT_OPEN_FILE);
|
||||
return bRaw;
|
||||
}
|
||||
|
||||
bRaw = ilSaveRawF(RawFile);
|
||||
iclosew(RawFile);
|
||||
|
||||
return bRaw;
|
||||
}
|
||||
|
||||
|
||||
//! Writes raw data to an already-opened file
|
||||
ILboolean ilSaveRawF(ILHANDLE File)
|
||||
{
|
||||
iSetOutputFile(File);
|
||||
return iSaveRawInternal();
|
||||
}
|
||||
|
||||
|
||||
//! Writes raw data to a memory "lump"
|
||||
ILboolean ilSaveRawL(ILvoid *Lump, ILuint Size)
|
||||
{
|
||||
iSetOutputLump(Lump, Size);
|
||||
return iSaveRawInternal();
|
||||
}
|
||||
|
||||
|
||||
// Internal function used to load the raw data.
|
||||
ILboolean iSaveRawInternal()
|
||||
{
|
||||
if (iCurImage == NULL) {
|
||||
ilSetError(IL_ILLEGAL_OPERATION);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
SaveLittleUInt(iCurImage->Width);
|
||||
SaveLittleUInt(iCurImage->Height);
|
||||
SaveLittleUInt(iCurImage->Depth);
|
||||
iputc(iCurImage->Bpp);
|
||||
iputc(iCurImage->Bpc);
|
||||
iwrite(iCurImage->Data, 1, iCurImage->SizeOfData);
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
#endif//IL_NO_RAW
|
||||
123
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_rawdata.c
Normal file
123
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_rawdata.c
Normal file
@@ -0,0 +1,123 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2001 by Denton Woods
|
||||
// Last modified: 05/25/2001 <--Y2K Compliant! =]
|
||||
//
|
||||
// Filename: src-IL/src/rawdata.c
|
||||
//
|
||||
// Description: "Raw" file functions
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "il_internal.h"
|
||||
//#ifndef IL_NO_DATA
|
||||
#include "il_manip.h"
|
||||
|
||||
|
||||
ILboolean iLoadDataInternal(ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp);
|
||||
|
||||
|
||||
//! Reads a raw data file
|
||||
ILboolean ILAPIENTRY ilLoadData(ILconst_string FileName, ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp)
|
||||
{
|
||||
ILHANDLE RawFile;
|
||||
ILboolean bRaw = IL_FALSE;
|
||||
|
||||
// No need to check for raw data
|
||||
/*if (!iCheckExtension(FileName, "raw")) {
|
||||
ilSetError(IL_INVALID_EXTENSION);
|
||||
return bRaw;
|
||||
}*/
|
||||
|
||||
RawFile = iopenr(FileName);
|
||||
if (RawFile == NULL) {
|
||||
ilSetError(IL_COULD_NOT_OPEN_FILE);
|
||||
return bRaw;
|
||||
}
|
||||
|
||||
bRaw = ilLoadDataF(RawFile, Width, Height, Depth, Bpp);
|
||||
icloser(RawFile);
|
||||
|
||||
return bRaw;
|
||||
}
|
||||
|
||||
|
||||
//! Reads an already-opened raw data file
|
||||
ILboolean ILAPIENTRY ilLoadDataF(ILHANDLE File, ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp)
|
||||
{
|
||||
ILuint FirstPos;
|
||||
ILboolean bRet;
|
||||
|
||||
iSetInputFile(File);
|
||||
FirstPos = itell();
|
||||
bRet = iLoadDataInternal(Width, Height, Depth, Bpp);
|
||||
iseek(FirstPos, IL_SEEK_SET);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
//! Reads from a raw data memory "lump"
|
||||
ILboolean ILAPIENTRY ilLoadDataL(ILvoid *Lump, ILuint Size, ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp)
|
||||
{
|
||||
iSetInputLump(Lump, Size);
|
||||
return iLoadDataInternal(Width, Height, Depth, Bpp);
|
||||
}
|
||||
|
||||
|
||||
// Internal function to load a raw data image
|
||||
ILboolean iLoadDataInternal(ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp)
|
||||
{
|
||||
if (iCurImage == NULL || ((Bpp != 1) && (Bpp != 3) && (Bpp != 4))) {
|
||||
ilSetError(IL_ILLEGAL_OPERATION);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
if (!ilTexImage(Width, Height, Depth, Bpp, 0, IL_UNSIGNED_BYTE, NULL)) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
|
||||
|
||||
// Tries to read the correct amount of data
|
||||
if (iread(iCurImage->Data, Width * Height * Depth * Bpp, 1) != 1)
|
||||
return IL_FALSE;
|
||||
|
||||
if (iCurImage->Bpp == 1)
|
||||
iCurImage->Format = IL_LUMINANCE;
|
||||
else if (iCurImage->Bpp == 3)
|
||||
iCurImage->Format = IL_RGB;
|
||||
else // 4
|
||||
iCurImage->Format = IL_RGBA;
|
||||
|
||||
ilFixImage();
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
//! Save the current image to FileName as raw data
|
||||
ILboolean ILAPIENTRY ilSaveData(ILconst_string FileName)
|
||||
{
|
||||
ILHANDLE DataFile;
|
||||
|
||||
if (iCurImage == NULL) {
|
||||
ilSetError(IL_ILLEGAL_OPERATION);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
DataFile = iopenr(FileName);
|
||||
if (DataFile == NULL) {
|
||||
ilSetError(IL_COULD_NOT_OPEN_FILE);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
iwrite(iCurImage->Data, 1, iCurImage->SizeOfData);
|
||||
icloser(DataFile);
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
//#endif//IL_NO_DATA
|
||||
429
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_register.c
Normal file
429
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_register.c
Normal file
@@ -0,0 +1,429 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2002 by Denton Woods
|
||||
// Last modified: 10/20/2001 <--Y2K Compliant! =]
|
||||
//
|
||||
// Filename: src-IL/src/il_register.c
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "il_internal.h"
|
||||
#include "il_register.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
// Linked lists of registered formats
|
||||
iFormatL *LoadProcs = NULL;
|
||||
iFormatS *SaveProcs = NULL;
|
||||
|
||||
|
||||
ILboolean ILAPIENTRY ilRegisterLoad(ILconst_string Ext, IL_LOADPROC Load) {
|
||||
iFormatL *TempNode, *NewNode;
|
||||
|
||||
TempNode = LoadProcs;
|
||||
if (TempNode != NULL) {
|
||||
while (TempNode->Next != NULL) {
|
||||
TempNode = TempNode->Next;
|
||||
#ifndef _UNICODE
|
||||
if (!stricmp(TempNode->Ext, Ext)) { // already registered
|
||||
#else
|
||||
if (!wcsicmp(TempNode->Ext, Ext)) {
|
||||
#endif//_UNICODE
|
||||
return IL_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NewNode = (iFormatL*)ialloc(sizeof(iFormatL));
|
||||
if (NewNode == NULL) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
if (LoadProcs == NULL) {
|
||||
LoadProcs = NewNode;
|
||||
}
|
||||
else {
|
||||
TempNode->Next = NewNode;
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
NewNode->Ext = ilStrDup(Ext);
|
||||
#else
|
||||
NewNode->Ext = _wcsdup(Ext);
|
||||
#endif//_UNICODE
|
||||
NewNode->Load = Load;
|
||||
NewNode->Next = NULL;
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
ILboolean ILAPIENTRY ilRegisterSave(ILconst_string Ext, IL_SAVEPROC Save)
|
||||
{
|
||||
iFormatS *TempNode, *NewNode;
|
||||
|
||||
TempNode = SaveProcs;
|
||||
if (TempNode != NULL) {
|
||||
while (TempNode->Next != NULL) {
|
||||
TempNode = TempNode->Next;
|
||||
#ifndef _UNICODE
|
||||
if (!stricmp(TempNode->Ext, Ext)) { // already registered
|
||||
#else
|
||||
if (!_wcsicmp(TempNode->Ext, Ext)) {
|
||||
#endif//_UNICODE
|
||||
return IL_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NewNode = (iFormatS*)ialloc(sizeof(iFormatL));
|
||||
if (NewNode == NULL) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
if (SaveProcs == NULL) {
|
||||
SaveProcs = NewNode;
|
||||
}
|
||||
else {
|
||||
TempNode->Next = NewNode;
|
||||
}
|
||||
|
||||
#ifndef _UNICODE
|
||||
NewNode->Ext = ilStrDup(Ext);
|
||||
#else
|
||||
NewNode->Ext = _wcsdup(Ext);
|
||||
#endif//_UNICODE
|
||||
NewNode->Save = Save;
|
||||
NewNode->Next = NULL;
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
//! Unregisters a load extension - doesn't have to be called.
|
||||
ILboolean ILAPIENTRY ilRemoveLoad(ILconst_string Ext)
|
||||
{
|
||||
iFormatL *TempNode = LoadProcs, *PrevNode = NULL;
|
||||
|
||||
while (TempNode != NULL) {
|
||||
#ifndef _UNICODE
|
||||
if (!stricmp(Ext, TempNode->Ext)) {
|
||||
#else
|
||||
if (_wcsicmp(Ext, TempNode->Ext)) {
|
||||
#endif//_UNICODE
|
||||
if (PrevNode == NULL) { // first node in the list
|
||||
LoadProcs = TempNode->Next;
|
||||
ifree((void*)TempNode->Ext);
|
||||
ifree(TempNode);
|
||||
}
|
||||
else {
|
||||
PrevNode->Next = TempNode->Next;
|
||||
ifree((void*)TempNode->Ext);
|
||||
ifree(TempNode);
|
||||
}
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
PrevNode = TempNode;
|
||||
TempNode = TempNode->Next;
|
||||
}
|
||||
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
//! Unregisters a save extension - doesn't have to be called.
|
||||
ILboolean ILAPIENTRY ilRemoveSave(ILconst_string Ext)
|
||||
{
|
||||
iFormatS *TempNode = SaveProcs, *PrevNode = NULL;
|
||||
|
||||
while (TempNode != NULL) {
|
||||
#ifndef _UNICODE
|
||||
if (!stricmp(Ext, TempNode->Ext)) {
|
||||
#else
|
||||
if (_wcsicmp(Ext, TempNode->Ext)) {
|
||||
#endif//_UNICODE
|
||||
if (PrevNode == NULL) { // first node in the list
|
||||
SaveProcs = TempNode->Next;
|
||||
ifree((void*)TempNode->Ext);
|
||||
ifree(TempNode);
|
||||
}
|
||||
else {
|
||||
PrevNode->Next = TempNode->Next;
|
||||
ifree((void*)TempNode->Ext);
|
||||
ifree(TempNode);
|
||||
}
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
PrevNode = TempNode;
|
||||
TempNode = TempNode->Next;
|
||||
}
|
||||
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
// Automatically removes all registered formats.
|
||||
ILvoid ilRemoveRegistered()
|
||||
{
|
||||
iFormatL *TempNodeL = LoadProcs;
|
||||
iFormatS *TempNodeS = SaveProcs;
|
||||
|
||||
while (LoadProcs != NULL) {
|
||||
TempNodeL = LoadProcs->Next;
|
||||
ifree((void*)LoadProcs->Ext);
|
||||
ifree(LoadProcs);
|
||||
LoadProcs = TempNodeL;
|
||||
}
|
||||
|
||||
while (SaveProcs != NULL) {
|
||||
TempNodeS = SaveProcs->Next;
|
||||
ifree((void*)SaveProcs->Ext);
|
||||
ifree(SaveProcs);
|
||||
SaveProcs = TempNodeS;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ILboolean iRegisterLoad(ILconst_string FileName)
|
||||
{
|
||||
iFormatL *TempNode = LoadProcs;
|
||||
ILstring Ext = iGetExtension(FileName);
|
||||
ILenum Error;
|
||||
|
||||
if (!Ext)
|
||||
return IL_FALSE;
|
||||
|
||||
while (TempNode != NULL) {
|
||||
#ifndef _UNICODE
|
||||
if (!stricmp(Ext, TempNode->Ext)) {
|
||||
#else
|
||||
if (_wcsicmp(Ext, TempNode->Ext)) {
|
||||
#endif//_UNICODE
|
||||
Error = TempNode->Load(FileName);
|
||||
if (Error == IL_NO_ERROR || Error == 0) { // 0 and IL_NO_ERROR are both valid.
|
||||
return IL_TRUE;
|
||||
}
|
||||
else {
|
||||
ilSetError(Error);
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
TempNode = TempNode->Next;
|
||||
}
|
||||
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
ILboolean iRegisterSave(ILconst_string FileName)
|
||||
{
|
||||
iFormatS *TempNode = SaveProcs;
|
||||
ILstring Ext = iGetExtension(FileName);
|
||||
ILenum Error;
|
||||
|
||||
if (!Ext)
|
||||
return IL_FALSE;
|
||||
|
||||
while (TempNode != NULL) {
|
||||
#ifndef _UNICODE
|
||||
if (!stricmp(Ext, TempNode->Ext)) {
|
||||
#else
|
||||
if (_wcsicmp(Ext, TempNode->Ext)) {
|
||||
#endif//_UNICODE
|
||||
Error = TempNode->Save(FileName);
|
||||
if (Error == IL_NO_ERROR || Error == 0) { // 0 and IL_NO_ERROR are both valid.
|
||||
return IL_TRUE;
|
||||
}
|
||||
else {
|
||||
ilSetError(Error);
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
TempNode = TempNode->Next;
|
||||
}
|
||||
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// "Reporting" functions
|
||||
//
|
||||
|
||||
ILvoid ILAPIENTRY ilRegisterOrigin(ILenum Origin)
|
||||
{
|
||||
switch (Origin)
|
||||
{
|
||||
case IL_ORIGIN_LOWER_LEFT:
|
||||
case IL_ORIGIN_UPPER_LEFT:
|
||||
iCurImage->Origin = Origin;
|
||||
break;
|
||||
default:
|
||||
ilSetError(IL_INVALID_ENUM);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ILvoid ILAPIENTRY ilRegisterFormat(ILenum Format)
|
||||
{
|
||||
switch (Format)
|
||||
{
|
||||
case IL_COLOUR_INDEX:
|
||||
case IL_RGB:
|
||||
case IL_RGBA:
|
||||
case IL_BGR:
|
||||
case IL_BGRA:
|
||||
case IL_LUMINANCE:
|
||||
case IL_LUMINANCE_ALPHA:
|
||||
iCurImage->Format = Format;
|
||||
break;
|
||||
default:
|
||||
ilSetError(IL_INVALID_ENUM);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ILboolean ILAPIENTRY ilRegisterMipNum(ILuint Num)
|
||||
{
|
||||
ILimage *Next, *Prev;
|
||||
|
||||
ilBindImage(ilGetCurName()); // Make sure the current image is actually bound.
|
||||
ilCloseImage(iCurImage->Mipmaps); // Close any current mipmaps.
|
||||
|
||||
iCurImage->Mipmaps = NULL;
|
||||
if (Num == 0) // Just gets rid of all the mipmaps.
|
||||
return IL_TRUE;
|
||||
|
||||
iCurImage->Mipmaps = ilNewImage(1, 1, 1, 1, 1);
|
||||
if (iCurImage->Mipmaps == NULL)
|
||||
return IL_FALSE;
|
||||
Next = iCurImage->Mipmaps;
|
||||
Num--;
|
||||
|
||||
while (Num) {
|
||||
Next->Next = ilNewImage(1, 1, 1, 1, 1);
|
||||
if (Next->Next == NULL) {
|
||||
// Clean up before we error out.
|
||||
Prev = iCurImage->Mipmaps;
|
||||
while (Prev) {
|
||||
Next = Prev->Next;
|
||||
ilCloseImage(Prev);
|
||||
Prev = Next;
|
||||
}
|
||||
return IL_FALSE;
|
||||
}
|
||||
Next = Next->Next;
|
||||
Num--;
|
||||
}
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
ILboolean ILAPIENTRY ilRegisterNumImages(ILuint Num)
|
||||
{
|
||||
ILimage *Next, *Prev;
|
||||
|
||||
ilBindImage(ilGetCurName()); // Make sure the current image is actually bound.
|
||||
ilCloseImage(iCurImage->Next); // Close any current "next" images.
|
||||
|
||||
iCurImage->Next = NULL;
|
||||
if (Num == 0) // Just gets rid of all the "next" images.
|
||||
return IL_TRUE;
|
||||
|
||||
iCurImage->Next = ilNewImage(1, 1, 1, 1, 1);
|
||||
if (iCurImage->Next == NULL)
|
||||
return IL_FALSE;
|
||||
Next = iCurImage->Next;
|
||||
Num--;
|
||||
|
||||
while (Num) {
|
||||
Next->Next = ilNewImage(1, 1, 1, 1, 1);
|
||||
if (Next->Next == NULL) {
|
||||
// Clean up before we error out.
|
||||
Prev = iCurImage->Next;
|
||||
while (Prev) {
|
||||
Next = Prev->Next;
|
||||
ilCloseImage(Prev);
|
||||
Prev = Next;
|
||||
}
|
||||
return IL_FALSE;
|
||||
}
|
||||
Next = Next->Next;
|
||||
Num--;
|
||||
}
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
ILvoid ILAPIENTRY ilRegisterType(ILenum Type)
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
case IL_BYTE:
|
||||
case IL_UNSIGNED_BYTE:
|
||||
case IL_SHORT:
|
||||
case IL_UNSIGNED_SHORT:
|
||||
case IL_INT:
|
||||
case IL_UNSIGNED_INT:
|
||||
case IL_FLOAT:
|
||||
case IL_DOUBLE:
|
||||
iCurImage->Type = Type;
|
||||
break;
|
||||
default:
|
||||
ilSetError(IL_INVALID_ENUM);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ILvoid ILAPIENTRY ilRegisterPal(ILvoid *Pal, ILuint Size, ILenum Type)
|
||||
{
|
||||
if (!iCurImage->Pal.Palette || !iCurImage->Pal.PalSize || iCurImage->Pal.PalType != IL_PAL_NONE) {
|
||||
ifree(iCurImage->Pal.Palette);
|
||||
}
|
||||
|
||||
iCurImage->Pal.PalSize = Size;
|
||||
iCurImage->Pal.PalType = Type;
|
||||
iCurImage->Pal.Palette = (ILubyte*)ialloc(Size);
|
||||
if (iCurImage->Pal.Palette == NULL)
|
||||
return;
|
||||
|
||||
if (Pal != NULL) {
|
||||
memcpy(iCurImage->Pal.Palette, Pal, Size);
|
||||
}
|
||||
else {
|
||||
ilSetError(IL_INVALID_PARAM);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ILboolean ILAPIENTRY ilSetDuration(ILuint Duration)
|
||||
{
|
||||
if (iCurImage == NULL) {
|
||||
ilSetError(IL_ILLEGAL_OPERATION);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
iCurImage->Duration = Duration;
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
153
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_rle.c
Normal file
153
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_rle.c
Normal file
@@ -0,0 +1,153 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Description: Functions for run-length encoding
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// RLE code from TrueVision's TGA sample code available as Tgautils.zip at
|
||||
// ftp://ftp.truevision.com/pub/TGA.File.Format.Spec/PC.Version
|
||||
|
||||
#define IL_RLE_C
|
||||
|
||||
#include "il_internal.h"
|
||||
#include "il_rle.h"
|
||||
|
||||
ILboolean ilRleCompressLine(ILubyte *p, ILuint n, ILubyte bpp,
|
||||
ILubyte *q, ILuint *DestWidth, ILenum CompressMode) {
|
||||
|
||||
ILint DiffCount; // pixel count until two identical
|
||||
ILint SameCount; // number of identical adjacent pixels
|
||||
ILint RLEBufSize = 0; // count of number of bytes encoded
|
||||
ILint MaxRun;
|
||||
const ILint bmp_pad_to_even = 1 - ((long)q - *DestWidth) % 2;
|
||||
|
||||
switch( CompressMode ) {
|
||||
case IL_TGACOMP:
|
||||
MaxRun = TGA_MAX_RUN;
|
||||
break;
|
||||
case IL_SGICOMP:
|
||||
MaxRun = SGI_MAX_RUN;
|
||||
break;
|
||||
case IL_BMPCOMP:
|
||||
MaxRun = BMP_MAX_RUN;
|
||||
break;
|
||||
default:
|
||||
ilSetError(IL_INVALID_PARAM);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
while( n > 0 ) {
|
||||
// Analyze pixels
|
||||
DiffCount = CountDiffPixels(p, bpp, n > MaxRun ? MaxRun : n);
|
||||
SameCount = CountSamePixels(p, bpp, n > MaxRun ? MaxRun : n);
|
||||
|
||||
if( CompressMode == IL_BMPCOMP ) {
|
||||
ILint remaining_data = n - DiffCount - SameCount;
|
||||
if( remaining_data < 3 ) { // check if the run has gone near the end
|
||||
// no absolute run can be done
|
||||
// complete the line adding 0x01 + pixel, for each pixel
|
||||
while( remaining_data > 0 ) {
|
||||
*q++ = 0x01;
|
||||
*q++ = *p++;
|
||||
remaining_data--;
|
||||
}
|
||||
DiffCount = 0;
|
||||
SameCount = 0;
|
||||
n = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if( DiffCount > 0 ) { // create a raw packet (bmp absolute run)
|
||||
switch(CompressMode) {
|
||||
case IL_TGACOMP:
|
||||
*q++ = (ILbyte)(DiffCount - 1);
|
||||
break;
|
||||
case IL_BMPCOMP:
|
||||
*q++ = 0x00; RLEBufSize++;
|
||||
*q++ = (ILbyte)DiffCount;
|
||||
break;
|
||||
case IL_SGICOMP:
|
||||
*q++ = (ILbyte)(DiffCount | 0x80);
|
||||
break;
|
||||
}
|
||||
n -= DiffCount;
|
||||
RLEBufSize += (DiffCount * bpp) + 1;
|
||||
|
||||
while( DiffCount > 0 ) {
|
||||
switch(bpp) {
|
||||
case 4: *q++ = *p++;
|
||||
case 3: *q++ = *p++;
|
||||
case 2: *q++ = *p++;
|
||||
case 1: *q++ = *p++;
|
||||
}
|
||||
DiffCount--;
|
||||
}
|
||||
|
||||
if( CompressMode == IL_BMPCOMP ) {
|
||||
if( (long)q % 2 == bmp_pad_to_even ) {
|
||||
*q++ = 0x00; // insert padding
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( SameCount > 1 ) { // create a RLE packet
|
||||
switch(CompressMode) {
|
||||
case IL_TGACOMP:
|
||||
*q++ = (ILbyte)((SameCount - 1) | 0x80);
|
||||
break;
|
||||
case IL_SGICOMP:
|
||||
case IL_BMPCOMP:
|
||||
*q++ = (ILbyte)(SameCount);
|
||||
break;
|
||||
}
|
||||
n -= SameCount;
|
||||
RLEBufSize += bpp + 1;
|
||||
p += (SameCount - 1) * bpp;
|
||||
*q++ = *p++;
|
||||
switch(bpp) {
|
||||
case 4: *q++ = *p++;
|
||||
case 3: *q++ = *p++;
|
||||
case 2: *q++ = *p++;
|
||||
case 1: *q++ = *p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write line termination code
|
||||
switch(CompressMode) {
|
||||
case IL_SGICOMP:
|
||||
++RLEBufSize;
|
||||
*q++ = 0;
|
||||
break;
|
||||
case IL_BMPCOMP:
|
||||
*q++ = 0x00; RLEBufSize++;
|
||||
*q++ = 0x00; RLEBufSize++;
|
||||
break;
|
||||
}
|
||||
*DestWidth = RLEBufSize;
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Compresses an entire image using run-length encoding
|
||||
ILuint ilRleCompress(ILubyte *Data, ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp,
|
||||
ILubyte *Dest, ILenum CompressMode, ILuint *ScanTable) {
|
||||
ILuint DestW = 0, i, j, LineLen, Bps = Width * Bpp, SizeOfPlane = Width * Height * Bpp;
|
||||
|
||||
if( ScanTable )
|
||||
imemclear(ScanTable,Depth*Height*sizeof(ILuint));
|
||||
for( j = 0; j < Depth; j++ ) {
|
||||
for( i = 0; i < Height; i++ ) {
|
||||
if( ScanTable )
|
||||
*ScanTable++ = DestW;
|
||||
ilRleCompressLine(Data + j * SizeOfPlane + i * Bps, Width, Bpp, Dest + DestW, &LineLen, CompressMode);
|
||||
DestW += LineLen;
|
||||
}
|
||||
}
|
||||
|
||||
if( CompressMode == IL_BMPCOMP ) { // add end of image
|
||||
*(Data+DestW) = 0x00; DestW++;
|
||||
*(Data+DestW) = 0x01; DestW++;
|
||||
}
|
||||
|
||||
return DestW;
|
||||
}
|
||||
737
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_sgi.c
Normal file
737
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_sgi.c
Normal file
@@ -0,0 +1,737 @@
|
||||
|
||||
#include "il_internal.h"
|
||||
#ifndef IL_NO_SGI
|
||||
#include "il_sgi.h"
|
||||
#include "il_manip.h"
|
||||
#include <limits.h>
|
||||
|
||||
static char *FName = NULL;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*! Checks if the file specified in FileName is a valid .sgi file. */
|
||||
ILboolean ilIsValidSgi(ILconst_string FileName)
|
||||
{
|
||||
ILHANDLE SgiFile;
|
||||
ILboolean bSgi = IL_FALSE;
|
||||
|
||||
if (!iCheckExtension(FileName, IL_TEXT("sgi"))) {
|
||||
ilSetError(IL_INVALID_EXTENSION);
|
||||
return bSgi;
|
||||
}
|
||||
|
||||
FName = (char*) FileName;
|
||||
|
||||
SgiFile = iopenr(FileName);
|
||||
if (SgiFile == NULL) {
|
||||
ilSetError(IL_COULD_NOT_OPEN_FILE);
|
||||
return bSgi;
|
||||
}
|
||||
|
||||
bSgi = ilIsValidSgiF(SgiFile);
|
||||
icloser(SgiFile);
|
||||
|
||||
return bSgi;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*! Checks if the ILHANDLE contains a valid .sgi file at the current position.*/
|
||||
ILboolean ilIsValidSgiF(ILHANDLE File)
|
||||
{
|
||||
ILuint FirstPos;
|
||||
ILboolean bRet;
|
||||
|
||||
iSetInputFile(File);
|
||||
FirstPos = itell();
|
||||
bRet = iIsValidSgi();
|
||||
iseek(FirstPos, IL_SEEK_SET);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
//! Checks if Lump is a valid .sgi lump.
|
||||
ILboolean ilIsValidSgiL(const ILvoid *Lump, ILuint Size)
|
||||
{
|
||||
FName = NULL;
|
||||
iSetInputLump(Lump, Size);
|
||||
return iIsValidSgi();
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
// Internal function used to get the .sgi header from the current file.
|
||||
ILboolean iGetSgiHead(iSgiHeader *Header)
|
||||
{
|
||||
Header->MagicNum = GetBigUShort();
|
||||
Header->Storage = igetc();
|
||||
Header->Bpc = igetc();
|
||||
Header->Dim = GetBigUShort();
|
||||
Header->XSize = GetBigUShort();
|
||||
Header->YSize = GetBigUShort();
|
||||
Header->ZSize = GetBigUShort();
|
||||
Header->PixMin = GetBigInt();
|
||||
Header->PixMax = GetBigInt();
|
||||
Header->Dummy1 = GetBigInt();
|
||||
iread(Header->Name, 1, 80);
|
||||
Header->ColMap = GetBigInt();
|
||||
iread(Header->Dummy, 1, 404);
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/* Internal function to get the header and check it. */
|
||||
ILboolean iIsValidSgi()
|
||||
{
|
||||
iSgiHeader Head;
|
||||
|
||||
if (!iGetSgiHead(&Head))
|
||||
return IL_FALSE;
|
||||
iseek(-(ILint)sizeof(iSgiHeader), IL_SEEK_CUR); // Go ahead and restore to previous state
|
||||
|
||||
return iCheckSgi(&Head);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/* Internal function used to check if the HEADER is a valid .sgi header. */
|
||||
ILboolean iCheckSgi(iSgiHeader *Header)
|
||||
{
|
||||
if (Header->MagicNum != SGI_MAGICNUM)
|
||||
return IL_FALSE;
|
||||
if (Header->Storage != SGI_RLE && Header->Storage != SGI_VERBATIM)
|
||||
return IL_FALSE;
|
||||
if (Header->Bpc == 0 || Header->Dim == 0)
|
||||
return IL_FALSE;
|
||||
if (Header->XSize == 0 || Header->YSize == 0 || Header->ZSize == 0)
|
||||
return IL_FALSE;
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*! Reads a SGI file */
|
||||
ILboolean ilLoadSgi(ILconst_string FileName)
|
||||
{
|
||||
ILHANDLE SgiFile;
|
||||
ILboolean bSgi = IL_FALSE;
|
||||
|
||||
SgiFile = iopenr(FileName);
|
||||
if (SgiFile == NULL) {
|
||||
ilSetError(IL_COULD_NOT_OPEN_FILE);
|
||||
return bSgi;
|
||||
}
|
||||
|
||||
bSgi = ilLoadSgiF(SgiFile);
|
||||
icloser(SgiFile);
|
||||
|
||||
return bSgi;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*! Reads an already-opened SGI file */
|
||||
ILboolean ilLoadSgiF(ILHANDLE File)
|
||||
{
|
||||
ILuint FirstPos;
|
||||
ILboolean bRet;
|
||||
|
||||
iSetInputFile(File);
|
||||
FirstPos = itell();
|
||||
bRet = iLoadSgiInternal();
|
||||
iseek(FirstPos, IL_SEEK_SET);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*! Reads from a memory "lump" that contains a SGI image */
|
||||
ILboolean ilLoadSgiL(const ILvoid *Lump, ILuint Size)
|
||||
{
|
||||
iSetInputLump(Lump, Size);
|
||||
return iLoadSgiInternal();
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/* Internal function used to load the SGI image */
|
||||
ILboolean iLoadSgiInternal()
|
||||
{
|
||||
iSgiHeader Header;
|
||||
ILboolean bSgi;
|
||||
|
||||
if (iCurImage == NULL) {
|
||||
ilSetError(IL_ILLEGAL_OPERATION);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
if (!iGetSgiHead(&Header))
|
||||
return IL_FALSE;
|
||||
if (!iCheckSgi(&Header)) {
|
||||
ilSetError(IL_INVALID_FILE_HEADER);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
if (Header.Storage == SGI_RLE) { // RLE
|
||||
bSgi = iReadRleSgi(&Header);
|
||||
}
|
||||
else { // Non-RLE //(Header.Storage == SGI_VERBATIM)
|
||||
bSgi = iReadNonRleSgi(&Header);
|
||||
}
|
||||
|
||||
ilFixImage();
|
||||
|
||||
return bSgi;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
ILboolean iReadRleSgi(iSgiHeader *Head)
|
||||
{
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
ILuint ixTable;
|
||||
#endif
|
||||
ILuint ChanInt = 0;
|
||||
ILuint ixPlane, ixHeight,ixPixel, RleOff, RleLen;
|
||||
ILuint *OffTable=NULL, *LenTable=NULL, TableSize, Cur;
|
||||
ILubyte **TempData=NULL;
|
||||
|
||||
if (!iNewSgi(Head))
|
||||
return IL_FALSE;
|
||||
|
||||
TableSize = Head->YSize * Head->ZSize;
|
||||
OffTable = (ILuint*)ialloc(TableSize * sizeof(ILuint));
|
||||
LenTable = (ILuint*)ialloc(TableSize * sizeof(ILuint));
|
||||
if (OffTable == NULL || LenTable == NULL)
|
||||
goto cleanup_error;
|
||||
if (iread(OffTable, TableSize * sizeof(ILuint), 1) != 1)
|
||||
goto cleanup_error;
|
||||
if (iread(LenTable, TableSize * sizeof(ILuint), 1) != 1)
|
||||
goto cleanup_error;
|
||||
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
// Fix the offset/len table (it's big endian format)
|
||||
for (ixTable = 0; ixTable < TableSize; ixTable++) {
|
||||
iSwapUInt(OffTable + ixTable);
|
||||
iSwapUInt(LenTable + ixTable);
|
||||
}
|
||||
#endif //__LITTLE_ENDIAN__
|
||||
|
||||
// We have to create a temporary buffer for the image, because SGI
|
||||
// images are plane-separated. */
|
||||
TempData = (ILubyte**)ialloc(Head->ZSize * sizeof(ILubyte*));
|
||||
if (TempData == NULL)
|
||||
goto cleanup_error;
|
||||
imemclear(TempData, Head->ZSize * sizeof(ILubyte*)); // Just in case ialloc fails then cleanup_error.
|
||||
for (ixPlane = 0; ixPlane < Head->ZSize; ixPlane++) {
|
||||
TempData[ixPlane] = (ILubyte*)ialloc(Head->XSize * Head->YSize * Head->Bpc);
|
||||
if (TempData[ixPlane] == NULL)
|
||||
goto cleanup_error;
|
||||
}
|
||||
|
||||
// Read the Planes into the temporary memory
|
||||
for (ixPlane = 0; ixPlane < Head->ZSize; ixPlane++) {
|
||||
for (ixHeight = 0, Cur = 0; ixHeight < Head->YSize;
|
||||
ixHeight++, Cur += Head->XSize * Head->Bpc) {
|
||||
|
||||
RleOff = OffTable[ixHeight + ixPlane * Head->YSize];
|
||||
RleLen = LenTable[ixHeight + ixPlane * Head->YSize];
|
||||
|
||||
// Seeks to the offset table position
|
||||
iseek(RleOff, IL_SEEK_SET);
|
||||
if (iGetScanLine((TempData[ixPlane]) + (ixHeight * Head->XSize * Head->Bpc),
|
||||
Head, RleLen) != Head->XSize * Head->Bpc) {
|
||||
ilSetError(IL_ILLEGAL_FILE_VALUE);
|
||||
goto cleanup_error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DW: Removed on 05/25/2002.
|
||||
/*// Check if an alphaplane exists and invert it
|
||||
if (Head->ZSize == 4) {
|
||||
for (ixPixel=0; (ILint)ixPixel<Head->XSize * Head->YSize; ixPixel++) {
|
||||
TempData[3][ixPixel] = TempData[3][ixPixel] ^ 255;
|
||||
}
|
||||
}*/
|
||||
|
||||
// Assemble the image from its planes
|
||||
for (ixPixel = 0; ixPixel < iCurImage->SizeOfData;
|
||||
ixPixel += Head->ZSize * Head->Bpc, ChanInt += Head->Bpc) {
|
||||
for (ixPlane = 0; (ILint)ixPlane < Head->ZSize * Head->Bpc; ixPlane += Head->Bpc) {
|
||||
iCurImage->Data[ixPixel + ixPlane] = TempData[ixPlane][ChanInt];
|
||||
if (Head->Bpc == 2)
|
||||
iCurImage->Data[ixPixel + ixPlane + 1] = TempData[ixPlane][ChanInt + 1];
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
if (Head->Bpc == 2)
|
||||
sgiSwitchData(iCurImage->Data, iCurImage->SizeOfData);
|
||||
#endif
|
||||
|
||||
ifree(OffTable);
|
||||
ifree(LenTable);
|
||||
|
||||
for (ixPlane = 0; ixPlane < Head->ZSize; ixPlane++) {
|
||||
ifree(TempData[ixPlane]);
|
||||
}
|
||||
ifree(TempData);
|
||||
|
||||
return IL_TRUE;
|
||||
|
||||
cleanup_error:
|
||||
ifree(OffTable);
|
||||
ifree(LenTable);
|
||||
if (TempData) {
|
||||
for (ixPlane = 0; ixPlane < Head->ZSize; ixPlane++) {
|
||||
ifree(TempData[ixPlane]);
|
||||
}
|
||||
ifree(TempData);
|
||||
}
|
||||
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
ILint iGetScanLine(ILubyte *ScanLine, iSgiHeader *Head, ILuint Length)
|
||||
{
|
||||
ILushort Pixel, Count; // For current pixel
|
||||
ILuint BppRead = 0, CurPos = 0, Bps = Head->XSize * Head->Bpc;
|
||||
|
||||
while (BppRead < Length && CurPos < Bps)
|
||||
{
|
||||
Pixel = 0;
|
||||
if (iread(&Pixel, Head->Bpc, 1) != 1)
|
||||
return -1;
|
||||
|
||||
#ifndef __LITTLE_ENDIAN__
|
||||
iSwapUShort(&Pixel);
|
||||
#endif
|
||||
|
||||
if (!(Count = (Pixel & 0x7f))) // If 0, line ends
|
||||
return CurPos;
|
||||
if (Pixel & 0x80) { // If top bit set, then it is a "run"
|
||||
if (iread(ScanLine, Head->Bpc, Count) != Count)
|
||||
return -1;
|
||||
BppRead += Head->Bpc * Count + Head->Bpc;
|
||||
ScanLine += Head->Bpc * Count;
|
||||
CurPos += Head->Bpc * Count;
|
||||
}
|
||||
else {
|
||||
if (iread(&Pixel, Head->Bpc, 1) != 1)
|
||||
return -1;
|
||||
#ifndef __LITTLE_ENDIAN__
|
||||
iSwapUShort(&Pixel);
|
||||
#endif
|
||||
if (Head->Bpc == 1) {
|
||||
while (Count--) {
|
||||
*ScanLine = (ILubyte)Pixel;
|
||||
ScanLine++;
|
||||
CurPos++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (Count--) {
|
||||
*(ILushort*)ScanLine = Pixel;
|
||||
ScanLine += 2;
|
||||
CurPos += 2;
|
||||
}
|
||||
}
|
||||
BppRead += Head->Bpc + Head->Bpc;
|
||||
}
|
||||
}
|
||||
|
||||
return CurPos;
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
// Much easier to read - just assemble from planes, no decompression
|
||||
ILboolean iReadNonRleSgi(iSgiHeader *Head)
|
||||
{
|
||||
ILuint i, c;
|
||||
// ILint ChanInt = 0; Unused
|
||||
ILint ChanSize;
|
||||
ILboolean Cache = IL_FALSE;
|
||||
|
||||
if (!iNewSgi(Head)) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
if (iGetHint(IL_MEM_SPEED_HINT) == IL_FASTEST) {
|
||||
Cache = IL_TRUE;
|
||||
ChanSize = Head->XSize * Head->YSize * Head->Bpc;
|
||||
iPreCache(ChanSize);
|
||||
}
|
||||
|
||||
for (c = 0; c < iCurImage->Bpp; c++) {
|
||||
for (i = c; i < iCurImage->SizeOfData; i += iCurImage->Bpp) {
|
||||
if (iread(iCurImage->Data + i, 1, 1) != 1) {
|
||||
if (Cache)
|
||||
iUnCache();
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Cache)
|
||||
iUnCache();
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
ILvoid sgiSwitchData(ILubyte *Data, ILuint SizeOfData)
|
||||
{
|
||||
ILubyte Temp;
|
||||
ILuint i;
|
||||
#ifdef ALTIVEC_GCC
|
||||
i = 0;
|
||||
union {
|
||||
vector unsigned char vec;
|
||||
vector unsigned int load;
|
||||
}inversion_vector;
|
||||
|
||||
inversion_vector.load = (vector unsigned int)\
|
||||
{0x01000302,0x05040706,0x09080B0A,0x0D0C0F0E};
|
||||
while( i <= SizeOfData-16 ) {
|
||||
vector unsigned char data = vec_ld(i,Data);
|
||||
vec_perm(data,data,inversion_vector.vec);
|
||||
vec_st(data,i,Data);
|
||||
i+=16;
|
||||
}
|
||||
SizeOfData -= i;
|
||||
#endif
|
||||
for (i = 0; i < SizeOfData; i += 2) {
|
||||
Temp = Data[i];
|
||||
Data[i] = Data[i+1];
|
||||
Data[i+1] = Temp;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
// Just an internal convenience function for reading SGI files
|
||||
ILboolean iNewSgi(iSgiHeader *Head)
|
||||
{
|
||||
if (!ilTexImage(Head->XSize, Head->YSize, Head->Bpc, (ILubyte)Head->ZSize, 0, IL_UNSIGNED_BYTE, NULL)) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
|
||||
|
||||
switch (Head->ZSize)
|
||||
{
|
||||
case 1:
|
||||
iCurImage->Format = IL_LUMINANCE;
|
||||
break;
|
||||
case 2:
|
||||
iCurImage->Format = IL_LUMINANCE_ALPHA;
|
||||
break;
|
||||
case 3:
|
||||
iCurImage->Format = IL_RGB;
|
||||
break;
|
||||
case 4:
|
||||
iCurImage->Format = IL_RGBA;
|
||||
break;
|
||||
default:
|
||||
ilSetError(IL_ILLEGAL_FILE_VALUE);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
switch (Head->Bpc)
|
||||
{
|
||||
case 1:
|
||||
if (Head->PixMin < 0)
|
||||
iCurImage->Type = IL_BYTE;
|
||||
else
|
||||
iCurImage->Type = IL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case 2:
|
||||
if (Head->PixMin < 0)
|
||||
iCurImage->Type = IL_SHORT;
|
||||
else
|
||||
iCurImage->Type = IL_UNSIGNED_SHORT;
|
||||
break;
|
||||
default:
|
||||
ilSetError(IL_ILLEGAL_FILE_VALUE);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
//! Writes a SGI file
|
||||
ILboolean ilSaveSgi(ILconst_string FileName)
|
||||
{
|
||||
ILHANDLE SgiFile;
|
||||
ILboolean bSgi = IL_FALSE;
|
||||
|
||||
if (ilGetBoolean(IL_FILE_MODE) == IL_FALSE) {
|
||||
if (iFileExists(FileName)) {
|
||||
ilSetError(IL_FILE_ALREADY_EXISTS);
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
SgiFile = iopenw(FileName);
|
||||
if (SgiFile == NULL) {
|
||||
ilSetError(IL_COULD_NOT_OPEN_FILE);
|
||||
return bSgi;
|
||||
}
|
||||
|
||||
bSgi = ilSaveSgiF(SgiFile);
|
||||
iclosew(SgiFile);
|
||||
|
||||
return bSgi;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
//! Writes a SGI to an already-opened file
|
||||
ILboolean ilSaveSgiF(ILHANDLE File)
|
||||
{
|
||||
iSetOutputFile(File);
|
||||
return iSaveSgiInternal();
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
//! Writes a SGI to a memory "lump"
|
||||
ILboolean ilSaveSgiL(ILvoid *Lump, ILuint Size)
|
||||
{
|
||||
iSetOutputLump(Lump, Size);
|
||||
return iSaveSgiInternal();
|
||||
}
|
||||
|
||||
|
||||
ILenum DetermineSgiType(ILenum Type)
|
||||
{
|
||||
if (Type > IL_UNSIGNED_SHORT) {
|
||||
if (iCurImage->Type == IL_INT)
|
||||
return IL_SHORT;
|
||||
return IL_UNSIGNED_SHORT;
|
||||
}
|
||||
return Type;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
// Rle does NOT work yet.
|
||||
|
||||
// Internal function used to save the Sgi.
|
||||
ILboolean iSaveSgiInternal()
|
||||
{
|
||||
ILuint i, c;
|
||||
ILboolean Compress;
|
||||
ILimage *Temp = iCurImage;
|
||||
ILubyte *TempData;
|
||||
|
||||
if (iCurImage == NULL) {
|
||||
ilSetError(IL_ILLEGAL_OPERATION);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
if (iCurImage->Format != IL_LUMINANCE
|
||||
//while the sgi spec doesn't directly forbid rgb files with 2
|
||||
//channels, they are quite uncommon and most apps don't support
|
||||
//them. so convert lum_a images to rgba before writing.
|
||||
//&& iCurImage->Format != IL_LUMINANCE_ALPHA
|
||||
&& iCurImage->Format != IL_RGB
|
||||
&& iCurImage->Format != IL_RGBA) {
|
||||
if (iCurImage->Format == IL_BGRA || iCurImage->Format == IL_LUMINANCE_ALPHA)
|
||||
Temp = iConvertImage(iCurImage, IL_RGBA, DetermineSgiType(iCurImage->Type));
|
||||
else
|
||||
Temp = iConvertImage(iCurImage, IL_RGB, DetermineSgiType(iCurImage->Type));
|
||||
}
|
||||
else if (iCurImage->Type > IL_UNSIGNED_SHORT) {
|
||||
Temp = iConvertImage(iCurImage, iCurImage->Format, DetermineSgiType(iCurImage->Type));
|
||||
}
|
||||
|
||||
//compression of images with 2 bytes per channel doesn't work yet
|
||||
Compress = iGetInt(IL_SGI_RLE) && Temp->Bpc == 1;
|
||||
|
||||
if (Temp == NULL)
|
||||
return IL_FALSE;
|
||||
|
||||
SaveBigUShort(SGI_MAGICNUM); // 'Magic' number
|
||||
if (Compress)
|
||||
iputc(1);
|
||||
else
|
||||
iputc(0);
|
||||
|
||||
if (Temp->Type == IL_UNSIGNED_BYTE)
|
||||
iputc(1);
|
||||
else if (Temp->Type == IL_UNSIGNED_SHORT)
|
||||
iputc(2);
|
||||
// Need to error here if not one of the two...
|
||||
|
||||
if (Temp->Format == IL_LUMINANCE || Temp->Format == IL_COLOUR_INDEX)
|
||||
SaveBigUShort(2);
|
||||
else
|
||||
SaveBigUShort(3);
|
||||
|
||||
SaveBigUShort((ILushort)Temp->Width);
|
||||
SaveBigUShort((ILushort)Temp->Height);
|
||||
SaveBigUShort((ILushort)Temp->Bpp);
|
||||
|
||||
switch (Temp->Type)
|
||||
{
|
||||
case IL_BYTE:
|
||||
SaveBigInt(SCHAR_MIN); // Minimum pixel value
|
||||
SaveBigInt(SCHAR_MAX); // Maximum pixel value
|
||||
break;
|
||||
case IL_UNSIGNED_BYTE:
|
||||
SaveBigInt(0); // Minimum pixel value
|
||||
SaveBigInt(UCHAR_MAX); // Maximum pixel value
|
||||
break;
|
||||
case IL_SHORT:
|
||||
SaveBigInt(SHRT_MIN); // Minimum pixel value
|
||||
SaveBigInt(SHRT_MAX); // Maximum pixel value
|
||||
break;
|
||||
case IL_UNSIGNED_SHORT:
|
||||
SaveBigInt(0); // Minimum pixel value
|
||||
SaveBigInt(USHRT_MAX); // Maximum pixel value
|
||||
break;
|
||||
}
|
||||
|
||||
SaveBigInt(0); // Dummy value
|
||||
|
||||
if (FName) {
|
||||
c = strlen(FName);
|
||||
c = c < 79 ? 79 : c;
|
||||
iwrite(FName, 1, c);
|
||||
c = 80 - c;
|
||||
for (i = 0; i < c; i++) {
|
||||
iputc(0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < 80; i++) {
|
||||
iputc(0);
|
||||
}
|
||||
}
|
||||
|
||||
SaveBigUInt(0); // Colormap
|
||||
|
||||
// Padding
|
||||
for (i = 0; i < 101; i++) {
|
||||
SaveLittleInt(0);
|
||||
}
|
||||
|
||||
|
||||
if (iCurImage->Origin == IL_ORIGIN_UPPER_LEFT) {
|
||||
TempData = iGetFlipped(Temp);
|
||||
if (TempData == NULL) {
|
||||
if (Temp!= iCurImage)
|
||||
ilCloseImage(Temp);
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
TempData = Temp->Data;
|
||||
}
|
||||
|
||||
|
||||
if (!Compress) {
|
||||
for (c = 0; c < Temp->Bpp; c++) {
|
||||
for (i = c; i < Temp->SizeOfData; i += Temp->Bpp) {
|
||||
iputc(TempData[i]); // Have to save each colour plane separately.
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
iSaveRleSgi(TempData, Temp->Width, Temp->Height, Temp->Bpp, Temp->Bps);
|
||||
}
|
||||
|
||||
|
||||
if (TempData != Temp->Data)
|
||||
ifree(TempData);
|
||||
if (Temp != iCurImage)
|
||||
ilCloseImage(Temp);
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
ILboolean iSaveRleSgi(ILubyte *Data, ILuint w, ILuint h, ILuint numChannels,
|
||||
ILuint bps)
|
||||
{
|
||||
//works only for sgi files with only 1 bpc
|
||||
|
||||
ILuint c, i, y, j;
|
||||
ILubyte *ScanLine = NULL, *CompLine = NULL;
|
||||
ILuint *StartTable = NULL, *LenTable = NULL;
|
||||
ILuint TableOff, DataOff = 0;
|
||||
|
||||
ScanLine = (ILubyte*)ialloc(w);
|
||||
CompLine = (ILubyte*)ialloc(w * 2 + 1); // Absolute worst case.
|
||||
StartTable = (ILuint*)ialloc(h * numChannels * sizeof(ILuint));
|
||||
LenTable = (ILuint*)icalloc(h * numChannels, sizeof(ILuint));
|
||||
if (!ScanLine || !CompLine || !StartTable || !LenTable) {
|
||||
ifree(ScanLine);
|
||||
ifree(CompLine);
|
||||
ifree(StartTable);
|
||||
ifree(LenTable);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
// These just contain dummy values at this point.
|
||||
TableOff = itellw();
|
||||
iwrite(StartTable, sizeof(ILuint), h * numChannels);
|
||||
iwrite(LenTable, sizeof(ILuint), h * numChannels);
|
||||
|
||||
DataOff = itellw();
|
||||
for (c = 0; c < numChannels; c++) {
|
||||
for (y = 0; y < h; y++) {
|
||||
i = y * bps + c;
|
||||
for (j = 0; j < w; j++, i += numChannels) {
|
||||
ScanLine[j] = Data[i];
|
||||
}
|
||||
|
||||
ilRleCompressLine(ScanLine, w, 1, CompLine, LenTable + h * c + y, IL_SGICOMP);
|
||||
iwrite(CompLine, 1, *(LenTable + h * c + y));
|
||||
}
|
||||
}
|
||||
|
||||
iseekw(TableOff, IL_SEEK_SET);
|
||||
|
||||
j = h * numChannels;
|
||||
for (y = 0; y < j; y++) {
|
||||
StartTable[y] = DataOff;
|
||||
DataOff += LenTable[y];
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
iSwapUInt(&StartTable[y]);
|
||||
iSwapUInt(&LenTable[y]);
|
||||
#endif
|
||||
}
|
||||
|
||||
iwrite(StartTable, sizeof(ILuint), h * numChannels);
|
||||
iwrite(LenTable, sizeof(ILuint), h * numChannels);
|
||||
|
||||
ifree(ScanLine);
|
||||
ifree(CompLine);
|
||||
ifree(StartTable);
|
||||
ifree(LenTable);
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#endif//IL_NO_SGI
|
||||
605
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_stack.c
Normal file
605
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_stack.c
Normal file
@@ -0,0 +1,605 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2001 by Denton Woods
|
||||
// Last modified: 12/25/2001 <--Y2K Compliant! =]
|
||||
//
|
||||
// Filename: src-IL/src/il_stack.c
|
||||
//
|
||||
// Description: The main image stack
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Credit goes to John Villar (johnny@reliaschev.com) for making the suggestion
|
||||
// of not letting the user use ILimage structs but instead binding images
|
||||
// like OpenGL.
|
||||
|
||||
#include "il_internal.h"
|
||||
#include "il_stack.h"
|
||||
|
||||
//! Creates Num images and puts their index in Images - similar to glGenTextures().
|
||||
ILvoid ILAPIENTRY ilGenImages(ILsizei Num, ILuint *Images)
|
||||
{
|
||||
ILsizei Index = 0;
|
||||
iFree *TempFree = FreeNames;
|
||||
|
||||
if (Num < 1 || Images == NULL) {
|
||||
ilSetError(IL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
|
||||
// No images have been generated yet, so create the image stack.
|
||||
if (ImageStack == NULL)
|
||||
if (!iEnlargeStack())
|
||||
return;
|
||||
|
||||
do {
|
||||
if (FreeNames != NULL) { // If any have been deleted, then reuse their image names.
|
||||
TempFree = (iFree*)FreeNames->Next;
|
||||
Images[Index] = FreeNames->Name;
|
||||
ImageStack[FreeNames->Name] = ilNewImage(1, 1, 1, 1, 1);
|
||||
ifree(FreeNames);
|
||||
FreeNames = TempFree;
|
||||
} else {
|
||||
if (LastUsed >= StackSize)
|
||||
if (!iEnlargeStack())
|
||||
return;
|
||||
Images[Index] = LastUsed;
|
||||
// Must be all 1's instead of 0's, because some functions would divide by 0.
|
||||
ImageStack[LastUsed] = ilNewImage(1, 1, 1, 1, 1);
|
||||
LastUsed++;
|
||||
}
|
||||
} while (++Index < Num);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ILint ILAPIENTRY ilGenImage() {
|
||||
ILuint i;
|
||||
ilGenImages(1,&i);
|
||||
return i;
|
||||
}
|
||||
|
||||
//! Makes Image the current active image - similar to glBindTexture().
|
||||
ILvoid ILAPIENTRY ilBindImage(ILuint Image)
|
||||
{
|
||||
if (ImageStack == NULL || StackSize == 0) {
|
||||
if (!iEnlargeStack()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If the user requests a high image name.
|
||||
while (Image >= StackSize) {
|
||||
if (!iEnlargeStack()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (ImageStack[Image] == NULL) {
|
||||
ImageStack[Image] = ilNewImage(1, 1, 1, 1, 1);
|
||||
if (Image >= LastUsed) // >= ?
|
||||
LastUsed = Image + 1;
|
||||
}
|
||||
|
||||
iCurImage = ImageStack[Image];
|
||||
CurName = Image;
|
||||
|
||||
ParentImage = IL_TRUE;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//! Deletes Num images from the image stack - similar to glDeleteTextures().
|
||||
ILvoid ILAPIENTRY ilDeleteImages(ILsizei Num, const ILuint *Images)
|
||||
{
|
||||
iFree *Temp = FreeNames;
|
||||
ILuint Index = 0;
|
||||
|
||||
if (Num < 1) {
|
||||
//ilSetError(IL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
if (StackSize == 0)
|
||||
return;
|
||||
|
||||
do {
|
||||
if (Images[Index] > 0 && Images[Index] < LastUsed) { // <= ?
|
||||
/*if (FreeNames != NULL) { // Terribly inefficient
|
||||
Temp = FreeNames;
|
||||
do {
|
||||
if (Temp->Name == Images[Index]) {
|
||||
continue; // Sufficient?
|
||||
}
|
||||
} while ((Temp = Temp->Next));
|
||||
}*/
|
||||
|
||||
// Already has been deleted or was never used.
|
||||
if (ImageStack[Images[Index]] == NULL)
|
||||
continue;
|
||||
|
||||
// Find out if current image - if so, set to default image zero.
|
||||
if (Images[Index] == CurName || Images[Index] == 0) {
|
||||
iCurImage = ImageStack[0];
|
||||
CurName = 0;
|
||||
}
|
||||
|
||||
// Should *NOT* be NULL here!
|
||||
ilCloseImage(ImageStack[Images[Index]]);
|
||||
ImageStack[Images[Index]] = NULL;
|
||||
|
||||
// Add to head of list - works for empty and non-empty lists
|
||||
Temp = (iFree*)ialloc(sizeof(iFree));
|
||||
if (!Temp) {
|
||||
return;
|
||||
}
|
||||
Temp->Name = Images[Index];
|
||||
Temp->Next = FreeNames;
|
||||
FreeNames = Temp;
|
||||
}
|
||||
/*else { // Shouldn't set an error...just continue onward.
|
||||
ilSetError(IL_ILLEGAL_OPERATION);
|
||||
}*/
|
||||
} while (++Index < (ILuint)Num);
|
||||
}
|
||||
|
||||
|
||||
ILvoid ILAPIENTRY ilDeleteImage(const ILuint Num) {
|
||||
ilDeleteImages(1,&Num);
|
||||
}
|
||||
|
||||
//! Checks if Image is a valid ilGenImages-generated image (like glIsTexture()).
|
||||
ILboolean ILAPIENTRY ilIsImage(ILuint Image)
|
||||
{
|
||||
//iFree *Temp = FreeNames;
|
||||
|
||||
if (ImageStack == NULL)
|
||||
return IL_FALSE;
|
||||
if (Image >= LastUsed || Image == 0)
|
||||
return IL_FALSE;
|
||||
|
||||
/*do {
|
||||
if (Temp->Name == Image)
|
||||
return IL_FALSE;
|
||||
} while ((Temp = Temp->Next));*/
|
||||
|
||||
if (ImageStack[Image] == NULL) // Easier check.
|
||||
return IL_FALSE;
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
//! Closes Image and frees all memory associated with it.
|
||||
ILAPI ILvoid ILAPIENTRY ilCloseImage(ILimage *Image)
|
||||
{
|
||||
if (Image == NULL)
|
||||
return;
|
||||
|
||||
if (Image->Data != NULL) {
|
||||
ifree(Image->Data);
|
||||
Image->Data = NULL;
|
||||
}
|
||||
|
||||
if (Image->Pal.Palette != NULL && Image->Pal.PalSize > 0 && Image->Pal.PalType != IL_PAL_NONE) {
|
||||
ifree(Image->Pal.Palette);
|
||||
Image->Pal.Palette = NULL;
|
||||
}
|
||||
|
||||
if (Image->Next != NULL) {
|
||||
ilCloseImage(Image->Next);
|
||||
Image->Next = NULL;
|
||||
}
|
||||
|
||||
if (Image->Mipmaps != NULL) {
|
||||
ilCloseImage(Image->Mipmaps);
|
||||
Image->Mipmaps = NULL;
|
||||
}
|
||||
|
||||
if (Image->Layers != NULL) {
|
||||
ilCloseImage(Image->Layers);
|
||||
Image->Layers = NULL;
|
||||
}
|
||||
|
||||
if (Image->AnimList != NULL && Image->AnimSize != 0) {
|
||||
ifree(Image->AnimList);
|
||||
Image->AnimList = NULL;
|
||||
}
|
||||
|
||||
if (Image->Profile != NULL && Image->ProfileSize != 0) {
|
||||
ifree(Image->Profile);
|
||||
Image->Profile = NULL;
|
||||
Image->ProfileSize = 0;
|
||||
}
|
||||
|
||||
if (Image->DxtcData != NULL && Image->DxtcFormat != IL_DXT_NO_COMP) {
|
||||
ifree(Image->DxtcData);
|
||||
Image->DxtcData = NULL;
|
||||
Image->DxtcFormat = IL_DXT_NO_COMP;
|
||||
Image->DxtcSize = 0;
|
||||
}
|
||||
|
||||
ifree(Image);
|
||||
Image = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ILAPI ILboolean ILAPIENTRY ilIsValidPal(ILpal *Palette)
|
||||
{
|
||||
if (Palette == NULL)
|
||||
return IL_FALSE;
|
||||
if (Palette->PalSize == 0 || Palette->Palette == NULL)
|
||||
return IL_FALSE;
|
||||
switch (Palette->PalType)
|
||||
{
|
||||
case IL_PAL_RGB24:
|
||||
case IL_PAL_RGB32:
|
||||
case IL_PAL_RGBA32:
|
||||
case IL_PAL_BGR24:
|
||||
case IL_PAL_BGR32:
|
||||
case IL_PAL_BGRA32:
|
||||
return IL_TRUE;
|
||||
}
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
//! Closes Palette and frees all memory associated with it.
|
||||
ILAPI ILvoid ILAPIENTRY ilClosePal(ILpal *Palette)
|
||||
{
|
||||
if (Palette == NULL)
|
||||
return;
|
||||
if (!ilIsValidPal(Palette))
|
||||
return;
|
||||
ifree(Palette->Palette);
|
||||
ifree(Palette);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ILimage *iGetBaseImage()
|
||||
{
|
||||
return ImageStack[ilGetCurName()];
|
||||
}
|
||||
|
||||
|
||||
//! Sets the current mipmap level
|
||||
ILboolean ILAPIENTRY ilActiveMipmap(ILuint Number)
|
||||
{
|
||||
ILuint Current;
|
||||
ILimage *iTempImage;
|
||||
|
||||
if (iCurImage == NULL) {
|
||||
ilSetError(IL_ILLEGAL_OPERATION);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
if (Number == 0) {
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
iTempImage = iCurImage;
|
||||
iCurImage = iCurImage->Mipmaps;
|
||||
for (Current = 1; Current < Number; Current++) {
|
||||
iCurImage = iCurImage->Next;
|
||||
if (iCurImage == NULL) {
|
||||
ilSetError(IL_INTERNAL_ERROR);
|
||||
iCurImage = iTempImage;
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
ParentImage = IL_FALSE;
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
//! Used for setting the current image if it is an animation.
|
||||
ILboolean ILAPIENTRY ilActiveImage(ILuint Number)
|
||||
{
|
||||
ILuint Current;
|
||||
ILimage *iTempImage;
|
||||
|
||||
if (iCurImage == NULL) {
|
||||
ilSetError(IL_ILLEGAL_OPERATION);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
if (Number == 0) {
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
iTempImage = iCurImage;
|
||||
iCurImage = iCurImage->Next;
|
||||
Number--; // Skip 0 (parent image)
|
||||
for (Current = 0; Current < Number; Current++) {
|
||||
iCurImage = iCurImage->Next;
|
||||
if (iCurImage == NULL) {
|
||||
ilSetError(IL_INTERNAL_ERROR);
|
||||
iCurImage = iTempImage;
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
ParentImage = IL_FALSE;
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
//! Used for setting the current layer if layers exist.
|
||||
ILboolean ILAPIENTRY ilActiveLayer(ILuint Number)
|
||||
{
|
||||
ILuint Current;
|
||||
ILimage *iTempImage;
|
||||
|
||||
if (iCurImage == NULL) {
|
||||
ilSetError(IL_ILLEGAL_OPERATION);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
if (Number == 0) {
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
iTempImage = iCurImage;
|
||||
iCurImage = iCurImage->Layers;
|
||||
//Number--; // Skip 0 (parent image)
|
||||
for (Current = 1; Current < Number; Current++) {
|
||||
iCurImage = iCurImage->Layers;
|
||||
if (iCurImage == NULL) {
|
||||
ilSetError(IL_INTERNAL_ERROR);
|
||||
iCurImage = iTempImage;
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
ParentImage = IL_FALSE;
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
ILuint ILAPIENTRY ilCreateSubImage(ILenum Type, ILuint Num)
|
||||
{
|
||||
ILimage *SubImage;
|
||||
ILuint Count ; // Create one before we go in the loop.
|
||||
|
||||
if (iCurImage == NULL) {
|
||||
ilSetError(IL_ILLEGAL_OPERATION);
|
||||
return 0;
|
||||
}
|
||||
if (Num == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (Type)
|
||||
{
|
||||
case IL_SUB_NEXT:
|
||||
if (iCurImage->Next)
|
||||
ilCloseImage(iCurImage->Next);
|
||||
iCurImage->Next = ilNewImage(1, 1, 1, 1, 1);
|
||||
SubImage = iCurImage->Next;
|
||||
break;
|
||||
|
||||
case IL_SUB_MIPMAP:
|
||||
if (iCurImage->Mipmaps)
|
||||
ilCloseImage(iCurImage->Mipmaps);
|
||||
iCurImage->Mipmaps = ilNewImage(1, 1, 1, 1, 1);
|
||||
SubImage = iCurImage->Mipmaps;
|
||||
break;
|
||||
|
||||
case IL_SUB_LAYER:
|
||||
if (iCurImage->Layers)
|
||||
ilCloseImage(iCurImage->Layers);
|
||||
iCurImage->Layers = ilNewImage(1, 1, 1, 1, 1);
|
||||
SubImage = iCurImage->Layers;
|
||||
break;
|
||||
|
||||
default:
|
||||
ilSetError(IL_INVALID_ENUM);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
if (SubImage == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (Count = 1; Count < Num; Count++) {
|
||||
SubImage->Next = ilNewImage(1, 1, 1, 1, 1);
|
||||
SubImage = SubImage->Next;
|
||||
if (SubImage == NULL)
|
||||
return Count;
|
||||
}
|
||||
|
||||
return Count;
|
||||
}
|
||||
|
||||
|
||||
// Returns the current index.
|
||||
ILAPI ILuint ILAPIENTRY ilGetCurName()
|
||||
{
|
||||
if (iCurImage == NULL || ImageStack == NULL || StackSize == 0)
|
||||
return 0;
|
||||
return CurName;
|
||||
}
|
||||
|
||||
|
||||
// Returns the current image.
|
||||
ILAPI ILimage* ILAPIENTRY ilGetCurImage()
|
||||
{
|
||||
return iCurImage;
|
||||
}
|
||||
|
||||
|
||||
// To be only used when the original image is going to be set back almost immediately.
|
||||
ILAPI ILvoid ILAPIENTRY ilSetCurImage(ILimage *Image)
|
||||
{
|
||||
iCurImage = Image;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Completely replaces the current image and the version in the image stack.
|
||||
ILAPI ILvoid ILAPIENTRY ilReplaceCurImage(ILimage *Image)
|
||||
{
|
||||
if (iCurImage) {
|
||||
ilActiveImage(0);
|
||||
ilCloseImage(iCurImage);
|
||||
}
|
||||
ImageStack[ilGetCurName()] = Image;
|
||||
iCurImage = Image;
|
||||
ParentImage = IL_TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Like realloc but sets new memory to 0.
|
||||
ILvoid* ILAPIENTRY ilRecalloc(ILvoid *Ptr, ILuint OldSize, ILuint NewSize)
|
||||
{
|
||||
ILvoid *Temp = ialloc(NewSize);
|
||||
ILuint CopySize = (OldSize < NewSize) ? OldSize : NewSize;
|
||||
|
||||
if (Temp != NULL) {
|
||||
if (Ptr != NULL) {
|
||||
memcpy(Temp, Ptr, CopySize);
|
||||
ifree(Ptr);
|
||||
}
|
||||
|
||||
Ptr = Temp;
|
||||
|
||||
if (OldSize < NewSize)
|
||||
imemclear((ILubyte*)Temp + OldSize, NewSize - OldSize);
|
||||
}
|
||||
|
||||
return Temp;
|
||||
}
|
||||
|
||||
|
||||
// Internal function to enlarge the image stack by I_STACK_INCREMENT members.
|
||||
ILboolean iEnlargeStack()
|
||||
{
|
||||
// 02-05-2001: Moved from ilGenImages().
|
||||
// Puts the cleanup function on the exit handler once.
|
||||
if (!OnExit) {
|
||||
#ifdef _MEM_DEBUG
|
||||
AddToAtexit(); // So iFreeMem doesn't get called after unfreed information.
|
||||
#endif//_MEM_DEBUG
|
||||
#if (!defined(_WIN32_WCE)) && (!defined(IL_STATIC_LIB))
|
||||
atexit((void*)ilShutDown);
|
||||
#endif
|
||||
OnExit = IL_TRUE;
|
||||
}
|
||||
|
||||
if (!(ImageStack = (ILimage**)ilRecalloc(ImageStack, StackSize * sizeof(ILimage*), (StackSize + I_STACK_INCREMENT) * sizeof(ILimage*)))) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
StackSize += I_STACK_INCREMENT;
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
static ILboolean IsInit = IL_FALSE;
|
||||
|
||||
// ONLY call at startup.
|
||||
ILvoid ILAPIENTRY ilInit()
|
||||
{
|
||||
// if it is already initialized skip initialization
|
||||
if (IsInit == IL_TRUE )
|
||||
return;
|
||||
|
||||
//ilSetMemory(NULL, NULL); Now useless 3/4/2006 (due to modification in il_alloc.c)
|
||||
ilSetError(IL_NO_ERROR);
|
||||
ilDefaultStates(); // Set states to their defaults.
|
||||
// Sets default file-reading callbacks.
|
||||
ilResetRead();
|
||||
ilResetWrite();
|
||||
#if (!defined(_WIN32_WCE)) && (!defined(IL_STATIC_LIB))
|
||||
atexit((void*)ilRemoveRegistered);
|
||||
#endif
|
||||
//_WIN32_WCE
|
||||
//ilShutDown();
|
||||
iSetImage0(); // Beware! Clears all existing textures!
|
||||
iBindImageTemp(); // Go ahead and create the temporary image.
|
||||
IsInit = IL_TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Frees any extra memory in the stack.
|
||||
// - Called on exit
|
||||
ILvoid ILAPIENTRY ilShutDown()
|
||||
{
|
||||
// if it is not initialized do not shutdown
|
||||
iFree* TempFree = (iFree*)FreeNames;
|
||||
ILuint i;
|
||||
|
||||
if (!IsInit)
|
||||
return;
|
||||
|
||||
if (!IsInit) { // Prevent from being called when not initialized.
|
||||
ilSetError(IL_ILLEGAL_OPERATION);
|
||||
return;
|
||||
}
|
||||
|
||||
while (TempFree != NULL) {
|
||||
FreeNames = (iFree*)TempFree->Next;
|
||||
ifree(TempFree);
|
||||
TempFree = FreeNames;
|
||||
}
|
||||
|
||||
//for (i = 0; i < LastUsed; i++) {
|
||||
for (i = 0; i < StackSize; i++) {
|
||||
if (ImageStack[i] != NULL)
|
||||
ilCloseImage(ImageStack[i]);
|
||||
}
|
||||
|
||||
if (ImageStack)
|
||||
ifree(ImageStack);
|
||||
ImageStack = NULL;
|
||||
LastUsed = 0;
|
||||
StackSize = 0;
|
||||
IsInit = IL_FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Initializes the image stack's first entry (default image) -- ONLY CALL ONCE!
|
||||
ILvoid iSetImage0()
|
||||
{
|
||||
if (ImageStack == NULL)
|
||||
if (!iEnlargeStack())
|
||||
return;
|
||||
|
||||
LastUsed = 1;
|
||||
CurName = 0;
|
||||
ParentImage = IL_TRUE;
|
||||
if (!ImageStack[0])
|
||||
ImageStack[0] = ilNewImage(1, 1, 1, 1, 1);
|
||||
iCurImage = ImageStack[0];
|
||||
ilDefaultImage();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ILAPI ILvoid ILAPIENTRY iBindImageTemp()
|
||||
{
|
||||
if (ImageStack == NULL || StackSize <= 1)
|
||||
if (!iEnlargeStack())
|
||||
return;
|
||||
|
||||
if (LastUsed <2 )
|
||||
LastUsed = 2;
|
||||
CurName = 1;
|
||||
ParentImage = IL_TRUE;
|
||||
if (!ImageStack[1])
|
||||
ImageStack[1] = ilNewImage(1, 1, 1, 1, 1);
|
||||
iCurImage = ImageStack[1];
|
||||
|
||||
return;
|
||||
}
|
||||
1111
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_states.c
Normal file
1111
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_states.c
Normal file
File diff suppressed because it is too large
Load Diff
886
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_targa.c
Normal file
886
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_targa.c
Normal file
@@ -0,0 +1,886 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2002 by Denton Woods
|
||||
// Last modified: 05/22/2002 <--Y2K Compliant! =]
|
||||
//
|
||||
// Filename: src-IL/src/il_targa.c
|
||||
//
|
||||
// Description: Reads from and writes to a targa (.tga) file.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "il_internal.h"
|
||||
#ifndef IL_NO_TGA
|
||||
#include "il_targa.h"
|
||||
//#include <time.h> // for ilMakeString()
|
||||
#include <string.h>
|
||||
#include "il_manip.h"
|
||||
#include "il_bits.h"
|
||||
|
||||
#ifdef DJGPP
|
||||
#include <dos.h>
|
||||
#endif
|
||||
|
||||
|
||||
//! Checks if the file specified in FileName is a valid Targa file.
|
||||
ILboolean ilIsValidTga(ILconst_string FileName)
|
||||
{
|
||||
ILHANDLE TargaFile;
|
||||
ILboolean bTarga = IL_FALSE;
|
||||
|
||||
if (!iCheckExtension(FileName, IL_TEXT("tga")) &&
|
||||
!iCheckExtension(FileName, IL_TEXT("vda")) &&
|
||||
!iCheckExtension(FileName, IL_TEXT("icb")) &&
|
||||
!iCheckExtension(FileName, IL_TEXT("vst"))) {
|
||||
ilSetError(IL_INVALID_EXTENSION);
|
||||
return bTarga;
|
||||
}
|
||||
|
||||
TargaFile = iopenr(FileName);
|
||||
if (TargaFile == NULL) {
|
||||
ilSetError(IL_COULD_NOT_OPEN_FILE);
|
||||
return bTarga;
|
||||
}
|
||||
|
||||
bTarga = ilIsValidTgaF(TargaFile);
|
||||
icloser(TargaFile);
|
||||
|
||||
return bTarga;
|
||||
}
|
||||
|
||||
|
||||
//! Checks if the ILHANDLE contains a valid Targa file at the current position.
|
||||
ILboolean ilIsValidTgaF(ILHANDLE File)
|
||||
{
|
||||
ILuint FirstPos;
|
||||
ILboolean bRet;
|
||||
|
||||
iSetInputFile(File);
|
||||
FirstPos = itell();
|
||||
bRet = iIsValidTarga();
|
||||
iseek(FirstPos, IL_SEEK_SET);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
//! Checks if Lump is a valid Targa lump.
|
||||
ILboolean ilIsValidTgaL(const ILvoid *Lump, ILuint Size)
|
||||
{
|
||||
iSetInputLump(Lump, Size);
|
||||
return iIsValidTarga();
|
||||
}
|
||||
|
||||
|
||||
// Internal function used to get the Targa header from the current file.
|
||||
ILboolean iGetTgaHead(TARGAHEAD *Header)
|
||||
{
|
||||
Header->IDLen = igetc();
|
||||
Header->ColMapPresent = igetc();
|
||||
Header->ImageType = igetc();
|
||||
Header->FirstEntry = GetLittleShort();
|
||||
Header->ColMapLen = GetLittleShort();
|
||||
Header->ColMapEntSize = igetc();
|
||||
|
||||
Header->OriginX = GetLittleShort();
|
||||
Header->OriginY = GetLittleShort();
|
||||
Header->Width = GetLittleUShort();
|
||||
Header->Height = GetLittleUShort();
|
||||
Header->Bpp = igetc();
|
||||
Header->ImageDesc = igetc();
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Internal function to get the header and check it.
|
||||
ILboolean iIsValidTarga()
|
||||
{
|
||||
TARGAHEAD Head;
|
||||
|
||||
if (!iGetTgaHead(&Head))
|
||||
return IL_FALSE;
|
||||
iseek(-(ILint)sizeof(TARGAHEAD), IL_SEEK_CUR);
|
||||
|
||||
return iCheckTarga(&Head);
|
||||
}
|
||||
|
||||
|
||||
// Internal function used to check if the HEADER is a valid Targa header.
|
||||
ILboolean iCheckTarga(TARGAHEAD *Header)
|
||||
{
|
||||
if (Header->Width == 0 || Header->Height == 0)
|
||||
return IL_FALSE;
|
||||
if (Header->Bpp != 8 && Header->Bpp != 15 && Header->Bpp != 16
|
||||
&& Header->Bpp != 24 && Header->Bpp != 32)
|
||||
return IL_FALSE;
|
||||
if (Header->ImageDesc & BIT_4) // Supposed to be set to 0
|
||||
return IL_FALSE;
|
||||
|
||||
// check type (added 20040218)
|
||||
if(Header->ImageType != TGA_NO_DATA
|
||||
&& Header->ImageType != TGA_COLMAP_UNCOMP
|
||||
&& Header->ImageType != TGA_UNMAP_UNCOMP
|
||||
&& Header->ImageType != TGA_BW_UNCOMP
|
||||
&& Header->ImageType != TGA_COLMAP_COMP
|
||||
&& Header->ImageType != TGA_UNMAP_COMP
|
||||
&& Header->ImageType != TGA_BW_COMP)
|
||||
return IL_FALSE;
|
||||
|
||||
// Doesn't work well with the bitshift so change it.
|
||||
if (Header->Bpp == 15)
|
||||
Header->Bpp = 16;
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
//! Reads a Targa file
|
||||
ILboolean ilLoadTarga(ILconst_string FileName)
|
||||
{
|
||||
ILHANDLE TargaFile;
|
||||
ILboolean bTarga = IL_FALSE;
|
||||
|
||||
TargaFile = iopenr(FileName);
|
||||
if (TargaFile == NULL) {
|
||||
ilSetError(IL_COULD_NOT_OPEN_FILE);
|
||||
return bTarga;
|
||||
}
|
||||
|
||||
bTarga = ilLoadTargaF(TargaFile);
|
||||
icloser(TargaFile);
|
||||
|
||||
return bTarga;
|
||||
}
|
||||
|
||||
|
||||
//! Reads an already-opened Targa file
|
||||
ILboolean ilLoadTargaF(ILHANDLE File) {
|
||||
ILuint FirstPos;
|
||||
ILboolean bRet;
|
||||
|
||||
iSetInputFile(File);
|
||||
FirstPos = itell();
|
||||
bRet = iLoadTargaInternal();
|
||||
iseek(FirstPos, IL_SEEK_SET);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
//! Reads from a memory "lump" that contains a Targa
|
||||
ILboolean ilLoadTargaL(const ILvoid *Lump, ILuint Size)
|
||||
{
|
||||
iSetInputLump(Lump, Size);
|
||||
return iLoadTargaInternal();
|
||||
}
|
||||
|
||||
|
||||
// Internal function used to load the Targa.
|
||||
ILboolean iLoadTargaInternal()
|
||||
{
|
||||
TARGAHEAD Header;
|
||||
ILboolean bTarga;
|
||||
ILenum iOrigin;
|
||||
|
||||
if (iCurImage == NULL) {
|
||||
ilSetError(IL_ILLEGAL_OPERATION);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
if (!iGetTgaHead(&Header))
|
||||
return IL_FALSE;
|
||||
if (!iCheckTarga(&Header)) {
|
||||
ilSetError(IL_INVALID_FILE_HEADER);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
switch (Header.ImageType)
|
||||
{
|
||||
case TGA_NO_DATA:
|
||||
ilSetError(IL_ILLEGAL_FILE_VALUE);
|
||||
return IL_FALSE;
|
||||
case TGA_COLMAP_UNCOMP:
|
||||
case TGA_COLMAP_COMP:
|
||||
bTarga = iReadColMapTga(&Header);
|
||||
break;
|
||||
case TGA_UNMAP_UNCOMP:
|
||||
case TGA_UNMAP_COMP:
|
||||
bTarga = iReadUnmapTga(&Header);
|
||||
break;
|
||||
case TGA_BW_UNCOMP:
|
||||
case TGA_BW_COMP:
|
||||
bTarga = iReadBwTga(&Header);
|
||||
break;
|
||||
default:
|
||||
ilSetError(IL_ILLEGAL_FILE_VALUE);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
// @JASON Extra Code to manipulate the image depending on
|
||||
// the Image Descriptor's origin bits.
|
||||
iOrigin = Header.ImageDesc & IMAGEDESC_ORIGIN_MASK;
|
||||
|
||||
switch (iOrigin)
|
||||
{
|
||||
case IMAGEDESC_TOPLEFT:
|
||||
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
|
||||
break;
|
||||
|
||||
case IMAGEDESC_TOPRIGHT:
|
||||
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
|
||||
iMirror();
|
||||
break;
|
||||
|
||||
case IMAGEDESC_BOTLEFT:
|
||||
iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
|
||||
break;
|
||||
|
||||
case IMAGEDESC_BOTRIGHT:
|
||||
iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
|
||||
iMirror();
|
||||
break;
|
||||
}
|
||||
|
||||
ilFixImage();
|
||||
|
||||
return bTarga;
|
||||
}
|
||||
|
||||
|
||||
ILboolean iReadColMapTga(TARGAHEAD *Header)
|
||||
{
|
||||
char ID[255];
|
||||
ILuint i;
|
||||
ILushort Pixel;
|
||||
|
||||
if (iread(ID, 1, Header->IDLen) != Header->IDLen)
|
||||
return IL_FALSE;
|
||||
|
||||
if (!ilTexImage(Header->Width, Header->Height, 1, (ILubyte)(Header->Bpp >> 3), 0, IL_UNSIGNED_BYTE, NULL)) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
if (iCurImage->Pal.Palette && iCurImage->Pal.PalSize)
|
||||
ifree(iCurImage->Pal.Palette);
|
||||
|
||||
iCurImage->Format = IL_COLOUR_INDEX;
|
||||
iCurImage->Pal.PalSize = Header->ColMapLen * (Header->ColMapEntSize >> 3);
|
||||
|
||||
switch (Header->ColMapEntSize)
|
||||
{
|
||||
case 16:
|
||||
iCurImage->Pal.PalType = IL_PAL_BGRA32;
|
||||
iCurImage->Pal.PalSize = Header->ColMapLen * 4;
|
||||
break;
|
||||
case 24:
|
||||
iCurImage->Pal.PalType = IL_PAL_BGR24;
|
||||
break;
|
||||
case 32:
|
||||
iCurImage->Pal.PalType = IL_PAL_BGRA32;
|
||||
break;
|
||||
default:
|
||||
// Should *never* reach here
|
||||
ilSetError(IL_ILLEGAL_FILE_VALUE);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
iCurImage->Pal.Palette = (ILubyte*)ialloc(iCurImage->Pal.PalSize);
|
||||
if (iCurImage->Pal.Palette == NULL) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
// Do we need to do something with FirstEntry? Like maybe:
|
||||
// iread(Image->Pal + Targa->FirstEntry, 1, Image->Pal.PalSize); ??
|
||||
if (Header->ColMapEntSize != 16) {
|
||||
if (iread(iCurImage->Pal.Palette, 1, iCurImage->Pal.PalSize) != iCurImage->Pal.PalSize)
|
||||
return IL_FALSE;
|
||||
}
|
||||
else {
|
||||
// 16 bit palette, so we have to break it up.
|
||||
for (i = 0; i < iCurImage->Pal.PalSize; i += 4) {
|
||||
Pixel = GetBigUShort();
|
||||
if (ieof())
|
||||
return IL_FALSE;
|
||||
iCurImage->Pal.Palette[3] = (Pixel & 0x8000) >> 12;
|
||||
iCurImage->Pal.Palette[0] = (Pixel & 0xFC00) >> 7;
|
||||
iCurImage->Pal.Palette[1] = (Pixel & 0x03E0) >> 2;
|
||||
iCurImage->Pal.Palette[2] = (Pixel & 0x001F) << 3;
|
||||
}
|
||||
}
|
||||
|
||||
if (Header->ImageType == TGA_COLMAP_COMP) {
|
||||
if (!iUncompressTgaData(iCurImage)) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (iread(iCurImage->Data, 1, iCurImage->SizeOfData) != iCurImage->SizeOfData) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
ILboolean iReadUnmapTga(TARGAHEAD *Header)
|
||||
{
|
||||
ILubyte Bpp;
|
||||
char ID[255];
|
||||
|
||||
if (iread(ID, 1, Header->IDLen) != Header->IDLen)
|
||||
return IL_FALSE;
|
||||
|
||||
/*if (Header->Bpp == 16)
|
||||
Bpp = 3;
|
||||
else*/
|
||||
Bpp = (ILubyte)(Header->Bpp >> 3);
|
||||
|
||||
if (!ilTexImage(Header->Width, Header->Height, 1, Bpp, 0, IL_UNSIGNED_BYTE, NULL)) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
switch (iCurImage->Bpp)
|
||||
{
|
||||
case 1:
|
||||
iCurImage->Format = IL_COLOUR_INDEX; // wtf? How is this possible?
|
||||
break;
|
||||
case 2: // 16-bit is not supported directly!
|
||||
//iCurImage->Format = IL_RGB5_A1;
|
||||
/*iCurImage->Format = IL_RGBA;
|
||||
iCurImage->Type = IL_UNSIGNED_SHORT_5_5_5_1_EXT;*/
|
||||
//iCurImage->Type = IL_UNSIGNED_SHORT_5_6_5_REV;
|
||||
|
||||
// Remove?
|
||||
//ilCloseImage(iCurImage);
|
||||
//ilSetError(IL_FORMAT_NOT_SUPPORTED);
|
||||
//return IL_FALSE;
|
||||
|
||||
/*iCurImage->Bpp = 4;
|
||||
iCurImage->Format = IL_BGRA;
|
||||
iCurImage->Type = IL_UNSIGNED_SHORT_1_5_5_5_REV;*/
|
||||
|
||||
iCurImage->Format = IL_BGR;
|
||||
|
||||
break;
|
||||
case 3:
|
||||
iCurImage->Format = IL_BGR;
|
||||
break;
|
||||
case 4:
|
||||
iCurImage->Format = IL_BGRA;
|
||||
break;
|
||||
default:
|
||||
ilSetError(IL_INVALID_VALUE);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
// @TODO: Determine this:
|
||||
// We assume that no palette is present, but it's possible...
|
||||
// Should we mess with it or not?
|
||||
|
||||
|
||||
if (Header->ImageType == TGA_UNMAP_COMP) {
|
||||
if (!iUncompressTgaData(iCurImage)) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (iread(iCurImage->Data, 1, iCurImage->SizeOfData) != iCurImage->SizeOfData) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Go ahead and expand it to 24-bit.
|
||||
if (Header->Bpp == 16) {
|
||||
if (!i16BitTarga(iCurImage))
|
||||
return IL_FALSE;
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
ILboolean iReadBwTga(TARGAHEAD *Header)
|
||||
{
|
||||
char ID[255];
|
||||
|
||||
if (iread(ID, 1, Header->IDLen) != Header->IDLen)
|
||||
return IL_FALSE;
|
||||
|
||||
// We assume that no palette is present, but it's possible...
|
||||
// Should we mess with it or not?
|
||||
|
||||
if (!ilTexImage(Header->Width, Header->Height, 1, (ILubyte)(Header->Bpp >> 3), IL_LUMINANCE, IL_UNSIGNED_BYTE, NULL)) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
if (Header->ImageType == TGA_BW_COMP) {
|
||||
if (!iUncompressTgaData(iCurImage)) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (iread(iCurImage->Data, 1, iCurImage->SizeOfData) != iCurImage->SizeOfData) {
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
ILboolean iUncompressTgaData(ILimage *Image)
|
||||
{
|
||||
ILuint BytesRead = 0, Size, RunLen, i;
|
||||
ILubyte Header, Color[4];
|
||||
ILint c;
|
||||
|
||||
Size = Image->Width * Image->Height * Image->Depth * Image->Bpp;
|
||||
|
||||
if (iGetHint(IL_MEM_SPEED_HINT) == IL_FASTEST)
|
||||
iPreCache(iCurImage->SizeOfData / 2);
|
||||
|
||||
while (BytesRead < Size) {
|
||||
Header = igetc();
|
||||
if (Header & BIT_7) {
|
||||
ClearBits(Header, BIT_7);
|
||||
if (iread(Color, 1, Image->Bpp) != Image->Bpp) {
|
||||
iUnCache();
|
||||
return IL_FALSE;
|
||||
}
|
||||
RunLen = (Header+1) * Image->Bpp;
|
||||
for (i = 0; i < RunLen; i += Image->Bpp) {
|
||||
for (c = 0; c < Image->Bpp; c++) {
|
||||
Image->Data[BytesRead+i+c] = Color[c];
|
||||
}
|
||||
}
|
||||
BytesRead += RunLen;
|
||||
}
|
||||
else {
|
||||
RunLen = (Header+1) * Image->Bpp;
|
||||
if (iread(Image->Data + BytesRead, 1, RunLen) != RunLen) {
|
||||
iUnCache();
|
||||
return IL_FALSE;
|
||||
}
|
||||
BytesRead += RunLen;
|
||||
}
|
||||
}
|
||||
|
||||
iUnCache();
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Pretty damn unoptimized
|
||||
ILboolean i16BitTarga(ILimage *Image)
|
||||
{
|
||||
ILushort *Temp1;
|
||||
ILubyte *Data, *Temp2;
|
||||
ILuint x, PixSize = Image->Width * Image->Height;
|
||||
|
||||
Data = (ILubyte*)ialloc(Image->Width * Image->Height * 3);
|
||||
Temp1 = (ILushort*)Image->Data;
|
||||
Temp2 = Data;
|
||||
|
||||
if (Data == NULL)
|
||||
return IL_FALSE;
|
||||
|
||||
for (x = 0; x < PixSize; x++) {
|
||||
*Temp2++ = (*Temp1 & 0x001F) << 3; // Blue
|
||||
*Temp2++ = (*Temp1 & 0x03E0) >> 2; // Green
|
||||
*Temp2++ = (*Temp1 & 0x7C00) >> 7; // Red
|
||||
|
||||
Temp1++;
|
||||
|
||||
|
||||
/*s = *Temp;
|
||||
s = SwapShort(s);
|
||||
a = !!(s & BIT_15);
|
||||
|
||||
s = s << 1;
|
||||
|
||||
//if (a) {
|
||||
SetBits(s, BIT_0);
|
||||
//}
|
||||
|
||||
//SetBits(s, BIT_15);
|
||||
|
||||
*Temp++ = s;*/
|
||||
}
|
||||
|
||||
if (!ilTexImage(Image->Width, Image->Height, 1, 3, IL_BGR, IL_UNSIGNED_BYTE, Data)) {
|
||||
ifree(Data);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
ifree(Data);
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
//! Writes a Targa file
|
||||
ILboolean ilSaveTarga(ILconst_string FileName)
|
||||
{
|
||||
ILHANDLE TargaFile;
|
||||
ILboolean bTarga = IL_FALSE;
|
||||
|
||||
if (ilGetBoolean(IL_FILE_MODE) == IL_FALSE) {
|
||||
if (iFileExists(FileName)) {
|
||||
ilSetError(IL_FILE_ALREADY_EXISTS);
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
TargaFile = iopenw(FileName);
|
||||
if (TargaFile == NULL) {
|
||||
ilSetError(IL_COULD_NOT_OPEN_FILE);
|
||||
return bTarga;
|
||||
}
|
||||
|
||||
bTarga = ilSaveTargaF(TargaFile);
|
||||
iclosew(TargaFile);
|
||||
|
||||
return bTarga;
|
||||
}
|
||||
|
||||
|
||||
//! Writes a Targa to an already-opened file
|
||||
ILboolean ilSaveTargaF(ILHANDLE File)
|
||||
{
|
||||
iSetOutputFile(File);
|
||||
return iSaveTargaInternal();
|
||||
}
|
||||
|
||||
|
||||
//! Writes a Targa to a memory "lump"
|
||||
ILboolean ilSaveTargaL(ILvoid *Lump, ILuint Size)
|
||||
{
|
||||
iSetOutputLump(Lump, Size);
|
||||
return iSaveTargaInternal();
|
||||
}
|
||||
|
||||
|
||||
// Internal function used to save the Targa.
|
||||
ILboolean iSaveTargaInternal()
|
||||
{
|
||||
char *ID = iGetString(IL_TGA_ID_STRING);
|
||||
char *AuthName = iGetString(IL_TGA_AUTHNAME_STRING);
|
||||
char *AuthComment = iGetString(IL_TGA_AUTHCOMMENT_STRING);
|
||||
ILubyte IDLen = 0, UsePal, Type, PalEntSize;
|
||||
ILshort ColMapStart = 0, PalSize;
|
||||
ILubyte Temp;
|
||||
ILenum Format;
|
||||
ILboolean Compress;
|
||||
ILuint RleLen;
|
||||
ILubyte *Rle;
|
||||
ILpal *TempPal = NULL;
|
||||
ILimage *TempImage = NULL;
|
||||
ILuint ExtOffset, i;
|
||||
char *Footer = "TRUEVISION-XFILE.\0";
|
||||
char *idString = "Developer's Image Library (DevIL)";
|
||||
ILuint Day, Month, Year, Hour, Minute, Second;
|
||||
char *TempData;
|
||||
|
||||
if (iCurImage == NULL) {
|
||||
ilSetError(IL_ILLEGAL_OPERATION);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
if (iGetInt(IL_TGA_RLE) == IL_TRUE)
|
||||
Compress = IL_TRUE;
|
||||
else
|
||||
Compress = IL_FALSE;
|
||||
|
||||
if (ID)
|
||||
IDLen = (ILubyte)strlen(ID);
|
||||
|
||||
if (iCurImage->Pal.Palette && iCurImage->Pal.PalSize && iCurImage->Pal.PalType != IL_PAL_NONE)
|
||||
UsePal = IL_TRUE;
|
||||
else
|
||||
UsePal = IL_FALSE;
|
||||
|
||||
iwrite(&IDLen, sizeof(ILubyte), 1);
|
||||
iwrite(&UsePal, sizeof(ILubyte), 1);
|
||||
|
||||
Format = iCurImage->Format;
|
||||
switch (Format) {
|
||||
case IL_COLOUR_INDEX:
|
||||
if (Compress)
|
||||
Type = 9;
|
||||
else
|
||||
Type = 1;
|
||||
break;
|
||||
case IL_BGR:
|
||||
case IL_BGRA:
|
||||
if (Compress)
|
||||
Type = 10;
|
||||
else
|
||||
Type = 2;
|
||||
break;
|
||||
case IL_RGB:
|
||||
case IL_RGBA:
|
||||
ilSwapColours();
|
||||
if (Compress)
|
||||
Type = 10;
|
||||
else
|
||||
Type = 2;
|
||||
break;
|
||||
case IL_LUMINANCE:
|
||||
if (Compress)
|
||||
Type = 11;
|
||||
else
|
||||
Type = 3;
|
||||
break;
|
||||
default:
|
||||
// Should convert the types here...
|
||||
ilSetError(IL_INVALID_VALUE);
|
||||
ifree(ID);
|
||||
ifree(AuthName);
|
||||
ifree(AuthComment);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
iwrite(&Type, sizeof(ILubyte), 1);
|
||||
SaveLittleShort(ColMapStart);
|
||||
|
||||
switch (iCurImage->Pal.PalType)
|
||||
{
|
||||
case IL_PAL_NONE:
|
||||
PalSize = 0;
|
||||
PalEntSize = 0;
|
||||
break;
|
||||
case IL_PAL_BGR24:
|
||||
PalSize = iCurImage->Pal.PalSize / 3;
|
||||
PalEntSize = 24;
|
||||
TempPal = &iCurImage->Pal;
|
||||
break;
|
||||
|
||||
case IL_PAL_RGB24:
|
||||
case IL_PAL_RGB32:
|
||||
case IL_PAL_RGBA32:
|
||||
case IL_PAL_BGR32:
|
||||
case IL_PAL_BGRA32:
|
||||
TempPal = iConvertPal(&iCurImage->Pal, IL_PAL_BGR24);
|
||||
if (TempPal == NULL)
|
||||
return IL_FALSE;
|
||||
PalSize = TempPal->PalSize / 3;
|
||||
PalEntSize = 24;
|
||||
break;
|
||||
default:
|
||||
ilSetError(IL_INVALID_VALUE);
|
||||
ifree(ID);
|
||||
ifree(AuthName);
|
||||
ifree(AuthComment);
|
||||
PalSize = 0;
|
||||
PalEntSize = 0;
|
||||
return IL_FALSE;
|
||||
}
|
||||
SaveLittleShort(PalSize);
|
||||
iwrite(&PalEntSize, sizeof(ILubyte), 1);
|
||||
|
||||
if (iCurImage->Bpc > 1) {
|
||||
TempImage = iConvertImage(iCurImage, iCurImage->Format, IL_UNSIGNED_BYTE);
|
||||
if (TempImage == NULL) {
|
||||
ifree(ID);
|
||||
ifree(AuthName);
|
||||
ifree(AuthComment);
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
TempImage = iCurImage;
|
||||
}
|
||||
|
||||
if (TempImage->Origin != IL_ORIGIN_LOWER_LEFT)
|
||||
TempData = (char*)iGetFlipped(TempImage);
|
||||
else
|
||||
TempData = (char*)TempImage->Data;
|
||||
|
||||
// Write out the origin stuff.
|
||||
Temp = 0;
|
||||
iwrite(&Temp, sizeof(ILshort), 1);
|
||||
iwrite(&Temp, sizeof(ILshort), 1);
|
||||
|
||||
Temp = iCurImage->Bpp << 3; // Changes to bits per pixel
|
||||
SaveLittleUShort((ILushort)iCurImage->Width);
|
||||
SaveLittleUShort((ILushort)iCurImage->Height);
|
||||
iwrite(&Temp, sizeof(ILubyte), 1);
|
||||
|
||||
// Still don't know what exactly this is for...
|
||||
Temp = 0;
|
||||
iwrite(&Temp, sizeof(ILubyte), 1);
|
||||
iwrite(ID, sizeof(char), IDLen);
|
||||
ifree(ID);
|
||||
//iwrite(ID, sizeof(ILbyte), IDLen - sizeof(ILuint));
|
||||
//iwrite(&iCurImage->Depth, sizeof(ILuint), 1);
|
||||
|
||||
// Write out the colormap
|
||||
if (UsePal)
|
||||
iwrite(TempPal->Palette, sizeof(ILubyte), TempPal->PalSize);
|
||||
// else do nothing
|
||||
|
||||
if (!Compress)
|
||||
iwrite(TempData, sizeof(ILubyte), TempImage->SizeOfData);
|
||||
else {
|
||||
Rle = (ILubyte*)ialloc(TempImage->SizeOfData + TempImage->SizeOfData / 2 + 1); // max
|
||||
if (Rle == NULL) {
|
||||
ifree(AuthName);
|
||||
ifree(AuthComment);
|
||||
return IL_FALSE;
|
||||
}
|
||||
RleLen = ilRleCompress((unsigned char*)TempData, TempImage->Width, TempImage->Height,
|
||||
TempImage->Depth, TempImage->Bpp, Rle, IL_TGACOMP, NULL);
|
||||
|
||||
iwrite(Rle, 1, RleLen);
|
||||
ifree(Rle);
|
||||
}
|
||||
|
||||
// Write the extension area.
|
||||
ExtOffset = itellw();
|
||||
SaveLittleUShort(495); // Number of bytes in the extension area (TGA 2.0 spec)
|
||||
iwrite(AuthName, 1, ilStrLen(AuthName));
|
||||
ipad(41 - ilStrLen(AuthName));
|
||||
iwrite(AuthComment, 1, ilStrLen(AuthComment));
|
||||
ipad(324 - ilStrLen(AuthComment));
|
||||
ifree(AuthName);
|
||||
ifree(AuthComment);
|
||||
|
||||
// Write time/date
|
||||
iGetDateTime(&Month, &Day, &Year, &Hour, &Minute, &Second);
|
||||
SaveLittleUShort((ILushort)Month);
|
||||
SaveLittleUShort((ILushort)Day);
|
||||
SaveLittleUShort((ILushort)Year);
|
||||
SaveLittleUShort((ILushort)Hour);
|
||||
SaveLittleUShort((ILushort)Minute);
|
||||
SaveLittleUShort((ILushort)Second);
|
||||
|
||||
for (i = 0; i < 6; i++) { // Time created
|
||||
SaveLittleUShort(0);
|
||||
}
|
||||
for (i = 0; i < 41; i++) { // Job name/ID
|
||||
iputc(0);
|
||||
}
|
||||
for (i = 0; i < 3; i++) { // Job time
|
||||
SaveLittleUShort(0);
|
||||
}
|
||||
|
||||
iwrite(idString, 1, strlen(idString)); // Software ID
|
||||
for (i = 0; i < 41 - strlen(idString); i++) {
|
||||
iputc(0);
|
||||
}
|
||||
SaveLittleUShort(IL_VERSION); // Software version
|
||||
iputc(' '); // Release letter (not beta anymore, so use a space)
|
||||
|
||||
SaveLittleUInt(0); // Key colour
|
||||
SaveLittleUInt(0); // Pixel aspect ratio
|
||||
SaveLittleUInt(0); // Gamma correction offset
|
||||
SaveLittleUInt(0); // Colour correction offset
|
||||
SaveLittleUInt(0); // Postage stamp offset
|
||||
SaveLittleUInt(0); // Scan line offset
|
||||
iputc(3); // Attributes type
|
||||
|
||||
// Write the footer.
|
||||
SaveLittleUInt(ExtOffset); // No extension area
|
||||
SaveLittleUInt(0); // No developer directory
|
||||
iwrite(Footer, 1, strlen(Footer));
|
||||
|
||||
if (TempImage->Origin != IL_ORIGIN_LOWER_LEFT) {
|
||||
ifree(TempData);
|
||||
}
|
||||
if (Format == IL_RGB || Format == IL_RGBA) {
|
||||
ilSwapColours();
|
||||
}
|
||||
|
||||
if (TempPal != &iCurImage->Pal && TempPal != NULL) {
|
||||
ifree(TempPal->Palette);
|
||||
ifree(TempPal);
|
||||
}
|
||||
|
||||
if (TempImage != iCurImage)
|
||||
ilCloseImage(TempImage);
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*// Makes a neat string to go into the id field of the .tga
|
||||
ILvoid iMakeString(char *Str)
|
||||
{
|
||||
char *PSG = "Generated by Developer's Image Library: ";
|
||||
char TimeStr[255];
|
||||
|
||||
time_t Time;
|
||||
struct tm *CurTime;
|
||||
|
||||
time(&Time);
|
||||
#ifdef _WIN32
|
||||
_tzset();
|
||||
#endif
|
||||
CurTime = localtime(&Time);
|
||||
|
||||
strftime(TimeStr, 255 - strlen(PSG), "%#c (%z)", CurTime);
|
||||
//strftime(TimeStr, 255 - strlen(PSG), "%C (%Z)", CurTime);
|
||||
sprintf(Str, "%s%s", PSG, TimeStr);
|
||||
|
||||
return;
|
||||
}*/
|
||||
|
||||
|
||||
//changed name to iGetDateTime on 20031221 to fix bug 830196
|
||||
ILvoid iGetDateTime(ILuint *Month, ILuint *Day, ILuint *Yr, ILuint *Hr, ILuint *Min, ILuint *Sec)
|
||||
{
|
||||
#ifdef DJGPP
|
||||
struct date day;
|
||||
struct time curtime;
|
||||
|
||||
gettime(&curtime);
|
||||
getdate(&day);
|
||||
|
||||
*Month = day.da_mon;
|
||||
*Day = day.da_day;
|
||||
*Yr = day.da_year;
|
||||
|
||||
*Hr = curtime.ti_hour;
|
||||
*Min = curtime.ti_min;
|
||||
*Sec = curtime.ti_sec;
|
||||
|
||||
return;
|
||||
#else
|
||||
|
||||
#ifdef _WIN32
|
||||
SYSTEMTIME Time;
|
||||
|
||||
GetSystemTime(&Time);
|
||||
|
||||
*Month = Time.wMonth;
|
||||
*Day = Time.wDay;
|
||||
*Yr = Time.wYear;
|
||||
|
||||
*Hr = Time.wHour;
|
||||
*Min = Time.wMinute;
|
||||
*Sec = Time.wSecond;
|
||||
|
||||
return;
|
||||
#else
|
||||
|
||||
*Month = 0;
|
||||
*Day = 0;
|
||||
*Yr = 0;
|
||||
|
||||
*Hr = 0;
|
||||
*Min = 0;
|
||||
*Sec = 0;
|
||||
|
||||
return;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#endif//IL_NO_TGA
|
||||
1074
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_tiff.c
Normal file
1074
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_tiff.c
Normal file
File diff suppressed because it is too large
Load Diff
155
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_utility.c
Normal file
155
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_utility.c
Normal file
@@ -0,0 +1,155 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2002 by Denton Woods
|
||||
// Last modified: 05/25/2001 <--Y2K Compliant! =]
|
||||
//
|
||||
// Filename: src-IL/src/il_utility.c
|
||||
//
|
||||
// Description: Utility functions
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "il_internal.h"
|
||||
|
||||
|
||||
// Returns the bpp of any Format
|
||||
ILAPI ILubyte ILAPIENTRY ilGetBppFormat(ILenum Format) {
|
||||
switch (Format) {
|
||||
case IL_COLOUR_INDEX:
|
||||
case IL_LUMINANCE:
|
||||
return 1;
|
||||
case IL_LUMINANCE_ALPHA:
|
||||
return 2;
|
||||
case IL_RGB:
|
||||
case IL_BGR:
|
||||
return 3;
|
||||
case IL_RGBA:
|
||||
case IL_BGRA:
|
||||
return 4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Returns the format of any bpp
|
||||
ILAPI ILenum ILAPIENTRY ilGetFormatBpp(ILubyte Bpp) {
|
||||
switch (Bpp) {
|
||||
case 1:
|
||||
return IL_LUMINANCE;
|
||||
case 2:
|
||||
return IL_LUMINANCE_ALPHA;
|
||||
case 3:
|
||||
return IL_RGB;
|
||||
case 4:
|
||||
return IL_RGBA;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Returns the bpc of any Type
|
||||
ILAPI ILubyte ILAPIENTRY ilGetBpcType(ILenum Type) {
|
||||
switch (Type) {
|
||||
case IL_BYTE:
|
||||
case IL_UNSIGNED_BYTE:
|
||||
return 1;
|
||||
case IL_SHORT:
|
||||
case IL_UNSIGNED_SHORT:
|
||||
case IL_HALF:
|
||||
return 2;
|
||||
case IL_INT:
|
||||
case IL_UNSIGNED_INT:
|
||||
case IL_FLOAT:
|
||||
return 4;
|
||||
case IL_DOUBLE:
|
||||
return 8;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Returns the type matching a bpc
|
||||
ILAPI ILenum ILAPIENTRY ilGetTypeBpc(ILubyte Bpc) {
|
||||
switch (Bpc) {
|
||||
case 1:
|
||||
return IL_UNSIGNED_BYTE;
|
||||
case 2:
|
||||
return IL_UNSIGNED_SHORT;
|
||||
case 4:
|
||||
return IL_UNSIGNED_INT;
|
||||
case 8:
|
||||
return IL_DOUBLE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Returns the bpp of any palette type (PalType)
|
||||
ILAPI ILubyte ILAPIENTRY ilGetBppPal(ILenum PalType) {
|
||||
switch (PalType) {
|
||||
case IL_PAL_RGB24:
|
||||
case IL_PAL_BGR24:
|
||||
return 3;
|
||||
case IL_PAL_RGB32:
|
||||
case IL_PAL_RGBA32:
|
||||
case IL_PAL_BGR32:
|
||||
case IL_PAL_BGRA32:
|
||||
return 4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Returns the base format of a palette type (PalType)
|
||||
ILAPI ILenum ILAPIENTRY ilGetPalBaseType(ILenum PalType) {
|
||||
switch (PalType) {
|
||||
case IL_PAL_RGB24:
|
||||
return IL_RGB;
|
||||
case IL_PAL_RGB32:
|
||||
return IL_RGBA; // Not sure
|
||||
case IL_PAL_RGBA32:
|
||||
return IL_RGBA;
|
||||
case IL_PAL_BGR24:
|
||||
return IL_BGR;
|
||||
case IL_PAL_BGR32:
|
||||
return IL_BGRA; // Not sure
|
||||
case IL_PAL_BGRA32:
|
||||
return IL_BGRA;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Returns the next power of 2 if Num isn't 2^n or returns Num if Num is 2^n
|
||||
ILAPI ILuint ILAPIENTRY ilNextPower2(ILuint n) {
|
||||
ILuint power = 1;
|
||||
while( power < n ) {
|
||||
power <<= 1;
|
||||
}
|
||||
return power;
|
||||
}
|
||||
|
||||
ILAPI ILvoid ILAPIENTRY iMemSwap( ILubyte *s1, ILubyte *s2, const ILuint size ) {
|
||||
const ILuint block_size = 4096;
|
||||
const ILuint blocks = size/block_size;
|
||||
ILuint i;
|
||||
|
||||
ILubyte *block = (ILubyte*)ialloc(block_size);
|
||||
if(block == NULL) return;
|
||||
for( i = 0; i < blocks; i++ ) {
|
||||
memcpy(block,s1,block_size);
|
||||
memcpy(s1,s2,block_size);
|
||||
memcpy(s2,block,block_size);
|
||||
s2 += block_size;
|
||||
s1 += block_size;
|
||||
}
|
||||
i = size - i*block_size;
|
||||
if( i > 0 ) {
|
||||
memcpy(block,s1,i);
|
||||
memcpy(s1,s2,i);
|
||||
memcpy(s2,block,i);
|
||||
}
|
||||
ifree(block);
|
||||
}
|
||||
179
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_wal.c
Normal file
179
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_wal.c
Normal file
@@ -0,0 +1,179 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2002 by Denton Woods
|
||||
// Last modified: 05/25/2001 <--Y2K Compliant! =]
|
||||
//
|
||||
// Filename: src-IL/src/il_wal.c
|
||||
//
|
||||
// Description: Loads a Quake .wal texture.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "il_internal.h"
|
||||
#ifndef IL_NO_WAL
|
||||
#include "il_manip.h"
|
||||
#include "il_q2pal.h"
|
||||
|
||||
|
||||
typedef struct WALHEAD
|
||||
{
|
||||
ILbyte FileName[32]; // Image name
|
||||
ILuint Width; // Width of first image
|
||||
ILuint Height; // Height of first image
|
||||
ILuint Offsets[4]; // Offsets to image data
|
||||
ILbyte AnimName[32]; // Name of next frame
|
||||
ILuint Flags; // ??
|
||||
ILuint Contents; // ??
|
||||
ILuint Value; // ??
|
||||
} WALHEAD;
|
||||
|
||||
ILboolean iLoadWalInternal(ILvoid);
|
||||
|
||||
|
||||
//! Reads a .wal file
|
||||
ILboolean ilLoadWal(ILconst_string FileName)
|
||||
{
|
||||
ILHANDLE WalFile;
|
||||
ILboolean bWal = IL_FALSE;
|
||||
|
||||
WalFile = iopenr(FileName);
|
||||
if (WalFile == NULL) {
|
||||
ilSetError(IL_COULD_NOT_OPEN_FILE);
|
||||
return bWal;
|
||||
}
|
||||
|
||||
bWal = ilLoadWalF(WalFile);
|
||||
icloser(WalFile);
|
||||
|
||||
return bWal;
|
||||
}
|
||||
|
||||
|
||||
//! Reads an already-opened .wal file
|
||||
ILboolean ilLoadWalF(ILHANDLE File)
|
||||
{
|
||||
ILuint FirstPos;
|
||||
ILboolean bRet;
|
||||
|
||||
iSetInputFile(File);
|
||||
FirstPos = itell();
|
||||
bRet = iLoadWalInternal();
|
||||
iseek(FirstPos, IL_SEEK_SET);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
//! Reads from a memory "lump" that contains a .wal file
|
||||
ILboolean ilLoadWalL(const ILvoid *Lump, ILuint Size)
|
||||
{
|
||||
iSetInputLump(Lump, Size);
|
||||
return iLoadWalInternal();
|
||||
}
|
||||
|
||||
|
||||
ILboolean iLoadWalInternal()
|
||||
{
|
||||
WALHEAD Header;
|
||||
ILimage *Mipmaps[3], *CurImage;
|
||||
ILuint i, NewW, NewH;
|
||||
|
||||
if (iCurImage == NULL) {
|
||||
ilSetError(IL_ILLEGAL_OPERATION);
|
||||
return IL_FALSE;
|
||||
}
|
||||
CurImage = iCurImage;
|
||||
|
||||
|
||||
//read header
|
||||
|
||||
iread(&Header.FileName, 1, 32);
|
||||
|
||||
Header.Width = GetLittleUInt();
|
||||
|
||||
Header.Height = GetLittleUInt();
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
|
||||
Header.Offsets[i] = GetLittleUInt();
|
||||
|
||||
iread(Header.AnimName, 1, 32);
|
||||
|
||||
Header.Flags = GetLittleUInt();
|
||||
|
||||
Header.Contents = GetLittleUInt();
|
||||
|
||||
Header.Value = GetLittleUInt();
|
||||
|
||||
|
||||
if (!ilTexImage(Header.Width, Header.Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL))
|
||||
return IL_FALSE;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
Mipmaps[i] = (ILimage*)icalloc(sizeof(ILimage), 1);
|
||||
if (Mipmaps[i] == NULL)
|
||||
goto cleanup_error;
|
||||
Mipmaps[i]->Pal.Palette = (ILubyte*)ialloc(768);
|
||||
if (Mipmaps[i]->Pal.Palette == NULL)
|
||||
goto cleanup_error;
|
||||
memcpy(Mipmaps[i]->Pal.Palette, ilDefaultQ2Pal, 768);
|
||||
Mipmaps[i]->Pal.PalType = IL_PAL_RGB24;
|
||||
}
|
||||
|
||||
NewW = Header.Width;
|
||||
NewH = Header.Height;
|
||||
for (i = 0; i < 3; i++) {
|
||||
NewW /= 2;
|
||||
NewH /= 2;
|
||||
iCurImage = Mipmaps[i];
|
||||
if (!ilTexImage(NewW, NewH, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL))
|
||||
goto cleanup_error;
|
||||
// Don't set until now so ilTexImage won't get rid of the palette.
|
||||
Mipmaps[i]->Pal.PalSize = 768;
|
||||
Mipmaps[i]->Origin = IL_ORIGIN_UPPER_LEFT;
|
||||
}
|
||||
|
||||
iCurImage = CurImage;
|
||||
ilCloseImage(iCurImage->Mipmaps);
|
||||
iCurImage->Mipmaps = Mipmaps[0];
|
||||
Mipmaps[0]->Next = Mipmaps[1];
|
||||
Mipmaps[1]->Next = Mipmaps[2];
|
||||
|
||||
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
|
||||
|
||||
if (iCurImage->Pal.Palette && iCurImage->Pal.PalSize && iCurImage->Pal.PalType != IL_PAL_NONE)
|
||||
ifree(iCurImage->Pal.Palette);
|
||||
iCurImage->Pal.Palette = (ILubyte*)ialloc(768);
|
||||
if (iCurImage->Pal.Palette == NULL)
|
||||
goto cleanup_error;
|
||||
|
||||
iCurImage->Pal.PalSize = 768;
|
||||
iCurImage->Pal.PalType = IL_PAL_RGB24;
|
||||
memcpy(iCurImage->Pal.Palette, ilDefaultQ2Pal, 768);
|
||||
|
||||
iseek(Header.Offsets[0], IL_SEEK_SET);
|
||||
if (iread(iCurImage->Data, Header.Width * Header.Height, 1) != 1)
|
||||
goto cleanup_error;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
iseek(Header.Offsets[i+1], IL_SEEK_SET);
|
||||
if (iread(Mipmaps[i]->Data, Mipmaps[i]->Width * Mipmaps[i]->Height, 1) != 1)
|
||||
goto cleanup_error;
|
||||
}
|
||||
|
||||
// Fixes all images, even mipmaps.
|
||||
ilFixImage();
|
||||
|
||||
return IL_TRUE;
|
||||
|
||||
cleanup_error:
|
||||
for (i = 0; i < 3; i++) {
|
||||
ilCloseImage(Mipmaps[i]);
|
||||
}
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
#endif//IL_NO_WAL
|
||||
789
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_xpm.c
Normal file
789
rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_xpm.c
Normal file
@@ -0,0 +1,789 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ImageLib Sources
|
||||
// Copyright (C) 2000-2002 by Denton Woods
|
||||
// Last modified: 05/27/2002 <--Y2K Compliant! =]
|
||||
//
|
||||
// Filename: src-IL/src/il_xpm.c
|
||||
//
|
||||
// Description: Reads from an .xpm file.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "il_internal.h"
|
||||
#ifndef IL_NO_XPM
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
//If this is defined, only xpm files with 1 char/pixel
|
||||
|
||||
//can be loaded. They load somewhat faster then, though
|
||||
|
||||
//(not much).
|
||||
|
||||
//#define XPM_DONT_USE_HASHTABLE
|
||||
|
||||
ILboolean iLoadXpmInternal(ILvoid);
|
||||
|
||||
|
||||
// Reads an .xpm file
|
||||
ILboolean ilLoadXpm(ILconst_string FileName)
|
||||
{
|
||||
ILHANDLE XpmFile;
|
||||
ILboolean bXpm = IL_FALSE;
|
||||
|
||||
XpmFile = iopenr(FileName);
|
||||
if (XpmFile == NULL) {
|
||||
ilSetError(IL_COULD_NOT_OPEN_FILE);
|
||||
return bXpm;
|
||||
}
|
||||
|
||||
iSetInputFile(XpmFile);
|
||||
|
||||
bXpm = ilLoadXpmF(XpmFile);
|
||||
|
||||
icloser(XpmFile);
|
||||
|
||||
return bXpm;
|
||||
}
|
||||
|
||||
|
||||
//! Reads an already-opened .xpm file
|
||||
ILboolean ilLoadXpmF(ILHANDLE File)
|
||||
{
|
||||
ILuint FirstPos;
|
||||
ILboolean bRet;
|
||||
|
||||
iSetInputFile(File);
|
||||
FirstPos = itell();
|
||||
bRet = iLoadXpmInternal();
|
||||
iseek(FirstPos, IL_SEEK_SET);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
//! Reads from a memory "lump" that contains an .xpm
|
||||
ILboolean ilLoadXpmL( const ILvoid *Lump, ILuint Size) {
|
||||
iSetInputLump(Lump, Size);
|
||||
return iLoadXpmInternal();
|
||||
}
|
||||
|
||||
|
||||
typedef ILubyte XpmPixel[4];
|
||||
|
||||
#define XPM_MAX_CHAR_PER_PIXEL 2
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef XPM_DONT_USE_HASHTABLE
|
||||
|
||||
|
||||
|
||||
//The following hash table code was inspired by the xpm
|
||||
|
||||
//loading code of xv, one of the best image viewers of X11
|
||||
|
||||
|
||||
|
||||
//For xpm files with more than one character/pixel, it is
|
||||
|
||||
//impractical to use a simple lookup table for the
|
||||
|
||||
//character-to-color mapping (because the table requires
|
||||
|
||||
//2^(chars/pixel) entries, this is quite big).
|
||||
|
||||
//Because of that, a hash table is used for the mapping.
|
||||
|
||||
//The hash table has 257 entries, and collisions are
|
||||
|
||||
//resolved by chaining.
|
||||
|
||||
|
||||
|
||||
//257 is the smallest prime > 256
|
||||
|
||||
#define XPM_HASH_LEN 257
|
||||
|
||||
|
||||
|
||||
typedef struct XPMHASHENTRY
|
||||
|
||||
{
|
||||
|
||||
ILubyte ColourName[XPM_MAX_CHAR_PER_PIXEL];
|
||||
|
||||
XpmPixel ColourValue;
|
||||
|
||||
struct XPMHASHENTRY *Next;
|
||||
|
||||
} XPMHASHENTRY;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static ILuint XpmHash(const ILubyte* name, int len)
|
||||
|
||||
{
|
||||
|
||||
ILint i, sum;
|
||||
|
||||
for (sum = i = 0; i < len; ++i)
|
||||
|
||||
sum += name[i];
|
||||
|
||||
return sum % XPM_HASH_LEN;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
XPMHASHENTRY** XpmCreateHashTable()
|
||||
|
||||
{
|
||||
|
||||
XPMHASHENTRY** Table =
|
||||
|
||||
(XPMHASHENTRY**)ialloc(XPM_HASH_LEN*sizeof(XPMHASHENTRY*));
|
||||
|
||||
if (Table != NULL)
|
||||
|
||||
memset(Table, 0, XPM_HASH_LEN*sizeof(XPMHASHENTRY*));
|
||||
|
||||
return Table;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void XpmDestroyHashTable(XPMHASHENTRY **Table)
|
||||
|
||||
{
|
||||
|
||||
ILint i;
|
||||
|
||||
XPMHASHENTRY* Entry;
|
||||
|
||||
|
||||
|
||||
for (i = 0; i < XPM_HASH_LEN; ++i) {
|
||||
|
||||
while (Table[i] != NULL) {
|
||||
|
||||
Entry = Table[i]->Next;
|
||||
|
||||
ifree(Table[i]);
|
||||
|
||||
Table[i] = Entry;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
ifree(Table);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void XpmInsertEntry(XPMHASHENTRY **Table, const ILubyte* Name, int Len, XpmPixel Colour)
|
||||
|
||||
{
|
||||
|
||||
XPMHASHENTRY* NewEntry;
|
||||
|
||||
ILuint Index;
|
||||
|
||||
Index = XpmHash(Name, Len);
|
||||
|
||||
|
||||
|
||||
NewEntry = (XPMHASHENTRY*)ialloc(sizeof(XPMHASHENTRY));
|
||||
|
||||
if (NewEntry != NULL) {
|
||||
|
||||
NewEntry->Next = Table[Index];
|
||||
|
||||
memcpy(NewEntry->ColourName, Name, Len);
|
||||
|
||||
memcpy(NewEntry->ColourValue, Colour, sizeof(Colour));
|
||||
|
||||
Table[Index] = NewEntry;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void XpmGetEntry(XPMHASHENTRY **Table, const ILubyte* Name, int Len, XpmPixel Colour)
|
||||
|
||||
{
|
||||
|
||||
XPMHASHENTRY* Entry;
|
||||
|
||||
ILuint Index;
|
||||
|
||||
|
||||
|
||||
Index = XpmHash(Name, Len);
|
||||
|
||||
Entry = Table[Index];
|
||||
|
||||
while (Entry != NULL && strncmp((char*)(Entry->ColourName), (char*)Name, Len) != 0)
|
||||
|
||||
Entry = Entry->Next;
|
||||
|
||||
|
||||
|
||||
if (Entry != NULL)
|
||||
|
||||
memcpy(Colour, Entry->ColourValue, sizeof(Colour));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif //XPM_DONT_USE_HASHTABLE
|
||||
|
||||
|
||||
|
||||
|
||||
ILint XpmGetsInternal(ILubyte *Buffer, ILint MaxLen)
|
||||
{
|
||||
ILint i = 0, Current;
|
||||
|
||||
if (ieof())
|
||||
return IL_EOF;
|
||||
|
||||
while ((Current = igetc()) != IL_EOF && i < MaxLen - 1) {
|
||||
if (Current == IL_EOF)
|
||||
return 0;
|
||||
if (Current == '\n') //unix line ending
|
||||
break;
|
||||
|
||||
if (Current == '\r') { //dos/mac line ending
|
||||
|
||||
Current = igetc();
|
||||
|
||||
if (Current == '\n') //dos line ending
|
||||
|
||||
break;
|
||||
|
||||
|
||||
|
||||
if (Current == IL_EOF)
|
||||
|
||||
break;
|
||||
|
||||
|
||||
|
||||
Buffer[i++] = Current;
|
||||
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
Buffer[i++] = Current;
|
||||
}
|
||||
|
||||
Buffer[i++] = 0;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
ILint XpmGets(ILubyte *Buffer, ILint MaxLen)
|
||||
{
|
||||
ILint Size, i, j;
|
||||
ILboolean NotComment = IL_FALSE, InsideComment = IL_FALSE;
|
||||
|
||||
|
||||
do {
|
||||
Size = XpmGetsInternal(Buffer, MaxLen);
|
||||
if (Size == IL_EOF)
|
||||
return IL_EOF;
|
||||
|
||||
|
||||
|
||||
//stip leading whitespace (sometimes there's whitespace
|
||||
|
||||
//before a comment or before the pixel data)
|
||||
|
||||
for(i = 0; i < Size && isspace(Buffer[i]); ++i) ;
|
||||
|
||||
Size = Size - i;
|
||||
|
||||
for(j = 0; j < Size; ++j)
|
||||
|
||||
Buffer[j] = Buffer[j + i];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (Size == 0)
|
||||
|
||||
continue;
|
||||
|
||||
|
||||
if (Buffer[0] == '/' && Buffer[1] == '*') {
|
||||
for (i = 2; i < Size; i++) {
|
||||
if (Buffer[i] == '*' && Buffer[i+1] == '/') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= Size)
|
||||
InsideComment = IL_TRUE;
|
||||
}
|
||||
else if (InsideComment) {
|
||||
for (i = 0; i < Size; i++) {
|
||||
if (Buffer[i] == '*' && Buffer[i+1] == '/') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i < Size)
|
||||
InsideComment = IL_FALSE;
|
||||
}
|
||||
else {
|
||||
NotComment = IL_TRUE;
|
||||
}
|
||||
} while (!NotComment);
|
||||
|
||||
return Size;
|
||||
}
|
||||
|
||||
|
||||
ILint XpmGetInt(ILubyte *Buffer, ILint Size, ILint *Position)
|
||||
{
|
||||
char Buff[1024];
|
||||
ILint i, j;
|
||||
ILboolean IsInNum = IL_FALSE;
|
||||
|
||||
for (i = *Position, j = 0; i < Size; i++) {
|
||||
if (isdigit(Buffer[i])) {
|
||||
IsInNum = IL_TRUE;
|
||||
Buff[j++] = Buffer[i];
|
||||
}
|
||||
else {
|
||||
if (IsInNum) {
|
||||
Buff[j] = 0;
|
||||
*Position = i;
|
||||
return atoi(Buff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
ILboolean XpmPredefCol(char *Buff, XpmPixel *Colour)
|
||||
{
|
||||
ILint len;
|
||||
ILint val = 128;
|
||||
|
||||
if (!stricmp(Buff, "none")) {
|
||||
(*Colour)[0] = 0;
|
||||
(*Colour)[1] = 0;
|
||||
(*Colour)[2] = 0;
|
||||
(*Colour)[3] = 0;
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
(*Colour)[3] = 255;
|
||||
|
||||
if (!stricmp(Buff, "black")) {
|
||||
(*Colour)[0] = 0;
|
||||
(*Colour)[1] = 0;
|
||||
(*Colour)[2] = 0;
|
||||
return IL_TRUE;
|
||||
}
|
||||
if (!stricmp(Buff, "white")) {
|
||||
(*Colour)[0] = 255;
|
||||
(*Colour)[1] = 255;
|
||||
(*Colour)[2] = 255;
|
||||
return IL_TRUE;
|
||||
}
|
||||
if (!stricmp(Buff, "red")) {
|
||||
(*Colour)[0] = 255;
|
||||
(*Colour)[1] = 0;
|
||||
(*Colour)[2] = 0;
|
||||
return IL_TRUE;
|
||||
}
|
||||
if (!stricmp(Buff, "green")) {
|
||||
(*Colour)[0] = 0;
|
||||
(*Colour)[1] = 255;
|
||||
(*Colour)[2] = 0;
|
||||
return IL_TRUE;
|
||||
}
|
||||
if (!stricmp(Buff, "blue")) {
|
||||
(*Colour)[0] = 0;
|
||||
(*Colour)[1] = 0;
|
||||
(*Colour)[2] = 255;
|
||||
return IL_TRUE;
|
||||
}
|
||||
if (!stricmp(Buff, "yellow")) {
|
||||
(*Colour)[0] = 255;
|
||||
(*Colour)[1] = 255;
|
||||
(*Colour)[2] = 0;
|
||||
return IL_TRUE;
|
||||
}
|
||||
if (!stricmp(Buff, "cyan")) {
|
||||
(*Colour)[0] = 0;
|
||||
(*Colour)[1] = 255;
|
||||
(*Colour)[2] = 255;
|
||||
return IL_TRUE;
|
||||
}
|
||||
if (!stricmp(Buff, "gray")) {
|
||||
(*Colour)[0] = 128;
|
||||
(*Colour)[1] = 128;
|
||||
(*Colour)[2] = 128;
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
//check for grayXXX codes (added 20040218)
|
||||
len = strlen(Buff);
|
||||
if (len >= 4) {
|
||||
if (Buff[0] == 'g' || Buff[0] == 'G'
|
||||
|| Buff[1] == 'r' || Buff[1] == 'R'
|
||||
|| Buff[2] == 'a' || Buff[2] == 'A'
|
||||
|| Buff[3] == 'y' || Buff[3] == 'Y') {
|
||||
if (isdigit(Buff[4])) { // isdigit returns false on '\0'
|
||||
val = Buff[4] - '0';
|
||||
if (isdigit(Buff[5])) {
|
||||
val = val*10 + Buff[5] - '0';
|
||||
if (isdigit(Buff[6]))
|
||||
val = val*10 + Buff[6] - '0';
|
||||
}
|
||||
val = (255*val)/100;
|
||||
}
|
||||
(*Colour)[0] = val;
|
||||
(*Colour)[1] = val;
|
||||
(*Colour)[2] = val;
|
||||
return IL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Unknown colour string, so use black
|
||||
// (changed 20040218)
|
||||
(*Colour)[0] = 0;
|
||||
(*Colour)[1] = 0;
|
||||
(*Colour)[2] = 0;
|
||||
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
#ifndef XPM_DONT_USE_HASHTABLE
|
||||
ILboolean XpmGetColour(ILubyte *Buffer, ILint Size, int Len, XPMHASHENTRY **Table)
|
||||
|
||||
#else
|
||||
|
||||
ILboolean XpmGetColour(ILubyte *Buffer, ILint Size, int Len, XpmPixel* Colours)
|
||||
|
||||
#endif
|
||||
{
|
||||
ILint i = 0, j, strLen = 0;
|
||||
ILubyte ColBuff[3];
|
||||
char Buff[1024];
|
||||
|
||||
XpmPixel Colour;
|
||||
|
||||
ILubyte Name[XPM_MAX_CHAR_PER_PIXEL];
|
||||
|
||||
|
||||
for ( ; i < Size; i++) {
|
||||
if (Buffer[i] == '\"')
|
||||
break;
|
||||
}
|
||||
i++; // Skip the quotes.
|
||||
|
||||
if (i >= Size)
|
||||
return IL_FALSE;
|
||||
|
||||
// Get the characters.
|
||||
|
||||
for (j = 0; j < Len; ++j) {
|
||||
Name[j] = Buffer[i++];
|
||||
|
||||
}
|
||||
|
||||
// Skip to the colour definition.
|
||||
for ( ; i < Size; i++) {
|
||||
if (Buffer[i] == 'c')
|
||||
break;
|
||||
}
|
||||
i++; // Skip the 'c'.
|
||||
|
||||
if (i >= Size || Buffer[i] != ' ') { // no 'c' found...assume black
|
||||
|
||||
#ifndef XPM_DONT_USE_HASHTABLE
|
||||
|
||||
memset(Colour, 0, sizeof(Colour));
|
||||
|
||||
Colour[3] = 255;
|
||||
|
||||
XpmInsertEntry(Table, Name, Len, Colour);
|
||||
|
||||
#else
|
||||
|
||||
memset(Colours[Name[0]], 0, sizeof(Colour));
|
||||
|
||||
Colours[Name[0]][3] = 255;
|
||||
|
||||
#endif
|
||||
return IL_TRUE;
|
||||
|
||||
}
|
||||
|
||||
for ( ; i < Size; i++) {
|
||||
if (Buffer[i] != ' ')
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= Size)
|
||||
return IL_FALSE;
|
||||
|
||||
if (Buffer[i] == '#') {
|
||||
// colour string may 4 digits/color or 1 digit/color
|
||||
// (added 20040218) TODO: is isxdigit() ANSI???
|
||||
++i;
|
||||
while (i + strLen < Size && isxdigit(Buffer[i + strLen]))
|
||||
++strLen;
|
||||
|
||||
for (j = 0; j < 3; j++) {
|
||||
if (strLen >= 10) { // 4 digits
|
||||
ColBuff[0] = Buffer[i + j*4];
|
||||
ColBuff[1] = Buffer[i + j*4 + 1];
|
||||
}
|
||||
else if (strLen >= 8) { // 3 digits
|
||||
ColBuff[0] = Buffer[i + j*3];
|
||||
ColBuff[1] = Buffer[i + j*3 + 1];
|
||||
}
|
||||
else if (strLen >= 6) { // 2 digits
|
||||
ColBuff[0] = Buffer[i + j*2];
|
||||
ColBuff[1] = Buffer[i + j*2 + 1];
|
||||
}
|
||||
else if(j < strLen) { // 1 digit, strLen >= 1
|
||||
ColBuff[0] = Buffer[i + j];
|
||||
ColBuff[1] = 0;
|
||||
}
|
||||
|
||||
ColBuff[2] = 0; // add terminating '\0' char
|
||||
Colour[j] = (ILubyte)strtol((char*)ColBuff, NULL, 16);
|
||||
}
|
||||
Colour[3] = 255; // Full alpha.
|
||||
}
|
||||
else {
|
||||
for (j = 0; i < Size; i++) {
|
||||
if (!isalnum(Buffer[i]))
|
||||
break;
|
||||
Buff[j++] = Buffer[i];
|
||||
}
|
||||
Buff[j] = 0;
|
||||
|
||||
if (i >= Size)
|
||||
return IL_FALSE;
|
||||
|
||||
if (!XpmPredefCol(Buff, &Colour))
|
||||
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifndef XPM_DONT_USE_HASHTABLE
|
||||
|
||||
XpmInsertEntry(Table, Name, Len, Colour);
|
||||
|
||||
#else
|
||||
|
||||
memcpy(Colours[Name[0]], Colour, sizeof(Colour));
|
||||
|
||||
#endif
|
||||
|
||||
return IL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
ILboolean iLoadXpmInternal()
|
||||
{
|
||||
|
||||
#define BUFFER_SIZE 2000
|
||||
ILubyte Buffer[BUFFER_SIZE], *Data;
|
||||
ILint Size, Pos, Width, Height, NumColours, i, x, y;
|
||||
|
||||
ILint CharsPerPixel;
|
||||
|
||||
#ifndef XPM_DONT_USE_HASHTABLE
|
||||
XPMHASHENTRY **HashTable;
|
||||
|
||||
#else
|
||||
|
||||
XpmPixel *Colours;
|
||||
|
||||
ILint Offset;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Size = XpmGetsInternal(Buffer, BUFFER_SIZE);
|
||||
if (strncmp("/* XPM */", (char*)Buffer, strlen("/* XPM */"))) {
|
||||
ilSetError(IL_INVALID_FILE_HEADER);
|
||||
return IL_FALSE;
|
||||
}
|
||||
|
||||
Size = XpmGets(Buffer, BUFFER_SIZE);
|
||||
// @TODO: Actually check the variable name here.
|
||||
|
||||
Size = XpmGets(Buffer, BUFFER_SIZE);
|
||||
Pos = 0;
|
||||
Width = XpmGetInt(Buffer, Size, &Pos);
|
||||
Height = XpmGetInt(Buffer, Size, &Pos);
|
||||
NumColours = XpmGetInt(Buffer, Size, &Pos);
|
||||
|
||||
CharsPerPixel = XpmGetInt(Buffer, Size, &Pos);
|
||||
|
||||
|
||||
|
||||
#ifdef XPM_DONT_USE_HASHTABLE
|
||||
|
||||
if (CharsPerPixel != 1) {
|
||||
|
||||
ilSetError(IL_FORMAT_NOT_SUPPORTED);
|
||||
|
||||
return IL_FALSE;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
if (CharsPerPixel > XPM_MAX_CHAR_PER_PIXEL
|
||||
|
||||
|| Width*CharsPerPixel > BUFFER_SIZE) {
|
||||
|
||||
ilSetError(IL_FORMAT_NOT_SUPPORTED);
|
||||
|
||||
return IL_FALSE;
|
||||
|
||||
}
|
||||
|
||||
|
||||
#ifndef XPM_DONT_USE_HASHTABLE
|
||||
HashTable = XpmCreateHashTable();
|
||||
|
||||
if (HashTable == NULL)
|
||||
|
||||
return IL_FALSE;
|
||||
|
||||
#else
|
||||
|
||||
Colours = ialloc(256 * sizeof(XpmPixel));
|
||||
|
||||
if (Colours == NULL)
|
||||
|
||||
return IL_FALSE;
|
||||
|
||||
#endif
|
||||
|
||||
for (i = 0; i < NumColours; i++) {
|
||||
Size = XpmGets(Buffer, BUFFER_SIZE);
|
||||
#ifndef XPM_DONT_USE_HASHTABLE
|
||||
|
||||
if (!XpmGetColour(Buffer, Size, CharsPerPixel, HashTable)) {
|
||||
|
||||
XpmDestroyHashTable(HashTable);
|
||||
|
||||
#else
|
||||
|
||||
if (!XpmGetColour(Buffer, Size, CharsPerPixel, Colours)) {
|
||||
|
||||
ifree(Colours);
|
||||
|
||||
#endif
|
||||
|
||||
return IL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ilTexImage(Width, Height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL)) {
|
||||
|
||||
#ifndef XPM_DONT_USE_HASHTABLE
|
||||
|
||||
XpmDestroyHashTable(HashTable);
|
||||
|
||||
#else
|
||||
|
||||
ifree(Colours);
|
||||
|
||||
#endif
|
||||
return IL_FALSE;
|
||||
|
||||
}
|
||||
|
||||
|
||||
Data = iCurImage->Data;
|
||||
|
||||
for (y = 0; y < Height; y++) {
|
||||
Size = XpmGets(Buffer, BUFFER_SIZE);
|
||||
for (x = 0; x < Width; x++) {
|
||||
|
||||
#ifndef XPM_DONT_USE_HASHTABLE
|
||||
XpmGetEntry(HashTable, &Buffer[1 + x*CharsPerPixel], CharsPerPixel, &Data[(x << 2)]);
|
||||
|
||||
#else
|
||||
|
||||
Offset = (x << 2);
|
||||
|
||||
Data[Offset + 0] = Colours[Buffer[x + 1]][0];
|
||||
|
||||
Data[Offset + 1] = Colours[Buffer[x + 1]][1];
|
||||
|
||||
Data[Offset + 2] = Colours[Buffer[x + 1]][2];
|
||||
|
||||
Data[Offset + 3] = Colours[Buffer[x + 1]][3];
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
Data += iCurImage->Bps;
|
||||
}
|
||||
|
||||
//added 20040218
|
||||
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
|
||||
|
||||
|
||||
#ifndef XPM_DONT_USE_HASHTABLE
|
||||
|
||||
XpmDestroyHashTable(HashTable);
|
||||
|
||||
#else
|
||||
ifree(Colours);
|
||||
|
||||
#endif
|
||||
|
||||
return IL_TRUE;
|
||||
|
||||
#undef BUFFER_SIZE
|
||||
}
|
||||
|
||||
#endif//IL_NO_XPM
|
||||
|
||||
Reference in New Issue
Block a user