Ejemplo n.º 1
0
static ILboolean ReadIndexed(ILimage* image, PSDHEAD *Head) {
  ILuint    ColorMode, ResourceSize, MiscInfo, i, j, NumEnt;
  ILushort  Compressed;
  ILubyte * Palette = NULL;
  ILubyte * Resources = NULL;
  SIO *     io = &image->io; 
  ILushort  ChannelNum;

  ColorMode = GetBigUInt(io);  // Skip over the 'color mode data section'
  if (ColorMode % 3 != 0) {
    iSetError(IL_INVALID_FILE_HEADER);
    return IL_FALSE;
  }

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

  if (SIOread(io, Palette, 1, ColorMode) != ColorMode)
    goto cleanup_error;

  ResourceSize = GetBigUInt(io);  // Read the 'image resources section'
  Resources = (ILubyte*)ialloc(ResourceSize);
  if (Resources == NULL) {
    return IL_FALSE;
  }

  if (SIOread(io, Resources, 1, ResourceSize) != ResourceSize)
    goto cleanup_error;

  MiscInfo = GetBigUInt(io);
  if (SIOeof(io))
    goto cleanup_error;

  SIOseek(io, MiscInfo, IL_SEEK_CUR);

  Compressed = GetBigUShort(io);
  if (SIOeof(io))
    goto cleanup_error;

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

  ChannelNum = Head->Channels;

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

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

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

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

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

  return IL_TRUE;

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

  return IL_FALSE;
}
Ejemplo n.º 2
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();
}
Ejemplo n.º 3
0
ILboolean iLoadIffInternal(void)
{
	iff_chunk chunkInfo;
    
	// -- Header info.
	ILuint width, height;
	ILuint flags, compress;
	ILushort tiles;

	ILenum	format;
	ILubyte bpp;

	ILboolean tileImageDataFound;

	// -- Initialize the top of the chunk stack.
	chunkDepth = -1;

	// -- File should begin with a FOR4 chunk of type CIMG
	chunkInfo = iff_begin_read_chunk();
	if (chunkInfo.chunkType != IFF_TAG_CIMG) {
		ilSetError(IL_ILLEGAL_FILE_VALUE);
		return IL_FALSE;
	}


	/*
	* Read the image header
	* OK, we have a FOR4 of type CIMG, look for the following tags
	*		FVER	
	*		TBHD	bitmap header, definition of size, etc.
	*		AUTH
	*		DATE
	*/
	while (1) {

		chunkInfo = iff_begin_read_chunk();
		
		// -- Right now, the only info we need about the image is in TBHD
		// -- so search this level until we find it.
		if( chunkInfo.tag == IFF_TAG_TBHD ) {
			// -- Header chunk found
			width = GetBigUInt();
			height = GetBigUInt();
			GetBigShort(); // -- Don't support 
			GetBigShort(); // -- Don't support 
			flags = GetBigUInt();
			GetBigShort(); // -- Don't support
			tiles = GetBigUShort();
			compress	= GetBigUInt();
			
			iff_end_read_chunk();
		
			if( compress > 1 ) {
				ilSetError(IL_ILLEGAL_FILE_VALUE);
				return	IL_FALSE;
			}
   				break;
		} else
			iff_end_read_chunk();
	} /* END find TBHD while loop */

	if (!(flags & RGB_FLAG)) {
		ilSetError(IL_ILLEGAL_FILE_VALUE);
		return	IL_FALSE;
	}

	if (flags & ALPHA_FLAG) {
		format = IL_RGBA; bpp = 4;
	} else {
		format = IL_RGB; bpp = 3;
	}

	if (!ilTexImage(width, height, 1, bpp, format, IL_UNSIGNED_BYTE, NULL))
		return IL_FALSE;

	iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;

	tileImageDataFound = IL_FALSE;

	while (!tileImageDataFound) {
		ILuint tileImage;
		ILuint tileZ;
	
		chunkInfo = iff_begin_read_chunk();

		/*
		 * OK, we have a FOR4 of type TBMP, (embedded FOR4)
		 * look for the following tags
		 *		RGBA	color data,	RLE compressed tiles of 32 bbp data
		 *		ZBUF	z-buffer data, 32 bit float values
		 *		CLPZ	depth map specific, clipping planes, 2 float values
		 *		ESXY	depth map specific, eye x-y ratios, 2 float values
		 *		HIST	
		 *		VERS
		 *		FOR4 <size>	BLUR (twice embedded FOR4)
		 */
		if (chunkInfo.chunkType != IFF_TAG_TBMP) {
			iff_end_read_chunk();
			continue;
		}
		tileImageDataFound = IL_TRUE;
		tileImage = 0;	// Si no RGBA, tileImage = tiles...
		if (flags & ZBUFFER_FLAG)
			tileZ = 0;
		else
			tileZ = tiles;

		// Read tiles
		while ( (tileImage < tiles) || (tileZ < tiles)) {
			char	 *tileData;
			ILushort x1, x2, y1, y2, tile_width, tile_height;
			ILuint remainingDataSize;
			ILushort	tile_area;
			ILuint	tileCompressed;

			chunkInfo = iff_begin_read_chunk();
			if ((chunkInfo.tag != IFF_TAG_RGBA) && (chunkInfo.tag != IFF_TAG_ZBUF)) {
				ilSetError(IL_ILLEGAL_FILE_VALUE);
				return IL_FALSE;
			}
			x1 = GetBigUShort();	y1 = GetBigUShort();
			x2 = GetBigUShort();	y2 = GetBigUShort();

			remainingDataSize = chunkInfo.size - 4*sizeof(ILushort);
			tile_width = x2 - x1 + 1;
			tile_height = y2 - y1 + 1;
			tile_area = tile_width * tile_height;

			if ((ILint)remainingDataSize >= (tile_width * tile_height * bpp))
				tileCompressed = 0;
			else
				tileCompressed = 1;

			if (chunkInfo.tag == IFF_TAG_RGBA) {
				if (tileCompressed) {
					char	*data = iff_read_data(remainingDataSize);
					if (data) {
						tileData = iff_decompress_tile_rle(tile_width, tile_height,
															bpp, data, remainingDataSize);
						ifree(data);
					}
				} else {
					tileData = iffReadUncompressedTile(tile_width, tile_height, bpp);
				}

				if (tileData) {
					// Dump RGBA data to our data structure 
					ILushort	i;
					ILuint		base;
					base = bpp*(width * y1 + x1);
					for (i = 0; i < tile_height; i++) {
						memcpy(&iCurImage->Data[base + bpp*i*width],
								&tileData[bpp*i*tile_width],
								tile_width*bpp*sizeof(char));
					}
					ifree(tileData);
					tileData = NULL;
	    
					iff_end_read_chunk();
					tileImage++;
				} else
					return IL_FALSE;
			} else if (chunkInfo.tag == IFF_TAG_ZBUF) {
				tileZ++;
				iff_end_read_chunk();
			}

		}
	}
	//ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE);  // Why was this here?
	return ilFixImage();
}
Ejemplo n.º 4
0
ILboolean ReadCMYK(ILimage* image, PSDHEAD *Head)
{
	ILuint		ColorMode, ResourceSize, MiscInfo, Size, i, j;
	ILushort	Compressed;
	ILenum		Format, Type;
	ILubyte		*Resources = NULL, *KChannel = NULL;
	ILushort ChannelNum;

	ColorMode = GetBigUInt(&image->io);  // Skip over the 'color mode data section'
	image->io.seek(&image->io, ColorMode, IL_SEEK_CUR);

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

	MiscInfo = GetBigUInt(&image->io);
	image->io.seek(&image->io, MiscInfo, IL_SEEK_CUR);

	Compressed = GetBigUShort(&image->io);

	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:
			il2SetError(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:
			il2SetError(IL_FORMAT_NOT_SUPPORTED);
			return IL_FALSE;
	}
	if (!il2TexImage(image, Head->Width, Head->Height, 1, (ILubyte)Head->Channels, Format, Type, NULL))
		goto cleanup_error;
	if (!PsdGetData(image, Head, image->Data, (ILboolean)Compressed, ChannelNum))
		goto cleanup_error;

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

	if (Format == IL_RGB) {
		for (i = 0, j = 0; i < image->SizeOfData; i += 3, j++) {
			image->Data[i  ] = (image->Data[i  ] * KChannel[j]) >> 8;
			image->Data[i+1] = (image->Data[i+1] * KChannel[j]) >> 8;
			image->Data[i+2] = (image->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 < image->SizeOfData; i += 4, j++) {
Ejemplo n.º 5
0
ILboolean ReadRGB(ILimage* image, PSDHEAD *Head)
{
	ILuint		ColorMode, ResourceSize, MiscInfo;
	ILushort	Compressed;
	ILenum		Format, Type;
	ILubyte		*Resources = NULL;
	ILushort ChannelNum;

	ColorMode = GetBigUInt(&image->io);  // Skip over the 'color mode data section'
	image->io.seek(&image->io, ColorMode, IL_SEEK_CUR);

	ResourceSize = GetBigUInt(&image->io);  // Read the 'image resources section'
	Resources = (ILubyte*)ialloc(ResourceSize);
	if (Resources == NULL)
		return IL_FALSE;
	if (image->io.read(&image->io, Resources, 1, ResourceSize) != ResourceSize)
		goto cleanup_error;

	MiscInfo = GetBigUInt(&image->io);
	image->io.seek(&image->io, MiscInfo, IL_SEEK_CUR);

	Compressed = GetBigUShort(&image->io);

	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
	{
		il2SetError(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:
			il2SetError(IL_FORMAT_NOT_SUPPORTED);
			return IL_FALSE;
	}
	if (!il2TexImage(image, Head->Width, Head->Height, 1, (Format==IL_RGB) ? 3 : 4, Format, Type, NULL))
		goto cleanup_error;
	if (!PsdGetData(image, Head, image->Data, (ILboolean)Compressed, ChannelNum))
		goto cleanup_error;
	if (!ParseResources(image, ResourceSize, Resources))
		goto cleanup_error;
	ifree(Resources);

	return IL_TRUE;

cleanup_error:
	ifree(Resources);
	return IL_FALSE;
}
Ejemplo n.º 6
0
ILboolean ReadIndexed(ILimage* image, PSDHEAD *Head)
{
	ILuint		ColorMode, ResourceSize, MiscInfo, NumEnt;
	ILushort	Compressed;
	ILubyte		*Palette = NULL, *Resources = NULL;
	ILushort ChannelNum;

	ColorMode = GetBigUInt(&image->io);  // Skip over the 'color mode data section'
	if (ColorMode % 3 != 0) {
		il2SetError(IL_INVALID_FILE_HEADER);
		return IL_FALSE;
	}
	Palette = (ILubyte*)ialloc(ColorMode);
	if (Palette == NULL)
		return IL_FALSE;
	if (image->io.read(&image->io, Palette, 1, ColorMode) != ColorMode)
		goto cleanup_error;

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

	MiscInfo = GetBigUInt(&image->io);
	if (image->io.eof(&image->io))
		goto cleanup_error;
	image->io.seek(&image->io, MiscInfo, IL_SEEK_CUR);

	Compressed = GetBigUShort(&image->io);
	if (image->io.eof(&image->io))
		goto cleanup_error;

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

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

	if (!image->Pal.use(ColorMode/3, NULL, IL_PAL_RGB24)) {
		goto cleanup_error;
	}

	NumEnt = image->Pal.getNumCols();
	for (ILuint j = 0; j < NumEnt; j++) {
		image->Pal.setRGB(j, Palette[j], Palette[j+NumEnt], Palette[j+NumEnt*2]);
	}
	ifree(Palette);
	Palette = NULL;

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

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

	return IL_TRUE;

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

	return IL_FALSE;
}