// Much easier to read - just assemble from planes, no decompression ILboolean iReadNonRleSgi(iSgiHeader *Head) { ILuint i, c; // ILint ChanInt = 0; Unused ILint ChanSize; ILboolean Cache = IL_FALSE; if (!iNewSgi(Head)) { return IL_FALSE; } if (iGetHint(IL_MEM_SPEED_HINT) == IL_FASTEST) { Cache = IL_TRUE; ChanSize = Head->XSize * Head->YSize * Head->Bpc; iPreCache(ChanSize); } for (c = 0; c < iCurImage->Bpp; c++) { for (i = c; i < iCurImage->SizeOfData; i += iCurImage->Bpp) { if (iread(iCurImage->Data + i, 1, 1) != 1) { if (Cache) iUnCache(); return IL_FALSE; } } } if (Cache) iUnCache(); return IL_TRUE; }
static ILuint ReadCompressedChannel(ILimage* image, const ILuint ChanLen, ILuint Size, ILubyte* Channel) { ILuint i; ILint Run; ILboolean PreCache = IL_FALSE; ILbyte HeadByte; if (iGetHint(IL_MEM_SPEED_HINT) == IL_FASTEST) PreCache = IL_TRUE; for (i = 0; i < Size; ) { HeadByte = image->io.getc(&image->io); if (HeadByte >= 0) { // && HeadByte <= 127 if (i + HeadByte > Size) { return READ_COMPRESSED_ERROR_FILE_CORRUPT; } if (image->io.read(&image->io, Channel + i, HeadByte + 1, 1) != 1) { return READ_COMPRESSED_ERROR_FILE_READ_ERROR; } i += HeadByte + 1; } if (HeadByte >= -127 && HeadByte <= -1) { Run = image->io.getc(&image->io); if (Run == IL_EOF) { return READ_COMPRESSED_ERROR_FILE_READ_ERROR; } if (i + (-HeadByte + 1) > Size) { return READ_COMPRESSED_ERROR_FILE_CORRUPT; } memset(Channel + i, Run, -HeadByte + 1); i += -HeadByte + 1; } if (HeadByte == -128) { } // Noop } return READ_COMPRESSED_SUCCESS; }
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; }
// Internal function to uncompress the .pcx (all .pcx files are rle compressed) ILboolean iUncompressPcx(PCXHEAD *Header) { //changed decompression loop 2003-09-01 //From the pcx spec: "There should always //be a decoding break at the end of each scan line. //But there will not be a decoding break at the end of //each plane within each scan line." //This is now handled correctly (hopefully ;) ) ILubyte ByteHead, Colour, *ScanLine /* For all planes */; ILuint ScanLineSize; ILuint c, i, x, y; if (Header->Bpp < 8) { /*ilSetError(IL_FORMAT_NOT_SUPPORTED); return IL_FALSE;*/ return iUncompressSmall(Header); } if (!ilTexImage(Header->Xmax - Header->Xmin + 1, Header->Ymax - Header->Ymin + 1, 1, Header->NumPlanes, 0, IL_UNSIGNED_BYTE, NULL)) return IL_FALSE; iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; switch (iCurImage->Bpp) { case 1: iCurImage->Format = IL_COLOUR_INDEX; iCurImage->Pal.PalType = IL_PAL_RGB24; iCurImage->Pal.PalSize = 256 * 3; // Need to find out for sure... iCurImage->Pal.Palette = (ILubyte*)ialloc(iCurImage->Pal.PalSize); if (iCurImage->Pal.Palette == NULL) { return IL_FALSE; } break; //case 2: // No 16-bit images in the pcx format! case 3: iCurImage->Format = IL_RGB; iCurImage->Pal.Palette = NULL; iCurImage->Pal.PalSize = 0; iCurImage->Pal.PalType = IL_PAL_NONE; break; case 4: iCurImage->Format = IL_RGBA; iCurImage->Pal.Palette = NULL; iCurImage->Pal.PalSize = 0; iCurImage->Pal.PalType = IL_PAL_NONE; break; default: ilSetError(IL_ILLEGAL_FILE_VALUE); return IL_FALSE; } ScanLineSize = iCurImage->Bpp*Header->Bps; ScanLine = (ILubyte*)ialloc(ScanLineSize); if (ScanLine == NULL) { return IL_FALSE; } //changed 2003-09-01 //having the decoding code twice is error-prone, //so I made iUnCache() smart enough to grasp //if iPreCache() wasn't called and call it //anyways. if (iGetHint(IL_MEM_SPEED_HINT) == IL_FASTEST) iPreCache(iCurImage->SizeOfData / 4); for (y = 0; y < iCurImage->Height; y++) { x = 0; //read scanline while (x < ScanLineSize) { if (iread(&ByteHead, 1, 1) != 1) { iUnCache(); goto file_read_error; } if ((ByteHead & 0xC0) == 0xC0) { ByteHead &= 0x3F; if (iread(&Colour, 1, 1) != 1) { iUnCache(); goto file_read_error; } if (x + ByteHead > ScanLineSize) { iUnCache(); goto file_read_error; } for (i = 0; i < ByteHead; i++) { ScanLine[x++] = Colour; } } else { ScanLine[x++] = ByteHead; } } //convert plane-separated scanline into index, rgb or rgba pixels. //there might be a padding byte at the end of each scanline... for (x = 0; x < iCurImage->Width; x++) { for(c = 0; c < iCurImage->Bpp; c++) { iCurImage->Data[y * iCurImage->Bps + x * iCurImage->Bpp + c] = ScanLine[x + c * Header->Bps]; } } } iUnCache(); // Read in the palette if (Header->Version == 5 && iCurImage->Bpp == 1) { x = itell(); if (iread(&ByteHead, 1, 1) == 0) { // If true, assume that we have a luminance image. ilGetError(); // Get rid of the IL_FILE_READ_ERROR. iCurImage->Format = IL_LUMINANCE; if (iCurImage->Pal.Palette) ifree(iCurImage->Pal.Palette); iCurImage->Pal.PalSize = 0; iCurImage->Pal.PalType = IL_PAL_NONE; } else { if (ByteHead != 12) // Some Quake2 .pcx files don't have this byte for some reason. iseek(-1, IL_SEEK_CUR); if (iread(iCurImage->Pal.Palette, 1, iCurImage->Pal.PalSize) != iCurImage->Pal.PalSize) goto file_read_error; } } ifree(ScanLine); return IL_TRUE; file_read_error: ifree(ScanLine); //added 2003-09-01 ilSetError(IL_FILE_READ_ERROR); return IL_FALSE; }
ILimage *iUncompressDcx(DCXHEAD *Header) { ILubyte ByteHead, Colour, *ScanLine = NULL /* Only one plane */; ILuint c, i, x, y;//, Read = 0; ILimage *Image = NULL; if (Header->Bpp < 8) { /*ilSetError(IL_FORMAT_NOT_SUPPORTED); return IL_FALSE;*/ return iUncompressDcxSmall(Header); } 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, Header->NumPlanes, 0, IL_UNSIGNED_BYTE, NULL)) { return IL_FALSE; }*/ Image->Origin = IL_ORIGIN_UPPER_LEFT; ScanLine = (ILubyte*)ialloc(Header->Bps); if (ScanLine == NULL) goto dcx_error; switch (Image->Bpp) { case 1: Image->Format = IL_COLOUR_INDEX; Image->Pal.PalType = IL_PAL_RGB24; Image->Pal.PalSize = 256 * 3; // Need to find out for sure... Image->Pal.Palette = (ILubyte*)ialloc(Image->Pal.PalSize); if (Image->Pal.Palette == NULL) goto dcx_error; break; //case 2: // No 16-bit images in the dcx format! case 3: Image->Format = IL_RGB; Image->Pal.Palette = NULL; Image->Pal.PalSize = 0; Image->Pal.PalType = IL_PAL_NONE; break; case 4: Image->Format = IL_RGBA; Image->Pal.Palette = NULL; Image->Pal.PalSize = 0; Image->Pal.PalType = IL_PAL_NONE; break; default: ilSetError(IL_ILLEGAL_FILE_VALUE); goto dcx_error; } /*StartPos = itell(); Compressed = (ILubyte*)ialloc(Image->SizeOfData * 4 / 3); iread(Compressed, 1, Image->SizeOfData * 4 / 3); for (y = 0; y < Image->Height; y++) { for (c = 0; c < Image->Bpp; c++) { x = 0; while (x < Header->Bps) { ByteHead = Compressed[Read++]; if ((ByteHead & 0xC0) == 0xC0) { ByteHead &= 0x3F; Colour = Compressed[Read++]; for (i = 0; i < ByteHead; i++) { ScanLine[x++] = Colour; } } else { ScanLine[x++] = ByteHead; } } for (x = 0; x < Image->Width; x++) { // 'Cleverly' ignores the pad bytes ;) Image->Data[y * Image->Bps + x * Image->Bpp + c] = ScanLine[x]; } } } ifree(Compressed); iseek(StartPos + Read, IL_SEEK_SET);*/ //changed 2003-09-01 if (iGetHint(IL_MEM_SPEED_HINT) == IL_FASTEST) iPreCache(iCurImage->SizeOfData); //TODO: because the .pcx-code was broken this //code is probably broken, too for (y = 0; y < Image->Height; y++) { for (c = 0; c < Image->Bpp; c++) { x = 0; while (x < Header->Bps) { if (iread(&ByteHead, 1, 1) != 1) { iUnCache(); goto dcx_error; } if ((ByteHead & 0xC0) == 0xC0) { ByteHead &= 0x3F; if (iread(&Colour, 1, 1) != 1) { iUnCache(); goto dcx_error; } for (i = 0; i < ByteHead; i++) { ScanLine[x++] = Colour; } } else { ScanLine[x++] = ByteHead; } } for (x = 0; x < Image->Width; x++) { // 'Cleverly' ignores the pad bytes ;) Image->Data[y * Image->Bps + x * Image->Bpp + c] = ScanLine[x]; } } } iUnCache(); ifree(ScanLine); // Read in the palette if (Image->Bpp == 1) { ByteHead = igetc(); // the value 12, because it signals there's a palette for some reason... // We should do a check to make certain it's 12... if (ByteHead != 12) iseek(-1, IL_SEEK_CUR); if (iread(Image->Pal.Palette, 1, Image->Pal.PalSize) != Image->Pal.PalSize) { ilCloseImage(Image); return NULL; } } return Image; dcx_error: ifree(ScanLine); ilCloseImage(Image); return NULL; }
// Internal function used to save the Pnm. ILboolean iSavePnmInternal() { ILuint Bpp, MaxVal = UCHAR_MAX, i = 0, j, k; ILenum Type = 0; ILuint LinePos = 0; // Cannot exceed 70 for pnm's! ILboolean Binary; ILimage *TempImage; ILubyte *TempData; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } if (iCheckExtension(FName, IL_TEXT("pbm"))) Type = IL_PBM_ASCII; else if (iCheckExtension(FName, IL_TEXT("pgm"))) Type = IL_PGM_ASCII; else if (iCheckExtension(FName, IL_TEXT("ppm"))) Type = IL_PPM_ASCII; else Type = IL_PPM_ASCII; /*if (!Type) { ilSetError(IL_INVALID_EXTENSION); return IL_FALSE; }*/ if (iGetHint(IL_COMPRESSION_HINT) == IL_USE_COMPRESSION) { Type += 3; Binary = IL_TRUE; } else { Binary = IL_FALSE; } if (iCurImage->Type == IL_UNSIGNED_BYTE) { MaxVal = UCHAR_MAX; } else if (iCurImage->Type == IL_UNSIGNED_SHORT) { MaxVal = USHRT_MAX; } else { ilSetError(IL_FORMAT_NOT_SUPPORTED); return IL_FALSE; } if (MaxVal > UCHAR_MAX && Type >= IL_PBM_BINARY) { // binary cannot be higher than 255 ilSetError(IL_FORMAT_NOT_SUPPORTED); return IL_FALSE; } switch (Type) { case IL_PBM_ASCII: Bpp = 1; ilprintf("P1\n"); TempImage = iConvertImage(iCurImage, IL_LUMINANCE, IL_UNSIGNED_BYTE); break; //case IL_PBM_BINARY: // Don't want to mess with saving bits just yet... //Bpp = 1; //ilprintf("P4\n"); //break; case IL_PBM_BINARY: ilSetError(IL_FORMAT_NOT_SUPPORTED); return IL_FALSE; case IL_PGM_ASCII: Bpp = 1; ilprintf("P2\n"); TempImage = iConvertImage(iCurImage, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE); break; case IL_PGM_BINARY: Bpp = 1; ilprintf("P5\n"); TempImage = iConvertImage(iCurImage, IL_COLOUR_INDEX, IL_UNSIGNED_BYTE); break; case IL_PPM_ASCII: Bpp = 3; ilprintf("P3\n"); TempImage = iConvertImage(iCurImage, IL_RGB, IL_UNSIGNED_BYTE); break; case IL_PPM_BINARY: Bpp = 3; ilprintf("P6\n"); TempImage = iConvertImage(iCurImage, IL_RGB, IL_UNSIGNED_BYTE); break; default: ilSetError(IL_INTERNAL_ERROR); return IL_FALSE; } if (TempImage == NULL) return IL_FALSE; if (Bpp != TempImage->Bpp) { ilSetError(IL_INVALID_CONVERSION); return IL_FALSE; } if (TempImage->Origin != IL_ORIGIN_UPPER_LEFT) { TempData = iGetFlipped(TempImage); if (TempData == NULL) { ilCloseImage(TempImage); return IL_FALSE; } } else { TempData = TempImage->Data; } ilprintf("%d %d\n", TempImage->Width, TempImage->Height); if (Type != IL_PBM_BINARY && Type != IL_PBM_ASCII) // not needed for .pbm's (only 0 and 1) ilprintf("%d\n", MaxVal); while (i < TempImage->SizeOfPlane) { for (j = 0; j < Bpp; j++) { if (Binary) { if (Type == IL_PBM_BINARY) { iputc((ILubyte)(TempData[i] > 127 ? 1 : 0)); } else { iputc(TempData[i]); } } else { if (TempImage->Type == IL_UNSIGNED_BYTE) k = TempData[i]; else // IL_UNSIGNED_SHORT k = *((ILushort*)TempData + i); if (Type == IL_PBM_ASCII) { LinePos += ilprintf("%d ", TempData[i] > 127 ? 1 : 0); } else { LinePos += ilprintf("%d ", TempData[i]); } } if (TempImage->Type == IL_UNSIGNED_SHORT) i++; i++; } if (LinePos > 65) { // Just a good number =] ilprintf("\n"); LinePos = 0; } } if (TempImage->Origin != IL_ORIGIN_UPPER_LEFT) ifree(TempData); ilCloseImage(TempImage); return IL_TRUE; }
// 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(); }
// Internal function used to save the Tiff. ILboolean iSaveTiffInternal(char *Filename) { ILenum Format; ILenum Compression; ILuint ixLine; TIFF *File; char Description[512]; ILimage *TempImage; if(iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } if (iGetHint(IL_COMPRESSION_HINT) == IL_USE_COMPRESSION) Compression = COMPRESSION_PACKBITS; else Compression = COMPRESSION_NONE; if (iCurImage->Format == IL_COLOUR_INDEX) { if (ilGetBppPal(iCurImage->Pal.PalType) == 4) // Preserve the alpha. TempImage = iConvertImage(iCurImage, IL_RGBA, IL_UNSIGNED_BYTE); else TempImage = iConvertImage(iCurImage, IL_RGB, IL_UNSIGNED_BYTE); if (TempImage == NULL) { return IL_FALSE; } } else { TempImage = iCurImage; } File = TIFFOpen(Filename, "w"); //File = iTIFFOpen("w"); if (File == NULL) { ilSetError(IL_COULD_NOT_OPEN_FILE); return IL_FALSE; } sprintf(Description, "Tiff generated by %s", ilGetString(IL_VERSION_NUM)); TIFFSetField(File, TIFFTAG_IMAGEWIDTH, TempImage->Width); TIFFSetField(File, TIFFTAG_IMAGELENGTH, TempImage->Height); TIFFSetField(File, TIFFTAG_COMPRESSION, Compression); TIFFSetField(File, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); TIFFSetField(File, TIFFTAG_BITSPERSAMPLE, TempImage->Bpc << 3); TIFFSetField(File, TIFFTAG_SAMPLESPERPIXEL, TempImage->Bpp); TIFFSetField(File, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); TIFFSetField(File, TIFFTAG_ROWSPERSTRIP, 1); TIFFSetField(File, TIFFTAG_SOFTWARE, ilGetString(IL_VERSION_NUM)); /*TIFFSetField(File, TIFFTAG_DOCUMENTNAME, iGetString(IL_TIF_DOCUMENTNAME_STRING) ? iGetString(IL_TIF_DOCUMENTNAME_STRING) : FileName);*/ if (iGetString(IL_TIF_DOCUMENTNAME_STRING)) TIFFSetField(File, TIFFTAG_DOCUMENTNAME, iGetString(IL_TIF_DOCUMENTNAME_STRING)); if (iGetString(IL_TIF_AUTHNAME_STRING)) TIFFSetField(File, TIFFTAG_ARTIST, iGetString(IL_TIF_AUTHNAME_STRING)); if (iGetString(IL_TIF_HOSTCOMPUTER_STRING)) TIFFSetField(File, TIFFTAG_HOSTCOMPUTER, iGetString(IL_TIF_HOSTCOMPUTER_STRING)); if (iGetString(IL_TIF_DESCRIPTION_STRING)) TIFFSetField(File, TIFFTAG_IMAGEDESCRIPTION, iGetString(IL_TIF_DESCRIPTION_STRING)); TIFFSetField(File, TIFFTAG_DATETIME, iMakeString()); // 24/4/2003 // Orientation flag is not always supported ( Photoshop, ...), orient the image data // and set it always to normal view TIFFSetField(File, TIFFTAG_ORIENTATION,ORIENTATION_TOPLEFT ); if( TempImage->Origin != IL_ORIGIN_UPPER_LEFT ) { ILubyte *Data = iGetFlipped(TempImage); ifree( (void*)TempImage->Data ); TempImage->Data = Data; } /* TIFFSetField(File, TIFFTAG_ORIENTATION, TempImage->Origin == IL_ORIGIN_UPPER_LEFT ? ORIENTATION_TOPLEFT : ORIENTATION_BOTLEFT); */ Format = TempImage->Format; if (Format == IL_BGR || Format == IL_BGRA) ilSwapColours(); for (ixLine = 0; ixLine < TempImage->Height; ++ixLine) { if (TIFFWriteScanline(File, TempImage->Data + ixLine * TempImage->Bps, ixLine, 0) < 0) { TIFFClose(File); ilSetError(IL_LIB_TIFF_ERROR); return IL_FALSE; } } if (Format == IL_BGR || Format == IL_BGRA) ilSwapColours(); if (TempImage != iCurImage) ilCloseImage(TempImage); TIFFClose(File); return IL_TRUE; }