ILboolean ILAPIENTRY ilRegisterNumImages(ILuint Num) { ILimage *Next, *Prev; ilBindImage(ilGetCurName()); // Make sure the current image is actually bound. ilCloseImage(iCurImage->Next); // Close any current "next" images. iCurImage->Next = NULL; if (Num == 0) // Just gets rid of all the "next" images. return IL_TRUE; iCurImage->Next = il2NewImage(1, 1, 1, 1, 1); if (iCurImage->Next == NULL) return IL_FALSE; Next = iCurImage->Next; Num--; while (Num) { Next->Next = il2NewImage(1, 1, 1, 1, 1); if (Next->Next == NULL) { // Clean up before we error out. Prev = iCurImage->Next; while (Prev) { Next = Prev->Next; ilCloseImage(Prev); Prev = Next; } return IL_FALSE; } Next = Next->Next; Num--; } return IL_TRUE; }
// Internal version of ilTexImage. ILAPI ILboolean ILAPIENTRY ilTexImage_(ILimage *Image, ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp, ILenum Format, ILenum Type, ILvoid *Data) { if (Image == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } //// // Not sure if we should be getting rid of the palette... if (Image->Pal.Palette && Image->Pal.PalSize && Image->Pal.PalType != IL_PAL_NONE) { ifree(Image->Pal.Palette); } ilCloseImage(Image->Mipmaps); ilCloseImage(Image->Next); ilCloseImage(Image->Layers); if (Image->AnimList) ifree(Image->AnimList); if (Image->Profile) ifree(Image->Profile); if (Image->DxtcData) ifree(Image->DxtcData); if (Image->Data) ifree(Image->Data); //// // Also check against format? /*if (Width == 0 || Height == 0 || Depth == 0 || Bpp == 0) { ilSetError(IL_INVALID_PARAM); return IL_FALSE; }*/ return ilInitImage(Image, Width, Height, Depth, Bpp, Format, Type, Data); }
ID3D10Texture2D* ILAPIENTRY ilutD3D10Texture(ID3D10Device *Device) { ID3D10Texture2D *Texture; DXGI_FORMAT Format; ILimage *Image; Image = ilutCurImage = ilGetCurImage(); if (ilutCurImage == NULL) { ilSetError(ILUT_ILLEGAL_OPERATION); return NULL; } if (!FormatsDX10Checked) CheckFormatsDX10(Device); Image = MakeD3D10Compliant(Device, &Format); if (Image == NULL) { if (Image != ilutCurImage) ilCloseImage(Image); return NULL; } Texture = iD3D10MakeTexture(Device, Image->Data, Image->Width, Image->Height, Format, 1); //@TODO: The 1 should be ilutGetInteger(ILUT_D3D_MIPLEVELS). if (!Texture) return NULL; //iD3D10CreateMipmaps(Texture, Image); //success: if (Image != ilutCurImage) ilCloseImage(Image); return Texture; }
//! Closes Image and frees all memory associated with it. ILAPI void ILAPIENTRY ilCloseImage(ILimage *Image) { if (Image == NULL) return; if (Image->Data != NULL) { ifree(Image->Data); Image->Data = NULL; } if (Image->Pal.Palette != NULL && Image->Pal.PalSize > 0 && Image->Pal.PalType != IL_PAL_NONE) { ifree(Image->Pal.Palette); Image->Pal.Palette = NULL; } if (Image->Next != NULL) { ilCloseImage(Image->Next); Image->Next = NULL; } if (Image->Faces != NULL) { ilCloseImage(Image->Faces); Image->Mipmaps = NULL; } if (Image->Mipmaps != NULL) { ilCloseImage(Image->Mipmaps); Image->Mipmaps = NULL; } if (Image->Layers != NULL) { ilCloseImage(Image->Layers); Image->Layers = NULL; } if (Image->AnimList != NULL && Image->AnimSize != 0) { ifree(Image->AnimList); Image->AnimList = NULL; } if (Image->Profile != NULL && Image->ProfileSize != 0) { ifree(Image->Profile); Image->Profile = NULL; Image->ProfileSize = 0; } if (Image->DxtcData != NULL && Image->DxtcFormat != IL_DXT_NO_COMP) { ifree(Image->DxtcData); Image->DxtcData = NULL; Image->DxtcFormat = IL_DXT_NO_COMP; Image->DxtcSize = 0; } ifree(Image); Image = NULL; return; }
//! Closes Image and frees all memory associated with it. ILAPI void ILAPIENTRY ilCloseImage(void * image) { ILimage* Image = (ILimage*) image; if (Image == NULL) return; if (Image->Data != NULL) { ifree(Image->Data); Image->Data = NULL; } Image->Pal.clear(); if (Image->Next != NULL) { ilCloseImage(Image->Next); Image->Next = NULL; } if (Image->Faces != NULL) { ilCloseImage(Image->Faces); Image->Mipmaps = NULL; } if (Image->Mipmaps != NULL) { ilCloseImage(Image->Mipmaps); Image->Mipmaps = NULL; } if (Image->Layers != NULL) { ilCloseImage(Image->Layers); Image->Layers = NULL; } if (Image->AnimList != NULL && Image->AnimSize != 0) { ifree(Image->AnimList); Image->AnimList = NULL; } if (Image->Profile != NULL && Image->ProfileSize != 0) { ifree(Image->Profile); Image->Profile = NULL; Image->ProfileSize = 0; } if (Image->DxtcData != NULL && Image->DxtcFormat != IL_DXT_NO_COMP) { ifree(Image->DxtcData); Image->DxtcData = NULL; Image->DxtcFormat = IL_DXT_NO_COMP; Image->DxtcSize = 0; } ifree(Image); Image = NULL; return; }
ILuint ILAPIENTRY ilCreateSubImage(ILenum Type, ILuint Num) { ILimage *SubImage; ILuint Count ; // Create one before we go in the loop. if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return 0; } if (Num == 0) { return 0; } switch (Type) { case IL_SUB_NEXT: if (iCurImage->Next) ilCloseImage(iCurImage->Next); iCurImage->Next = ilNewImage(1, 1, 1, 1, 1); SubImage = iCurImage->Next; break; case IL_SUB_MIPMAP: if (iCurImage->Mipmaps) ilCloseImage(iCurImage->Mipmaps); iCurImage->Mipmaps = ilNewImage(1, 1, 1, 1, 1); SubImage = iCurImage->Mipmaps; break; case IL_SUB_LAYER: if (iCurImage->Layers) ilCloseImage(iCurImage->Layers); iCurImage->Layers = ilNewImage(1, 1, 1, 1, 1); SubImage = iCurImage->Layers; break; default: ilSetError(IL_INVALID_ENUM); return IL_FALSE; } if (SubImage == NULL) { return 0; } for (Count = 1; Count < Num; Count++) { SubImage->Next = ilNewImage(1, 1, 1, 1, 1); SubImage = SubImage->Next; if (SubImage == NULL) return Count; } return Count; }
ILAPI ILimage* ILAPIENTRY iluScale_(ILimage *Image, ILuint Width, ILuint Height, ILuint Depth) { ILimage *Scaled, *CurImage, *ToScale; ILenum Format, PalType; CurImage = ilGetCurImage(); Format = Image->Format; if (Format == IL_COLOUR_INDEX) { ilSetCurImage(Image); PalType = Image->Pal.PalType; ToScale = iConvertImage(iluCurImage, ilGetPalBaseType(Image->Pal.PalType), iluCurImage->Type); } else { ToScale = Image; } // So we don't replicate this 3 times (one in each iluScalexD_() function. Scaled = (ILimage*)icalloc(1, sizeof(ILimage)); if (ilCopyImageAttr(Scaled, ToScale) == IL_FALSE) { ilCloseImage(Scaled); if (ToScale != Image) ilCloseImage(ToScale); ilSetCurImage(CurImage); return NULL; } if (ilResizeImage(Scaled, Width, Height, Depth, ToScale->Bpp, ToScale->Bpc) == IL_FALSE) { ilCloseImage(Scaled); if (ToScale != Image) ilCloseImage(ToScale); ilSetCurImage(CurImage); return NULL; } if (Height <= 1 && Image->Height <= 1) { iluScale1D_(ToScale, Scaled, Width); } if (Depth <= 1 && Image->Depth <= 1) { iluScale2D_(ToScale, Scaled, Width, Height); } else { iluScale3D_(ToScale, Scaled, Width, Height, Depth); } if (Format == IL_COLOUR_INDEX) { //ilSetCurImage(Scaled); //ilConvertImage(IL_COLOUR_INDEX); ilSetCurImage(CurImage); ilCloseImage(ToScale); } return Scaled; }
// Sharpens when Factor is in the range [1.0, 2.5]. // Blurs when Factor is in the range [0.0, 1.0]. ILboolean ILAPIENTRY iluSharpen(ILfloat Factor, ILuint Iter) { ILimage *Blur, *CurImage; // iluBlur() changes iluCurImage ILuint i; CurImage = ilGetCurImage(); if (CurImage == NULL) { ilSetError(ILU_ILLEGAL_OPERATION); return IL_FALSE; } Blur = ilNewImage(CurImage->Width, CurImage->Height, CurImage->Depth, CurImage->Bpp, CurImage->Bpc); if (Blur == NULL) { return IL_FALSE; } ilCopyImageAttr(Blur, CurImage); ilCopyPixels(0, 0, 0, CurImage->Width, CurImage->Height, 1, CurImage->Format, CurImage->Type, Blur->Data); ilSetCurImage(Blur); iluBlurGaussian(1); for (i = 0; i < Iter; i++) { iIntExtImg(Blur, CurImage, Factor); } ilCloseImage(Blur); ilSetCurImage(CurImage); return IL_TRUE; }
// Frees any extra memory in the stack. // - Called on exit ILvoid ILAPIENTRY ilShutDown() { // if it is not initialized do not shutdown iFree* TempFree = (iFree*)FreeNames; ILuint i; if (!IsInit) return; if (!IsInit) { // Prevent from being called when not initialized. ilSetError(IL_ILLEGAL_OPERATION); return; } while (TempFree != NULL) { FreeNames = (iFree*)TempFree->Next; ifree(TempFree); TempFree = FreeNames; } //for (i = 0; i < LastUsed; i++) { for (i = 0; i < StackSize; i++) { if (ImageStack[i] != NULL) ilCloseImage(ImageStack[i]); } if (ImageStack) ifree(ImageStack); ImageStack = NULL; LastUsed = 0; StackSize = 0; IsInit = IL_FALSE; return; }
// Frees any extra memory in the stack. // - Should be called on exit or when unloading the library ILAPI void ILAPIENTRY ilShutDown() { // if it is not initialized do not shutdown iFree* TempFree = (iFree*)FreeNames; ILuint i; while (TempFree != NULL) { FreeNames = (iFree*)TempFree->Next; ifree(TempFree); TempFree = FreeNames; } //for (i = 0; i < LastUsed; i++) { for (i = 0; i < StackSize; i++) { if (ImageStack[i] != NULL) ilCloseImage(ImageStack[i]); } if (ImageStack) ifree(ImageStack); ImageStack = NULL; LastUsed = 0; StackSize = 0; return; }
// Works best when Contrast is in the range [-0.5, 1.7]. ILboolean ILAPIENTRY iluContrast(ILfloat Contrast) { ILimage *Grey; ILuint i; iluCurImage = ilGetCurImage(); if (iluCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } Grey = ilNewImage(iluCurImage->Width, iluCurImage->Height, iluCurImage->Depth, iluCurImage->Bpp, iluCurImage->Bpc); if (Grey == NULL) { return IL_FALSE; } // Make Grey all 127's for (i = 0; i < Grey->SizeOfData; i++) { Grey->Data[i] = 127; } iIntExtImg(Grey, iluCurImage, Contrast); ilCloseImage(Grey); return IL_TRUE; }
ILimage *iUncompressDcxSmall(DCXHEAD *Header) { ILuint i = 0, j, k, c, d, x, y, Bps; ILubyte HeadByte, Colour, Data = 0, *ScanLine = NULL; ILimage *Image; Image = ilNewImage(Header->Xmax - Header->Xmin + 1, Header->Ymax - Header->Ymin + 1, 1, Header->NumPlanes, 1); if (Image == NULL) return NULL; /*if (!ilTexImage(Header->Xmax - Header->Xmin + 1, Header->Ymax - Header->Ymin + 1, 1, 1, 0, IL_UNSIGNED_BYTE, NULL)) { return IL_FALSE; }*/ Image->Origin = IL_ORIGIN_UPPER_LEFT; switch (Header->NumPlanes) { case 1: Image->Format = IL_LUMINANCE; break; case 4: Image->Format = IL_COLOUR_INDEX; break; default: ilSetError(IL_ILLEGAL_FILE_VALUE); ilCloseImage(Image); return NULL; } if (Header->NumPlanes == 1) { for (j = 0; j < Image->Height; j++) { i = 0; while (i < Image->Width) { if (iread(&HeadByte, 1, 1) != 1) goto file_read_error; if (HeadByte >= 192) { HeadByte -= 192; if (iread(&Data, 1, 1) != 1) goto file_read_error; for (c = 0; c < HeadByte; c++) { k = 128; for (d = 0; d < 8 && i < Image->Width; d++) { Image->Data[j * Image->Width + i++] = (!!(Data & k) == 1 ? 255 : 0); k >>= 1; } } } else { k = 128; for (c = 0; c < 8 && i < Image->Width; c++) { Image->Data[j * Image->Width + i++] = (!!(HeadByte & k) == 1 ? 255 : 0); k >>= 1; } } } if (Data != 0) igetc(); // Skip pad byte if last byte not a 0 }
ILboolean iD3D8CreateMipmaps(IDirect3DTexture8 *Texture, ILimage *Image) { D3DLOCKED_RECT Rect; D3DSURFACE_DESC Desc; ILuint NumMips, Width, Height, i; ILimage *CurImage, *MipImage, *Temp; NumMips = IDirect3DTexture8_GetLevelCount(Texture); Width = Image->Width; Height = Image->Height; CurImage = ilGetCurImage(); MipImage = ilCopyImage_(CurImage); ilSetCurImage(MipImage); if (!iluBuildMipmaps()) { ilCloseImage(MipImage); ilSetCurImage(CurImage); return IL_FALSE; } ilSetCurImage(CurImage); Temp = MipImage->Mipmaps; // Counts the base texture as 1. for (i = 1; i < NumMips && Temp != NULL; i++) { if (FAILED(IDirect3DTexture8_LockRect(Texture, i, &Rect, NULL, 0))) return IL_FALSE; Width = IL_MAX(1, Width / 2); Height = IL_MAX(1, Height / 2); IDirect3DTexture8_GetLevelDesc(Texture, i, &Desc); if (Desc.Width != Width || Desc.Height != Height) { IDirect3DTexture8_UnlockRect(Texture, i); return IL_FALSE; } memcpy(Rect.pBits, Temp->Data, Temp->SizeOfData); IDirect3DTexture8_UnlockRect(Texture, i); Temp = Temp->Next; } ilCloseImage(MipImage); return IL_TRUE; }
// Does not account for converting luminance... BITMAP* ILAPIENTRY ilutConvertToAlleg(PALETTE Pal) { BITMAP *Bitmap; ILimage *TempImage; ILuint i = 0, j = 0; ilutCurImage = ilGetCurImage(); if (ilutCurImage == NULL) { ilSetError(ILUT_ILLEGAL_OPERATION); return NULL; } // Should be IL_BGR(A), but Djgpp screws up somewhere along the line. if (ilutCurImage->Format == IL_RGB || ilutCurImage->Format == IL_RGBA) { iluSwapColours(); } if (ilutCurImage->Origin == IL_ORIGIN_LOWER_LEFT) iluFlipImage(); if (ilutCurImage->Type > IL_UNSIGNED_BYTE) {} // Can't do anything about this right now... if (ilutCurImage->Type == IL_BYTE) {} // Can't do anything about this right now... Bitmap = create_bitmap_ex(ilutCurImage->Bpp * 8, ilutCurImage->Width, ilutCurImage->Height); if (Bitmap == NULL) { return IL_FALSE; } memcpy(Bitmap->dat, ilutCurImage->Data, ilutCurImage->SizeOfData); // Should we make this toggleable? if (ilutCurImage->Bpp == 8 && ilutCurImage->Pal.PalType != IL_PAL_NONE) { // Use the image's palette if there is one // ilConvertPal is destructive to the original image // @TODO: Use new ilCopyPal!!! TempImage = ilNewImage(ilutCurImage->Width, ilutCurImage->Height, ilutCurImage->Depth, ilutCurImage->Bpp, 1); ilCopyImageAttr(TempImage, ilutCurImage); ilSetCurImage(TempImage); if (!ilConvertPal(IL_PAL_RGB24)) { destroy_bitmap(Bitmap); ilSetError(ILUT_ILLEGAL_OPERATION); return NULL; } for (; i < ilutCurImage->Pal.PalSize && i < 768; i += 3, j++) { Pal[j].r = TempImage->Pal.Palette[i+0]; Pal[j].g = TempImage->Pal.Palette[i+1]; Pal[j].b = TempImage->Pal.Palette[i+2]; Pal[j].filler = 255; } ilCloseImage(TempImage); ilSetCurImage(ilutCurImage); } return Bitmap; }
ILboolean ILAPIENTRY iluRotate(ILfloat Angle) { ILimage *Temp, *Temp1, *CurImage = NULL; ILenum PalType = 0; iluCurImage = ilGetCurImage(); if (iluCurImage == NULL) { ilSetError(ILU_ILLEGAL_OPERATION); return IL_FALSE; } if (iluCurImage->Format == IL_COLOUR_INDEX) { PalType = iluCurImage->Pal.PalType; CurImage = iluCurImage; iluCurImage = iConvertImage(iluCurImage, ilGetPalBaseType(CurImage->Pal.PalType), IL_UNSIGNED_BYTE); } Temp = iluRotate_(iluCurImage, Angle); if (Temp != NULL) { if (PalType != 0) { ilCloseImage(iluCurImage); Temp1 = iConvertImage(Temp, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE); ilCloseImage(Temp); Temp = Temp1; ilSetCurImage(CurImage); } ilTexImage(Temp->Width, Temp->Height, Temp->Depth, Temp->Bpp, Temp->Format, Temp->Type, Temp->Data); if (PalType != 0) { iluCurImage = ilGetCurImage(); iluCurImage->Pal.PalSize = Temp->Pal.PalSize; iluCurImage->Pal.PalType = Temp->Pal.PalType; iluCurImage->Pal.Palette = (ILubyte*)ialloc(Temp->Pal.PalSize); if (iluCurImage->Pal.Palette == NULL) { ilCloseImage(Temp); return IL_FALSE; } memcpy(iluCurImage->Pal.Palette, Temp->Pal.Palette, Temp->Pal.PalSize); } iluCurImage->Origin = Temp->Origin; ilCloseImage(Temp); return IL_TRUE; } return IL_FALSE; }
// Completely replaces the current image and the version in the image stack. ILAPI void ILAPIENTRY ilReplaceCurImage(ILimage *Image) { if (iCurImage) { ilActiveImage(0); ilCloseImage(iCurImage); } ImageStack[ilGetCurName()] = Image; iCurImage = Image; return; }
//! Deletes Num images from the image stack - similar to glDeleteTextures(). ILvoid ILAPIENTRY ilDeleteImages(ILsizei Num, const ILuint *Images) { iFree *Temp = FreeNames; ILuint Index = 0; if (Num < 1) { //ilSetError(IL_INVALID_VALUE); return; } if (StackSize == 0) return; do { if (Images[Index] > 0 && Images[Index] < LastUsed) { // <= ? /*if (FreeNames != NULL) { // Terribly inefficient Temp = FreeNames; do { if (Temp->Name == Images[Index]) { continue; // Sufficient? } } while ((Temp = Temp->Next)); }*/ // Already has been deleted or was never used. if (ImageStack[Images[Index]] == NULL) continue; // Find out if current image - if so, set to default image zero. if (Images[Index] == CurName || Images[Index] == 0) { iCurImage = ImageStack[0]; CurName = 0; } // Should *NOT* be NULL here! ilCloseImage(ImageStack[Images[Index]]); ImageStack[Images[Index]] = NULL; // Add to head of list - works for empty and non-empty lists Temp = (iFree*)ialloc(sizeof(iFree)); if (!Temp) { return; } Temp->Name = Images[Index]; Temp->Next = FreeNames; FreeNames = Temp; } /*else { // Shouldn't set an error...just continue onward. ilSetError(IL_ILLEGAL_OPERATION); }*/ } while (++Index < (ILuint)Num); }
ILboolean iLoadDcxInternal() { DCXHEAD Header; ILuint Signature, i, Entries[1024], Num = 0; ILimage *Image, *Base; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } if (!iIsValidDcx()) return IL_FALSE; iread(&Signature, 1, 4); do { if (iread(&Entries[Num], 1, 4) != 4) return IL_FALSE; Num++; } while (Entries[Num-1] != 0); iCurImage->NumNext = Num - 1; for (i = 0; i < Num; i++) { iseek(Entries[i], IL_SEEK_SET); iGetDcxHead(&Header); /*if (!iCheckDcx(&Header)) { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; }*/ Image = iUncompressDcx(&Header); if (Image == NULL) return IL_FALSE; if (i == 0) { ilTexImage(Image->Width, Image->Height, 1, Image->Bpp, Image->Format, Image->Type, Image->Data); Base = iCurImage; Base->Origin = IL_ORIGIN_UPPER_LEFT; ilCloseImage(Image); } else { iCurImage->Next = Image; iCurImage = iCurImage->Next; } } ilFixImage(); return IL_TRUE; }
// Note: No longer changes all textures to powers of 2. ILboolean ILAPIENTRY iluBuildMipmaps() { iluCurImage = ilGetCurImage(); if (iluCurImage == NULL) { il2SetError(ILU_ILLEGAL_OPERATION); return IL_FALSE; } // Get rid of any existing mipmaps. if (iluCurImage->Mipmaps) { ilCloseImage(iluCurImage->Mipmaps); iluCurImage->Mipmaps = NULL; } return iBuildMipmaps(iluCurImage, iluCurImage->Width >> 1, iluCurImage->Height >> 1, iluCurImage->Depth >> 1); }
ILboolean ILAPIENTRY iluRotate3D(ILfloat x, ILfloat y, ILfloat z, ILfloat Angle) { ILimage *Temp; // return IL_FALSE; iluCurImage = ilGetCurImage(); Temp = iluRotate3D_(iluCurImage, x, y, z, Angle); if (Temp != NULL) { ilTexImage(Temp->Width, Temp->Height, Temp->Depth, Temp->Bpp, Temp->Format, Temp->Type, Temp->Data); iluCurImage->Origin = Temp->Origin; ilSetPal(&Temp->Pal); ilCloseImage(Temp); return IL_TRUE; } return IL_FALSE; }
ILuint ilu2ScaleAdvanced(ILimage* image, ILuint Width, ILuint Height, ILenum Filter) { double (*f)(double) = filter; double s = filter_support; ILimage *Dest; if (image == NULL) { il2SetError(ILU_ILLEGAL_OPERATION); return IL_FALSE; } // Not supported yet. if (image->Type != IL_UNSIGNED_BYTE || image->Format == IL_COLOUR_INDEX || image->Depth > 1) { il2SetError(ILU_ILLEGAL_OPERATION); return IL_FALSE; } switch (Filter) { case ILU_SCALE_BOX: f=box_filter; s=box_support; break; case ILU_SCALE_TRIANGLE: f=triangle_filter; s=triangle_support; break; case ILU_SCALE_BELL: f=bell_filter; s=bell_support; break; case ILU_SCALE_BSPLINE: f=B_spline_filter; s=B_spline_support; break; case ILU_SCALE_LANCZOS3: f=Lanczos3_filter; s=Lanczos3_support; break; case ILU_SCALE_MITCHELL: f=Mitchell_filter; s=Mitchell_support; break; } Dest = il2NewImage(Width, Height, 1, image->Bpp, 1); Dest->Origin = image->Origin; Dest->Duration = image->Duration; for (c = 0; c < (ILuint)image->Bpp; c++) { if (zoom(Dest, image, f, s) != 0) { return IL_FALSE; } } il2TexImage(image, Width, Height, 1, image->Bpp, image->Format, image->Type, Dest->Data); image->Origin = Dest->Origin; image->Duration = Dest->Duration; ilCloseImage(Dest); return IL_TRUE; }
ILimage *MakeD3D8Compliant(IDirect3DDevice8 *Device, D3DFORMAT *DestFormat) { ILimage *Converted, *Scaled, *CurImage; *DestFormat = D3DFMT_A8R8G8B8; // Images must be in BGRA format. if (ilutCurImage->Format != IL_BGRA) { Converted = iConvertImage(ilutCurImage, IL_BGRA, IL_UNSIGNED_BYTE); if (Converted == NULL) return NULL; } else { Converted = ilutCurImage; } // Images must have their origin in the upper left. if (Converted->Origin != IL_ORIGIN_UPPER_LEFT) { CurImage = ilutCurImage; ilSetCurImage(Converted); iluFlipImage(); ilSetCurImage(CurImage); } // Images must have powers-of-2 dimensions. if (ilNextPower2(ilutCurImage->Width) != ilutCurImage->Width || ilNextPower2(ilutCurImage->Height) != ilutCurImage->Height || ilNextPower2(ilutCurImage->Depth) != ilutCurImage->Depth) { Scaled = iluScale_(Converted, ilNextPower2(ilutCurImage->Width), ilNextPower2(ilutCurImage->Height), ilNextPower2(ilutCurImage->Depth)); if (Converted != ilutCurImage) { ilCloseImage(Converted); } if (Scaled == NULL) { return NULL; } Converted = Scaled; } return Converted; }
IDirect3DVolumeTexture8* ILAPIENTRY ilutD3D8VolumeTexture(IDirect3DDevice8 *Device) { IDirect3DVolumeTexture8 *Texture; D3DLOCKED_BOX Box; D3DFORMAT Format; ILimage *Image; ilutCurImage = ilGetCurImage(); if (ilutCurImage == NULL) { ilSetError(ILUT_ILLEGAL_OPERATION); return NULL; } if (!FormatsDX8Checked) CheckFormatsDX8(Device); Image = MakeD3D8Compliant(Device, &Format); if (Image == NULL) return NULL; if (FAILED(IDirect3DDevice8_CreateVolumeTexture(Device, Image->Width, Image->Height, Image->Depth, 1, 0, Format, ilutGetInteger(ILUT_D3D_POOL), &Texture))) return NULL; if (FAILED(IDirect3DVolumeTexture8_LockBox(Texture, 0, &Box, NULL, 0))) return NULL; memcpy(Box.pBits, Image->Data, Image->SizeOfData); if (!IDirect3DVolumeTexture8_UnlockBox(Texture, 0)) return IL_FALSE; // We don't want to have mipmaps for such a large image. if (Image != ilutCurImage) ilCloseImage(Image); return Texture; }
IDirect3DTexture8* ILAPIENTRY ilutD3D8Texture(IDirect3DDevice8 *Device) { IDirect3DTexture8 *Texture; D3DLOCKED_RECT Rect; D3DFORMAT Format; ILimage *Image; ILenum DXTCFormat; ILuint Size; ILubyte *Buffer; Image = ilutCurImage = ilGetCurImage(); if (ilutCurImage == NULL) { ilSetError(ILUT_ILLEGAL_OPERATION); return NULL; } if (!FormatsDX8Checked) CheckFormatsDX8(Device); if (ilutGetBoolean(ILUT_D3D_USE_DXTC) && FormatsDX8supported[3] && FormatsDX8supported[4] && FormatsDX8supported[5]) { if (ilutCurImage->DxtcData != NULL && ilutCurImage->DxtcSize != 0) { Format = D3DGetDXTCNumDX8(ilutCurImage->DxtcFormat); if (FAILED(IDirect3DDevice8_CreateTexture(Device, ilutCurImage->Width, ilutCurImage->Height, ilutGetInteger(ILUT_D3D_MIPLEVELS), 0, Format, ilutGetInteger(ILUT_D3D_POOL), &Texture))) return NULL; if (FAILED(IDirect3DTexture8_LockRect(Texture, 0, &Rect, NULL, 0))) return NULL; memcpy(Rect.pBits, ilutCurImage->DxtcData, ilutCurImage->DxtcSize); goto success; } if (ilutGetBoolean(ILUT_D3D_GEN_DXTC)) { DXTCFormat = ilutGetInteger(ILUT_DXTC_FORMAT); Size = ilGetDXTCData(NULL, 0, DXTCFormat); if (Size != 0) { Buffer = (ILubyte*)ialloc(Size); if (Buffer == NULL) return NULL; Size = ilGetDXTCData(Buffer, Size, DXTCFormat); if (Size == 0) { ifree(Buffer); return NULL; } Format = D3DGetDXTCNumDX8(DXTCFormat); if (FAILED(IDirect3DDevice8_CreateTexture(Device, ilutCurImage->Width, ilutCurImage->Height, ilutGetInteger(ILUT_D3D_MIPLEVELS), 0, Format, ilutGetInteger(ILUT_D3D_POOL), &Texture))) { ifree(Buffer); return NULL; } if (FAILED(IDirect3DTexture8_LockRect(Texture, 0, &Rect, NULL, 0))) { ifree(Buffer); return NULL; } memcpy(Rect.pBits, Buffer, Size); ifree(Buffer); goto success; } } } Image = MakeD3D8Compliant(Device, &Format); if (Image == NULL) { if (Image != ilutCurImage) ilCloseImage(Image); return NULL; } if (FAILED(IDirect3DDevice8_CreateTexture(Device, Image->Width, Image->Height, ilutGetInteger(ILUT_D3D_MIPLEVELS), 0, Format, ilutGetInteger(ILUT_D3D_POOL), &Texture))) { if (Image != ilutCurImage) ilCloseImage(Image); return NULL; } if (FAILED(IDirect3DTexture8_LockRect(Texture, 0, &Rect, NULL, 0))) return NULL; memcpy(Rect.pBits, Image->Data, Image->SizeOfPlane); success: IDirect3DTexture8_UnlockRect(Texture, 0); // Just let D3DX filter for us. //D3DXFilterTexture(Texture, NULL, D3DX_DEFAULT, D3DX_FILTER_BOX); iD3D8CreateMipmaps(Texture, Image); if (Image != ilutCurImage) ilCloseImage(Image); return Texture; }
ILboolean iSaveJpegInternal() { struct jpeg_compress_struct JpegInfo; struct jpeg_error_mgr Error; JSAMPROW row_pointer[1]; ILimage *TempImage; ILubyte *TempData; ILenum Type = 0; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } /*if (iGetHint(IL_COMPRESSION_HINT) == IL_USE_COMPRESSION) Quality = 85; // Not sure how low we should dare go... else Quality = 99;*/ // angua: RGB images also need to be converted to RGBA if ((iCurImage->Format != IL_RGBA && iCurImage->Format != IL_LUMINANCE) || iCurImage->Bpc != 1) { // taaaki: since RGB_PIXELSIZE was changed to 4, the conversion to // RGB is short one colour component, causing screenshots to crash TempImage = iConvertImage(iCurImage, IL_RGBA, IL_UNSIGNED_BYTE); if (TempImage == NULL) { return IL_FALSE; } } else { TempImage = iCurImage; } if (TempImage->Origin == IL_ORIGIN_LOWER_LEFT) { TempData = iGetFlipped(TempImage); if (TempData == NULL) { if (TempImage != iCurImage) ilCloseImage(TempImage); return IL_FALSE; } } else { TempData = TempImage->Data; } JpegInfo.err = jpeg_std_error(&Error); // Now we can initialize the JPEG compression object. jpeg_create_compress(&JpegInfo); //jpeg_stdio_dest(&JpegInfo, JpegFile); devil_jpeg_write_init(&JpegInfo); JpegInfo.image_width = TempImage->Width; // image width and height, in pixels JpegInfo.image_height = TempImage->Height; JpegInfo.input_components = TempImage->Bpp; // # of color components per pixel // John Villar's addition if (TempImage->Bpp == 1) JpegInfo.in_color_space = JCS_GRAYSCALE; else JpegInfo.in_color_space = JCS_RGB; jpeg_set_defaults(&JpegInfo); /*#ifndef IL_USE_JPEGLIB_UNMODIFIED Type = iGetInt(IL_JPG_SAVE_FORMAT); if (Type == IL_EXIF) { JpegInfo.write_JFIF_header = FALSE; JpegInfo.write_EXIF_header = TRUE; } else if (Type == IL_JFIF) { JpegInfo.write_JFIF_header = TRUE; JpegInfo.write_EXIF_header = FALSE; } EXIF not present int libjpeg... #else*/ Type = Type; JpegInfo.write_JFIF_header = TRUE; //#endif//IL_USE_JPEGLIB_UNMODIFIED jpeg_set_quality(&JpegInfo, iGetInt(IL_JPG_QUALITY), IL_TRUE); jpeg_start_compress(&JpegInfo, IL_TRUE); //row_stride = image_width * 3; // JSAMPLEs per row in image_buffer while (JpegInfo.next_scanline < JpegInfo.image_height) { // jpeg_write_scanlines expects an array of pointers to scanlines. // Here the array is only one element long, but you could pass // more than one scanline at a time if that's more convenient. row_pointer[0] = &TempData[JpegInfo.next_scanline * TempImage->Bps]; (void) jpeg_write_scanlines(&JpegInfo, row_pointer, 1); } // Step 6: Finish compression jpeg_finish_compress(&JpegInfo); // Step 7: release JPEG compression object // This is an important step since it will release a good deal of memory. jpeg_destroy_compress(&JpegInfo); if (TempImage->Origin == IL_ORIGIN_LOWER_LEFT) ifree(TempData); if (TempImage != iCurImage) ilCloseImage(TempImage); return IL_TRUE; }
ILboolean ilSaveFromJpegStruct(ILvoid *_JpegInfo) { #ifndef IL_NO_JPG #ifndef IL_USE_IJL void (*errorHandler)(j_common_ptr); JSAMPROW row_pointer[1]; ILimage *TempImage; ILubyte *TempData; j_compress_ptr JpegInfo = (j_compress_ptr)_JpegInfo; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } //added on 2003-08-31 as explained in sf bug 596793 jpgErrorOccured = IL_FALSE; errorHandler = JpegInfo->err->error_exit; JpegInfo->err->error_exit = ExitErrorHandle; if ((iCurImage->Format != IL_RGB && iCurImage->Format != IL_LUMINANCE) || iCurImage->Bpc != 1) { TempImage = iConvertImage(iCurImage, IL_RGB, IL_UNSIGNED_BYTE); if (TempImage == NULL) { return IL_FALSE; } } else { TempImage = iCurImage; } if (TempImage->Origin == IL_ORIGIN_LOWER_LEFT) { TempData = iGetFlipped(TempImage); if (TempData == NULL) { if (TempImage != iCurImage) ilCloseImage(TempImage); return IL_FALSE; } } else { TempData = TempImage->Data; } JpegInfo->image_width = TempImage->Width; // image width and height, in pixels JpegInfo->image_height = TempImage->Height; JpegInfo->input_components = TempImage->Bpp; // # of color components per pixel jpeg_start_compress(JpegInfo, IL_TRUE); //row_stride = image_width * 3; // JSAMPLEs per row in image_buffer while (JpegInfo->next_scanline < JpegInfo->image_height) { // jpeg_write_scanlines expects an array of pointers to scanlines. // Here the array is only one element long, but you could pass // more than one scanline at a time if that's more convenient. row_pointer[0] = &TempData[JpegInfo->next_scanline * TempImage->Bps]; (void) jpeg_write_scanlines(JpegInfo, row_pointer, 1); } if (TempImage->Origin == IL_ORIGIN_LOWER_LEFT) ifree(TempData); if (TempImage != iCurImage) ilCloseImage(TempImage); return (!jpgErrorOccured); #endif #endif return IL_FALSE; }
ILboolean iSaveJpegInternal(ILstring FileName, ILvoid *Lump, ILuint Size) { JPEG_CORE_PROPERTIES Image; ILuint Quality; ILimage *TempImage; ILubyte *TempData; imemclear(&Image, sizeof(JPEG_CORE_PROPERTIES)); if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } if (FileName == NULL && Lump == NULL) { ilSetError(IL_INVALID_PARAM); return IL_FALSE; } if (iGetHint(IL_COMPRESSION_HINT) == IL_USE_COMPRESSION) Quality = 85; // Not sure how low we should dare go... else Quality = 99; if (ijlInit(&Image) != IJL_OK) { ilSetError(IL_LIB_JPEG_ERROR); return IL_FALSE; } if ((iCurImage->Format != IL_RGB && iCurImage->Format != IL_RGBA && iCurImage->Format != IL_LUMINANCE) || iCurImage->Bpc != 1) { if (iCurImage->Format == IL_BGRA) Temp = iConvertImage(iCurImage, IL_RGBA, IL_UNSIGNED_BYTE); else Temp = iConvertImage(iCurImage, IL_RGB, IL_UNSIGNED_BYTE); if (Temp == NULL) { return IL_FALSE; } } else { Temp = iCurImage; } if (TempImage->Origin == IL_ORIGIN_LOWER_LEFT) { TempData = iGetFlipped(TempImage); if (TempData == NULL) { if (TempImage != iCurImage) ilCloseImage(TempImage); return IL_FALSE; } } else { TempData = TempImage->Data; } // Setup DIB Image.DIBWidth = TempImage->Width; Image.DIBHeight = TempImage->Height; Image.DIBChannels = TempImage->Bpp; Image.DIBBytes = TempData; Image.DIBPadBytes = 0; // Setup JPEG Image.JPGWidth = TempImage->Width; Image.JPGHeight = TempImage->Height; Image.JPGChannels = TempImage->Bpp; switch (Temp->Bpp) { case 1: Image.DIBColor = IJL_G; Image.JPGColor = IJL_G; Image.JPGSubsampling = IJL_NONE; break; case 3: Image.DIBColor = IJL_RGB; Image.JPGColor = IJL_YCBCR; Image.JPGSubsampling = IJL_411; break; case 4: Image.DIBColor = IJL_RGBA_FPX; Image.JPGColor = IJL_YCBCRA_FPX; Image.JPGSubsampling = IJL_4114; break; } if (FileName != NULL) { Image.JPGFile = FileName; if (ijlWrite(&Image, IJL_JFILE_WRITEWHOLEIMAGE) != IJL_OK) { if (TempImage != iCurImage) ilCloseImage(TempImage); ilSetError(IL_LIB_JPEG_ERROR); return IL_FALSE; } } else { Image.JPGBytes = Lump; Image.JPGSizeBytes = Size; if (ijlWrite(&Image, IJL_JBUFF_WRITEWHOLEIMAGE) != IJL_OK) { if (TempImage != iCurImage) ilCloseImage(TempImage); ilSetError(IL_LIB_JPEG_ERROR); return IL_FALSE; } } ijlFree(&Image); if (TempImage->Origin == IL_ORIGIN_LOWER_LEFT) ifree(TempData); if (Temp != iCurImage) ilCloseImage(Temp); return IL_TRUE; }
ILAPI ILimage* ILAPIENTRY iluRotate_(ILimage *Image, ILfloat Angle) { ILimage *Rotated = NULL; ILuint x, y, c; ILfloat x0, y0, x1, y1; ILfloat HalfRotW, HalfRotH, HalfImgW, HalfImgH, Cos, Sin; ILuint RotOffset, ImgOffset; ILint XCorner[4], YCorner[4], MaxX, MaxY; ILushort *ShortPtr; ILuint *IntPtr; Rotated = (ILimage*)icalloc(1, sizeof(ILimage)); if (Rotated == NULL) return NULL; if (ilCopyImageAttr(Rotated, Image) == IL_FALSE) { ilCloseImage(Rotated); return NULL; } // Precalculate shit HalfImgW = Image->Width / 2.0f; HalfImgH = Image->Height / 2.0f; Cos = ilCos(Angle); Sin = ilSin(Angle); // Find where edges are in new image (origin in center). XCorner[0] = ilRound(-HalfImgW * Cos - -HalfImgH * Sin); YCorner[0] = ilRound(-HalfImgW * Sin + -HalfImgH * Cos); XCorner[1] = ilRound(HalfImgW * Cos - -HalfImgH * Sin); YCorner[1] = ilRound(HalfImgW * Sin + -HalfImgH * Cos); XCorner[2] = ilRound(HalfImgW * Cos - HalfImgH * Sin); YCorner[2] = ilRound(HalfImgW * Sin + HalfImgH * Cos); XCorner[3] = ilRound(-HalfImgW * Cos - HalfImgH * Sin); YCorner[3] = ilRound(-HalfImgW * Sin + HalfImgH * Cos); MaxX = 0; MaxY = 0; for (x = 0; x < 4; x++) { if (XCorner[x] > MaxX) MaxX = XCorner[x]; if (YCorner[x] > MaxY) MaxY = YCorner[x]; } if (ilResizeImage(Rotated, MaxX * 2, MaxY * 2, 1, Image->Bpp, Image->Bpc) == IL_FALSE) { ilCloseImage(Rotated); return IL_FALSE; } HalfRotW = Rotated->Width / 2.0f; HalfRotH = Rotated->Height / 2.0f; ilClearImage_(Rotated); ShortPtr = (ILushort*)iluCurImage->Data; IntPtr = (ILuint*)iluCurImage->Data; //if (iluFilter == ILU_NEAREST) { switch (iluCurImage->Bpc) { case 1: for (y = 0; y < Rotated->Height; y++) { y0 = y - HalfRotH; for (x = 0; x < Rotated->Width; x++) { x0 = x - HalfRotW; x1 = x0 * Cos - y0 * Sin; y1 = x0 * Sin + y0 * Cos; x1 += HalfImgW; y1 += HalfImgH; if (x1 < Image->Width && x1 >= 0 && y1 < Image->Height && y1 >= 0) { RotOffset = y * Rotated->Bps + x * Rotated->Bpp; ImgOffset = (ILuint)y1 * Image->Bps + (ILuint)x1 * Image->Bpp; for (c = 0; c < Image->Bpp; c++) { Rotated->Data[RotOffset + c] = Image->Data[ImgOffset + c]; } } } } break; case 2: Image->Bps /= 2; Rotated->Bps /= 2; for (y = 0; y < Rotated->Height; y++) { y0 = y - HalfRotH; for (x = 0; x < Rotated->Width; x++) { x0 = x - HalfRotW; x1 = x0 * Cos - y0 * Sin; y1 = x0 * Sin + y0 * Cos; x1 += HalfImgW; y1 += HalfImgH; if (x1 < Image->Width && x1 >= 0 && y1 < Image->Height && y1 >= 0) { RotOffset = y * Rotated->Bps + x * Rotated->Bpp; ImgOffset = (ILuint)y1 * Image->Bps + (ILuint)x1 * Image->Bpp; for (c = 0; c < Image->Bpp; c++) { ((ILushort*)(Rotated->Data))[RotOffset + c] = ShortPtr[ImgOffset + c]; } } } } Image->Bps *= 2; Rotated->Bps *= 2; break; case 4: Image->Bps /= 4; Rotated->Bps /= 4; for (y = 0; y < Rotated->Height; y++) { y0 = y - HalfRotH; for (x = 0; x < Rotated->Width; x++) { x0 = x - HalfRotW; x1 = x0 * Cos - y0 * Sin; y1 = x0 * Sin + y0 * Cos; x1 += HalfImgW; y1 += HalfImgH; if (x1 < Image->Width && x1 >= 0 && y1 < Image->Height && y1 >= 0) { RotOffset = y * Rotated->Bps + x * Rotated->Bpp; ImgOffset = (ILuint)y1 * Image->Bps + (ILuint)x1 * Image->Bpp; for (c = 0; c < Image->Bpp; c++) { ((ILuint*)(Rotated->Data))[RotOffset + c] = IntPtr[ImgOffset + c]; } } } } Image->Bps *= 4; Rotated->Bps *= 4; break; } //} return Rotated; }
//! Generates a C-style header file for the current image. ILboolean ilSaveCHeader(ILimage* image, char *InternalName) { FILE *HeadFile = NULL; ILuint i = 0, j; ILimage *TempImage; const char *Name; if (image == NULL) { il2SetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } Name = iGetString(IL_CHEAD_HEADER_STRING); if (Name == NULL) Name = InternalName; if (image->Bpc > 1) { TempImage = iConvertImage(image, image->Format, IL_UNSIGNED_BYTE); if (TempImage == NULL) return IL_FALSE; } else { TempImage = image; } FILE* file = (FILE*) image->io.handle; fprintf(HeadFile, "//#include <il/il.h>\n"); fprintf(HeadFile, "// C Image Header:\n\n\n"); fprintf(HeadFile, "// IMAGE_BPP is in bytes per pixel, *not* bits\n"); fprintf(HeadFile, "#define IMAGE_BPP %d\n",image->Bpp); fprintf(HeadFile, "#define IMAGE_WIDTH %d\n", image->Width); fprintf(HeadFile, "#define IMAGE_HEIGHT %d\n", image->Height); fprintf(HeadFile, "#define IMAGE_DEPTH %d\n\n\n", image->Depth); fprintf(HeadFile, "#define IMAGE_TYPE 0x%X\n", image->Type); fprintf(HeadFile, "#define IMAGE_FORMAT 0x%X\n\n\n", image->Format); fprintf(HeadFile, "ILubyte %s[] = {\n", Name); for (; i < TempImage->SizeOfData; i += MAX_LINE_WIDTH) { fprintf(HeadFile, "\t"); for (j = 0; j < MAX_LINE_WIDTH; j++) { if (i + j >= TempImage->SizeOfData - 1) { fprintf(HeadFile, "%4d", TempImage->Data[i+j]); break; } else fprintf(HeadFile, "%4d,", TempImage->Data[i+j]); } fprintf(HeadFile, "\n"); } if (TempImage != image) ilCloseImage(TempImage); fprintf(HeadFile, "};\n"); if (image->Pal.hasPalette()) { fprintf(HeadFile, "\n\n"); fprintf(HeadFile, "#define IMAGE_PALSIZE %u\n\n", image->Pal.getPalSize()); fprintf(HeadFile, "#define IMAGE_PALTYPE 0x%X\n\n", image->Pal.getPalType()); fprintf(HeadFile, "ILubyte %sPal[] = {\n", Name); for (i = 0; i < image->Pal.getPalSize(); i += MAX_LINE_WIDTH) { fprintf(HeadFile, "\t"); for (j = 0; j < MAX_LINE_WIDTH; j++) { if (i + j >= image->Pal.getPalSize() - 1) { fprintf(HeadFile, " %4d", image->Pal.getPalette()[i+j]); break; } else fprintf(HeadFile, " %4d,", image->Pal.getPalette()[i+j]); } fprintf(HeadFile, "\n"); } fprintf(HeadFile, "};\n"); } fclose(HeadFile); return IL_TRUE; }
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; }