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_lif.c
8 //
9 // Description: Reads a Homeworld image.
10 //
11 //-----------------------------------------------------------------------------
12 
13 
14 #include "il_internal.h"
15 #ifndef IL_NO_LIF
16 #include "il_lif.h"
17 
18 
19 //! Checks if the file specified in FileName is a valid Lif file.
ilIsValidLif(ILconst_string FileName)20 ILboolean ilIsValidLif(ILconst_string FileName)
21 {
22 	ILHANDLE	LifFile;
23 	ILboolean	bLif = IL_FALSE;
24 
25 	if (!iCheckExtension(FileName, IL_TEXT("lif"))) {
26 		ilSetError(IL_INVALID_EXTENSION);
27 		return bLif;
28 	}
29 
30 	LifFile = iopenr(FileName);
31 	if (LifFile == NULL) {
32 		ilSetError(IL_COULD_NOT_OPEN_FILE);
33 		return bLif;
34 	}
35 
36 	bLif = ilIsValidLifF(LifFile);
37 	icloser(LifFile);
38 
39 	return bLif;
40 }
41 
42 
43 //! Checks if the ILHANDLE contains a valid Lif file at the current position.
ilIsValidLifF(ILHANDLE File)44 ILboolean ilIsValidLifF(ILHANDLE File)
45 {
46 	ILuint		FirstPos;
47 	ILboolean	bRet;
48 
49 	iSetInputFile(File);
50 	FirstPos = itell();
51 	bRet = iIsValidLif();
52 	iseek(FirstPos, IL_SEEK_SET);
53 
54 	return bRet;
55 }
56 
57 
58 //! Checks if Lump is a valid Lif lump.
ilIsValidLifL(const void * Lump,ILuint Size)59 ILboolean ilIsValidLifL(const void *Lump, ILuint Size)
60 {
61 	iSetInputLump(Lump, Size);
62 	return iIsValidLif();
63 }
64 
65 
66 // Internal function used to get the Lif header from the current file.
iGetLifHead(LIF_HEAD * Header)67 ILboolean iGetLifHead(LIF_HEAD *Header)
68 {
69 
70 	iread(Header->Id, 1, 8);
71 
72 	Header->Version = GetLittleUInt();
73 
74 	Header->Flags = GetLittleUInt();
75 
76 	Header->Width = GetLittleUInt();
77 
78 	Header->Height = GetLittleUInt();
79 
80 	Header->PaletteCRC = GetLittleUInt();
81 
82 	Header->ImageCRC = GetLittleUInt();
83 
84 	Header->PalOffset = GetLittleUInt();
85 
86 	Header->TeamEffect0 = GetLittleUInt();
87 
88 	Header->TeamEffect1 = GetLittleUInt();
89 
90 
91 	return IL_TRUE;
92 }
93 
94 
95 // Internal function to get the header and check it.
iIsValidLif()96 ILboolean iIsValidLif()
97 {
98 	LIF_HEAD	Head;
99 
100 	if (!iGetLifHead(&Head))
101 		return IL_FALSE;
102 	iseek(-(ILint)sizeof(LIF_HEAD), IL_SEEK_CUR);
103 
104 	return iCheckLif(&Head);
105 }
106 
107 
108 // Internal function used to check if the HEADER is a valid Lif header.
iCheckLif(LIF_HEAD * Header)109 ILboolean iCheckLif(LIF_HEAD *Header)
110 {
111 	if (Header->Version != 260 || Header->Flags != 50)
112 		return IL_FALSE;
113 	if (stricmp(Header->Id, "Willy 7"))
114 		return IL_FALSE;
115 	return IL_TRUE;
116 }
117 
118 
119 //! Reads a .Lif file
ilLoadLif(ILconst_string FileName)120 ILboolean ilLoadLif(ILconst_string FileName)
121 {
122 	ILHANDLE	LifFile;
123 	ILboolean	bLif = IL_FALSE;
124 
125 	LifFile = iopenr(FileName);
126 	if (LifFile == NULL) {
127 		ilSetError(IL_COULD_NOT_OPEN_FILE);
128 		return bLif;
129 	}
130 
131 	bLif = ilLoadLifF(LifFile);
132 	icloser(LifFile);
133 
134 	return bLif;
135 }
136 
137 
138 //! Reads an already-opened .Lif file
ilLoadLifF(ILHANDLE File)139 ILboolean ilLoadLifF(ILHANDLE File)
140 {
141 	ILuint		FirstPos;
142 	ILboolean	bRet;
143 
144 	iSetInputFile(File);
145 	FirstPos = itell();
146 	bRet = iLoadLifInternal();
147 	iseek(FirstPos, IL_SEEK_SET);
148 
149 	return bRet;
150 }
151 
152 
153 //! Reads from a memory "lump" that contains a .Lif
ilLoadLifL(const void * Lump,ILuint Size)154 ILboolean ilLoadLifL(const void *Lump, ILuint Size)
155 {
156 	iSetInputLump(Lump, Size);
157 	return iLoadLifInternal();
158 }
159 
160 
iLoadLifInternal()161 ILboolean iLoadLifInternal()
162 {
163 	LIF_HEAD	LifHead;
164 	ILuint		i;
165 
166 	if (iCurImage == NULL) {
167 		ilSetError(IL_ILLEGAL_OPERATION);
168 		return IL_FALSE;
169 	}
170 
171 	if (!iGetLifHead(&LifHead))
172 		return IL_FALSE;
173 
174 	if (!ilTexImage(LifHead.Width, LifHead.Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) {
175 		return IL_FALSE;
176 	}
177 	iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
178 
179 	iCurImage->Pal.Palette = (ILubyte*)ialloc(1024);
180 	if (iCurImage->Pal.Palette == NULL)
181 		return IL_FALSE;
182 	iCurImage->Pal.PalSize = 1024;
183 	iCurImage->Pal.PalType = IL_PAL_RGBA32;
184 
185 	if (iread(iCurImage->Data, LifHead.Width * LifHead.Height, 1) != 1)
186 		return IL_FALSE;
187 	if (iread(iCurImage->Pal.Palette, 1, 1024) != 1024)
188 		return IL_FALSE;
189 
190 	// Each data offset is offset by -1, so we add one.
191 	for (i = 0; i < iCurImage->SizeOfData; i++) {
192 		iCurImage->Data[i]++;
193 	}
194 
195 	return ilFixImage();
196 }
197 
198 #endif//IL_NO_LIF
199