1
//-----------------------------------------------------------------------------
4
// Copyright (C) 2000-2002 by Denton Woods
5
// Last modified: 05/19/2002 <--Y2K Compliant! =]
7
// Filename: src-IL/src/il_pcd.c
9
// Description: Reads from a Kodak PhotoCD (.pcd) file.
10
// Note: The code here is sloppy - I had to convert it from Pascal,
11
// which I've never even attempted to read before...enjoy! =)
13
//-----------------------------------------------------------------------------
16
#include "il_internal.h"
21
ILboolean iLoadPcdInternal(ILvoid);
24
ILboolean ilLoadPcd(const ILstring FileName)
27
ILboolean bPcd = IL_FALSE;
29
PcdFile = iopenr(FileName);
30
if (PcdFile == NULL) {
31
ilSetError(IL_COULD_NOT_OPEN_FILE);
35
bPcd = ilLoadPcdF(PcdFile);
42
//! Reads an already-opened .pcd file
43
ILboolean ilLoadPcdF(ILHANDLE File)
50
bRet = iLoadPcdInternal();
51
iseek(FirstPos, IL_SEEK_SET);
57
//! Reads from a memory "lump" that contains a .pcd file
58
ILboolean ilLoadPcdL(ILvoid *Lump, ILuint Size)
60
iSetInputLump(Lump, Size);
61
return iLoadPcdInternal();
65
ILvoid YCbCr2RGB(ILubyte Y, ILubyte Cb, ILubyte Cr, ILubyte *r, ILubyte *g, ILubyte *b)
67
static const ILdouble c11 = 0.0054980*256;
68
static const ILdouble c12 = 0.0000000*256;
69
static const ILdouble c13 = 0.0051681*256;
70
static const ILdouble c21 = 0.0054980*256;
71
static const ILdouble c22 =-0.0015446*256;
72
static const ILdouble c23 =-0.0026325*256;
73
static const ILdouble c31 = 0.0054980*256;
74
static const ILdouble c32 = 0.0079533*256;
75
static const ILdouble c33 = 0.0000000*256;
78
r1 = (ILint)(c11*Y + c12*(Cb-156) + c13*(Cr-137));
79
g1 = (ILint)(c21*Y + c22*(Cb-156) + c23*(Cr-137));
80
b1 = (ILint)(c31*Y + c32*(Cb-156) + c33*(Cr-137));
107
ILboolean iLoadPcdInternal()
109
ILubyte VertOrientation;
110
ILuint Width, Height, i, Total, x, CurPos = 0;
111
ILubyte *Y1=NULL, *Y2=NULL, *CbCr=NULL, r = 0, g = 0, b = 0;
114
if (iCurImage == NULL) {
115
ilSetError(IL_ILLEGAL_OPERATION);
119
iseek(72, IL_SEEK_CUR);
120
if (iread(&VertOrientation, 1, 1) != 1)
123
iseek(-72, IL_SEEK_CUR); // Can't rewind
125
PicNum = iGetInt(IL_PCD_PICNUM);
130
iseek(0x02000, IL_SEEK_CUR);
135
iseek(0x0b800, IL_SEEK_CUR);
140
iseek(0x30000, IL_SEEK_CUR);
145
ilSetError(IL_INVALID_PARAM);
149
Y1 = (ILubyte*)ialloc(Width);
150
Y2 = (ILubyte*)ialloc(Width);
151
CbCr = (ILubyte*)ialloc(Width);
152
if (Y1 == NULL || Y2 == NULL || CbCr == NULL) {
159
if (!ilTexImage(Width, Height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL)) {
162
iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
165
for (i = 0; i < Total; i++) {
168
if (iread(CbCr, 1, Width) != Width) { // Only really need to check the last one.
175
for (x = 0; x < Width; x++) {
176
YCbCr2RGB(Y1[x], CbCr[x / 2], CbCr[(Width / 2) + (x / 2)], &r, &g, &b);
177
iCurImage->Data[CurPos++] = r;
178
iCurImage->Data[CurPos++] = g;
179
iCurImage->Data[CurPos++] = b;
182
for (x = 0; x < Width; x++) {
183
YCbCr2RGB(Y2[x], CbCr[x / 2], CbCr[(Width / 2) + (x / 2)], &r, &g, &b);
184
iCurImage->Data[CurPos++] = r;
185
iCurImage->Data[CurPos++] = g;
186
iCurImage->Data[CurPos++] = b;
194
// Not sure how it is...the documentation is hard to understand
195
if ((VertOrientation & 0x3F) != 8)
196
iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
198
iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;