Changeset 10862 in josm for trunk/src/com/drew/metadata/exif


Ignore:
Timestamp:
2016-08-20T20:58:03+02:00 (5 years ago)
Author:
Don-vip
Message:

update to metadata-extractor 2.9.1

Location:
trunk/src/com/drew/metadata/exif
Files:
4 added
50 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/com/drew/metadata/exif/ExifDescriptorBase.java

    r8243 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
     
    3030
    3131import java.io.UnsupportedEncodingException;
     32import java.math.RoundingMode;
    3233import java.text.DecimalFormat;
    3334import java.util.HashMap;
     
    5152    @NotNull
    5253    private static final java.text.DecimalFormat SimpleDecimalFormatter = new DecimalFormat("0.#");
    53     @NotNull
    54     private static final java.text.DecimalFormat SimpleDecimalFormatterWithPrecision = new DecimalFormat("0.0");
    5554
    5655    // Note for the potential addition of brightness presentation in eV:
     
    206205            case TAG_JPEG_PROC:
    207206                return getJpegProcDescription();
     207            case TAG_LENS_SPECIFICATION:
     208                return getLensSpecificationDescription();
    208209            default:
    209210                return super.getDescription(tagType);
     
    509510
    510511    @Nullable
     512    public String getLensSpecificationDescription()
     513    {
     514        return getLensSpecificationDescription(TAG_LENS_SPECIFICATION);
     515    }
     516
     517    @Nullable
    511518    public String getSharpnessDescription()
    512519    {
     
    568575            ? null
    569576            : value == 0
    570             ? "Unknown"
    571             : SimpleDecimalFormatter.format(value) + "mm";
     577                ? "Unknown"
     578                : getFocalLengthDescription(value);
    572579    }
    573580
     
    579586            ? null
    580587            : value.getNumerator() == 0
    581             ? "Digital zoom not used."
    582             : SimpleDecimalFormatter.format(value.doubleValue());
     588                ? "Digital zoom not used"
     589                : SimpleDecimalFormatter.format(value.doubleValue());
    583590    }
    584591
     
    711718            return null;
    712719        double fStop = PhotographicConversions.apertureToFStop(aperture);
    713         return "f/" + SimpleDecimalFormatterWithPrecision.format(fStop);
     720        return getFStopDescription(fStop);
    714721    }
    715722
     
    721728            return null;
    722729        double fStop = PhotographicConversions.apertureToFStop(aperture);
    723         return "f/" + SimpleDecimalFormatterWithPrecision.format(fStop);
     730        return getFStopDescription(fStop);
    724731    }
    725732
     
    807814    {
    808815        Rational value = _directory.getRational(TAG_FOCAL_LENGTH);
    809         if (value == null)
    810             return null;
    811         java.text.DecimalFormat formatter = new DecimalFormat("0.0##");
    812         return formatter.format(value.doubleValue()) + " mm";
     816        return value == null ? null : getFocalLengthDescription(value.doubleValue());
    813817    }
    814818
     
    859863    public String getWhiteBalanceDescription()
    860864    {
    861         // '0' means unknown, '1' daylight, '2' fluorescent, '3' tungsten, '4' flash,
    862         // '17' standard light A, '18' standard light B, '19' standard light C, '20' D55,
    863         // '21' D65, '22' D75, '255' other.
    864         // see http://web.archive.org/web/20131018091152/http://exif.org/Exif2-2.PDF page 35
     865        // See http://web.archive.org/web/20131018091152/http://exif.org/Exif2-2.PDF page 35
    865866        final Integer value = _directory.getInteger(TAG_WHITE_BALANCE);
    866867        if (value == null)
     
    875876            case 10: return "Cloudy";
    876877            case 11: return "Shade";
    877             case 12: return "Daylight Flourescent";
    878             case 13: return "Day White Flourescent";
    879             case 14: return "Cool White Flourescent";
    880             case 15: return "White Flourescent";
    881             case 16: return "Warm White Flourescent";
     878            case 12: return "Daylight Fluorescent";
     879            case 13: return "Day White Fluorescent";
     880            case 14: return "Cool White Fluorescent";
     881            case 15: return "White Fluorescent";
     882            case 16: return "Warm White Fluorescent";
    882883            case 17: return "Standard light";
    883884            case 18: return "Standard light (B)";
     
    975976        if (value == null)
    976977            return null;
    977         java.text.DecimalFormat formatter = new DecimalFormat("0.0##");
     978        DecimalFormat formatter = new DecimalFormat("0.0##");
    978979        return formatter.format(value.doubleValue()) + " metres";
    979980    }
     
    10181019            long apexPower10 = Math.round((double)apexPower * 10.0);
    10191020            float fApexPower = (float)apexPower10 / 10.0f;
    1020             return fApexPower + " sec";
     1021            DecimalFormat format = new DecimalFormat("0.##");
     1022            format.setRoundingMode(RoundingMode.HALF_UP);
     1023            return format.format(fApexPower) + " sec";
    10211024        } else {
    10221025            int apexPower = (int)((Math.exp(apexValue * Math.log(2))));
     
    10511054        if (value == null)
    10521055            return null;
    1053         return "f/" + SimpleDecimalFormatterWithPrecision.format(value.doubleValue());
     1056        return getFStopDescription(value.doubleValue());
    10541057    }
    10551058
  • trunk/src/com/drew/metadata/exif/ExifDirectoryBase.java

    r8243 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
     
    140140    public static final int TAG_TILE_BYTE_COUNTS                  = 0x0145;
    141141
     142    /**
     143     * Tag is a pointer to one or more sub-IFDs.
     144     + Seems to be used exclusively by raw formats, referencing one or two IFDs.
     145     */
    142146    public static final int TAG_SUB_IFD_OFFSET                    = 0x014a;
    143147
     
    150154    public static final int TAG_YCBCR_POSITIONING                 = 0x0213;
    151155    public static final int TAG_REFERENCE_BLACK_WHITE             = 0x0214;
     156    public static final int TAG_STRIP_ROW_COUNTS                  = 0x022f;
     157    public static final int TAG_APPLICATION_NOTES                 = 0x02bc;
    152158
    153159    public static final int TAG_RELATED_IMAGE_FILE_FORMAT         = 0x1000;
     
    260266    public static final int TAG_METERING_MODE                     = 0x9207;
    261267
    262     public static final int TAG_LIGHT_SOURCE                      = 0x9208; // TODO duplicate tag
    263268    /**
    264269     * White balance (aka light source). '0' means unknown, '1' daylight,
     
    267272     * '22' D75, '255' other.
    268273     */
    269     public static final int TAG_WHITE_BALANCE                     = 0x9208; // TODO duplicate tag
     274    public static final int TAG_WHITE_BALANCE                     = 0x9208;
    270275    /**
    271276     * 0x0  = 0000000 = No Flash
     
    600605        map.put(TAG_ROWS_PER_STRIP, "Rows Per Strip");
    601606        map.put(TAG_STRIP_BYTE_COUNTS, "Strip Byte Counts");
    602         map.put(TAG_MIN_SAMPLE_VALUE, "Minimum sample value");
    603         map.put(TAG_MAX_SAMPLE_VALUE, "Maximum sample value");
     607        map.put(TAG_MIN_SAMPLE_VALUE, "Minimum Sample Value");
     608        map.put(TAG_MAX_SAMPLE_VALUE, "Maximum Sample Value");
    604609        map.put(TAG_X_RESOLUTION, "X Resolution");
    605610        map.put(TAG_Y_RESOLUTION, "Y Resolution");
     
    627632        map.put(TAG_YCBCR_POSITIONING, "YCbCr Positioning");
    628633        map.put(TAG_REFERENCE_BLACK_WHITE, "Reference Black/White");
     634        map.put(TAG_STRIP_ROW_COUNTS, "Strip Row Counts");
     635        map.put(TAG_APPLICATION_NOTES, "Application Notes");
    629636        map.put(TAG_RELATED_IMAGE_FILE_FORMAT, "Related Image File Format");
    630637        map.put(TAG_RELATED_IMAGE_WIDTH, "Related Image Width");
     
    663670        map.put(TAG_SUBJECT_DISTANCE, "Subject Distance");
    664671        map.put(TAG_METERING_MODE, "Metering Mode");
    665         map.put(TAG_LIGHT_SOURCE, "Light Source");
    666672        map.put(TAG_WHITE_BALANCE, "White Balance");
    667673        map.put(TAG_FLASH, "Flash");
  • trunk/src/com/drew/metadata/exif/ExifIFD0Descriptor.java

    r8243 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/ExifIFD0Directory.java

    r8243 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
     
    2222package com.drew.metadata.exif;
    2323
     24import java.util.HashMap;
     25
    2426import com.drew.lang.annotations.NotNull;
    25 
    26 import java.util.HashMap;
    2727
    2828/**
  • trunk/src/com/drew/metadata/exif/ExifInteropDescriptor.java

    r8243 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/ExifInteropDirectory.java

    r8243 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/ExifReader.java

    r8243 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
     
    2828import com.drew.lang.RandomAccessReader;
    2929import com.drew.lang.annotations.NotNull;
     30import com.drew.lang.annotations.Nullable;
     31import com.drew.metadata.Directory;
    3032import com.drew.metadata.Metadata;
    3133
    3234import java.io.IOException;
    33 import java.util.Arrays;
     35import java.util.Collections;
    3436
    3537/**
     
    6062    public Iterable<JpegSegmentType> getSegmentTypes()
    6163    {
    62         return Arrays.asList(JpegSegmentType.APP1);
     64        return Collections.singletonList(JpegSegmentType.APP1);
    6365    }
    6466
     
    8486    public void extract(@NotNull final RandomAccessReader reader, @NotNull final Metadata metadata, int readerOffset)
    8587    {
     88        extract(reader, metadata, readerOffset, null);
     89    }
     90
     91    /** Reads TIFF formatted Exif data a specified offset within a {@link RandomAccessReader}. */
     92    public void extract(@NotNull final RandomAccessReader reader, @NotNull final Metadata metadata, int readerOffset, @Nullable Directory parentDirectory)
     93    {
    8694        try {
    8795            // Read the TIFF-formatted Exif data
    8896            new TiffReader().processTiff(
    8997                reader,
    90                 new ExifTiffHandler(metadata, _storeThumbnailBytes),
     98                new ExifTiffHandler(metadata, _storeThumbnailBytes, parentDirectory),
    9199                readerOffset
    92100            );
  • trunk/src/com/drew/metadata/exif/ExifSubIFDDescriptor.java

    r8243 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/ExifSubIFDDirectory.java

    r8243 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
     
    2121package com.drew.metadata.exif;
    2222
     23import java.util.Date;
     24import java.util.HashMap;
     25import java.util.TimeZone;
     26
    2327import com.drew.lang.annotations.NotNull;
    24 
    25 import java.util.HashMap;
     28import com.drew.lang.annotations.Nullable;
    2629
    2730/**
     
    6164        return _tagNameMap;
    6265    }
     66
     67    /**
     68     * Parses the date/time tag and the subsecond tag to obtain a single Date object with milliseconds
     69     * representing the date and time when this image was captured.  Attempts will be made to parse the
     70     * values as though it is in the GMT {@link TimeZone}.
     71     *
     72     * @return A Date object representing when this image was captured, if possible, otherwise null
     73     */
     74    @Nullable
     75    public Date getDateOriginal()
     76    {
     77        return getDateOriginal(null);
     78    }
     79
     80    /**
     81     * Parses the date/time tag and the subsecond tag to obtain a single Date object with milliseconds
     82     * representing the date and time when this image was captured.  Attempts will be made to parse the
     83     * values as though it is in the {@link TimeZone} represented by the {@code timeZone} parameter
     84     * (if it is non-null).
     85     *
     86     * @param timeZone the time zone to use
     87     * @return A Date object representing when this image was captured, if possible, otherwise null
     88     */
     89    @Nullable
     90    public Date getDateOriginal(TimeZone timeZone)
     91    {
     92        return getDate(TAG_DATETIME_ORIGINAL, getString(TAG_SUBSECOND_TIME_ORIGINAL), timeZone);
     93    }
     94
     95    /**
     96     * Parses the date/time tag and the subsecond tag to obtain a single Date object with milliseconds
     97     * representing the date and time when this image was digitized.  Attempts will be made to parse the
     98     * values as though it is in the GMT {@link TimeZone}.
     99     *
     100     * @return A Date object representing when this image was digitized, if possible, otherwise null
     101     */
     102    @Nullable
     103    public Date getDateDigitized()
     104    {
     105        return getDateDigitized(null);
     106    }
     107
     108    /**
     109     * Parses the date/time tag and the subsecond tag to obtain a single Date object with milliseconds
     110     * representing the date and time when this image was digitized.  Attempts will be made to parse the
     111     * values as though it is in the {@link TimeZone} represented by the {@code timeZone} parameter
     112     * (if it is non-null).
     113     *
     114     * @param timeZone the time zone to use
     115     * @return A Date object representing when this image was digitized, if possible, otherwise null
     116     */
     117    @Nullable
     118    public Date getDateDigitized(TimeZone timeZone)
     119    {
     120        return getDate(TAG_DATETIME_DIGITIZED, getString(TAG_SUBSECOND_TIME_DIGITIZED), timeZone);
     121    }
    63122}
  • trunk/src/com/drew/metadata/exif/ExifThumbnailDescriptor.java

    r8243 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
     
    2222package com.drew.metadata.exif;
    2323
     24import static com.drew.metadata.exif.ExifThumbnailDirectory.TAG_THUMBNAIL_LENGTH;
     25import static com.drew.metadata.exif.ExifThumbnailDirectory.TAG_THUMBNAIL_OFFSET;
     26
    2427import com.drew.lang.annotations.NotNull;
    2528import com.drew.lang.annotations.Nullable;
    26 
    27 import static com.drew.metadata.exif.ExifThumbnailDirectory.*;
    2829
    2930/**
     
    4849            case TAG_THUMBNAIL_LENGTH:
    4950                return getThumbnailLengthDescription();
    50             case TAG_THUMBNAIL_COMPRESSION:
    51                 return getCompressionDescription();
    5251            default:
    5352                return super.getDescription(tagType);
    54         }
    55     }
    56 
    57     @Nullable
    58     public String getCompressionDescription()
    59     {
    60         Integer value = _directory.getInteger(TAG_THUMBNAIL_COMPRESSION);
    61         if (value == null)
    62             return null;
    63         switch (value) {
    64             case 1: return "Uncompressed";
    65             case 2: return "CCITT 1D";
    66             case 3: return "T4/Group 3 Fax";
    67             case 4: return "T6/Group 4 Fax";
    68             case 5: return "LZW";
    69             case 6: return "JPEG (old-style)";
    70             case 7: return "JPEG";
    71             case 8: return "Adobe Deflate";
    72             case 9: return "JBIG B&W";
    73             case 10: return "JBIG Color";
    74             case 32766: return "Next";
    75             case 32771: return "CCIRLEW";
    76             case 32773: return "PackBits";
    77             case 32809: return "Thunderscan";
    78             case 32895: return "IT8CTPAD";
    79             case 32896: return "IT8LW";
    80             case 32897: return "IT8MP";
    81             case 32898: return "IT8BL";
    82             case 32908: return "PixarFilm";
    83             case 32909: return "PixarLog";
    84             case 32946: return "Deflate";
    85             case 32947: return "DCS";
    86             case 32661: return "JBIG";
    87             case 32676: return "SGILog";
    88             case 32677: return "SGILog24";
    89             case 32712: return "JPEG 2000";
    90             case 32713: return "Nikon NEF Compressed";
    91             default:
    92                 return "Unknown compression";
    9353        }
    9454    }
  • trunk/src/com/drew/metadata/exif/ExifThumbnailDirectory.java

    r8243 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
     
    2222package com.drew.metadata.exif;
    2323
     24import java.io.FileOutputStream;
     25import java.io.IOException;
     26import java.util.HashMap;
     27
    2428import com.drew.lang.annotations.NotNull;
    2529import com.drew.lang.annotations.Nullable;
    2630import com.drew.metadata.MetadataException;
    27 
    28 import java.io.FileOutputStream;
    29 import java.io.IOException;
    30 import java.util.HashMap;
    3131
    3232/**
     
    4646    public static final int TAG_THUMBNAIL_LENGTH = 0x0202;
    4747
    48     /**
    49      * Shows compression method for Thumbnail.
    50      * 1 = Uncompressed
    51      * 2 = CCITT 1D
    52      * 3 = T4/Group 3 Fax
    53      * 4 = T6/Group 4 Fax
    54      * 5 = LZW
    55      * 6 = JPEG (old-style)
    56      * 7 = JPEG
    57      * 8 = Adobe Deflate
    58      * 9 = JBIG B&amp;W
    59      * 10 = JBIG Color
    60      * 32766 = Next
    61      * 32771 = CCIRLEW
    62      * 32773 = PackBits
    63      * 32809 = Thunderscan
    64      * 32895 = IT8CTPAD
    65      * 32896 = IT8LW
    66      * 32897 = IT8MP
    67      * 32898 = IT8BL
    68      * 32908 = PixarFilm
    69      * 32909 = PixarLog
    70      * 32946 = Deflate
    71      * 32947 = DCS
    72      * 34661 = JBIG
    73      * 34676 = SGILog
    74      * 34677 = SGILog24
    75      * 34712 = JPEG 2000
    76      * 34713 = Nikon NEF Compressed
    77      */
    78     public static final int TAG_THUMBNAIL_COMPRESSION = 0x0103;
    79 
    8048    @NotNull
    8149    protected static final HashMap<Integer, String> _tagNameMap = new HashMap<Integer, String>();
     
    8553        addExifTagNames(_tagNameMap);
    8654
    87         _tagNameMap.put(TAG_THUMBNAIL_COMPRESSION, "Thumbnail Compression");
    8855        _tagNameMap.put(TAG_THUMBNAIL_OFFSET, "Thumbnail Offset");
    8956        _tagNameMap.put(TAG_THUMBNAIL_LENGTH, "Thumbnail Length");
  • trunk/src/com/drew/metadata/exif/ExifTiffHandler.java

    r8243 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
     
    2626import com.drew.lang.SequentialByteArrayReader;
    2727import com.drew.lang.annotations.NotNull;
     28import com.drew.lang.annotations.Nullable;
    2829import com.drew.metadata.Directory;
    2930import com.drew.metadata.Metadata;
     
    4748    private final boolean _storeThumbnailBytes;
    4849
    49     public ExifTiffHandler(@NotNull Metadata metadata, boolean storeThumbnailBytes)
     50    public ExifTiffHandler(@NotNull Metadata metadata, boolean storeThumbnailBytes, @Nullable Directory parentDirectory)
    5051    {
    5152        super(metadata, ExifIFD0Directory.class);
    5253        _storeThumbnailBytes = storeThumbnailBytes;
     54
     55        if (parentDirectory != null)
     56            _currentDirectory.setParent(parentDirectory);
    5357    }
    5458
     
    6569    }
    6670
    67     public boolean isTagIfdPointer(int tagType)
    68     {
    69         if (tagType == ExifIFD0Directory.TAG_EXIF_SUB_IFD_OFFSET && _currentDirectory instanceof ExifIFD0Directory) {
     71    public boolean tryEnterSubIfd(int tagId)
     72    {
     73        if (tagId == ExifDirectoryBase.TAG_SUB_IFD_OFFSET) {
    7074            pushDirectory(ExifSubIFDDirectory.class);
    7175            return true;
    72         } else if (tagType == ExifIFD0Directory.TAG_GPS_INFO_OFFSET && _currentDirectory instanceof ExifIFD0Directory) {
    73             pushDirectory(GpsDirectory.class);
    74             return true;
    75         } else if (tagType == ExifSubIFDDirectory.TAG_INTEROP_OFFSET && _currentDirectory instanceof ExifSubIFDDirectory) {
    76             pushDirectory(ExifInteropDirectory.class);
    77             return true;
     76        }
     77
     78        if (_currentDirectory instanceof ExifIFD0Directory) {
     79            if (tagId == ExifIFD0Directory.TAG_EXIF_SUB_IFD_OFFSET) {
     80                pushDirectory(ExifSubIFDDirectory.class);
     81                return true;
     82            }
     83
     84            if (tagId == ExifIFD0Directory.TAG_GPS_INFO_OFFSET) {
     85                pushDirectory(GpsDirectory.class);
     86                return true;
     87            }
     88        }
     89
     90        if (_currentDirectory instanceof ExifSubIFDDirectory) {
     91            if (tagId == ExifSubIFDDirectory.TAG_INTEROP_OFFSET) {
     92                pushDirectory(ExifInteropDirectory.class);
     93                return true;
     94            }
     95        }
     96
     97        if (_currentDirectory instanceof OlympusMakernoteDirectory) {
     98            if (tagId == OlympusMakernoteDirectory.TAG_EQUIPMENT) {
     99                pushDirectory(OlympusEquipmentMakernoteDirectory.class);
     100                return true;
     101            }
     102
     103            if (tagId == OlympusMakernoteDirectory.TAG_CAMERA_SETTINGS) {
     104                pushDirectory(OlympusCameraSettingsMakernoteDirectory.class);
     105                return true;
     106            }
    78107        }
    79108
     
    96125        // NOTE have seen the CanonMakernoteDirectory IFD have a follower pointer, but it points to invalid data.
    97126        return false;
     127    }
     128
     129    @Nullable
     130    public Long tryCustomProcessFormat(final int tagId, final int formatCode, final long componentCount)
     131    {
     132        if (formatCode == 13)
     133            return componentCount * 4;
     134
     135        return null;
    98136    }
    99137
     
    115153            if (reader.getInt8(tagOffset) == 0x1c) {
    116154                final byte[] iptcBytes = reader.getBytes(tagOffset, byteCount);
    117                 new IptcReader().extract(new SequentialByteArrayReader(iptcBytes), _metadata, iptcBytes.length);
     155                new IptcReader().extract(new SequentialByteArrayReader(iptcBytes), _metadata, iptcBytes.length, _currentDirectory);
    118156                return true;
    119157            }
     
    129167            // after the extraction process, if we have the correct tags, we may be able to store thumbnail information
    130168            ExifThumbnailDirectory thumbnailDirectory = _metadata.getFirstDirectoryOfType(ExifThumbnailDirectory.class);
    131             if (thumbnailDirectory != null && thumbnailDirectory.containsTag(ExifThumbnailDirectory.TAG_THUMBNAIL_COMPRESSION)) {
     169            if (thumbnailDirectory != null && thumbnailDirectory.containsTag(ExifThumbnailDirectory.TAG_COMPRESSION)) {
    132170                Integer offset = thumbnailDirectory.getInteger(ExifThumbnailDirectory.TAG_THUMBNAIL_OFFSET);
    133171                Integer length = thumbnailDirectory.getInteger(ExifThumbnailDirectory.TAG_THUMBNAIL_LENGTH);
     
    164202        final String firstSevenChars = reader.getString(makernoteOffset, 7);
    165203        final String firstEightChars = reader.getString(makernoteOffset, 8);
     204        final String firstTenChars = reader.getString(makernoteOffset, 10);
    166205        final String firstTwelveChars = reader.getString(makernoteOffset, 12);
    167206
    168207        boolean byteOrderBefore = reader.isMotorolaByteOrder();
    169208
    170         if ("OLYMP".equals(firstFiveChars) || "EPSON".equals(firstFiveChars) || "AGFA".equals(firstFourChars)) {
     209        if ("OLYMP\0".equals(firstSixChars) || "EPSON".equals(firstFiveChars) || "AGFA".equals(firstFourChars)) {
    171210            // Olympus Makernote
    172211            // Epson and Agfa use Olympus makernote standard: http://www.ozhiker.com/electronics/pjmt/jpeg_info/
    173212            pushDirectory(OlympusMakernoteDirectory.class);
    174213            TiffReader.processIfd(this, reader, processedIfdOffsets, makernoteOffset + 8, tiffHeaderOffset);
     214        } else if ("OLYMPUS\0II".equals(firstTenChars)) {
     215            // Olympus Makernote (alternate)
     216            // Note that data is relative to the beginning of the makernote
     217            // http://exiv2.org/makernote.html
     218            pushDirectory(OlympusMakernoteDirectory.class);
     219            TiffReader.processIfd(this, reader, processedIfdOffsets, makernoteOffset + 12, makernoteOffset);
    175220        } else if (cameraMake != null && cameraMake.toUpperCase().startsWith("MINOLTA")) {
    176221            // Cases seen with the model starting with MINOLTA in capitals seem to have a valid Olympus makernote
  • trunk/src/com/drew/metadata/exif/GpsDescriptor.java

    r8243 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
     
    110110        // time in hour, min, sec
    111111        Rational[] timeComponents = _directory.getRationalArray(TAG_TIME_STAMP);
    112         DecimalFormat df = new DecimalFormat("00.00");
     112        DecimalFormat df = new DecimalFormat("00.000");
    113113        return timeComponents == null
    114114            ? null
  • trunk/src/com/drew/metadata/exif/GpsDirectory.java

    r8243 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
     
    2626import com.drew.lang.annotations.Nullable;
    2727
     28import java.text.DateFormat;
     29import java.text.ParseException;
     30import java.text.SimpleDateFormat;
     31import java.util.Date;
    2832import java.util.HashMap;
     33import java.util.Locale;
    2934
    3035/**
     
    164169    public GeoLocation getGeoLocation()
    165170    {
    166         Rational[] latitudes = getRationalArray(GpsDirectory.TAG_LATITUDE);
    167         Rational[] longitudes = getRationalArray(GpsDirectory.TAG_LONGITUDE);
    168         String latitudeRef = getString(GpsDirectory.TAG_LATITUDE_REF);
    169         String longitudeRef = getString(GpsDirectory.TAG_LONGITUDE_REF);
     171        Rational[] latitudes = getRationalArray(TAG_LATITUDE);
     172        Rational[] longitudes = getRationalArray(TAG_LONGITUDE);
     173        String latitudeRef = getString(TAG_LATITUDE_REF);
     174        String longitudeRef = getString(TAG_LONGITUDE_REF);
    170175
    171176        // Make sure we have the required values
     
    186191        return new GeoLocation(lat, lon);
    187192    }
     193
     194    /**
     195     * Parses the date stamp tag and the time stamp tag to obtain a single Date object representing the
     196     * date and time when this image was captured.
     197     *
     198     * @return A Date object representing when this image was captured, if possible, otherwise null
     199     */
     200    @Nullable
     201    public Date getGpsDate()
     202    {
     203        String date = getString(TAG_DATE_STAMP);
     204        Rational[] timeComponents = getRationalArray(TAG_TIME_STAMP);
     205
     206        // Make sure we have the required values
     207        if (date == null)
     208            return null;
     209        if (timeComponents == null || timeComponents.length != 3)
     210            return null;
     211
     212        String dateTime = String.format(Locale.US, "%s %02d:%02d:%02.3f UTC",
     213            date, timeComponents[0].intValue(), timeComponents[1].intValue(), timeComponents[2].doubleValue());
     214        try {
     215            DateFormat parser = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss.S z");
     216            return parser.parse(dateTime);
     217        } catch (ParseException e) {
     218            return null;
     219        }
     220    }
    188221}
  • trunk/src/com/drew/metadata/exif/makernotes/CanonMakernoteDescriptor.java

    r8243 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
     
    2424import com.drew.lang.annotations.Nullable;
    2525import com.drew.metadata.TagDescriptor;
     26
     27import java.text.DecimalFormat;
    2628
    2729import static com.drew.metadata.exif.makernotes.CanonMakernoteDirectory.*;
     
    138140    public String getSerialNumberDescription()
    139141    {
     142        // http://www.ozhiker.com/electronics/pjmt/jpeg_info/canon_mn.html
    140143        Integer value = _directory.getInteger(TAG_CANON_SERIAL_NUMBER);
    141144        if (value == null)
     
    673676            return "Self timer not used";
    674677        } else {
    675             // TODO find an image that tests this calculation
    676             return Double.toString((double)value * 0.1d) + " sec";
     678            DecimalFormat format = new DecimalFormat("0.##");
     679            return format.format((double)value * 0.1d) + " sec";
    677680        }
    678681    }
  • trunk/src/com/drew/metadata/exif/makernotes/CanonMakernoteDirectory.java

    r8243 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/makernotes/CasioType1MakernoteDescriptor.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
     
    155155    {
    156156        Integer value = _directory.getInteger(TAG_OBJECT_DISTANCE);
    157 
    158         if (value == null)
    159             return null;
    160 
    161         return value + " mm";
     157        return value == null ? null : getFocalLengthDescription(value);
    162158    }
    163159
  • trunk/src/com/drew/metadata/exif/makernotes/CasioType1MakernoteDirectory.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/makernotes/CasioType2MakernoteDescriptor.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
     
    240240    {
    241241        Double value = _directory.getDoubleObject(TAG_FOCAL_LENGTH);
    242         if (value == null)
    243             return null;
    244         return Double.toString(value / 10d) + " mm";
     242        return value == null ? null : getFocalLengthDescription(value / 10d);
    245243    }
    246244
  • trunk/src/com/drew/metadata/exif/makernotes/CasioType2MakernoteDirectory.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/makernotes/FujifilmMakernoteDescriptor.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/makernotes/FujifilmMakernoteDirectory.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/makernotes/KodakMakernoteDescriptor.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/makernotes/KodakMakernoteDirectory.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/makernotes/KyoceraMakernoteDescriptor.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/makernotes/KyoceraMakernoteDirectory.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/makernotes/LeicaMakernoteDescriptor.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/makernotes/LeicaMakernoteDirectory.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/makernotes/NikonType1MakernoteDescriptor.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/makernotes/NikonType1MakernoteDirectory.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/makernotes/NikonType2MakernoteDescriptor.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
     
    306306    {
    307307        int[] values = _directory.getIntArray(tagType);
    308         if (values == null)
     308        if (values == null || values.length < 2)
    309309            return null;
    310310        if (values.length < 3 || values[2] == 0)
     
    329329    public String getLensDescription()
    330330    {
    331         Rational[] values = _directory.getRationalArray(TAG_LENS);
    332 
    333         return values == null
    334             ? null
    335             : values.length < 4
    336                 ? _directory.getString(TAG_LENS)
    337                 : String.format("%d-%dmm f/%.1f-%.1f", values[0].intValue(), values[1].intValue(), values[2].floatValue(), values[3].floatValue());
    338 
     331        return getLensSpecificationDescription(TAG_LENS);
    339332    }
    340333
  • trunk/src/com/drew/metadata/exif/makernotes/NikonType2MakernoteDirectory.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/makernotes/OlympusMakernoteDescriptor.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
     
    2121package com.drew.metadata.exif.makernotes;
    2222
     23import com.drew.lang.DateUtil;
    2324import com.drew.lang.annotations.NotNull;
    2425import com.drew.lang.annotations.Nullable;
    2526import com.drew.metadata.TagDescriptor;
    2627
    27 import java.util.GregorianCalendar;
     28import java.math.RoundingMode;
     29import java.text.DecimalFormat;
    2830
    2931import static com.drew.metadata.exif.makernotes.OlympusMakernoteDirectory.*;
     
    115117                return getFocusDistanceDescription();
    116118            case CameraSettings.TAG_FLASH_FIRED:
    117                 return getFlastFiredDescription();
     119                return getFlashFiredDescription();
    118120            case CameraSettings.TAG_DATE:
    119121                return getDateDescription();
     
    142144                return getSubjectProgramDescription();
    143145            case CameraSettings.TAG_FLASH_COMPENSATION:
    144                 return getFlastCompensationDescription();
     146                return getFlashCompensationDescription();
    145147            case CameraSettings.TAG_ISO_SETTING:
    146148                return getIsoSettingDescription();
     
    258260
    259261        double iso = Math.pow((value / 8d) - 1, 2) * 3.125;
    260         return Double.toString(iso);
     262        DecimalFormat format = new DecimalFormat("0.##");
     263        format.setRoundingMode(RoundingMode.HALF_UP);
     264        return format.format(iso);
    261265    }
    262266
     
    274278
    275279        double shutterSpeed = Math.pow((49-value) / 8d, 2);
    276         return Double.toString(shutterSpeed) + " sec";
     280        DecimalFormat format = new DecimalFormat("0.###");
     281        format.setRoundingMode(RoundingMode.HALF_UP);
     282        return format.format(shutterSpeed) + " sec";
    277283    }
    278284
     
    289295
    290296        double fStop = Math.pow((value/16d) - 0.5, 2);
    291         return "F" + Double.toString(fStop);
     297        return getFStopDescription(fStop);
    292298    }
    293299
     
    308314    {
    309315        Long value = _directory.getLongObject(CameraSettings.TAG_EXPOSURE_COMPENSATION);
    310         return value == null ? null : ((value / 3d) - 2) + " EV";
     316        DecimalFormat format = new DecimalFormat("0.##");
     317        return value == null ? null : format.format((value / 3d) - 2) + " EV";
    311318    }
    312319
     
    341348    {
    342349        Long value = _directory.getLongObject(CameraSettings.TAG_FOCAL_LENGTH);
    343         return value == null ? null : Double.toString(value/256d) + " mm";
     350        return value == null ? null : getFocalLengthDescription(value/256d);
    344351    }
    345352
     
    356363
    357364    @Nullable
    358     public String getFlastFiredDescription()
     365    public String getFlashFiredDescription()
    359366    {
    360367        return getIndexedDescription(CameraSettings.TAG_FLASH_FIRED, "No", "Yes");
     
    370377        if (value == null)
    371378            return null;
    372         long day = value & 0xFF;
    373         long month = (value >> 16) & 0xFF;
    374         long year = (value >> 8) & 0xFF;
    375         return new GregorianCalendar((int)year + 1970, (int)month, (int)day).getTime().toString();
     379
     380        int day = (int) (value & 0xFF);
     381        int month = (int) ((value >> 16) & 0xFF);
     382        int year = (int) ((value >> 8) & 0xFF) + 1970;
     383
     384        if (!DateUtil.isValidDate(year, month, day))
     385            return "Invalid date";
     386
     387        return String.format("%04d-%02d-%02d", year, month + 1, day);
    376388    }
    377389
     
    385397        if (value == null)
    386398            return null;
    387         long hours = (value >> 8) & 0xFF;
    388         long minutes = (value >> 16) & 0xFF;
    389         long seconds = value & 0xFF;
     399
     400        int hours = (int) ((value >> 8) & 0xFF);
     401        int minutes = (int) ((value >> 16) & 0xFF);
     402        int seconds = (int) (value & 0xFF);
     403
     404        if (!DateUtil.isValidTime(hours, minutes, seconds))
     405            return "Invalid time";
    390406
    391407        return String.format("%02d:%02d:%02d", hours, minutes, seconds);
     
    400416            return null;
    401417        double fStop = Math.pow((value/16d) - 0.5, 2);
    402         return "F" + fStop;
     418        return getFStopDescription(fStop);
    403419    }
    404420
     
    424440    {
    425441        Long value = _directory.getLongObject(CameraSettings.TAG_WHITE_BALANCE_RED);
    426         return value == null ? null : Double.toString(value/256d);
     442        DecimalFormat format = new DecimalFormat("0.##");
     443        return value == null ? null : format.format(value/256d);
    427444    }
    428445
     
    431448    {
    432449        Long value = _directory.getLongObject(CameraSettings.TAG_WHITE_BALANCE_GREEN);
    433         return value == null ? null : Double.toString(value/256d);
     450        DecimalFormat format = new DecimalFormat("0.##");
     451        return value == null ? null : format.format(value/256d);
    434452    }
    435453
     
    438456    {
    439457        Long value = _directory.getLongObject(CameraSettings.TAG_WHITE_BALANCE_BLUE);
    440         return value == null ? null : Double.toString(value/256d);
     458        DecimalFormat format = new DecimalFormat("0.##");
     459        return value == null ? null : format.format(value / 256d);
    441460    }
    442461
     
    468487
    469488    @Nullable
    470     public String getFlastCompensationDescription()
     489    public String getFlashCompensationDescription()
    471490    {
    472491        Long value = _directory.getLongObject(CameraSettings.TAG_FLASH_COMPENSATION);
    473         return value == null ? null : ((value-6)/3d) + " EV";
     492        DecimalFormat format = new DecimalFormat("0.##");
     493        return value == null ? null : format.format((value-6)/3d) + " EV";
    474494    }
    475495
     
    535555    {
    536556        Long value = _directory.getLongObject(CameraSettings.TAG_APEX_BRIGHTNESS_VALUE);
    537         return value == null ? null : Double.toString((value/8d)-6);
     557        DecimalFormat format = new DecimalFormat("0.##");
     558        return value == null ? null : format.format((value/8d)-6);
    538559    }
    539560
  • trunk/src/com/drew/metadata/exif/makernotes/OlympusMakernoteDirectory.java

    r8243 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/makernotes/PanasonicMakernoteDescriptor.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/makernotes/PanasonicMakernoteDirectory.java

    r8243 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/makernotes/PentaxMakernoteDescriptor.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/makernotes/PentaxMakernoteDirectory.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/makernotes/RicohMakernoteDescriptor.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/makernotes/RicohMakernoteDirectory.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/makernotes/SanyoMakernoteDescriptor.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/makernotes/SanyoMakernoteDirectory.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/makernotes/SigmaMakernoteDescriptor.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/makernotes/SigmaMakernoteDirectory.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/makernotes/SonyType1MakernoteDescriptor.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/makernotes/SonyType1MakernoteDirectory.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/makernotes/SonyType6MakernoteDescriptor.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/makernotes/SonyType6MakernoteDirectory.java

    r8132 r10862  
    11/*
    2  * Copyright 2002-2015 Drew Noakes
     2 * Copyright 2002-2016 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/makernotes/package.html

    r8132 r10862  
    11<!--
    2   ~ Copyright 2002-2015 Drew Noakes
     2  ~ Copyright 2002-2016 Drew Noakes
    33  ~
    44  ~    Licensed under the Apache License, Version 2.0 (the "License");
  • trunk/src/com/drew/metadata/exif/package.html

    r8132 r10862  
    11<!--
    2   ~ Copyright 2002-2015 Drew Noakes
     2  ~ Copyright 2002-2016 Drew Noakes
    33  ~
    44  ~    Licensed under the Apache License, Version 2.0 (the "License");
Note: See TracChangeset for help on using the changeset viewer.