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:
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
|
||||
Reference in New Issue
Block a user