//! Creates Num images and puts their index in Images - similar to glGenTextures(). ILAPI void ILAPIENTRY ilGenImages(ILsizei Num, ILuint *Images) { ILsizei Index = 0; iFree *TempFree = FreeNames; if (Num < 1 || Images == NULL) { il2SetError(IL_INVALID_VALUE); return; } // No images have been generated yet, so create the image stack. if (ImageStack == NULL) if (!iEnlargeStack()) return; do { if (FreeNames != NULL) { // If any have been deleted, then reuse their image names. TempFree = (iFree*)FreeNames->Next; Images[Index] = FreeNames->Name; ImageStack[FreeNames->Name] = il2NewImage(1, 1, 1, 1, 1); ifree(FreeNames); FreeNames = TempFree; } else { if (LastUsed >= StackSize) if (!iEnlargeStack()) return; Images[Index] = LastUsed; // Must be all 1's instead of 0's, because some functions would divide by 0. ImageStack[LastUsed] = il2NewImage(1, 1, 1, 1, 1); LastUsed++; } } while (++Index < Num); return; }
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; }
//! Makes Image the current active image - similar to glBindTexture(). ILAPI void ILAPIENTRY ilBindImage(ILuint Image) { if (ImageStack == NULL || StackSize == 0) { if (!iEnlargeStack()) { return; } } // If the user requests a high image name. while (Image >= StackSize) { if (!iEnlargeStack()) { return; } } if (ImageStack[Image] == NULL) { ImageStack[Image] = il2NewImage(1, 1, 1, 1, 1); if (Image >= LastUsed) // >= ? LastUsed = Image + 1; } iCurImage = ImageStack[Image]; CurName = Image; return; }
ILAPI void ILAPIENTRY iBindImageTemp() { if (ImageStack == NULL || StackSize <= 1) if (!iEnlargeStack()) return; if (LastUsed < 2) LastUsed = 2; CurName = 1; if (!ImageStack[1]) ImageStack[1] = il2NewImage(1, 1, 1, 1, 1); iCurImage = ImageStack[1]; return; }
// Initializes the image stack's first entry (default image) -- ONLY CALL ONCE! void iSetImage0() { if (ImageStack == NULL) if (!iEnlargeStack()) return; LastUsed = 1; CurName = 0; if (!ImageStack[0]) ImageStack[0] = il2NewImage(1, 1, 1, 1, 1); iCurImage = ImageStack[0]; il2DefaultImage(iCurImage); return; }
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; }
// Creates a copy of Src and returns it. ILAPI ILimage* ILAPIENTRY il2CopyImage_(ILimage *Src) { ILimage *Dest; if (Src == NULL) { il2SetError(IL_INVALID_PARAM); return NULL; } Dest = il2NewImage(Src->Width, Src->Height, Src->Depth, Src->Bpp, Src->Bpc); if (Dest == NULL) { return NULL; } if (il2CopyImageAttr(Dest, Src) == IL_FALSE) return NULL; memcpy(Dest->Data, Src->Data, Src->SizeOfData); return Dest; }
ILboolean iIcnsReadData(ILimage* image, ILboolean *BaseCreated, ILboolean IsAlpha, ILint Width, ICNSDATA *Entry, ILimage **Image) { ILint Position = 0, RLEPos = 0, Channel, i; ILubyte RLERead, *Data = NULL; ILimage *TempImage = NULL; ILboolean ImageAlreadyExists = IL_FALSE; // The .icns format stores the alpha and RGB as two separate images, so this // checks to see if one exists for that particular size. Unfortunately, // there is no guarantee that they are in any particular order. if (*BaseCreated && image != NULL) { TempImage = image; while (TempImage != NULL) { if ((ILuint)Width == TempImage->Width) { ImageAlreadyExists = IL_TRUE; break; } TempImage = TempImage->Next; } } Data = (ILubyte*) ialloc(Entry->Size - 8); if (Data == NULL) return IL_FALSE; if (!ImageAlreadyExists) { if (!*BaseCreated) // Create base image { il2TexImage(image, Width, Width, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL); image->Origin = IL_ORIGIN_UPPER_LEFT; *Image = image; *BaseCreated = IL_TRUE; } else // Create next image in list { (*Image)->Next = il2NewImage(Width, Width, 1, 4, 1); *Image = (*Image)->Next; (*Image)->Format = IL_RGBA; (*Image)->Origin = IL_ORIGIN_UPPER_LEFT; } TempImage = *Image; } if (IsAlpha) // Alpha is never compressed. { image->io.read(&image->io, Data, Entry->Size - 8, 1); // Size includes the header if (Entry->Size - 8 != Width * Width) { ifree(Data); return IL_FALSE; } for (i = 0; i < Width * Width; i++) { TempImage->Data[(i * 4) + 3] = Data[i]; } } else if (Width == 256 || Width == 512) // JPEG2000 encoded - uses JasPer { #ifndef IL_NO_JP2 image->io.read(&image->io, Data, Entry->Size - 8, 1); // Size includes the header if (ilLoadJp2LInternal(TempImage, Data, Entry->Size - 8) == IL_FALSE) { ifree(Data); il2SetError(IL_LIB_JP2_ERROR); return IL_TRUE; } #else // Cannot io this size. il2SetError(IL_LIB_JP2_ERROR); //@TODO: io this better...just skip the data. return IL_FALSE; #endif//IL_NO_JP2 } else // RGB data { image->io.read(&image->io, Data, Entry->Size - 8, 1); // Size includes the header if (Width == 128) RLEPos += 4; // There are an extra 4 bytes here of zeros. //@TODO: Should we check to make sure they are all 0? if (Entry->Size - 8 == Width * Width * 4) // Uncompressed { //memcpy(TempImage->Data, Data, Entry->Size); for (i = 0; i < Width * Width; i++, Position += 4) { TempImage->Data[i * 4 + 0] = Data[Position+1]; TempImage->Data[i * 4 + 1] = Data[Position+2]; TempImage->Data[i * 4 + 2] = Data[Position+3]; } } else // RLE decoding { for (Channel = 0; Channel < 3; Channel++) { Position = 0; while (Position < Width * Width) { RLERead = Data[RLEPos]; RLEPos++; if (RLERead >= 128) { for (i = 0; i < RLERead - 125 && (Position + i) < Width * Width; i++) { TempImage->Data[Channel + (Position + i) * 4] = Data[RLEPos]; } RLEPos++; Position += RLERead - 125; } else { for (i = 0; i < RLERead + 1 && (Position + i) < Width * Width; i++) { TempImage->Data[Channel + (Position + i) * 4] = Data[RLEPos + i]; } RLEPos += RLERead + 1; Position += RLERead + 1; } } } } } ifree(Data); return IL_TRUE; }
// Generate a new image ILAPI ILimage* ILAPIENTRY il2GenImage() { return il2NewImage(1, 1, 1, 1, 1); }