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>
207 lines
4.2 KiB
C
207 lines
4.2 KiB
C
//-----------------------------------------------------------------------------
|
|
//
|
|
// 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
|