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:
2025-11-29 20:17:20 +09:00
parent 5d3cd64a25
commit dd97ddec92
11602 changed files with 1446576 additions and 0 deletions

View 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