summaryrefslogtreecommitdiff
path: root/DevIL/src-IL/src/il_pix.c
blob: 2f1b070d92b6929b28becc1ceceaa181459201b0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
//-----------------------------------------------------------------------------
//
// ImageLib Sources
// Copyright (C) 2000-2009 by Denton Woods
// Last modified: 03/07/2009
//
// Filename: src-IL/src/il_pix.c
//
// Description: Reads from an Alias | Wavefront .pix file.
//
//-----------------------------------------------------------------------------


#include "il_internal.h"
#ifndef IL_NO_PIX
#include "il_endian.h"


#ifdef _MSC_VER
#pragma pack(push, pix_struct, 1)
#endif
typedef struct PIXHEAD
{
	ILushort	Width;
	ILushort	Height;
	ILushort	OffX;
	ILushort	OffY;
	ILushort	Bpp;
} IL_PACKSTRUCT PIXHEAD;
#ifdef _MSC_VER
#pragma pack(pop, pix_struct)
#endif

ILboolean iCheckPix(PIXHEAD *Header);
ILboolean iLoadPixInternal(void);


// Internal function used to get the Pix header from the current file.
ILboolean iGetPixHead(PIXHEAD *Header)
{
	Header->Width = GetBigUShort();
	Header->Height = GetBigUShort();
	Header->OffX = GetBigUShort();
	Header->OffY = GetBigUShort();
	Header->Bpp = GetBigUShort();

	return IL_TRUE;
}


// Internal function to get the header and check it.
ILboolean iIsValidPix()
{
	PIXHEAD	Head;

	if (!iGetPixHead(&Head))
		return IL_FALSE;
	iseek(-(ILint)sizeof(PIXHEAD), IL_SEEK_CUR);

	return iCheckPix(&Head);
}


// Internal function used to check if the HEADER is a valid Pix header.
ILboolean iCheckPix(PIXHEAD *Header)
{
	if (Header->Width == 0 || Header->Height == 0)
		return IL_FALSE;
	if (Header->Bpp != 24)
		return IL_FALSE;
	//if (Header->OffY != Header->Height)
	//	return IL_FALSE;

	return IL_TRUE;
}


//! Reads a Pix file
ILboolean ilLoadPix(ILconst_string FileName)
{
	ILHANDLE	PixFile;
	ILboolean	bPix = IL_FALSE;

	PixFile = iopenr(FileName);
	if (PixFile == NULL) {
		ilSetError(IL_COULD_NOT_OPEN_FILE);
		return bPix;
	}

	bPix = ilLoadPixF(PixFile);
	icloser(PixFile);

	return bPix;
}


//! Reads an already-opened Pix file
ILboolean ilLoadPixF(ILHANDLE File)
{
	ILuint		FirstPos;
	ILboolean	bRet;

	iSetInputFile(File);
	FirstPos = itell();
	bRet = iLoadPixInternal();
	iseek(FirstPos, IL_SEEK_SET);

	return bRet;
}


//! Reads from a memory "lump" that contains a Pix
ILboolean ilLoadPixL(const void *Lump, ILuint Size)
{
	iSetInputLump(Lump, Size);
	return iLoadPixInternal();
}


// Internal function used to load the Pix.
ILboolean iLoadPixInternal()
{
	PIXHEAD	Header;
	ILuint	i, j;
	ILubyte	ByteHead, Colour[3];

	if (iCurImage == NULL) {
		ilSetError(IL_ILLEGAL_OPERATION);
		return IL_FALSE;
	}

	if (!iGetPixHead(&Header))
		return IL_FALSE;
	if (!iCheckPix(&Header)) {
		ilSetError(IL_INVALID_FILE_HEADER);
		return IL_FALSE;
	}

	if (!ilTexImage(Header.Width, Header.Height, 1, 3, IL_BGR, IL_UNSIGNED_BYTE, NULL))
		return IL_FALSE;

	for (i = 0; i < iCurImage->SizeOfData; ) {
		ByteHead = igetc();
		if (iread(Colour, 1, 3) != 3)
			return IL_FALSE;
		for (j = 0; j < ByteHead; j++) {
			iCurImage->Data[i++] = Colour[0];
			iCurImage->Data[i++] = Colour[1];
			iCurImage->Data[i++] = Colour[2];
		}
	}

	iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;

	return ilFixImage();
}

#endif//IL_NO_PIX