From d7a5c33776635e92548c8d5494d1c8060318144c Mon Sep 17 00:00:00 2001 From: Denton Woods Date: Sat, 21 Jan 2017 18:46:48 -0600 Subject: - Added Scitex .ct support - Added .blp validation checks --- DevIL/include/IL/il.h | 1 + DevIL/src-IL/include/il_internal.h | 12 +- DevIL/src-IL/src/il_io.cpp | 59 ++++++++ DevIL/src-IL/src/il_pnm.cpp | 4 +- DevIL/src-IL/src/il_scitex.cpp | 296 +++++++++++++++++++++++++++++++++++++ 5 files changed, 367 insertions(+), 5 deletions(-) create mode 100644 DevIL/src-IL/src/il_scitex.cpp diff --git a/DevIL/include/IL/il.h b/DevIL/include/IL/il.h index 47dfcd7d..d3bf65db 100644 --- a/DevIL/include/IL/il.h +++ b/DevIL/include/IL/il.h @@ -242,6 +242,7 @@ typedef long long unsigned int ILuint64; #define IL_UTX 0x0451 //!< Unreal (and Unreal Tournament) Texture - .utx extension #define IL_MP3 0x0452 //!< MPEG-1 Audio Layer 3 - .mp3 extension #define IL_KTX 0x0453 //!< Khronos Texture - .ktx extension +#define IL_SCITEX 0x0454 //!< Scitex Continuous Tone - .ch, .ct, and .sct extensions #define IL_JASC_PAL 0x0475 //!< PaintShop Pro Palette diff --git a/DevIL/src-IL/include/il_internal.h b/DevIL/src-IL/include/il_internal.h index 0ad1e413..4ea71a45 100644 --- a/DevIL/src-IL/include/il_internal.h +++ b/DevIL/src-IL/include/il_internal.h @@ -436,12 +436,18 @@ ILboolean ilLoadRawL(const void *Lump, ILuint Size); ILboolean ilSaveRaw(ILconst_string FileName); ILuint ilSaveRawF(ILHANDLE File); ILuint ilSaveRawL(void *Lump, ILuint Size); -ILboolean ilLoadRot(ILconst_string FileName); -ILboolean ilLoadRotF(ILHANDLE File); -ILboolean ilLoadRotL(const void *Lump, ILuint Size); ILboolean ilIsValidRot(ILconst_string FileName); ILboolean ilIsValidRotF(ILHANDLE File); ILboolean ilIsValidRotL(const void *Lump, ILuint Size); +ILboolean ilLoadRot(ILconst_string FileName); +ILboolean ilLoadRotF(ILHANDLE File); +ILboolean ilLoadRotL(const void *Lump, ILuint Size); +ILboolean ilIsValidScitex(ILconst_string FileName); +ILboolean ilIsValidScitexF(ILHANDLE File); +ILboolean ilIsValidScitexL(const void *Lump, ILuint Size); +ILboolean ilLoadScitex(ILconst_string FileName); +ILboolean ilLoadScitexF(ILHANDLE File); +ILboolean ilLoadScitexL(const void *Lump, ILuint Size); ILboolean ilIsValidSgi(ILconst_string FileName); ILboolean ilIsValidSgiF(ILHANDLE File); ILboolean ilIsValidSgiL(const void *Lump, ILuint Size); diff --git a/DevIL/src-IL/src/il_io.cpp b/DevIL/src-IL/src/il_io.cpp index cc40de5a..01f324dd 100644 --- a/DevIL/src-IL/src/il_io.cpp +++ b/DevIL/src-IL/src/il_io.cpp @@ -79,6 +79,8 @@ ILenum ILAPIENTRY ilTypeFromExt(ILconst_string FileName) Type = IL_BLP; else if (!iStrCmp(Ext, IL_TEXT("cut"))) Type = IL_CUT; + else if (!iStrCmp(Ext, IL_TEXT("ch")) || !iStrCmp(Ext, IL_TEXT("ct")) || !iStrCmp(Ext, IL_TEXT("sct"))) + Type = IL_SCITEX; else if (!iStrCmp(Ext, IL_TEXT("dcm")) || !iStrCmp(Ext, IL_TEXT("dicom"))) Type = IL_DICOM; else if (!iStrCmp(Ext, IL_TEXT("dpx"))) @@ -214,6 +216,11 @@ ILenum ILAPIENTRY ilDetermineTypeF(ILHANDLE File) return IL_BMP; #endif + #ifndef IL_NO_BLP + if (ilIsValidBlpF(File)) + return IL_BLP; + #endif + #ifndef IL_NO_EXR if (ilIsValidExrF(File)) return IL_EXR; @@ -299,6 +306,11 @@ ILenum ILAPIENTRY ilDetermineTypeF(ILHANDLE File) return IL_SGI; #endif + #ifndef IL_NO_SCITEX + if (ilIsValidScitexF(File)) + return IL_SCITEX; + #endif + #ifndef IL_NO_SUN if (ilIsValidSunF(File)) return IL_SUN; @@ -360,6 +372,11 @@ ILenum ILAPIENTRY ilDetermineTypeL(const void *Lump, ILuint Size) return IL_BMP; #endif + #ifndef IL_NO_BLP + if (ilIsValidBlpL(Lump, Size)) + return IL_BLP; + #endif + #ifndef IL_NO_EXR if (ilIsValidExrL(Lump, Size)) return IL_EXR; @@ -440,6 +457,11 @@ ILenum ILAPIENTRY ilDetermineTypeL(const void *Lump, ILuint Size) return IL_PSP; #endif + #ifndef IL_NO_SCITEX + if (ilIsValidScitexL(Lump, Size)) + return IL_SCITEX; + #endif + #ifndef IL_NO_SGI if (ilIsValidSgiL(Lump, Size)) return IL_SGI; @@ -515,6 +537,11 @@ ILboolean ILAPIENTRY ilIsValid(ILenum Type, ILconst_string FileName) return ilIsValidBmp(FileName); #endif + #ifndef IL_NO_BLP + case IL_BLP: + return ilIsValidBlp(FileName); + #endif + #ifndef IL_NO_DICOM case IL_DICOM: return ilIsValidDicom(FileName); @@ -600,6 +627,11 @@ ILboolean ILAPIENTRY ilIsValid(ILenum Type, ILconst_string FileName) return ilIsValidPsp(FileName); #endif + #ifndef IL_NO_SCITEX + case IL_SCITEX: + return ilIsValidScitex(FileName); + #endif + #ifndef IL_NO_SGI case IL_SGI: return ilIsValidSgi(FileName); @@ -665,6 +697,11 @@ ILboolean ILAPIENTRY ilIsValidF(ILenum Type, ILHANDLE File) return ilIsValidPngF(File); #endif + #ifndef IL_NO_BLP + case IL_BLP: + return ilIsValidBlpF(File); + #endif + #ifndef IL_NO_BMP case IL_BMP: return ilIsValidBmpF(File); @@ -755,6 +792,11 @@ ILboolean ILAPIENTRY ilIsValidF(ILenum Type, ILHANDLE File) return ilIsValidPspF(File); #endif + #ifndef IL_NO_SCITEX + case IL_SCITEX: + return ilIsValidScitexF(File); + #endif + #ifndef IL_NO_SGI case IL_SGI: return ilIsValidSgiF(File); @@ -825,6 +867,11 @@ ILboolean ILAPIENTRY ilIsValidL(ILenum Type, void *Lump, ILuint Size) return ilIsValidBmpL(Lump, Size); #endif + #ifndef IL_NO_BLP + case IL_BLP: + return ilIsValidBlpL(Lump, Size); + #endif + #ifndef IL_NO_DICOM case IL_DICOM: return ilIsValidDicomL(Lump, Size); @@ -910,6 +957,11 @@ ILboolean ILAPIENTRY ilIsValidL(ILenum Type, void *Lump, ILuint Size) return ilIsValidPspL(Lump, Size); #endif + #ifndef IL_NO_SCITEX + case IL_SCITEX: + return ilIsValidScitexL(Lump, Size); + #endif + #ifndef IL_NO_SGI case IL_SGI: return ilIsValidSgiL(Lump, Size); @@ -1879,6 +1931,13 @@ ILboolean ILAPIENTRY ilLoadImage(ILconst_string FileName) } #endif + #ifndef IL_NO_SCITEX + if (!iStrCmp(Ext, IL_TEXT("ch")) || !iStrCmp(Ext, IL_TEXT("ct")) || !iStrCmp(Ext, IL_TEXT("sct"))) { + bRet = ilLoadScitex(FileName); + goto finish; + } + #endif + #ifndef IL_NO_DPX if (!iStrCmp(Ext, IL_TEXT("dpx"))) { bRet = ilLoadDpx(FileName); diff --git a/DevIL/src-IL/src/il_pnm.cpp b/DevIL/src-IL/src/il_pnm.cpp index 794f6e55..2b057035 100644 --- a/DevIL/src-IL/src/il_pnm.cpp +++ b/DevIL/src-IL/src/il_pnm.cpp @@ -551,10 +551,10 @@ ILboolean ilReadPam() if (iread(iCurImage->Data, 1, Size) != Size) { ilCloseImage(iCurImage); - return NULL; + return IL_FALSE; } - return IL_TRUE; + return ilFixImage(); } diff --git a/DevIL/src-IL/src/il_scitex.cpp b/DevIL/src-IL/src/il_scitex.cpp new file mode 100644 index 00000000..c2a863d9 --- /dev/null +++ b/DevIL/src-IL/src/il_scitex.cpp @@ -0,0 +1,296 @@ +//----------------------------------------------------------------------------- +// +// ImageLib Sources +// Copyright (C) 2000-2017 by Denton Woods +// Last modified: 01/21/2017 +// +// Filename: src-IL/src/il_scitex.cpp +// +// Description: Reads from a Scitex Continuous Tone (.ct) file. +// Specifications were found at http://fileformats.archiveteam.org/wiki/Scitex_CT +// and http://web.archive.org/web/20130506073138/http://electricmessiah.org/press/the-scitex-ct-file-format/ +// +//----------------------------------------------------------------------------- + + +#include "il_internal.h" +#ifndef IL_NO_SCITEX +//#include "il_scitex.h" + + +typedef struct SCITEXHEAD +{ + ILubyte Comment[80]; + ILubyte Sig[2]; // Signature, should be "CT" + ILubyte Units; // 0 for mm, 1 for inches + ILubyte NumChans; // Number of channels + ILushort ColorModel; // Color model (7=RGB, 8=GREYSCALE, 15=CMYK) + ILfloat HeightUnits; // Physical height + ILfloat WidthUnits; // Physical width + ILuint HeightPixels; + ILuint WidthPixels; +} SCITEXHEAD; + +ILboolean iIsValidScitex(void); +ILboolean iLoadScitexInternal(void); +ILboolean iCheckScitex(SCITEXHEAD *Header); + + +// Internal function used to get the Scitex header from the current file. +ILboolean iGetScitexHead(SCITEXHEAD *Header) +{ + char HeightUnits[15], WidthUnits[15], HeightPixels[13], WidthPixels[13]; + + if (iread(Header->Comment, 1, 80) != 80) + return IL_FALSE; + if (iread(Header->Sig, 1, 2) != 2) + return IL_FALSE; + if (iseek(942, IL_SEEK_CUR) == -1) + return IL_FALSE; + Header->Units = igetc(); + Header->NumChans = igetc(); + Header->ColorModel = GetBigUShort(); + if (iread(&HeightUnits, 1, 14) != 14) + return IL_FALSE; + if (iread(&WidthUnits, 1, 14) != 14) + return IL_FALSE; + if (iread(&HeightPixels, 1, 12) != 12) + return IL_FALSE; + if (iread(&WidthPixels, 1, 12) != 12) + return IL_FALSE; + + HeightUnits[14] = NULL; + WidthUnits[14] = NULL; + HeightPixels[12] = NULL; + WidthPixels[12] = NULL; + + Header->HeightUnits = (ILfloat)atof(HeightUnits); + Header->WidthUnits = (ILfloat)atof(WidthUnits); + Header->HeightPixels = (ILint)atoi(HeightPixels); + Header->WidthPixels = (ILint)atof(WidthPixels); + + switch (Header->ColorModel) + { + case 7: + if (Header->NumChans != 3) + return IL_FALSE; + break; + case 8: + if (Header->NumChans != 1) + return IL_FALSE; + break; + //case 15: + //default: + } + + return IL_TRUE; +} + + +//! Checks if the file specified in FileName is a valid BLP file. +ILboolean ilIsValidScitex(ILconst_string FileName) +{ + ILHANDLE ScitexFile; + ILboolean bScitex = IL_FALSE; + + if (!iCheckExtension(FileName, IL_TEXT("ct"))) { + ilSetError(IL_INVALID_EXTENSION); + return bScitex; + } + + ScitexFile = iopenr(FileName); + if (ScitexFile == NULL) { + ilSetError(IL_COULD_NOT_OPEN_FILE); + return bScitex; + } + + bScitex = ilIsValidScitexF(ScitexFile); + icloser(ScitexFile); + + return bScitex; +} + + +//! Checks if the ILHANDLE contains a valid Scitex file at the current position. +ILboolean ilIsValidScitexF(ILHANDLE File) +{ + ILuint FirstPos; + ILboolean bRet; + + iSetInputFile(File); + FirstPos = itell(); + bRet = iIsValidScitex(); + iseek(FirstPos, IL_SEEK_SET); + + return bRet; +} + + +//! Checks if Lump is a valid BLP lump. +ILboolean ilIsValidScitexL(const void *Lump, ILuint Size) +{ + iSetInputLump(Lump, Size); + return iIsValidScitex(); +} + + +// Internal function to get the header and check it. +ILboolean iIsValidScitex(void) +{ + SCITEXHEAD Header; + + if (!iGetScitexHead(&Header)) + return IL_FALSE; + iseek(-2048, IL_SEEK_CUR); + + return iCheckScitex(&Header); +} + + +// Internal function used to check if the HEADER is a valid BLP header. +ILboolean iCheckScitex(SCITEXHEAD *Header) +{ + // The file signature is 'CT'. + if (Header->Sig[0] != 'C' || Header->Sig[1] != 'T') + return IL_FALSE; + if (Header->Units != 0 && Header->Units != 1) + return IL_FALSE; + //@TODO: Handle CMYK version + if (Header->ColorModel != 7 && Header->ColorModel != 8 /*&& Header->ColorModel != 15*/) + return IL_FALSE; + if (Header->HeightUnits <= 0 || Header->WidthUnits <= 0) + return IL_FALSE; + if (Header->HeightPixels <= 0 || Header->WidthPixels <= 0) + return IL_FALSE; + + return IL_TRUE; +} + + + +//! Reads a BLP file +ILboolean ilLoadScitex(ILconst_string FileName) +{ + ILHANDLE ScitexFile; + ILboolean bScitex = IL_FALSE; + + ScitexFile = iopenr(FileName); + if (ScitexFile == NULL) { + ilSetError(IL_COULD_NOT_OPEN_FILE); + return bScitex; + } + + bScitex = ilLoadScitexF(ScitexFile); + icloser(ScitexFile); + + return bScitex; +} + + +//! Reads an already-opened BLP file +ILboolean ilLoadScitexF(ILHANDLE File) +{ + ILuint FirstPos; + ILboolean bRet; + + iSetInputFile(File); + FirstPos = itell(); + bRet = iLoadScitexInternal(); + iseek(FirstPos, IL_SEEK_SET); + + return bRet; +} + + +//! Reads from a memory "lump" that contains a BLP +ILboolean ilLoadScitexL(const void *Lump, ILuint Size) +{ + iSetInputLump(Lump, Size); + return iLoadScitexInternal(); +} + + +// Internal function used to load the BLP. +ILboolean iLoadScitexInternal(void) +{ + SCITEXHEAD Header; + ILuint Pos = 0; + ILubyte *RowData; + + if (iCurImage == NULL) { + ilSetError(IL_ILLEGAL_OPERATION); + return IL_FALSE; + } + + if (!iGetScitexHead(&Header)) { + ilSetError(IL_INVALID_FILE_HEADER); + return IL_FALSE; + } + if (!iCheckScitex(&Header)) { + return IL_FALSE; + } + + iseek(2048, IL_SEEK_SET); + RowData = (ILubyte*)ialloc(Header.WidthPixels); + if (RowData == NULL) + return IL_FALSE; + + switch (Header.ColorModel) + { + case 7: + if (!ilTexImage(Header.WidthPixels, Header.HeightPixels, 1, Header.NumChans, 0, IL_UNSIGNED_BYTE, NULL)) + { + ifree(RowData); + return IL_FALSE; + } + iCurImage->Format = IL_RGB; + + for (ILuint h = 0; h < iCurImage->Height; h++) + { + for (ILuint c = 0; c < iCurImage->Bpp; c++) + { + if (iread(RowData, 1, Header.WidthPixels) != Header.WidthPixels) + { + ifree(RowData); + return IL_FALSE; + } + for (ILuint w = 0; w < iCurImage->Width; w++) + { + iCurImage->Data[Pos + w * 3 + c] = RowData[w]; + } + if (iCurImage->Width % 2 != 0) // Pads to even width + igetc(); + } + Pos += Header.WidthPixels * 3; + } + break; + + case 8: + if (!ilTexImage(Header.WidthPixels, Header.HeightPixels, 1, Header.NumChans, 0, IL_UNSIGNED_BYTE, NULL)) + { + ifree(RowData); + return IL_FALSE; + } + iCurImage->Format = IL_LUMINANCE; + + for (ILuint h = 0; h < iCurImage->Height; h++) + { + iread(iCurImage->Data + Pos, 1, iCurImage->Width); + if (iCurImage->Width % 2 != 0) // Pads to even width + igetc(); + Pos += Header.WidthPixels; + } + + break; + + //case 15: + //default: + } + iCurImage->Origin = IL_ORIGIN_UPPER_LEFT; + + return ilFixImage(); +}; + + + +#endif//IL_NO_SCITEX -- cgit v1.2.1