~ubuntu-branches/ubuntu/hardy/devil/hardy-updates

« back to all changes in this revision

Viewing changes to src-IL/src/il_pcd.c

  • Committer: Bazaar Package Importer
  • Author(s): Marcelo E. Magallon
  • Date: 2005-01-03 19:57:42 UTC
  • Revision ID: james.westby@ubuntu.com-20050103195742-4ipkplcwygu3irv0
Tags: upstream-1.6.7
ImportĀ upstreamĀ versionĀ 1.6.7

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//-----------------------------------------------------------------------------
 
2
//
 
3
// ImageLib Sources
 
4
// Copyright (C) 2000-2002 by Denton Woods
 
5
// Last modified: 05/19/2002 <--Y2K Compliant! =]
 
6
//
 
7
// Filename: src-IL/src/il_pcd.c
 
8
//
 
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! =)
 
12
//
 
13
//-----------------------------------------------------------------------------
 
14
 
 
15
 
 
16
#include "il_internal.h"
 
17
#ifndef IL_NO_PCD
 
18
#include "il_manip.h"
 
19
 
 
20
 
 
21
ILboolean iLoadPcdInternal(ILvoid);
 
22
 
 
23
//! Reads a .pcd file
 
24
ILboolean ilLoadPcd(const ILstring FileName)
 
25
{
 
26
        ILHANDLE        PcdFile;
 
27
        ILboolean       bPcd = IL_FALSE;
 
28
 
 
29
        PcdFile = iopenr(FileName);
 
30
        if (PcdFile == NULL) {
 
31
                ilSetError(IL_COULD_NOT_OPEN_FILE);
 
32
                return bPcd;
 
33
        }
 
34
 
 
35
        bPcd = ilLoadPcdF(PcdFile);
 
36
        icloser(PcdFile);
 
37
 
 
38
        return bPcd;
 
39
}
 
40
 
 
41
 
 
42
//! Reads an already-opened .pcd file
 
43
ILboolean ilLoadPcdF(ILHANDLE File)
 
44
{
 
45
        ILuint          FirstPos;
 
46
        ILboolean       bRet;
 
47
 
 
48
        iSetInputFile(File);
 
49
        FirstPos = itell();
 
50
        bRet = iLoadPcdInternal();
 
51
        iseek(FirstPos, IL_SEEK_SET);
 
52
 
 
53
        return bRet;
 
54
}
 
55
 
 
56
 
 
57
//! Reads from a memory "lump" that contains a .pcd file
 
58
ILboolean ilLoadPcdL(ILvoid *Lump, ILuint Size)
 
59
{
 
60
        iSetInputLump(Lump, Size);
 
61
        return iLoadPcdInternal();
 
62
}
 
63
 
 
64
 
 
65
ILvoid YCbCr2RGB(ILubyte Y, ILubyte Cb, ILubyte Cr, ILubyte *r, ILubyte *g, ILubyte *b)
 
66
{
 
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;
 
76
        ILint r1, g1, b1;
 
77
 
 
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));
 
81
 
 
82
        if (r1 < 0)
 
83
                *r = 0;
 
84
        else if (r1 > 255)
 
85
                *r = 255;
 
86
        else
 
87
                *r = r1;
 
88
 
 
89
        if (g1 < 0)
 
90
                *g = 0;
 
91
        else if (g1 > 255)
 
92
                *g = 255;
 
93
        else
 
94
                *g = g1;
 
95
 
 
96
        if (b1 < 0)
 
97
                *b = 0;
 
98
        else if (b1 > 255)
 
99
                *b = 255;
 
100
        else
 
101
                *b = b1;
 
102
 
 
103
        return;
 
104
}
 
105
 
 
106
 
 
107
ILboolean iLoadPcdInternal()
 
108
{
 
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;
 
112
        ILuint  PicNum;
 
113
 
 
114
        if (iCurImage == NULL) {
 
115
                ilSetError(IL_ILLEGAL_OPERATION);
 
116
                return IL_FALSE;
 
117
        }
 
118
 
 
119
        iseek(72, IL_SEEK_CUR);
 
120
        if (iread(&VertOrientation, 1, 1) != 1)
 
121
                return IL_FALSE;
 
122
 
 
123
        iseek(-72, IL_SEEK_CUR);  // Can't rewind
 
124
 
 
125
        PicNum = iGetInt(IL_PCD_PICNUM);
 
126
 
 
127
        switch (PicNum)
 
128
        {
 
129
                case 0:
 
130
                        iseek(0x02000, IL_SEEK_CUR);
 
131
                        Width = 192;
 
132
                        Height = 128;
 
133
                        break;
 
134
                case 1:
 
135
                        iseek(0x0b800, IL_SEEK_CUR);
 
136
                        Width = 384;
 
137
                        Height = 256;
 
138
                        break;
 
139
                case 2:
 
140
                        iseek(0x30000, IL_SEEK_CUR);
 
141
                        Width = 768;
 
142
                        Height = 512;
 
143
                        break;
 
144
                default:
 
145
                        ilSetError(IL_INVALID_PARAM);
 
146
                        return IL_FALSE;
 
147
        }
 
148
 
 
149
        Y1 = (ILubyte*)ialloc(Width);
 
150
        Y2 = (ILubyte*)ialloc(Width);
 
151
        CbCr = (ILubyte*)ialloc(Width);
 
152
        if (Y1 == NULL || Y2 == NULL || CbCr == NULL) {
 
153
                ifree(Y1);
 
154
                ifree(Y2);
 
155
                ifree(CbCr);
 
156
                return IL_FALSE;
 
157
        }
 
158
 
 
159
        if (!ilTexImage(Width, Height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL)) {
 
160
                return IL_FALSE;
 
161
        }
 
162
        iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
 
163
 
 
164
        Total = Height >> 1;
 
165
        for (i = 0; i < Total; i++) {
 
166
                iread(Y1, 1, Width);
 
167
                iread(Y2, 1, Width);
 
168
                if (iread(CbCr, 1, Width) != Width) {  // Only really need to check the last one.
 
169
                        ifree(Y1);
 
170
                        ifree(Y2);
 
171
                        ifree(CbCr);
 
172
                        return IL_FALSE;
 
173
                }
 
174
 
 
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;
 
180
                }
 
181
 
 
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;
 
187
                }
 
188
        }
 
189
 
 
190
        ifree(Y1);
 
191
        ifree(Y2);
 
192
        ifree(CbCr);
 
193
 
 
194
        // Not sure how it is...the documentation is hard to understand
 
195
        if ((VertOrientation & 0x3F) != 8)
 
196
                iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
 
197
        else
 
198
                iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
 
199
 
 
200
        ilFixImage();
 
201
 
 
202
        return IL_TRUE;
 
203
}
 
204
 
 
205
 
 
206
#endif//IL_NO_PCD