source: liacs/MIR2010/SourceCode/cximage/ximajpg.h@ 205

Last change on this file since 205 was 95, checked in by Rick van der Zwet, 15 years ago

Bad boy, improper move of directory

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