Beispiel #1
0
ILboolean iGetOS2Head(OS2_HEAD * const Header)
{
	if (iread(Header, sizeof(OS2_HEAD), 1) != 1)
		return IL_FALSE;

	UShort(&Header->bfType);
	UInt(&Header->biSize);
	Short(&Header->xHotspot);
	Short(&Header->yHotspot);
	UInt(&Header->DataOff);
	UInt(&Header->cbFix);

	//2003-09-01 changed to UShort according to MSDN
	UShort(&Header->cx);
	UShort(&Header->cy);
	UShort(&Header->cPlanes);
	UShort(&Header->cBitCount);

	iseek((ILint)Header->cbFix - 12, IL_SEEK_CUR);  // Skip rest of header, if any.

	return IL_TRUE;
}
Beispiel #2
0
ILvoid iUnCache()
{
	//changed 2003-09-01:
	//make iUnCache smart enough to return if
	//no cache is used
	if(!UseCache)
		return;

	if (iread == iReadLump)
		return;

	CacheSize = 0;
	CachePos = 0;
	if (Cache) {
		ifree(Cache);
		Cache = NULL;
	}
	UseCache = IL_FALSE;

	iseek(CacheStartPos + CacheBytesRead, IL_SEEK_SET);

	return;
}
Beispiel #3
0
ILboolean ilIsValidJpgF(ILHANDLE File)

{

	ILuint		FirstPos;

	ILboolean	bRet;



	iSetInputFile(File);

	FirstPos = itell();

	bRet = iIsValidJpg();

	iseek(FirstPos, IL_SEEK_SET);



	return bRet;

}
Beispiel #4
0
ILboolean ilLoadJpegF(ILHANDLE File)

{

	ILboolean	bRet;

	ILuint		FirstPos;



	iSetInputFile(File);

	FirstPos = itell();

	bRet = iLoadJpegInternal();

	iseek(FirstPos, IL_SEEK_SET);



	return bRet;

}
Beispiel #5
0
UTXIMPORTTABLE *GetUtxImportTable(UTXHEADER *Header)
{
	UTXIMPORTTABLE	*ImportTable;
	ILuint			i;

	// Go to the name table.
	iseek(Header->ImportOffset, IL_SEEK_SET);

	// Allocate the name table.
	ImportTable = (UTXIMPORTTABLE*)ialloc(Header->ImportCount * sizeof(UTXIMPORTTABLE));
	if (ImportTable == NULL)
		return NULL;

	for (i = 0; i < Header->ImportCount; i++) {
		ImportTable[i].ClassPackage = UtxReadCompactInteger();
		ImportTable[i].ClassName = UtxReadCompactInteger();
		ImportTable[i].Package = GetLittleUInt();
		ImportTable[i].ObjectName = UtxReadCompactInteger();

		ChangeObjectReference(&ImportTable[i].Package, &ImportTable[i].PackageImported);
	}

	return ImportTable;
}
Beispiel #6
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;
}
Beispiel #7
0
ILboolean ReadIndexed(PSDHEAD *Head)
{
	ILuint		ColorMode, ResourceSize, MiscInfo, i, j, NumEnt;
	ILushort	Compressed;
	ILubyte		*Palette = NULL, *Resources = NULL;

	ColorMode = GetBigUInt();  // Skip over the 'color mode data section'
	if (ColorMode % 3 != 0) {
		ilSetError(IL_INVALID_FILE_HEADER);
		return IL_FALSE;
	}
	Palette = (ILubyte*)ialloc(ColorMode);
	if (Palette == NULL)
		return IL_FALSE;
	if (iread(Palette, 1, ColorMode) != ColorMode)
		goto cleanup_error;

	ResourceSize = GetBigUInt();  // Read the 'image resources section'
	Resources = (ILubyte*)ialloc(ResourceSize);
	if (Resources == NULL) {
		return IL_FALSE;
	}
	if (iread(Resources, 1, ResourceSize) != ResourceSize)
		goto cleanup_error;

	MiscInfo = GetBigUInt();
	if (ieof())
		goto cleanup_error;
	iseek(MiscInfo, IL_SEEK_CUR);

	Compressed = GetBigUShort();
	if (ieof())
		goto cleanup_error;

	if (Head->Channels != 1 || Head->Depth != 8) {
		ilSetError(IL_FORMAT_NOT_SUPPORTED);
		goto cleanup_error;
	}
	ChannelNum = Head->Channels;

	if (!ilTexImage(Head->Width, Head->Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL))
		goto cleanup_error;

	iCurImage->Pal.Palette = (ILubyte*)ialloc(ColorMode);
	if (iCurImage->Pal.Palette == NULL) {
		goto cleanup_error;
	}
	iCurImage->Pal.PalSize = ColorMode;
	iCurImage->Pal.PalType = IL_PAL_RGB24;

	NumEnt = iCurImage->Pal.PalSize / 3;
	for (i = 0, j = 0; i < iCurImage->Pal.PalSize; i += 3, j++) {
		iCurImage->Pal.Palette[i  ] = Palette[j];
		iCurImage->Pal.Palette[i+1] = Palette[j+NumEnt];
		iCurImage->Pal.Palette[i+2] = Palette[j+NumEnt*2];
	}
	ifree(Palette);
	Palette = NULL;

	if (!PsdGetData(Head, iCurImage->Data, (ILboolean)Compressed))
		goto cleanup_error;

	ParseResources(ResourceSize, Resources);
	ifree(Resources);
	Resources = NULL;

	return IL_TRUE;

cleanup_error:
	ifree(Palette);
	ifree(Resources);

	return IL_FALSE;
}
Beispiel #8
0
// From the DTE sources (mostly by Denton Woods with corrections by Randy Heit)
ILboolean iLoadDoomInternal()
{
	ILshort	width, height, graphic_header[2], column_loop, row_loop;
	ILint	column_offset, pointer_position, first_pos;
	ILubyte	post, topdelta, length;
	ILubyte	*NewData;
	ILuint	i;

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

	first_pos = itell();  // Needed to go back to the offset table
	width = GetLittleShort();
	height = GetLittleShort();
	graphic_header[0] = GetLittleShort();  // Not even used
	graphic_header[1] = GetLittleShort();  // Not even used

	if (!ilTexImage(width, height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) {
		return IL_FALSE;
	}
	iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;

	iCurImage->Pal.Palette = (ILubyte*)ialloc(IL_DOOMPAL_SIZE);
	if (iCurImage->Pal.Palette == NULL) {
		return IL_FALSE;
	}
	iCurImage->Pal.PalSize = IL_DOOMPAL_SIZE;
	iCurImage->Pal.PalType = IL_PAL_RGB24;
	memcpy(iCurImage->Pal.Palette, ilDefaultDoomPal, IL_DOOMPAL_SIZE);

	// 247 is always the transparent colour (usually cyan)
	memset(iCurImage->Data, 247, iCurImage->SizeOfData);

	for (column_loop = 0; column_loop < width; column_loop++) {
		column_offset = GetLittleInt();
		pointer_position = itell();
		iseek(first_pos + column_offset, IL_SEEK_SET);

		while (1) {
			if (iread(&topdelta, 1, 1) != 1)
				return IL_FALSE;
			if (topdelta == 255)
				break;
			if (iread(&length, 1, 1) != 1)
				return IL_FALSE;
			if (iread(&post, 1, 1) != 1)
				return IL_FALSE; // Skip extra byte for scaling

			for (row_loop = 0; row_loop < length; row_loop++) {
				if (iread(&post, 1, 1) != 1)
					return IL_FALSE;
				if (row_loop + topdelta < height)
					iCurImage->Data[(row_loop+topdelta) * width + column_loop] = post;
			}
			iread(&post, 1, 1); // Skip extra scaling byte
		}

		iseek(pointer_position, IL_SEEK_SET);
	}

	// Converts palette entry 247 (cyan) to transparent.
	if (ilGetBoolean(IL_CONV_PAL) == IL_TRUE) {
		NewData = (ILubyte*)ialloc(iCurImage->SizeOfData * 4);
		if (NewData == NULL) {
			return IL_FALSE;
		}

		for (i = 0; i < iCurImage->SizeOfData; i++) {
			NewData[i * 4] = iCurImage->Pal.Palette[iCurImage->Data[i]];
			NewData[i * 4] = iCurImage->Pal.Palette[iCurImage->Data[i]];
			NewData[i * 4] = iCurImage->Pal.Palette[iCurImage->Data[i]];
			NewData[i * 4 + 3] = iCurImage->Data[i] != 247 ? 255 : 0;
		}

		if (!ilTexImage(iCurImage->Width, iCurImage->Height, iCurImage->Depth,
			4, IL_RGBA, iCurImage->Type, NewData)) {
			ifree(NewData);
			return IL_FALSE;
		}
		iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
		ifree(NewData);
	}

	ilFixImage();

	return IL_TRUE;
}
Beispiel #9
0
ILboolean iLoadPcdInternal()
{
	ILubyte	VertOrientation;
	ILuint	Width, Height, i, Total, x, CurPos = 0;
	ILubyte	*Y1=NULL, *Y2=NULL, *CbCr=NULL, r = 0, g = 0, b = 0;
	ILuint	PicNum;

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

	iseek(72, IL_SEEK_CUR);
	if (iread(&VertOrientation, 1, 1) != 1)
		return IL_FALSE;

	iseek(-72, IL_SEEK_CUR);  // Can't rewind

	PicNum = iGetInt(IL_PCD_PICNUM);

	switch (PicNum)
	{
		case 0:
			iseek(0x02000, IL_SEEK_CUR);
			Width = 192;
			Height = 128;
			break;
		case 1:
			iseek(0x0b800, IL_SEEK_CUR);
			Width = 384;
			Height = 256;
			break;
		case 2:
			iseek(0x30000, IL_SEEK_CUR);
			Width = 768;
			Height = 512;
			break;
		default:
			ilSetError(IL_INVALID_PARAM);
			return IL_FALSE;
	}

	if (itell() == IL_EOF)  // Supposed to have data here.
		return IL_FALSE;

	Y1 = (ILubyte*)ialloc(Width);
	Y2 = (ILubyte*)ialloc(Width);
	CbCr = (ILubyte*)ialloc(Width);
	if (Y1 == NULL || Y2 == NULL || CbCr == NULL) {
		ifree(Y1);
		ifree(Y2);
		ifree(CbCr);
		return IL_FALSE;
	}

	if (!ilTexImage(Width, Height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL)) {
		return IL_FALSE;
	}
	iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;

	Total = Height >> 1;
	for (i = 0; i < Total; i++) {
		iread(Y1, 1, Width);
		iread(Y2, 1, Width);
		if (iread(CbCr, 1, Width) != Width) {  // Only really need to check the last one.
			ifree(Y1);
			ifree(Y2);
			ifree(CbCr);
			return IL_FALSE;
		}

		for (x = 0; x < Width; x++) {
			YCbCr2RGB(Y1[x], CbCr[x / 2], CbCr[(Width / 2) + (x / 2)], &r, &g, &b);
			iCurImage->Data[CurPos++] = r;
			iCurImage->Data[CurPos++] = g;
			iCurImage->Data[CurPos++] = b;
		}

		for (x = 0; x < Width; x++) {
			YCbCr2RGB(Y2[x], CbCr[x / 2], CbCr[(Width / 2) + (x / 2)], &r, &g, &b);
			iCurImage->Data[CurPos++] = r;
			iCurImage->Data[CurPos++] = g;
			iCurImage->Data[CurPos++] = b;
		}
	}

	ifree(Y1);
	ifree(Y2);
	ifree(CbCr);

	// Not sure how it is...the documentation is hard to understand
	if ((VertOrientation & 0x3F) != 8)
		iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
	else
		iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;

	return ilFixImage();
}
Beispiel #10
0
ILboolean iLoadSunInternal(void)
{
	SUNHEAD	Header;
	BITFILE	*File;
	ILuint	i, j, Padding, Offset, BytesRead;
	ILubyte	PaddingData[16];

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

	//@TODO: Right now, iGetSunHead cannot fail.
	if (!iGetSunHead(&Header) || !iCheckSun(&Header)) {
		ilSetError(IL_INVALID_FILE_HEADER);
		return IL_FALSE;
	}

	switch (Header.Depth)
	{
		case 1:  //@TODO: Find a file to test this on.
			File = bfile(iGetFile());
			if (File == NULL)
				return IL_FALSE;

			if (!ilTexImage(Header.Width, Header.Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL))
				return IL_FALSE;
			if (Header.ColorMapLength != 0) {
				// Data should be an index into the color map, but the color map should only be RGB (6 bytes, 2 entries).
				if (Header.ColorMapLength != 6) {
					ilSetError(IL_INVALID_FILE_HEADER);
					return IL_FALSE;
				}
			}
			iCurImage->Pal.Palette = (ILubyte*)ialloc(6);  // Just need 2 entries in the color map.
			if (Header.ColorMapLength == 0) {  // Create the color map
				iCurImage->Pal.Palette[0] = 0x00;  // Entry for black
				iCurImage->Pal.Palette[1] = 0x00;
				iCurImage->Pal.Palette[2] = 0x00;
				iCurImage->Pal.Palette[3] = 0xFF;  // Entry for white
				iCurImage->Pal.Palette[4] = 0xFF;
				iCurImage->Pal.Palette[5] = 0xFF;
			}
			else {
				iread(iCurImage->Pal.Palette, 1, 6);  // Read in the color map.
			}
			iCurImage->Pal.PalSize = 6;
			iCurImage->Pal.PalType = IL_PAL_RGB24;

			Padding = (16 - (iCurImage->Width % 16)) % 16;  // Has to be aligned on a 16-bit boundary.  The rest is padding.

			// Reads the bits
			for (i = 0; i < iCurImage->Height; i++) {
				bread(&iCurImage->Data[iCurImage->Width * i], 1, iCurImage->Width, File);
				//bseek(File, BitPadding, IL_SEEK_CUR);  //@TODO: This function does not work correctly.
				bread(PaddingData, 1, Padding, File);  // Skip padding bits.
			}
			break;


		case 8:
			if (Header.ColorMapType == IL_SUN_NO_MAP) {  // Greyscale image
				if (!ilTexImage(Header.Width, Header.Height, 1, 1, IL_LUMINANCE, IL_UNSIGNED_BYTE, NULL))
					return IL_FALSE;
			}
			else {  // Colour-mapped image
				if (!ilTexImage(Header.Width, Header.Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL))
					return IL_FALSE;
				iCurImage->Pal.Palette = (ILubyte*)ialloc(Header.ColorMapLength);  // Allocate color map.
				if (iCurImage->Pal.Palette == NULL)
					return IL_FALSE;
				if (iread(iCurImage->Pal.Palette, 1, Header.ColorMapLength) != Header.ColorMapLength) {  // Read color map.
					ilSetError(IL_FILE_READ_ERROR);
					return IL_FALSE;
				}

				iCurImage->Pal.PalSize = Header.ColorMapLength;
				iCurImage->Pal.PalType = IL_PAL_RGB24;
			}

			if (Header.Type != IL_SUN_BYTE_ENC) {  // Regular uncompressed image data
				Padding = (2 - (iCurImage->Bps % 2)) % 2;  // Must be padded on a 16-bit boundary (2 bytes)
				for (i = 0; i < Header.Height; i++) {
					iread(iCurImage->Data + i * Header.Width, 1, iCurImage->Bps);
					if (Padding)  // Only possible for padding to be 0 or 1.
						igetc();
				}
			}
			else {  // RLE image data
				for (i = 0; i < iCurImage->Height; i++) {
					BytesRead = iSunGetRle(iCurImage->Data + iCurImage->Bps * i, iCurImage->Bps);
					if (BytesRead % 2)  // Each scanline must be aligned on a 2-byte boundary.
						igetc();  // Skip padding
				}
			}
			break;

		case 24:
			if (Header.ColorMapLength > 0)  // Ignore any possible colormaps.
				iseek(Header.ColorMapLength, IL_SEEK_CUR);

			if (Header.Type == IL_SUN_RGB) {
				if (!ilTexImage(Header.Width, Header.Height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL))
					return IL_FALSE;
			}
			else {
				if (!ilTexImage(Header.Width, Header.Height, 1, 3, IL_BGR, IL_UNSIGNED_BYTE, NULL))
					return IL_FALSE;
			}

			if (Header.Type != IL_SUN_BYTE_ENC) {  // Regular uncompressed image data
				Padding = (2 - (iCurImage->Bps % 2)) % 2;  // Must be padded on a 16-bit boundary (2 bytes)
				for (i = 0; i < Header.Height; i++) {
					iread(iCurImage->Data + i * Header.Width * 3, 1, iCurImage->Bps);
					if (Padding)  // Only possible for padding to be 0 or 1.
						igetc();
				}
			}
			else {  // RLE image data
				for (i = 0; i < iCurImage->Height; i++) {
					BytesRead = iSunGetRle(iCurImage->Data + iCurImage->Bps * i, iCurImage->Bps);
					if (BytesRead % 2)  // Each scanline must be aligned on a 2-byte boundary.
						igetc();  // Skip padding
				}
			}

			break;

		case 32:
			if (Header.ColorMapLength > 0)  // Ignore any possible colormaps.
				iseek(Header.ColorMapLength, IL_SEEK_CUR);

			if (Header.Type == IL_SUN_RGB) {
				if (!ilTexImage(Header.Width, Header.Height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL))
					return IL_FALSE;
			}
			else {
				if (!ilTexImage(Header.Width, Header.Height, 1, 3, IL_BGR, IL_UNSIGNED_BYTE, NULL))
					return IL_FALSE;
			}

			// There is no padding at the end of each scanline.
			Offset = 0;
			for (i = 0; i < Header.Height; i++) {
				for (j = 0; j < Header.Width; j++) {
					igetc();  // There is a pad byte before each pixel.
					iCurImage->Data[Offset]   = igetc();
					iCurImage->Data[Offset+1] = igetc();
					iCurImage->Data[Offset+2] = igetc();
				}
			}
			break;


		default:  // Should have already been checked with iGetSunHead.
			return IL_FALSE;
	}

	iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
	return ilFixImage();
}
Beispiel #11
0
ILboolean ReadLayerBlock(ILuint BlockLen)
{
	BLOCKHEAD			Block;
	LAYERINFO_CHUNK		LayerInfo;
	LAYERBITMAP_CHUNK	Bitmap;
	ILuint				ChunkSize, Padding, i, j;
	ILushort			NumChars;

	BlockLen;

	// Layer sub-block header
	if (iread(&Block, 1, sizeof(Block)) != sizeof(Block))
		return IL_FALSE;
	if (Header.MajorVersion == 3)
		Block.BlockLen = GetLittleUInt();
	else
		UInt(&Block.BlockLen);

	if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 ||
		Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00) {
			return IL_FALSE;
	}
	if (Block.BlockID != PSP_LAYER_BLOCK)
		return IL_FALSE;


	if (Header.MajorVersion == 3) {
		iseek(256, IL_SEEK_CUR);  // We don't care about the name of the layer.
		iread(&LayerInfo, sizeof(LayerInfo), 1);
		if (iread(&Bitmap, sizeof(Bitmap), 1) != 1)
			return IL_FALSE;
	}
	else {  // Header.MajorVersion >= 4
		ChunkSize = GetLittleUInt();
		NumChars = GetLittleUShort();
		iseek(NumChars, IL_SEEK_CUR);  // We don't care about the layer's name.

		ChunkSize -= (2 + 4 + NumChars);

		if (iread(&LayerInfo, IL_MIN(sizeof(LayerInfo), ChunkSize), 1) != 1)
			return IL_FALSE;

		// Can have new entries in newer versions of the spec (5.0).
		Padding = (ChunkSize) - sizeof(LayerInfo);
		if (Padding > 0)
			iseek(Padding, IL_SEEK_CUR);

		ChunkSize = GetLittleUInt();
		if (iread(&Bitmap, sizeof(Bitmap), 1) != 1)
			return IL_FALSE;
		Padding = (ChunkSize - 4) - sizeof(Bitmap);
		if (Padding > 0)
			iseek(Padding, IL_SEEK_CUR);
	}


	Channels = (ILubyte**)ialloc(sizeof(ILubyte*) * Bitmap.NumChannels);
	if (Channels == NULL) {
		return IL_FALSE;
	}

	NumChannels = Bitmap.NumChannels;

	for (i = 0; i < NumChannels; i++) {
		Channels[i] = GetChannel();
		if (Channels[i] == NULL) {
			for (j = 0; j < i; j++)
				ifree(Channels[j]);
			return IL_FALSE;
		}
	}

	return IL_TRUE;
}
Beispiel #12
0
ILboolean iLoadBlp1()
{
    BLP1HEAD	Header;
    ILubyte		*DataAndAlpha, *Palette;
    ILuint		i;
    ILimage		*Image = iCurImage;
    ILboolean	BaseCreated = IL_FALSE;
#ifndef IL_NO_JPG
    ILubyte		*JpegHeader, *JpegData;
    ILuint		JpegHeaderSize;
#endif//IL_NO_JPG

    if (!iGetBlp1Head(&Header))
        return IL_FALSE;
    if (!iCheckBlp1(&Header)) {
        ilSetError(IL_INVALID_FILE_HEADER);
        return IL_FALSE;
    }

    //@TODO: Remove this.
    i = 0;

    switch (Header.Compression)
    {
    case BLP_TYPE_JPG:
#ifdef IL_NO_JPG
        // We can only do the Jpeg decoding if we do not have IL_NO_JPEG defined.
        return IL_FALSE;
#else
        JpegHeaderSize = GetLittleUInt();
        JpegHeader = (ILubyte*)ialloc(JpegHeaderSize);
        if (JpegHeader == NULL)
            return IL_FALSE;
        // Read the shared Jpeg header.
        if (iread(JpegHeader, 1, JpegHeaderSize) != JpegHeaderSize) {
            ifree(JpegHeader);
            return IL_FALSE;
        }

        //for (i = 0; i < 16; i++) {  // Possible maximum of 16 mipmaps
        //@TODO: Check return value?
        iseek(Header.MipOffsets[i], IL_SEEK_SET);
        JpegData = (ILubyte*)ialloc(JpegHeaderSize + Header.MipLengths[i]);
        if (JpegData == NULL) {
            ifree(JpegHeader);
            return IL_FALSE;
        }
        memcpy(JpegData, JpegHeader, JpegHeaderSize);
        if (iread(JpegData + JpegHeaderSize, Header.MipLengths[i], 1) != 1)
            return IL_FALSE;

        // Just send the data straight to the Jpeg loader.
        if (!ilLoadJpegL(JpegData, JpegHeaderSize + Header.MipLengths[i]))
            return IL_FALSE;

        // The image data is in BGR(A) order, even though it is Jpeg-compressed.
        if (Image->Format == IL_RGBA)
            Image->Format = IL_BGRA;
        if (Image->Format == IL_RGB)
            Image->Format = IL_BGR;

        ifree(JpegData);
        //}
        ifree(JpegHeader);
#endif//IL_NO_JPG
        break;

    case BLP_RAW:
        switch (Header.PictureType)
        {
        // There is no alpha list, so we just read like a normal indexed image.
        case BLP_RAW_NO_ALPHA:
            for (i = 0; i < 16; i++) {  // Possible maximum of 16 mipmaps
                if (!BaseCreated) {  // Have not created the base image yet, so use ilTexImage.
                    if (!ilTexImage(Header.Width, Header.Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL))
                        return IL_FALSE;
                    Image = iCurImage;
                    BaseCreated = IL_TRUE;

                    // We have a BGRA palette.
                    Image->Pal.Palette = (ILubyte*)ialloc(256 * 4);
                    if (Image->Pal.Palette == NULL)
                        return IL_FALSE;
                    Image->Pal.PalSize = 1024;
                    Image->Pal.PalType = IL_PAL_BGRA32;

                    // Read in the palette ...
                    if (iread(Image->Pal.Palette, 1, 1024) != 1024)
                        return IL_FALSE;
                }
                else {
                    if (Image->Width == 1 && Image->Height == 1)  // Already at the smallest mipmap (1x1), so we are done.
                        break;
                    if (Header.MipOffsets[i] == 0 || Header.MipLengths[i] == 0)  // No more mipmaps in the file.
                        break;

                    Image->Mipmaps = ilNewImageFull(Image->Width >> 1, Image->Height >> 1, 1, 1, IL_COLOR_INDEX, IL_UNSIGNED_BYTE, NULL);
                    if (Image->Mipmaps == NULL)
                        return IL_FALSE;

                    // Copy the palette from the first image before we change our Image pointer.
                    Image->Mipmaps->Pal.Palette = (ILubyte*)ialloc(256 * 4);
                    if (Image->Mipmaps->Pal.Palette == NULL)
                        return IL_FALSE;
                    Image->Mipmaps->Pal.PalSize = 1024;
                    Image->Mipmaps->Pal.PalType = IL_PAL_BGRA32;
                    memcpy(Image->Mipmaps->Pal.Palette, Image->Pal.Palette, 1024);

                    // Move to the next mipmap in the linked list.
                    Image = Image->Mipmaps;
                }
                // The origin should be in the upper left.
                Image->Origin = IL_ORIGIN_UPPER_LEFT;

                // Seek to the data and read it.
                iseek(Header.MipOffsets[i], IL_SEEK_SET);
                if (iread(Image->Data, 1, Image->SizeOfData) != Image->SizeOfData)
                    return IL_FALSE;
            }
            break;

        // These cases are identical and have an alpha list following the image data.
        case BLP_RAW_PLUS_ALPHA1:
        case BLP_RAW_PLUS_ALPHA2:
            // Create the image.
            if (!ilTexImage(Header.Width, Header.Height, 1, 4, IL_BGRA, IL_UNSIGNED_BYTE, NULL))
                return IL_FALSE;

            DataAndAlpha = (ILubyte*)ialloc(Header.Width * Header.Height);
            Palette = (ILubyte*)ialloc(256 * 4);
            if (DataAndAlpha == NULL || Palette == NULL) {
                ifree(DataAndAlpha);
                ifree(Palette);
                return IL_FALSE;
            }

            // Read in the data and the palette.
            if (iread(Palette, 1, 1024) != 1024) {
                ifree(Palette);
                return IL_FALSE;
            }
            // Seek to the data and read it.
            iseek(Header.MipOffsets[i], IL_SEEK_SET);
            if (iread(DataAndAlpha, Header.Width * Header.Height, 1) != 1) {
                ifree(DataAndAlpha);
                ifree(Palette);
                return IL_FALSE;
            }

            // Convert the color-indexed data to BGRX.
            for (i = 0; i < Header.Width * Header.Height; i++) {
                Image->Data[i*4]   = Palette[DataAndAlpha[i]*4];
                Image->Data[i*4+1] = Palette[DataAndAlpha[i]*4+1];
                Image->Data[i*4+2] = Palette[DataAndAlpha[i]*4+2];
            }

            // Read in the alpha list.
            if (iread(DataAndAlpha, Header.Width * Header.Height, 1) != 1) {
                ifree(DataAndAlpha);
                ifree(Palette);
                return IL_FALSE;
            }
            // Finally put the alpha data into the image data.
            for (i = 0; i < Header.Width * Header.Height; i++) {
                Image->Data[i*4+3] = DataAndAlpha[i];
            }

            ifree(DataAndAlpha);
            ifree(Palette);
            break;
        }
        break;

        //default:  // Should already be checked by iCheckBlp1.
    }

    // Set the origin (always upper left).
    Image->Origin = IL_ORIGIN_UPPER_LEFT;

    return ilFixImage();
}
Beispiel #13
0
// Internal function to uncompress the .pcx (all .pcx files are rle compressed)
ILboolean iUncompressPcx(PCXHEAD *Header)
{
	//changed decompression loop 2003-09-01
	//From the pcx spec: "There should always
	//be a decoding break at the end of each scan line.
	//But there will not be a decoding break at the end of
	//each plane within each scan line."
	//This is now handled correctly (hopefully ;) )

	ILubyte	ByteHead, Colour, *ScanLine /* For all planes */;
	ILuint ScanLineSize;
	ILuint	c, i, x, y;

	if (Header->Bpp < 8) {
		/*ilSetError(IL_FORMAT_NOT_SUPPORTED);
		return IL_FALSE;*/
		return iUncompressSmall(Header);
	}

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

	switch (iCurImage->Bpp)
	{
		case 1:
			iCurImage->Format = IL_COLOUR_INDEX;
			iCurImage->Pal.PalType = IL_PAL_RGB24;
			iCurImage->Pal.PalSize = 256 * 3;  // Need to find out for sure...
			iCurImage->Pal.Palette = (ILubyte*)ialloc(iCurImage->Pal.PalSize);
			if (iCurImage->Pal.Palette == NULL) {
				return IL_FALSE;
			}
			break;
		//case 2:  // No 16-bit images in the pcx format!
		case 3:
			iCurImage->Format = IL_RGB;
			iCurImage->Pal.Palette = NULL;
			iCurImage->Pal.PalSize = 0;
			iCurImage->Pal.PalType = IL_PAL_NONE;
			break;
		case 4:
			iCurImage->Format = IL_RGBA;
			iCurImage->Pal.Palette = NULL;
			iCurImage->Pal.PalSize = 0;
			iCurImage->Pal.PalType = IL_PAL_NONE;
			break;

		default:
			ilSetError(IL_ILLEGAL_FILE_VALUE);
			return IL_FALSE;
	}

	ScanLineSize = iCurImage->Bpp*Header->Bps;
	ScanLine = (ILubyte*)ialloc(ScanLineSize);
	if (ScanLine == NULL) {
		return IL_FALSE;
	}


	//changed 2003-09-01
	//having the decoding code twice is error-prone,
	//so I made iUnCache() smart enough to grasp
	//if iPreCache() wasn't called and call it
	//anyways.
	if (iGetHint(IL_MEM_SPEED_HINT) == IL_FASTEST)
		iPreCache(iCurImage->SizeOfData / 4);

	for (y = 0; y < iCurImage->Height; y++) {
		x = 0;
		//read scanline
		while (x < ScanLineSize) {
			if (iread(&ByteHead, 1, 1) != 1) {
				iUnCache();
				goto file_read_error;
			}
			if ((ByteHead & 0xC0) == 0xC0) {
				ByteHead &= 0x3F;
				if (iread(&Colour, 1, 1) != 1) {
					iUnCache();
					goto file_read_error;
				}
				if (x + ByteHead > ScanLineSize) {
					iUnCache();
					goto file_read_error;
				}
				for (i = 0; i < ByteHead; i++) {
					ScanLine[x++] = Colour;
				}
			}
			else {
				ScanLine[x++] = ByteHead;
			}
		}

		//convert plane-separated scanline into index, rgb or rgba pixels.
		//there might be a padding byte at the end of each scanline...
		for (x = 0; x < iCurImage->Width; x++) {
			for(c = 0; c < iCurImage->Bpp; c++) {
				iCurImage->Data[y * iCurImage->Bps + x * iCurImage->Bpp + c] =
						ScanLine[x + c * Header->Bps];
			}
		}
	}

	iUnCache();

	// Read in the palette
	if (Header->Version == 5 && iCurImage->Bpp == 1) {
		x = itell();
		if (iread(&ByteHead, 1, 1) == 0) {  // If true, assume that we have a luminance image.
			ilGetError();  // Get rid of the IL_FILE_READ_ERROR.
			iCurImage->Format = IL_LUMINANCE;
			if (iCurImage->Pal.Palette)
				ifree(iCurImage->Pal.Palette);
			iCurImage->Pal.PalSize = 0;
			iCurImage->Pal.PalType = IL_PAL_NONE;
		}
		else {
			if (ByteHead != 12)  // Some Quake2 .pcx files don't have this byte for some reason.
				iseek(-1, IL_SEEK_CUR);
			if (iread(iCurImage->Pal.Palette, 1, iCurImage->Pal.PalSize) != iCurImage->Pal.PalSize)
				goto file_read_error;
		}
	}

	ifree(ScanLine);

	return IL_TRUE;

file_read_error:
	ifree(ScanLine);

	//added 2003-09-01
	ilSetError(IL_FILE_READ_ERROR);
	return IL_FALSE;
}
Beispiel #14
0
// Internal function used to load the icon.
ILboolean iLoadIcnsInternal()
{
	ICNSHEAD	Header;
	ICNSDATA	Entry;
	ILimage		*Image = NULL;
	ILboolean	BaseCreated = IL_FALSE;


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

	iread(Header.Head, 4, 1);
	Header.Size = GetBigInt();

	if (strncmp(Header.Head, "icns", 4))  // First 4 bytes have to be 'icns'.
		return IL_FALSE;

	while ((ILint)itell() < Header.Size && !ieof())
	{
		iread(Entry.ID, 4, 1);
		Entry.Size = GetBigInt();

		if (!strncmp(Entry.ID, "it32", 4))  // 128x128 24-bit
		{
			if (iIcnsReadData(&BaseCreated, IL_FALSE, 128, &Entry, &Image) == IL_FALSE)
				goto icns_error;
		}
		else if (!strncmp(Entry.ID, "t8mk", 4))  // 128x128 alpha mask
		{
			if (iIcnsReadData(&BaseCreated, IL_TRUE, 128, &Entry, &Image) == IL_FALSE)
				goto icns_error;
		}
		else if (!strncmp(Entry.ID, "ih32", 4))  // 48x48 24-bit
		{
			if (iIcnsReadData(&BaseCreated, IL_FALSE, 48, &Entry, &Image) == IL_FALSE)
				goto icns_error;
		}
		else if (!strncmp(Entry.ID, "h8mk", 4))  // 48x48 alpha mask
		{
			if (iIcnsReadData(&BaseCreated, IL_TRUE, 48, &Entry, &Image) == IL_FALSE)
				goto icns_error;
		}
		else if (!strncmp(Entry.ID, "il32", 4))  // 32x32 24-bit
		{
			if (iIcnsReadData(&BaseCreated, IL_FALSE, 32, &Entry, &Image) == IL_FALSE)
				goto icns_error;
		}
		else if (!strncmp(Entry.ID, "l8mk", 4))  // 32x32 alpha mask
		{
			if (iIcnsReadData(&BaseCreated, IL_TRUE, 32, &Entry, &Image) == IL_FALSE)
				goto icns_error;
		}
		else if (!strncmp(Entry.ID, "is32", 4))  // 16x16 24-bit
		{
			if (iIcnsReadData(&BaseCreated, IL_FALSE, 16, &Entry, &Image) == IL_FALSE)
				goto icns_error;
		}
		else if (!strncmp(Entry.ID, "s8mk", 4))  // 16x16 alpha mask
		{
			if (iIcnsReadData(&BaseCreated, IL_TRUE, 16, &Entry, &Image) == IL_FALSE)
				goto icns_error;
		}
#ifndef IL_NO_JP2
		else if (!strncmp(Entry.ID, "ic09", 4))  // 512x512 JPEG2000 encoded - Uses JasPer
		{
			if (iIcnsReadData(&BaseCreated, IL_FALSE, 512, &Entry, &Image) == IL_FALSE)
				goto icns_error;
		}
		else if (!strncmp(Entry.ID, "ic08", 4))  // 256x256 JPEG2000 encoded - Uses JasPer
		{
			if (iIcnsReadData(&BaseCreated, IL_FALSE, 256, &Entry, &Image) == IL_FALSE)
				goto icns_error;
		}
#endif//IL_NO_JP2
		else  // Not a valid format or one that we can use
		{
			iseek(Entry.Size - 8, IL_SEEK_CUR);
		}
	}

	return ilFixImage();

icns_error:
	return IL_FALSE;
}
Beispiel #15
0
// Internal function used to load the BLP.
ILboolean iLoadBlpInternal(void)
{
    BLP2HEAD	Header;
    ILubyte		*CompData;
    ILimage		*Image;
    ILuint		Mip, j, x, CompSize, AlphaSize, AlphaOff;
    ILint		y;
    ILboolean	BaseCreated = IL_FALSE;
    ILubyte		*DataAndAlpha = NULL, *Palette = NULL, AlphaMask; //, *JpegHeader, *JpegData;

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

    if (!iGetBlp2Head(&Header)) {
        ilSetError(IL_INVALID_FILE_HEADER);
        return IL_FALSE;
    }
    if (!iCheckBlp2(&Header)) {
        goto check_blp1;
    }

//@TODO: Remove this!
    if (Header.Type != BLP_TYPE_DXTC_RAW)
        return IL_FALSE;

    switch (Header.Compression)
    {
    case BLP_RAW:
        for (Mip = 0; Mip < 16; Mip++) {  // Possible maximum of 16 mipmaps
            if (BaseCreated) {
                if (Header.HasMips == 0)  // Does not have mipmaps, so we are done.
                    break;
                if (Image->Width == 1 && Image->Height == 1)  // Already at the smallest mipmap (1x1), so we are done.
                    break;
                if (Header.MipOffsets[Mip] == 0 || Header.MipLengths == 0)  // No more mipmaps in the file.
                    break;
            }

            switch (Header.AlphaBits)
            {
            case 0:
                if (!BaseCreated) {  // Have not created the base image yet, so use ilTexImage.
                    if (!ilTexImage(Header.Width, Header.Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL))
                        return IL_FALSE;
                    Image = iCurImage;
                    BaseCreated = IL_TRUE;

                    Image->Pal.Palette = (ILubyte*)ialloc(256 * 4);  // 256 entries of ARGB8888 values (1024).
                    if (Image->Pal.Palette == NULL)
                        return IL_FALSE;
                    Image->Pal.PalSize = 1024;
                    Image->Pal.PalType = IL_PAL_BGRA32;  //@TODO: Find out if this is really BGRA data.
                    if (iread(Image->Pal.Palette, 1, 1024) != 1024)  // Read in the palette.
                        return IL_FALSE;
                }
                else {
                    Image->Mipmaps = ilNewImageFull(Image->Width >> 1, Image->Height >> 1, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL);
                    if (Image->Mipmaps == NULL)
                        return IL_FALSE;

                    // Copy the palette from the first image before we change our Image pointer.
                    iCopyPalette(&Image->Mipmaps->Pal, &Image->Pal);
                    // Move to the next mipmap in the linked list.
                    Image = Image->Mipmaps;
                }
                // The origin should be in the upper left.
                Image->Origin = IL_ORIGIN_UPPER_LEFT;

                // These two should be the same (tells us how much data is in the file for this mipmap level).
                if (Header.MipLengths[Mip] != Image->SizeOfData) {
                    ilSetError(IL_INVALID_FILE_HEADER);
                    return IL_FALSE;
                }
                // Finally read in the image data.
                iseek(Header.MipOffsets[Mip], IL_SEEK_SET);
                if (iread(Image->Data, 1, Image->SizeOfData) != Image->SizeOfData)
                    return IL_FALSE;
                break;

            case 1:
                if (!BaseCreated) {  // Have not created the base image yet, so use ilTexImage.
                    if (!ilTexImage(Header.Width, Header.Height, 1, 4, IL_BGRA, IL_UNSIGNED_BYTE, NULL))
                        return IL_FALSE;
                    Image = iCurImage;
                    BaseCreated = IL_TRUE;

                    Palette = (ILubyte*)ialloc(256 * 4);
                    if (Palette == NULL)
                        return IL_FALSE;

                    // Read in the palette.
                    if (iread(Palette, 1, 1024) != 1024) {
                        ifree(Palette);
                        return IL_FALSE;
                    }

                    // We only allocate this once and reuse this buffer with every mipmap (since successive ones are smaller).
                    DataAndAlpha = (ILubyte*)ialloc(Image->Width * Image->Height);
                    if (DataAndAlpha == NULL) {
                        ifree(DataAndAlpha);
                        ifree(Palette);
                        return IL_FALSE;
                    }
                }
                else {
                    Image->Mipmaps = ilNewImageFull(Image->Width >> 1, Image->Height >> 1, 1, 4, IL_BGRA, IL_UNSIGNED_BYTE, NULL);
                    if (Image->Mipmaps == NULL)
                        return IL_FALSE;

                    // Move to the next mipmap in the linked list.
                    Image = Image->Mipmaps;
                }
                // The origin should be in the upper left.
                Image->Origin = IL_ORIGIN_UPPER_LEFT;

                // Determine the size of the alpha data following the color indices.
                AlphaSize = Image->Width * Image->Height / 8;
                if (AlphaSize == 0)
                    AlphaSize = 1;  // Should never be 0.
                // These two should be the same (tells us how much data is in the file for this mipmap level).
                if (Header.MipLengths[Mip] != Image->SizeOfData / 4 + AlphaSize) {
                    ilSetError(IL_INVALID_FILE_HEADER);
                    return IL_FALSE;
                }

                // Seek to the data and read it.
                iseek(Header.MipOffsets[Mip], IL_SEEK_SET);
                if (iread(DataAndAlpha, Image->Width * Image->Height, 1) != 1) {
                    ifree(DataAndAlpha);
                    ifree(Palette);
                    return IL_FALSE;
                }

                // Convert the color-indexed data to BGRX.
                for (j = 0; j < Image->Width * Image->Height; j++) {
                    Image->Data[j*4]   = Palette[DataAndAlpha[j]*4];
                    Image->Data[j*4+1] = Palette[DataAndAlpha[j]*4+1];
                    Image->Data[j*4+2] = Palette[DataAndAlpha[j]*4+2];
                }

                // Read in the alpha list.
                if (iread(DataAndAlpha, AlphaSize, 1) != 1) {
                    ifree(DataAndAlpha);
                    ifree(Palette);
                    return IL_FALSE;
                }

                AlphaMask = 0x01;  // Lowest bit
                AlphaOff = 0;
                // The really strange thing about this alpha data is that it is upside-down when compared to the
                //   regular color-indexed data, so we have to flip it.
                for (y = Image->Height - 1; y >= 0; y--) {
                    for (x = 0; x < Image->Width; x++) {
                        if (AlphaMask == 0) {  // Shifting it past the highest bit makes it 0, since we only have 1 byte.
                            AlphaOff++;        // Move along the alpha buffer.
                            AlphaMask = 0x01;  // Reset the alpha mask.
                        }
                        // This is just 1-bit alpha, so it is either on or off.
                        Image->Data[Image->Bps * y + x * 4 + 3] = DataAndAlpha[AlphaOff] & AlphaMask ? 0xFF : 0x00;
                        AlphaMask <<= 1;
                    }
                }

                break;

            default:
                //@TODO: Accept any other alpha values?
                ilSetError(IL_INVALID_FILE_HEADER);
                return IL_FALSE;
            }
        }

        // Done, so we can finally free these two.
        ifree(DataAndAlpha);
        ifree(Palette);

        break;

    case BLP_DXTC:
        for (Mip = 0; Mip < 16; Mip++) {  // Possible maximum of 16 mipmaps
            //@TODO: Other formats
            //if (Header.AlphaBits == 0)
            //	if (!ilTexImage(Header.Width, Header.Height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL))
            //	return IL_FALSE;
            if (!BaseCreated) {  // Have not created the base image yet, so use ilTexImage.
                if (!ilTexImage(Header.Width, Header.Height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL))
                    return IL_FALSE;
                Image = iCurImage;
                BaseCreated = IL_TRUE;
            }
            else {
                if (Header.HasMips == 0)  // Does not have mipmaps, so we are done.
                    break;
                if (Image->Width == 1 && Image->Height == 1)  // Already at the smallest mipmap (1x1), so we are done.
                    break;
                if (Header.MipOffsets[Mip] == 0 || Header.MipLengths[Mip] == 0)  // No more mipmaps in the file.
                    break;

                //@TODO: Other formats
                // ilNewImageFull automatically changes widths and heights of 0 to 1, so we do not have to worry about it.
                Image->Mipmaps = ilNewImageFull(Image->Width >> 1, Image->Height >> 1, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL);
                if (Image->Mipmaps == NULL)
                    return IL_FALSE;
                Image = Image->Mipmaps;
            }
            // The origin should be in the upper left.
            Image->Origin = IL_ORIGIN_UPPER_LEFT;

            //@TODO: Only do the allocation once.
            CompData = (ILubyte*)ialloc(Header.MipLengths[Mip]);
            if (CompData == NULL)
                return IL_FALSE;

            // Read in the compressed mipmap data.
            iseek(Header.MipOffsets[Mip], IL_SEEK_SET);
            if (iread(CompData, 1, Header.MipLengths[Mip]) != Header.MipLengths[Mip]) {
                ifree(CompData);
                return IL_FALSE;
            }

            switch (Header.AlphaBits)
            {
            case 0:  // DXT1 without alpha
            case 1:  // DXT1 with alpha
                // Check to make sure that the MipLength reported is the size needed, so that
                //  DecompressDXT1 does not crash.
                CompSize = ((Image->Width + 3) / 4) * ((Image->Height + 3) / 4) * 8;
                if (CompSize != Header.MipLengths[Mip]) {
                    ilSetError(IL_INVALID_FILE_HEADER);
                    ifree(CompData);
                    return IL_FALSE;
                }
                if (!DecompressDXT1(Image, CompData)) {
                    ifree(CompData);
                    return IL_FALSE;
                }
                break;

            case 8:
                // Check to make sure that the MipLength reported is the size needed, so that
                //  DecompressDXT3/5 do not crash.
                CompSize = ((Image->Width + 3) / 4) * ((Image->Height + 3) / 4) * 16;
                if (CompSize != Header.MipLengths[Mip]) {
                    ifree(CompData);
                    ilSetError(IL_INVALID_FILE_HEADER);
                    return IL_FALSE;
                }
                switch (Header.AlphaType)
                {
                case 0:  // All three of
                case 1:  //  these refer to
                case 8:  //  DXT3...
                    if (!DecompressDXT3(Image, CompData)) {
                        ifree(CompData);
                        return IL_FALSE;
                    }
                    break;

                case 7:  // DXT5 compression
                    if (!DecompressDXT5(Image, CompData)) {
                        ifree(CompData);
                        return IL_FALSE;
                    }
                    break;

                    //default:  // Should already be checked by iCheckBlp2.
                }
                break;
                //default:  // Should already be checked by iCheckBlp2.
            }
            //@TODO: Save DXTC data.
            ifree(CompData);
        }
        break;
        //default:
    }

    return ilFixImage();

check_blp1:
    iseek(-148, IL_SEEK_CUR);  // Go back the size of the BLP2 header, since we tried reading it.
    return iLoadBlp1();
}
Beispiel #16
0
ILboolean iReadRleSgi(iSgiHeader *Head)
{
	#ifdef __LITTLE_ENDIAN__
	ILuint ixTable;
	#endif
	ILuint 		ChanInt = 0;
	ILuint  	ixPlane, ixHeight,ixPixel, RleOff, RleLen;
	ILuint		*OffTable=NULL, *LenTable=NULL, TableSize, Cur;
	ILubyte		**TempData=NULL;

	if (!iNewSgi(Head))
		return IL_FALSE;

	TableSize = Head->YSize * Head->ZSize;
	OffTable = (ILuint*)ialloc(TableSize * sizeof(ILuint));
	LenTable = (ILuint*)ialloc(TableSize * sizeof(ILuint));
	if (OffTable == NULL || LenTable == NULL)
		goto cleanup_error;
	if (iread(OffTable, TableSize * sizeof(ILuint), 1) != 1)
		goto cleanup_error;
	if (iread(LenTable, TableSize * sizeof(ILuint), 1) != 1)
		goto cleanup_error;

#ifdef __LITTLE_ENDIAN__
	// Fix the offset/len table (it's big endian format)
	for (ixTable = 0; ixTable < TableSize; ixTable++) {
		iSwapUInt(OffTable + ixTable);
		iSwapUInt(LenTable + ixTable);
	}
#endif //__LITTLE_ENDIAN__

	// We have to create a temporary buffer for the image, because SGI
	//	images are plane-separated. */
	TempData = (ILubyte**)ialloc(Head->ZSize * sizeof(ILubyte*));
	if (TempData == NULL)
		goto cleanup_error;
	imemclear(TempData, Head->ZSize * sizeof(ILubyte*));  // Just in case ialloc fails then cleanup_error.
	for (ixPlane = 0; ixPlane < Head->ZSize; ixPlane++) {
		TempData[ixPlane] = (ILubyte*)ialloc(Head->XSize * Head->YSize * Head->Bpc);
		if (TempData[ixPlane] == NULL)
			goto cleanup_error;
	}

	// Read the Planes into the temporary memory
	for (ixPlane = 0; ixPlane < Head->ZSize; ixPlane++) {
		for (ixHeight = 0, Cur = 0;	ixHeight < Head->YSize;
			ixHeight++, Cur += Head->XSize * Head->Bpc) {

			RleOff = OffTable[ixHeight + ixPlane * Head->YSize];
			RleLen = LenTable[ixHeight + ixPlane * Head->YSize];
			
			// Seeks to the offset table position
			iseek(RleOff, IL_SEEK_SET);
			if (iGetScanLine((TempData[ixPlane]) + (ixHeight * Head->XSize * Head->Bpc),
				Head, RleLen) != Head->XSize * Head->Bpc) {
					ilSetError(IL_ILLEGAL_FILE_VALUE);
					goto cleanup_error;
			}
		}
	}

	// DW: Removed on 05/25/2002.
	/*// Check if an alphaplane exists and invert it
	if (Head->ZSize == 4) {
		for (ixPixel=0; (ILint)ixPixel<Head->XSize * Head->YSize; ixPixel++) {
 			TempData[3][ixPixel] = TempData[3][ixPixel] ^ 255;
 		}	
	}*/
	
	// Assemble the image from its planes
	for (ixPixel = 0; ixPixel < iCurImage->SizeOfData;
		ixPixel += Head->ZSize * Head->Bpc, ChanInt += Head->Bpc) {
		for (ixPlane = 0; (ILint)ixPlane < Head->ZSize * Head->Bpc;	ixPlane += Head->Bpc) {
			iCurImage->Data[ixPixel + ixPlane] = TempData[ixPlane][ChanInt];
			if (Head->Bpc == 2)
				iCurImage->Data[ixPixel + ixPlane + 1] = TempData[ixPlane][ChanInt + 1];
		}
	}

	#ifdef __LITTLE_ENDIAN__
	if (Head->Bpc == 2)
		sgiSwitchData(iCurImage->Data, iCurImage->SizeOfData);
	#endif

	ifree(OffTable);
	ifree(LenTable);

	for (ixPlane = 0; ixPlane < Head->ZSize; ixPlane++) {
		ifree(TempData[ixPlane]);
	}
	ifree(TempData);

	return IL_TRUE;

cleanup_error:
	ifree(OffTable);
	ifree(LenTable);
	if (TempData) {
		for (ixPlane = 0; ixPlane < Head->ZSize; ixPlane++) {
			ifree(TempData[ixPlane]);
		}
		ifree(TempData);
	}

	return IL_FALSE;
}
Beispiel #17
0
ILubyte *GetChannel()
{
	BLOCKHEAD		Block;
	CHANNEL_CHUNK	Channel;
	ILubyte			*CompData, *Data;
	ILuint			ChunkSize, Padding;

	if (iread(&Block, 1, sizeof(Block)) != sizeof(Block))
		return NULL;
	if (Header.MajorVersion == 3)
		Block.BlockLen = GetLittleUInt();
	else
		UInt(&Block.BlockLen);

	if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 ||
		Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00) {
			ilSetError(IL_ILLEGAL_FILE_VALUE);
			return NULL;
	}
	if (Block.BlockID != PSP_CHANNEL_BLOCK) {
		ilSetError(IL_ILLEGAL_FILE_VALUE);
		return NULL;
	}


	if (Header.MajorVersion >= 4) {
		ChunkSize = GetLittleUInt();
		if (iread(&Channel, sizeof(Channel), 1) != 1)
			return NULL;

		Padding = (ChunkSize - 4) - sizeof(Channel);
		if (Padding > 0)
			iseek(Padding, IL_SEEK_CUR);
	}
	else {
		if (iread(&Channel, sizeof(Channel), 1) != 1)
			return NULL;
	}


	CompData = (ILubyte*)ialloc(Channel.CompLen);
	Data = (ILubyte*)ialloc(AttChunk.Width * AttChunk.Height);
	if (CompData == NULL || Data == NULL) {
		ifree(Data);
		ifree(CompData);
		return NULL;
	}

	if (iread(CompData, 1, Channel.CompLen) != Channel.CompLen) {
		ifree(CompData);
		ifree(Data);
		return NULL;
	}

	switch (AttChunk.Compression)
	{
		case PSP_COMP_NONE:
			ifree(Data);
			return CompData;
			break;

		case PSP_COMP_RLE:
			if (!UncompRLE(CompData, Data, Channel.CompLen)) {
				ifree(CompData);
				ifree(Data);
				return IL_FALSE;
			}
			break;

		default:
			ifree(CompData);
			ifree(Data);
			ilSetError(IL_INVALID_FILE_HEADER);
			return NULL;
	}

	ifree(CompData);

	return Data;
}
Beispiel #18
0
ILboolean ReadAlphaBlock(ILuint BlockLen)
{
	BLOCKHEAD		Block;
	ALPHAINFO_CHUNK	AlphaInfo;
	ALPHA_CHUNK		AlphaChunk;
	ILushort		NumAlpha, StringSize;
	ILuint			ChunkSize, Padding;

	if (Header.MajorVersion == 3) {
		NumAlpha = GetLittleUShort();
	}
	else {
		ChunkSize = GetLittleUInt();
		NumAlpha = GetLittleUShort();
		Padding = (ChunkSize - 4 - 2);
		if (Padding > 0)
			iseek(Padding, IL_SEEK_CUR);
	}

	// Alpha channel header
	if (iread(&Block, 1, sizeof(Block)) != sizeof(Block))
		return IL_FALSE;
	if (Header.MajorVersion == 3)
		Block.BlockLen = GetLittleUInt();
	else
		UInt(&Block.BlockLen);

	if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 ||
		Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00) {
			return IL_FALSE;
	}
	if (Block.BlockID != PSP_ALPHA_CHANNEL_BLOCK)
		return IL_FALSE;


	if (Header.MajorVersion >= 4) {
		ChunkSize = GetLittleUInt();
		StringSize = GetLittleUShort();
		iseek(StringSize, IL_SEEK_CUR);
		if (iread(&AlphaInfo, sizeof(AlphaInfo), 1) != 1)
			return IL_FALSE;
		Padding = (ChunkSize - 4 - 2 - StringSize - sizeof(AlphaInfo));
		if (Padding > 0)
			iseek(Padding, IL_SEEK_CUR);

		ChunkSize = GetLittleUInt();
		if (iread(&AlphaChunk, sizeof(AlphaChunk), 1) != 1)
			return IL_FALSE;
		Padding = (ChunkSize - 4 - sizeof(AlphaChunk));
		if (Padding > 0)
			iseek(Padding, IL_SEEK_CUR);
	}
	else {
		iseek(256, IL_SEEK_CUR);
		iread(&AlphaInfo, sizeof(AlphaInfo), 1);
		if (iread(&AlphaChunk, sizeof(AlphaChunk), 1) != 1)
			return IL_FALSE;
	}


	/*Alpha = (ILubyte*)ialloc(AlphaInfo.AlphaRect.x2 * AlphaInfo.AlphaRect.y2);
	if (Alpha == NULL) {
		return IL_FALSE;
	}*/


	Alpha = GetChannel();
	if (Alpha == NULL)
		return IL_FALSE;

	return IL_TRUE;
}
Beispiel #19
0
ILboolean ReadRGB(PSDHEAD *Head)
{
	ILuint		ColorMode, ResourceSize, MiscInfo;
	ILushort	Compressed;
	ILenum		Format, Type;
	ILubyte		*Resources = NULL;

	ColorMode = GetBigUInt();  // Skip over the 'color mode data section'
	iseek(ColorMode, IL_SEEK_CUR);

	ResourceSize = GetBigUInt();  // Read the 'image resources section'
	Resources = (ILubyte*)ialloc(ResourceSize);
	if (Resources == NULL)
		return IL_FALSE;
	if (iread(Resources, 1, ResourceSize) != ResourceSize)
		goto cleanup_error;

	MiscInfo = GetBigUInt();
	iseek(MiscInfo, IL_SEEK_CUR);

	Compressed = GetBigUShort();

	ChannelNum = Head->Channels;
	if (Head->Channels == 3)
 	{
		Format = IL_RGB;
	}
	else if (Head->Channels == 4)
	{
		Format = IL_RGBA;
	}
	else if (Head->Channels >= 5)
	{
		// Additional channels are accumulated as a single alpha channel, since
		// if an image does not have a layer set as the "background", but also
		// has a real alpha channel, there will be 5 channels (or more).
		Format = IL_RGBA;
	}
	else
	{
		ilSetError(IL_FORMAT_NOT_SUPPORTED);
		return IL_FALSE;
	}

	switch (Head->Depth)
	{
		case 8:
			Type = IL_UNSIGNED_BYTE;
			break;
		case 16:
			Type = IL_UNSIGNED_SHORT;
			break;
		default:
			ilSetError(IL_FORMAT_NOT_SUPPORTED);
			return IL_FALSE;
	}
	if (!ilTexImage(Head->Width, Head->Height, 1, (Format==IL_RGB) ? 3 : 4, Format, Type, NULL))
		goto cleanup_error;
	if (!PsdGetData(Head, iCurImage->Data, (ILboolean)Compressed))
		goto cleanup_error;
	if (!ParseResources(ResourceSize, Resources))
		goto cleanup_error;
	ifree(Resources);

	return IL_TRUE;

cleanup_error:
	ifree(Resources);
	return IL_FALSE;
}
Beispiel #20
0
// Internal function used to load the UTX.
ILboolean iLoadUtxInternal(void)
{
	UTXHEADER		Header;
	UTXENTRYNAME	*NameEntries;
	UTXEXPORTTABLE	*ExportTable;
	UTXIMPORTTABLE	*ImportTable;
	UTXPALETTE		*Palettes;
	ILimage			*Image;
	ILuint			NumPal = 0, i, j = 0;
ILint Name;
ILubyte Type;
ILint	Val;
ILint	Size;
ILint	Width, Height, PalEntry;
ILboolean	BaseCreated = IL_FALSE, HasPal;
ILuint	Pos;
ILint	Format;
ILubyte	*CompData = NULL;
ILubyte ExtraData[9];

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

	if (!GetUtxHead(&Header))
		return IL_FALSE;
	if (!CheckUtxHead(&Header))
		return IL_FALSE;

	// Now we grab the name table.
	NameEntries = GetUtxNameTable(&Header);
	if (NameEntries == NULL)
		return IL_FALSE;
	// Then we get the export table.
	ExportTable = GetUtxExportTable(&Header);
	if (ExportTable == NULL) {
		UtxDestroyNameEntries(NameEntries, &Header);
		return IL_FALSE;
	}
	// Then the last table is the import table.
	ImportTable = GetUtxImportTable(&Header);
	if (ImportTable == NULL) {
		UtxDestroyNameEntries(NameEntries, &Header);
		UtxDestroyExportTable(ExportTable, &Header);
		return IL_FALSE;
	}

	for (i = 0; i < Header.ExportCount; i++) {
		if (!strcmp(NameEntries[ImportTable[ExportTable[i].Class].ObjectName].Name, "Palette"))
			NumPal++;
	}
	if (NumPal == 0)  //@TODO: Take care of UTX files without paletted data.
		return IL_FALSE;
	Palettes = (UTXPALETTE*)ialloc(NumPal * sizeof(UTXPALETTE));
	if (Palettes == NULL) {
		UtxDestroyNameEntries(NameEntries, &Header);
		UtxDestroyExportTable(ExportTable, &Header);
		UtxDestroyImportTable(ImportTable, &Header);
		return IL_FALSE;
	}
	NumPal = 0;
	for (i = 0; i < Header.ExportCount; i++) {
		if (!strcmp(NameEntries[ImportTable[ExportTable[i].Class].ObjectName].Name, "Palette")) {
			//Palettes[i].Name = strdup(NameEntries[ExportTable[i].ObjectName].Name);
			Palettes[NumPal].Name = i;//ExportTable[i].ObjectName;
			iseek(ExportTable[NumPal].SerialOffset, IL_SEEK_SET);
Name = igetc();  // Skip the 2.
			Palettes[NumPal].Count = UtxReadCompactInteger();
			Palettes[NumPal].Pal = (ILubyte*)ialloc(Palettes[NumPal].Count * 4);
			if (/*Palettes[NumPal].Name == NULL || */Palettes[NumPal].Pal == NULL) {
				UtxDestroyNameEntries(NameEntries, &Header);
				UtxDestroyExportTable(ExportTable, &Header);
				UtxDestroyImportTable(ImportTable, &Header);
				UtxDestroyPalettes(Palettes, NumPal);
				return IL_FALSE;
			}
			if (iread(Palettes[NumPal].Pal, Palettes[NumPal].Count * 4, 1) != 1)
				//@TODO: Deallocations here!
				return IL_FALSE;
			NumPal++;
		}
	}

	for (i = 0; i < Header.ExportCount; i++) {
		if (!strcmp(NameEntries[ImportTable[ExportTable[i].Class].ObjectName].Name, "Texture")) {
			iseek(ExportTable[i].SerialOffset, IL_SEEK_SET);
			Width = -1;  Height = -1;  PalEntry = NumPal;  HasPal = IL_FALSE;  Format = -1;
++j;
j = j;

			do {
Pos = itell();
				Name = UtxReadCompactInteger();
				if (!strcmp(NameEntries[Name].Name, "None"))
					break;
				Type = igetc();
				Size = (Type & 0x70) >> 4;

				if (/*Name == 0 && */Type == 0xA2)
					igetc();  // Byte is 1 here...

				switch (Type & 0x0F)
				{
					case 1:
						Val = igetc();
						break;

					case 2:
						Val = GetLittleUInt();
						break;

					case 3:  // Boolean value is in the info byte.
						igetc();
						break;

					case 4:
						GetLittleFloat();
						break;

					case 5:
					case 6:
						Val = itell();
						Val = UtxReadCompactInteger();
						break;

					case 10:
						Val = igetc();
						switch (Size)
						{
							case 0:
								iseek(1, IL_SEEK_CUR);
								break;
							case 1:
								iseek(2, IL_SEEK_CUR);
								break;
							case 2:
								iseek(4, IL_SEEK_CUR);
								break;
							case 3:
								iseek(12, IL_SEEK_CUR);
								break;
						}
						break;

					default:  // Uhm...
						Val = Val;
						break;
				}

				//@TODO: What should we do if Name >= Header.NameCount?
				if ((ILuint)Name < Header.NameCount) {
					if (!strcmp(NameEntries[Name].Name, "Palette")) {
						Val--;
						if (HasPal == IL_FALSE) {
							for (PalEntry = 0; (ILuint)PalEntry < NumPal; PalEntry++) {
								if (Val == Palettes[PalEntry].Name) {
									HasPal = IL_TRUE;
									break;
								}
							}
						}
					}
					if (!strcmp(NameEntries[Name].Name, "Format"))
						if (Format == -1)
							Format = Val;
					if (!strcmp(NameEntries[Name].Name, "USize"))
						if (Width == -1)
							Width = Val;
					if (!strcmp(NameEntries[Name].Name, "VSize"))
						if (Height == -1)
							Height = Val;
				}

			} while (!ieof());

			if (Format == -1)
				Format = UTX_P8;
			if (Width == -1 || Height == -1 || (PalEntry == NumPal && Format != UTX_DXT1) || (Format != UTX_P8 && Format != UTX_DXT1))
				return IL_FALSE;
			if (BaseCreated == IL_FALSE) {
				BaseCreated = IL_TRUE;
				ilTexImage(Width, Height, 1, UtxFormatToBpp(Format), UtxFormatToDevIL(Format), IL_UNSIGNED_BYTE, NULL);
				Image = iCurImage;
			}
			else {
				Image->Next = ilNewImageFull(Width, Height, 1, UtxFormatToBpp(Format), UtxFormatToDevIL(Format), IL_UNSIGNED_BYTE, NULL);
				if (Image->Next == NULL)
					return IL_FALSE;
				Image = Image->Next;
			}

			iseek(5, IL_SEEK_CUR);
			UtxReadCompactInteger();

			switch (Format)
			{
				case UTX_P8:
					Image->Pal.PalSize = Palettes[PalEntry].Count * 4;
					Image->Pal.Palette = (ILubyte*)ialloc(Image->Pal.PalSize);
					if (Image->Pal.Palette == NULL)
						//@TODO: Do all the deallocations needed here!
						return IL_FALSE;
					memcpy(Image->Pal.Palette, Palettes[PalEntry].Pal, Image->Pal.PalSize);
					Image->Pal.PalType = IL_PAL_RGBA32;

					if (iread(Image->Data, Image->SizeOfData, 1) != 1)
						return IL_FALSE;  //@TODO: Deallocations...
					break;

				case UTX_DXT1:
//
//
// HACK!!!
//
//
//igetc();
//ExtraData[0] = igetc();
//if (ExtraData[0] == 0x0C)
	//iseek(8, IL_SEEK_CUR);
//	iread(ExtraData+1, 8, 1);
//else
	//iseek(7, IL_SEEK_CUR);
//	iread(ExtraData+1, 7, 1);
//if (igetc() == 0x80)
//	igetc();
					Image->DxtcSize = IL_MAX(Image->Width * Image->Height / 2, 8);
					CompData = (ILubyte*)ialloc(Image->DxtcSize);
					if (CompData == NULL)
						//@TODO: Do all the deallocations needed here!
						return IL_FALSE;

					if (iread(CompData, Image->DxtcSize, 1) != 1) {
						ifree(CompData);
						return IL_FALSE;  //@TODO: Deallocations...
					}
					// Keep a copy of the DXTC data if the user wants it.
					if (ilGetInteger(IL_KEEP_DXTC_DATA) == IL_TRUE) {
						Image->DxtcData = CompData;
						Image->DxtcFormat = IL_DXT1;
						CompData = NULL;
					}
					if (DecompressDXT1(Image, CompData) == IL_FALSE) {
						ifree(CompData);
						return IL_FALSE;
					}
					ifree(CompData);
					break;
			}
			Image->Origin = IL_ORIGIN_UPPER_LEFT;
		}
	}
Beispiel #21
0
ILboolean ReadCMYK(PSDHEAD *Head)
{
	ILuint		ColorMode, ResourceSize, MiscInfo, Size, i, j;
	ILushort	Compressed;
	ILenum		Format, Type;
	ILubyte		*Resources = NULL, *KChannel = NULL;

	ColorMode = GetBigUInt();  // Skip over the 'color mode data section'
	iseek(ColorMode, IL_SEEK_CUR);

	ResourceSize = GetBigUInt();  // Read the 'image resources section'
	Resources = (ILubyte*)ialloc(ResourceSize);
	if (Resources == NULL) {
		return IL_FALSE;
	}
	if (iread(Resources, 1, ResourceSize) != ResourceSize)
		goto cleanup_error;

	MiscInfo = GetBigUInt();
	iseek(MiscInfo, IL_SEEK_CUR);

	Compressed = GetBigUShort();

	switch (Head->Channels)
	{
		case 4:
			Format = IL_RGB;
			ChannelNum = 4;
			Head->Channels = 3;
			break;
		case 5:
			Format = IL_RGBA;
			ChannelNum = 5;
			Head->Channels = 4;
			break;
		default:
			ilSetError(IL_FORMAT_NOT_SUPPORTED);
			return IL_FALSE;
	}
	switch (Head->Depth)
	{
		case 8:
			Type = IL_UNSIGNED_BYTE;
			break;
		case 16:
			Type = IL_UNSIGNED_SHORT;
			break;
		default:
			ilSetError(IL_FORMAT_NOT_SUPPORTED);
			return IL_FALSE;
	}
	if (!ilTexImage(Head->Width, Head->Height, 1, (ILubyte)Head->Channels, Format, Type, NULL))
		goto cleanup_error;
	if (!PsdGetData(Head, iCurImage->Data, (ILboolean)Compressed))
		goto cleanup_error;

	Size = iCurImage->Bpc * iCurImage->Width * iCurImage->Height;
	KChannel = (ILubyte*)ialloc(Size);
	if (KChannel == NULL)
		goto cleanup_error;
	if (!GetSingleChannel(Head, KChannel, (ILboolean)Compressed))
		goto cleanup_error;

	if (Format == IL_RGB) {
		for (i = 0, j = 0; i < iCurImage->SizeOfData; i += 3, j++) {
			iCurImage->Data[i  ] = (iCurImage->Data[i  ] * KChannel[j]) >> 8;
			iCurImage->Data[i+1] = (iCurImage->Data[i+1] * KChannel[j]) >> 8;
			iCurImage->Data[i+2] = (iCurImage->Data[i+2] * KChannel[j]) >> 8;
		}
	}
	else {  // IL_RGBA
		// The KChannel array really holds the alpha channel on this one.
		for (i = 0, j = 0; i < iCurImage->SizeOfData; i += 4, j++) {
Beispiel #22
0
ILimage *iUncompressDcx(DCXHEAD *Header)
{
	ILubyte		ByteHead, Colour, *ScanLine = NULL /* Only one plane */;
	ILuint		c, i, x, y;//, Read = 0;
	ILimage		*Image = NULL;

	if (Header->Bpp < 8) {
		/*ilSetError(IL_FORMAT_NOT_SUPPORTED);
		return IL_FALSE;*/
		return iUncompressDcxSmall(Header);
	}

	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, Header->NumPlanes, 0, IL_UNSIGNED_BYTE, NULL)) {
		return IL_FALSE;
	}*/
	Image->Origin = IL_ORIGIN_UPPER_LEFT;

	ScanLine = (ILubyte*)ialloc(Header->Bps);
	if (ScanLine == NULL)
		goto dcx_error;

	switch (Image->Bpp)
	{
		case 1:
			Image->Format = IL_COLOUR_INDEX;
			Image->Pal.PalType = IL_PAL_RGB24;
			Image->Pal.PalSize = 256 * 3; // Need to find out for sure...
			Image->Pal.Palette = (ILubyte*)ialloc(Image->Pal.PalSize);
			if (Image->Pal.Palette == NULL)
				goto dcx_error;
			break;
		//case 2:  // No 16-bit images in the dcx format!
		case 3:
			Image->Format = IL_RGB;
			Image->Pal.Palette = NULL;
			Image->Pal.PalSize = 0;
			Image->Pal.PalType = IL_PAL_NONE;
			break;
		case 4:
			Image->Format = IL_RGBA;
			Image->Pal.Palette = NULL;
			Image->Pal.PalSize = 0;
			Image->Pal.PalType = IL_PAL_NONE;
			break;

		default:
			ilSetError(IL_ILLEGAL_FILE_VALUE);
			goto dcx_error;
	}


		/*StartPos = itell();
		Compressed = (ILubyte*)ialloc(Image->SizeOfData * 4 / 3);
		iread(Compressed, 1, Image->SizeOfData * 4 / 3);

		for (y = 0; y < Image->Height; y++) {
			for (c = 0; c < Image->Bpp; c++) {
				x = 0;
				while (x < Header->Bps) {
					ByteHead = Compressed[Read++];
					if ((ByteHead & 0xC0) == 0xC0) {
						ByteHead &= 0x3F;
						Colour = Compressed[Read++];
						for (i = 0; i < ByteHead; i++) {
							ScanLine[x++] = Colour;
						}
					}
					else {
						ScanLine[x++] = ByteHead;
					}
				}

				for (x = 0; x < Image->Width; x++) {  // 'Cleverly' ignores the pad bytes ;)
					Image->Data[y * Image->Bps + x * Image->Bpp + c] = ScanLine[x];
				}
			}
		}

		ifree(Compressed);
		iseek(StartPos + Read, IL_SEEK_SET);*/

	//changed 2003-09-01
	if (iGetHint(IL_MEM_SPEED_HINT) == IL_FASTEST)
		iPreCache(iCurImage->SizeOfData);

	//TODO: because the .pcx-code was broken this
	//code is probably broken, too
	for (y = 0; y < Image->Height; y++) {
		for (c = 0; c < Image->Bpp; c++) {
			x = 0;
			while (x < Header->Bps) {
				if (iread(&ByteHead, 1, 1) != 1) {
					iUnCache();
					goto dcx_error;
				}
				if ((ByteHead & 0xC0) == 0xC0) {
					ByteHead &= 0x3F;
					if (iread(&Colour, 1, 1) != 1) {
						iUnCache();
						goto dcx_error;
					}
					for (i = 0; i < ByteHead; i++) {
						ScanLine[x++] = Colour;
					}
				}
				else {
					ScanLine[x++] = ByteHead;
				}
			}

			for (x = 0; x < Image->Width; x++) {  // 'Cleverly' ignores the pad bytes ;)
				Image->Data[y * Image->Bps + x * Image->Bpp + c] = ScanLine[x];
			}
		}
	}

	iUnCache();


	ifree(ScanLine);

	// Read in the palette
	if (Image->Bpp == 1) {
		ByteHead = igetc();	// the value 12, because it signals there's a palette for some reason...
							//	We should do a check to make certain it's 12...
		if (ByteHead != 12)
			iseek(-1, IL_SEEK_CUR);
		if (iread(Image->Pal.Palette, 1, Image->Pal.PalSize) != Image->Pal.PalSize) {
			ilCloseImage(Image);
			return NULL;
		}
	}

	return Image;

dcx_error:
	ifree(ScanLine);
	ilCloseImage(Image);
	return NULL;
}
Beispiel #23
0
// Note:  .Ktx support has not been tested yet!
//  https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/
ILboolean iLoadKtxInternal()
{
	KTX_HEAD	Header;
	ILuint		imageSize;
	ILenum		Format;
	ILubyte		Bpp;
	ILubyte		FileIdentifier[12] = {
		//0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A
		'«', 'K', 'T', 'X', ' ', '1', '1', '»', '\r', '\n', '\x1A', '\n'
	};

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

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

	if (iread(Header.identifier, 1, 12) != 12)
		return IL_FALSE;
	Header.endianness = GetLittleUInt();
	Header.glType = GetLittleUInt();
	Header.glTypeSize = GetLittleUInt();
	Header.glFormat = GetLittleUInt();
	Header.glInternalFormat = GetLittleUInt();
	Header.glBaseInternalFormat = GetLittleUInt();
	Header.pixelWidth = GetLittleUInt();
	Header.pixelHeight = GetLittleUInt();
	Header.pixelDepth = GetLittleUInt();
	Header.numberOfArrayElements = GetLittleUInt();
	Header.numberOfFaces = GetLittleUInt();
	Header.numberOfMipmapLevels = GetLittleUInt();
	Header.bytesOfKeyValueData = GetLittleUInt();


	if (memcmp(Header.identifier, FileIdentifier, 12) || Header.endianness != 0x04030201) {
		ilSetError(IL_ILLEGAL_FILE_VALUE);
		return IL_FALSE;
	}
	//@TODO: Additional types
	if (Header.glType != I_GL_UNSIGNED_BYTE || Header.glTypeSize != 1) {
		ilSetError(IL_ILLEGAL_FILE_VALUE);
		return IL_FALSE;
	}
	//@TODO: Additional formats
	if (Header.glFormat <= I_GL_ALPHA || Header.glFormat >= I_GL_LUMINANCE_ALPHA || Header.glInternalFormat != Header.glFormat /*|| Header.glBaseInternalFormat != Header.glFormat*/) {
		ilSetError(IL_ILLEGAL_FILE_VALUE);
		return IL_FALSE;
	}

	//@TODO: Mipmaps, etc.
	if (Header.numberOfArrayElements != 0 || Header.numberOfFaces != 1 || Header.numberOfMipmapLevels != 1) {
		ilSetError(IL_ILLEGAL_FILE_VALUE);
		return IL_FALSE;
	}
	//@TODO: Parse this data
	if (iseek(Header.bytesOfKeyValueData, IL_SEEK_CUR))
		return IL_FALSE;

	switch (Header.glFormat)
	{
		case I_GL_LUMINANCE:
			Bpp = 1;
			Format = IL_LUMINANCE;
			break;
		case IL_LUMINANCE_ALPHA:
			Bpp = 2;
			Format = IL_LUMINANCE_ALPHA;
			break;
		case I_GL_RGB:
			Bpp = 3;
			Format = IL_RGB;
			break;
		case I_GL_RGBA:
			Bpp = 4;
			Format = IL_RGBA;
			break;
		default:
			ilSetError(IL_ILLEGAL_FILE_VALUE);
			return IL_FALSE;
	}

	//@TODO: More than just RGBA
	if (!ilTexImage(Header.pixelWidth, Header.pixelHeight, 1, Bpp, Format, IL_UNSIGNED_BYTE, NULL)) {
		return IL_FALSE;
	}
	iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;

	imageSize = GetLittleUInt();
	if (imageSize != Header.pixelWidth * Header.pixelHeight * Bpp) {
		ilSetError(IL_ILLEGAL_FILE_VALUE);
		return IL_FALSE;
	}

	if (iread(iCurImage->Data, Bpp, Header.pixelWidth * Header.pixelHeight) != Header.pixelWidth * Header.pixelHeight)
		return IL_FALSE;

	return ilFixImage();
}
Beispiel #24
0
// 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;
}
//! Loads a .col palette file
ILboolean ilLoadColPal(ILconst_string FileName)
{
	ILuint		RealFileSize, FileSize;
	ILushort	Version;
	ILHANDLE	ColFile;

	if (!iCheckExtension(FileName, IL_TEXT("col"))) {
		ilSetError(IL_INVALID_EXTENSION);
		return IL_FALSE;
	}

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

	ColFile = iopenr(FileName);
	if (ColFile == NULL) {
		ilSetError(IL_COULD_NOT_OPEN_FILE);
		return IL_FALSE;
	}

	if (iCurImage->Pal.Palette && iCurImage->Pal.PalSize > 0 && iCurImage->Pal.PalType != IL_PAL_NONE) {
		ifree(iCurImage->Pal.Palette);
		iCurImage->Pal.Palette = NULL;
	}

	iseek(0, IL_SEEK_END);
	RealFileSize = ftell((FILE*)ColFile);
	iseek(0, IL_SEEK_SET);

	if (RealFileSize > 768) {  // has a header
		fread(&FileSize, 4, 1, (FILE*)ColFile);
		if ((FileSize - 8) % 3 != 0) {  // check to make sure an even multiple of 3!
			icloser(ColFile);
			ilSetError(IL_ILLEGAL_FILE_VALUE);
			return IL_FALSE;
		}
		if (iread(&Version, 2, 1) != 1) {
			icloser(ColFile);
			return IL_FALSE;
		}
		if (Version != 0xB123) {
			icloser(ColFile);
			ilSetError(IL_ILLEGAL_FILE_VALUE);
			return IL_FALSE;
		}
		if (iread(&Version, 2, 1) != 1) {
			icloser(ColFile);
			return IL_FALSE;
		}
		if (Version != 0) {
			icloser(ColFile);
			ilSetError(IL_ILLEGAL_FILE_VALUE);
			return IL_FALSE;
		}
	}

	iCurImage->Pal.Palette = (ILubyte*)ialloc(768);
	if (iCurImage->Pal.Palette == NULL) {
		icloser(ColFile);
		return IL_FALSE;
	}

	if (iread(iCurImage->Pal.Palette, 1, 768) != 768) {
		icloser(ColFile);
		ifree(iCurImage->Pal.Palette);
		iCurImage->Pal.Palette = NULL;
		return IL_FALSE;
	}

	iCurImage->Pal.PalSize = 768;
	iCurImage->Pal.PalType = IL_PAL_RGB24;

	icloser(ColFile);

	return IL_TRUE;
}
Beispiel #26
0
ILboolean iLoadMdlInternal()
{
	ILuint		Id, Version, NumTex, TexOff, TexDataOff, Position, ImageNum;
	ILubyte		*TempPal;
	TEX_HEAD	TexHead;
	ILimage		*BaseImage=NULL;
	ILboolean	BaseCreated = IL_FALSE;

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

	Id = GetLittleUInt();
	Version = GetLittleUInt();

	// 0x54534449 == "IDST"
	if (Id != 0x54534449 || Version != 10) {
		ilSetError(IL_INVALID_FILE_HEADER);
		return IL_FALSE;
	}

	// Skips the actual model header.
	iseek(172, IL_SEEK_CUR);

	NumTex = GetLittleUInt();
	TexOff = GetLittleUInt();
	TexDataOff = GetLittleUInt();

	if (NumTex == 0 || TexOff == 0 || TexDataOff == 0) {
		ilSetError(IL_ILLEGAL_FILE_VALUE);
		return IL_FALSE;
	}

	iseek(TexOff, IL_SEEK_SET);

	for (ImageNum = 0; ImageNum < NumTex; ImageNum++) {
		if (iread(TexHead.Name, 1, 64) != 64)
			return IL_FALSE;
		TexHead.Flags = GetLittleUInt();
		TexHead.Width = GetLittleUInt();
		TexHead.Height = GetLittleUInt();
		TexHead.Offset = GetLittleUInt();
		Position = itell();

		if (TexHead.Offset == 0) {
			ilSetError(IL_ILLEGAL_FILE_VALUE);
			return IL_FALSE;
		}

		if (!BaseCreated) {
			ilTexImage(TexHead.Width, TexHead.Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL);
			iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
			BaseCreated = IL_TRUE;
			BaseImage = iCurImage;
			//iCurImage->NumNext = NumTex - 1;  // Don't count the first image.
		}
		else {
			//iCurImage->Next = ilNewImage(TexHead.Width, TexHead.Height, 1, 1, 1);
			iCurImage = iCurImage->Next;
			iCurImage->Format = IL_COLOUR_INDEX;
			iCurImage->Type = IL_UNSIGNED_BYTE;
		}

		TempPal	= (ILubyte*)ialloc(768);
		if (TempPal == NULL) {
			iCurImage = BaseImage;
			return IL_FALSE;
		}
		iCurImage->Pal.Palette = TempPal;
		iCurImage->Pal.PalSize = 768;
		iCurImage->Pal.PalType = IL_PAL_RGB24;

		iseek(TexHead.Offset, IL_SEEK_SET);
		if (iread(iCurImage->Data, TexHead.Width * TexHead.Height, 1) != 1)
			return IL_FALSE;
		if (iread(iCurImage->Pal.Palette, 1, 768) != 768)
			return IL_FALSE;

		if (ilGetBoolean(IL_CONV_PAL) == IL_TRUE) {
			ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE);
		}

		iseek(Position, IL_SEEK_SET);
	}

	iCurImage = BaseImage;

	return ilFixImage();
}