Ignore:
Timestamp:
2013-08-09T18:05:11+02:00 (13 years ago)
Author:
bastiK
Message:

applied #8895 - Upgrade metadata-extractor to v. 2.6.4 (patch by ebourg)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/com/drew/imaging/jpeg/JpegMetadataReader.java

    r4231 r6127  
    11/*
    2  * This is public domain software - that is, you can do whatever you want
    3  * with it, and include it software that is licensed under the GNU or the
    4  * BSD license, or whatever other licence you choose, including proprietary
    5  * closed source licenses.  I do ask that you leave this header in tact.
     2 * Copyright 2002-2012 Drew Noakes
    63 *
    7  * If you make modifications to this code that you think would benefit the
    8  * wider community, please send me a copy and I'll post it on my site.
     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
    97 *
    10  * If you make use of this code, I'd appreciate hearing about it.
    11  *   drew@drewnoakes.com
    12  * Latest version of this software kept at
    13  *   http://drewnoakes.com/
     8 *        http://www.apache.org/licenses/LICENSE-2.0
    149 *
    15  * Created by dnoakes on 12-Nov-2002 18:51:36 using IntelliJ IDEA.
     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 *    http://drewnoakes.com/code/exif/
     19 *    http://code.google.com/p/metadata-extractor/
    1620 */
    1721package com.drew.imaging.jpeg;
    1822
    19 import com.drew.metadata.Directory;
     23import com.drew.lang.ByteArrayReader;
     24import com.drew.lang.annotations.NotNull;
    2025import com.drew.metadata.Metadata;
    21 import com.drew.metadata.MetadataException;
    22 import com.drew.metadata.Tag;
    23 import com.drew.metadata.exif.ExifDirectory;
    2426import com.drew.metadata.exif.ExifReader;
    2527import com.drew.metadata.iptc.IptcReader;
    2628import com.drew.metadata.jpeg.JpegCommentReader;
     29import com.drew.metadata.jpeg.JpegDirectory;
    2730import com.drew.metadata.jpeg.JpegReader;
    2831
     
    3033import java.io.IOException;
    3134import java.io.InputStream;
    32 import java.util.Iterator;
    3335
    3436/**
     37 * Obtains all available metadata from Jpeg formatted files.
    3538 *
     39 * @author Drew Noakes http://drewnoakes.com
    3640 */
    3741public class JpegMetadataReader
    3842{
     43    // TODO investigate supporting javax.imageio
    3944//    public static Metadata readMetadata(IIOMetadata metadata) throws JpegProcessingException {}
    4045//    public static Metadata readMetadata(ImageInputStream in) throws JpegProcessingException{}
     
    4247//    public static Metadata readMetadata(ImageReader reader) throws JpegProcessingException{}
    4348
    44     public static Metadata readMetadata(InputStream in) throws JpegProcessingException
     49    @NotNull
     50    public static Metadata readMetadata(@NotNull InputStream inputStream) throws JpegProcessingException
    4551    {
    46         JpegSegmentReader segmentReader = new JpegSegmentReader(in);
    47         return extractMetadataFromJpegSegmentReader(segmentReader);
     52        return readMetadata(inputStream, true);
    4853    }
    4954
    50     public static Metadata readMetadata(File file) throws JpegProcessingException
     55    @NotNull
     56    public static Metadata readMetadata(@NotNull InputStream inputStream, final boolean waitForBytes) throws JpegProcessingException
     57    {
     58        JpegSegmentReader segmentReader = new JpegSegmentReader(inputStream, waitForBytes);
     59        return extractMetadataFromJpegSegmentReader(segmentReader.getSegmentData());
     60    }
     61
     62    @NotNull
     63    public static Metadata readMetadata(@NotNull File file) throws JpegProcessingException, IOException
    5164    {
    5265        JpegSegmentReader segmentReader = new JpegSegmentReader(file);
    53         return extractMetadataFromJpegSegmentReader(segmentReader);
     66        return extractMetadataFromJpegSegmentReader(segmentReader.getSegmentData());
    5467    }
    5568
    56     public static Metadata extractMetadataFromJpegSegmentReader(JpegSegmentReader segmentReader)
     69    @NotNull
     70    public static Metadata extractMetadataFromJpegSegmentReader(@NotNull JpegSegmentData segmentReader)
    5771    {
    5872        final Metadata metadata = new Metadata();
    59         try {
    60             byte[] exifSegment = segmentReader.readSegment(JpegSegmentReader.SEGMENT_APP1);
    61             new ExifReader(exifSegment).extract(metadata);
    62         } catch (JpegProcessingException e) {
    63             // in the interests of catching as much data as possible, continue
    64             // TODO lodge error message within exif directory?
     73
     74        // Loop through looking for all SOFn segments.  When we find one, we know what type of compression
     75        // was used for the JPEG, and we can process the JPEG metadata in the segment too.
     76        for (byte i = 0; i < 16; i++) {
     77            // There are no SOF4 or SOF12 segments, so don't bother
     78            if (i == 4 || i == 12)
     79                continue;
     80            // Should never have more than one SOFn for a given 'n'.
     81            byte[] jpegSegment = segmentReader.getSegment((byte)(JpegSegmentReader.SEGMENT_SOF0 + i));
     82            if (jpegSegment == null)
     83                continue;
     84            JpegDirectory directory = metadata.getOrCreateDirectory(JpegDirectory.class);
     85            directory.setInt(JpegDirectory.TAG_JPEG_COMPRESSION_TYPE, i);
     86            new JpegReader().extract(new ByteArrayReader(jpegSegment), metadata);
     87            break;
    6588        }
    6689
    67         try {
    68             byte[] iptcSegment = segmentReader.readSegment(JpegSegmentReader.SEGMENT_APPD);
    69             new IptcReader(iptcSegment).extract(metadata);
    70         } catch (JpegProcessingException e) {
    71             // TODO lodge error message within iptc directory?
     90        // There should never be more than one COM segment.
     91        byte[] comSegment = segmentReader.getSegment(JpegSegmentReader.SEGMENT_COM);
     92        if (comSegment != null)
     93            new JpegCommentReader().extract(new ByteArrayReader(comSegment), metadata);
     94
     95        // Loop through all APP1 segments, checking the leading bytes to identify the format of each.
     96        for (byte[] app1Segment : segmentReader.getSegments(JpegSegmentReader.SEGMENT_APP1)) {
     97            if (app1Segment.length > 3 && "EXIF".equalsIgnoreCase(new String(app1Segment, 0, 4)))
     98                new ExifReader().extract(new ByteArrayReader(app1Segment), metadata);
     99
     100            //if (app1Segment.length > 27 && "http://ns.adobe.com/xap/1.0/".equalsIgnoreCase(new String(app1Segment, 0, 28)))
     101            //    new XmpReader().extract(new ByteArrayReader(app1Segment), metadata);
    72102        }
    73103
    74                 try {
    75                         byte[] jpegSegment = segmentReader.readSegment(JpegSegmentReader.SEGMENT_SOF0);
    76                         new JpegReader(jpegSegment).extract(metadata);
    77                 } catch (JpegProcessingException e) {
    78                         // TODO lodge error message within jpeg directory?
    79                 }
    80 
    81                 try {
    82                         byte[] jpegCommentSegment = segmentReader.readSegment(JpegSegmentReader.SEGMENT_COM);
    83                         new JpegCommentReader(jpegCommentSegment).extract(metadata);
    84                 } catch (JpegProcessingException e) {
    85                         // TODO lodge error message within jpegcomment directory?
    86                 }
     104        // Loop through all APPD segments, checking the leading bytes to identify the format of each.
     105        for (byte[] appdSegment : segmentReader.getSegments(JpegSegmentReader.SEGMENT_APPD)) {
     106            if (appdSegment.length > 12 && "Photoshop 3.0".compareTo(new String(appdSegment, 0, 13))==0) {
     107                //new PhotoshopReader().extract(new ByteArrayReader(appdSegment), metadata);
     108            } else {
     109                // TODO might be able to check for a leading 0x1c02 for IPTC data...
     110                new IptcReader().extract(new ByteArrayReader(appdSegment), metadata);
     111            }
     112        }
    87113
    88114        return metadata;
    89115    }
    90116
    91     private JpegMetadataReader()
     117    private JpegMetadataReader() throws Exception
    92118    {
    93     }
    94 
    95     public static void main(String[] args) throws MetadataException, IOException
    96     {
    97         Metadata metadata = null;
    98         try {
    99             metadata = JpegMetadataReader.readMetadata(new File(args[0]));
    100         } catch (Exception e) {
    101             e.printStackTrace(System.err);
    102             System.exit(1);
    103         }
    104 
    105         // iterate over the exif data and print to System.out
    106         Iterator directories = metadata.getDirectoryIterator();
    107         while (directories.hasNext()) {
    108             Directory directory = (Directory)directories.next();
    109             Iterator tags = directory.getTagIterator();
    110             while (tags.hasNext()) {
    111                 Tag tag = (Tag)tags.next();
    112                 try {
    113                     System.out.println("[" + directory.getName() + "] " + tag.getTagName() + " = " + tag.getDescription());
    114                 } catch (MetadataException e) {
    115                     System.err.println(e.getMessage());
    116                     System.err.println(tag.getDirectoryName() + " " + tag.getTagName() + " (error)");
    117                 }
    118             }
    119             if (directory.hasErrors()) {
    120                 Iterator errors = directory.getErrors();
    121                 while (errors.hasNext()) {
    122                     System.out.println("ERROR: " + errors.next());
    123                 }
    124             }
    125         }
    126 
    127         if (args.length>1 && args[1].trim().equals("/thumb"))
    128         {
    129             ExifDirectory directory = (ExifDirectory)metadata.getDirectory(ExifDirectory.class);
    130             if (directory.containsThumbnail())
    131             {
    132                 System.out.println("Writing thumbnail...");
    133                 directory.writeThumbnail(args[0].trim() + ".thumb.jpg");
    134             }
    135             else
    136             {
    137                 System.out.println("No thumbnail data exists in this image");
    138             }
    139         }
     119        throw new Exception("Not intended for instantiation");
    140120    }
    141121}
     122
Note: See TracChangeset for help on using the changeset viewer.