Exemplo n.º 1
0
ILint iGetScanLine(ILubyte *ScanLine, iSgiHeader *Head, ILuint Length)
{
	ILushort Pixel, Count;  // For current pixel
	ILuint	 BppRead = 0, CurPos = 0, Bps = Head->XSize * Head->Bpc;

	while (BppRead < Length && CurPos < Bps)
	{
		Pixel = 0;
		if (iread(&Pixel, Head->Bpc, 1) != 1)
			return -1;
		
#ifndef __LITTLE_ENDIAN__
		iSwapUShort(&Pixel);
#endif

		if (!(Count = (Pixel & 0x7f)))  // If 0, line ends
			return CurPos;
		if (Pixel & 0x80) {  // If top bit set, then it is a "run"
			if (iread(ScanLine, Head->Bpc, Count) != Count)
				return -1;
			BppRead += Head->Bpc * Count + Head->Bpc;
			ScanLine += Head->Bpc * Count;
			CurPos += Head->Bpc * Count;
		}
		else {
			if (iread(&Pixel, Head->Bpc, 1) != 1)
				return -1;
#ifndef __LITTLE_ENDIAN__
			iSwapUShort(&Pixel);
#endif
			if (Head->Bpc == 1) {
				while (Count--) {
					*ScanLine = (ILubyte)Pixel;
					ScanLine++;
					CurPos++;
				}
			}
			else {
				while (Count--) {
					*(ILushort*)ScanLine = Pixel;
					ScanLine += 2;
					CurPos += 2;
				}
			}
			BppRead += Head->Bpc + Head->Bpc;
		}
	}

	return CurPos;
}
Exemplo n.º 2
0
// Internal function used to load the Gif.
ILboolean iLoadGifInternal(ILimage* image)
{
	GIFHEAD	Header;
	ILpal	GlobalPal;

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

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

	// Read header
	iCurImage->io.read(iCurImage->io.handle, &Header, 1, sizeof(Header));
	#ifdef __BIG_ENDIAN__
	iSwapUShort(Header.Width);
	iSwapUShort(Header.Height);
	#endif

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

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

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

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

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

	return ilFixImage();
}
Exemplo n.º 3
0
// Internal function used to get the Psd header from the current file.
ILboolean iGetPsdHead(SIO* io, PSDHEAD *Header)
{
	io->read(io, Header, 1, sizeof(PSDHEAD));

#ifdef IL_LITTLE_ENDIAN
	iSwapUShort(&Header->Version);
	iSwapUShort(&Header->Channels);
	iSwapUInt(&Header->Height);
	iSwapUInt(&Header->Width);
	iSwapUShort(&Header->Depth);
	iSwapUShort(&Header->Mode);
#endif

	return IL_TRUE;
}
Exemplo n.º 4
0
ILuint *GetCompChanLen(ILimage* image, PSDHEAD *Head, ILushort& ChannelNum)
{
	ILushort	*RleTable;
	ILuint		*ChanLen, c, i, j;

	RleTable = (ILushort*)ialloc(Head->Height * ChannelNum * sizeof(ILushort));
	ChanLen = (ILuint*)ialloc(ChannelNum * sizeof(ILuint));
	if (RleTable == NULL || ChanLen == NULL) {
		return NULL;
	}

	if (image->io.read(&image->io, RleTable, sizeof(ILushort), Head->Height * ChannelNum) != Head->Height * ChannelNum) {
		ifree(RleTable);
		ifree(ChanLen);
		return NULL;
	}
#ifdef IL_LITTLE_ENDIAN
	for (i = 0; i < Head->Height * ChannelNum; i++) {
		iSwapUShort(&RleTable[i]);
	}
#endif

	imemclear(ChanLen, ChannelNum * sizeof(ILuint));
	for (c = 0; c < ChannelNum; c++) {
		j = c * Head->Height;
		for (i = 0; i < Head->Height; i++) {
			ChanLen[c] += RleTable[i + j];
		}
	}

	ifree(RleTable);

	return ChanLen;
}
Exemplo n.º 5
0
// Obtain .pcx header
ILuint iGetPcxHead(SIO* io, PCXHEAD *header)
{
	auto read = io->read(io->handle, header, 1, sizeof(PCXHEAD));

	#ifdef __BIG_ENDIAN__
	iSwapUShort(header->Xmin); // = GetLittleShort();
	iSwapUShort(header->Ymin); // = GetLittleShort();
	iSwapUShort(header->Xmax); // = GetLittleShort();
	iSwapUShort(header->Ymax); // = GetLittleShort();
	iSwapUShort(header->HDpi); // = GetLittleShort();
	iSwapUShort(header->VDpi); // = GetLittleShort();
	iSwapUShort(header->Bps); // = GetLittleShort();
	iSwapUShort(header->PaletteInfo); // = GetLittleShort();
	iSwapUShort(header->HScreenSize); // = GetLittleShort();
	iSwapUShort(header->VScreenSize); // = GetLittleShort();
	#endif

	return read;
}
Exemplo n.º 6
0
ILvoid EndianSwapData(void *_Image) {
	ILuint		i;
	ILubyte		*temp, *s, *d;
	ILushort	*ShortS, *ShortD;
	ILuint		*IntS, *IntD;
	ILfloat		*FltS, *FltD;
	ILdouble	*DblS, *DblD;

	ILimage *Image = (ILimage*)_Image;

	switch (Image->Type) {
		case IL_BYTE:
		case IL_UNSIGNED_BYTE:
			switch (Image->Bpp) {
				case 3:
					temp = (ILubyte*)ialloc(Image->SizeOfData);
					if (temp == NULL)
						return;
					s = Image->Data;
					d = temp;

					for( i = Image->Width * Image->Height; i > 0; i-- ) {
						*d++ = *(s+2);
						*d++ = *(s+1);
						*d++ = *s;
						s += 3;
					}

					ifree(Image->Data);
					Image->Data = temp;
					break;

				case 4:
					temp = (ILubyte*)ialloc(Image->SizeOfData);
					if (temp == NULL)
						return;
					s = Image->Data;
					d = temp;

					for (i = Image->Width * Image->Height; i > 0; i--) {
						*d++ = *(s+3);
						*d++ = *(s+2);
						*d++ = *(s+1);
						*d++ = *s;
						s += 4;
					}

					ifree(Image->Data);
					Image->Data = temp;
					break;
			}
			break;

		case IL_SHORT:
		case IL_UNSIGNED_SHORT:
			switch (Image->Bpp) {
				case 3:
					temp = (ILubyte*)ialloc(Image->SizeOfData);
					if (temp == NULL)
						return;
					ShortS = (ILushort*)Image->Data;
					ShortD = (ILushort*)temp;

					for (i = Image->Width * Image->Height; i > 0; i--) {
						*ShortD = *ShortS++; iSwapUShort(ShortD++);
						*ShortD = *ShortS++; iSwapUShort(ShortD++);
						*ShortD = *ShortS++; iSwapUShort(ShortD++);
					}

					ifree(Image->Data);
					Image->Data = temp;
					break;

				case 4:
					temp = (ILubyte*)ialloc(Image->SizeOfData);
					if (temp == NULL)
						return;
					ShortS = (ILushort*)Image->Data;
					ShortD = (ILushort*)temp;

					for (i = Image->Width * Image->Height; i > 0; i--) {
						*ShortD = *ShortS++; iSwapUShort(ShortD++);
						*ShortD = *ShortS++; iSwapUShort(ShortD++);
						*ShortD = *ShortS++; iSwapUShort(ShortD++);
						*ShortD = *ShortS++; iSwapUShort(ShortD++);
					}

					ifree(Image->Data);
					Image->Data = temp;
					break;
			}
			break;

		case IL_INT:
		case IL_UNSIGNED_INT:
			switch (Image->Bpp)
			{
				case 3:
					temp = (ILubyte*)ialloc(Image->SizeOfData);
					if (temp == NULL)
						return;
					IntS = (ILuint*)Image->Data;
					IntD = (ILuint*)temp;

					for (i = Image->Width * Image->Height; i > 0; i--) {
						*IntD = *IntS++; iSwapUInt(IntD++);
						*IntD = *IntS++; iSwapUInt(IntD++);
						*IntD = *IntS++; iSwapUInt(IntD++);
					}

					ifree(Image->Data);
					Image->Data = temp;
					break;

				case 4:
					temp = (ILubyte*)ialloc(Image->SizeOfData);
					if (temp == NULL)
						return;
					IntS = (ILuint*)Image->Data;
					IntD = (ILuint*)temp;

					for (i = Image->Width * Image->Height; i > 0; i--) {
						*IntD = *IntS++; iSwapUInt(IntD++);
						*IntD = *IntS++; iSwapUInt(IntD++);
						*IntD = *IntS++; iSwapUInt(IntD++);
						*IntD = *IntS++; iSwapUInt(IntD++);
					}

					ifree(Image->Data);
					Image->Data = temp;
					break;
			}
			break;

		case IL_FLOAT:
			switch (Image->Bpp)
			{
				case 3:
					temp = (ILubyte*)ialloc(Image->SizeOfData);
					if (temp == NULL)
						return;
					FltS = (ILfloat*)Image->Data;
					FltD = (ILfloat*)temp;

					for (i = Image->Width * Image->Height; i > 0; i--) {
						*FltD = *FltS++; iSwapFloat(FltD++);
						*FltD = *FltS++; iSwapFloat(FltD++);
						*FltD = *FltS++; iSwapFloat(FltD++);
					}

					ifree(Image->Data);
					Image->Data = temp;
					break;

				case 4:
					temp = (ILubyte*)ialloc(Image->SizeOfData);
					if (temp == NULL)
						return;
					FltS = (ILfloat*)Image->Data;
					FltD = (ILfloat*)temp;

					for (i = Image->Width * Image->Height; i > 0; i--) {
						*FltD = *FltS++; iSwapFloat(FltD++);
						*FltD = *FltS++; iSwapFloat(FltD++);
						*FltD = *FltS++; iSwapFloat(FltD++);
						*FltD = *FltS++; iSwapFloat(FltD++);
					}

					ifree(Image->Data);
					Image->Data = temp;
					break;
			}
			break;

		case IL_DOUBLE:
			switch (Image->Bpp)
			{
				case 3:
					temp = (ILubyte*)ialloc(Image->SizeOfData);
					if (temp == NULL)
						return;
					DblS = (ILdouble*)Image->Data;
					DblD = (ILdouble*)temp;

					for (i = Image->Width * Image->Height; i > 0; i--) {
						*DblD = *DblS++; iSwapDouble(DblD++);
						*DblD = *DblS++; iSwapDouble(DblD++);
						*DblD = *DblS++; iSwapDouble(DblD++);
					}

					ifree(Image->Data);
					Image->Data = temp;
					break;

				case 4:
					temp = (ILubyte*)ialloc(Image->SizeOfData);
					if (temp == NULL)
						return;
					DblS = (ILdouble*)Image->Data;
					DblD = (ILdouble*)temp;

					for (i = Image->Width * Image->Height; i > 0; i--) {
						*DblD = *DblS++; iSwapDouble(DblD++);
						*DblD = *DblS++; iSwapDouble(DblD++);
						*DblD = *DblS++; iSwapDouble(DblD++);
						*DblD = *DblS++; iSwapDouble(DblD++);
					}

					ifree(Image->Data);
					Image->Data = temp;
					break;
			}
			break;
	}

	if( iCurImage->Format == IL_COLOUR_INDEX ) {
		switch (iCurImage->Pal.PalType) {
			case IL_PAL_RGB24:
			case IL_PAL_BGR24:
				temp = (ILubyte*)ialloc(Image->Pal.PalSize);
				if (temp == NULL)
					return;
				s = Image->Pal.Palette;
				d = temp;

				for (i = Image->Pal.PalSize / 3; i > 0; i--) {
					*d++ = *(s+2);
					*d++ = *(s+1);
					*d++ = *s;
					s += 3;
				}

				ifree(Image->Pal.Palette);
				Image->Pal.Palette = temp;
				break;

			case IL_PAL_RGBA32:
			case IL_PAL_RGB32:
			case IL_PAL_BGRA32:
			case IL_PAL_BGR32:
				temp = (ILubyte*)ialloc(Image->Pal.PalSize);
				if (temp == NULL)
					return;
				s = Image->Pal.Palette;
				d = temp;

				for (i = Image->Pal.PalSize / 4; i > 0; i--) {
					*d++ = *(s+3);
					*d++ = *(s+2);
					*d++ = *(s+1);
					*d++ = *s;
					s += 4;
				}

				ifree(Image->Pal.Palette);
				Image->Pal.Palette = temp;
				break;
		}
	}
	return;
}
Exemplo n.º 7
0
ILboolean GetImages(ILimage* Image, ILpal *GlobalPal, GIFHEAD *GifHead)
{
	IMAGEDESC	ImageDesc, OldImageDesc;
	GFXCONTROL	Gfx;
	ILboolean	BaseImage = IL_TRUE;
	ILimage		*TempImage = NULL, *PrevImage = NULL;
	ILuint		NumImages = 0, i;
	ILint		input;

	OldImageDesc.ImageInfo = 0; // to initialize the data with an harmless value 
	Gfx.Used = IL_TRUE;

	while (!iCurImage->io.eof(iCurImage->io.handle)) {
		ILubyte DisposalMethod = 1;
		
		i = iCurImage->io.tell(iCurImage->io.handle);
		if (!SkipExtensions(&Gfx))
			goto error_clean;
		i = iCurImage->io.tell(iCurImage->io.handle);

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

		//read image descriptor
      iCurImage->io.read(iCurImage->io.handle, &ImageDesc, 1, sizeof(ImageDesc));
      #ifdef __BIG_ENDIAN__
      iSwapUShort(ImageDesc.OffX);
      iSwapUShort(ImageDesc.OffY);
      iSwapUShort(ImageDesc.Width);
      iSwapUShort(ImageDesc.Height);
      #endif
      
		if (ImageDesc.Separator != 0x2C) //end of image
			break;

      if (!setMinSizes(ImageDesc.OffX + ImageDesc.Width, ImageDesc.OffY + ImageDesc.Height, Image))
			goto error_clean;

		if (iCurImage->io.eof(iCurImage->io.handle)) {
			ilGetError();  // Gets rid of the IL_FILE_READ_ERROR that inevitably results.
			break;
		}


		if (!BaseImage) {
			NumImages++;
			Image->Next = ilNewImage(Image->Width, Image->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;
			}

			PrevImage = Image;
			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);
		}

		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, PrevImage)) {
				goto error_clean;
			}
		} else {
			if (!iCopyPalette(&Image->Pal, GlobalPal)) {
				goto error_clean;
			}
		}

		if (!GifGetData(Image, Image->Data, Image->SizeOfData, ImageDesc.OffX, ImageDesc.OffY,
				ImageDesc.Width, ImageDesc.Height, Image->Bps, &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 = iCurImage->io.tell(iCurImage->io.handle);
		// Terminates each block.
		if((input = iCurImage->io.getc(iCurImage->io.handle)) == IL_EOF)
			goto error_clean;

		if (input != 0x00)
		    iCurImage->io.seek(iCurImage->io.handle, -1, IL_SEEK_CUR);
		//	break;

		OldImageDesc = ImageDesc;
	}

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

	if (BaseImage)  // Was not able to load any images in...
		return IL_FALSE;

	return IL_TRUE;

error_clean:
	Image = Image->Next;
    /*	while (Image) {
		TempImage = Image;
		Image = Image->Next;
		ilCloseImage(TempImage);
	}*/
	return IL_FALSE;
}
Exemplo n.º 8
0
static Uint16 iSDL_SwapBE16( Uint16 s )
    { Uint16 foo = s; iSwapUShort(&foo); return foo; }
Exemplo n.º 9
0
ILboolean PsdGetData(ILimage* image, PSDHEAD *Head, void *Buffer, ILboolean Compressed, ILushort& ChannelNum)
{
	ILuint		c, x, y, i, Size, ReadResult, NumChan;
	ILubyte		*Channel = NULL;
	ILushort	*ShortPtr;
	ILuint		*ChanLen = NULL;

	// Added 01-07-2009: This is needed to correctly load greyscale and
	//  paletted images.
	switch (Head->Mode)
	{
		case 1:
		case 2:
			NumChan = 1;
			break;
		default:
			NumChan = 3;
	}

	Channel = (ILubyte*)ialloc(Head->Width * Head->Height * image->Bpc);
	if (Channel == NULL) {
		return IL_FALSE;
	}
	ShortPtr = (ILushort*)Channel;

	// @TODO: Add support for this in, though I have yet to run across a .psd
	//	file that uses this.
	if (Compressed && image->Type == IL_UNSIGNED_SHORT) {
		il2SetError(IL_FORMAT_NOT_SUPPORTED);
		return IL_FALSE;
	}

	if (!Compressed) {
		if (image->Bpc == 1) {
			for (c = 0; c < NumChan; c++) {
				i = 0;
				if (image->io.read(&image->io, Channel, Head->Width * Head->Height, 1) != 1) {
					ifree(Channel);
					return IL_FALSE;
				}
				for (y = 0; y < Head->Height * image->Bps; y += image->Bps) {
					for (x = 0; x < image->Bps; x += image->Bpp, i++) {
						image->Data[y + x + c] = Channel[i];
					}
				}
			}
			// Accumulate any remaining channels into a single alpha channel
			//@TODO: This needs to be changed for greyscale images.
			for (; c < Head->Channels; c++) {
				i = 0;
				if (image->io.read(&image->io, Channel, Head->Width * Head->Height, 1) != 1) {
					ifree(Channel);
					return IL_FALSE;
				}
				for (y = 0; y < Head->Height * image->Bps; y += image->Bps) {
					for (x = 0; x < image->Bps; x += image->Bpp, i++) {
						float curVal = ubyte_to_float(image->Data[y + x + 3]);
						float newVal = ubyte_to_float(Channel[i]);
						image->Data[y + x + 3] = float_to_ubyte(curVal * newVal);
					}
				}
			}
		}
		else {  // image->Bpc == 2
			for (c = 0; c < NumChan; c++) {
				i = 0;
				if (image->io.read(&image->io, Channel, Head->Width * Head->Height * 2, 1) != 1) {
					ifree(Channel);
					return IL_FALSE;
				}
				image->Bps /= 2;
				for (y = 0; y < Head->Height * image->Bps; y += image->Bps) {
					for (x = 0; x < image->Bps; x += image->Bpp, i++) {
					 #ifndef WORDS_BIGENDIAN
						iSwapUShort(ShortPtr+i);
					 #endif
						((ILushort*)image->Data)[y + x + c] = ShortPtr[i];
					}
				}
				image->Bps *= 2;
			}
			// Accumulate any remaining channels into a single alpha channel
			//@TODO: This needs to be changed for greyscale images.
			for (; c < Head->Channels; c++) {
				i = 0;
				if (image->io.read(&image->io, Channel, Head->Width * Head->Height * 2, 1) != 1) {
					ifree(Channel);
					return IL_FALSE;
				}
				image->Bps /= 2;
				for (y = 0; y < Head->Height * image->Bps; y += image->Bps) {
					for (x = 0; x < image->Bps; x += image->Bpp, i++) {
						float curVal = ushort_to_float(((ILushort*)image->Data)[y + x + 3]);
						float newVal = ushort_to_float(ShortPtr[i]);
						((ILushort*)image->Data)[y + x + 3] = float_to_ushort(curVal * newVal);
					}
				}
				image->Bps *= 2;
			}
		}
	}
	else {
		ChanLen = GetCompChanLen(image, Head, ChannelNum);

		Size = Head->Width * Head->Height;
		for (c = 0; c < NumChan; c++) {
			ReadResult = ReadCompressedChannel(image, ChanLen[c], Size, Channel);
			if (ReadResult == READ_COMPRESSED_ERROR_FILE_CORRUPT)
				goto file_corrupt;
			else if (ReadResult == READ_COMPRESSED_ERROR_FILE_READ_ERROR)
				goto file_read_error;

			i = 0;
			for (y = 0; y < Head->Height * image->Bps; y += image->Bps) {
				for (x = 0; x < image->Bps; x += image->Bpp, i++) {
					image->Data[y + x + c] = Channel[i];
				}
			}
		}

		// Initialize the alpha channel to solid
		//@TODO: This needs to be changed for greyscale images.
		if (Head->Channels >= 4) {
			for (y = 0; y < Head->Height * image->Bps; y += image->Bps) {
				for (x = 0; x < image->Bps; x += image->Bpp) {
					image->Data[y + x + 3] = 255;
				}
			}
					
			for (; c < Head->Channels; c++) {
				ReadResult = ReadCompressedChannel(image, ChanLen[c], Size, Channel);
				if (ReadResult == READ_COMPRESSED_ERROR_FILE_CORRUPT)
					goto file_corrupt;
				else if (ReadResult == READ_COMPRESSED_ERROR_FILE_READ_ERROR)
					goto file_read_error;

				i = 0;
				for (y = 0; y < Head->Height * image->Bps; y += image->Bps) {
					for (x = 0; x < image->Bps; x += image->Bpp, i++) {
						float curVal = ubyte_to_float(image->Data[y + x + 3]);
						float newVal = ubyte_to_float(Channel[i]);
						image->Data[y + x + 3] = float_to_ubyte(curVal * newVal);
					}
				}
			}
		}

		ifree(ChanLen);
	}

	ifree(Channel);

	return IL_TRUE;

file_corrupt:
	ifree(ChanLen);
	ifree(Channel);
	il2SetError(IL_ILLEGAL_FILE_VALUE);
	return IL_FALSE;

file_read_error:
	ifree(ChanLen);
	ifree(Channel);
	return IL_FALSE;
}