]> Creatis software - clitk.git/blob - utilities/CxImage/ximajpg.h
Debug RTStruct conversion with empty struc
[clitk.git] / utilities / CxImage / ximajpg.h
1 /*
2  * File:        ximajpg.h
3  * Purpose:     JPG Image Class Loader and Writer
4  */
5 /* ==========================================================
6  * CxImageJPG (c) 07/Aug/2001 Davide Pizzolato - www.xdp.it
7  * For conditions of distribution and use, see copyright notice in ximage.h
8  *
9  * Special thanks to Troels Knakkergaard for new features, enhancements and bugfixes
10  *
11  * Special thanks to Chris Shearer Cooper for CxFileJpg tips & code
12  *
13  * EXIF support based on jhead-1.8 by Matthias Wandel <mwandel(at)rim(dot)net>
14  *
15  * original CImageJPG  and CImageIterator implementation are:
16  * Copyright:   (c) 1995, Alejandro Aguilar Sierra <asierra(at)servidor(dot)unam(dot)mx>
17  *
18  * This software is based in part on the work of the Independent JPEG Group.
19  * Copyright (C) 1991-1998, Thomas G. Lane.
20  * ==========================================================
21  */
22 #if !defined(__ximaJPEG_h)
23 #define __ximaJPEG_h
24
25 #include "ximage.h"
26
27 #if CXIMAGE_SUPPORT_JPG
28
29 #define CXIMAGEJPG_SUPPORT_EXIF 1
30
31 extern "C" {
32  #include "../jpeg/jpeglib.h"
33  #include "../jpeg/jerror.h"
34 }
35
36 class DLL_EXP CxImageJPG: public CxImage
37 {
38 public:
39         CxImageJPG();
40         ~CxImageJPG();
41
42 //      bool Load(const TCHAR * imageFileName){ return CxImage::Load(imageFileName,CXIMAGE_FORMAT_JPG);}
43 //      bool Save(const TCHAR * imageFileName){ return CxImage::Save(imageFileName,CXIMAGE_FORMAT_JPG);}
44         bool Decode(CxFile * hFile);
45         bool Decode(FILE *hFile) { CxIOFile file(hFile); return Decode(&file); }
46
47 #if CXIMAGE_SUPPORT_ENCODE
48         bool Encode(CxFile * hFile);
49         bool Encode(FILE *hFile) { CxIOFile file(hFile); return Encode(&file); }
50 #endif // CXIMAGE_SUPPORT_ENCODE
51
52 /*
53  * EXIF support based on jhead-1.8 by Matthias Wandel <mwandel(at)rim(dot)net>
54  */
55
56 #if CXIMAGEJPG_SUPPORT_EXIF
57
58 #define MAX_COMMENT 1000
59 #define MAX_SECTIONS 20
60
61 typedef struct tag_ExifInfo {
62         char  Version      [5];
63     char  CameraMake   [32];
64     char  CameraModel  [40];
65     char  DateTime     [20];
66     int   Height, Width;
67     int   Orientation;
68     int   IsColor;
69     int   Process;
70     int   FlashUsed;
71     float FocalLength;
72     float ExposureTime;
73     float ApertureFNumber;
74     float Distance;
75     float CCDWidth;
76     float ExposureBias;
77     int   Whitebalance;
78     int   MeteringMode;
79     int   ExposureProgram;
80     int   ISOequivalent;
81     int   CompressionLevel;
82         float FocalplaneXRes;
83         float FocalplaneYRes;
84         float FocalplaneUnits;
85         float Xresolution;
86         float Yresolution;
87         float ResolutionUnit;
88         float Brightness;
89     char  Comments[MAX_COMMENT];
90
91     unsigned char * ThumbnailPointer;  /* Pointer at the thumbnail */
92     unsigned ThumbnailSize;     /* Size of thumbnail. */
93
94         bool  IsExif;
95 } EXIFINFO;
96
97 //--------------------------------------------------------------------------
98 // JPEG markers consist of one or more 0xFF bytes, followed by a marker
99 // code byte (which is not an FF).  Here are the marker codes of interest
100 // in this program.  (See jdmarker.c for a more complete list.)
101 //--------------------------------------------------------------------------
102
103 #define M_SOF0  0xC0            // Start Of Frame N
104 #define M_SOF1  0xC1            // N indicates which compression process
105 #define M_SOF2  0xC2            // Only SOF0-SOF2 are now in common use
106 #define M_SOF3  0xC3
107 #define M_SOF5  0xC5            // NB: codes C4 and CC are NOT SOF markers
108 #define M_SOF6  0xC6
109 #define M_SOF7  0xC7
110 #define M_SOF9  0xC9
111 #define M_SOF10 0xCA
112 #define M_SOF11 0xCB
113 #define M_SOF13 0xCD
114 #define M_SOF14 0xCE
115 #define M_SOF15 0xCF
116 #define M_SOI   0xD8            // Start Of Image (beginning of datastream)
117 #define M_EOI   0xD9            // End Of Image (end of datastream)
118 #define M_SOS   0xDA            // Start Of Scan (begins compressed data)
119 #define M_JFIF  0xE0            // Jfif marker
120 #define M_EXIF  0xE1            // Exif marker
121 #define M_COM   0xFE            // COMment 
122
123 #define PSEUDO_IMAGE_MARKER 0x123; // Extra value.
124
125 #define EXIF_READ_EXIF  0x01
126 #define EXIF_READ_IMAGE 0x02
127 #define EXIF_READ_ALL   0x03
128
129 class DLL_EXP CxExifInfo
130 {
131
132 typedef struct tag_Section_t{
133     BYTE*    Data;
134     int      Type;
135     unsigned Size;
136 } Section_t;
137
138 public:
139         EXIFINFO* m_exifinfo;
140         char m_szLastError[256];
141         CxExifInfo(EXIFINFO* info = NULL);
142         ~CxExifInfo();
143         bool DecodeExif(CxFile * hFile, int nReadMode = EXIF_READ_EXIF);
144         bool EncodeExif(CxFile * hFile);
145         void DiscardAllButExif();
146 protected:
147         bool process_EXIF(unsigned char * CharBuf, unsigned int length);
148         void process_COM (const BYTE * Data, int length);
149         void process_SOFn (const BYTE * Data, int marker);
150         int Get16u(void * Short);
151         int Get16m(void * Short);
152         long Get32s(void * Long);
153         unsigned long Get32u(void * Long);
154         double ConvertAnyFormat(void * ValuePtr, int Format);
155         void* FindSection(int SectionType);
156         bool ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength,
157                            EXIFINFO * const pInfo, unsigned char ** const LastExifRefdP, int NestingLevel=0);
158         int ExifImageWidth;
159         int MotorolaOrder;
160         Section_t Sections[MAX_SECTIONS];
161         int SectionsRead;
162         bool freeinfo;
163 };
164
165         CxExifInfo* m_exif;
166         EXIFINFO m_exifinfo;
167         bool DecodeExif(CxFile * hFile);
168         bool DecodeExif(FILE * hFile) { CxIOFile file(hFile); return DecodeExif(&file); }
169
170 #endif //CXIMAGEJPG_SUPPORT_EXIF
171
172 ////////////////////////////////////////////////////////////////////////////////////////
173 //////////////////////        C x F i l e J p g         ////////////////////////////////
174 ////////////////////////////////////////////////////////////////////////////////////////
175
176 // thanks to Chris Shearer Cooper <cscooper(at)frii(dot)com>
177 class CxFileJpg : public jpeg_destination_mgr, public jpeg_source_mgr
178         {
179 public:
180         enum { eBufSize = 4096 };
181
182         CxFileJpg(CxFile* pFile)
183         {
184         m_pFile = pFile;
185
186                 init_destination = InitDestination;
187                 empty_output_buffer = EmptyOutputBuffer;
188                 term_destination = TermDestination;
189
190                 init_source = InitSource;
191                 fill_input_buffer = FillInputBuffer;
192                 skip_input_data = SkipInputData;
193                 resync_to_restart = jpeg_resync_to_restart; // use default method
194                 term_source = TermSource;
195                 next_input_byte = NULL; //* => next byte to read from buffer 
196                 bytes_in_buffer = 0;    //* # of bytes remaining in buffer 
197
198                 m_pBuffer = new unsigned char[eBufSize];
199         }
200         ~CxFileJpg()
201         {
202                 delete [] m_pBuffer;
203         }
204
205         static void InitDestination(j_compress_ptr cinfo)
206         {
207                 CxFileJpg* pDest = (CxFileJpg*)cinfo->dest;
208                 pDest->next_output_byte = pDest->m_pBuffer;
209                 pDest->free_in_buffer = eBufSize;
210         }
211
212         static boolean EmptyOutputBuffer(j_compress_ptr cinfo)
213         {
214                 CxFileJpg* pDest = (CxFileJpg*)cinfo->dest;
215                 if (pDest->m_pFile->Write(pDest->m_pBuffer,1,eBufSize)!=(size_t)eBufSize)
216                         ERREXIT(cinfo, JERR_FILE_WRITE);
217                 pDest->next_output_byte = pDest->m_pBuffer;
218                 pDest->free_in_buffer = eBufSize;
219                 return TRUE;
220         }
221
222         static void TermDestination(j_compress_ptr cinfo)
223         {
224                 CxFileJpg* pDest = (CxFileJpg*)cinfo->dest;
225                 size_t datacount = eBufSize - pDest->free_in_buffer;
226                 /* Write any data remaining in the buffer */
227                 if (datacount > 0) {
228                         if (!pDest->m_pFile->Write(pDest->m_pBuffer,1,datacount))
229                                 ERREXIT(cinfo, JERR_FILE_WRITE);
230                 }
231                 pDest->m_pFile->Flush();
232                 /* Make sure we wrote the output file OK */
233                 if (pDest->m_pFile->Error()) ERREXIT(cinfo, JERR_FILE_WRITE);
234                 return;
235         }
236
237         static void InitSource(j_decompress_ptr cinfo)
238         {
239                 CxFileJpg* pSource = (CxFileJpg*)cinfo->src;
240                 pSource->m_bStartOfFile = TRUE;
241         }
242
243         static boolean FillInputBuffer(j_decompress_ptr cinfo)
244         {
245                 size_t nbytes;
246                 CxFileJpg* pSource = (CxFileJpg*)cinfo->src;
247                 nbytes = pSource->m_pFile->Read(pSource->m_pBuffer,1,eBufSize);
248                 if (nbytes <= 0){
249                         if (pSource->m_bStartOfFile)    //* Treat empty input file as fatal error 
250                                 ERREXIT(cinfo, JERR_INPUT_EMPTY);
251                         WARNMS(cinfo, JWRN_JPEG_EOF);
252                         // Insert a fake EOI marker 
253                         pSource->m_pBuffer[0] = (JOCTET) 0xFF;
254                         pSource->m_pBuffer[1] = (JOCTET) JPEG_EOI;
255                         nbytes = 2;
256                 }
257                 pSource->next_input_byte = pSource->m_pBuffer;
258                 pSource->bytes_in_buffer = nbytes;
259                 pSource->m_bStartOfFile = FALSE;
260                 return TRUE;
261         }
262
263         static void SkipInputData(j_decompress_ptr cinfo, long num_bytes)
264         {
265                 CxFileJpg* pSource = (CxFileJpg*)cinfo->src;
266                 if (num_bytes > 0){
267                         while (num_bytes > (long)pSource->bytes_in_buffer){
268                                 num_bytes -= (long)pSource->bytes_in_buffer;
269                                 FillInputBuffer(cinfo);
270                                 // note we assume that fill_input_buffer will never return FALSE,
271                                 // so suspension need not be handled.
272                         }
273                         pSource->next_input_byte += (size_t) num_bytes;
274                         pSource->bytes_in_buffer -= (size_t) num_bytes;
275                 }
276         }
277
278         static void TermSource(j_decompress_ptr /*cinfo*/)
279         {
280                 return;
281         }
282 protected:
283     CxFile  *m_pFile;
284         unsigned char *m_pBuffer;
285         bool m_bStartOfFile;
286 };
287
288 public:
289         enum CODEC_OPTION
290         {
291                 ENCODE_BASELINE = 0x1,
292                 ENCODE_ARITHMETIC = 0x2,
293                 ENCODE_GRAYSCALE = 0x4,
294                 ENCODE_OPTIMIZE = 0x8,
295                 ENCODE_PROGRESSIVE = 0x10,
296                 ENCODE_LOSSLESS = 0x20,
297                 ENCODE_SMOOTHING = 0x40,
298                 DECODE_GRAYSCALE = 0x80,
299                 DECODE_QUANTIZE = 0x100,
300                 DECODE_DITHER = 0x200,
301                 DECODE_ONEPASS = 0x400,
302                 DECODE_NOSMOOTH = 0x800,
303                 ENCODE_SUBSAMPLE_422 = 0x1000,
304                 ENCODE_SUBSAMPLE_444 = 0x2000
305         }; 
306
307         int m_nPredictor;
308         int m_nPointTransform;
309         int m_nSmoothing;
310         int m_nQuantize;
311         J_DITHER_MODE m_nDither;
312
313 };
314
315 #endif
316
317 #endif