示例#1
0
ILuint iSunGetRle(ILubyte *Data, ILuint Length)
{
	ILuint	i = 0, j;
	ILubyte	Flag, Value;
	ILuint	Count;

	for (i = 0; i < Length; ) {
		Flag = igetc();
		if (Flag == 0x80) {  // Run follows (or 1 byte of 0x80)
			Count = igetc();
			if (Count == 0) {  // 1 pixel of value (0x80)
				*Data = 0x80;
				Data++;
				i++;
			}
			else {  // Here we have a run.
				Value = igetc();
				Count++;  // Should really be Count+1
				for (j = 0; j < Count && i + j < Length; j++, Data++) {
					*Data = Value;
				}
				i += Count;
			}
		}
		else {  // 1 byte of this value (cannot be 0x80)
			*Data = Flag;
			Data++;
			i++;
		}
	}

	return i;
}
示例#2
0
ILint XpmGetsInternal(ILubyte *Buffer, ILint MaxLen)
{
	ILint	i = 0, Current;

	if (ieof())
		return IL_EOF;

	while ((Current = igetc()) != IL_EOF && i < MaxLen - 1) {
		if (Current == IL_EOF)
			return 0;
		if (Current == '\n') //unix line ending
			break;
		if (Current == '\r') { //dos/mac line ending
			Current = igetc();
			if (Current == '\n') //dos line ending
				break;

			if (Current == IL_EOF)
				break;

			Buffer[i++] = Current;
			continue;
		}

		Buffer[i++] = Current;
	}

	Buffer[i++] = 0;

	return i;
}
示例#3
0
文件: il_dicom.cpp 项目: damucz/devil
ILboolean SkipElement(DICOMHEAD *Header, ILushort GroupNum, ILushort ElementNum)
{
	ILubyte	VR1, VR2;
	ILuint	ValLen;

	// 2 byte character string telling what type this element is ('OB', 'UI', etc.)
	VR1 = igetc();
	VR2 = igetc();

	if ((VR1 == 'O' && VR2 == 'B') || (VR1 == 'O' && VR2 == 'W') || (VR1 == 'O' && VR2 == 'F') ||
		(VR1 == 'S' && VR2 == 'Q') || (VR1 == 'U' && VR2 == 'T') || (VR1 == 'U' && VR2 == 'N')) {
		// These all have a different format than the other formats, since they can be up to 32 bits long.
		GetLittleUShort();  // Values reserved, we do not care about them.
		ValLen = GetInt(Header, GroupNum);//GetLittleUInt();  // Length of the rest of the element
		if (ValLen % 2)  // This length must be even, according to the specs.
			return IL_FALSE;
		if (ElementNum != 0x00)  // Element numbers of 0 tell the size of the full group, so we do not skip this.
								 //  @TODO: We could use this to skip groups that we do not care about.
			if (iseek(ValLen, IL_SEEK_CUR))
				return IL_FALSE;
	}
	else {
		// These have a length of 16 bits.
		ValLen = GetShort(Header, GroupNum);//GetLittleUShort();
		//if (ValLen % 2)  // This length must be even, according to the specs.
		//	ValLen++;  // Add the extra byte to seek.
		//if (ElementNum != 0x00)  // Element numbers of 0 tell the size of the full group, so we do not skip this.
								 //  @TODO: We could use this to skip groups that we do not care about.
			if (iseek(ValLen, IL_SEEK_CUR))
				return IL_FALSE;
	}

	return IL_TRUE;
}
示例#4
0
文件: il_cut.c 项目: 123woodman/minko
//	Note:  .Cut support has not been tested yet!
// A .cut can only have 1 bpp.
//	We need to add support for the .pal's PSP outputs with these...
ILboolean iLoadCutInternal()
{
	CUT_HEAD	Header;
	ILuint		Size, i = 0, j;
	ILubyte		Count, Run;

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

	Header.Width = GetLittleShort();
	Header.Height = GetLittleShort();
	Header.Dummy = GetLittleInt();

	if (Header.Width == 0 || Header.Height == 0) {
		ilSetError(IL_INVALID_FILE_HEADER);
		return IL_FALSE;
	}

	if (!ilTexImage(Header.Width, Header.Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) {  // always 1 bpp
		return IL_FALSE;
	}
	iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;

	Size = Header.Width * Header.Height;

	while (i < Size) {
		Count = igetc();
		if (Count == 0) { // end of row
			igetc();  // Not supposed to be here, but
			igetc();  //  PSP is putting these two bytes here...WHY?!
			continue;
		}
		if (Count & BIT_7) {  // rle-compressed
			ClearBits(Count, BIT_7);
			Run = igetc();
			for (j = 0; j < Count; j++) {
				iCurImage->Data[i++] = Run;
			}
		}
		else {  // run of pixels
			for (j = 0; j < Count; j++) {
				iCurImage->Data[i++] = igetc();
			}
		}
	}

	iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;  // Not sure

	/*iCurImage->Pal.Palette = SharedPal.Palette;
	iCurImage->Pal.PalSize = SharedPal.PalSize;
	iCurImage->Pal.PalType = SharedPal.PalType;*/

	return ilFixImage();
}
示例#5
0
// Internal function used to load the Gif.
ILboolean iLoadGifInternal()
{
	GIFHEAD	Header;
	ILpal	GlobalPal;

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

	GlobalPal.Palette = NULL;
	GlobalPal.PalSize = 0;

	//read header
	iread(&Header.Sig, 1, 6);
	Header.Width = GetLittleUShort();
	Header.Height = GetLittleUShort();
	Header.ColourInfo = igetc();
	Header.Background = igetc();
	Header.Aspect = igetc();

	if (!strnicmp(Header.Sig, "GIF87A", 6)) {
		GifType = GIF87A;
	}
	else if (!strnicmp(Header.Sig, "GIF89A", 6)) {
		GifType = GIF89A;
	}
	else {
		ilSetError(IL_INVALID_FILE_HEADER);
		return IL_FALSE;
	}

	if (!ilTexImage(Header.Width, Header.Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL))
		return IL_FALSE;
	iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;

	// Check for a global colour map.
	if (Header.ColourInfo & (1 << 7)) {
		if (!iGetPalette(Header.ColourInfo, &GlobalPal)) {
			return IL_FALSE;
		}
	}

	if (!GetImages(&GlobalPal, &Header))
		return IL_FALSE;

	if (GlobalPal.Palette && GlobalPal.PalSize)
		ifree(GlobalPal.Palette);
	GlobalPal.Palette = NULL;
	GlobalPal.PalSize = 0;

	ilFixImage();

	return IL_TRUE;
}
示例#6
0
ILvoid iGetJpgHead(ILubyte *Header)

{

	Header[0] = igetc();

	Header[1] = igetc();

	return;

}
示例#7
0
ILboolean iGetWord(ILvoid)
{
	ILint WordPos = 0;
	ILint Current = 0;
	ILboolean Started = IL_FALSE;
	ILboolean Looping = IL_TRUE;

	if (ieof())
		return IL_FALSE;

	while (Looping) {
		while ((Current = igetc()) != IL_EOF && Current != '\n' && Current != '#' && Current != ' ') {
			if (Current == IL_EOF)
				return IL_FALSE;
			if (!isalnum(Current)) {
				if (Started) {
					Looping = IL_FALSE;
					break;
				}
				continue;
			}

			if (Looping)
				SmallBuff[WordPos++] = Current;
		}

		SmallBuff[WordPos] = NUL;

		if (!Looping)
			break;

		if (Current == '#') {  // '#' is a comment...read until end of line
			while ((Current = igetc()) != IL_EOF && Current != '\n');
		}

		// Get rid of any erroneous spaces
		while ((Current = igetc()) != IL_EOF) {
			if (Current != ' ')
				break;
		}
		iseek(-1, IL_SEEK_CUR);

		if (WordPos > 0)
			break;
	}

	if (Current == -1 || WordPos == 0) {
		ilSetError(IL_INVALID_FILE_HEADER);
		return IL_FALSE;
	}

	return IL_TRUE;
}
示例#8
0
// Internal function used to load the Pxr.
ILboolean iLoadPxrInternal()
{
	ILushort	Width, Height;
	ILubyte		Bpp;

	Width = sizeof(PIXHEAD);

	iseek(416, IL_SEEK_SET);
	Height = GetLittleUShort();
	Width = GetLittleUShort();
	iseek(424, IL_SEEK_SET);
	Bpp = igetc();

	switch (Bpp)
	{
		case 0x08:
			ilTexImage(Width, Height, 1, 1, IL_LUMINANCE, IL_UNSIGNED_BYTE, NULL);
			break;
		case 0x0E:
			ilTexImage(Width, Height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL);
			break;
		case 0x0F:
			ilTexImage(Width, Height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL);
			break;
		default:
			ilSetError(IL_INVALID_FILE_HEADER);
			return IL_FALSE;
	}

	iseek(1024, IL_SEEK_SET);
	iread(iCurImage->Data, 1, iCurImage->SizeOfData);
	iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;

	return IL_TRUE;
}
示例#9
0
文件: il_pic.c 项目: AMDmi3/DevIL
ILboolean channelReadPure(ILubyte *scan, ILint width, ILint noCol, ILint *off, ILint bytes)
{
	ILubyte		col[4];
	ILint		count;
	int			i, j, k;

	for (i = width; i > 0; ) {
		count = igetc();
		if (count == IL_EOF)
			return IL_FALSE;
		if (count > width)
			count = width;
		i -= count;
		
		if (ieof())
			return IL_FALSE;
		
		for (j = 0; j < noCol; j++)
			if (iread(&col[j], 1, 1) != 1)
				return IL_FALSE;
		
		for (k = 0; k < count; k++, scan += bytes) {
			for(j = 0; j < noCol; j++)
				scan[off[j] + k] = col[j];
		}
	}
	return IL_TRUE;
}
示例#10
0
文件: il_dcx.c 项目: brock7/TianLong
ILimage *iUncompressDcxSmall(DCXHEAD *Header)
{
	ILuint	i = 0, j, k, c, d, x, y, Bps;
	ILubyte	HeadByte, Colour, Data = 0, *ScanLine = NULL;
	ILimage	*Image;

	Image = ilNewImage(Header->Xmax - Header->Xmin + 1, Header->Ymax - Header->Ymin + 1, 1, Header->NumPlanes, 1);
	if (Image == NULL)
		return NULL;

	/*if (!ilTexImage(Header->Xmax - Header->Xmin + 1, Header->Ymax - Header->Ymin + 1, 1, 1, 0, IL_UNSIGNED_BYTE, NULL)) {
		return IL_FALSE;
	}*/
	Image->Origin = IL_ORIGIN_UPPER_LEFT;

	switch (Header->NumPlanes)
	{
		case 1:
			Image->Format = IL_LUMINANCE;
			break;
		case 4:
			Image->Format = IL_COLOUR_INDEX;
			break;
		default:
			ilSetError(IL_ILLEGAL_FILE_VALUE);
			ilCloseImage(Image);
			return NULL;
	}

	if (Header->NumPlanes == 1) {
		for (j = 0; j < Image->Height; j++) {
			i = 0;
			while (i < Image->Width) {
				if (iread(&HeadByte, 1, 1) != 1)
					goto file_read_error;
				if (HeadByte >= 192) {
					HeadByte -= 192;
					if (iread(&Data, 1, 1) != 1)
						goto file_read_error;

					for (c = 0; c < HeadByte; c++) {
						k = 128;
						for (d = 0; d < 8 && i < Image->Width; d++) {
							Image->Data[j * Image->Width + i++] = (!!(Data & k) == 1 ? 255 : 0);
							k >>= 1;
						}
					}
				}
				else {
					k = 128;
					for (c = 0; c < 8 && i < Image->Width; c++) {
						Image->Data[j * Image->Width + i++] = (!!(HeadByte & k) == 1 ? 255 : 0);
						k >>= 1;
					}
				}
			}
			if (Data != 0)
				igetc();  // Skip pad byte if last byte not a 0
		}
示例#11
0
ILboolean SkipExtensions(GFXCONTROL *Gfx)
{
	ILint	Code;
	ILint	Label;
	ILint	Size;

	// DW (06-03-2002):  Apparently there can be...
	//if (GifType == GIF87A)
	//	return IL_TRUE;  // No extensions in the GIF87a format.

	do {
		if((Code = igetc()) == IL_EOF)
			return IL_FALSE;

		if (Code != 0x21) {
			iseek(-1, IL_SEEK_CUR);
			return IL_TRUE;
		}

		if((Label = igetc()) == IL_EOF)
			return IL_FALSE;

		switch (Label)
		{
			case 0xF9:
				Gfx->Size = igetc();
				Gfx->Packed = igetc();
				Gfx->Delay = GetLittleUShort();
				Gfx->Transparent = igetc();
				Gfx->Terminator = igetc();
				if (ieof())
					return IL_FALSE;
				Gfx->Used = IL_FALSE;

				break;

			/*case 0xFE:
				break;

			case 0x01:
				break;*/

			default:
				do {
					if((Size = igetc()) == IL_EOF)
						return IL_FALSE;

					iseek(Size, IL_SEEK_CUR);
				} while (!ieof() && Size != 0);
		}

		// @TODO:  Handle this better.
		if (ieof()) {
			ilSetError(IL_FILE_READ_ERROR);
			return IL_FALSE;
		}
	} while (1);

	return IL_TRUE;
}
示例#12
0
文件: il_sgi.c 项目: kphillisjr/DevIL
// Internal function used to get the .sgi header from the current file.
ILboolean iGetSgiHead(iSgiHeader *Header)
{
	Header->MagicNum = GetBigUShort();
	Header->Storage = (ILbyte)igetc();
	Header->Bpc = (ILbyte)igetc();
	Header->Dim = GetBigUShort();
	Header->XSize = GetBigUShort();
	Header->YSize = GetBigUShort();
	Header->ZSize = GetBigUShort();
	Header->PixMin = GetBigInt();
	Header->PixMax = GetBigInt();
	Header->Dummy1 = GetBigInt();
	iread(Header->Name, 1, 80);
	Header->ColMap = GetBigInt();
	iread(Header->Dummy, 1, 404);

	return IL_TRUE;
}
示例#13
0
文件: il_dicom.cpp 项目: damucz/devil
ILboolean GetUID(ILubyte *UID)
{
	ILubyte		VR1, VR2;
	ILushort	ValLen;

	// 2 byte character string telling what type this element is ('OB', 'UI', etc.)
	VR1 = igetc();
	VR2 = igetc();

	if (VR1 != 'U' || VR2 != 'I')  // 'UI' == UID
		return IL_FALSE;

	ValLen = GetLittleUShort();
	if (iread(UID, ValLen, 1) != 1)
		return IL_FALSE;
	UID[64] = 0;  // Just to make sure that our string is terminated.

	return IL_TRUE;
}
示例#14
0
文件: il_blp.cpp 项目: damucz/devil
// Internal function used to get the BLP header from the current file.
ILboolean iGetBlp2Head(BLP2HEAD *Header)
{
    ILuint i;

    iread(Header->Sig, 1, 4);
    Header->Type = GetLittleUInt();
    Header->Compression = igetc();
    Header->AlphaBits = igetc();
    Header->AlphaType = igetc();
    Header->HasMips = igetc();
    Header->Width = GetLittleUInt();
    Header->Height = GetLittleUInt();
    for (i = 0; i < 16; i++)
        Header->MipOffsets[i] = GetLittleUInt();
    for (i = 0; i < 16; i++)
        Header->MipLengths[i] = GetLittleUInt();

    return IL_TRUE;
}
示例#15
0
ILboolean channelReadMixed(ILubyte *scan, ILint width, ILint noCol, ILint *off, ILint bytes)
{
	ILint	count;
	int		i, j, k;
	ILubyte	col[4];

	for(i = 0; i < width; i += count) {
		if (ieof())
			return IL_FALSE;

		count = igetc();
		if (count == IL_EOF)
			return IL_FALSE;

		if (count >= 128) {  // Repeated sequence
			if (count == 128) {  // Long run
				count = GetLittleUShort();
				if (ieof())
					return IL_FALSE;
			}
			else
				count -= 127;
			
			// We've run past...
			if ((i + count) > width) {
				//fprintf(stderr, "ERROR: FF_PIC_load(): Overrun scanline (Repeat) [%d + %d > %d] (NC=%d)\n", i, count, width, noCol);
				return IL_FALSE;
			}

			for (j = 0; j < noCol; j++)
				if (iread(&col[j], 1, 1) != 1)
					return IL_FALSE;

			for (k = 0; k < count; k++, scan += bytes) {
				for (j = 0; j < noCol; j++)
					scan[off[j]] = col[j];
			}
		} else {				// Raw sequence
			count++;
			if ((i + count) > width) {
				//fprintf(stderr, "ERROR: FF_PIC_load(): Overrun scanline (Raw) [%d + %d > %d] (NC=%d)\n", i, count, width, noCol);
				return IL_FALSE;
			}
			
			for (k = count; k > 0; k--, scan += bytes) {
				for (j = 0; j < noCol; j++)
					if (iread(&scan[off[j]], 1, 1) != 1)
						return IL_FALSE;
			}
		}
	}

	return IL_TRUE;
}
示例#16
0
文件: il_dicom.cpp 项目: damucz/devil
ILboolean GetNumericValue(DICOMHEAD *Header, ILushort GroupNum, ILuint *Number)
{
	ILubyte		VR1, VR2;
	ILushort	ValLen;

	// 2 byte character string telling what type this element is ('OB', 'UI', etc.)
	VR1 = igetc();
	VR2 = igetc();

	if (VR1 == 'U' && VR2 == 'S') {  // Unsigned short
		ValLen = GetShort(Header, GroupNum);//GetLittleUShort();
		if (ValLen != 2)  // Must always be 2 for short ('US')
			return IL_FALSE;
		*((ILushort*)Number) = GetShort(Header, GroupNum);//GetLittleUShort();
		return IL_TRUE;
	}
	if (VR1 == 'U' && VR2 == 'L') {  // Unsigned long
		ValLen = GetInt(Header, GroupNum);//GetLittleUInt();
		if (ValLen != 4)  // Must always be 4 for long ('UL')
			return IL_FALSE;
		*Number = GetInt(Header, GroupNum);
		return IL_TRUE;
	}
	if (VR1 == 'S' && VR2 == 'S') {  // Signed short
		ValLen = GetShort(Header, GroupNum);
		if (ValLen != 2)  // Must always be 2 for short ('US')
			return IL_FALSE;
		*((ILshort*)Number) = GetShort(Header, GroupNum);
		return IL_TRUE;
	}
	if (VR1 == 'S' && VR2 == 'L') {  // Signed long
		ValLen = GetInt(Header, GroupNum);
		if (ValLen != 4)  // Must always be 4 for long ('UL')
			return IL_FALSE;
		*((ILint*)Number) = GetInt(Header, GroupNum);
		return IL_TRUE;
	}

	return IL_FALSE;
}
示例#17
0
文件: il_utx.c 项目: AMDmi3/DevIL
// Gets a name variable from the file.  Keep in mind that the return value must be freed.
char *GetUtxName(UTXHEADER *Header)
{
#define NAME_MAX_LEN 256  //@TODO: Figure out if these can possibly be longer.
	char	*Name, OldName[NAME_MAX_LEN];
	ILubyte	Length = 0;

	// New style (Unreal Tournament) name.  This has a byte at the beginning telling
	//  how long the string is (plus terminating 0), followed by the terminating 0. 
	if (Header->Version >= 64) {
		Length = igetc();
		Name = (char*)ialloc(Length);
		if (Name == NULL)
			return NULL;
		if (iread(Name, Length, 1) != 1) {
			ifree(Name);
			return NULL;
		}
		return Name;
	}

	// Old style (Unreal) name.  This string length is unknown, but it is terminated
	//  by a 0.
	do {
		OldName[Length++] = igetc();
	} while (!ieof() && OldName[Length-1] != 0 && Length < NAME_MAX_LEN);

	// Never reached the terminating 0.
	if (Length == NAME_MAX_LEN && OldName[Length-1] != 0)
		return NULL;

	// Just copy the string and return it.
	Name = (char*)ialloc(Length);
	if (Name == NULL)
		return NULL;
	memcpy(Name, OldName, Length);

	return Name;

#undef NAME_MAX_LEN
}
示例#18
0
// Last time I tried, MSVC++'s fgets() was really really screwy
ILbyte *iFgets(char *buffer, ILuint maxlen)
{
	ILuint	counter = 0;
	ILint	temp = '\0';

	while ((temp = igetc()) && temp != '\n' && temp != IL_EOF && counter < maxlen) {
		buffer[counter] = temp;
		counter++;
	}
	buffer[counter] = '\0';
	
	if (temp == IL_EOF && counter == 0)  // Only return NULL if no data was "got".
		return NULL;

	return buffer;
}
示例#19
0
文件: il_utx.c 项目: AMDmi3/DevIL
// This following code is from http://wiki.beyondunreal.com/Legacy:Package_File_Format/Data_Details.
/// <summary>Reads a compact integer from the FileReader.
/// Bytes read differs, so do not make assumptions about
/// physical data being read from the stream. (If you have
/// to, get the difference of FileReader.BaseStream.Position
/// before and after this is executed.)</summary>
/// <returns>An "uncompacted" signed integer.</returns>
/// <remarks>FileReader is a System.IO.BinaryReader mapped
/// to a file. Also, there may be better ways to implement
/// this, but this is fast, and it works.</remarks>
ILint UtxReadCompactInteger()
{
        int output = 0;
        ILboolean sign = IL_FALSE;
		int i;
		ILubyte x;
        for(i = 0; i < 5; i++)
        {
                x = igetc();
                // First byte
                if(i == 0)
                {
                        // Bit: X0000000
                        if((x & 0x80) > 0)
                                sign = IL_TRUE;
                        // Bits: 00XXXXXX
                        output |= (x & 0x3F);
                        // Bit: 0X000000
                        if((x & 0x40) == 0)
                                break;
                }
                // Last byte
                else if(i == 4)
                {
                        // Bits: 000XXXXX -- the 0 bits are ignored
                        // (hits the 32 bit boundary)
                        output |= (x & 0x1F) << (6 + (3 * 7));
                }
                // Middle bytes
                else
                {
                        // Bits: 0XXXXXXX
                        output |= (x & 0x7F) << (6 + ((i - 1) * 7));
                        // Bit: X0000000
                        if((x & 0x80) == 0)
                                break;
                }
        }
        // multiply by negative one here, since the first 6+ bits could be 0
        if (sign)
                output *= -1;
        return output;
}
示例#20
0
// Internal function to load a raw image
ILboolean iLoadRawInternal()
{
	if (iCurImage == NULL) {
		ilSetError(IL_ILLEGAL_OPERATION);
		return IL_FALSE;
	}

	iCurImage->Width = GetLittleUInt();
	iCurImage->Height = GetLittleUInt();
	iCurImage->Depth = GetLittleUInt();
	iCurImage->Bpp = igetc();
	if (iread(&iCurImage->Bpc, 1, 1) != 1)
		return IL_FALSE;

	if (!ilTexImage(iCurImage->Width, iCurImage->Height, iCurImage->Depth, iCurImage->Bpp, 0, ilGetTypeBpc(iCurImage->Bpc), NULL)) {
		return IL_FALSE;
	}
	iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;

	// Tries to read the correct amount of data
	if (iread(iCurImage->Data, 1, iCurImage->SizeOfData) < iCurImage->SizeOfData)
		return IL_FALSE;

	if (ilIsEnabled(IL_ORIGIN_SET)) {
		iCurImage->Origin = ilGetInteger(IL_ORIGIN_MODE);
	}
	else {
		iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
	}

	if (iCurImage->Bpp == 1)
		iCurImage->Format = IL_LUMINANCE;
	else if (iCurImage->Bpp == 3)
		iCurImage->Format = IL_RGB;
	else  // 4
		iCurImage->Format = IL_RGBA;

	ilFixImage();

	return IL_TRUE;
}
示例#21
0
ILimage *ilReadBitPbm(PPMINFO *Info)
{
	ILuint	m, j, x, CurrByte;

	if (!ilTexImage(Info->Width, Info->Height, 1, (ILubyte)(Info->Bpp), 0, IL_UNSIGNED_BYTE, NULL)) {
		return IL_FALSE;
	}
	iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;

	x = 0;
	for (j = 0; j < iCurImage->SizeOfData;) {
		CurrByte = igetc();
		for (m = 128; m > 0 && x < Info->Width; m >>= 1, ++x, ++j) {
			iCurImage->Data[j] = (CurrByte & m)?255:0;
		}
		if (x == Info->Width)
			x = 0;
	}

	return iCurImage;
}
示例#22
0
// 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;

	ilFixImage();

	return IL_TRUE;
}
示例#23
0
// Internal function obtain the .pcx header from the current file.
ILboolean iGetPcxHead(PCXHEAD *Head)
{
	Head->Manufacturer = igetc();
	Head->Version = igetc();
	Head->Encoding = igetc();
	Head->Bpp = igetc();
	Head->Xmin = GetLittleUShort();
	Head->Ymin = GetLittleUShort();
	Head->Xmax = GetLittleUShort();
	Head->Ymax = GetLittleUShort();
	Head->HDpi = GetLittleUShort();
	Head->VDpi = GetLittleUShort();
	iread(Head->ColMap, 1, 48);
	Head->Reserved = igetc();
	Head->NumPlanes = igetc();
	Head->Bps = GetLittleUShort();
	Head->PaletteInfo = GetLittleUShort();
	Head->HScreenSize = GetLittleUShort();
	Head->VScreenSize = GetLittleUShort();
	iread(Head->Filler, 1, 54);

	return IL_TRUE;
}
示例#24
0
ILboolean iUncompressSmall(PCXHEAD *Header)
{
	ILuint	i = 0, j, k, c, d, x, y, Bps;
	ILubyte	HeadByte, Colour, Data = 0, *ScanLine;

	if (!ilTexImage(Header->Xmax - Header->Xmin + 1, Header->Ymax - Header->Ymin + 1, 1, 1, 0, IL_UNSIGNED_BYTE, NULL)) {
		return IL_FALSE;
	}
	iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;

	switch (Header->NumPlanes)
	{
		case 1:
			iCurImage->Format = IL_LUMINANCE;
			break;
		case 4:
			iCurImage->Format = IL_COLOUR_INDEX;
			break;
		default:
			ilSetError(IL_ILLEGAL_FILE_VALUE);
			return IL_FALSE;
	}

	if (Header->NumPlanes == 1 && Header->Bpp == 1) {
		for (j = 0; j < iCurImage->Height; j++) {
			i = 0; //number of written pixels
			while (i < iCurImage->Width) {
				if (iread(&HeadByte, 1, 1) != 1)
					return IL_FALSE;
				if (HeadByte >= 192) {
					HeadByte -= 192;
					if (iread(&Data, 1, 1) != 1)
						return IL_FALSE;

					for (c = 0; c < HeadByte; c++) {
						k = 128;
						for (d = 0; d < 8 && i < iCurImage->Width; d++) {
							iCurImage->Data[j * iCurImage->Width + i++] = ((Data & k) != 0 ? 255 : 0);
							k >>= 1;
						}
					}
				}
				else {
					k = 128;
					for (c = 0; c < 8 && i < iCurImage->Width; c++) {
						iCurImage->Data[j * iCurImage->Width + i++] = ((HeadByte & k) != 0 ? 255 : 0);
						k >>= 1;
					}
				}
			}

			//if(Data != 0)
			//changed 2003-09-01:
			//There has to be an even number of bytes per line in a pcx.
			//One byte can hold up to 8 bits, so Width/8 bytes
			//are needed to hold a 1 bit per pixel image line.
			//If Width/8 is even no padding is needed,
			//one pad byte has to be read otherwise.
			//(let's hope the above is true ;-))
			if(!((iCurImage->Width >> 3) & 0x1))
				igetc();	// Skip pad byte
		}
示例#25
0
ILboolean GifGetData(ILubyte *Data, ILuint ImageSize, ILuint Width, ILuint Height, ILuint Stride, GFXCONTROL *Gfx)
{
	ILubyte	*sp;
	ILint	code, fc, oc;
	ILubyte	DisposalMethod = 0;
	ILint	c, size;
	ILuint	i = 0, Read = 0;

	if (!Gfx->Used)
		DisposalMethod = (Gfx->Packed & 0x1C) >> 2;

	if((size = igetc()) == IL_EOF)
		return IL_FALSE;

	if (size < 2 || 9 < size) {
		return IL_FALSE;
	}

	stack  = (ILubyte*)ialloc(MAX_CODES + 1);
	suffix = (ILubyte*)ialloc(MAX_CODES + 1);
	prefix = (ILshort*)ialloc(sizeof(*prefix) * (MAX_CODES + 1));
	if (!stack || !suffix || !prefix) {
		ifree(stack);
		ifree(suffix);
		ifree(prefix);
		return IL_FALSE;
	}

	curr_size = size + 1;
	top_slot = 1 << curr_size;
	clear = 1 << size;
	ending = clear + 1;
	slot = newcodes = ending + 1;
	navail_bytes = nbits_left = 0;
	oc = fc = 0;
	sp = stack;
	success = IL_TRUE;

	while ((c = get_next_code()) != ending && Read < Height) {
		if (c == clear) {
			curr_size = size + 1;
			slot = newcodes;
			top_slot = 1 << curr_size;
			while ((c = get_next_code()) == clear);
			if (c == ending)
				break;
			if (c >= slot)
				c = 0;
			oc = fc = c;

			if (DisposalMethod == 1 && !Gfx->Used && Gfx->Transparent == c && (Gfx->Packed & 0x1) != 0)
				i++;
			else
				Data[i++] = c;

			if (i == Width) {
				Data += Stride;
				i = 0;
				Read += 1;
			}
		}
		else {
			code = c;
			if (code >= slot) {
				code = oc;
				*sp++ = fc;
			}
			while (code >= newcodes) {
				*sp++ = suffix[code];
				code = prefix[code];
			}
			*sp++ = (ILbyte)code;
			if (slot < top_slot) {
				fc = code;
				suffix[slot]   = fc;
				prefix[slot++] = oc;
				oc = c;
			}
			if (slot >= top_slot && curr_size < 12) {
				top_slot <<= 1;
				curr_size++;
			}
			while (sp > stack) {
				sp--;

				if (DisposalMethod == 1 && !Gfx->Used && Gfx->Transparent == *sp && (Gfx->Packed & 0x1) != 0)
					i++;
				else
					Data[i++] = *sp;

				if (i == Width) {
					Data += Stride;
					i = 0;
					Read += 1;
				}
			}
		}

	}

	ifree(stack);
	ifree(suffix);
	ifree(prefix);

	return success;
}
示例#26
0
ILint get_next_code(void)
{
	ILint	i, t;
	ILuint	ret;

	//20050102: Tests for IL_EOF were added because this function
	//crashed sometimes if igetc() returned IL_EOF
	//(for example "table-add-column-before-active.gif" included in the
	//mozilla source package)

	if (!nbits_left) {
		if (navail_bytes <= 0) {
			pbytes = byte_buff;
			navail_bytes = igetc();

			if(navail_bytes == IL_EOF) {
				success = IL_FALSE;
				return ending;
			}

			if (navail_bytes) {
				for (i = 0; i < navail_bytes; i++) {
					if((t = igetc()) == IL_EOF) {
						success = IL_FALSE;
						return ending;
					}
					byte_buff[i] = t;
				}
			}
		}
		b1 = *pbytes++;
		nbits_left = 8;
		navail_bytes--;
	}

	ret = b1 >> (8 - nbits_left);
	while (curr_size > nbits_left) {
		if (navail_bytes <= 0) {
			pbytes = byte_buff;
			navail_bytes = igetc();

			if(navail_bytes == IL_EOF) {
				success = IL_FALSE;
				return ending;
			}

			if (navail_bytes) {
				for (i = 0; i < navail_bytes; i++) {
					if((t = igetc()) == IL_EOF) {
						success = IL_FALSE;
						return ending;
					}
					byte_buff[i] = t;
				}
			}
		}
		b1 = *pbytes++;
		ret |= b1 << nbits_left;
		nbits_left += 8;
		navail_bytes--;
	}
	nbits_left -= curr_size;

	return (ret & code_mask[curr_size]);
}
示例#27
0
ILboolean GetImages(ILpal *GlobalPal, GIFHEAD *GifHead)
{
	IMAGEDESC	ImageDesc, OldImageDesc;
	GFXCONTROL	Gfx;
	ILboolean	BaseImage = IL_TRUE;
	ILimage		*Image = iCurImage, *TempImage = NULL;
	ILuint		NumImages = 0, i;
	ILint		input;

	Gfx.Used = IL_TRUE;

	while (!ieof()) {
		ILubyte DisposalMethod = 1;

		i = itell();
		if (!SkipExtensions(&Gfx))
			goto error_clean;
		i = itell();
		if (!Gfx.Used)
			DisposalMethod = (Gfx.Packed & 0x1C) >> 2;


		//read image descriptor
		ImageDesc.Separator = igetc();
		if (ImageDesc.Separator != 0x2C) //end of image
			break;
		ImageDesc.OffX = GetLittleUShort();
		ImageDesc.OffY = GetLittleUShort();
		ImageDesc.Width = GetLittleUShort();
		ImageDesc.Height = GetLittleUShort();
		ImageDesc.ImageInfo = igetc();
		if (ieof()) {
			ilGetError();  // Gets rid of the IL_FILE_READ_ERROR that inevitably results.
			break;
		}


		if (!BaseImage) {
			NumImages++;
			Image->Next = ilNewImage(iCurImage->Width, iCurImage->Height, 1, 1, 1);
			if (Image->Next == NULL)
				goto error_clean;

			//20040612: DisposalMethod controls how the new images data is to be combined
			//with the old image. 0 means that it doesn't matter how they are combined,
			//1 means keep the old image, 2 means set to background color, 3 is
			//load the image that was in place before the current (this is not implemented
			//here! (TODO?))
			if (DisposalMethod == 2 || DisposalMethod == 3)
				//Note that this is actually wrong, too: If the image has a local
				//color table, we should really search for the best fit of the
				//background color table and use that index (?). Furthermore,
				//we should only memset the part of the image that is not read
				//later (if we are sure that no parts of the read image are transparent).
				if (!Gfx.Used && Gfx.Packed & 0x1)
					memset(Image->Next->Data, Gfx.Transparent, Image->SizeOfData);
				else
					memset(Image->Next->Data, GifHead->Background, Image->SizeOfData);
			else if (DisposalMethod == 1 || DisposalMethod == 0)
				memcpy(Image->Next->Data, Image->Data, Image->SizeOfData);

			//Interlacing has to be removed after the image was copied (line above)
			if (OldImageDesc.ImageInfo & (1 << 6)) {  // Image is interlaced.
				if (!RemoveInterlace(Image))
					goto error_clean;
			}


			Image = Image->Next;
			Image->Format = IL_COLOUR_INDEX;
			Image->Origin = IL_ORIGIN_UPPER_LEFT;
		}
		else {
			BaseImage = IL_FALSE;
			if (!Gfx.Used && Gfx.Packed & 0x1)
				memset(Image->Data, Gfx.Transparent, Image->SizeOfData);
			else
				memset(Image->Data, GifHead->Background, Image->SizeOfData);
			//memset(Image->Data, GifHead->Background, Image->SizeOfData);
		}

		Image->OffX = ImageDesc.OffX;
		Image->OffY = ImageDesc.OffY;


		// Check to see if the image has its own palette.
		if (ImageDesc.ImageInfo & (1 << 7)) {
			if (!iGetPalette(ImageDesc.ImageInfo, &Image->Pal)) {
				goto error_clean;
			}
		}
		else {
			if (!iCopyPalette(&Image->Pal, GlobalPal)) {
				goto error_clean;
			}
		}


		if (!GifGetData(Image->Data + ImageDesc.OffX + ImageDesc.OffY*Image->Width, Image->SizeOfData,
				ImageDesc.Width, ImageDesc.Height, Image->Width, &Gfx)) {
			ilSetError(IL_ILLEGAL_FILE_VALUE);
			goto error_clean;
		}

		// See if there was a valid graphics control extension.
		if (!Gfx.Used) {
			Gfx.Used = IL_TRUE;
			Image->Duration = Gfx.Delay * 10;  // We want it in milliseconds.

			// See if a transparent colour is defined.
			if (Gfx.Packed & 1) {
				if (!ConvertTransparent(Image, Gfx.Transparent)) {
					goto error_clean;
				}
			}
		}

		i = itell();

		// Terminates each block.
		if((input = igetc()) == IL_EOF)
			goto error_clean;

		if (input != 0x00)
			iseek(-1, IL_SEEK_CUR);
		//	break;

		OldImageDesc = ImageDesc;
	}

	//Deinterlace last image
	if (OldImageDesc.ImageInfo & (1 << 6)) {  // Image is interlaced.
		if (!RemoveInterlace(Image))
			goto error_clean;
	}


	iCurImage->NumNext = NumImages;
	if (BaseImage)  // Was not able to load any images in...
		return IL_FALSE;

	return IL_TRUE;

error_clean:
	Image = iCurImage->Next;
	while (Image) {
		TempImage = Image;
		Image = Image->Next;
		ilCloseImage(TempImage);
	}
	
	return IL_FALSE;
}
示例#28
0
文件: il_gif.c 项目: kphillisjr/DevIL
ILboolean GifGetData(ILimage *Image, ILubyte *Data, ILuint ImageSize, ILuint Width, ILuint Height, ILuint Stride, ILuint PalOffset, GFXCONTROL *Gfx)
{
	ILubyte	*sp;
	ILint	code, fc, oc;
	ILubyte	DisposalMethod = 0;
	ILint	c, size;
	ILuint	i = 0, Read = 0, j = 0;
	ILubyte	*DataPtr = Data;

	if (!Gfx->Used)
		DisposalMethod = (Gfx->Packed & 0x1C) >> 2;
	if((size = igetc()) == IL_EOF)
		return IL_FALSE;

	if (size < 2 || 9 < size) {
		return IL_FALSE;
	}

	stack  = (ILubyte*)ialloc(MAX_CODES + 1);
	suffix = (ILubyte*)ialloc(MAX_CODES + 1);
	prefix = (ILshort*)ialloc(sizeof(*prefix) * (MAX_CODES + 1));
	if (!stack || !suffix || !prefix)
	{
		cleanUpGifLoadState();
		return IL_FALSE;
	}

	curr_size = size + 1;
	top_slot = 1 << curr_size;
	clear = 1 << size;
	ending = clear + 1;
	slot = newcodes = ending + 1;
	navail_bytes = nbits_left = 0;
	oc = fc = 0;
	sp = stack;

	while ((c = get_next_code()) != ending && Read < Height) {
		if (c == clear)
		{
			curr_size = size + 1;
			slot = newcodes;
			top_slot = 1 << curr_size;
			while ((c = get_next_code()) == clear);
			if (c == ending)
				break;
			if (c >= slot)
				c = 0;
			oc = fc = c;

			if (DisposalMethod == 1 && !Gfx->Used && Gfx->Transparent == c && (Gfx->Packed & 0x1) != 0)
				i++;
			else if (i < Width)
				DataPtr[i++] = c + PalOffset;

			if (i == Width)
			{
				DataPtr += Stride;
				i = 0;
				Read += 1;
                ++j;
                if (j >= Height) {
                   cleanUpGifLoadState();
                   return IL_FALSE;
                }
			}
		}
		else
		{
			code = c;
            //BG-2007-01-10: several fixes for incomplete GIFs
			if (code >= slot)
			{
				code = oc;
                if (sp >= stack + MAX_CODES) {
                   cleanUpGifLoadState();
                   return IL_FALSE;
                }
                *sp++ = fc;
			}

            if (code >= MAX_CODES)
                return IL_FALSE; 
                while (code >= newcodes)
				{
                    if (sp >= stack + MAX_CODES)
					{
                        cleanUpGifLoadState();
                        return IL_FALSE;
                    }
                    *sp++ = suffix[code];
                    code = prefix[code];
                }
            
                if (sp >= stack + MAX_CODES) {
                cleanUpGifLoadState();
                return IL_FALSE;
            }

            *sp++ = (ILbyte)code;
			if (slot < top_slot)
			{
				fc = code;
				suffix[slot]   = fc;
				prefix[slot++] = oc;
				oc = c;
			}
			if (slot >= top_slot && curr_size < 12)
			{
				top_slot <<= 1;
				curr_size++;
			}
			while (sp > stack)
			{
				sp--;
				if (DisposalMethod == 1 && !Gfx->Used && Gfx->Transparent == *sp && (Gfx->Packed & 0x1) != 0)
					i++;
				else if (i < Width)
					DataPtr[i++] = *sp + PalOffset;

				if (i == Width)
				{
					i = 0;
					Read += 1;
                    j = (j+1) % Height;
					// Needs to start from Data, not Image->Data.
					DataPtr = Data + j * Stride;
				}
			}
		}
	}
	cleanUpGifLoadState();
	return IL_TRUE;
}
示例#29
0
文件: il_dicom.cpp 项目: damucz/devil
// Internal function used to get the DICOM header from the current file.
ILboolean iGetDicomHead(DICOMHEAD *Header)
{
	ILushort	GroupNum, ElementNum;
	ILboolean	ReachedData = IL_FALSE;
	ILubyte		Var2, UID[65];

	// Signature should be "DICM" at position 128.
	iseek(128, IL_SEEK_SET);
	if (iread(Header->Signature, 1, 4) != 4)
		return IL_FALSE;

//@TODO: What about the case when we are reading an image with Big Endian data?

	do {
		GroupNum = GetGroupNum(Header);
		ElementNum = GetShort(Header, GroupNum);;

		switch (GroupNum)
		{
			case 0x02:
				switch (ElementNum)
				{
					/*case 0x01:  // Version number
						if (!GetNumericValue(&Header->Version))
							return IL_FALSE;
						if (Header->Version != 0x0100)
							return IL_FALSE;
						break;*/

					case 0x10:
						//@TODO: Look at pg. 60 of 07_05pu.pdf (PS 3.5) for more UIDs.
						if (!GetUID(UID))
							return IL_FALSE;
						if (!strncmp((const char*)UID, "1.2.840.10008.1.2.2", 64))  // Explicit big endian
							Header->BigEndian = IL_TRUE;
                        else if (!strncmp((const char*)UID, "1.2.840.10008.1.2.1", 64))  // Explicit little endian
							Header->BigEndian = IL_FALSE;
                        else if (!strncmp((const char*)UID, "1.2.840.10008.1.2", 64))  // Implicit little endian
							Header->BigEndian = IL_FALSE;
						else 
							return IL_FALSE;  // Unrecognized UID.
						break;

					default:
						if (!SkipElement(Header, GroupNum, ElementNum))  // We do not understand this entry, so we just skip it.
							return IL_FALSE;
				}
				break;

			case 0x28:
				switch (ElementNum)
				{
					case 0x02:  // Samples per pixel
						if (!GetNumericValue(Header, GroupNum, &Header->Samples))
							return IL_FALSE;
						break;

					case 0x08:  // Number of frames, or depth
						if (!GetNumericValue(Header, GroupNum, &Header->Depth))
							return IL_FALSE;
						break;

					case 0x10:  // The number of rows
						if (!GetNumericValue(Header, GroupNum, &Header->Height))
							return IL_FALSE;
						break;

					case 0x11:  // The number of columns
						if (!GetNumericValue(Header, GroupNum, &Header->Width))
							return IL_FALSE;
						break;

					case 0x100:  // Bits allocated per sample
						if (!GetNumericValue(Header, GroupNum, &Header->BitsAllocated))
							return IL_FALSE;
						break;

					case 0x101:  // Bits stored per sample - Do we really need this information?
						if (!GetNumericValue(Header, GroupNum, &Header->BitsStored))
							return IL_FALSE;
						break;

					default:
						if (!SkipElement(Header, GroupNum, ElementNum))  // We do not understand this entry, so we just skip it.
							return IL_FALSE;
				}
				break;

			case 0x7FE0:
				switch (ElementNum)
				{
					case 0x10:  // This element is the actual pixel data.  We are done with the header here.
						if (igetc() != 'O')  // @TODO: Can we assume that this is always 'O'?
							return IL_FALSE;
						Var2 = igetc();
						if (Var2 != 'B' && Var2 != 'W' && Var2 != 'F')  // 'OB', 'OW' and 'OF' accepted for this element.
							return IL_FALSE;
						GetLittleUShort();  // Skip the 2 reserved bytes.
						Header->DataLen = GetInt(Header, GroupNum);//GetLittleUInt();
						ReachedData = IL_TRUE;
						break;
					default:
						if (!SkipElement(Header, GroupNum, ElementNum))  // We do not understand this entry, so we just skip it.
							return IL_FALSE;
				}
				break;

			default:
				if (!SkipElement(Header, GroupNum, ElementNum))  // We do not understand this entry, so we just skip it.
					return IL_FALSE;
		}
	} while (!ieof() && !ReachedData);

	if (ieof())
		return IL_FALSE;

	// Some DICOM images do not have the depth (number of frames) field.
	if (Header->Depth == 0)
		Header->Depth = 1;

	switch (Header->BitsAllocated)
	{
		case 8:
			Header->Type = IL_UNSIGNED_BYTE;
			break;
		case 16:
			Header->Type = IL_UNSIGNED_SHORT;
			break;
		case 32:
			Header->Type = IL_FLOAT;  //@TODO: Is this ever an integer?
			break;
		default:  //@TODO: Any other types we can deal with?
			return IL_FALSE;
	}

	// Cannot handle more than 4 channels in an image.
	if (Header->Samples > 4)
		return IL_FALSE;
	Header->Format = ilGetFormatBpp(Header->Samples);

	return IL_TRUE;
}
示例#30
0
文件: il_pic.c 项目: AMDmi3/DevIL
// Internal function used to load the .pic
ILboolean iLoadPicInternal()
{
	ILuint		Alpha = IL_FALSE;
	ILubyte		Chained;
	CHANNEL		*Channel = NULL, *Channels = NULL, *Prev;
	PIC_HEAD	Header;
	ILboolean	Read;

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

	if (!iGetPicHead(&Header))
		return IL_FALSE;
	if (!iCheckPic(&Header)) {
		ilSetError(IL_INVALID_FILE_HEADER);
		return IL_FALSE;
	}

	// Read channels
	do {
		if (Channel == NULL) {
			Channel = Channels = (CHANNEL*)ialloc(sizeof(CHANNEL));
			if (Channels == NULL)
				return IL_FALSE;
		}
		else {
			Channels->Next = (CHANNEL*)ialloc(sizeof(CHANNEL));
			if (Channels->Next == NULL) {
				// Clean up the list before erroring out.
				while (Channel) {
					Prev = Channel;
					Channel = (CHANNEL*)Channel->Next;
					ifree(Prev);
				}
				return IL_FALSE;
			}
			Channels = (CHANNEL*)Channels->Next;
		}
		Channels->Next = NULL;

		Chained = igetc();
		Channels->Size = igetc();
		Channels->Type = igetc();
		Channels->Chan = igetc();
		if (ieof()) {
			Read = IL_FALSE;
			goto finish;
		}
		
		// See if we have an alpha channel in there
		if (Channels->Chan & PIC_ALPHA_CHANNEL)
			Alpha = IL_TRUE;
		
	} while (Chained);

	if (Alpha) {  // Has an alpha channel
		if (!ilTexImage(Header.Width, Header.Height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL)) {
			Read = IL_FALSE;
			goto finish;  // Have to destroy Channels first.
		}
	}
	else {  // No alpha channel
		if (!ilTexImage(Header.Width, Header.Height, 1, 3, IL_RGBA, IL_UNSIGNED_BYTE, NULL)) {
			Read = IL_FALSE;
			goto finish;  // Have to destroy Channels first.
		}
	}
	iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;

	Read = readScanlines((ILuint*)iCurImage->Data, Header.Width, Header.Height, Channel, Alpha);

finish:
	// Destroy channels
	while (Channel) {
		Prev = Channel;
		Channel = (CHANNEL*)Channel->Next;
		ifree(Prev);
	}

	if (Read == IL_FALSE)
		return IL_FALSE;

	return ilFixImage();
}