source: josm/trunk/src/com/drew/metadata/exif/ExifDirectory.java@ 5259

Last change on this file since 5259 was 4231, checked in by stoecker, 15 years ago

add signpost and metadata extractor code to repository directly

File size: 40.7 KB
Line 
1/*
2 * ExifDirectory.java
3 *
4 * This is public domain software - that is, you can do whatever you want
5 * with it, and include it software that is licensed under the GNU or the
6 * BSD license, or whatever other licence you choose, including proprietary
7 * closed source licenses. I do ask that you leave this header in tact.
8 *
9 * If you make modifications to this code that you think would benefit the
10 * wider community, please send me a copy and I'll post it on my site.
11 *
12 * If you make use of this code, I'd appreciate hearing about it.
13 * drew@drewnoakes.com
14 * Latest version of this software kept at
15 * http://drewnoakes.com/
16 *
17 * Created by dnoakes on 25-Nov-2002 20:41:00 using IntelliJ IDEA.
18 */
19package com.drew.metadata.exif;
20
21import com.drew.metadata.Directory;
22import com.drew.metadata.MetadataException;
23
24import java.io.FileOutputStream;
25import java.io.IOException;
26import java.util.HashMap;
27
28/**
29 *
30 */
31public class ExifDirectory extends Directory
32{
33 // TODO do these tags belong in the exif directory?
34 public static final int TAG_SUB_IFDS = 0x014A;
35 public static final int TAG_GPS_INFO = 0x8825;
36
37 /**
38 * The actual aperture value of lens when the image was taken. Unit is APEX.
39 * To convert this value to ordinary F-number (F-stop), calculate this value's
40 * power of root 2 (=1.4142). For example, if the ApertureValue is '5',
41 * F-number is 1.4142^5 = F5.6.
42 */
43 public static final int TAG_APERTURE = 0x9202;
44 /**
45 * When image format is no compression, this value shows the number of bits
46 * per component for each pixel. Usually this value is '8,8,8'.
47 */
48 public static final int TAG_BITS_PER_SAMPLE = 0x0102;
49 /**
50 * Shows compression method for Thumbnail.
51 * 1 = Uncompressed
52 * 2 = CCITT 1D
53 * 3 = T4/Group 3 Fax
54 * 4 = T6/Group 4 Fax
55 * 5 = LZW
56 * 6 = JPEG (old-style)
57 * 7 = JPEG
58 * 8 = Adobe Deflate
59 * 9 = JBIG B&W
60 * 10 = JBIG Color
61 * 32766 = Next
62 * 32771 = CCIRLEW
63 * 32773 = PackBits
64 * 32809 = Thunderscan
65 * 32895 = IT8CTPAD
66 * 32896 = IT8LW
67 * 32897 = IT8MP
68 * 32898 = IT8BL
69 * 32908 = PixarFilm
70 * 32909 = PixarLog
71 * 32946 = Deflate
72 * 32947 = DCS
73 * 34661 = JBIG
74 * 34676 = SGILog
75 * 34677 = SGILog24
76 * 34712 = JPEG 2000
77 * 34713 = Nikon NEF Compressed
78 */
79 public static final int TAG_COMPRESSION = 0x0103;
80 public static final int COMPRESSION_NONE = 1;
81 public static final int COMPRESSION_JPEG = 6;
82
83 /**
84 * Shows the color space of the image data components.
85 * 0 = WhiteIsZero
86 * 1 = BlackIsZero
87 * 2 = RGB
88 * 3 = RGB Palette
89 * 4 = Transparency Mask
90 * 5 = CMYK
91 * 6 = YCbCr
92 * 8 = CIELab
93 * 9 = ICCLab
94 * 10 = ITULab
95 * 32803 = Color Filter Array
96 * 32844 = Pixar LogL
97 * 32845 = Pixar LogLuv
98 * 34892 = Linear Raw
99 */
100 public static final int TAG_PHOTOMETRIC_INTERPRETATION = 0x0106;
101 /**
102 * 1 = No dithering or halftoning
103 * 2 = Ordered dither or halftone
104 * 3 = Randomized dither
105 */
106 public static final int TAG_THRESHOLDING = 0x0107;
107 public static final int PHOTOMETRIC_INTERPRETATION_MONOCHROME = 1;
108 public static final int PHOTOMETRIC_INTERPRETATION_RGB = 2;
109 public static final int PHOTOMETRIC_INTERPRETATION_YCBCR = 6;
110
111 /** The position in the file of raster data. */
112 public static final int TAG_STRIP_OFFSETS = 0x0111;
113 /** Each pixel is composed of this many samples. */
114 public static final int TAG_SAMPLES_PER_PIXEL = 0x0115;
115 /** The raster is codified by a single block of data holding this many rows. */
116 public static final int TAG_ROWS_PER_STRIP = 0x116;
117 /** The size of the raster data in bytes. */
118 public static final int TAG_STRIP_BYTE_COUNTS = 0x0117;
119 public static final int TAG_MIN_SAMPLE_VALUE = 0x0118;
120 public static final int TAG_MAX_SAMPLE_VALUE = 0x0119;
121 /**
122 * When image format is no compression YCbCr, this value shows byte aligns of
123 * YCbCr data. If value is '1', Y/Cb/Cr value is chunky format, contiguous for
124 * each subsampling pixel. If value is '2', Y/Cb/Cr value is separated and
125 * stored to Y plane/Cb plane/Cr plane format.
126 */
127 public static final int TAG_PLANAR_CONFIGURATION = 0x011C;
128 public static final int TAG_YCBCR_SUBSAMPLING = 0x0212;
129 public static final int TAG_IMAGE_DESCRIPTION = 0x010E;
130 public static final int TAG_SOFTWARE = 0x0131;
131 public static final int TAG_DATETIME = 0x0132;
132 public static final int TAG_WHITE_POINT = 0x013E;
133 public static final int TAG_PRIMARY_CHROMATICITIES = 0x013F;
134 public static final int TAG_YCBCR_COEFFICIENTS = 0x0211;
135 public static final int TAG_REFERENCE_BLACK_WHITE = 0x0214;
136 public static final int TAG_COPYRIGHT = 0x8298;
137
138 /**
139 * The new subfile type tag.
140 * 0 = Full-resolution Image
141 * 1 = Reduced-resolution image
142 * 2 = Single page of multi-page image
143 * 3 = Single page of multi-page reduced-resolution image
144 * 4 = Transparency mask
145 * 5 = Transparency mask of reduced-resolution image
146 * 6 = Transparency mask of multi-page image
147 * 7 = Transparency mask of reduced-resolution multi-page image
148 */
149 public static final int TAG_NEW_SUBFILE_TYPE = 0x00FE;
150 /**
151 * The old subfile type tag.
152 * 1 = Full-resolution image (Main image)
153 * 2 = Reduced-resolution image (Thumbnail)
154 * 3 = Single page of multi-page image
155 */
156 public static final int TAG_SUBFILE_TYPE = 0x00FF;
157 public static final int TAG_TRANSFER_FUNCTION = 0x012D;
158 public static final int TAG_ARTIST = 0x013B;
159 public static final int TAG_PREDICTOR = 0x013D;
160 public static final int TAG_TILE_WIDTH = 0x0142;
161 public static final int TAG_TILE_LENGTH = 0x0143;
162 public static final int TAG_TILE_OFFSETS = 0x0144;
163 public static final int TAG_TILE_BYTE_COUNTS = 0x0145;
164 public static final int TAG_JPEG_TABLES = 0x015B;
165 public static final int TAG_CFA_REPEAT_PATTERN_DIM = 0x828D;
166 /** There are two definitions for CFA pattern, I don't know the difference... */
167 public static final int TAG_CFA_PATTERN_2 = 0x828E;
168 public static final int TAG_BATTERY_LEVEL = 0x828F;
169 public static final int TAG_IPTC_NAA = 0x83BB;
170 public static final int TAG_INTER_COLOR_PROFILE = 0x8773;
171 public static final int TAG_SPECTRAL_SENSITIVITY = 0x8824;
172 public static final int TAG_OECF = 0x8828;
173 public static final int TAG_INTERLACE = 0x8829;
174 public static final int TAG_TIME_ZONE_OFFSET = 0x882A;
175 public static final int TAG_SELF_TIMER_MODE = 0x882B;
176 public static final int TAG_FLASH_ENERGY = 0x920B;
177 public static final int TAG_SPATIAL_FREQ_RESPONSE = 0x920C;
178 public static final int TAG_NOISE = 0x920D;
179 public static final int TAG_IMAGE_NUMBER = 0x9211;
180 public static final int TAG_SECURITY_CLASSIFICATION = 0x9212;
181 public static final int TAG_IMAGE_HISTORY = 0x9213;
182 public static final int TAG_SUBJECT_LOCATION = 0x9214;
183 /** There are two definitions for exposure index, I don't know the difference... */
184 public static final int TAG_EXPOSURE_INDEX_2 = 0x9215;
185 public static final int TAG_TIFF_EP_STANDARD_ID = 0x9216;
186 public static final int TAG_FLASH_ENERGY_2 = 0xA20B;
187 public static final int TAG_SPATIAL_FREQ_RESPONSE_2 = 0xA20C;
188 public static final int TAG_SUBJECT_LOCATION_2 = 0xA214;
189 public static final int TAG_MAKE = 0x010F;
190 public static final int TAG_MODEL = 0x0110;
191 public static final int TAG_ORIENTATION = 0x0112;
192 public static final int TAG_X_RESOLUTION = 0x011A;
193 public static final int TAG_Y_RESOLUTION = 0x011B;
194 public static final int TAG_PAGE_NAME = 0x011D;
195 public static final int TAG_RESOLUTION_UNIT = 0x0128;
196 public static final int TAG_THUMBNAIL_OFFSET = 0x0201;
197 public static final int TAG_THUMBNAIL_LENGTH = 0x0202;
198 public static final int TAG_YCBCR_POSITIONING = 0x0213;
199 /**
200 * Exposure time (reciprocal of shutter speed). Unit is second.
201 */
202 public static final int TAG_EXPOSURE_TIME = 0x829A;
203 /**
204 * The actual F-number(F-stop) of lens when the image was taken.
205 */
206 public static final int TAG_FNUMBER = 0x829D;
207 /**
208 * Exposure program that the camera used when image was taken. '1' means
209 * manual control, '2' program normal, '3' aperture priority, '4' shutter
210 * priority, '5' program creative (slow program), '6' program action
211 * (high-speed program), '7' portrait mode, '8' landscape mode.
212 */
213 public static final int TAG_EXPOSURE_PROGRAM = 0x8822;
214 public static final int TAG_ISO_EQUIVALENT = 0x8827;
215 public static final int TAG_EXIF_VERSION = 0x9000;
216 public static final int TAG_DATETIME_ORIGINAL = 0x9003;
217 public static final int TAG_DATETIME_DIGITIZED = 0x9004;
218 public static final int TAG_COMPONENTS_CONFIGURATION = 0x9101;
219 /**
220 * Average (rough estimate) compression level in JPEG bits per pixel.
221 * */
222 public static final int TAG_COMPRESSION_LEVEL = 0x9102;
223 /**
224 * Shutter speed by APEX value. To convert this value to ordinary 'Shutter Speed';
225 * calculate this value's power of 2, then reciprocal. For example, if the
226 * ShutterSpeedValue is '4', shutter speed is 1/(24)=1/16 second.
227 */
228 public static final int TAG_SHUTTER_SPEED = 0x9201;
229 public static final int TAG_BRIGHTNESS_VALUE = 0x9203;
230 public static final int TAG_EXPOSURE_BIAS = 0x9204;
231 /**
232 * Maximum aperture value of lens. You can convert to F-number by calculating
233 * power of root 2 (same process of ApertureValue:0x9202).
234 * The actual aperture value of lens when the image was taken. To convert this
235 * value to ordinary f-number(f-stop), calculate the value's power of root 2
236 * (=1.4142). For example, if the ApertureValue is '5', f-number is 1.41425^5 = F5.6.
237 */
238 public static final int TAG_MAX_APERTURE = 0x9205;
239 /**
240 * Indicates the distance the autofocus camera is focused to. Tends to be less accurate as distance increases.
241 */
242 public static final int TAG_SUBJECT_DISTANCE = 0x9206;
243 /**
244 * Exposure metering method. '0' means unknown, '1' average, '2' center
245 * weighted average, '3' spot, '4' multi-spot, '5' multi-segment, '6' partial,
246 * '255' other.
247 */
248 public static final int TAG_METERING_MODE = 0x9207;
249
250 public static final int TAG_LIGHT_SOURCE = 0x9208;
251 /**
252 * White balance (aka light source). '0' means unknown, '1' daylight,
253 * '2' fluorescent, '3' tungsten, '10' flash, '17' standard light A,
254 * '18' standard light B, '19' standard light C, '20' D55, '21' D65,
255 * '22' D75, '255' other.
256 */
257 public static final int TAG_WHITE_BALANCE = 0x9208;
258 /**
259 * 0x0 = 0000000 = No Flash
260 * 0x1 = 0000001 = Fired
261 * 0x5 = 0000101 = Fired, Return not detected
262 * 0x7 = 0000111 = Fired, Return detected
263 * 0x9 = 0001001 = On
264 * 0xd = 0001101 = On, Return not detected
265 * 0xf = 0001111 = On, Return detected
266 * 0x10 = 0010000 = Off
267 * 0x18 = 0011000 = Auto, Did not fire
268 * 0x19 = 0011001 = Auto, Fired
269 * 0x1d = 0011101 = Auto, Fired, Return not detected
270 * 0x1f = 0011111 = Auto, Fired, Return detected
271 * 0x20 = 0100000 = No flash function
272 * 0x41 = 1000001 = Fired, Red-eye reduction
273 * 0x45 = 1000101 = Fired, Red-eye reduction, Return not detected
274 * 0x47 = 1000111 = Fired, Red-eye reduction, Return detected
275 * 0x49 = 1001001 = On, Red-eye reduction
276 * 0x4d = 1001101 = On, Red-eye reduction, Return not detected
277 * 0x4f = 1001111 = On, Red-eye reduction, Return detected
278 * 0x59 = 1011001 = Auto, Fired, Red-eye reduction
279 * 0x5d = 1011101 = Auto, Fired, Red-eye reduction, Return not detected
280 * 0x5f = 1011111 = Auto, Fired, Red-eye reduction, Return detected
281 * 6543210 (positions)
282 *
283 * This is a bitmask.
284 * 0 = flash fired
285 * 1 = return detected
286 * 2 = return able to be detected
287 * 3 = unknown
288 * 4 = auto used
289 * 5 = unknown
290 * 6 = red eye reduction used
291 */
292 public static final int TAG_FLASH = 0x9209;
293 /**
294 * Focal length of lens used to take image. Unit is millimeter.
295 * Nice digital cameras actually save the focal length as a function of how far they are zoomed in.
296 */
297 public static final int TAG_FOCAL_LENGTH = 0x920A;
298 public static final int TAG_USER_COMMENT = 0x9286;
299 public static final int TAG_SUBSECOND_TIME = 0x9290;
300 public static final int TAG_SUBSECOND_TIME_ORIGINAL = 0x9291;
301 public static final int TAG_SUBSECOND_TIME_DIGITIZED = 0x9292;
302 public static final int TAG_FLASHPIX_VERSION = 0xA000;
303 /**
304 * Defines Color Space. DCF image must use sRGB color space so value is
305 * always '1'. If the picture uses the other color space, value is
306 * '65535':Uncalibrated.
307 */
308 public static final int TAG_COLOR_SPACE = 0xA001;
309 public static final int TAG_EXIF_IMAGE_WIDTH = 0xA002;
310 public static final int TAG_EXIF_IMAGE_HEIGHT = 0xA003;
311 public static final int TAG_RELATED_SOUND_FILE = 0xA004;
312 public static final int TAG_FOCAL_PLANE_X_RES = 0xA20E;
313 public static final int TAG_FOCAL_PLANE_Y_RES = 0xA20F;
314 /**
315 * Unit of FocalPlaneXResoluton/FocalPlaneYResolution. '1' means no-unit,
316 * '2' inch, '3' centimeter.
317 *
318 * Note: Some of Fujifilm's digicam(e.g.FX2700,FX2900,Finepix4700Z/40i etc)
319 * uses value '3' so it must be 'centimeter', but it seems that they use a
320 * '8.3mm?'(1/3in.?) to their ResolutionUnit. Fuji's BUG? Finepix4900Z has
321 * been changed to use value '2' but it doesn't match to actual value also.
322 */
323 public static final int TAG_FOCAL_PLANE_UNIT = 0xA210;
324 public static final int TAG_EXPOSURE_INDEX = 0xA215;
325 public static final int TAG_SENSING_METHOD = 0xA217;
326 public static final int TAG_FILE_SOURCE = 0xA300;
327 public static final int TAG_SCENE_TYPE = 0xA301;
328 public static final int TAG_CFA_PATTERN = 0xA302;
329
330 // these tags new with Exif 2.2 (?) [A401 - A4
331 /**
332 * This tag indicates the use of special processing on image data, such as rendering
333 * geared to output. When special processing is performed, the reader is expected to
334 * disable or minimize any further processing.
335 * Tag = 41985 (A401.H)
336 * Type = SHORT
337 * Count = 1
338 * Default = 0
339 * 0 = Normal process
340 * 1 = Custom process
341 * Other = reserved
342 */
343 public static final int TAG_CUSTOM_RENDERED = 0xA401;
344
345 /**
346 * This tag indicates the exposure mode set when the image was shot. In auto-bracketing
347 * mode, the camera shoots a series of frames of the same scene at different exposure settings.
348 * Tag = 41986 (A402.H)
349 * Type = SHORT
350 * Count = 1
351 * Default = none
352 * 0 = Auto exposure
353 * 1 = Manual exposure
354 * 2 = Auto bracket
355 * Other = reserved
356 */
357 public static final int TAG_EXPOSURE_MODE = 0xA402;
358
359 /**
360 * This tag indicates the white balance mode set when the image was shot.
361 * Tag = 41987 (A403.H)
362 * Type = SHORT
363 * Count = 1
364 * Default = none
365 * 0 = Auto white balance
366 * 1 = Manual white balance
367 * Other = reserved
368 */
369 public static final int TAG_WHITE_BALANCE_MODE = 0xA403;
370
371 /**
372 * This tag indicates the digital zoom ratio when the image was shot. If the
373 * numerator of the recorded value is 0, this indicates that digital zoom was
374 * not used.
375 * Tag = 41988 (A404.H)
376 * Type = RATIONAL
377 * Count = 1
378 * Default = none
379 */
380 public static final int TAG_DIGITAL_ZOOM_RATIO = 0xA404;
381
382 /**
383 * This tag indicates the equivalent focal length assuming a 35mm film camera,
384 * in mm. A value of 0 means the focal length is unknown. Note that this tag
385 * differs from the FocalLength tag.
386 * Tag = 41989 (A405.H)
387 * Type = SHORT
388 * Count = 1
389 * Default = none
390 */
391 public static final int TAG_35MM_FILM_EQUIV_FOCAL_LENGTH = 0xA405;
392
393 /**
394 * This tag indicates the type of scene that was shot. It can also be used to
395 * record the mode in which the image was shot. Note that this differs from
396 * the scene type (SceneType) tag.
397 * Tag = 41990 (A406.H)
398 * Type = SHORT
399 * Count = 1
400 * Default = 0
401 * 0 = Standard
402 * 1 = Landscape
403 * 2 = Portrait
404 * 3 = Night scene
405 * Other = reserved
406 */
407 public static final int TAG_SCENE_CAPTURE_TYPE = 0xA406;
408
409 /**
410 * This tag indicates the degree of overall image gain adjustment.
411 * Tag = 41991 (A407.H)
412 * Type = SHORT
413 * Count = 1
414 * Default = none
415 * 0 = None
416 * 1 = Low gain up
417 * 2 = High gain up
418 * 3 = Low gain down
419 * 4 = High gain down
420 * Other = reserved
421 */
422 public static final int TAG_GAIN_CONTROL = 0xA407;
423
424 /**
425 * This tag indicates the direction of contrast processing applied by the camera
426 * when the image was shot.
427 * Tag = 41992 (A408.H)
428 * Type = SHORT
429 * Count = 1
430 * Default = 0
431 * 0 = Normal
432 * 1 = Soft
433 * 2 = Hard
434 * Other = reserved
435 */
436 public static final int TAG_CONTRAST = 0xA408;
437
438 /**
439 * This tag indicates the direction of saturation processing applied by the camera
440 * when the image was shot.
441 * Tag = 41993 (A409.H)
442 * Type = SHORT
443 * Count = 1
444 * Default = 0
445 * 0 = Normal
446 * 1 = Low saturation
447 * 2 = High saturation
448 * Other = reserved
449 */
450 public static final int TAG_SATURATION = 0xA409;
451
452 /**
453 * This tag indicates the direction of sharpness processing applied by the camera
454 * when the image was shot.
455 * Tag = 41994 (A40A.H)
456 * Type = SHORT
457 * Count = 1
458 * Default = 0
459 * 0 = Normal
460 * 1 = Soft
461 * 2 = Hard
462 * Other = reserved
463 */
464 public static final int TAG_SHARPNESS = 0xA40A;
465
466 // TODO support this tag (I haven't seen a camera's actual implementation of this yet)
467
468 /**
469 * This tag indicates information on the picture-taking conditions of a particular
470 * camera model. The tag is used only to indicate the picture-taking conditions in
471 * the reader.
472 * Tag = 41995 (A40B.H)
473 * Type = UNDEFINED
474 * Count = Any
475 * Default = none
476 *
477 * The information is recorded in the format shown below. The data is recorded
478 * in Unicode using SHORT type for the number of display rows and columns and
479 * UNDEFINED type for the camera settings. The Unicode (UCS-2) string including
480 * Signature is NULL terminated. The specifics of the Unicode string are as given
481 * in ISO/IEC 10464-1.
482 *
483 * Length Type Meaning
484 * ------+-----------+------------------
485 * 2 SHORT Display columns
486 * 2 SHORT Display rows
487 * Any UNDEFINED Camera setting-1
488 * Any UNDEFINED Camera setting-2
489 * : : :
490 * Any UNDEFINED Camera setting-n
491 */
492 public static final int TAG_DEVICE_SETTING_DESCRIPTION = 0xA40B;
493
494 /**
495 * This tag indicates the distance to the subject.
496 * Tag = 41996 (A40C.H)
497 * Type = SHORT
498 * Count = 1
499 * Default = none
500 * 0 = unknown
501 * 1 = Macro
502 * 2 = Close view
503 * 3 = Distant view
504 * Other = reserved
505 */
506 public static final int TAG_SUBJECT_DISTANCE_RANGE = 0xA40C;
507
508 /**
509 * The image title, as used by Windows XP.
510 */
511 public static final int TAG_WIN_TITLE = 0x9C9B;
512
513 /**
514 * The image comment, as used by Windows XP.
515 */
516 public static final int TAG_WIN_COMMENT = 0x9C9C;
517
518 /**
519 * The image author, as used by Windows XP (called Artist in the Windows shell).
520 */
521 public static final int TAG_WIN_AUTHOR = 0x9C9D;
522
523 /**
524 * The image keywords, as used by Windows XP.
525 */
526 public static final int TAG_WIN_KEYWORDS = 0x9C9E;
527
528 /**
529 * The image subject, as used by Windows XP.
530 */
531 public static final int TAG_WIN_SUBJECT = 0x9C9F;
532
533 /**
534 * This tag indicates an identifier assigned uniquely to each image. It is
535 * recorded as an ASCII string equivalent to hexadecimal notation and 128-bit
536 * fixed length.
537 * Tag = 42016 (A420.H)
538 * Type = ASCII
539 * Count = 33
540 * Default = none
541 */
542 public static final int TAG_IMAGE_UNIQUE_ID = 0xA420;
543
544 public static final int TAG_THUMBNAIL_IMAGE_WIDTH = 0x0100;
545 public static final int TAG_THUMBNAIL_IMAGE_HEIGHT = 0x0101;
546 public static final int TAG_THUMBNAIL_DATA = 0xF001;
547
548 /**
549 * 1 = Normal
550 * 2 = Reversed
551 */
552 public static final int TAG_FILL_ORDER = 0x010A;
553 public static final int TAG_DOCUMENT_NAME = 0x010D;
554
555 protected static final HashMap tagNameMap = new HashMap();
556
557 static
558 {
559 tagNameMap.put(new Integer(TAG_FILL_ORDER), "Fill Order");
560 tagNameMap.put(new Integer(TAG_DOCUMENT_NAME), "Document Name");
561 tagNameMap.put(new Integer(0x1000), "Related Image File Format");
562 tagNameMap.put(new Integer(0x1001), "Related Image Width");
563 tagNameMap.put(new Integer(0x1002), "Related Image Length");
564 tagNameMap.put(new Integer(0x0156), "Transfer Range");
565 tagNameMap.put(new Integer(0x0200), "JPEG Proc");
566 tagNameMap.put(new Integer(0x8769), "Exif Offset");
567 tagNameMap.put(new Integer(TAG_COMPRESSION_LEVEL), "Compressed Bits Per Pixel");
568 tagNameMap.put(new Integer(0x927C), "Maker Note");
569 tagNameMap.put(new Integer(0xA005), "Interoperability Offset");
570
571 tagNameMap.put(new Integer(TAG_NEW_SUBFILE_TYPE), "New Subfile Type");
572 tagNameMap.put(new Integer(TAG_SUBFILE_TYPE), "Subfile Type");
573 tagNameMap.put(new Integer(TAG_THUMBNAIL_IMAGE_WIDTH), "Thumbnail Image Width");
574 tagNameMap.put(new Integer(TAG_THUMBNAIL_IMAGE_HEIGHT), "Thumbnail Image Height");
575 tagNameMap.put(new Integer(TAG_BITS_PER_SAMPLE), "Bits Per Sample");
576 tagNameMap.put(new Integer(TAG_COMPRESSION), "Compression");
577 tagNameMap.put(new Integer(TAG_PHOTOMETRIC_INTERPRETATION), "Photometric Interpretation");
578 tagNameMap.put(new Integer(TAG_THRESHOLDING), "Thresholding");
579 tagNameMap.put(new Integer(TAG_IMAGE_DESCRIPTION), "Image Description");
580 tagNameMap.put(new Integer(TAG_MAKE), "Make");
581 tagNameMap.put(new Integer(TAG_MODEL), "Model");
582 tagNameMap.put(new Integer(TAG_STRIP_OFFSETS), "Strip Offsets");
583 tagNameMap.put(new Integer(TAG_ORIENTATION), "Orientation");
584 tagNameMap.put(new Integer(TAG_SAMPLES_PER_PIXEL), "Samples Per Pixel");
585 tagNameMap.put(new Integer(TAG_ROWS_PER_STRIP), "Rows Per Strip");
586 tagNameMap.put(new Integer(TAG_STRIP_BYTE_COUNTS), "Strip Byte Counts");
587 tagNameMap.put(new Integer(TAG_X_RESOLUTION), "X Resolution");
588 tagNameMap.put(new Integer(TAG_Y_RESOLUTION), "Y Resolution");
589 tagNameMap.put(new Integer(TAG_PAGE_NAME), "Page Name");
590 tagNameMap.put(new Integer(TAG_PLANAR_CONFIGURATION), "Planar Configuration");
591 tagNameMap.put(new Integer(TAG_RESOLUTION_UNIT), "Resolution Unit");
592 tagNameMap.put(new Integer(TAG_TRANSFER_FUNCTION), "Transfer Function");
593 tagNameMap.put(new Integer(TAG_SOFTWARE), "Software");
594 tagNameMap.put(new Integer(TAG_DATETIME), "Date/Time");
595 tagNameMap.put(new Integer(TAG_ARTIST), "Artist");
596 tagNameMap.put(new Integer(TAG_PREDICTOR), "Predictor");
597 tagNameMap.put(new Integer(TAG_WHITE_POINT), "White Point");
598 tagNameMap.put(new Integer(TAG_PRIMARY_CHROMATICITIES), "Primary Chromaticities");
599 tagNameMap.put(new Integer(TAG_TILE_WIDTH), "Tile Width");
600 tagNameMap.put(new Integer(TAG_TILE_LENGTH), "Tile Length");
601 tagNameMap.put(new Integer(TAG_TILE_OFFSETS), "Tile Offsets");
602 tagNameMap.put(new Integer(TAG_TILE_BYTE_COUNTS), "Tile Byte Counts");
603 tagNameMap.put(new Integer(TAG_SUB_IFDS), "Sub IFDs");
604 tagNameMap.put(new Integer(TAG_JPEG_TABLES), "JPEG Tables");
605 tagNameMap.put(new Integer(TAG_THUMBNAIL_OFFSET), "Thumbnail Offset");
606 tagNameMap.put(new Integer(TAG_THUMBNAIL_LENGTH), "Thumbnail Length");
607 tagNameMap.put(new Integer(TAG_THUMBNAIL_DATA), "Thumbnail Data");
608 tagNameMap.put(new Integer(TAG_YCBCR_COEFFICIENTS), "YCbCr Coefficients");
609 tagNameMap.put(new Integer(TAG_YCBCR_SUBSAMPLING), "YCbCr Sub-Sampling");
610 tagNameMap.put(new Integer(TAG_YCBCR_POSITIONING), "YCbCr Positioning");
611 tagNameMap.put(new Integer(TAG_REFERENCE_BLACK_WHITE), "Reference Black/White");
612 tagNameMap.put(new Integer(TAG_CFA_REPEAT_PATTERN_DIM), "CFA Repeat Pattern Dim");
613 tagNameMap.put(new Integer(TAG_CFA_PATTERN_2), "CFA Pattern");
614 tagNameMap.put(new Integer(TAG_BATTERY_LEVEL), "Battery Level");
615 tagNameMap.put(new Integer(TAG_COPYRIGHT), "Copyright");
616 tagNameMap.put(new Integer(TAG_EXPOSURE_TIME), "Exposure Time");
617 tagNameMap.put(new Integer(TAG_FNUMBER), "F-Number");
618 tagNameMap.put(new Integer(TAG_IPTC_NAA), "IPTC/NAA");
619 tagNameMap.put(new Integer(TAG_INTER_COLOR_PROFILE), "Inter Color Profile");
620 tagNameMap.put(new Integer(TAG_EXPOSURE_PROGRAM), "Exposure Program");
621 tagNameMap.put(new Integer(TAG_SPECTRAL_SENSITIVITY), "Spectral Sensitivity");
622 tagNameMap.put(new Integer(TAG_GPS_INFO), "GPS Info");
623 tagNameMap.put(new Integer(TAG_ISO_EQUIVALENT), "ISO Speed Ratings");
624 tagNameMap.put(new Integer(TAG_OECF), "OECF");
625 tagNameMap.put(new Integer(TAG_INTERLACE), "Interlace");
626 tagNameMap.put(new Integer(TAG_TIME_ZONE_OFFSET), "Time Zone Offset");
627 tagNameMap.put(new Integer(TAG_SELF_TIMER_MODE), "Self Timer Mode");
628 tagNameMap.put(new Integer(TAG_EXIF_VERSION), "Exif Version");
629 tagNameMap.put(new Integer(TAG_DATETIME_ORIGINAL), "Date/Time Original");
630 tagNameMap.put(new Integer(TAG_DATETIME_DIGITIZED), "Date/Time Digitized");
631 tagNameMap.put(new Integer(TAG_COMPONENTS_CONFIGURATION), "Components Configuration");
632 tagNameMap.put(new Integer(TAG_SHUTTER_SPEED), "Shutter Speed Value");
633 tagNameMap.put(new Integer(TAG_APERTURE), "Aperture Value");
634 tagNameMap.put(new Integer(TAG_BRIGHTNESS_VALUE), "Brightness Value");
635 tagNameMap.put(new Integer(TAG_EXPOSURE_BIAS), "Exposure Bias Value");
636 tagNameMap.put(new Integer(TAG_MAX_APERTURE), "Max Aperture Value");
637 tagNameMap.put(new Integer(TAG_SUBJECT_DISTANCE), "Subject Distance");
638 tagNameMap.put(new Integer(TAG_METERING_MODE), "Metering Mode");
639 tagNameMap.put(new Integer(TAG_WHITE_BALANCE), "Light Source");
640 tagNameMap.put(new Integer(TAG_FLASH), "Flash");
641 tagNameMap.put(new Integer(TAG_FOCAL_LENGTH), "Focal Length");
642 tagNameMap.put(new Integer(TAG_FLASH_ENERGY), "Flash Energy");
643 tagNameMap.put(new Integer(TAG_SPATIAL_FREQ_RESPONSE), "Spatial Frequency Response");
644 tagNameMap.put(new Integer(TAG_NOISE), "Noise");
645 tagNameMap.put(new Integer(TAG_IMAGE_NUMBER), "Image Number");
646 tagNameMap.put(new Integer(TAG_SECURITY_CLASSIFICATION), "Security Classification");
647 tagNameMap.put(new Integer(TAG_IMAGE_HISTORY), "Image History");
648 tagNameMap.put(new Integer(TAG_SUBJECT_LOCATION), "Subject Location");
649 tagNameMap.put(new Integer(TAG_EXPOSURE_INDEX), "Exposure Index");
650 tagNameMap.put(new Integer(TAG_TIFF_EP_STANDARD_ID), "TIFF/EP Standard ID");
651 tagNameMap.put(new Integer(TAG_USER_COMMENT), "User Comment");
652 tagNameMap.put(new Integer(TAG_SUBSECOND_TIME), "Sub-Sec Time");
653 tagNameMap.put(new Integer(TAG_SUBSECOND_TIME_ORIGINAL), "Sub-Sec Time Original");
654 tagNameMap.put(new Integer(TAG_SUBSECOND_TIME_DIGITIZED), "Sub-Sec Time Digitized");
655 tagNameMap.put(new Integer(TAG_FLASHPIX_VERSION), "FlashPix Version");
656 tagNameMap.put(new Integer(TAG_COLOR_SPACE), "Color Space");
657 tagNameMap.put(new Integer(TAG_EXIF_IMAGE_WIDTH), "Exif Image Width");
658 tagNameMap.put(new Integer(TAG_EXIF_IMAGE_HEIGHT), "Exif Image Height");
659 tagNameMap.put(new Integer(TAG_RELATED_SOUND_FILE), "Related Sound File");
660 // 0x920B in TIFF/EP
661 tagNameMap.put(new Integer(TAG_FLASH_ENERGY_2), "Flash Energy");
662 // 0x920C in TIFF/EP
663 tagNameMap.put(new Integer(TAG_SPATIAL_FREQ_RESPONSE_2), "Spatial Frequency Response");
664 // 0x920E in TIFF/EP
665 tagNameMap.put(new Integer(TAG_FOCAL_PLANE_X_RES), "Focal Plane X Resolution");
666 // 0x920F in TIFF/EP
667 tagNameMap.put(new Integer(TAG_FOCAL_PLANE_Y_RES), "Focal Plane Y Resolution");
668 // 0x9210 in TIFF/EP
669 tagNameMap.put(new Integer(TAG_FOCAL_PLANE_UNIT), "Focal Plane Resolution Unit");
670 // 0x9214 in TIFF/EP
671 tagNameMap.put(new Integer(TAG_SUBJECT_LOCATION_2), "Subject Location");
672 // 0x9215 in TIFF/EP
673 tagNameMap.put(new Integer(TAG_EXPOSURE_INDEX_2), "Exposure Index");
674 // 0x9217 in TIFF/EP
675 tagNameMap.put(new Integer(TAG_SENSING_METHOD), "Sensing Method");
676 tagNameMap.put(new Integer(TAG_FILE_SOURCE), "File Source");
677 tagNameMap.put(new Integer(TAG_SCENE_TYPE), "Scene Type");
678 tagNameMap.put(new Integer(TAG_CFA_PATTERN), "CFA Pattern");
679
680 tagNameMap.put(new Integer(TAG_CUSTOM_RENDERED), "Custom Rendered");
681 tagNameMap.put(new Integer(TAG_EXPOSURE_MODE), "Exposure Mode");
682 tagNameMap.put(new Integer(TAG_WHITE_BALANCE_MODE), "White Balance");
683 tagNameMap.put(new Integer(TAG_DIGITAL_ZOOM_RATIO), "Digital Zoom Ratio");
684 tagNameMap.put(new Integer(TAG_35MM_FILM_EQUIV_FOCAL_LENGTH), "Focal Length 35");
685 tagNameMap.put(new Integer(TAG_SCENE_CAPTURE_TYPE), "Scene Capture Type");
686 tagNameMap.put(new Integer(TAG_GAIN_CONTROL), "Gain Control");
687 tagNameMap.put(new Integer(TAG_CONTRAST), "Contrast");
688 tagNameMap.put(new Integer(TAG_SATURATION), "Saturation");
689 tagNameMap.put(new Integer(TAG_SHARPNESS), "Sharpness");
690 tagNameMap.put(new Integer(TAG_DEVICE_SETTING_DESCRIPTION), "Device Setting Description");
691 tagNameMap.put(new Integer(TAG_SUBJECT_DISTANCE_RANGE), "Subject Distance Range");
692
693 tagNameMap.put(new Integer(TAG_WIN_AUTHOR), "Windows XP Author");
694 tagNameMap.put(new Integer(TAG_WIN_COMMENT), "Windows XP Comment");
695 tagNameMap.put(new Integer(TAG_WIN_KEYWORDS), "Windows XP Keywords");
696 tagNameMap.put(new Integer(TAG_WIN_SUBJECT), "Windows XP Subject");
697 tagNameMap.put(new Integer(TAG_WIN_TITLE), "Windows XP Title");
698
699 tagNameMap.put(new Integer(TAG_MIN_SAMPLE_VALUE), "Minimum sample value");
700 tagNameMap.put(new Integer(TAG_MAX_SAMPLE_VALUE), "Maximum sample value");
701 }
702
703 public ExifDirectory()
704 {
705 this.setDescriptor(new ExifDescriptor(this));
706 }
707
708 public String getName()
709 {
710 return "Exif";
711 }
712
713 protected HashMap getTagNameMap()
714 {
715 return tagNameMap;
716 }
717
718 public byte[] getThumbnailData() throws MetadataException
719 {
720 if (!containsThumbnail())
721 return null;
722
723 return this.getByteArray(ExifDirectory.TAG_THUMBNAIL_DATA);
724 }
725
726 public void writeThumbnail(String filename) throws MetadataException, IOException
727 {
728 byte[] data = getThumbnailData();
729
730 if (data==null)
731 throw new MetadataException("No thumbnail data exists.");
732
733 FileOutputStream stream = null;
734 try {
735 stream = new FileOutputStream(filename);
736 stream.write(data);
737 } finally {
738 if (stream!=null)
739 stream.close();
740 }
741 }
742
743/*
744 // This thumbnail extraction code is not complete, and is included to assist anyone who feels like looking into
745 // it. Please share any progress with the original author, and hence the community. Thanks.
746
747 /**
748 *
749 * @return
750 * @throws MetadataException
751 * /
752 public Image getThumbnailImage() throws MetadataException
753 {
754 if (!containsThumbnail())
755 return null;
756
757 int compression = 0;
758 try {
759 compression = this.getInt(ExifDirectory.TAG_COMPRESSION);
760 } catch (Throwable e) {
761 this.addError("Unable to determine thumbnail type " + e.getMessage());
762 }
763
764 final byte[] thumbnailBytes = getThumbnailData();
765
766 if (compression == ExifDirectory.COMPRESSION_JPEG)
767 {
768 // JPEG Thumbnail
769 // operate directly on thumbnailBytes
770// try {
771// int offset = this.getInt(ExifDirectory.TAG_THUMBNAIL_OFFSET);
772// int length = this.getInt(ExifDirectory.TAG_THUMBNAIL_LENGTH);
773// byte[] result = new byte[length];
774// for (int i = 0; i<result.length; i++) {
775// result[i] = _data[tiffHeaderOffset + offset + i];
776// }
777// this.setByteArray(ExifDirectory.TAG_THUMBNAIL_DATA, result);
778// } catch (Throwable e) {
779// this.addError("Unable to extract thumbnail: " + e.getMessage());
780// }
781 // TODO decode the JPEG bytes as an image
782 return null; //new Image();
783 }
784 else if (compression == ExifDirectory.COMPRESSION_NONE)
785 {
786 // uncompressed thumbnail (raw RGB data)
787 if (!this.containsTag(ExifDirectory.TAG_PHOTOMETRIC_INTERPRETATION))
788 return null;
789
790 try
791 {
792 // If the image is RGB format, then convert it to a bitmap
793 final int photometricInterpretation = this.getInt(ExifDirectory.TAG_PHOTOMETRIC_INTERPRETATION);
794 if (photometricInterpretation == ExifDirectory.PHOTOMETRIC_INTERPRETATION_RGB)
795 {
796 // RGB
797 Image image = createImageFromRawRgb(thumbnailBytes);
798 return image;
799 }
800 else if (photometricInterpretation == ExifDirectory.PHOTOMETRIC_INTERPRETATION_YCBCR)
801 {
802 // YCbCr
803 Image image = createImageFromRawYCbCr(thumbnailBytes);
804 return image;
805 }
806 else if (photometricInterpretation == ExifDirectory.PHOTOMETRIC_INTERPRETATION_MONOCHROME)
807 {
808 // Monochrome
809 // TODO
810 return null;
811 }
812 } catch (Throwable e) {
813 this.addError("Unable to extract thumbnail: " + e.getMessage());
814 }
815 }
816 return null;
817 }
818
819 /**
820 * Handle the YCbCr thumbnail encoding used by Ricoh RDC4200/4300, Fuji DS-7/300 and DX-5/7/9 cameras.
821 *
822 * At DX-5/7/9, YCbCrSubsampling(0x0212) has values of '2,1', PlanarConfiguration(0x011c) has a value '1'. So the
823 * data align of this image is below.
824 *
825 * Y(0,0),Y(1,0),Cb(0,0),Cr(0,0), Y(2,0),Y(3,0),Cb(2,0),Cr(3.0), Y(4,0),Y(5,0),Cb(4,0),Cr(4,0). . . .
826 *
827 * The numerics in parenthesis are pixel coordinates. DX series' YCbCrCoefficients(0x0211) has values '0.299/0.587/0.114',
828 * ReferenceBlackWhite(0x0214) has values '0,255,128,255,128,255'. Therefore to convert from Y/Cb/Cr to RGB is;
829 *
830 * B(0,0)=(Cb-128)*(2-0.114*2)+Y(0,0)
831 * R(0,0)=(Cr-128)*(2-0.299*2)+Y(0,0)
832 * G(0,0)=(Y(0,0)-0.114*B(0,0)-0.299*R(0,0))/0.587
833 *
834 * Horizontal subsampling is a value '2', so you can calculate B(1,0)/R(1,0)/G(1,0) by using the Y(1,0) and Cr(0,0)/Cb(0,0).
835 * Repeat this conversion by value of ImageWidth(0x0100) and ImageLength(0x0101).
836 *
837 * @param thumbnailBytes
838 * @return
839 * @throws com.drew.metadata.MetadataException
840 * /
841 private Image createImageFromRawYCbCr(byte[] thumbnailBytes) throws MetadataException
842 {
843 /*
844 Y = 0.257R + 0.504G + 0.098B + 16
845 Cb = -0.148R - 0.291G + 0.439B + 128
846 Cr = 0.439R - 0.368G - 0.071B + 128
847
848 G = 1.164(Y-16) - 0.391(Cb-128) - 0.813(Cr-128)
849 R = 1.164(Y-16) + 1.596(Cr-128)
850 B = 1.164(Y-16) + 2.018(Cb-128)
851
852 R, G and B range from 0 to 255.
853 Y ranges from 16 to 235.
854 Cb and Cr range from 16 to 240.
855
856 http://www.faqs.org/faqs/graphics/colorspace-faq/
857 * /
858
859 int length = thumbnailBytes.length; // this.getInt(ExifDirectory.TAG_STRIP_BYTE_COUNTS);
860 final int imageWidth = this.getInt(ExifDirectory.TAG_THUMBNAIL_IMAGE_WIDTH);
861 final int imageHeight = this.getInt(ExifDirectory.TAG_THUMBNAIL_IMAGE_HEIGHT);
862// final int headerLength = 54;
863// byte[] result = new byte[length + headerLength];
864// // Add a windows BMP header described:
865// // http://www.onicos.com/staff/iz/formats/bmp.html
866// result[0] = 'B';
867// result[1] = 'M'; // File Type identifier
868// result[3] = (byte)(result.length / 256);
869// result[2] = (byte)result.length;
870// result[10] = (byte)headerLength;
871// result[14] = 40; // MS Windows BMP header
872// result[18] = (byte)imageWidth;
873// result[22] = (byte)imageHeight;
874// result[26] = 1; // 1 Plane
875// result[28] = 24; // Colour depth
876// result[34] = (byte)length;
877// result[35] = (byte)(length / 256);
878
879 final BufferedImage image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
880
881 // order is YCbCr and image is upside down, bitmaps are BGR
882//// for (int i = headerLength, dataOffset = length; i<result.length; i += 3, dataOffset -= 3)
883// {
884// final int y = thumbnailBytes[dataOffset - 2] & 0xFF;
885// final int cb = thumbnailBytes[dataOffset - 1] & 0xFF;
886// final int cr = thumbnailBytes[dataOffset] & 0xFF;
887// if (y<16 || y>235 || cb<16 || cb>240 || cr<16 || cr>240)
888// "".toString();
889//
890// int g = (int)(1.164*(y-16) - 0.391*(cb-128) - 0.813*(cr-128));
891// int r = (int)(1.164*(y-16) + 1.596*(cr-128));
892// int b = (int)(1.164*(y-16) + 2.018*(cb-128));
893//
894//// result[i] = (byte)b;
895//// result[i + 1] = (byte)g;
896//// result[i + 2] = (byte)r;
897//
898// // TODO compose the image here
899// image.setRGB(1, 2, 3);
900// }
901
902 return image;
903 }
904
905 /**
906 * Creates a thumbnail image in (Windows) BMP format from raw RGB data.
907 * @param thumbnailBytes
908 * @return
909 * @throws com.drew.metadata.MetadataException
910 * /
911 private Image createImageFromRawRgb(byte[] thumbnailBytes) throws MetadataException
912 {
913 final int length = thumbnailBytes.length; // this.getInt(ExifDirectory.TAG_STRIP_BYTE_COUNTS);
914 final int imageWidth = this.getInt(ExifDirectory.TAG_THUMBNAIL_IMAGE_WIDTH);
915 final int imageHeight = this.getInt(ExifDirectory.TAG_THUMBNAIL_IMAGE_HEIGHT);
916// final int headerlength = 54;
917// final byte[] result = new byte[length + headerlength];
918// // Add a windows BMP header described:
919// // http://www.onicos.com/staff/iz/formats/bmp.html
920// result[0] = 'B';
921// result[1] = 'M'; // File Type identifier
922// result[3] = (byte)(result.length / 256);
923// result[2] = (byte)result.length;
924// result[10] = (byte)headerlength;
925// result[14] = 40; // MS Windows BMP header
926// result[18] = (byte)imageWidth;
927// result[22] = (byte)imageHeight;
928// result[26] = 1; // 1 Plane
929// result[28] = 24; // Colour depth
930// result[34] = (byte)length;
931// result[35] = (byte)(length / 256);
932
933 final BufferedImage image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
934
935 // order is RGB and image is upside down, bitmaps are BGR
936// for (int i = headerlength, dataOffset = length; i<result.length; i += 3, dataOffset -= 3)
937// {
938// byte b = thumbnailBytes[dataOffset - 2];
939// byte g = thumbnailBytes[dataOffset - 1];
940// byte r = thumbnailBytes[dataOffset];
941//
942// // TODO compose the image here
943// image.setRGB(1, 2, 3);
944// }
945
946 return image;
947 }
948*/
949
950 public boolean containsThumbnail()
951 {
952 return containsTag(ExifDirectory.TAG_THUMBNAIL_DATA);
953 }
954}
Note: See TracBrowser for help on using the repository browser.