Ignore:
Timestamp:
2017-10-30T22:46:09+01:00 (6 years ago)
Author:
Don-vip
Message:

fix #15505 - update to metadata-extractor 2.10.1

File:
1 edited

Legend:

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

    r10862 r13061  
    11/*
    2  * Copyright 2002-2016 Drew Noakes
     2 * Copyright 2002-2017 Drew Noakes
    33 *
    44 *    Licensed under the Apache License, Version 2.0 (the "License");
     
    2222package com.drew.metadata.exif;
    2323
    24 import java.io.FileOutputStream;
    25 import java.io.IOException;
     24import com.drew.lang.annotations.NotNull;
     25
    2626import java.util.HashMap;
    27 
    28 import com.drew.lang.annotations.NotNull;
    29 import com.drew.lang.annotations.Nullable;
    30 import com.drew.metadata.MetadataException;
    3127
    3228/**
     
    3531 * @author Drew Noakes https://drewnoakes.com
    3632 */
     33@SuppressWarnings("WeakerAccess")
    3734public class ExifThumbnailDirectory extends ExifDirectoryBase
    3835{
     
    4643    public static final int TAG_THUMBNAIL_LENGTH = 0x0202;
    4744
     45    /**
     46     * @deprecated use {@link com.drew.metadata.exif.ExifDirectoryBase#TAG_COMPRESSION} instead.
     47     */
     48    @Deprecated
     49    public static final int TAG_THUMBNAIL_COMPRESSION = 0x0103;
     50
    4851    @NotNull
    4952    protected static final HashMap<Integer, String> _tagNameMap = new HashMap<Integer, String>();
     
    5659        _tagNameMap.put(TAG_THUMBNAIL_LENGTH, "Thumbnail Length");
    5760    }
    58 
    59     @Nullable
    60     private byte[] _thumbnailData;
    6161
    6262    public ExifThumbnailDirectory()
     
    7878        return _tagNameMap;
    7979    }
    80 
    81     public boolean hasThumbnailData()
    82     {
    83         return _thumbnailData != null;
    84     }
    85 
    86     @Nullable
    87     public byte[] getThumbnailData()
    88     {
    89         return _thumbnailData;
    90     }
    91 
    92     public void setThumbnailData(@Nullable byte[] data)
    93     {
    94         _thumbnailData = data;
    95     }
    96 
    97     public void writeThumbnail(@NotNull String filename) throws MetadataException, IOException
    98     {
    99         byte[] data = _thumbnailData;
    100 
    101         if (data == null)
    102             throw new MetadataException("No thumbnail data exists.");
    103 
    104         FileOutputStream stream = null;
    105         try {
    106             stream = new FileOutputStream(filename);
    107             stream.write(data);
    108         } finally {
    109             if (stream != null)
    110                 stream.close();
    111         }
    112     }
    113 
    114 /*
    115     // This thumbnail extraction code is not complete, and is included to assist anyone who feels like looking into
    116     // it.  Please share any progress with the original author, and hence the community.  Thanks.
    117 
    118     public Image getThumbnailImage() throws MetadataException
    119     {
    120         if (!hasThumbnailData())
    121             return null;
    122 
    123         int compression = 0;
    124         try {
    125             compression = this.getInt(ExifSubIFDDirectory.TAG_COMPRESSION);
    126         } catch (Throwable e) {
    127             this.addError("Unable to determine thumbnail type " + e.getMessage());
    128         }
    129 
    130         final byte[] thumbnailBytes = getThumbnailData();
    131 
    132         if (compression == ExifSubIFDDirectory.COMPRESSION_JPEG)
    133         {
    134             // JPEG Thumbnail
    135             // operate directly on thumbnailBytes
    136             return decodeBytesAsImage(thumbnailBytes);
    137         }
    138         else if (compression == ExifSubIFDDirectory.COMPRESSION_NONE)
    139         {
    140             // uncompressed thumbnail (raw RGB data)
    141             if (!this.containsTag(ExifSubIFDDirectory.TAG_PHOTOMETRIC_INTERPRETATION))
    142                 return null;
    143 
    144             try
    145             {
    146                 // If the image is RGB format, then convert it to a bitmap
    147                 final int photometricInterpretation = this.getInt(ExifSubIFDDirectory.TAG_PHOTOMETRIC_INTERPRETATION);
    148                 if (photometricInterpretation == ExifSubIFDDirectory.PHOTOMETRIC_INTERPRETATION_RGB)
    149                 {
    150                     // RGB
    151                     Image image = createImageFromRawRgb(thumbnailBytes);
    152                     return image;
    153                 }
    154                 else if (photometricInterpretation == ExifSubIFDDirectory.PHOTOMETRIC_INTERPRETATION_YCBCR)
    155                 {
    156                     // YCbCr
    157                     Image image = createImageFromRawYCbCr(thumbnailBytes);
    158                     return image;
    159                 }
    160                 else if (photometricInterpretation == ExifSubIFDDirectory.PHOTOMETRIC_INTERPRETATION_MONOCHROME)
    161                 {
    162                     // Monochrome
    163                     return null;
    164                 }
    165             } catch (Throwable e) {
    166                 this.addError("Unable to extract thumbnail: " + e.getMessage());
    167             }
    168         }
    169         return null;
    170     }
    171 
    172     /**
    173      * Handle the YCbCr thumbnail encoding used by Ricoh RDC4200/4300, Fuji DS-7/300 and DX-5/7/9 cameras.
    174      *
    175      * At DX-5/7/9, YCbCrSubsampling(0x0212) has values of '2,1', PlanarConfiguration(0x011c) has a value '1'. So the
    176      * data align of this image is below.
    177      *
    178      * Y(0,0),Y(1,0),Cb(0,0),Cr(0,0), Y(2,0),Y(3,0),Cb(2,0),Cr(3.0), Y(4,0),Y(5,0),Cb(4,0),Cr(4,0). . . .
    179      *
    180      * The numbers in parenthesis are pixel coordinates. DX series' YCbCrCoefficients(0x0211) has values '0.299/0.587/0.114',
    181      * ReferenceBlackWhite(0x0214) has values '0,255,128,255,128,255'. Therefore to convert from Y/Cb/Cr to RGB is;
    182      *
    183      * B(0,0)=(Cb-128)*(2-0.114*2)+Y(0,0)
    184      * R(0,0)=(Cr-128)*(2-0.299*2)+Y(0,0)
    185      * G(0,0)=(Y(0,0)-0.114*B(0,0)-0.299*R(0,0))/0.587
    186      *
    187      * Horizontal subsampling is a value '2', so you can calculate B(1,0)/R(1,0)/G(1,0) by using the Y(1,0) and Cr(0,0)/Cb(0,0).
    188      * Repeat this conversion by value of ImageWidth(0x0100) and ImageLength(0x0101).
    189      *
    190      * @param thumbnailBytes
    191      * @return
    192      * @throws com.drew.metadata.MetadataException
    193      * /
    194     private Image createImageFromRawYCbCr(byte[] thumbnailBytes) throws MetadataException
    195     {
    196         /*
    197             Y  =  0.257R + 0.504G + 0.098B + 16
    198             Cb = -0.148R - 0.291G + 0.439B + 128
    199             Cr =  0.439R - 0.368G - 0.071B + 128
    200 
    201             G = 1.164(Y-16) - 0.391(Cb-128) - 0.813(Cr-128)
    202             R = 1.164(Y-16) + 1.596(Cr-128)
    203             B = 1.164(Y-16) + 2.018(Cb-128)
    204 
    205             R, G and B range from 0 to 255.
    206             Y ranges from 16 to 235.
    207             Cb and Cr range from 16 to 240.
    208 
    209             http://www.faqs.org/faqs/graphics/colorspace-faq/
    210         * /
    211 
    212         int length = thumbnailBytes.length; // this.getInt(ExifSubIFDDirectory.TAG_STRIP_BYTE_COUNTS);
    213         final int imageWidth = this.getInt(ExifSubIFDDirectory.TAG_THUMBNAIL_IMAGE_WIDTH);
    214         final int imageHeight = this.getInt(ExifSubIFDDirectory.TAG_THUMBNAIL_IMAGE_HEIGHT);
    215 //        final int headerLength = 54;
    216 //        byte[] result = new byte[length + headerLength];
    217 //        // Add a windows BMP header described:
    218 //        // http://www.onicos.com/staff/iz/formats/bmp.html
    219 //        result[0] = 'B';
    220 //        result[1] = 'M'; // File Type identifier
    221 //        result[3] = (byte)(result.length / 256);
    222 //        result[2] = (byte)result.length;
    223 //        result[10] = (byte)headerLength;
    224 //        result[14] = 40; // MS Windows BMP header
    225 //        result[18] = (byte)imageWidth;
    226 //        result[22] = (byte)imageHeight;
    227 //        result[26] = 1;  // 1 Plane
    228 //        result[28] = 24; // Colour depth
    229 //        result[34] = (byte)length;
    230 //        result[35] = (byte)(length / 256);
    231 
    232         final BufferedImage image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
    233 
    234         // order is YCbCr and image is upside down, bitmaps are BGR
    235 ////        for (int i = headerLength, dataOffset = length; i<result.length; i += 3, dataOffset -= 3)
    236 //        {
    237 //            final int y =  thumbnailBytes[dataOffset - 2] & 0xFF;
    238 //            final int cb = thumbnailBytes[dataOffset - 1] & 0xFF;
    239 //            final int cr = thumbnailBytes[dataOffset] & 0xFF;
    240 //            if (y<16 || y>235 || cb<16 || cb>240 || cr<16 || cr>240)
    241 //                "".toString();
    242 //
    243 //            int g = (int)(1.164*(y-16) - 0.391*(cb-128) - 0.813*(cr-128));
    244 //            int r = (int)(1.164*(y-16) + 1.596*(cr-128));
    245 //            int b = (int)(1.164*(y-16) + 2.018*(cb-128));
    246 //
    247 ////            result[i] = (byte)b;
    248 ////            result[i + 1] = (byte)g;
    249 ////            result[i + 2] = (byte)r;
    250 //
    251 //            // TODO compose the image here
    252 //            image.setRGB(1, 2, 3);
    253 //        }
    254 
    255         return image;
    256     }
    257 
    258     /**
    259      * Creates a thumbnail image in (Windows) BMP format from raw RGB data.
    260      * @param thumbnailBytes
    261      * @return
    262      * @throws com.drew.metadata.MetadataException
    263      * /
    264     private Image createImageFromRawRgb(byte[] thumbnailBytes) throws MetadataException
    265     {
    266         final int length = thumbnailBytes.length; // this.getInt(ExifSubIFDDirectory.TAG_STRIP_BYTE_COUNTS);
    267         final int imageWidth = this.getInt(ExifSubIFDDirectory.TAG_THUMBNAIL_IMAGE_WIDTH);
    268         final int imageHeight = this.getInt(ExifSubIFDDirectory.TAG_THUMBNAIL_IMAGE_HEIGHT);
    269 //        final int headerLength = 54;
    270 //        final byte[] result = new byte[length + headerLength];
    271 //        // Add a windows BMP header described:
    272 //        // http://www.onicos.com/staff/iz/formats/bmp.html
    273 //        result[0] = 'B';
    274 //        result[1] = 'M'; // File Type identifier
    275 //        result[3] = (byte)(result.length / 256);
    276 //        result[2] = (byte)result.length;
    277 //        result[10] = (byte)headerLength;
    278 //        result[14] = 40; // MS Windows BMP header
    279 //        result[18] = (byte)imageWidth;
    280 //        result[22] = (byte)imageHeight;
    281 //        result[26] = 1;  // 1 Plane
    282 //        result[28] = 24; // Colour depth
    283 //        result[34] = (byte)length;
    284 //        result[35] = (byte)(length / 256);
    285 
    286         final BufferedImage image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
    287 
    288         // order is RGB and image is upside down, bitmaps are BGR
    289 //        for (int i = headerLength, dataOffset = length; i<result.length; i += 3, dataOffset -= 3)
    290 //        {
    291 //            byte b = thumbnailBytes[dataOffset - 2];
    292 //            byte g = thumbnailBytes[dataOffset - 1];
    293 //            byte r = thumbnailBytes[dataOffset];
    294 //
    295 //            // TODO compose the image here
    296 //            image.setRGB(1, 2, 3);
    297 //        }
    298 
    299         return image;
    300     }
    301 */
    30280}
Note: See TracChangeset for help on using the changeset viewer.