Changeset 10862 in josm for trunk/src/com/drew/imaging


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

update to metadata-extractor 2.9.1

Location:
trunk/src/com/drew/imaging
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/com/drew/imaging/ImageProcessingException.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/imaging/PhotographicConversions.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/imaging/jpeg/JpegMetadataReader.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");
     
    3939import com.drew.metadata.iptc.IptcReader;
    4040//import com.drew.metadata.jfif.JfifReader;
     41//import com.drew.metadata.jfxx.JfxxReader;
    4142import com.drew.metadata.jpeg.JpegCommentReader;
    4243import com.drew.metadata.jpeg.JpegReader;
     44//import com.drew.metadata.photoshop.DuckyReader;
    4345//import com.drew.metadata.photoshop.PhotoshopReader;
    4446//import com.drew.metadata.xmp.XmpReader;
     
    5557            new JpegCommentReader(),
    5658            //new JfifReader(),
     59            //new JfxxReader(),
    5760            new ExifReader(),
    5861            //new XmpReader(),
    5962            //new IccReader(),
    6063            //new PhotoshopReader(),
     64            //new DuckyReader(),
    6165            new IptcReader()//,
    6266            //new AdobeJpegReader()
  • trunk/src/com/drew/imaging/jpeg/JpegProcessingException.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/imaging/jpeg/JpegSegmentData.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");
     
    5252     * @param segmentBytes the byte array holding data for the segment being added
    5353     */
    54     @SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"})
    5554    public void addSegment(byte segmentType, @NotNull byte[] segmentBytes)
    5655    {
     
    207206     * @param occurrence  the zero-based index of the segment occurrence to remove.
    208207     */
    209     @SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"})
    210208    public void removeSegmentOccurrence(@NotNull JpegSegmentType segmentType, int occurrence)
    211209    {
     
    220218     * @param occurrence  the zero-based index of the segment occurrence to remove.
    221219     */
    222     @SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"})
    223220    public void removeSegmentOccurrence(byte segmentType, int occurrence)
    224221    {
  • trunk/src/com/drew/imaging/jpeg/JpegSegmentReader.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");
     
    4343public class JpegSegmentReader
    4444{
     45    /**
     46     * The 0xFF byte that signals the start of a segment.
     47     */
     48    private static final byte SEGMENT_IDENTIFIER = (byte) 0xFF;
     49
    4550    /**
    4651     * Private, because this segment crashes my algorithm, and searching for it doesn't work (yet).
     
    112117            // by a 0xFF and then a byte not equal to 0x00 or 0xFF.
    113118
    114             final short segmentIdentifier = reader.getUInt8();
     119            byte segmentIdentifier = reader.getInt8();
     120            byte segmentType = reader.getInt8();
    115121
    116             // We must have at least one 0xFF byte
    117             if (segmentIdentifier != 0xFF)
    118                 throw new JpegProcessingException("Expected JPEG segment start identifier 0xFF, not 0x" + Integer.toHexString(segmentIdentifier).toUpperCase());
    119 
    120             // Read until we have a non-0xFF byte. This identifies the segment type.
    121             byte segmentType = reader.getInt8();
    122             while (segmentType == (byte)0xFF)
    123                 segmentType = reader.getInt8();
    124 
    125             if (segmentType == 0)
    126                 throw new JpegProcessingException("Expected non-zero byte as part of JPEG marker identifier");
     122            // Read until we have a 0xFF byte followed by a byte that is not 0xFF or 0x00
     123            while (segmentIdentifier != SEGMENT_IDENTIFIER || segmentType == SEGMENT_IDENTIFIER || segmentType == 0) {
     124                segmentIdentifier = segmentType;
     125                segmentType = reader.getInt8();
     126            }
    127127
    128128            if (segmentType == SEGMENT_SOS) {
  • trunk/src/com/drew/imaging/jpeg/JpegSegmentType.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");
     
    3030 * An enumeration of the known segment types found in JPEG files.
    3131 *
     32 * <ul>
     33 *     <li>http://www.ozhiker.com/electronics/pjmt/jpeg_info/app_segments.html</li>
     34 *     <li>http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/JPEG.html</li>
     35 * </ul>
     36 *
    3237 * @author Drew Noakes https://drewnoakes.com
    3338 */
    3439public enum JpegSegmentType
    3540{
    36     /** APP0 JPEG segment identifier -- JFIF data (also JFXX apparently). */
     41    /** APP0 JPEG segment identifier. Commonly contains JFIF, JFXX. */
    3742    APP0((byte)0xE0, true),
    3843
    39     /** APP1 JPEG segment identifier -- where Exif data is kept. XMP data is also kept in here, though usually in a second instance. */
     44    /** APP1 JPEG segment identifier. Commonly contains Exif. XMP data is also kept in here, though usually in a second instance. */
    4045    APP1((byte)0xE1, true),
    4146
    42     /** APP2 JPEG segment identifier. */
     47    /** APP2 JPEG segment identifier. Commonly contains ICC. */
    4348    APP2((byte)0xE2, true),
    4449
     
    6469    APP9((byte)0xE9, true),
    6570
    66     /** APPA (App10) JPEG segment identifier -- can hold Unicode comments. */
     71    /** APPA (App10) JPEG segment identifier. Can contain Unicode comments, though {@link JpegSegmentType#COM} is more commonly used for comments. */
    6772    APPA((byte)0xEA, true),
    6873
     
    7378    APPC((byte)0xEC, true),
    7479
    75     /** APPD (App13) JPEG segment identifier -- IPTC data in here. */
     80    /** APPD (App13) JPEG segment identifier. Commonly contains IPTC, Photoshop data. */
    7681    APPD((byte)0xED, true),
    7782
    78     /** APPE (App14) JPEG segment identifier. */
     83    /** APPE (App14) JPEG segment identifier. Commonly contains Adobe data. */
    7984    APPE((byte)0xEE, true),
    8085
  • trunk/src/com/drew/imaging/jpeg/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/imaging/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/imaging/tiff/TiffDataFormat.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/imaging/tiff/TiffHandler.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.Rational;
    2525import com.drew.lang.annotations.NotNull;
     26import com.drew.lang.annotations.Nullable;
    2627
    2728import java.io.IOException;
     
    4647    void setTiffMarker(int marker) throws TiffProcessingException;
    4748
    48     boolean isTagIfdPointer(int tagType);
     49    boolean tryEnterSubIfd(int tagId);
    4950    boolean hasFollowerIfd();
    5051
     
    5253
    5354    void completed(@NotNull final RandomAccessReader reader, final int tiffHeaderOffset);
     55
     56    @Nullable
     57    Long tryCustomProcessFormat(int tagId, int formatCode, long componentCount);
    5458
    5559    boolean customProcessTag(int tagOffset,
  • trunk/src/com/drew/imaging/tiff/TiffProcessingException.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/imaging/tiff/TiffReader.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");
     
    110110                                  final int tiffHeaderOffset) throws IOException
    111111    {
     112        Boolean resetByteOrder = null;
    112113        try {
    113114            // check for directories we've already visited to avoid stack overflows when recursive/cyclic directory structures exist
     
    126127            // First two bytes in the IFD are the number of tags in this directory
    127128            int dirTagCount = reader.getUInt16(ifdOffset);
     129
     130            // Some software modifies the byte order of the file, but misses some IFDs (such as makernotes).
     131            // The entire test image repository doesn't contain a single IFD with more than 255 entries.
     132            // Here we detect switched bytes that suggest this problem, and temporarily swap the byte order.
     133            // This was discussed in GitHub issue #136.
     134            if (dirTagCount > 0xFF && (dirTagCount & 0xFF) == 0) {
     135                resetByteOrder = reader.isMotorolaByteOrder();
     136                dirTagCount >>= 8;
     137                reader.setMotorolaByteOrder(!reader.isMotorolaByteOrder());
     138            }
    128139
    129140            int dirLength = (2 + (12 * dirTagCount) + 4);
     
    147158                final TiffDataFormat format = TiffDataFormat.fromTiffFormatCode(formatCode);
    148159
     160                // 4 bytes dictate the number of components in this tag's data
     161                final long componentCount = reader.getUInt32(tagOffset + 4);
     162
     163                final long byteCount;
    149164                if (format == null) {
    150                     // This error suggests that we are processing at an incorrect index and will generate
    151                     // rubbish until we go out of bounds (which may be a while).  Exit now.
    152                     handler.error("Invalid TIFF tag format code: " + formatCode);
    153                     // TODO specify threshold as a parameter, or provide some other external control over this behaviour
    154                     if (++invalidTiffFormatCodeCount > 5) {
    155                         handler.error("Stopping processing as too many errors seen in TIFF IFD");
    156                         return;
     165                    Long byteCountOverride = handler.tryCustomProcessFormat(tagId, formatCode, componentCount);
     166                    if (byteCountOverride == null) {
     167                        // This error suggests that we are processing at an incorrect index and will generate
     168                        // rubbish until we go out of bounds (which may be a while).  Exit now.
     169                        handler.error(String.format("Invalid TIFF tag format code %d for tag 0x%04X", formatCode, tagId));
     170                        // TODO specify threshold as a parameter, or provide some other external control over this behaviour
     171                        if (++invalidTiffFormatCodeCount > 5) {
     172                            handler.error("Stopping processing as too many errors seen in TIFF IFD");
     173                            return;
     174                        }
     175                        continue;
    157176                    }
    158                     continue;
    159                 }
    160 
    161                 // 4 bytes dictate the number of components in this tag's data
    162                 final int componentCount = reader.getInt32(tagOffset + 4);
    163                 if (componentCount < 0) {
    164                     handler.error("Negative TIFF tag component count");
    165                     continue;
    166                 }
    167 
    168                 final int byteCount = componentCount * format.getComponentSizeBytes();
    169 
    170                 final int tagValueOffset;
     177                    byteCount = byteCountOverride;
     178                } else {
     179                    byteCount = componentCount * format.getComponentSizeBytes();
     180                }
     181
     182                final long tagValueOffset;
    171183                if (byteCount > 4) {
    172184                    // If it's bigger than 4 bytes, the dir entry contains an offset.
    173                     final int offsetVal = reader.getInt32(tagOffset + 8);
     185                    final long offsetVal = reader.getUInt32(tagOffset + 8);
    174186                    if (offsetVal + byteCount > reader.getLength()) {
    175187                        // Bogus pointer offset and / or byteCount value
     
    195207                }
    196208
    197                 //
    198                 // Special handling for tags that point to other IFDs
    199                 //
    200                 if (byteCount == 4 && handler.isTagIfdPointer(tagId)) {
    201                     final int subDirOffset = tiffHeaderOffset + reader.getInt32(tagValueOffset);
    202                     processIfd(handler, reader, processedIfdOffsets, subDirOffset, tiffHeaderOffset);
    203                 } else {
    204                     if (!handler.customProcessTag(tagValueOffset, processedIfdOffsets, tiffHeaderOffset, reader, tagId, byteCount)) {
    205                         processTag(handler, tagId, tagValueOffset, componentCount, formatCode, reader);
     209                // Some tags point to one or more additional IFDs to process
     210                boolean isIfdPointer = false;
     211                if (byteCount == 4 * componentCount) {
     212                    for (int i = 0; i < componentCount; i++) {
     213                        if (handler.tryEnterSubIfd(tagId)) {
     214                            isIfdPointer = true;
     215                            int subDirOffset = tiffHeaderOffset + reader.getInt32((int) (tagValueOffset + i * 4));
     216                            processIfd(handler, reader, processedIfdOffsets, subDirOffset, tiffHeaderOffset);
     217                        }
    206218                    }
     219                }
     220
     221                // If it wasn't an IFD pointer, allow custom tag processing to occur
     222                if (!isIfdPointer && !handler.customProcessTag((int) tagValueOffset, processedIfdOffsets, tiffHeaderOffset, reader, tagId, (int) byteCount)) {
     223                    // If no custom processing occurred, process the tag in the standard fashion
     224                    processTag(handler, tagId, (int) tagValueOffset, (int) componentCount, formatCode, reader);
    207225                }
    208226            }
     
    229247        } finally {
    230248            handler.endingIFD();
     249            if (resetByteOrder != null)
     250                reader.setMotorolaByteOrder(resetByteOrder);
    231251        }
    232252    }
     
    350370                break;
    351371            default:
    352                 handler.error(String.format("Unknown format code %d for tag %d", formatCode, tagId));
     372                handler.error(String.format("Invalid TIFF tag format code %d for tag 0x%04X", formatCode, tagId));
    353373        }
    354374    }
  • trunk/src/com/drew/imaging/tiff/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.