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