// Internal function to load a raw data image ILboolean iLoadDataInternal(ILuint Width, ILuint Height, ILuint Depth, ILubyte Bpp) { if (iCurImage == NULL || ((Bpp != 1) && (Bpp != 3) && (Bpp != 4))) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } if (!ilTexImage(Width, Height, Depth, Bpp, 0, IL_UNSIGNED_BYTE, NULL)) { return IL_FALSE; } iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; // Tries to read the correct amount of data if (iCurImage->io.read(iCurImage->io.handle, iCurImage->Data, Width * Height * Depth * Bpp, 1) != 1) return IL_FALSE; 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(); }
ILboolean iLoadMngInternal() { mng_handle mng; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } mng = mng_initialize(MNG_NULL, mymngalloc, mymngfree, MNG_NULL); if (mng == MNG_NULL) { ilSetError(IL_LIB_MNG_ERROR); return IL_FALSE; } // If .mng background is available, use it. mng_set_usebkgd(mng, MNG_TRUE); // Set the callbacks. mng_setcb_errorproc(mng, mymngerror); mng_setcb_openstream(mng, mymngopenstream); mng_setcb_closestream(mng, mymngclosestream); mng_setcb_readdata(mng, (mng_readdata)mymngreadstream); mng_setcb_gettickcount(mng, mymnggetticks); mng_setcb_settimer(mng, mymngsettimer); mng_setcb_processheader(mng, mymngprocessheader); mng_setcb_getcanvasline(mng, mymnggetcanvasline); mng_setcb_refresh(mng, mymngrefresh); mng_read(mng); mng_display(mng); return ilFixImage(); }
/* Internal function used to load the SGI image */ ILboolean iLoadSgiInternal() { iSgiHeader Header; ILboolean bSgi; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } if (!iGetSgiHead(&Header)) return IL_FALSE; if (!iCheckSgi(&Header)) { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } if (Header.Storage == SGI_RLE) { // RLE bSgi = iReadRleSgi(&Header); } else { // Non-RLE //(Header.Storage == SGI_VERBATIM) bSgi = iReadNonRleSgi(&Header); } ilFixImage(); return bSgi; }
// Internal function used to load the PSP. ILboolean iLoadPspInternal() { if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } Channels = NULL; Alpha = NULL; Pal.Palette = NULL; if (!iGetPspHead()) return IL_FALSE; if (!iCheckPsp()) { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } if (!ReadGenAttributes()) return IL_FALSE; if (!ParseChunks()) return IL_FALSE; if (!AssembleImage()) return IL_FALSE; Cleanup(); return ilFixImage(); }
// Note: .Cut support has not been tested yet! // A .cut can only have 1 bpp. // We need to add support for the .pal's PSP outputs with these... ILboolean iLoadCutInternal() { CUT_HEAD Header; ILuint Size, i = 0, j; ILubyte Count, Run; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } Header.Width = GetLittleShort(); Header.Height = GetLittleShort(); Header.Dummy = GetLittleInt(); if (Header.Width == 0 || Header.Height == 0) { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } if (!ilTexImage(Header.Width, Header.Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) { // always 1 bpp return IL_FALSE; } iCurImage->Origin = IL_ORIGIN_LOWER_LEFT; Size = Header.Width * Header.Height; while (i < Size) { Count = igetc(); if (Count == 0) { // end of row igetc(); // Not supposed to be here, but igetc(); // PSP is putting these two bytes here...WHY?! continue; } if (Count & BIT_7) { // rle-compressed ClearBits(Count, BIT_7); Run = igetc(); for (j = 0; j < Count; j++) { iCurImage->Data[i++] = Run; } } else { // run of pixels for (j = 0; j < Count; j++) { iCurImage->Data[i++] = igetc(); } } } iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; // Not sure /*iCurImage->Pal.Palette = SharedPal.Palette; iCurImage->Pal.PalSize = SharedPal.PalSize; iCurImage->Pal.PalType = SharedPal.PalType;*/ return ilFixImage(); }
// Access point for applications wishing to use the jpeg library directly in // conjunction with DevIL. // // The decompressor must be set up with an input source and all desired parameters // this function is called. The caller must call jpeg_finish_decompress because // the caller may still need decompressor after calling this for e.g. examining // saved markers. ILboolean ILAPIENTRY ilLoadFromJpegStruct(ILvoid *_JpegInfo) { #ifndef IL_NO_JPG #ifndef IL_USE_IJL // sam. void (*errorHandler)(j_common_ptr); ILubyte *TempPtr[1]; ILuint Returned; j_decompress_ptr JpegInfo = (j_decompress_ptr)_JpegInfo; //added on 2003-08-31 as explained in sf bug 596793 jpgErrorOccured = IL_FALSE; // sam. errorHandler = JpegInfo->err->error_exit; // sam. JpegInfo->err->error_exit = ExitErrorHandle; jpeg_start_decompress((j_decompress_ptr)JpegInfo); if (!ilTexImage(JpegInfo->output_width, JpegInfo->output_height, 1, (ILubyte)JpegInfo->output_components, 0, IL_UNSIGNED_BYTE, NULL)) { return IL_FALSE; } iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; switch (iCurImage->Bpp) { case 1: iCurImage->Format = IL_LUMINANCE; break; case 3: iCurImage->Format = IL_RGB; break; case 4: iCurImage->Format = IL_RGBA; break; default: // Anyway to get here? Need to error out or something... break; } TempPtr[0] = iCurImage->Data; while (JpegInfo->output_scanline < JpegInfo->output_height) { Returned = jpeg_read_scanlines(JpegInfo, TempPtr, 1); // anyway to make it read all at once? TempPtr[0] += iCurImage->Bps; if (Returned == 0) break; } // sam. JpegInfo->err->error_exit = errorHandler; if (jpgErrorOccured) return IL_FALSE; ilFixImage(); return IL_TRUE; #endif #endif return IL_FALSE; }
// Internal function used to load the Gif. ILboolean iLoadGifInternal() { GIFHEAD Header; ILpal GlobalPal; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } GlobalPal.Palette = NULL; GlobalPal.PalSize = 0; //read header iread(&Header.Sig, 1, 6); Header.Width = GetLittleUShort(); Header.Height = GetLittleUShort(); Header.ColourInfo = igetc(); Header.Background = igetc(); Header.Aspect = igetc(); if (!strnicmp(Header.Sig, "GIF87A", 6)) { GifType = GIF87A; } else if (!strnicmp(Header.Sig, "GIF89A", 6)) { GifType = GIF89A; } else { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } if (!ilTexImage(Header.Width, Header.Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) return IL_FALSE; iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; // Check for a global colour map. if (Header.ColourInfo & (1 << 7)) { if (!iGetPalette(Header.ColourInfo, &GlobalPal)) { return IL_FALSE; } } if (!GetImages(&GlobalPal, &Header)) return IL_FALSE; if (GlobalPal.Palette && GlobalPal.PalSize) ifree(GlobalPal.Palette); GlobalPal.Palette = NULL; GlobalPal.PalSize = 0; ilFixImage(); return IL_TRUE; }
// Basically just ireads 4096 bytes and copies the palette ILboolean iLoadDoomFlatInternal() { ILubyte *NewData; ILuint i; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } if (!ilTexImage(64, 64, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) { return IL_FALSE; } iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; iCurImage->Pal.Palette = (ILubyte*)ialloc(IL_DOOMPAL_SIZE); if (iCurImage->Pal.Palette == NULL) { return IL_FALSE; } iCurImage->Pal.PalSize = IL_DOOMPAL_SIZE; iCurImage->Pal.PalType = IL_PAL_RGB24; memcpy(iCurImage->Pal.Palette, ilDefaultDoomPal, IL_DOOMPAL_SIZE); if (iread(iCurImage->Data, 1, 4096) != 4096) return IL_FALSE; if (ilGetBoolean(IL_CONV_PAL) == IL_TRUE) { NewData = (ILubyte*)ialloc(iCurImage->SizeOfData * 4); if (NewData == NULL) { return IL_FALSE; } for (i = 0; i < iCurImage->SizeOfData; i++) { NewData[i * 4] = iCurImage->Pal.Palette[iCurImage->Data[i]]; NewData[i * 4] = iCurImage->Pal.Palette[iCurImage->Data[i]]; NewData[i * 4] = iCurImage->Pal.Palette[iCurImage->Data[i]]; NewData[i * 4 + 3] = iCurImage->Data[i] != 247 ? 255 : 0; } if (!ilTexImage(iCurImage->Width, iCurImage->Height, iCurImage->Depth, 4, IL_RGBA, iCurImage->Type, NewData)) { ifree(NewData); return IL_FALSE; } iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; ifree(NewData); } ilFixImage(); return IL_TRUE; }
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; }
// 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(); }
ILboolean iLoadIlbmInternal() { if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } if (!iIsValidIlbm()) { ilSetError(IL_INVALID_VALUE); return IL_FALSE; } if (!load_ilbm() ) { return IL_FALSE; } return ilFixImage(); }
// 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(); }
// Internal function used to load the Psd. ILboolean iLoadPsdInternal() { PSDHEAD Header; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } iGetPsdHead(&Header); if (!iCheckPsd(&Header)) { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } if (!ReadPsd(&Header)) return IL_FALSE; iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; return ilFixImage(); }
// Internal function used to load the Pix. ILboolean iLoadPixInternal() { PIXHEAD Header; ILuint i, j; ILubyte ByteHead, Colour[3]; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } if (!iGetPixHead(&Header)) return IL_FALSE; if (!iCheckPix(&Header)) { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } if (!ilTexImage(Header.Width, Header.Height, 1, 3, IL_BGR, IL_UNSIGNED_BYTE, NULL)) return IL_FALSE; for (i = 0; i < iCurImage->SizeOfData; ) { ByteHead = igetc(); if (iread(Colour, 1, 3) != 3) return IL_FALSE; for (j = 0; j < ByteHead; j++) { iCurImage->Data[i++] = Colour[0]; iCurImage->Data[i++] = Colour[1]; iCurImage->Data[i++] = Colour[2]; } } iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; ilFixImage(); return IL_TRUE; }
ILboolean iLoadLifInternal() { LIF_HEAD LifHead; ILuint i; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } if (!iGetLifHead(&LifHead)) return IL_FALSE; if (!ilTexImage(LifHead.Width, LifHead.Height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) { return IL_FALSE; } iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; iCurImage->Pal.Palette = (ILubyte*)ialloc(1024); if (iCurImage->Pal.Palette == NULL) return IL_FALSE; iCurImage->Pal.PalSize = 1024; iCurImage->Pal.PalType = IL_PAL_RGBA32; if (iread(iCurImage->Data, LifHead.Width * LifHead.Height, 1) != 1) return IL_FALSE; if (iread(iCurImage->Pal.Palette, 1, 1024) != 1024) return IL_FALSE; // Each data offset is offset by -1, so we add one. for (i = 0; i < iCurImage->SizeOfData; i++) { iCurImage->Data[i]++; } ilFixImage(); return IL_TRUE; }
// Internal function used to load the .pcx. ILboolean iLoadPcxInternal() { PCXHEAD Header; ILboolean bPcx = IL_FALSE; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return bPcx; } if (!iGetPcxHead(&Header)) return IL_FALSE; if (!iCheckPcx(&Header)) { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } bPcx = iUncompressPcx(&Header); ilFixImage(); return bPcx; }
// Internal function used to load the FTX. ILboolean iLoadFtxInternal(void) { ILuint Width, Height, HasAlpha; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } Width = GetLittleUInt(); Height = GetLittleUInt(); HasAlpha = GetLittleUInt(); // 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 (!ilTexImage(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 // ilSetError(IL_INVALID_FILE_HEADER); // return IL_FALSE; //} // The origin will always be in the upper left. iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; // All we have to do for this format is read the raw, uncompressed data. if (iread(iCurImage->Data, 1, iCurImage->SizeOfData) != iCurImage->SizeOfData) return IL_FALSE; return ilFixImage(); }
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(); }
ILboolean iLoadJpegInternal(ILstring FileName, ILvoid *Lump, ILuint Size) { JPEG_CORE_PROPERTIES Image; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } if (ijlInit(&Image) != IJL_OK) { ilSetError(IL_LIB_JPEG_ERROR); return IL_FALSE; } if (FileName != NULL) { Image.JPGFile = FileName; if (ijlRead(&Image, IJL_JFILE_READPARAMS) != IJL_OK) { ilSetError(IL_LIB_JPEG_ERROR); return IL_FALSE; } } else { Image.JPGBytes = Lump; Image.JPGSizeBytes = Size > 0 ? Size : UINT_MAX; if (ijlRead(&Image, IJL_JBUFF_READPARAMS) != IJL_OK) { ilSetError(IL_LIB_JPEG_ERROR); return IL_FALSE; } } switch (Image.JPGChannels) { case 1: Image.JPGColor = IJL_G; Image.DIBChannels = 1; Image.DIBColor = IJL_G; iCurImage->Format = IL_LUMINANCE; break; case 3: Image.JPGColor = IJL_YCBCR; Image.DIBChannels = 3; Image.DIBColor = IJL_RGB; iCurImage->Format = IL_RGB; break; case 4: Image.JPGColor = IJL_YCBCRA_FPX; Image.DIBChannels = 4; Image.DIBColor = IJL_RGBA_FPX; iCurImage->Format = IL_RGBA; break; default: // This catches everything else, but no // color twist will be performed by the IJL. /*Image.DIBColor = (IJL_COLOR)IJL_OTHER; Image.JPGColor = (IJL_COLOR)IJL_OTHER; Image.DIBChannels = Image.JPGChannels; break;*/ ijlFree(&Image); ilSetError(IL_LIB_JPEG_ERROR); return IL_FALSE; } if (!ilTexImage(Image.JPGWidth, Image.JPGHeight, 1, (ILubyte)Image.DIBChannels, iCurImage->Format, IL_UNSIGNED_BYTE, NULL)) { ijlFree(&Image); return IL_FALSE; } iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; Image.DIBWidth = Image.JPGWidth; Image.DIBHeight = Image.JPGHeight; Image.DIBPadBytes = 0; Image.DIBBytes = iCurImage->Data; if (FileName != NULL) { if (ijlRead(&Image, IJL_JFILE_READWHOLEIMAGE) != IJL_OK) { ijlFree(&Image); ilSetError(IL_LIB_JPEG_ERROR); return IL_FALSE; } } else { if (ijlRead(&Image, IJL_JBUFF_READWHOLEIMAGE) != IJL_OK) { ijlFree(&Image); ilSetError(IL_LIB_JPEG_ERROR); return IL_FALSE; } } ijlFree(&Image); ilFixImage(); return IL_TRUE; }
// Internal function used to load the icon. ILboolean iLoadIcnsInternal() { ICNSHEAD Header; ICNSDATA Entry; ILimage *Image = NULL; ILboolean BaseCreated = IL_FALSE; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } iread(Header.Head, 4, 1); Header.Size = GetBigInt(); if (strncmp(Header.Head, "icns", 4)) // First 4 bytes have to be 'icns'. return IL_FALSE; while ((ILint)itell() < Header.Size && !ieof()) { iread(Entry.ID, 4, 1); Entry.Size = GetBigInt(); if (!strncmp(Entry.ID, "it32", 4)) // 128x128 24-bit { if (iIcnsReadData(&BaseCreated, IL_FALSE, 128, &Entry, &Image) == IL_FALSE) goto icns_error; } else if (!strncmp(Entry.ID, "t8mk", 4)) // 128x128 alpha mask { if (iIcnsReadData(&BaseCreated, IL_TRUE, 128, &Entry, &Image) == IL_FALSE) goto icns_error; } else if (!strncmp(Entry.ID, "ih32", 4)) // 48x48 24-bit { if (iIcnsReadData(&BaseCreated, IL_FALSE, 48, &Entry, &Image) == IL_FALSE) goto icns_error; } else if (!strncmp(Entry.ID, "h8mk", 4)) // 48x48 alpha mask { if (iIcnsReadData(&BaseCreated, IL_TRUE, 48, &Entry, &Image) == IL_FALSE) goto icns_error; } else if (!strncmp(Entry.ID, "il32", 4)) // 32x32 24-bit { if (iIcnsReadData(&BaseCreated, IL_FALSE, 32, &Entry, &Image) == IL_FALSE) goto icns_error; } else if (!strncmp(Entry.ID, "l8mk", 4)) // 32x32 alpha mask { if (iIcnsReadData(&BaseCreated, IL_TRUE, 32, &Entry, &Image) == IL_FALSE) goto icns_error; } else if (!strncmp(Entry.ID, "is32", 4)) // 16x16 24-bit { if (iIcnsReadData(&BaseCreated, IL_FALSE, 16, &Entry, &Image) == IL_FALSE) goto icns_error; } else if (!strncmp(Entry.ID, "s8mk", 4)) // 16x16 alpha mask { if (iIcnsReadData(&BaseCreated, IL_TRUE, 16, &Entry, &Image) == IL_FALSE) goto icns_error; } #ifndef IL_NO_JP2 else if (!strncmp(Entry.ID, "ic09", 4)) // 512x512 JPEG2000 encoded - Uses JasPer { if (iIcnsReadData(&BaseCreated, IL_FALSE, 512, &Entry, &Image) == IL_FALSE) goto icns_error; } else if (!strncmp(Entry.ID, "ic08", 4)) // 256x256 JPEG2000 encoded - Uses JasPer { if (iIcnsReadData(&BaseCreated, IL_FALSE, 256, &Entry, &Image) == IL_FALSE) goto icns_error; } #endif//IL_NO_JP2 else // Not a valid format or one that we can use { iseek(Entry.Size - 8, IL_SEEK_CUR); } } return ilFixImage(); icns_error: return IL_FALSE; }
// 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(); }
ILboolean iLoadPcdInternal() { ILubyte VertOrientation; ILuint Width, Height, i, Total, x, CurPos = 0; ILubyte *Y1=NULL, *Y2=NULL, *CbCr=NULL, r = 0, g = 0, b = 0; ILuint PicNum; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } iseek(72, IL_SEEK_CUR); if (iread(&VertOrientation, 1, 1) != 1) return IL_FALSE; iseek(-72, IL_SEEK_CUR); // Can't rewind PicNum = iGetInt(IL_PCD_PICNUM); switch (PicNum) { case 0: iseek(0x02000, IL_SEEK_CUR); Width = 192; Height = 128; break; case 1: iseek(0x0b800, IL_SEEK_CUR); Width = 384; Height = 256; break; case 2: iseek(0x30000, IL_SEEK_CUR); Width = 768; Height = 512; break; default: ilSetError(IL_INVALID_PARAM); return IL_FALSE; } if (itell() == IL_EOF) // Supposed to have data here. return IL_FALSE; Y1 = (ILubyte*)ialloc(Width); Y2 = (ILubyte*)ialloc(Width); CbCr = (ILubyte*)ialloc(Width); if (Y1 == NULL || Y2 == NULL || CbCr == NULL) { ifree(Y1); ifree(Y2); ifree(CbCr); return IL_FALSE; } if (!ilTexImage(Width, Height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL)) { return IL_FALSE; } iCurImage->Origin = IL_ORIGIN_LOWER_LEFT; Total = Height >> 1; for (i = 0; i < Total; i++) { iread(Y1, 1, Width); iread(Y2, 1, Width); if (iread(CbCr, 1, Width) != Width) { // Only really need to check the last one. ifree(Y1); ifree(Y2); ifree(CbCr); return IL_FALSE; } for (x = 0; x < Width; x++) { YCbCr2RGB(Y1[x], CbCr[x / 2], CbCr[(Width / 2) + (x / 2)], &r, &g, &b); iCurImage->Data[CurPos++] = r; iCurImage->Data[CurPos++] = g; iCurImage->Data[CurPos++] = b; } for (x = 0; x < Width; x++) { YCbCr2RGB(Y2[x], CbCr[x / 2], CbCr[(Width / 2) + (x / 2)], &r, &g, &b); iCurImage->Data[CurPos++] = r; iCurImage->Data[CurPos++] = g; iCurImage->Data[CurPos++] = b; } } ifree(Y1); ifree(Y2); ifree(CbCr); // Not sure how it is...the documentation is hard to understand if ((VertOrientation & 0x3F) != 8) iCurImage->Origin = IL_ORIGIN_LOWER_LEFT; else iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; return ilFixImage(); }
// Internal function used to load the .pic ILboolean iLoadPicInternal() { ILuint Alpha = IL_FALSE; ILubyte Chained; CHANNEL *Channel = NULL, *Channels = NULL, *Prev; PIC_HEAD Header; ILboolean Read; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } if (!iGetPicHead(&Header)) return IL_FALSE; if (!iCheckPic(&Header)) { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } // Read channels do { if (Channel == NULL) { Channel = Channels = (CHANNEL*)ialloc(sizeof(CHANNEL)); if (Channels == NULL) return IL_FALSE; } else { Channels->Next = (CHANNEL*)ialloc(sizeof(CHANNEL)); if (Channels->Next == NULL) { // Clean up the list before erroring out. while (Channel) { Prev = Channel; Channel = (CHANNEL*)Channel->Next; ifree(Prev); } return IL_FALSE; } Channels = (CHANNEL*)Channels->Next; } Channels->Next = NULL; Chained = igetc(); Channels->Size = igetc(); Channels->Type = igetc(); Channels->Chan = igetc(); if (ieof()) { Read = IL_FALSE; goto finish; } // See if we have an alpha channel in there if (Channels->Chan & PIC_ALPHA_CHANNEL) Alpha = IL_TRUE; } while (Chained); if (Alpha) { // Has an alpha channel if (!ilTexImage(Header.Width, Header.Height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL)) { Read = IL_FALSE; goto finish; // Have to destroy Channels first. } } else { // No alpha channel if (!ilTexImage(Header.Width, Header.Height, 1, 3, IL_RGBA, IL_UNSIGNED_BYTE, NULL)) { Read = IL_FALSE; goto finish; // Have to destroy Channels first. } } iCurImage->Origin = IL_ORIGIN_LOWER_LEFT; Read = readScanlines((ILuint*)iCurImage->Data, Header.Width, Header.Height, Channel, Alpha); finish: // Destroy channels while (Channel) { Prev = Channel; Channel = (CHANNEL*)Channel->Next; ifree(Prev); } if (Read == IL_FALSE) return IL_FALSE; return ilFixImage(); }
// Internal function used to load the BLP. ILboolean iLoadBlpInternal(void) { BLP2HEAD Header; ILubyte *CompData; ILimage *Image; ILuint Mip, j, x, CompSize, AlphaSize, AlphaOff; ILint y; ILboolean BaseCreated = IL_FALSE; ILubyte *DataAndAlpha = NULL, *Palette = NULL, AlphaMask; //, *JpegHeader, *JpegData; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } if (!iGetBlp2Head(&Header)) { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } if (!iCheckBlp2(&Header)) { goto check_blp1; } //@TODO: Remove this! if (Header.Type != BLP_TYPE_DXTC_RAW) return IL_FALSE; switch (Header.Compression) { case BLP_RAW: for (Mip = 0; Mip < 16; Mip++) { // Possible maximum of 16 mipmaps if (BaseCreated) { if (Header.HasMips == 0) // Does not have mipmaps, so we are done. break; if (Image->Width == 1 && Image->Height == 1) // Already at the smallest mipmap (1x1), so we are done. break; if (Header.MipOffsets[Mip] == 0 || Header.MipLengths == 0) // No more mipmaps in the file. break; } switch (Header.AlphaBits) { case 0: 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; Image->Pal.Palette = (ILubyte*)ialloc(256 * 4); // 256 entries of ARGB8888 values (1024). if (Image->Pal.Palette == NULL) return IL_FALSE; Image->Pal.PalSize = 1024; Image->Pal.PalType = IL_PAL_BGRA32; //@TODO: Find out if this is really BGRA data. if (iread(Image->Pal.Palette, 1, 1024) != 1024) // Read in the palette. return IL_FALSE; } else { Image->Mipmaps = ilNewImageFull(Image->Width >> 1, Image->Height >> 1, 1, 1, IL_COLOUR_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. iCopyPalette(&Image->Mipmaps->Pal, &Image->Pal); // 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; // These two should be the same (tells us how much data is in the file for this mipmap level). if (Header.MipLengths[Mip] != Image->SizeOfData) { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } // Finally read in the image data. iseek(Header.MipOffsets[Mip], IL_SEEK_SET); if (iread(Image->Data, 1, Image->SizeOfData) != Image->SizeOfData) return IL_FALSE; break; case 1: if (!BaseCreated) { // Have not created the base image yet, so use ilTexImage. if (!ilTexImage(Header.Width, Header.Height, 1, 4, IL_BGRA, IL_UNSIGNED_BYTE, NULL)) return IL_FALSE; Image = iCurImage; BaseCreated = IL_TRUE; Palette = (ILubyte*)ialloc(256 * 4); if (Palette == NULL) return IL_FALSE; // Read in the palette. if (iread(Palette, 1, 1024) != 1024) { ifree(Palette); return IL_FALSE; } // We only allocate this once and reuse this buffer with every mipmap (since successive ones are smaller). DataAndAlpha = (ILubyte*)ialloc(Image->Width * Image->Height); if (DataAndAlpha == NULL) { ifree(DataAndAlpha); ifree(Palette); return IL_FALSE; } } else { Image->Mipmaps = ilNewImageFull(Image->Width >> 1, Image->Height >> 1, 1, 4, IL_BGRA, IL_UNSIGNED_BYTE, NULL); if (Image->Mipmaps == NULL) return IL_FALSE; // 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; // Determine the size of the alpha data following the color indices. AlphaSize = Image->Width * Image->Height / 8; if (AlphaSize == 0) AlphaSize = 1; // Should never be 0. // These two should be the same (tells us how much data is in the file for this mipmap level). if (Header.MipLengths[Mip] != Image->SizeOfData / 4 + AlphaSize) { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } // Seek to the data and read it. iseek(Header.MipOffsets[Mip], IL_SEEK_SET); if (iread(DataAndAlpha, Image->Width * Image->Height, 1) != 1) { ifree(DataAndAlpha); ifree(Palette); return IL_FALSE; } // Convert the color-indexed data to BGRX. for (j = 0; j < Image->Width * Image->Height; j++) { Image->Data[j*4] = Palette[DataAndAlpha[j]*4]; Image->Data[j*4+1] = Palette[DataAndAlpha[j]*4+1]; Image->Data[j*4+2] = Palette[DataAndAlpha[j]*4+2]; } // Read in the alpha list. if (iread(DataAndAlpha, AlphaSize, 1) != 1) { ifree(DataAndAlpha); ifree(Palette); return IL_FALSE; } AlphaMask = 0x01; // Lowest bit AlphaOff = 0; // The really strange thing about this alpha data is that it is upside-down when compared to the // regular color-indexed data, so we have to flip it. for (y = Image->Height - 1; y >= 0; y--) { for (x = 0; x < Image->Width; x++) { if (AlphaMask == 0) { // Shifting it past the highest bit makes it 0, since we only have 1 byte. AlphaOff++; // Move along the alpha buffer. AlphaMask = 0x01; // Reset the alpha mask. } // This is just 1-bit alpha, so it is either on or off. Image->Data[Image->Bps * y + x * 4 + 3] = DataAndAlpha[AlphaOff] & AlphaMask ? 0xFF : 0x00; AlphaMask <<= 1; } } break; default: //@TODO: Accept any other alpha values? ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } } // Done, so we can finally free these two. ifree(DataAndAlpha); ifree(Palette); break; case BLP_DXTC: for (Mip = 0; Mip < 16; Mip++) { // Possible maximum of 16 mipmaps //@TODO: Other formats //if (Header.AlphaBits == 0) // if (!ilTexImage(Header.Width, Header.Height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL)) // return IL_FALSE; if (!BaseCreated) { // Have not created the base image yet, so use ilTexImage. if (!ilTexImage(Header.Width, Header.Height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL)) return IL_FALSE; Image = iCurImage; BaseCreated = IL_TRUE; } else { if (Header.HasMips == 0) // Does not have mipmaps, so we are done. break; if (Image->Width == 1 && Image->Height == 1) // Already at the smallest mipmap (1x1), so we are done. break; if (Header.MipOffsets[Mip] == 0 || Header.MipLengths[Mip] == 0) // No more mipmaps in the file. break; //@TODO: Other formats // ilNewImageFull automatically changes widths and heights of 0 to 1, so we do not have to worry about it. Image->Mipmaps = ilNewImageFull(Image->Width >> 1, Image->Height >> 1, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL); if (Image->Mipmaps == NULL) return IL_FALSE; Image = Image->Mipmaps; } // The origin should be in the upper left. Image->Origin = IL_ORIGIN_UPPER_LEFT; //@TODO: Only do the allocation once. CompData = (ILubyte*)ialloc(Header.MipLengths[Mip]); if (CompData == NULL) return IL_FALSE; // Read in the compressed mipmap data. iseek(Header.MipOffsets[Mip], IL_SEEK_SET); if (iread(CompData, 1, Header.MipLengths[Mip]) != Header.MipLengths[Mip]) { ifree(CompData); return IL_FALSE; } switch (Header.AlphaBits) { case 0: // DXT1 without alpha case 1: // DXT1 with alpha // Check to make sure that the MipLength reported is the size needed, so that // DecompressDXT1 does not crash. CompSize = ((Image->Width + 3) / 4) * ((Image->Height + 3) / 4) * 8; if (CompSize != Header.MipLengths[Mip]) { ilSetError(IL_INVALID_FILE_HEADER); ifree(CompData); return IL_FALSE; } if (!DecompressDXT1(Image, CompData)) { ifree(CompData); return IL_FALSE; } break; case 8: // Check to make sure that the MipLength reported is the size needed, so that // DecompressDXT3/5 do not crash. CompSize = ((Image->Width + 3) / 4) * ((Image->Height + 3) / 4) * 16; if (CompSize != Header.MipLengths[Mip]) { ifree(CompData); ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } switch (Header.AlphaType) { case 0: // All three of case 1: // these refer to case 8: // DXT3... if (!DecompressDXT3(Image, CompData)) { ifree(CompData); return IL_FALSE; } break; case 7: // DXT5 compression if (!DecompressDXT5(Image, CompData)) { ifree(CompData); return IL_FALSE; } break; //default: // Should already be checked by iCheckBlp2. } break; //default: // Should already be checked by iCheckBlp2. } //@TODO: Save DXTC data. ifree(CompData); } break; //default: } return ilFixImage(); check_blp1: iseek(-148, IL_SEEK_CUR); // Go back the size of the BLP2 header, since we tried reading it. return iLoadBlp1(); }
// From the DTE sources (mostly by Denton Woods with corrections by Randy Heit) ILboolean iLoadDoomInternal() { ILshort width, height, graphic_header[2], column_loop, row_loop; ILint column_offset, pointer_position, first_pos; ILubyte post, topdelta, length; ILubyte *NewData; ILuint i; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } first_pos = itell(); // Needed to go back to the offset table width = GetLittleShort(); height = GetLittleShort(); graphic_header[0] = GetLittleShort(); // Not even used graphic_header[1] = GetLittleShort(); // Not even used if (!ilTexImage(width, height, 1, 1, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE, NULL)) { return IL_FALSE; } iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; iCurImage->Pal.Palette = (ILubyte*)ialloc(IL_DOOMPAL_SIZE); if (iCurImage->Pal.Palette == NULL) { return IL_FALSE; } iCurImage->Pal.PalSize = IL_DOOMPAL_SIZE; iCurImage->Pal.PalType = IL_PAL_RGB24; memcpy(iCurImage->Pal.Palette, ilDefaultDoomPal, IL_DOOMPAL_SIZE); // 247 is always the transparent colour (usually cyan) memset(iCurImage->Data, 247, iCurImage->SizeOfData); for (column_loop = 0; column_loop < width; column_loop++) { column_offset = GetLittleInt(); pointer_position = itell(); iseek(first_pos + column_offset, IL_SEEK_SET); while (1) { if (iread(&topdelta, 1, 1) != 1) return IL_FALSE; if (topdelta == 255) break; if (iread(&length, 1, 1) != 1) return IL_FALSE; if (iread(&post, 1, 1) != 1) return IL_FALSE; // Skip extra byte for scaling for (row_loop = 0; row_loop < length; row_loop++) { if (iread(&post, 1, 1) != 1) return IL_FALSE; if (row_loop + topdelta < height) iCurImage->Data[(row_loop+topdelta) * width + column_loop] = post; } iread(&post, 1, 1); // Skip extra scaling byte } iseek(pointer_position, IL_SEEK_SET); } // Converts palette entry 247 (cyan) to transparent. if (ilGetBoolean(IL_CONV_PAL) == IL_TRUE) { NewData = (ILubyte*)ialloc(iCurImage->SizeOfData * 4); if (NewData == NULL) { return IL_FALSE; } for (i = 0; i < iCurImage->SizeOfData; i++) { NewData[i * 4] = iCurImage->Pal.Palette[iCurImage->Data[i]]; NewData[i * 4] = iCurImage->Pal.Palette[iCurImage->Data[i]]; NewData[i * 4] = iCurImage->Pal.Palette[iCurImage->Data[i]]; NewData[i * 4 + 3] = iCurImage->Data[i] != 247 ? 255 : 0; } if (!ilTexImage(iCurImage->Width, iCurImage->Height, iCurImage->Depth, 4, IL_RGBA, iCurImage->Type, NewData)) { ifree(NewData); return IL_FALSE; } iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; ifree(NewData); } ilFixImage(); return IL_TRUE; }
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(); }
// Internal function used to load the DICOM. ILboolean iLoadDicomInternal(void) { DICOMHEAD Header; ILuint i; ILushort TempS, *ShortPtr; ILfloat TempF, *FloatPtr; ILboolean Swizzle = IL_FALSE; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } // Clear the header to all 0s to make checks later easier. memset(&Header, 0, sizeof(DICOMHEAD)); if (!iGetDicomHead(&Header)) { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } if (!iCheckDicom(&Header)) return IL_FALSE; if (!ilTexImage(Header.Width, Header.Height, Header.Depth, ilGetBppFormat(Header.Format), Header.Format, Header.Type, NULL)) return IL_FALSE; //@TODO: Find out if the origin is always in the upper left. iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; // Header.DataLen may be larger than SizeOfData, since it has to be padded with a NULL if it is not an even length, // so we just test to make sure it is at least large enough. //@TODO: Do this check before ilTexImage call. if (Header.DataLen < iCurImage->SizeOfData) { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } // We may have to swap the order of the data. #ifdef __BIG_ENDIAN__ if (!Header.BigEndian) { if (Header.Format == IL_RGB) Header.Format = IL_BGR; else if (Header.Format == IL_RGBA) Swizzle = IL_TRUE; } #else // Little endian if (Header.BigEndian) { if (Header.Format == IL_RGB) Header.Format = IL_BGR; if (Header.Format == IL_RGBA) Swizzle = IL_TRUE; } #endif switch (Header.Type) { case IL_UNSIGNED_BYTE: if (iread(iCurImage->Data, iCurImage->SizeOfData, 1) != 1) return IL_FALSE; // Swizzle the data from ABGR to RGBA. if (Swizzle) { for (i = 0; i < iCurImage->SizeOfData; i += 4) { iSwapUInt((ILuint*)(iCurImage->Data + i)); } } break; case IL_UNSIGNED_SHORT: for (i = 0; i < iCurImage->SizeOfData; i += 2) { *((ILushort*)(iCurImage->Data + i)) = GetShort(&Header, 0);//GetLittleUShort(); } // Swizzle the data from ABGR to RGBA. if (Swizzle) { ShortPtr = (ILushort*)iCurImage->Data; for (i = 0; i < iCurImage->SizeOfData / 2; i += 4) { TempS = ShortPtr[i]; ShortPtr[i] = ShortPtr[i+3]; ShortPtr[i+3] = TempS; } } break; case IL_FLOAT: for (i = 0; i < iCurImage->SizeOfData; i += 4) { *((ILfloat*)(iCurImage->Data + i)) = GetFloat(&Header, 0);//GetLittleFloat(); } // Swizzle the data from ABGR to RGBA. if (Swizzle) { FloatPtr = (ILfloat*)iCurImage->Data; for (i = 0; i < iCurImage->SizeOfData / 4; i += 4) { TempF = FloatPtr[i]; FloatPtr[i] = FloatPtr[i+3]; FloatPtr[i+3] = TempF; } } break; } return ilFixImage(); }
// Internal function used to load the .hdr. ILboolean iLoadHdrInternal() { HDRHEADER Header; ILfloat *data; ILubyte *scanline; ILuint i, j, e, r, g, b; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } if (!iGetHdrHead(&Header)) { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } if (!iCheckHdr(&Header)) { //iseek(-(ILint)sizeof(HDRHEAD), IL_SEEK_CUR); ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } // Update the current image with the new dimensions if (!ilTexImage(Header.Width, Header.Height, 1, 3, IL_RGB, IL_FLOAT, NULL)) { return IL_FALSE; } iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; //read image data if (iGetHint(IL_MEM_SPEED_HINT) == IL_FASTEST) iPreCache(iCurImage->Width / 8 * iCurImage->Height); data = (ILfloat*)iCurImage->Data; scanline = (ILubyte*)ialloc(Header.Width*4); for (i = 0; i < Header.Height; ++i) { ReadScanline(scanline, Header.Width); //convert hdrs internal format to floats for (j = 0; j < 4*Header.Width; j += 4) { ILuint *ee; ILfloat t, *ff; e = scanline[j + 3]; r = scanline[j + 0]; g = scanline[j + 1]; b = scanline[j + 2]; //t = (float)pow(2.f, ((ILint)e) - 128); if (e != 0) e = (e - 1) << 23; // All this just to avoid stric-aliasing warnings... // was: t = *(ILfloat*)&e ee = &e; ff = (ILfloat*)ee; t = *ff; data[0] = (r/255.0f)*t; data[1] = (g/255.0f)*t; data[2] = (b/255.0f)*t; data += 3; } } iUnCache(); ifree(scanline); return ilFixImage(); }
// Load either a pgm or a ppm ILboolean iLoadPnmInternal() { ILimage *PmImage = NULL; PPMINFO Info; // ILuint LineInc = 0, SmallInc = 0; Info.Type = 0; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } // Find out what type of pgm/ppm this is if (iGetWord() == IL_FALSE) return IL_FALSE; if (SmallBuff[0] != 'P') { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } if (SmallBuff[1] == '1') { Info.Type = IL_PBM_ASCII; } else if (SmallBuff[1] == '2') { Info.Type = IL_PGM_ASCII; } else if (SmallBuff[1] == '3') { Info.Type = IL_PPM_ASCII; } else if (SmallBuff[1] == '4') { Info.Type = IL_PBM_BINARY; if (IsLump) { ilSetError(IL_FORMAT_NOT_SUPPORTED); return IL_FALSE; } } else if (SmallBuff[1] == '5') { Info.Type = IL_PGM_BINARY; } else if (SmallBuff[1] == '6') { Info.Type = IL_PPM_BINARY; } else { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } // Retrieve the width and height if (iGetWord() == IL_FALSE) return IL_FALSE; Info.Width = atoi(SmallBuff); if (Info.Width == 0) { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } if (iGetWord() == IL_FALSE) return IL_FALSE; Info.Height = atoi(SmallBuff); if (Info.Height == 0) { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } // Retrieve the maximum colour component value if (Info.Type != IL_PBM_ASCII && Info.Type != IL_PBM_BINARY) { if (iGetWord() == IL_FALSE) return IL_FALSE; if ((Info.MaxColour = atoi(SmallBuff)) == 0) { ilSetError(IL_INVALID_FILE_HEADER); return IL_FALSE; } } else Info.MaxColour = 1; if (Info.Type == IL_PBM_ASCII || Info.Type == IL_PBM_BINARY || Info.Type == IL_PGM_ASCII || Info.Type == IL_PGM_BINARY) { if (Info.Type == IL_PGM_ASCII) { if (Info.MaxColour < 256) Info.Bpp = 1; else Info.Bpp = 2; } else Info.Bpp = 1; } else { Info.Bpp = 3; } switch (Info.Type) { case IL_PBM_ASCII: case IL_PGM_ASCII: case IL_PPM_ASCII: PmImage = ilReadAsciiPpm(&Info); break; case IL_PBM_BINARY: PmImage = ilReadBitPbm(&Info); break; case IL_PGM_BINARY: case IL_PPM_BINARY: PmImage = ilReadBinaryPpm(&Info); break; default: return IL_FALSE; } if (PmImage == NULL) { iCurImage->Format = ilGetFormatBpp(iCurImage->Bpp); ilSetError(IL_FILE_READ_ERROR); return IL_FALSE; } // Is this conversion needed? Just 0's and 1's shows up as all black if (Info.Type == IL_PBM_ASCII) { PbmMaximize(PmImage); } if (Info.MaxColour > 255) PmImage->Type = IL_UNSIGNED_SHORT; PmImage->Origin = IL_ORIGIN_UPPER_LEFT; if (Info.Type == IL_PBM_ASCII || Info.Type == IL_PBM_BINARY || Info.Type == IL_PGM_ASCII || Info.Type == IL_PGM_BINARY) PmImage->Format = IL_LUMINANCE; else PmImage->Format = IL_RGB; PmImage->Origin = IL_ORIGIN_UPPER_LEFT; ilFixImage(); if (PmImage == NULL) return IL_FALSE; return IL_TRUE; }
// Internal function used to load the Jpeg2000 stream. ILboolean iLoadJp2Internal(jas_stream_t *Stream, ILimage *Image) { jas_image_t *Jp2Image = NULL; jas_matrix_t *origdata; ILuint x, y, c; ILimage *TempImage; // Decode image Jp2Image = jas_image_decode(Stream, -1, 0); if (!Jp2Image) { ilSetError(IL_ILLEGAL_FILE_VALUE); jas_stream_close(Stream); return IL_FALSE; } // We're not supporting anything other than 8 bits/component yet. if (jas_image_cmptprec(Jp2Image, 0) != 8) { jas_image_destroy(Jp2Image); ilSetError(IL_ILLEGAL_FILE_VALUE); return IL_FALSE; } switch (jas_image_numcmpts(Jp2Image)) { case 3: if (Image == NULL) { ilTexImage(jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL); TempImage = iCurImage; } else { ifree(Image->Data); // @TODO: Not really the most efficient way to do this... ilInitImage(Image, jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL); TempImage = Image; } break; case 4: if (Image == NULL) { ilTexImage(jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL); TempImage = iCurImage; } else { ifree(Image->Data); // @TODO: Not really the most efficient way to do this... ilInitImage(Image, jas_image_width(Jp2Image), jas_image_height(Jp2Image), 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL); TempImage = Image; } break; default: jas_image_destroy(Jp2Image); ilSetError(IL_ILLEGAL_FILE_VALUE); return IL_FALSE; } TempImage->Origin = IL_ORIGIN_UPPER_LEFT; // JasPer stores the data channels separately. // I am assuming RGBA format. Is it possible for other formats to be included? for (c = 0; c < TempImage->Bpp; c++) { origdata = jas_matrix_create(TempImage->Height, TempImage->Width); if (!origdata) { ilSetError(IL_LIB_JP2_ERROR); return IL_FALSE; // @TODO: Error } // Have to convert data into an intermediate matrix format. if (jas_image_readcmpt(Jp2Image, c, 0, 0, TempImage->Width, TempImage->Height, origdata)) { return IL_FALSE; } for (y = 0; y < TempImage->Height; y++) { for (x = 0; x < TempImage->Width; x++) { TempImage->Data[y * TempImage->Width * TempImage->Bpp + x * TempImage->Bpp + c] = origdata->data_[y * origdata->numcols_ + x]; } } jas_matrix_destroy(origdata); } jas_image_destroy(Jp2Image); ilFixImage(); return IL_TRUE; }