Files
Client/rylCoder_16.02.2008_src/addons/DevIL/src-IL/src/il_pcd.c
LGram16 dd97ddec92 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>
2025-11-29 20:17:20 +09:00

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