X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=utilities%2FCxImage%2Fximajpg.h;h=de7835a6d84476a889fb0561d95f8930d71787f5;hb=refs%2Fheads%2FGammaIndex3D;hp=899c6bc123beb2fd3e268809850736faa8b9b7d4;hpb=19d5db17f1c0e98cf84a6cb83643404a550a12a4;p=clitk.git diff --git a/utilities/CxImage/ximajpg.h b/utilities/CxImage/ximajpg.h index 899c6bc..de7835a 100644 --- a/utilities/CxImage/ximajpg.h +++ b/utilities/CxImage/ximajpg.h @@ -1,317 +1,317 @@ -/* - * File: ximajpg.h - * Purpose: JPG Image Class Loader and Writer - */ -/* ========================================================== - * CxImageJPG (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it - * For conditions of distribution and use, see copyright notice in ximage.h - * - * Special thanks to Troels Knakkergaard for new features, enhancements and bugfixes - * - * Special thanks to Chris Shearer Cooper for CxFileJpg tips & code - * - * EXIF support based on jhead-1.8 by Matthias Wandel - * - * original CImageJPG and CImageIterator implementation are: - * Copyright: (c) 1995, Alejandro Aguilar Sierra - * - * This software is based in part on the work of the Independent JPEG Group. - * Copyright (C) 1991-1998, Thomas G. Lane. - * ========================================================== - */ -#if !defined(__ximaJPEG_h) -#define __ximaJPEG_h - -#include "ximage.h" - -#if CXIMAGE_SUPPORT_JPG - -#define CXIMAGEJPG_SUPPORT_EXIF 1 - -extern "C" { - #include "../jpeg/jpeglib.h" - #include "../jpeg/jerror.h" -} - -class DLL_EXP CxImageJPG: public CxImage -{ -public: - CxImageJPG(); - ~CxImageJPG(); - -// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_JPG);} -// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_JPG);} - bool Decode(CxFile * hFile); - bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); } - -#if CXIMAGE_SUPPORT_ENCODE - bool Encode(CxFile * hFile); - bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); } -#endif // CXIMAGE_SUPPORT_ENCODE - -/* - * EXIF support based on jhead-1.8 by Matthias Wandel - */ - -#if CXIMAGEJPG_SUPPORT_EXIF - -#define MAX_COMMENT 1000 -#define MAX_SECTIONS 20 - -typedef struct tag_ExifInfo { - char Version [5]; - char CameraMake [32]; - char CameraModel [40]; - char DateTime [20]; - int Height, Width; - int Orientation; - int IsColor; - int Process; - int FlashUsed; - float FocalLength; - float ExposureTime; - float ApertureFNumber; - float Distance; - float CCDWidth; - float ExposureBias; - int Whitebalance; - int MeteringMode; - int ExposureProgram; - int ISOequivalent; - int CompressionLevel; - float FocalplaneXRes; - float FocalplaneYRes; - float FocalplaneUnits; - float Xresolution; - float Yresolution; - float ResolutionUnit; - float Brightness; - char Comments[MAX_COMMENT]; - - unsigned char * ThumbnailPointer; /* Pointer at the thumbnail */ - unsigned ThumbnailSize; /* Size of thumbnail. */ - - bool IsExif; -} EXIFINFO; - -//-------------------------------------------------------------------------- -// JPEG markers consist of one or more 0xFF bytes, followed by a marker -// code byte (which is not an FF). Here are the marker codes of interest -// in this program. (See jdmarker.c for a more complete list.) -//-------------------------------------------------------------------------- - -#define M_SOF0 0xC0 // Start Of Frame N -#define M_SOF1 0xC1 // N indicates which compression process -#define M_SOF2 0xC2 // Only SOF0-SOF2 are now in common use -#define M_SOF3 0xC3 -#define M_SOF5 0xC5 // NB: codes C4 and CC are NOT SOF markers -#define M_SOF6 0xC6 -#define M_SOF7 0xC7 -#define M_SOF9 0xC9 -#define M_SOF10 0xCA -#define M_SOF11 0xCB -#define M_SOF13 0xCD -#define M_SOF14 0xCE -#define M_SOF15 0xCF -#define M_SOI 0xD8 // Start Of Image (beginning of datastream) -#define M_EOI 0xD9 // End Of Image (end of datastream) -#define M_SOS 0xDA // Start Of Scan (begins compressed data) -#define M_JFIF 0xE0 // Jfif marker -#define M_EXIF 0xE1 // Exif marker -#define M_COM 0xFE // COMment - -#define PSEUDO_IMAGE_MARKER 0x123; // Extra value. - -#define EXIF_READ_EXIF 0x01 -#define EXIF_READ_IMAGE 0x02 -#define EXIF_READ_ALL 0x03 - -class DLL_EXP CxExifInfo -{ - -typedef struct tag_Section_t{ - BYTE* Data; - int Type; - unsigned Size; -} Section_t; - -public: - EXIFINFO* m_exifinfo; - char m_szLastError[256]; - CxExifInfo(EXIFINFO* info = NULL); - ~CxExifInfo(); - bool DecodeExif(CxFile * hFile, int nReadMode = EXIF_READ_EXIF); - bool EncodeExif(CxFile * hFile); - void DiscardAllButExif(); -protected: - bool process_EXIF(unsigned char * CharBuf, unsigned int length); - void process_COM (const BYTE * Data, int length); - void process_SOFn (const BYTE * Data, int marker); - int Get16u(void * Short); - int Get16m(void * Short); - long Get32s(void * Long); - unsigned long Get32u(void * Long); - double ConvertAnyFormat(void * ValuePtr, int Format); - void* FindSection(int SectionType); - bool ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength, - EXIFINFO * const pInfo, unsigned char ** const LastExifRefdP, int NestingLevel=0); - int ExifImageWidth; - int MotorolaOrder; - Section_t Sections[MAX_SECTIONS]; - int SectionsRead; - bool freeinfo; -}; - - CxExifInfo* m_exif; - EXIFINFO m_exifinfo; - bool DecodeExif(CxFile * hFile); - bool DecodeExif(FILE * hFile) { CxIOFile file(hFile); return DecodeExif(&file); } - -#endif //CXIMAGEJPG_SUPPORT_EXIF - -//////////////////////////////////////////////////////////////////////////////////////// -////////////////////// C x F i l e J p g //////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - -// thanks to Chris Shearer Cooper -class CxFileJpg : public jpeg_destination_mgr, public jpeg_source_mgr - { -public: - enum { eBufSize = 4096 }; - - CxFileJpg(CxFile* pFile) - { - m_pFile = pFile; - - init_destination = InitDestination; - empty_output_buffer = EmptyOutputBuffer; - term_destination = TermDestination; - - init_source = InitSource; - fill_input_buffer = FillInputBuffer; - skip_input_data = SkipInputData; - resync_to_restart = jpeg_resync_to_restart; // use default method - term_source = TermSource; - next_input_byte = NULL; //* => next byte to read from buffer - bytes_in_buffer = 0; //* # of bytes remaining in buffer - - m_pBuffer = new unsigned char[eBufSize]; - } - ~CxFileJpg() - { - delete [] m_pBuffer; - } - - static void InitDestination(j_compress_ptr cinfo) - { - CxFileJpg* pDest = (CxFileJpg*)cinfo->dest; - pDest->next_output_byte = pDest->m_pBuffer; - pDest->free_in_buffer = eBufSize; - } - - static boolean EmptyOutputBuffer(j_compress_ptr cinfo) - { - CxFileJpg* pDest = (CxFileJpg*)cinfo->dest; - if (pDest->m_pFile->Write(pDest->m_pBuffer,1,eBufSize)!=(size_t)eBufSize) - ERREXIT(cinfo, JERR_FILE_WRITE); - pDest->next_output_byte = pDest->m_pBuffer; - pDest->free_in_buffer = eBufSize; - return TRUE; - } - - static void TermDestination(j_compress_ptr cinfo) - { - CxFileJpg* pDest = (CxFileJpg*)cinfo->dest; - size_t datacount = eBufSize - pDest->free_in_buffer; - /* Write any data remaining in the buffer */ - if (datacount > 0) { - if (!pDest->m_pFile->Write(pDest->m_pBuffer,1,datacount)) - ERREXIT(cinfo, JERR_FILE_WRITE); - } - pDest->m_pFile->Flush(); - /* Make sure we wrote the output file OK */ - if (pDest->m_pFile->Error()) ERREXIT(cinfo, JERR_FILE_WRITE); - return; - } - - static void InitSource(j_decompress_ptr cinfo) - { - CxFileJpg* pSource = (CxFileJpg*)cinfo->src; - pSource->m_bStartOfFile = TRUE; - } - - static boolean FillInputBuffer(j_decompress_ptr cinfo) - { - size_t nbytes; - CxFileJpg* pSource = (CxFileJpg*)cinfo->src; - nbytes = pSource->m_pFile->Read(pSource->m_pBuffer,1,eBufSize); - if (nbytes <= 0){ - if (pSource->m_bStartOfFile) //* Treat empty input file as fatal error - ERREXIT(cinfo, JERR_INPUT_EMPTY); - WARNMS(cinfo, JWRN_JPEG_EOF); - // Insert a fake EOI marker - pSource->m_pBuffer[0] = (JOCTET) 0xFF; - pSource->m_pBuffer[1] = (JOCTET) JPEG_EOI; - nbytes = 2; - } - pSource->next_input_byte = pSource->m_pBuffer; - pSource->bytes_in_buffer = nbytes; - pSource->m_bStartOfFile = FALSE; - return TRUE; - } - - static void SkipInputData(j_decompress_ptr cinfo, long num_bytes) - { - CxFileJpg* pSource = (CxFileJpg*)cinfo->src; - if (num_bytes > 0){ - while (num_bytes > (long)pSource->bytes_in_buffer){ - num_bytes -= (long)pSource->bytes_in_buffer; - FillInputBuffer(cinfo); - // note we assume that fill_input_buffer will never return FALSE, - // so suspension need not be handled. - } - pSource->next_input_byte += (size_t) num_bytes; - pSource->bytes_in_buffer -= (size_t) num_bytes; - } - } - - static void TermSource(j_decompress_ptr /*cinfo*/) - { - return; - } -protected: - CxFile *m_pFile; - unsigned char *m_pBuffer; - bool m_bStartOfFile; -}; - -public: - enum CODEC_OPTION - { - ENCODE_BASELINE = 0x1, - ENCODE_ARITHMETIC = 0x2, - ENCODE_GRAYSCALE = 0x4, - ENCODE_OPTIMIZE = 0x8, - ENCODE_PROGRESSIVE = 0x10, - ENCODE_LOSSLESS = 0x20, - ENCODE_SMOOTHING = 0x40, - DECODE_GRAYSCALE = 0x80, - DECODE_QUANTIZE = 0x100, - DECODE_DITHER = 0x200, - DECODE_ONEPASS = 0x400, - DECODE_NOSMOOTH = 0x800, - ENCODE_SUBSAMPLE_422 = 0x1000, - ENCODE_SUBSAMPLE_444 = 0x2000 - }; - - int m_nPredictor; - int m_nPointTransform; - int m_nSmoothing; - int m_nQuantize; - J_DITHER_MODE m_nDither; - -}; - -#endif - -#endif +/* + * File: ximajpg.h + * Purpose: JPG Image Class Loader and Writer + */ +/* ========================================================== + * CxImageJPG (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it + * For conditions of distribution and use, see copyright notice in ximage.h + * + * Special thanks to Troels Knakkergaard for new features, enhancements and bugfixes + * + * Special thanks to Chris Shearer Cooper for CxFileJpg tips & code + * + * EXIF support based on jhead-1.8 by Matthias Wandel + * + * original CImageJPG and CImageIterator implementation are: + * Copyright: (c) 1995, Alejandro Aguilar Sierra + * + * This software is based in part on the work of the Independent JPEG Group. + * Copyright (C) 1991-1998, Thomas G. Lane. + * ========================================================== + */ +#if !defined(__ximaJPEG_h) +#define __ximaJPEG_h + +#include "ximage.h" + +#if CXIMAGE_SUPPORT_JPG + +#define CXIMAGEJPG_SUPPORT_EXIF 1 + +extern "C" { + #include "../jpeg/jpeglib.h" + #include "../jpeg/jerror.h" +} + +class DLL_EXP CxImageJPG: public CxImage +{ +public: + CxImageJPG(); + ~CxImageJPG(); + +// bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_JPG);} +// bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_JPG);} + bool Decode(CxFile * hFile); + bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); } + +#if CXIMAGE_SUPPORT_ENCODE + bool Encode(CxFile * hFile); + bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); } +#endif // CXIMAGE_SUPPORT_ENCODE + +/* + * EXIF support based on jhead-1.8 by Matthias Wandel + */ + +#if CXIMAGEJPG_SUPPORT_EXIF + +#define MAX_COMMENT 1000 +#define MAX_SECTIONS 20 + +typedef struct tag_ExifInfo { + char Version [5]; + char CameraMake [32]; + char CameraModel [40]; + char DateTime [20]; + int Height, Width; + int Orientation; + int IsColor; + int Process; + int FlashUsed; + float FocalLength; + float ExposureTime; + float ApertureFNumber; + float Distance; + float CCDWidth; + float ExposureBias; + int Whitebalance; + int MeteringMode; + int ExposureProgram; + int ISOequivalent; + int CompressionLevel; + float FocalplaneXRes; + float FocalplaneYRes; + float FocalplaneUnits; + float Xresolution; + float Yresolution; + float ResolutionUnit; + float Brightness; + char Comments[MAX_COMMENT]; + + unsigned char * ThumbnailPointer; /* Pointer at the thumbnail */ + unsigned ThumbnailSize; /* Size of thumbnail. */ + + bool IsExif; +} EXIFINFO; + +//-------------------------------------------------------------------------- +// JPEG markers consist of one or more 0xFF bytes, followed by a marker +// code byte (which is not an FF). Here are the marker codes of interest +// in this program. (See jdmarker.c for a more complete list.) +//-------------------------------------------------------------------------- + +#define M_SOF0 0xC0 // Start Of Frame N +#define M_SOF1 0xC1 // N indicates which compression process +#define M_SOF2 0xC2 // Only SOF0-SOF2 are now in common use +#define M_SOF3 0xC3 +#define M_SOF5 0xC5 // NB: codes C4 and CC are NOT SOF markers +#define M_SOF6 0xC6 +#define M_SOF7 0xC7 +#define M_SOF9 0xC9 +#define M_SOF10 0xCA +#define M_SOF11 0xCB +#define M_SOF13 0xCD +#define M_SOF14 0xCE +#define M_SOF15 0xCF +#define M_SOI 0xD8 // Start Of Image (beginning of datastream) +#define M_EOI 0xD9 // End Of Image (end of datastream) +#define M_SOS 0xDA // Start Of Scan (begins compressed data) +#define M_JFIF 0xE0 // Jfif marker +#define M_EXIF 0xE1 // Exif marker +#define M_COM 0xFE // COMment + +#define PSEUDO_IMAGE_MARKER 0x123; // Extra value. + +#define EXIF_READ_EXIF 0x01 +#define EXIF_READ_IMAGE 0x02 +#define EXIF_READ_ALL 0x03 + +class DLL_EXP CxExifInfo +{ + +typedef struct tag_Section_t{ + BYTE* Data; + int Type; + unsigned Size; +} Section_t; + +public: + EXIFINFO* m_exifinfo; + char m_szLastError[256]; + CxExifInfo(EXIFINFO* info = NULL); + ~CxExifInfo(); + bool DecodeExif(CxFile * hFile, int nReadMode = EXIF_READ_EXIF); + bool EncodeExif(CxFile * hFile); + void DiscardAllButExif(); +protected: + bool process_EXIF(unsigned char * CharBuf, unsigned int length); + void process_COM (const BYTE * Data, int length); + void process_SOFn (const BYTE * Data, int marker); + int Get16u(void * Short); + int Get16m(void * Short); + long Get32s(void * Long); + unsigned long Get32u(void * Long); + double ConvertAnyFormat(void * ValuePtr, int Format); + void* FindSection(int SectionType); + bool ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength, + EXIFINFO * const pInfo, unsigned char ** const LastExifRefdP, int NestingLevel=0); + int ExifImageWidth; + int MotorolaOrder; + Section_t Sections[MAX_SECTIONS]; + int SectionsRead; + bool freeinfo; +}; + + CxExifInfo* m_exif; + EXIFINFO m_exifinfo; + bool DecodeExif(CxFile * hFile); + bool DecodeExif(FILE * hFile) { CxIOFile file(hFile); return DecodeExif(&file); } + +#endif //CXIMAGEJPG_SUPPORT_EXIF + +//////////////////////////////////////////////////////////////////////////////////////// +////////////////////// C x F i l e J p g //////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////// + +// thanks to Chris Shearer Cooper +class CxFileJpg : public jpeg_destination_mgr, public jpeg_source_mgr + { +public: + enum { eBufSize = 4096 }; + + CxFileJpg(CxFile* pFile) + { + m_pFile = pFile; + + init_destination = InitDestination; + empty_output_buffer = EmptyOutputBuffer; + term_destination = TermDestination; + + init_source = InitSource; + fill_input_buffer = FillInputBuffer; + skip_input_data = SkipInputData; + resync_to_restart = jpeg_resync_to_restart; // use default method + term_source = TermSource; + next_input_byte = NULL; //* => next byte to read from buffer + bytes_in_buffer = 0; //* # of bytes remaining in buffer + + m_pBuffer = new unsigned char[eBufSize]; + } + ~CxFileJpg() + { + delete [] m_pBuffer; + } + + static void InitDestination(j_compress_ptr cinfo) + { + CxFileJpg* pDest = (CxFileJpg*)cinfo->dest; + pDest->next_output_byte = pDest->m_pBuffer; + pDest->free_in_buffer = eBufSize; + } + + static boolean EmptyOutputBuffer(j_compress_ptr cinfo) + { + CxFileJpg* pDest = (CxFileJpg*)cinfo->dest; + if (pDest->m_pFile->Write(pDest->m_pBuffer,1,eBufSize)!=(size_t)eBufSize) + ERREXIT(cinfo, JERR_FILE_WRITE); + pDest->next_output_byte = pDest->m_pBuffer; + pDest->free_in_buffer = eBufSize; + return TRUE; + } + + static void TermDestination(j_compress_ptr cinfo) + { + CxFileJpg* pDest = (CxFileJpg*)cinfo->dest; + size_t datacount = eBufSize - pDest->free_in_buffer; + /* Write any data remaining in the buffer */ + if (datacount > 0) { + if (!pDest->m_pFile->Write(pDest->m_pBuffer,1,datacount)) + ERREXIT(cinfo, JERR_FILE_WRITE); + } + pDest->m_pFile->Flush(); + /* Make sure we wrote the output file OK */ + if (pDest->m_pFile->Error()) ERREXIT(cinfo, JERR_FILE_WRITE); + return; + } + + static void InitSource(j_decompress_ptr cinfo) + { + CxFileJpg* pSource = (CxFileJpg*)cinfo->src; + pSource->m_bStartOfFile = TRUE; + } + + static boolean FillInputBuffer(j_decompress_ptr cinfo) + { + size_t nbytes; + CxFileJpg* pSource = (CxFileJpg*)cinfo->src; + nbytes = pSource->m_pFile->Read(pSource->m_pBuffer,1,eBufSize); + if (nbytes <= 0){ + if (pSource->m_bStartOfFile) //* Treat empty input file as fatal error + ERREXIT(cinfo, JERR_INPUT_EMPTY); + WARNMS(cinfo, JWRN_JPEG_EOF); + // Insert a fake EOI marker + pSource->m_pBuffer[0] = (JOCTET) 0xFF; + pSource->m_pBuffer[1] = (JOCTET) JPEG_EOI; + nbytes = 2; + } + pSource->next_input_byte = pSource->m_pBuffer; + pSource->bytes_in_buffer = nbytes; + pSource->m_bStartOfFile = FALSE; + return TRUE; + } + + static void SkipInputData(j_decompress_ptr cinfo, long num_bytes) + { + CxFileJpg* pSource = (CxFileJpg*)cinfo->src; + if (num_bytes > 0){ + while (num_bytes > (long)pSource->bytes_in_buffer){ + num_bytes -= (long)pSource->bytes_in_buffer; + FillInputBuffer(cinfo); + // note we assume that fill_input_buffer will never return FALSE, + // so suspension need not be handled. + } + pSource->next_input_byte += (size_t) num_bytes; + pSource->bytes_in_buffer -= (size_t) num_bytes; + } + } + + static void TermSource(j_decompress_ptr /*cinfo*/) + { + return; + } +protected: + CxFile *m_pFile; + unsigned char *m_pBuffer; + bool m_bStartOfFile; +}; + +public: + enum CODEC_OPTION + { + ENCODE_BASELINE = 0x1, + ENCODE_ARITHMETIC = 0x2, + ENCODE_GRAYSCALE = 0x4, + ENCODE_OPTIMIZE = 0x8, + ENCODE_PROGRESSIVE = 0x10, + ENCODE_LOSSLESS = 0x20, + ENCODE_SMOOTHING = 0x40, + DECODE_GRAYSCALE = 0x80, + DECODE_QUANTIZE = 0x100, + DECODE_DITHER = 0x200, + DECODE_ONEPASS = 0x400, + DECODE_NOSMOOTH = 0x800, + ENCODE_SUBSAMPLE_422 = 0x1000, + ENCODE_SUBSAMPLE_444 = 0x2000 + }; + + int m_nPredictor; + int m_nPointTransform; + int m_nSmoothing; + int m_nQuantize; + J_DITHER_MODE m_nDither; + +}; + +#endif + +#endif