Example #1
0
UTXEXPORTTABLE *GetUtxExportTable(UTXHEADER *Header)
{
	UTXEXPORTTABLE	*ExportTable;
	ILuint			i;

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

	// Allocate the name table.
	ExportTable = (UTXEXPORTTABLE*)ialloc(Header->ExportCount * sizeof(UTXEXPORTTABLE));
	if (ExportTable == NULL)
		return NULL;

	for (i = 0; i < Header->ExportCount; i++) {
		ExportTable[i].Class = UtxReadCompactInteger();
		ExportTable[i].Super = UtxReadCompactInteger();
		ExportTable[i].Group = GetLittleUInt();
		ExportTable[i].ObjectName = UtxReadCompactInteger();
		ExportTable[i].ObjectFlags = GetLittleUInt();
		ExportTable[i].SerialSize = UtxReadCompactInteger();
		ExportTable[i].SerialOffset = UtxReadCompactInteger();

		ChangeObjectReference(&ExportTable[i].Class, &ExportTable[i].ClassImported);
		ChangeObjectReference(&ExportTable[i].Super, &ExportTable[i].SuperImported);
		ChangeObjectReference(&ExportTable[i].Group, &ExportTable[i].GroupImported);
	}

	return ExportTable;
}
Example #2
0
static ILboolean ReadPalette(PSP_CTX *ctx) {
	ILuint ChunkSize, PalCount, Padding;

	if (ctx->Header.MajorVersion >= 4) {
		ChunkSize = GetLittleUInt(ctx->io);
		PalCount = GetLittleUInt(ctx->io);
		Padding = (ChunkSize - 4 - 4);
		if (Padding > 0)
			SIOseek(ctx->io, Padding, IL_SEEK_CUR);
	}
	else {
		PalCount = GetLittleUInt(ctx->io);
	}

	ctx->Pal.PalSize = PalCount * 4;
	ctx->Pal.PalType = IL_PAL_BGRA32;
	ctx->Pal.Palette = (ILubyte*)ialloc(ctx->Pal.PalSize);
	if (ctx->Pal.Palette == NULL)
		return IL_FALSE;

	if (SIOread(ctx->io, ctx->Pal.Palette, ctx->Pal.PalSize, 1) != 1) {
		ifree(ctx->Pal.Palette);
		return IL_FALSE;
	}

	return IL_TRUE;
}
Example #3
0
ILboolean ReadPalette(ILuint BlockLen)
{
	ILuint ChunkSize, PalCount, Padding;

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

	Pal.PalSize = PalCount * 4;
	Pal.PalType = IL_PAL_BGRA32;
	Pal.Palette = (ILubyte*)ialloc(Pal.PalSize);
	if (Pal.Palette == NULL)
		return IL_FALSE;

	if (iread(Pal.Palette, Pal.PalSize, 1) != 1) {
		ifree(Pal.Palette);
		return IL_FALSE;
	}

	return IL_TRUE;
}
Example #4
0
// Internal function used to get the Lif header from the current file.
ILboolean iGetLifHead(LIF_HEAD *Header)
{

    iread(Header->Id, 1, 8);

    Header->Version = GetLittleUInt();

    Header->Flags = GetLittleUInt();

    Header->Width = GetLittleUInt();

    Header->Height = GetLittleUInt();

    Header->PaletteCRC = GetLittleUInt();

    Header->ImageCRC = GetLittleUInt();

    Header->PalOffset = GetLittleUInt();

    Header->TeamEffect0 = GetLittleUInt();

    Header->TeamEffect1 = GetLittleUInt();


    return IL_TRUE;
}
Example #5
0
// Internal function to get the header and check it.
ILboolean iIsValidMdl(void)
{
	ILuint Id, Version;

	Id = GetLittleUInt();
	Version = GetLittleUInt();
	iseek(-8, IL_SEEK_CUR);  // Restore to previous position.

	// 0x54534449 == "IDST"
	if (Id != 0x54534449 || Version != 10)
		return IL_FALSE;
	return IL_TRUE;
}
Example #6
0
UTXENTRYNAME *GetUtxNameTable(UTXHEADER *Header)
{
	UTXENTRYNAME *NameEntries;
	ILuint	i, NumRead;

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

	// Allocate the name table.
	NameEntries = (UTXENTRYNAME*)ialloc(Header->NameCount * sizeof(UTXENTRYNAME));
	if (NameEntries == NULL)
		return NULL;

	// Read in the name table.
	for (NumRead = 0; NumRead < Header->NameCount; NumRead++) {
		NameEntries[NumRead].Name = GetUtxName(Header);
		if (NameEntries[NumRead].Name == NULL)
			break;
		NameEntries[NumRead].Flags = GetLittleUInt();
	}

	// Did not read all of the entries (most likely GetUtxName failed).
	if (NumRead < Header->NameCount) {
		// So we have to free all of the memory we allocated here.
		for (i = 0; i < NumRead; i++) {
			ifree(NameEntries[NumRead].Name);
		}
		ilSetError(IL_INVALID_FILE_HEADER);
		return NULL;
	}

	return NameEntries;
}
Example #7
0
static ILboolean ParseChunks(PSP_CTX *ctx)
{
	BLOCKHEAD	Block;
	ILuint		Pos;

	do {
		if (SIOread(ctx->io, &Block, 1, sizeof(Block)) != sizeof(Block)) {
			iPopError();  // Get rid of the erroneous IL_FILE_READ_ERROR.
			break;
		}

		if (ctx->Header.MajorVersion == 3) {
			Block.BlockLen = GetLittleUInt(ctx->io);
		}	else {
			UInt(&Block.BlockLen);
		}

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

		UShort(&Block.BlockID);
		UInt(&Block.BlockLen);

		Pos = SIOtell(ctx->io);

		switch (Block.BlockID)
		{
			case PSP_LAYER_START_BLOCK:
				if (!ReadLayerBlock(ctx))
					return IL_FALSE;
				break;

			case PSP_ALPHA_BANK_BLOCK:
				if (!ReadAlphaBlock(ctx))
					return IL_FALSE;
				break;

			case PSP_COLOR_BLOCK:
				if (!ReadPalette(ctx))
					return IL_FALSE;
				break;

			// Gets done in the next iseek, so this is now commented out.
			//default:
				//SIOseek(ctx->io, Block.BlockLen, IL_SEEK_CUR);
		}

		// Skip to next block just in case we didn't read the entire block.
		SIOseek(ctx->io, Pos + Block.BlockLen, IL_SEEK_SET);

		// @TODO: Do stuff here.

	} while (1);

	return IL_TRUE;
}
Example #8
0
// Internal function to load a raw image
ILboolean iLoadRawInternal()
{
	if (iCurImage == NULL) {
		ilSetError(IL_ILLEGAL_OPERATION);
		return IL_FALSE;
	}


	iCurImage->Width = GetLittleUInt(&iCurImage->io);

	iCurImage->Height = GetLittleUInt(&iCurImage->io);

	iCurImage->Depth = GetLittleUInt(&iCurImage->io);

	iCurImage->Bpp = (ILubyte)iCurImage->io.getc(iCurImage->io.handle);

	if (iCurImage->io.read(iCurImage->io.handle, &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 (iCurImage->io.read(iCurImage->io.handle, 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;

	return ilFixImage();
}
Example #9
0
// 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;
}
Example #10
0
ILboolean ParseChunks(PspLoadState* state, ILimage* image)
{
	BLOCKHEAD	Block;

	do {
		if (image->io.read(&image->io, &Block, 1, sizeof(Block)) != sizeof(Block)) {
			il2GetError();  // Get rid of the erroneous IL_FILE_READ_ERROR.
			return IL_TRUE;
		}
		if (state->Header.MajorVersion == 3)
			Block.BlockLen = GetLittleUInt(&image->io);
		else
			UInt(&Block.BlockLen);

		if (Block.HeadID[0] != 0x7E || Block.HeadID[1] != 0x42 ||
			Block.HeadID[2] != 0x4B || Block.HeadID[3] != 0x00) {
				return IL_TRUE;
		}
		UShort(&Block.BlockID);
		UInt(&Block.BlockLen);

		auto Pos = image->io.tell(&image->io);

		switch (Block.BlockID)
		{
			case PSP_LAYER_START_BLOCK:
				if (!ReadLayerBlock(state, Block.BlockLen, image))
					return IL_FALSE;
				break;

			case PSP_ALPHA_BANK_BLOCK:
				if (!ReadAlphaBlock(state, Block.BlockLen, image))
					return IL_FALSE;
				break;

			case PSP_COLOR_BLOCK:
				if (!ReadPalette(state, Block.BlockLen, image))
					return IL_FALSE;
				break;

			// Gets done in the next iseek, so this is now commented out.
			//default:
				//image->io.seek(&image->io, Block.BlockLen, IL_SEEK_CUR);
		}

		// Skip to next block just in case we didn't read the entire block.
		image->io.seek(&image->io, Pos + Block.BlockLen, IL_SEEK_SET);

		// @TODO: Do stuff here.

	} while (1);

	return IL_TRUE;
}
Example #11
0
ILboolean GetUtxHead(UTXHEADER *Header)
{
	Header->Signature = GetLittleUInt();
	Header->Version = GetLittleUShort();
	Header->LicenseMode = GetLittleUShort();
	Header->Flags = GetLittleUInt();
	Header->NameCount = GetLittleUInt();
	Header->NameOffset = GetLittleUInt();
	Header->ExportCount = GetLittleUInt();
	Header->ExportOffset = GetLittleUInt();
	Header->ImportCount = GetLittleUInt();
	Header->ImportOffset = GetLittleUInt();

	return IL_TRUE;
}
Example #12
0
// Internal function used to load the FTX.
ILboolean iLoadFtxInternal(ILimage* image)
{
	ILuint Width, Height, HasAlpha;
	SIO * io = &image->io;

	if (image == NULL) {
		il2SetError(IL_ILLEGAL_OPERATION);
		return IL_FALSE;
	}

	Width = GetLittleUInt(io);
	Height = GetLittleUInt(io);
	HasAlpha = GetLittleUInt(io);  // Kind of backwards from what I would think...

	//@TODO: Right now, it appears that all images are in RGBA format.  See if I can find specs otherwise
	//  or images that load incorrectly like this.
	//if (HasAlpha == 0) {  // RGBA format
		if (!il2TexImage(image, Width, Height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL))
			return IL_FALSE;
	//}
	//else if (HasAlpha == 1) {  // RGB format
	//	if (!ilTexImage(Width, Height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL))
	//		return IL_FALSE;
	//}
	//else {  // Unknown format
	//	il2SetError(IL_INVALID_FILE_HEADER);
	//	return IL_FALSE;
	//}

	// The origin will always be in the upper left.
	image->Origin = IL_ORIGIN_UPPER_LEFT;

	// All we have to do for this format is read the raw, uncompressed data.
	if (io->read(io, image->Data, 1, image->SizeOfData) != image->SizeOfData)
		return IL_FALSE;

	return il2FixImage(image);
}
Example #13
0
ILboolean ReadPalette(PspLoadState* state, ILuint BlockLen, ILimage* image)
{
	ILuint ChunkSize, PalCount, Padding;

	if (state->Header.MajorVersion >= 4) {
		ChunkSize = GetLittleUInt(&image->io);
		PalCount = GetLittleUInt(&image->io);
		Padding = (ChunkSize - 4 - 4);
		if (Padding > 0)
			image->io.seek(&image->io, Padding, IL_SEEK_CUR);
	}
	else {
		PalCount = GetLittleUInt(&image->io);
	}

	if (state->Pal.use(PalCount, NULL, IL_PAL_BGRA32))
		return IL_FALSE;

	if (!state->Pal.readFromFile(&image->io))
		return IL_FALSE;

	return IL_TRUE;
}
Example #14
0
static ILboolean ReadGenAttributes(PSP_CTX *ctx)
{
	BLOCKHEAD		AttHead;
	ILint				Padding;
	ILuint			ChunkLen;

	if (SIOread(ctx->io, &AttHead, sizeof(AttHead), 1) != 1)
		return IL_FALSE;

	UShort(&AttHead.BlockID);
	UInt(&AttHead.BlockLen);

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

	ChunkLen = GetLittleUInt(ctx->io);
	if (ctx->Header.MajorVersion != 3)
		ChunkLen -= 4;

	if (SIOread(ctx->io, &ctx->AttChunk, IL_MIN(sizeof(ctx->AttChunk), ChunkLen), 1) != 1)
		return IL_FALSE;

	// Can have new entries in newer versions of the spec (4.0).
	Padding = (ILint)(ChunkLen - sizeof(ctx->AttChunk));
	if (Padding > 0)
		SIOseek(ctx->io, Padding, IL_SEEK_CUR);

	// @TODO:  Anything but 24 not supported yet...
	if (ctx->AttChunk.BitDepth != 24 && ctx->AttChunk.BitDepth != 8) {
		iSetError(IL_INVALID_FILE_HEADER);
		return IL_FALSE;
	}

	// @TODO;  Add support for compression...
	if (ctx->AttChunk.Compression != PSP_COMP_NONE && ctx->AttChunk.Compression != PSP_COMP_RLE) {
		iSetError(IL_INVALID_FILE_HEADER);
		return IL_FALSE;
	}

	// @TODO: Check more things in the general attributes chunk here.

	return IL_TRUE;
}
//! Loads an .plt palette file.
ILboolean ilLoadPltPal(ILconst_string FileName)
{
	ILHANDLE	PltFile;

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

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

	PltFile = iopenr(FileName);
	if (PltFile == 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;
	}

	iCurImage->Pal.PalSize = GetLittleUInt();
	if (iCurImage->Pal.PalSize == 0) {
		ilSetError(IL_INVALID_FILE_HEADER);
		return IL_FALSE;
	}
	iCurImage->Pal.PalType = IL_PAL_RGB24;
	iCurImage->Pal.Palette = (ILubyte*)ialloc(iCurImage->Pal.PalSize);
	if (!iCurImage->Pal.Palette) {
		icloser(PltFile);
		return IL_FALSE;
	}

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

	icloser(PltFile);

	return IL_TRUE;
}
Example #16
0
ILboolean iGetBlp1Head(BLP1HEAD *Header)
{
    ILuint i;

    iread(Header->Sig, 1, 4);
    Header->Compression = GetLittleUInt();
    Header->Flags = GetLittleUInt();
    Header->Width = GetLittleUInt();
    Header->Height = GetLittleUInt();
    Header->PictureType = GetLittleUInt();
    Header->PictureSubType = GetLittleUInt();
    for (i = 0; i < 16; i++)
        Header->MipOffsets[i] = GetLittleUInt();
    for (i = 0; i < 16; i++)
        Header->MipLengths[i] = GetLittleUInt();

    return IL_TRUE;
}
Example #17
0
// Internal function used to get the .bmp header from the current file.
ILboolean iGetBmpHead(BMPHEAD * const Header)
{
	Header->bfType = GetLittleUShort();
	Header->bfSize = GetLittleInt();
	Header->bfReserved = GetLittleUInt();
	Header->bfDataOff = GetLittleInt();
	Header->biSize = GetLittleInt();
	Header->biWidth = GetLittleInt();
	Header->biHeight = GetLittleInt();
	Header->biPlanes = GetLittleShort();
	Header->biBitCount = GetLittleShort();
	Header->biCompression = GetLittleInt();
	Header->biSizeImage = GetLittleInt();
	Header->biXPelsPerMeter = GetLittleInt();
	Header->biYPelsPerMeter = GetLittleInt();
	Header->biClrUsed = GetLittleInt();
	Header->biClrImportant = GetLittleInt();
	return IL_TRUE;
}
Example #18
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;
}
Example #19
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();
}
Example #20
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();
}
Example #21
0
static ILubyte *GetChannel(PSP_CTX *ctx)
{
	BLOCKHEAD		Block;
	CHANNEL_CHUNK	Channel;
	ILubyte			*CompData, *Data;
	ILuint			ChunkSize, Padding;

	if (SIOread(ctx->io, &Block, 1, sizeof(Block)) != sizeof(Block))
		return NULL;

	if (ctx->Header.MajorVersion == 3) {
		Block.BlockLen = GetLittleUInt(ctx->io);
	}	else {
		UInt(&Block.BlockLen);
	}

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


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

		Padding = (ChunkSize - 4) - sizeof(Channel);
		if (Padding > 0)
			SIOseek(ctx->io, Padding, IL_SEEK_CUR);
	}
	else {
		if (SIOread(ctx->io, &Channel, sizeof(Channel), 1) != 1)
			return NULL;
	}


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

	if (SIOread(ctx->io, CompData, 1, Channel.CompLen) != Channel.CompLen) {
		ifree(CompData);
		ifree(Data);
		return NULL;
	}

	switch (ctx->AttChunk.Compression)
	{
		case PSP_COMP_NONE:
			ifree(Data);
			return CompData;

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

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

	ifree(CompData);

	return Data;
}
Example #22
0
static ILboolean ReadAlphaBlock(PSP_CTX *ctx) {
	BLOCKHEAD				Block;
	ALPHAINFO_CHUNK	AlphaInfo;
	ALPHA_CHUNK			AlphaChunk;
	ILushort				StringSize;
	ILuint					ChunkSize, Padding;

	if (ctx->Header.MajorVersion == 3) {
		/* ILuint NumAlpha = */ GetLittleUShort(ctx->io);
	}
	else {
		ChunkSize = GetLittleUInt(ctx->io);
		/* NumAlpha = */ GetLittleUShort(ctx->io);
		Padding = (ChunkSize - 4 - 2);
		if (Padding > 0)
			SIOseek(ctx->io, Padding, IL_SEEK_CUR);
	}

	// Alpha channel header
	if (SIOread(ctx->io, &Block, 1, sizeof(Block)) != sizeof(Block))
		return IL_FALSE;

	if (ctx->Header.MajorVersion == 3) {
		Block.BlockLen = GetLittleUInt(ctx->io);
	}	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 (ctx->Header.MajorVersion >= 4) {
		ChunkSize = GetLittleUInt(ctx->io);
		StringSize = GetLittleUShort(ctx->io);
		SIOseek(ctx->io, StringSize, IL_SEEK_CUR);
		if (SIOread(ctx->io, &AlphaInfo, sizeof(AlphaInfo), 1) != 1)
			return IL_FALSE;
		Padding = (ChunkSize - 4 - 2 - StringSize - sizeof(AlphaInfo));
		if (Padding > 0)
			SIOseek(ctx->io, Padding, IL_SEEK_CUR);

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


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


	ctx->Alpha = GetChannel(ctx);
	if (ctx->Alpha == NULL)
		return IL_FALSE;

	return IL_TRUE;
}
Example #23
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;
}
Example #24
0
// Internal function used to load the ROT.
ILboolean iLoadRotInternal(void)
{
	ILubyte		Form[4], FormName[4];
	ILuint		FormLen, Width, Height, Format, Channels, CompSize;
	ILuint		MipSize, MipLevel, MipWidth, MipHeight;
	ILenum		FormatIL;
	ILimage		*Image;
	ILboolean	BaseCreated = IL_FALSE;
	ILubyte		*CompData = NULL;

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

	// The first entry in the file must be 'FORM', 0x20 in a big endian integer and then 'HEAD'.
	iread(Form, 1, 4);
	FormLen = GetBigUInt();
	iread(FormName, 1, 4);
	if (strncmp(Form, "FORM", 4) || FormLen != 0x14 || strncmp(FormName, "HEAD", 4)) {
		ilSetError(IL_INVALID_FILE_HEADER);
		return IL_FALSE;
	}

	// Next follows the width, height and format in the header.
	Width = GetLittleUInt();
	Height = GetLittleUInt();
	Format = GetLittleUInt();

	//@TODO: More formats.
	switch (Format)
	{
		case ROT_RGBA32:  // 32-bit RGBA format
			Channels = 4;
			FormatIL = IL_RGBA;
			break;

		case ROT_DXT1:  // DXT1 (no alpha)
			Channels = 4;
			FormatIL = IL_RGBA;
			break;

		case ROT_DXT3:  // DXT3
		case ROT_DXT5:  // DXT5
			Channels = 4;
			FormatIL = IL_RGBA;
			// Allocates the maximum needed (the first width/height given in the file).
			CompSize = ((Width + 3) / 4) * ((Height + 3) / 4) * 16;
			CompData = ialloc(CompSize);
			if (CompData == NULL)
				return IL_FALSE;
			break;

		default:
			ilSetError(IL_INVALID_FILE_HEADER);
			return IL_FALSE;
	}

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

	//@TODO: Find out what this is.
	GetLittleUInt();  // Skip this for the moment.  This appears to be the number of channels.

	// Next comes 'FORM', a length and 'MIPS'.
	iread(Form, 1, 4);
	FormLen = GetBigUInt();
	iread(FormName, 1, 4);
	//@TODO: Not sure if the FormLen has to be anything specific here.
	if (strncmp(Form, "FORM", 4) || strncmp(FormName, "MIPS", 4)) {
		ilSetError(IL_INVALID_FILE_HEADER);
		return IL_FALSE;
	}

	//@TODO: Can these mipmap levels be in any order?  Some things may be easier if the answer is no.
	Image = iCurImage;
	do {
		// Then we have 'FORM' again.
		iread(Form, 1, 4);
		// This is the size of the mipmap data.
		MipSize = GetBigUInt();
		iread(FormName, 1, 4);
		if (strncmp(Form, "FORM", 4)) {
			if (!BaseCreated) {  // Our file is malformed.
				ilSetError(IL_INVALID_FILE_HEADER);
				return IL_FALSE;
			}
			// We have reached the end of the mipmap data.
			break;
		}
		if (strncmp(FormName, "MLVL", 4)) {
			ilSetError(IL_INVALID_FILE_HEADER);
			return IL_FALSE;
		}

		// Next is the mipmap attributes (level number, width, height and length)
		MipLevel = GetLittleUInt();
		MipWidth = GetLittleUInt();
		MipHeight = GetLittleUInt();
		MipSize = GetLittleUInt();  // This is the same as the previous size listed -20 (for attributes).

		// Lower level mipmaps cannot be larger than the main image.
		if (MipWidth > Width || MipHeight > Height || MipSize > CompSize) {
			ilSetError(IL_INVALID_FILE_HEADER);
			return IL_FALSE;
		}

		// Just create our images here.
		if (!BaseCreated) {
			if (!ilTexImage(MipWidth, MipHeight, 1, Channels, FormatIL, IL_UNSIGNED_BYTE, NULL))
				return IL_FALSE;
			BaseCreated = IL_TRUE;
		}
		else {
			Image->Mipmaps = ilNewImageFull(MipWidth, MipHeight, 1, Channels, FormatIL, IL_UNSIGNED_BYTE, NULL);
			Image = Image->Mipmaps;
		}

		switch (Format)
		{
			case ROT_RGBA32:  // 32-bit RGBA format
				if (iread(Image->Data, Image->SizeOfData, 1) != 1)
					return IL_FALSE;
				break;

			case ROT_DXT1:
				// Allocates the size of the compressed data.
				CompSize = ((MipWidth + 3) / 4) * ((MipHeight + 3) / 4) * 8;
				if (CompSize != MipSize) {
					ilSetError(IL_INVALID_FILE_HEADER);
					return IL_FALSE;
				}
				CompData = ialloc(CompSize);
				if (CompData == NULL)
					return IL_FALSE;

				// Read in the DXT1 data...
				if (iread(CompData, CompSize, 1) != 1)
					return IL_FALSE;
				// ...and decompress it.
				if (!DecompressDXT1(Image, CompData)) {
					ifree(CompData);
					return IL_FALSE;
				}
				if (ilGetInteger(IL_KEEP_DXTC_DATA) == IL_TRUE) {
					Image->DxtcSize = CompSize;
					Image->DxtcData = CompData;
					Image->DxtcFormat = IL_DXT1;
					CompData = NULL;
				}
				break;

			case ROT_DXT3:
				// Allocates the size of the compressed data.
				CompSize = ((MipWidth + 3) / 4) * ((MipHeight + 3) / 4) * 16;
				if (CompSize != MipSize) {
					ilSetError(IL_INVALID_FILE_HEADER);
					return IL_FALSE;
				}
				CompData = ialloc(CompSize);
				if (CompData == NULL)
					return IL_FALSE;

				// Read in the DXT3 data...
				if (iread(CompData, MipSize, 1) != 1)
					return IL_FALSE;
				// ...and decompress it.
				if (!DecompressDXT3(Image, CompData)) {
					ifree(CompData);
					return IL_FALSE;
				}
				if (ilGetInteger(IL_KEEP_DXTC_DATA) == IL_TRUE) {
					Image->DxtcSize = CompSize;
					Image->DxtcData = CompData;
					Image->DxtcFormat = IL_DXT3;
					CompData = NULL;
				}
				break;

			case ROT_DXT5:
				// Allocates the size of the compressed data.
				CompSize = ((MipWidth + 3) / 4) * ((MipHeight + 3) / 4) * 16;
				if (CompSize != MipSize) {
					ilSetError(IL_INVALID_FILE_HEADER);
					return IL_FALSE;
				}
				CompData = ialloc(CompSize);
				if (CompData == NULL)
					return IL_FALSE;

				// Read in the DXT5 data...
				if (iread(CompData, MipSize, 1) != 1)
					return IL_FALSE;
				// ...and decompress it.
				if (!DecompressDXT5(Image, CompData)) {
					ifree(CompData);
					return IL_FALSE;
				}
				// Keeps a copy
				if (ilGetInteger(IL_KEEP_DXTC_DATA) == IL_TRUE) {
					Image->DxtcSize = CompSize;
					Image->DxtcData = CompData;
					Image->DxtcFormat = IL_DXT5;
					CompData = NULL;
				}
				break;
		}
		ifree(CompData);  // Free it if it was not saved.
	} while (!ieof());  //@TODO: Is there any other condition that should end this?

	return ilFixImage();
}
Example #25
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;
		}
	}
Example #26
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();
}
Example #27
0
static ILboolean ReadLayerBlock(PSP_CTX *ctx) {
	BLOCKHEAD			Block;
	LAYERINFO_CHUNK		LayerInfo;
	LAYERBITMAP_CHUNK	Bitmap;
	ILuint				ChunkSize, Padding, i, j;
	ILushort			NumChars;

	// Layer sub-block header
	if (SIOread(ctx->io, &Block, 1, sizeof(Block)) != sizeof(Block))
		return IL_FALSE;

	if (ctx->Header.MajorVersion == 3) {
		Block.BlockLen = GetLittleUInt(ctx->io);
	}	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 (ctx->Header.MajorVersion == 3) {
		SIOseek(ctx->io, 256, IL_SEEK_CUR);  // We don't care about the name of the layer.
		SIOread(ctx->io, &LayerInfo, sizeof(LayerInfo), 1);
		if (SIOread(ctx->io, &Bitmap, sizeof(Bitmap), 1) != 1)
			return IL_FALSE;
	}
	else {  // ctx->Header.MajorVersion >= 4
		ChunkSize = GetLittleUInt(ctx->io);
		NumChars = GetLittleUShort(ctx->io);
		SIOseek(ctx->io, NumChars, IL_SEEK_CUR);  // We don't care about the layer's name.

		ChunkSize -= (2 + 4 + NumChars);

		if (SIOread(ctx->io, &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)
			SIOseek(ctx->io, Padding, IL_SEEK_CUR);

		ChunkSize = GetLittleUInt(ctx->io);
		if (SIOread(ctx->io, &Bitmap, sizeof(Bitmap), 1) != 1)
			return IL_FALSE;
		Padding = (ChunkSize - 4) - sizeof(Bitmap);
		if (Padding > 0)
			SIOseek(ctx->io, Padding, IL_SEEK_CUR);
	}


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

	ctx->NumChannels = Bitmap.NumChannels;

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

	return IL_TRUE;
}