Changeset 8243 in josm for trunk/src/com/drew/metadata/exif/ExifSubIFDDescriptor.java
- Timestamp:
- 2015-04-21T00:42:50+02:00 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/com/drew/metadata/exif/ExifSubIFDDescriptor.java
r8132 r8243 21 21 package com.drew.metadata.exif; 22 22 23 import com.drew.imaging.PhotographicConversions;24 import com.drew.lang.Rational;25 23 import com.drew.lang.annotations.NotNull; 26 import com.drew.lang.annotations.Nullable;27 import com.drew.metadata.TagDescriptor;28 29 import java.io.UnsupportedEncodingException;30 import java.text.DecimalFormat;31 import java.util.HashMap;32 import java.util.Map;33 34 import static com.drew.metadata.exif.ExifSubIFDDirectory.*;35 24 36 25 /** … … 39 28 * @author Drew Noakes https://drewnoakes.com 40 29 */ 41 public class ExifSubIFDDescriptor extends TagDescriptor<ExifSubIFDDirectory>30 public class ExifSubIFDDescriptor extends ExifDescriptorBase<ExifSubIFDDirectory> 42 31 { 43 /**44 * Dictates whether rational values will be represented in decimal format in instances45 * where decimal notation is elegant (such as 1/2 -> 0.5, but not 1/3).46 */47 private final boolean _allowDecimalRepresentationOfRationals = true;48 49 @NotNull50 private static final java.text.DecimalFormat SimpleDecimalFormatter = new DecimalFormat("0.#");51 52 32 public ExifSubIFDDescriptor(@NotNull ExifSubIFDDirectory directory) 53 33 { 54 34 super(directory); 55 35 } 56 57 // Note for the potential addition of brightness presentation in eV:58 // Brightness of taken subject. To calculate Exposure(Ev) from BrightnessValue(Bv),59 // you must add SensitivityValue(Sv).60 // Ev=BV+Sv Sv=log2(ISOSpeedRating/3.125)61 // ISO100:Sv=5, ISO200:Sv=6, ISO400:Sv=7, ISO125:Sv=5.32.62 63 /**64 * Returns a descriptive value of the specified tag for this image.65 * Where possible, known values will be substituted here in place of the raw66 * tokens actually kept in the Exif segment. If no substitution is67 * available, the value provided by getString(int) will be returned.68 *69 * @param tagType the tag to find a description for70 * @return a description of the image's value for the specified tag, or71 * <code>null</code> if the tag hasn't been defined.72 */73 @Override74 @Nullable75 public String getDescription(int tagType)76 {77 switch (tagType) {78 case TAG_NEW_SUBFILE_TYPE:79 return getNewSubfileTypeDescription();80 case TAG_SUBFILE_TYPE:81 return getSubfileTypeDescription();82 case TAG_THRESHOLDING:83 return getThresholdingDescription();84 case TAG_FILL_ORDER:85 return getFillOrderDescription();86 case TAG_EXPOSURE_TIME:87 return getExposureTimeDescription();88 case TAG_SHUTTER_SPEED:89 return getShutterSpeedDescription();90 case TAG_FNUMBER:91 return getFNumberDescription();92 case TAG_COMPRESSED_AVERAGE_BITS_PER_PIXEL:93 return getCompressedAverageBitsPerPixelDescription();94 case TAG_SUBJECT_DISTANCE:95 return getSubjectDistanceDescription();96 case TAG_METERING_MODE:97 return getMeteringModeDescription();98 case TAG_WHITE_BALANCE:99 return getWhiteBalanceDescription();100 case TAG_FLASH:101 return getFlashDescription();102 case TAG_FOCAL_LENGTH:103 return getFocalLengthDescription();104 case TAG_COLOR_SPACE:105 return getColorSpaceDescription();106 case TAG_EXIF_IMAGE_WIDTH:107 return getExifImageWidthDescription();108 case TAG_EXIF_IMAGE_HEIGHT:109 return getExifImageHeightDescription();110 case TAG_FOCAL_PLANE_RESOLUTION_UNIT:111 return getFocalPlaneResolutionUnitDescription();112 case TAG_FOCAL_PLANE_X_RESOLUTION:113 return getFocalPlaneXResolutionDescription();114 case TAG_FOCAL_PLANE_Y_RESOLUTION:115 return getFocalPlaneYResolutionDescription();116 case TAG_BITS_PER_SAMPLE:117 return getBitsPerSampleDescription();118 case TAG_PHOTOMETRIC_INTERPRETATION:119 return getPhotometricInterpretationDescription();120 case TAG_ROWS_PER_STRIP:121 return getRowsPerStripDescription();122 case TAG_STRIP_BYTE_COUNTS:123 return getStripByteCountsDescription();124 case TAG_SAMPLES_PER_PIXEL:125 return getSamplesPerPixelDescription();126 case TAG_PLANAR_CONFIGURATION:127 return getPlanarConfigurationDescription();128 case TAG_YCBCR_SUBSAMPLING:129 return getYCbCrSubsamplingDescription();130 case TAG_EXPOSURE_PROGRAM:131 return getExposureProgramDescription();132 case TAG_APERTURE:133 return getApertureValueDescription();134 case TAG_MAX_APERTURE:135 return getMaxApertureValueDescription();136 case TAG_SENSING_METHOD:137 return getSensingMethodDescription();138 case TAG_EXPOSURE_BIAS:139 return getExposureBiasDescription();140 case TAG_FILE_SOURCE:141 return getFileSourceDescription();142 case TAG_SCENE_TYPE:143 return getSceneTypeDescription();144 case TAG_COMPONENTS_CONFIGURATION:145 return getComponentConfigurationDescription();146 case TAG_EXIF_VERSION:147 return getExifVersionDescription();148 case TAG_FLASHPIX_VERSION:149 return getFlashPixVersionDescription();150 case TAG_ISO_EQUIVALENT:151 return getIsoEquivalentDescription();152 case TAG_USER_COMMENT:153 return getUserCommentDescription();154 case TAG_CUSTOM_RENDERED:155 return getCustomRenderedDescription();156 case TAG_EXPOSURE_MODE:157 return getExposureModeDescription();158 case TAG_WHITE_BALANCE_MODE:159 return getWhiteBalanceModeDescription();160 case TAG_DIGITAL_ZOOM_RATIO:161 return getDigitalZoomRatioDescription();162 case TAG_35MM_FILM_EQUIV_FOCAL_LENGTH:163 return get35mmFilmEquivFocalLengthDescription();164 case TAG_SCENE_CAPTURE_TYPE:165 return getSceneCaptureTypeDescription();166 case TAG_GAIN_CONTROL:167 return getGainControlDescription();168 case TAG_CONTRAST:169 return getContrastDescription();170 case TAG_SATURATION:171 return getSaturationDescription();172 case TAG_SHARPNESS:173 return getSharpnessDescription();174 case TAG_SUBJECT_DISTANCE_RANGE:175 return getSubjectDistanceRangeDescription();176 default:177 return super.getDescription(tagType);178 }179 }180 181 @Nullable182 public String getNewSubfileTypeDescription()183 {184 return getIndexedDescription(TAG_NEW_SUBFILE_TYPE, 1,185 "Full-resolution image",186 "Reduced-resolution image",187 "Single page of multi-page reduced-resolution image",188 "Transparency mask",189 "Transparency mask of reduced-resolution image",190 "Transparency mask of multi-page image",191 "Transparency mask of reduced-resolution multi-page image"192 );193 }194 195 @Nullable196 public String getSubfileTypeDescription()197 {198 return getIndexedDescription(TAG_SUBFILE_TYPE, 1,199 "Full-resolution image",200 "Reduced-resolution image",201 "Single page of multi-page image"202 );203 }204 205 @Nullable206 public String getThresholdingDescription()207 {208 return getIndexedDescription(TAG_THRESHOLDING, 1,209 "No dithering or halftoning",210 "Ordered dither or halftone",211 "Randomized dither"212 );213 }214 215 @Nullable216 public String getFillOrderDescription()217 {218 return getIndexedDescription(TAG_FILL_ORDER, 1,219 "Normal",220 "Reversed"221 );222 }223 224 @Nullable225 public String getSubjectDistanceRangeDescription()226 {227 return getIndexedDescription(TAG_SUBJECT_DISTANCE_RANGE,228 "Unknown",229 "Macro",230 "Close view",231 "Distant view"232 );233 }234 235 @Nullable236 public String getSharpnessDescription()237 {238 return getIndexedDescription(TAG_SHARPNESS,239 "None",240 "Low",241 "Hard"242 );243 }244 245 @Nullable246 public String getSaturationDescription()247 {248 return getIndexedDescription(TAG_SATURATION,249 "None",250 "Low saturation",251 "High saturation"252 );253 }254 255 @Nullable256 public String getContrastDescription()257 {258 return getIndexedDescription(TAG_CONTRAST,259 "None",260 "Soft",261 "Hard"262 );263 }264 265 @Nullable266 public String getGainControlDescription()267 {268 return getIndexedDescription(TAG_GAIN_CONTROL,269 "None",270 "Low gain up",271 "Low gain down",272 "High gain up",273 "High gain down"274 );275 }276 277 @Nullable278 public String getSceneCaptureTypeDescription()279 {280 return getIndexedDescription(TAG_SCENE_CAPTURE_TYPE,281 "Standard",282 "Landscape",283 "Portrait",284 "Night scene"285 );286 }287 288 @Nullable289 public String get35mmFilmEquivFocalLengthDescription()290 {291 Integer value = _directory.getInteger(TAG_35MM_FILM_EQUIV_FOCAL_LENGTH);292 return value == null293 ? null294 : value == 0295 ? "Unknown"296 : SimpleDecimalFormatter.format(value) + "mm";297 }298 299 @Nullable300 public String getDigitalZoomRatioDescription()301 {302 Rational value = _directory.getRational(TAG_DIGITAL_ZOOM_RATIO);303 return value == null304 ? null305 : value.getNumerator() == 0306 ? "Digital zoom not used."307 : SimpleDecimalFormatter.format(value.doubleValue());308 }309 310 @Nullable311 public String getWhiteBalanceModeDescription()312 {313 return getIndexedDescription(TAG_WHITE_BALANCE_MODE,314 "Auto white balance",315 "Manual white balance"316 );317 }318 319 @Nullable320 public String getExposureModeDescription()321 {322 return getIndexedDescription(TAG_EXPOSURE_MODE,323 "Auto exposure",324 "Manual exposure",325 "Auto bracket"326 );327 }328 329 @Nullable330 public String getCustomRenderedDescription()331 {332 return getIndexedDescription(TAG_CUSTOM_RENDERED,333 "Normal process",334 "Custom process"335 );336 }337 338 @Nullable339 public String getUserCommentDescription()340 {341 byte[] commentBytes = _directory.getByteArray(TAG_USER_COMMENT);342 if (commentBytes == null)343 return null;344 if (commentBytes.length == 0)345 return "";346 347 final Map<String, String> encodingMap = new HashMap<String, String>();348 encodingMap.put("ASCII", System.getProperty("file.encoding")); // Someone suggested "ISO-8859-1".349 encodingMap.put("UNICODE", "UTF-16LE");350 encodingMap.put("JIS", "Shift-JIS"); // We assume this charset for now. Another suggestion is "JIS".351 352 try {353 if (commentBytes.length >= 10) {354 String firstTenBytesString = new String(commentBytes, 0, 10);355 356 // try each encoding name357 for (Map.Entry<String, String> pair : encodingMap.entrySet()) {358 String encodingName = pair.getKey();359 String charset = pair.getValue();360 if (firstTenBytesString.startsWith(encodingName)) {361 // skip any null or blank characters commonly present after the encoding name, up to a limit of 10 from the start362 for (int j = encodingName.length(); j < 10; j++) {363 byte b = commentBytes[j];364 if (b != '\0' && b != ' ')365 return new String(commentBytes, j, commentBytes.length - j, charset).trim();366 }367 return new String(commentBytes, 10, commentBytes.length - 10, charset).trim();368 }369 }370 }371 // special handling fell through, return a plain string representation372 return new String(commentBytes, System.getProperty("file.encoding")).trim();373 } catch (UnsupportedEncodingException ex) {374 return null;375 }376 }377 378 @Nullable379 public String getIsoEquivalentDescription()380 {381 // Have seen an exception here from files produced by ACDSEE that stored an int[] here with two values382 Integer isoEquiv = _directory.getInteger(TAG_ISO_EQUIVALENT);383 // There used to be a check here that multiplied ISO values < 50 by 200.384 // Issue 36 shows a smart-phone image from a Samsung Galaxy S2 with ISO-40.385 return isoEquiv != null386 ? Integer.toString(isoEquiv)387 : null;388 }389 390 @Nullable391 public String getExifVersionDescription()392 {393 return getVersionBytesDescription(TAG_EXIF_VERSION, 2);394 }395 396 @Nullable397 public String getFlashPixVersionDescription()398 {399 return getVersionBytesDescription(TAG_FLASHPIX_VERSION, 2);400 }401 402 @Nullable403 public String getSceneTypeDescription()404 {405 return getIndexedDescription(TAG_SCENE_TYPE,406 1,407 "Directly photographed image"408 );409 }410 411 @Nullable412 public String getFileSourceDescription()413 {414 return getIndexedDescription(TAG_FILE_SOURCE,415 1,416 "Film Scanner",417 "Reflection Print Scanner",418 "Digital Still Camera (DSC)"419 );420 }421 422 @Nullable423 public String getExposureBiasDescription()424 {425 Rational value = _directory.getRational(TAG_EXPOSURE_BIAS);426 if (value == null)427 return null;428 return value.toSimpleString(true) + " EV";429 }430 431 @Nullable432 public String getMaxApertureValueDescription()433 {434 Double aperture = _directory.getDoubleObject(TAG_MAX_APERTURE);435 if (aperture == null)436 return null;437 double fStop = PhotographicConversions.apertureToFStop(aperture);438 return "F" + SimpleDecimalFormatter.format(fStop);439 }440 441 @Nullable442 public String getApertureValueDescription()443 {444 Double aperture = _directory.getDoubleObject(TAG_APERTURE);445 if (aperture == null)446 return null;447 double fStop = PhotographicConversions.apertureToFStop(aperture);448 return "F" + SimpleDecimalFormatter.format(fStop);449 }450 451 @Nullable452 public String getExposureProgramDescription()453 {454 return getIndexedDescription(TAG_EXPOSURE_PROGRAM,455 1,456 "Manual control",457 "Program normal",458 "Aperture priority",459 "Shutter priority",460 "Program creative (slow program)",461 "Program action (high-speed program)",462 "Portrait mode",463 "Landscape mode"464 );465 }466 467 @Nullable468 public String getYCbCrSubsamplingDescription()469 {470 int[] positions = _directory.getIntArray(TAG_YCBCR_SUBSAMPLING);471 if (positions == null)472 return null;473 if (positions[0] == 2 && positions[1] == 1) {474 return "YCbCr4:2:2";475 } else if (positions[0] == 2 && positions[1] == 2) {476 return "YCbCr4:2:0";477 } else {478 return "(Unknown)";479 }480 }481 482 @Nullable483 public String getPlanarConfigurationDescription()484 {485 // When image format is no compression YCbCr, this value shows byte aligns of YCbCr486 // data. If value is '1', Y/Cb/Cr value is chunky format, contiguous for each subsampling487 // pixel. If value is '2', Y/Cb/Cr value is separated and stored to Y plane/Cb plane/Cr488 // plane format.489 return getIndexedDescription(TAG_PLANAR_CONFIGURATION,490 1,491 "Chunky (contiguous for each subsampling pixel)",492 "Separate (Y-plane/Cb-plane/Cr-plane format)"493 );494 }495 496 @Nullable497 public String getSamplesPerPixelDescription()498 {499 String value = _directory.getString(TAG_SAMPLES_PER_PIXEL);500 return value == null ? null : value + " samples/pixel";501 }502 503 @Nullable504 public String getRowsPerStripDescription()505 {506 final String value = _directory.getString(TAG_ROWS_PER_STRIP);507 return value == null ? null : value + " rows/strip";508 }509 510 @Nullable511 public String getStripByteCountsDescription()512 {513 final String value = _directory.getString(TAG_STRIP_BYTE_COUNTS);514 return value == null ? null : value + " bytes";515 }516 517 @Nullable518 public String getPhotometricInterpretationDescription()519 {520 // Shows the color space of the image data components521 Integer value = _directory.getInteger(TAG_PHOTOMETRIC_INTERPRETATION);522 if (value == null)523 return null;524 switch (value) {525 case 0: return "WhiteIsZero";526 case 1: return "BlackIsZero";527 case 2: return "RGB";528 case 3: return "RGB Palette";529 case 4: return "Transparency Mask";530 case 5: return "CMYK";531 case 6: return "YCbCr";532 case 8: return "CIELab";533 case 9: return "ICCLab";534 case 10: return "ITULab";535 case 32803: return "Color Filter Array";536 case 32844: return "Pixar LogL";537 case 32845: return "Pixar LogLuv";538 case 32892: return "Linear Raw";539 default:540 return "Unknown colour space";541 }542 }543 544 @Nullable545 public String getBitsPerSampleDescription()546 {547 String value = _directory.getString(TAG_BITS_PER_SAMPLE);548 return value == null ? null : value + " bits/component/pixel";549 }550 551 @Nullable552 public String getFocalPlaneXResolutionDescription()553 {554 Rational rational = _directory.getRational(TAG_FOCAL_PLANE_X_RESOLUTION);555 if (rational == null)556 return null;557 final String unit = getFocalPlaneResolutionUnitDescription();558 return rational.getReciprocal().toSimpleString(_allowDecimalRepresentationOfRationals)559 + (unit == null ? "" : " " + unit.toLowerCase());560 }561 562 @Nullable563 public String getFocalPlaneYResolutionDescription()564 {565 Rational rational = _directory.getRational(TAG_FOCAL_PLANE_Y_RESOLUTION);566 if (rational == null)567 return null;568 final String unit = getFocalPlaneResolutionUnitDescription();569 return rational.getReciprocal().toSimpleString(_allowDecimalRepresentationOfRationals)570 + (unit == null ? "" : " " + unit.toLowerCase());571 }572 573 @Nullable574 public String getFocalPlaneResolutionUnitDescription()575 {576 // Unit of FocalPlaneXResolution/FocalPlaneYResolution.577 // '1' means no-unit, '2' inch, '3' centimeter.578 return getIndexedDescription(TAG_FOCAL_PLANE_RESOLUTION_UNIT,579 1,580 "(No unit)",581 "Inches",582 "cm"583 );584 }585 586 @Nullable587 public String getExifImageWidthDescription()588 {589 final Integer value = _directory.getInteger(TAG_EXIF_IMAGE_WIDTH);590 return value == null ? null : value + " pixels";591 }592 593 @Nullable594 public String getExifImageHeightDescription()595 {596 final Integer value = _directory.getInteger(TAG_EXIF_IMAGE_HEIGHT);597 return value == null ? null : value + " pixels";598 }599 600 @Nullable601 public String getColorSpaceDescription()602 {603 final Integer value = _directory.getInteger(TAG_COLOR_SPACE);604 if (value == null)605 return null;606 if (value == 1)607 return "sRGB";608 if (value == 65535)609 return "Undefined";610 return "Unknown (" + value + ")";611 }612 613 @Nullable614 public String getFocalLengthDescription()615 {616 Rational value = _directory.getRational(TAG_FOCAL_LENGTH);617 if (value == null)618 return null;619 java.text.DecimalFormat formatter = new DecimalFormat("0.0##");620 return formatter.format(value.doubleValue()) + " mm";621 }622 623 @Nullable624 public String getFlashDescription()625 {626 /*627 * This is a bit mask.628 * 0 = flash fired629 * 1 = return detected630 * 2 = return able to be detected631 * 3 = unknown632 * 4 = auto used633 * 5 = unknown634 * 6 = red eye reduction used635 */636 637 final Integer value = _directory.getInteger(TAG_FLASH);638 639 if (value == null)640 return null;641 642 StringBuilder sb = new StringBuilder();643 644 if ((value & 0x1) != 0)645 sb.append("Flash fired");646 else647 sb.append("Flash did not fire");648 649 // check if we're able to detect a return, before we mention it650 if ((value & 0x4) != 0) {651 if ((value & 0x2) != 0)652 sb.append(", return detected");653 else654 sb.append(", return not detected");655 }656 657 if ((value & 0x10) != 0)658 sb.append(", auto");659 660 if ((value & 0x40) != 0)661 sb.append(", red-eye reduction");662 663 return sb.toString();664 }665 666 @Nullable667 public String getWhiteBalanceDescription()668 {669 // '0' means unknown, '1' daylight, '2' fluorescent, '3' tungsten, '10' flash,670 // '17' standard light A, '18' standard light B, '19' standard light C, '20' D55,671 // '21' D65, '22' D75, '255' other.672 final Integer value = _directory.getInteger(TAG_WHITE_BALANCE);673 if (value == null)674 return null;675 switch (value) {676 case 0: return "Unknown";677 case 1: return "Daylight";678 case 2: return "Florescent";679 case 3: return "Tungsten";680 case 10: return "Flash";681 case 17: return "Standard light";682 case 18: return "Standard light (B)";683 case 19: return "Standard light (C)";684 case 20: return "D55";685 case 21: return "D65";686 case 22: return "D75";687 case 255: return "(Other)";688 default:689 return "Unknown (" + value + ")";690 }691 }692 693 @Nullable694 public String getMeteringModeDescription()695 {696 // '0' means unknown, '1' average, '2' center weighted average, '3' spot697 // '4' multi-spot, '5' multi-segment, '6' partial, '255' other698 Integer value = _directory.getInteger(TAG_METERING_MODE);699 if (value == null)700 return null;701 switch (value) {702 case 0: return "Unknown";703 case 1: return "Average";704 case 2: return "Center weighted average";705 case 3: return "Spot";706 case 4: return "Multi-spot";707 case 5: return "Multi-segment";708 case 6: return "Partial";709 case 255: return "(Other)";710 default:711 return "";712 }713 }714 715 @Nullable716 public String getSubjectDistanceDescription()717 {718 Rational value = _directory.getRational(TAG_SUBJECT_DISTANCE);719 if (value == null)720 return null;721 java.text.DecimalFormat formatter = new DecimalFormat("0.0##");722 return formatter.format(value.doubleValue()) + " metres";723 }724 725 @Nullable726 public String getCompressedAverageBitsPerPixelDescription()727 {728 Rational value = _directory.getRational(TAG_COMPRESSED_AVERAGE_BITS_PER_PIXEL);729 if (value == null)730 return null;731 String ratio = value.toSimpleString(_allowDecimalRepresentationOfRationals);732 return value.isInteger() && value.intValue() == 1733 ? ratio + " bit/pixel"734 : ratio + " bits/pixel";735 }736 737 @Nullable738 public String getExposureTimeDescription()739 {740 String value = _directory.getString(TAG_EXPOSURE_TIME);741 return value == null ? null : value + " sec";742 }743 744 @Nullable745 public String getShutterSpeedDescription()746 {747 // I believe this method to now be stable, but am leaving some alternative snippets of748 // code in here, to assist anyone who's looking into this (given that I don't have a public CVS).749 750 // float apexValue = _directory.getFloat(ExifSubIFDDirectory.TAG_SHUTTER_SPEED);751 // int apexPower = (int)Math.pow(2.0, apexValue);752 // return "1/" + apexPower + " sec";753 // TODO test this method754 // thanks to Mark Edwards for spotting and patching a bug in the calculation of this755 // description (spotted bug using a Canon EOS 300D)756 // thanks also to Gli Blr for spotting this bug757 Float apexValue = _directory.getFloatObject(TAG_SHUTTER_SPEED);758 if (apexValue == null)759 return null;760 if (apexValue <= 1) {761 float apexPower = (float)(1 / (Math.exp(apexValue * Math.log(2))));762 long apexPower10 = Math.round((double)apexPower * 10.0);763 float fApexPower = (float)apexPower10 / 10.0f;764 return fApexPower + " sec";765 } else {766 int apexPower = (int)((Math.exp(apexValue * Math.log(2))));767 return "1/" + apexPower + " sec";768 }769 770 /*771 // This alternative implementation offered by Bill Richards772 // TODO determine which is the correct / more-correct implementation773 double apexValue = _directory.getDouble(ExifSubIFDDirectory.TAG_SHUTTER_SPEED);774 double apexPower = Math.pow(2.0, apexValue);775 776 StringBuffer sb = new StringBuffer();777 if (apexPower > 1)778 apexPower = Math.floor(apexPower);779 780 if (apexPower < 1) {781 sb.append((int)Math.round(1/apexPower));782 } else {783 sb.append("1/");784 sb.append((int)apexPower);785 }786 sb.append(" sec");787 return sb.toString();788 */789 }790 791 @Nullable792 public String getFNumberDescription()793 {794 Rational value = _directory.getRational(TAG_FNUMBER);795 if (value == null)796 return null;797 return "F" + SimpleDecimalFormatter.format(value.doubleValue());798 }799 800 @Nullable801 public String getSensingMethodDescription()802 {803 // '1' Not defined, '2' One-chip color area sensor, '3' Two-chip color area sensor804 // '4' Three-chip color area sensor, '5' Color sequential area sensor805 // '7' Trilinear sensor '8' Color sequential linear sensor, 'Other' reserved806 return getIndexedDescription(TAG_SENSING_METHOD,807 1,808 "(Not defined)",809 "One-chip color area sensor",810 "Two-chip color area sensor",811 "Three-chip color area sensor",812 "Color sequential area sensor",813 null,814 "Trilinear sensor",815 "Color sequential linear sensor"816 );817 }818 819 @Nullable820 public String getComponentConfigurationDescription()821 {822 int[] components = _directory.getIntArray(TAG_COMPONENTS_CONFIGURATION);823 if (components == null)824 return null;825 String[] componentStrings = {"", "Y", "Cb", "Cr", "R", "G", "B"};826 StringBuilder componentConfig = new StringBuilder();827 for (int i = 0; i < Math.min(4, components.length); i++) {828 int j = components[i];829 if (j > 0 && j < componentStrings.length) {830 componentConfig.append(componentStrings[j]);831 }832 }833 return componentConfig.toString();834 }835 36 }
Note:
See TracChangeset
for help on using the changeset viewer.
