1 //-----------------------------------------------------------------------------
2 //
3 // ImageLib Sources
4 // Copyright (C) 2000-2009 by Denton Woods
5 // Last modified: 03/07/2009
6 //
7 // Filename: src-IL/src/il_pix.c
8 //
9 // Description: Reads from an Alias | Wavefront .pix file.
10 //
11 //-----------------------------------------------------------------------------
12
13
14 #include "il_internal.h"
15 #ifndef IL_NO_PIX
16 #include "il_manip.h"
17 #include "il_endian.h"
18
19
20 #ifdef _MSC_VER
21 #pragma pack(push, pix_struct, 1)
22 #endif
23 typedef struct PIXHEAD
24 {
25 ILushort Width;
26 ILushort Height;
27 ILushort OffX;
28 ILushort OffY;
29 ILushort Bpp;
30 } IL_PACKSTRUCT PIXHEAD;
31 #ifdef _MSC_VER
32 #pragma pack(pop, pix_struct)
33 #endif
34
35 ILboolean iCheckPix(PIXHEAD *Header);
36 ILboolean iLoadPixInternal(void);
37
38
39 // Internal function used to get the Pix header from the current file.
iGetPixHead(PIXHEAD * Header)40 ILboolean iGetPixHead(PIXHEAD *Header)
41 {
42 Header->Width = GetBigUShort();
43 Header->Height = GetBigUShort();
44 Header->OffX = GetBigUShort();
45 Header->OffY = GetBigUShort();
46 Header->Bpp = GetBigUShort();
47
48 return IL_TRUE;
49 }
50
51
52 // Internal function to get the header and check it.
iIsValidPix()53 ILboolean iIsValidPix()
54 {
55 PIXHEAD Head;
56
57 if (!iGetPixHead(&Head))
58 return IL_FALSE;
59 iseek(-(ILint)sizeof(PIXHEAD), IL_SEEK_CUR);
60
61 return iCheckPix(&Head);
62 }
63
64
65 // Internal function used to check if the HEADER is a valid Pix header.
iCheckPix(PIXHEAD * Header)66 ILboolean iCheckPix(PIXHEAD *Header)
67 {
68 if (Header->Width == 0 || Header->Height == 0)
69 return IL_FALSE;
70 if (Header->Bpp != 24)
71 return IL_FALSE;
72 //if (Header->OffY != Header->Height)
73 // return IL_FALSE;
74
75 return IL_TRUE;
76 }
77
78
79 //! Reads a Pix file
ilLoadPix(ILconst_string FileName)80 ILboolean ilLoadPix(ILconst_string FileName)
81 {
82 ILHANDLE PixFile;
83 ILboolean bPix = IL_FALSE;
84
85 PixFile = iopenr(FileName);
86 if (PixFile == NULL) {
87 ilSetError(IL_COULD_NOT_OPEN_FILE);
88 return bPix;
89 }
90
91 bPix = ilLoadPixF(PixFile);
92 icloser(PixFile);
93
94 return bPix;
95 }
96
97
98 //! Reads an already-opened Pix file
ilLoadPixF(ILHANDLE File)99 ILboolean ilLoadPixF(ILHANDLE File)
100 {
101 ILuint FirstPos;
102 ILboolean bRet;
103
104 iSetInputFile(File);
105 FirstPos = itell();
106 bRet = iLoadPixInternal();
107 iseek(FirstPos, IL_SEEK_SET);
108
109 return bRet;
110 }
111
112
113 //! Reads from a memory "lump" that contains a Pix
ilLoadPixL(const void * Lump,ILuint Size)114 ILboolean ilLoadPixL(const void *Lump, ILuint Size)
115 {
116 iSetInputLump(Lump, Size);
117 return iLoadPixInternal();
118 }
119
120
121 // Internal function used to load the Pix.
iLoadPixInternal()122 ILboolean iLoadPixInternal()
123 {
124 PIXHEAD Header;
125 ILuint i, j;
126 ILubyte ByteHead, Colour[3];
127
128 if (iCurImage == NULL) {
129 ilSetError(IL_ILLEGAL_OPERATION);
130 return IL_FALSE;
131 }
132
133 if (!iGetPixHead(&Header))
134 return IL_FALSE;
135 if (!iCheckPix(&Header)) {
136 ilSetError(IL_INVALID_FILE_HEADER);
137 return IL_FALSE;
138 }
139
140 if (!ilTexImage(Header.Width, Header.Height, 1, 3, IL_BGR, IL_UNSIGNED_BYTE, NULL))
141 return IL_FALSE;
142
143 for (i = 0; i < iCurImage->SizeOfData; ) {
144 ByteHead = igetc();
145 if (iread(Colour, 1, 3) != 3)
146 return IL_FALSE;
147 for (j = 0; j < ByteHead; j++) {
148 iCurImage->Data[i++] = Colour[0];
149 iCurImage->Data[i++] = Colour[1];
150 iCurImage->Data[i++] = Colour[2];
151 }
152 }
153
154 iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
155
156 return ilFixImage();
157 }
158
159 #endif//IL_NO_PIX
160