1 // ==========================================================
2 // Tag manipulation functions
3 //
4 // Design and implementation by
5 // - Herv� Drolon <drolon@infonie.fr>
6 //
7 // This file is part of FreeImage 3
8 //
9 // COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
10 // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
11 // THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
12 // OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
13 // CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
14 // THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
15 // SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
16 // PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
17 // THIS DISCLAIMER.
18 //
19 // Use at your own risk!
20 // ==========================================================
21 
22 #ifndef FREEIMAGE_TAG_H
23 #define FREEIMAGE_TAG_H
24 
25 // ==========================================================
26 // Exif JPEG tags
27 // ==========================================================
28 
29 // ----------------------------------------------------------
30 // TIFF Rev. 6.0 Attribute Information Used in Exif
31 // ----------------------------------------------------------
32 
33 // Tags relating to image data structure
34 
35 #define TAG_IMAGE_WIDTH					0x0100
36 #define TAG_IMAGE_HEIGHT				0x0101
37 #define TAG_BITS_PER_SAMPLE				0x0102
38 #define TAG_COMPRESSION					0x0103
39 #define TAG_PHOTOMETRIC_INTERPRETATION	0x0106
40 #define TAG_ORIENTATION					0x0112
41 #define TAG_SAMPLES_PER_PIXEL			0x0115
42 #define TAG_PLANAR_CONFIGURATION		0x011C
43 #define TAG_YCBCR_SUBSAMPLING			0x0212
44 #define TAG_YCBCR_POSITIONING			0x0213
45 #define TAG_X_RESOLUTION				0x011A
46 #define TAG_Y_RESOLUTION				0x011B
47 #define TAG_RESOLUTION_UNIT				0x0128
48 
49 // LibTIF compression modes
50 
51 #define	    TAG_COMPRESSION_NONE		1	/* dump mode */
52 #define	    TAG_COMPRESSION_CCITTRLE	2	/* CCITT modified Huffman RLE */
53 #define	    TAG_COMPRESSION_CCITTFAX3	3	/* CCITT Group 3 fax encoding */
54 #define     TAG_COMPRESSION_CCITT_T4        3       /* CCITT T.4 (TIFF 6 name) */
55 #define	    TAG_COMPRESSION_CCITTFAX4	4	/* CCITT Group 4 fax encoding */
56 #define     TAG_COMPRESSION_CCITT_T6        4       /* CCITT T.6 (TIFF 6 name) */
57 #define	    TAG_COMPRESSION_LZW		5       /* Lempel-Ziv  & Welch */
58 #define	    TAG_COMPRESSION_OJPEG		6	/* !6.0 JPEG */
59 #define	    TAG_COMPRESSION_JPEG		7	/* %JPEG DCT compression */
60 #define	    TAG_COMPRESSION_NEXT		32766	/* NeXT 2-bit RLE */
61 #define	    TAG_COMPRESSION_CCITTRLEW	32771	/* #1 w/ word alignment */
62 #define	    TAG_COMPRESSION_PACKBITS	32773	/* Macintosh RLE */
63 #define	    TAG_COMPRESSION_THUNDERSCAN	32809	/* ThunderScan RLE */
64 /* codes 32895-32898 are reserved for ANSI IT8 TIFF/IT <dkelly@apago.com) */
65 #define	    TAG_COMPRESSION_IT8CTPAD	32895   /* IT8 CT w/padding */
66 #define	    TAG_COMPRESSION_IT8LW		32896   /* IT8 Linework RLE */
67 #define	    TAG_COMPRESSION_IT8MP		32897   /* IT8 Monochrome picture */
68 #define	    TAG_COMPRESSION_IT8BL		32898   /* IT8 Binary line art */
69 /* compression codes 32908-32911 are reserved for Pixar */
70 #define     TAG_COMPRESSION_PIXARFILM	32908   /* Pixar companded 10bit LZW */
71 #define	    TAG_COMPRESSION_PIXARLOG	32909   /* Pixar companded 11bit ZIP */
72 #define	    TAG_COMPRESSION_DEFLATE		32946	/* Deflate compression */
73 #define     TAG_COMPRESSION_ADOBE_DEFLATE   8       /* Deflate compression,
74 						   as recognized by Adobe */
75 /* compression code 32947 is reserved for Oceana Matrix <dev@oceana.com> */
76 #define     TAG_COMPRESSION_DCS             32947   /* Kodak DCS encoding */
77 #define	    TAG_COMPRESSION_JBIG		34661	/* ISO JBIG */
78 #define     TAG_COMPRESSION_SGILOG		34676	/* SGI Log Luminance RLE */
79 #define     TAG_COMPRESSION_SGILOG24	34677	/* SGI Log 24-bit packed */
80 #define     TAG_COMPRESSION_JP2000          34712   /* Leadtools JPEG2000 */
81 #define	    TAG_COMPRESSION_LZMA		34925	/* LZMA2 */
82 
83 // Tags relating to recording offset
84 
85 #define TAG_STRIP_OFFSETS					0x0111
86 #define TAG_ROWS_PER_STRIP					0x0116
87 #define TAG_STRIP_BYTE_COUNTS				0x0117
88 #define TAG_JPEG_INTERCHANGE_FORMAT			0x0201
89 #define TAG_JPEG_INTERCHANGE_FORMAT_LENGTH	0x0202
90 
91 // Tags relating to image data characteristics
92 
93 #define TAG_TRANSFER_FUNCTION		0x012D
94 #define TAG_WHITE_POINT				0x013E
95 #define TAG_PRIMARY_CHROMATICITIES	0x013F
96 #define TAG_YCBCR_COEFFICIENTS		0x0211
97 #define TAG_REFERENCE_BLACK_WHITE	0x0214
98 
99 // Other tags
100 
101 #define TAG_DATETIME 				0x0132
102 #define TAG_IMAGE_DESCRIPTION 		0x010E
103 #define TAG_MAKE 					0x010F
104 #define TAG_MODEL 					0x0110
105 #define TAG_SOFTWARE 				0x0131
106 #define TAG_ARTIST 					0x013B
107 #define TAG_COPYRIGHT 				0x8298
108 
109 // ----------------------------------------------------------
110 // Exif IFD Attribute Information
111 // ----------------------------------------------------------
112 
113 // Tags relating to version
114 
115 #define TAG_EXIF_VERSION 			0x9000
116 #define TAG_FLASHPIX_VERSION 		0xA000
117 
118 // Tag relating to image data characteristics
119 
120 #define TAG_COLOR_SPACE 			0xA001
121 
122 // Tags relating to image configuration
123 
124 #define TAG_COMPONENTS_CONFIGURATION	0x9101
125 #define TAG_COMPRESSED_BITS_PER_PIXEL	0x9102
126 #define TAG_PIXEL_X_DIMENSION			0xA002
127 #define TAG_PIXEL_Y_DIMENSION			0xA003
128 
129 // Tags relating to user information
130 
131 #define TAG_MARKER_NOTE		0x927C
132 #define TAG_USER_COMMENT	0x9286
133 
134 // Tag relating to related file information
135 
136 #define TAG_RELATED_SOUND_FILE			0xA004
137 
138 // Tags relating to date and time
139 
140 #define TAG_DATETIME_ORIGINAL			0x9003
141 #define TAG_DATETIME_DIGITIZED			0x9004
142 #define TAG_SUBSECOND_TIME				0x9290
143 #define TAG_SUBSECOND_TIME_ORIGINAL		0x9291
144 #define TAG_SUBSECOND_TIME_DIGITIZED	0x9292
145 
146 // Tags relating to picture-taking conditions
147 
148 #define TAG_EXPOSURE_TIME				0x829A
149 #define TAG_FNUMBER						0x829D
150 #define TAG_EXPOSURE_PROGRAM			0x8822
151 #define TAG_SPECTRAL_SENSITIVITY		0x8824
152 #define TAG_ISO_SPEED_RATINGS 			0x8827
153 #define TAG_OECF						0x8828
154 #define TAG_SHUTTER_SPEED_VALUE 		0x9201
155 #define TAG_APERTURE_VALUE 				0x9202
156 #define TAG_BRIGHTNESS_VALUE			0x9203
157 #define TAG_EXPOSURE_BIAS_VALUE 		0x9204
158 #define TAG_MAX_APERTURE_VALUE 			0x9205
159 #define TAG_SUBJECT_DISTANCE			0x9206
160 #define TAG_METERING_MODE				0x9207
161 #define TAG_LIGHT_SOURCE				0x9208
162 #define TAG_FLASH						0x9209
163 #define TAG_FOCAL_LENGTH				0x920A
164 #define TAG_SUBJECT_AREA				0x9214
165 #define TAG_FLASH_ENERGY				0xA20B
166 #define TAG_SPATIAL_FREQ_RESPONSE 		0xA20C
167 #define TAG_FOCAL_PLANE_X_RES			0xA20E
168 #define TAG_FOCAL_PLANE_Y_RES			0xA20F
169 #define TAG_FOCAL_PLANE_UNIT			0xA210
170 #define TAG_SUBJECT_LOCATION 			0xA214
171 #define TAG_EXPOSURE_INDEX				0xA215
172 #define TAG_SENSING_METHOD				0xA217
173 #define TAG_FILE_SOURCE					0xA300
174 #define TAG_SCENE_TYPE					0xA301
175 #define TAG_CFA_PATTERN					0xA302
176 #define TAG_CUSTOM_RENDERED				0xA401
177 #define TAG_EXPOSURE_MODE				0xA402
178 #define TAG_WHITE_BALANCE				0xA403
179 #define TAG_DIGITAL_ZOOM_RATIO			0xA404
180 #define TAG_FOCAL_LENGTH_IN_35MM_FILM	0xA405
181 #define TAG_SCENE_CAPTURE_TYPE			0xA406
182 #define TAG_GAIN_CONTROL				0xA407
183 #define TAG_CONTRAST					0xA408
184 #define TAG_SATURATION					0xA409
185 #define TAG_SHARPNESS					0xA40A
186 #define TAG_DEVICE_SETTING_DESCRIPTION	0xA40B
187 #define TAG_SUBJECT_DISTANCE_RANGE		0xA40C
188 
189 // Other tags
190 
191 #define TAG_IMAGE_UNIQUE_ID				0xA420
192 
193 // ----------------------------------------------------------
194 // GPS Attribute Information
195 // ----------------------------------------------------------
196 
197 #define TAG_GPS_VERSION_ID				0x0000
198 #define TAG_GPS_LATITUDE_REF			0x0001
199 #define TAG_GPS_LATITUDE				0x0002
200 #define TAG_GPS_LONGITUDE_REF			0x0003
201 #define TAG_GPS_LONGITUDE				0x0004
202 #define TAG_GPS_ALTITUDE_REF			0x0005
203 #define TAG_GPS_ALTITUDE				0x0006
204 #define TAG_GPS_TIME_STAMP				0x0007
205 #define TAG_GPS_SATELLITES				0x0008
206 #define TAG_GPS_STATUS					0x0009
207 #define TAG_GPS_MEASURE_MODE			0x000A
208 #define TAG_GPS_DOP						0x000B
209 #define TAG_GPS_SPEED_REF				0x000C
210 #define TAG_GPS_SPEED					0x000D
211 #define TAG_GPS_TRACK_REF				0x000E
212 #define TAG_GPS_TRACK					0x000F
213 #define TAG_GPS_IMG_DIRECTION_REF		0x0010
214 #define TAG_GPS_IMG_DIRECTION			0x0011
215 #define TAG_GPS_MAP_DATUM				0x0012
216 #define TAG_GPS_DEST_LATITUDE_REF		0x0013
217 #define TAG_GPS_DEST_LATITUDE			0x0014
218 #define TAG_GPS_DEST_LONGITUDE_REF		0x0015
219 #define TAG_GPS_DEST_LONGITUDE			0x0016
220 #define TAG_GPS_DEST_BEARING_REF		0x0017
221 #define TAG_GPS_DEST_BEARING			0x0018
222 #define TAG_GPS_DEST_DISTANCE_REF		0x0019
223 #define TAG_GPS_DEST_DISTANCE			0x001A
224 #define TAG_GPS_PROCESSING_METHOD		0x001B
225 #define TAG_GPS_AREA_INFORMATION		0x001C
226 #define TAG_GPS_DATE_STAMP				0x001D
227 #define TAG_GPS_DIFFERENTIAL			0x001E
228 
229 // ==========================================================
230 // IPTC/NAA tags
231 // ==========================================================
232 
233 #define TAG_RECORD_VERSION					0x0200
234 #define TAG_CAPTION							0x0278
235 #define TAG_WRITER							0x027A
236 #define TAG_HEADLINE						0x0269
237 #define TAG_SPECIAL_INSTRUCTIONS			0x0228
238 #define TAG_BY_LINE							0x0250
239 #define TAG_BY_LINE_TITLE					0x0255
240 #define TAG_CREDIT							0x026E
241 #define TAG_SOURCE							0x0273
242 #define TAG_OBJECT_NAME						0x0205
243 #define TAG_DATE_CREATED					0x0237
244 #define TAG_CITY							0x025A
245 #define TAG_PROVINCE_OR_STATE				0x025F
246 #define TAG_COUNTRY_OR_PRIMARY_LOCATION		0x0265
247 #define TAG_ORIGINAL_TRANSMISSION_REFERENCE 0x0267
248 #define TAG_CATEGORY						0x020F
249 #define TAG_SUPPLEMENTAL_CATEGORIES			0x0214
250 #define TAG_URGENCY							0x020A
251 #define TAG_KEYWORDS						0x0219
252 #define TAG_COPYRIGHT_NOTICE				0x0274
253 #define TAG_RELEASE_DATE					0x021E
254 #define TAG_RELEASE_TIME					0x0223
255 #define TAG_TIME_CREATED					0x023C
256 #define TAG_ORIGINATING_PROGRAM				0x0241
257 
258 // ==========================================================
259 // GeoTIFF tags
260 // ==========================================================
261 
262 // tags 33550 is a private tag registered to SoftDesk, Inc
263 #define TIFFTAG_GEOPIXELSCALE		33550
264 // tags 33920-33921 are private tags registered to Intergraph, Inc
265 #define TIFFTAG_INTERGRAPH_MATRIX	33920
266 #define TIFFTAG_GEOTIEPOINTS		33922
267 // tags 34263-34264 are private tags registered to NASA-JPL Carto Group
268 #define TIFFTAG_JPL_CARTO_IFD		34263
269 #define TIFFTAG_GEOTRANSMATRIX		34264    /* New Matrix Tag replaces 33920 */
270 // tags 34735-3438 are private tags registered to SPOT Image, Inc
271 #define TIFFTAG_GEOKEYDIRECTORY		34735
272 #define TIFFTAG_GEODOUBLEPARAMS		34736
273 #define TIFFTAG_GEOASCIIPARAMS		34737
274 
275 // ==========================================================
276 // FreeImage Animation tags
277 // ==========================================================
278 
279 #define ANIMTAG_LOGICALWIDTH	0x0001
280 #define ANIMTAG_LOGICALHEIGHT	0x0002
281 #define ANIMTAG_GLOBALPALETTE	0x0003
282 #define ANIMTAG_LOOP			0x0004
283 #define ANIMTAG_FRAMELEFT		0x1001
284 #define ANIMTAG_FRAMETOP		0x1002
285 #define ANIMTAG_NOLOCALPALETTE	0x1003
286 #define ANIMTAG_INTERLACED		0x1004
287 #define ANIMTAG_FRAMETIME		0x1005
288 #define ANIMTAG_DISPOSALMETHOD	0x1006
289 
290 // --------------------------------------------------------------------------
291 // Helper functions to deal with the FITAG structure
292 // --------------------------------------------------------------------------
293 
294 /**
295 Describes the tag format descriptor
296 Given a FREE_IMAGE_MDTYPE, calculate the size of this type in bytes unit
297 @param type Tag data type
298 @return Returns the size of the data type, in bytes
299 @see FREE_IMAGE_MDTYPE
300 */
301 unsigned FreeImage_TagDataWidth(FREE_IMAGE_MDTYPE type);
302 
303 /**
304 Calculate the memory size required by a tag, including the size of the structure
305 @param tag The tag to examine
306 @return Retuns the memory size used by a tag
307 */
308 size_t FreeImage_GetTagMemorySize(FITAG *tag);
309 
310 // --------------------------------------------------------------------------
311 
312 /**
313 	Structure to hold a tag information
314 */
315 typedef struct tagTagInfo {
316 	WORD tag;			// Tag ID (required)
317 	char *fieldname;	// Field name (required)
318 	char *description;	// Field description (may be NULL)
319 } TagInfo;
320 
321 
322 /**
323 Class to hold tag information (based on Meyers� Singleton).<br>
324 
325 Sample usage :<br>
326 <code>
327 TagLib& s = TagLib::instance();
328 TagInfo *tag_info = s.getTagInfo(EXIF_MAIN, 0x0100);
329 </code>
330 
331 Note on multi-threaded applications :
332 
333 The singleton pattern must be carefully constructed in multi-threaded applications.
334 If two threads are to execute the creation method at the same time when a singleton
335 does not yet exist, they both must check for an instance of the singleton and then
336 only one should create the new one.
337 The classic solution to this problem is to use mutual exclusion on the class that
338 indicates that the object is being instantiated.
339 The FreeImage solution is to instantiate the singleton before any other thread is launched,
340 i.e. inside the FreeImage_Initialise function (see Plugin.cpp).
341 */
342 
343 class TagLib {
344 public:
345 
346 	/**
347 	internal tag info tables registered in TagLib
348 	*/
349 	enum MDMODEL {
350 		UNKNOWN,
351 		EXIF_MAIN,
352 		EXIF_EXIF,
353 		EXIF_GPS,
354 		EXIF_INTEROP,
355 		EXIF_MAKERNOTE_CANON,
356 		EXIF_MAKERNOTE_CASIOTYPE1,
357 		EXIF_MAKERNOTE_CASIOTYPE2,
358 		EXIF_MAKERNOTE_FUJIFILM,
359 		EXIF_MAKERNOTE_KYOCERA,
360 		EXIF_MAKERNOTE_MINOLTA,
361 		EXIF_MAKERNOTE_NIKONTYPE1,
362 		EXIF_MAKERNOTE_NIKONTYPE2,
363 		EXIF_MAKERNOTE_NIKONTYPE3,
364 		EXIF_MAKERNOTE_OLYMPUSTYPE1,
365 		EXIF_MAKERNOTE_PANASONIC,
366 		EXIF_MAKERNOTE_ASAHI,
367 		EXIF_MAKERNOTE_PENTAX,
368 		EXIF_MAKERNOTE_SONY,
369 		EXIF_MAKERNOTE_SIGMA_SD1,
370 		EXIF_MAKERNOTE_SIGMA_FOVEON,
371 		IPTC,
372 		GEOTIFF,
373 		ANIMATION
374 	};
375 
376 private:
377 
378 	typedef std::map<WORD, TagInfo*> TAGINFO;
379 	typedef std::map<int, TAGINFO*>  TABLEMAP;
380 
381 	/// store hash tables for all known tag info tables
382 	TABLEMAP _table_map;
383 
384 private:
385 	/**
386 	Constructor (private)<br>
387 	This is where the tag info tables are initialized.
388 	@see addMetadataModel
389 	*/
390 	TagLib();
391 
392 	/// Assignement operator (disabled)
393 	void operator=(TagLib&);
394 
395 	/// Copy constructor (disabled)
396 	TagLib(const TagLib&);
397 
398 	/**
399 	Used in the constructor to initialize the tag tables
400 	@param md_model Internal metadata model
401 	@param tag_table Tag info table
402 	@return Returns TRUE if successful, returns FALSE otherwise
403 	*/
404 	BOOL addMetadataModel(MDMODEL md_model, TagInfo *tag_table);
405 
406 public:
407 	/// Destructor
408 	~TagLib();
409 
410 	/**
411 	@return Returns a reference to the TagLib instance
412 	*/
413 	static TagLib& instance();
414 
415 	/**
416 	Given a tag ID, returns its TagInfo descriptor
417 	@param md_model Internal metadata model
418 	@param tagID tag ID
419 	@return Returns the TagInfo descriptor if successful, returns NULL otherwise
420 	*/
421 	const TagInfo* getTagInfo(MDMODEL md_model, WORD tagID);
422 
423 	/**
424 	Given a tag ID, returns its tag field name.
425 	When the tag is unknown and defaultKey is not NULL, a string such as "Tag 0x1234" is returned.
426 	This string is contained in the provided defaultKey buffer (assumed to be an array of at least 16 chars).
427 	@param md_model Internal metadata model
428 	@param tagID tag ID
429 	@param defaultKey Assumed to be an array of 16 chars. If not NULL, build a key for unknown tags
430 	@return Returns the tag field name if successful, returns an 'unknown tag' string contained in defaultKey otherwise
431 	*/
432 	const char* getTagFieldName(MDMODEL md_model, WORD tagID, char *defaultKey);
433 
434 	/**
435 	Given a tag ID, returns its description.
436 	When the tag has no description, a NULL value is returned.
437 	@param md_model Internal metadata model
438 	@param tagID tag ID
439 	@return Returns the tag description if successful, returns NULL otherwise
440 	*/
441 	const char* getTagDescription(MDMODEL md_model, WORD tagID);
442 
443 	/**
444 	Given a tag field name, returns its tag ID.
445 	When the tag doesn't exists, a value '-1' is returned.
446 	@param md_model Internal metadata model
447 	@param key tag field name
448 	@return Returns the tag ID if successful, returns -1 otherwise
449 	*/
450 	int getTagID(MDMODEL md_model, const char *key);
451 
452 	/**
453 	Perform a conversion between internal metadata models and FreeImage public metadata models
454 	@param md_model Internal metadata model
455 	*/
456 	FREE_IMAGE_MDMODEL getFreeImageModel(MDMODEL model);
457 
458 };
459 
460 // --------------------------------------------------------------------------
461 // Constant strings
462 // --------------------------------------------------------------------------
463 
464 /// Name of the XMP field
465 static const char *g_TagLib_XMPFieldName = "XMLPacket";
466 
467 /// Name of the Exif raw field
468 static const char *g_TagLib_ExifRawFieldName = "ExifRaw";
469 
470 // --------------------------------------------------------------------------
471 // Metadata routines
472 // --------------------------------------------------------------------------
473 
474 #if defined(__cplusplus)
475 extern "C" {
476 #endif
477 
478 // JPEG / JPEG-XR Exif profile (see Exif.cpp)
479 // --------------------------------------------------------------------------
480 BOOL jpeg_read_exif_profile(FIBITMAP *dib, const BYTE *dataptr, unsigned datalen);
481 BOOL jpeg_read_exif_profile_raw(FIBITMAP *dib, const BYTE *profile, unsigned length);
482 BOOL jpegxr_read_exif_profile(FIBITMAP *dib, const BYTE *profile, unsigned length, unsigned file_offset);
483 BOOL jpegxr_read_exif_gps_profile(FIBITMAP *dib, const BYTE *profile, unsigned length, unsigned file_offset);
484 
485 BOOL tiff_get_ifd_profile(FIBITMAP *dib, FREE_IMAGE_MDMODEL md_model, BYTE **ppbProfile, unsigned *uProfileLength);
486 
487 
488 // PSD Exif profile (see Exif.cpp)
489 // --------------------------------------------------------------------------
490 BOOL psd_read_exif_profile(FIBITMAP *dib, const BYTE *dataptr, unsigned datalen);
491 BOOL psd_read_exif_profile_raw(FIBITMAP *dib, const BYTE *dataptr, unsigned datalen);
492 
493 
494 // JPEG / PSD / TIFF IPTC profile (see IPTC.cpp)
495 // --------------------------------------------------------------------------
496 BOOL read_iptc_profile(FIBITMAP *dib, const BYTE *dataptr, unsigned int datalen);
497 BOOL write_iptc_profile(FIBITMAP *dib, BYTE **profile, unsigned *profile_size);
498 
499 #if defined(__cplusplus)
500 }
501 #endif
502 
503 
504 #endif // FREEIMAGE_TAG_H
505 
506 
507