source: josm/trunk/src/com/drew/metadata/exif/ExifThumbnailDescriptor.java@ 8132

Last change on this file since 8132 was 8132, checked in by Don-vip, 9 years ago

fix #11162 - update to metadata-extractor 2.7.2

  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 11.6 KB
Line 
1/*
2 * Copyright 2002-2015 Drew Noakes
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * More information about this project is available at:
17 *
18 * https://drewnoakes.com/code/exif/
19 * https://github.com/drewnoakes/metadata-extractor
20 */
21
22package com.drew.metadata.exif;
23
24import com.drew.lang.Rational;
25import com.drew.lang.annotations.NotNull;
26import com.drew.lang.annotations.Nullable;
27import com.drew.metadata.TagDescriptor;
28
29import static com.drew.metadata.exif.ExifThumbnailDirectory.*;
30
31/**
32 * Provides human-readable string representations of tag values stored in a {@link ExifThumbnailDirectory}.
33 *
34 * @author Drew Noakes https://drewnoakes.com
35 */
36public class ExifThumbnailDescriptor extends TagDescriptor<ExifThumbnailDirectory>
37{
38 /**
39 * Dictates whether rational values will be represented in decimal format in instances
40 * where decimal notation is elegant (such as 1/2 -> 0.5, but not 1/3).
41 */
42 private final boolean _allowDecimalRepresentationOfRationals = true;
43
44 public ExifThumbnailDescriptor(@NotNull ExifThumbnailDirectory directory)
45 {
46 super(directory);
47 }
48
49 // Note for the potential addition of brightness presentation in eV:
50 // Brightness of taken subject. To calculate Exposure(Ev) from BrightnessValue(Bv),
51 // you must add SensitivityValue(Sv).
52 // Ev=BV+Sv Sv=log2(ISOSpeedRating/3.125)
53 // ISO100:Sv=5, ISO200:Sv=6, ISO400:Sv=7, ISO125:Sv=5.32.
54
55 /**
56 * Returns a descriptive value of the specified tag for this image.
57 * Where possible, known values will be substituted here in place of the raw
58 * tokens actually kept in the Exif segment. If no substitution is
59 * available, the value provided by getString(int) will be returned.
60 *
61 * @param tagType the tag to find a description for
62 * @return a description of the image's value for the specified tag, or
63 * <code>null</code> if the tag hasn't been defined.
64 */
65 @Override
66 @Nullable
67 public String getDescription(int tagType)
68 {
69 switch (tagType) {
70 case TAG_ORIENTATION:
71 return getOrientationDescription();
72 case TAG_RESOLUTION_UNIT:
73 return getResolutionDescription();
74 case TAG_YCBCR_POSITIONING:
75 return getYCbCrPositioningDescription();
76 case TAG_X_RESOLUTION:
77 return getXResolutionDescription();
78 case TAG_Y_RESOLUTION:
79 return getYResolutionDescription();
80 case TAG_THUMBNAIL_OFFSET:
81 return getThumbnailOffsetDescription();
82 case TAG_THUMBNAIL_LENGTH:
83 return getThumbnailLengthDescription();
84 case TAG_THUMBNAIL_IMAGE_WIDTH:
85 return getThumbnailImageWidthDescription();
86 case TAG_THUMBNAIL_IMAGE_HEIGHT:
87 return getThumbnailImageHeightDescription();
88 case TAG_BITS_PER_SAMPLE:
89 return getBitsPerSampleDescription();
90 case TAG_THUMBNAIL_COMPRESSION:
91 return getCompressionDescription();
92 case TAG_PHOTOMETRIC_INTERPRETATION:
93 return getPhotometricInterpretationDescription();
94 case TAG_ROWS_PER_STRIP:
95 return getRowsPerStripDescription();
96 case TAG_STRIP_BYTE_COUNTS:
97 return getStripByteCountsDescription();
98 case TAG_SAMPLES_PER_PIXEL:
99 return getSamplesPerPixelDescription();
100 case TAG_PLANAR_CONFIGURATION:
101 return getPlanarConfigurationDescription();
102 case TAG_YCBCR_SUBSAMPLING:
103 return getYCbCrSubsamplingDescription();
104 case TAG_REFERENCE_BLACK_WHITE:
105 return getReferenceBlackWhiteDescription();
106 default:
107 return super.getDescription(tagType);
108 }
109 }
110
111 @Nullable
112 public String getReferenceBlackWhiteDescription()
113 {
114 int[] ints = _directory.getIntArray(TAG_REFERENCE_BLACK_WHITE);
115 if (ints == null || ints.length < 6)
116 return null;
117 int blackR = ints[0];
118 int whiteR = ints[1];
119 int blackG = ints[2];
120 int whiteG = ints[3];
121 int blackB = ints[4];
122 int whiteB = ints[5];
123 return String.format("[%d,%d,%d] [%d,%d,%d]", blackR, blackG, blackB, whiteR, whiteG, whiteB);
124 }
125
126 @Nullable
127 public String getYCbCrSubsamplingDescription()
128 {
129 int[] positions = _directory.getIntArray(TAG_YCBCR_SUBSAMPLING);
130 if (positions == null || positions.length < 2)
131 return null;
132 if (positions[0] == 2 && positions[1] == 1) {
133 return "YCbCr4:2:2";
134 } else if (positions[0] == 2 && positions[1] == 2) {
135 return "YCbCr4:2:0";
136 } else {
137 return "(Unknown)";
138 }
139 }
140
141 @Nullable
142 public String getPlanarConfigurationDescription()
143 {
144 // When image format is no compression YCbCr, this value shows byte aligns of YCbCr
145 // data. If value is '1', Y/Cb/Cr value is chunky format, contiguous for each subsampling
146 // pixel. If value is '2', Y/Cb/Cr value is separated and stored to Y plane/Cb plane/Cr
147 // plane format.
148 return getIndexedDescription(TAG_PLANAR_CONFIGURATION,
149 1,
150 "Chunky (contiguous for each subsampling pixel)",
151 "Separate (Y-plane/Cb-plane/Cr-plane format)"
152 );
153 }
154
155 @Nullable
156 public String getSamplesPerPixelDescription()
157 {
158 String value = _directory.getString(TAG_SAMPLES_PER_PIXEL);
159 return value == null ? null : value + " samples/pixel";
160 }
161
162 @Nullable
163 public String getRowsPerStripDescription()
164 {
165 final String value = _directory.getString(TAG_ROWS_PER_STRIP);
166 return value == null ? null : value + " rows/strip";
167 }
168
169 @Nullable
170 public String getStripByteCountsDescription()
171 {
172 final String value = _directory.getString(TAG_STRIP_BYTE_COUNTS);
173 return value == null ? null : value + " bytes";
174 }
175
176 @Nullable
177 public String getPhotometricInterpretationDescription()
178 {
179 // Shows the color space of the image data components
180 Integer value = _directory.getInteger(TAG_PHOTOMETRIC_INTERPRETATION);
181 if (value == null)
182 return null;
183 switch (value) {
184 case 0: return "WhiteIsZero";
185 case 1: return "BlackIsZero";
186 case 2: return "RGB";
187 case 3: return "RGB Palette";
188 case 4: return "Transparency Mask";
189 case 5: return "CMYK";
190 case 6: return "YCbCr";
191 case 8: return "CIELab";
192 case 9: return "ICCLab";
193 case 10: return "ITULab";
194 case 32803: return "Color Filter Array";
195 case 32844: return "Pixar LogL";
196 case 32845: return "Pixar LogLuv";
197 case 32892: return "Linear Raw";
198 default:
199 return "Unknown colour space";
200 }
201 }
202
203 @Nullable
204 public String getCompressionDescription()
205 {
206 Integer value = _directory.getInteger(TAG_THUMBNAIL_COMPRESSION);
207 if (value == null)
208 return null;
209 switch (value) {
210 case 1: return "Uncompressed";
211 case 2: return "CCITT 1D";
212 case 3: return "T4/Group 3 Fax";
213 case 4: return "T6/Group 4 Fax";
214 case 5: return "LZW";
215 case 6: return "JPEG (old-style)";
216 case 7: return "JPEG";
217 case 8: return "Adobe Deflate";
218 case 9: return "JBIG B&W";
219 case 10: return "JBIG Color";
220 case 32766: return "Next";
221 case 32771: return "CCIRLEW";
222 case 32773: return "PackBits";
223 case 32809: return "Thunderscan";
224 case 32895: return "IT8CTPAD";
225 case 32896: return "IT8LW";
226 case 32897: return "IT8MP";
227 case 32898: return "IT8BL";
228 case 32908: return "PixarFilm";
229 case 32909: return "PixarLog";
230 case 32946: return "Deflate";
231 case 32947: return "DCS";
232 case 32661: return "JBIG";
233 case 32676: return "SGILog";
234 case 32677: return "SGILog24";
235 case 32712: return "JPEG 2000";
236 case 32713: return "Nikon NEF Compressed";
237 default:
238 return "Unknown compression";
239 }
240 }
241
242 @Nullable
243 public String getBitsPerSampleDescription()
244 {
245 String value = _directory.getString(TAG_BITS_PER_SAMPLE);
246 return value == null ? null : value + " bits/component/pixel";
247 }
248
249 @Nullable
250 public String getThumbnailImageWidthDescription()
251 {
252 String value = _directory.getString(TAG_THUMBNAIL_IMAGE_WIDTH);
253 return value == null ? null : value + " pixels";
254 }
255
256 @Nullable
257 public String getThumbnailImageHeightDescription()
258 {
259 String value = _directory.getString(TAG_THUMBNAIL_IMAGE_HEIGHT);
260 return value == null ? null : value + " pixels";
261 }
262
263 @Nullable
264 public String getThumbnailLengthDescription()
265 {
266 String value = _directory.getString(TAG_THUMBNAIL_LENGTH);
267 return value == null ? null : value + " bytes";
268 }
269
270 @Nullable
271 public String getThumbnailOffsetDescription()
272 {
273 String value = _directory.getString(TAG_THUMBNAIL_OFFSET);
274 return value == null ? null : value + " bytes";
275 }
276
277 @Nullable
278 public String getYResolutionDescription()
279 {
280 Rational value = _directory.getRational(TAG_Y_RESOLUTION);
281 if (value == null)
282 return null;
283 final String unit = getResolutionDescription();
284 return value.toSimpleString(_allowDecimalRepresentationOfRationals) +
285 " dots per " +
286 (unit == null ? "unit" : unit.toLowerCase());
287 }
288
289 @Nullable
290 public String getXResolutionDescription()
291 {
292 Rational value = _directory.getRational(TAG_X_RESOLUTION);
293 if (value == null)
294 return null;
295 final String unit = getResolutionDescription();
296 return value.toSimpleString(_allowDecimalRepresentationOfRationals) +
297 " dots per " +
298 (unit == null ? "unit" : unit.toLowerCase());
299 }
300
301 @Nullable
302 public String getYCbCrPositioningDescription()
303 {
304 return getIndexedDescription(TAG_YCBCR_POSITIONING, 1, "Center of pixel array", "Datum point");
305 }
306
307 @Nullable
308 public String getOrientationDescription()
309 {
310 return getIndexedDescription(TAG_ORIENTATION, 1,
311 "Top, left side (Horizontal / normal)",
312 "Top, right side (Mirror horizontal)",
313 "Bottom, right side (Rotate 180)",
314 "Bottom, left side (Mirror vertical)",
315 "Left side, top (Mirror horizontal and rotate 270 CW)",
316 "Right side, top (Rotate 90 CW)",
317 "Right side, bottom (Mirror horizontal and rotate 90 CW)",
318 "Left side, bottom (Rotate 270 CW)");
319 }
320
321 @Nullable
322 public String getResolutionDescription()
323 {
324 // '1' means no-unit, '2' means inch, '3' means centimeter. Default value is '2'(inch)
325 return getIndexedDescription(TAG_RESOLUTION_UNIT, 1, "(No unit)", "Inch", "cm");
326 }
327}
Note: See TracBrowser for help on using the repository browser.