From bab48fbe78d6246ee97255d73bce4a9d228c8986 Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 21 May 2021 14:38:44 +0200 Subject: [PATCH 01/34] Initial work on configurable Locale, works for Longitude/Latitude and F-number. --- .../drew/imaging/jpeg/JpegMetadataReader.java | 51 +++++++++++++++---- .../jpeg/JpegSegmentMetadataReader.java | 5 +- .../drew/imaging/png/PngMetadataReader.java | 2 +- .../drew/imaging/tiff/TiffMetadataReader.java | 2 +- Source/com/drew/lang/GeoLocation.java | 15 +++++- Source/com/drew/metadata/TagDescriptor.java | 10 +++- .../drew/metadata/adobe/AdobeJpegReader.java | 3 +- .../metadata/exif/ExifDescriptorBase.java | 10 +++- Source/com/drew/metadata/exif/ExifReader.java | 15 ++++-- .../metadata/exif/ExifSubIFDDescriptor.java | 10 +++- .../metadata/exif/ExifSubIFDDirectory.java | 6 +++ .../drew/metadata/exif/ExifTiffHandler.java | 4 +- .../com/drew/metadata/exif/GpsDescriptor.java | 13 +++-- .../com/drew/metadata/exif/GpsDirectory.java | 7 ++- Source/com/drew/metadata/icc/IccReader.java | 3 +- Source/com/drew/metadata/iptc/IptcReader.java | 3 +- Source/com/drew/metadata/jfif/JfifReader.java | 3 +- Source/com/drew/metadata/jfxx/JfxxReader.java | 3 +- .../drew/metadata/jpeg/JpegCommentReader.java | 3 +- .../com/drew/metadata/jpeg/JpegDhtReader.java | 3 +- .../com/drew/metadata/jpeg/JpegDnlReader.java | 3 +- Source/com/drew/metadata/jpeg/JpegReader.java | 3 +- .../mov/atoms/canon/CanonThumbnailAtom.java | 2 +- .../drew/metadata/photoshop/DuckyReader.java | 3 +- .../metadata/photoshop/PhotoshopReader.java | 3 +- .../photoshop/PhotoshopTiffHandler.java | 2 +- .../metadata/tiff/DirectoryTiffHandler.java | 40 +++++++++++---- Source/com/drew/metadata/xmp/XmpReader.java | 5 +- .../imaging/jpeg/JpegMetadataReaderTest.java | 49 ++++++++++++++++++ .../drew/metadata/exif/ExifReaderTest.java | 4 +- .../com/drew/metadata/icc/IccReaderTest.java | 4 +- .../com/drew/metadata/xmp/XmpReaderTest.java | 2 +- 32 files changed, 231 insertions(+), 60 deletions(-) diff --git a/Source/com/drew/imaging/jpeg/JpegMetadataReader.java b/Source/com/drew/imaging/jpeg/JpegMetadataReader.java index 4d92f09a7..859236a96 100644 --- a/Source/com/drew/imaging/jpeg/JpegMetadataReader.java +++ b/Source/com/drew/imaging/jpeg/JpegMetadataReader.java @@ -45,6 +45,7 @@ import java.io.InputStream; import java.util.Arrays; import java.util.HashSet; +import java.util.Locale; import java.util.Set; /** @@ -71,45 +72,72 @@ public class JpegMetadataReader ); @NotNull - public static Metadata readMetadata(@NotNull InputStream inputStream, @Nullable Iterable readers) throws JpegProcessingException, IOException + public static Metadata readMetadata(@NotNull InputStream inputStream, @Nullable Iterable readers, @Nullable Locale locale) throws JpegProcessingException, IOException { + // TODO idea: store Locale in Metadata, since that is passed everywhere anyway? (for now: pass along as parameter) Metadata metadata = new Metadata(); - process(metadata, inputStream, readers); + process(metadata, inputStream, readers, locale); return metadata; } + @NotNull + public static Metadata readMetadata(@NotNull InputStream inputStream, @Nullable Iterable readers) throws JpegProcessingException, IOException + { + return readMetadata(inputStream, readers, null); + } + + @NotNull + public static Metadata readMetadata(@NotNull InputStream inputStream, @Nullable Locale locale) throws JpegProcessingException, IOException + { + return readMetadata(inputStream, null, locale); + } + @NotNull public static Metadata readMetadata(@NotNull InputStream inputStream) throws JpegProcessingException, IOException { - return readMetadata(inputStream, null); + return readMetadata(inputStream, null, null); } @NotNull - public static Metadata readMetadata(@NotNull File file, @Nullable Iterable readers) throws JpegProcessingException, IOException + public static Metadata readMetadata(@NotNull File file, @Nullable Iterable readers, @Nullable Locale locale) throws JpegProcessingException, IOException { InputStream inputStream = new FileInputStream(file); Metadata metadata; try { - metadata = readMetadata(inputStream, readers); + metadata = readMetadata(inputStream, readers, locale); } finally { inputStream.close(); } + // TODO pass locale? new FileSystemMetadataReader().read(file, metadata); return metadata; } + @NotNull + public static Metadata readMetadata(@NotNull File file, @Nullable Iterable readers) throws JpegProcessingException, IOException + { + return readMetadata(file, readers, null); + } + + @NotNull + public static Metadata readMetadata(@NotNull File file, @Nullable Locale locale) throws JpegProcessingException, IOException + { + return readMetadata(file, null, locale); + } + @NotNull public static Metadata readMetadata(@NotNull File file) throws JpegProcessingException, IOException { - return readMetadata(file, null); + return readMetadata(file, null, null); } public static void process(@NotNull Metadata metadata, @NotNull InputStream inputStream) throws JpegProcessingException, IOException { - process(metadata, inputStream, null); + process(metadata, inputStream, null, null); } - public static void process(@NotNull Metadata metadata, @NotNull InputStream inputStream, @Nullable Iterable readers) throws JpegProcessingException, IOException + // TODO create method with original signature for backwards compatibility + public static void process(@NotNull Metadata metadata, @NotNull InputStream inputStream, @Nullable Iterable readers, @Nullable Locale locale) throws JpegProcessingException, IOException { if (readers == null) readers = ALL_READERS; @@ -123,15 +151,16 @@ public static void process(@NotNull Metadata metadata, @NotNull InputStream inpu JpegSegmentData segmentData = JpegSegmentReader.readSegments(new StreamReader(inputStream), segmentTypes); - processJpegSegmentData(metadata, readers, segmentData); + processJpegSegmentData(metadata, readers, segmentData, locale); } - public static void processJpegSegmentData(Metadata metadata, Iterable readers, JpegSegmentData segmentData) + // TODO create method with original signature for backwards compatibility + public static void processJpegSegmentData(Metadata metadata, Iterable readers, JpegSegmentData segmentData, Locale locale) { // Pass the appropriate byte arrays to each reader. for (JpegSegmentMetadataReader reader : readers) { for (JpegSegmentType segmentType : reader.getSegmentTypes()) { - reader.readJpegSegments(segmentData.getSegments(segmentType), metadata, segmentType); + reader.readJpegSegments(segmentData.getSegments(segmentType), metadata, segmentType, locale); } } } diff --git a/Source/com/drew/imaging/jpeg/JpegSegmentMetadataReader.java b/Source/com/drew/imaging/jpeg/JpegSegmentMetadataReader.java index e1d2aef34..44d6f6762 100644 --- a/Source/com/drew/imaging/jpeg/JpegSegmentMetadataReader.java +++ b/Source/com/drew/imaging/jpeg/JpegSegmentMetadataReader.java @@ -3,6 +3,8 @@ import com.drew.lang.annotations.NotNull; import com.drew.metadata.Metadata; +import java.util.Locale; + /** * Defines an object that extracts metadata from in JPEG segments. */ @@ -21,6 +23,7 @@ public interface JpegSegmentMetadataReader * encountered in the original file. * @param metadata The {@link Metadata} object into which extracted values should be merged. * @param segmentType The {@link JpegSegmentType} being read. + * @param locale TODO document this */ - void readJpegSegments(@NotNull final Iterable segments, @NotNull final Metadata metadata, @NotNull final JpegSegmentType segmentType); + void readJpegSegments(@NotNull final Iterable segments, @NotNull final Metadata metadata, @NotNull final JpegSegmentType segmentType, Locale locale); } diff --git a/Source/com/drew/imaging/png/PngMetadataReader.java b/Source/com/drew/imaging/png/PngMetadataReader.java index cb1c50dfa..261b30e55 100644 --- a/Source/com/drew/imaging/png/PngMetadataReader.java +++ b/Source/com/drew/imaging/png/PngMetadataReader.java @@ -329,7 +329,7 @@ private static void processChunk(@NotNull Metadata metadata, @NotNull PngChunk c metadata.addDirectory(directory); } else if (chunkType.equals(PngChunkType.eXIf)) { try { - ExifTiffHandler handler = new ExifTiffHandler(metadata, null); + ExifTiffHandler handler = new ExifTiffHandler(metadata, null, null); new TiffReader().processTiff(new ByteArrayReader(bytes), handler, 0); } catch (TiffProcessingException ex) { PngDirectory directory = new PngDirectory(PngChunkType.eXIf); diff --git a/Source/com/drew/imaging/tiff/TiffMetadataReader.java b/Source/com/drew/imaging/tiff/TiffMetadataReader.java index 7137a0384..491622d13 100644 --- a/Source/com/drew/imaging/tiff/TiffMetadataReader.java +++ b/Source/com/drew/imaging/tiff/TiffMetadataReader.java @@ -67,7 +67,7 @@ public static Metadata readMetadata(@NotNull InputStream inputStream) throws IOE public static Metadata readMetadata(@NotNull RandomAccessReader reader) throws IOException, TiffProcessingException { Metadata metadata = new Metadata(); - ExifTiffHandler handler = new ExifTiffHandler(metadata, null); + ExifTiffHandler handler = new ExifTiffHandler(metadata, null, null); new TiffReader().processTiff(reader, handler, 0); return metadata; } diff --git a/Source/com/drew/lang/GeoLocation.java b/Source/com/drew/lang/GeoLocation.java index b4a1abff1..60d6cead5 100644 --- a/Source/com/drew/lang/GeoLocation.java +++ b/Source/com/drew/lang/GeoLocation.java @@ -25,6 +25,8 @@ import com.drew.lang.annotations.Nullable; import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.Locale; /** * Represents a latitude and longitude pair, giving a position on earth in spherical coordinates. @@ -74,15 +76,23 @@ public boolean isZero() return _latitude == 0 && _longitude == 0; } + // TODO document this + @NotNull + public static String decimalToDegreesMinutesSecondsString(double decimal) + { + return decimalToDegreesMinutesSecondsString(decimal, null); + } + /** * Converts a decimal degree angle into its corresponding DMS (degrees-minutes-seconds) representation as a string, * of format: {@code -1° 23' 4.56"} */ @NotNull - public static String decimalToDegreesMinutesSecondsString(double decimal) + public static String decimalToDegreesMinutesSecondsString(double decimal, Locale locale) { double[] dms = decimalToDegreesMinutesSeconds(decimal); - DecimalFormat format = new DecimalFormat("0.##"); + DecimalFormatSymbols symbols = locale == null ? DecimalFormatSymbols.getInstance() : DecimalFormatSymbols.getInstance(locale); + DecimalFormat format = new DecimalFormat("0.##", symbols); return String.format("%s\u00B0 %s' %s\"", format.format(dms[0]), format.format(dms[1]), format.format(dms[2])); } @@ -158,6 +168,7 @@ public String toString() @NotNull public String toDMSString() { + // TODO add a Locale version of this method? return decimalToDegreesMinutesSecondsString(_latitude) + ", " + decimalToDegreesMinutesSecondsString(_longitude); } } diff --git a/Source/com/drew/metadata/TagDescriptor.java b/Source/com/drew/metadata/TagDescriptor.java index a3fa1cd2f..4e16817eb 100644 --- a/Source/com/drew/metadata/TagDescriptor.java +++ b/Source/com/drew/metadata/TagDescriptor.java @@ -30,6 +30,7 @@ import java.math.RoundingMode; import java.nio.charset.Charset; import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; @@ -303,7 +304,14 @@ protected String getRationalOrDoubleString(int tagType) @Nullable protected static String getFStopDescription(double fStop) { - DecimalFormat format = new DecimalFormat("0.0"); + return getFStopDescription(fStop, null); + } + + @Nullable + protected static String getFStopDescription(double fStop, Locale locale) + { + DecimalFormatSymbols symbols = locale == null ? DecimalFormatSymbols.getInstance() : DecimalFormatSymbols.getInstance(locale); + DecimalFormat format = new DecimalFormat("0.0", symbols); format.setRoundingMode(RoundingMode.HALF_UP); return "f/" + format.format(fStop); } diff --git a/Source/com/drew/metadata/adobe/AdobeJpegReader.java b/Source/com/drew/metadata/adobe/AdobeJpegReader.java index 78ca68280..7e58ef678 100644 --- a/Source/com/drew/metadata/adobe/AdobeJpegReader.java +++ b/Source/com/drew/metadata/adobe/AdobeJpegReader.java @@ -31,6 +31,7 @@ import java.io.IOException; import java.util.Collections; +import java.util.Locale; /** * Decodes Adobe formatted data stored in JPEG files, normally in the APPE (App14) segment. @@ -49,7 +50,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APPE); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, Locale locale) { for (byte[] bytes : segments) { if (bytes.length == 12 && PREAMBLE.equalsIgnoreCase(new String(bytes, 0, PREAMBLE.length()))) diff --git a/Source/com/drew/metadata/exif/ExifDescriptorBase.java b/Source/com/drew/metadata/exif/ExifDescriptorBase.java index 2c3a2fc71..e57dd43fe 100644 --- a/Source/com/drew/metadata/exif/ExifDescriptorBase.java +++ b/Source/com/drew/metadata/exif/ExifDescriptorBase.java @@ -32,6 +32,7 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; import java.text.DecimalFormat; +import java.util.Locale; import static com.drew.metadata.exif.ExifDirectoryBase.*; @@ -48,6 +49,7 @@ public abstract class ExifDescriptorBase extends TagDescrip * where decimal notation is elegant (such as 1/2 -> 0.5, but not 1/3). */ private final boolean _allowDecimalRepresentationOfRationals = true; + private Locale _locale; // Note for the potential addition of brightness presentation in eV: // Brightness of taken subject. To calculate Exposure(Ev) from BrightnessValue(Bv), @@ -60,6 +62,12 @@ public ExifDescriptorBase(@NotNull T directory) super(directory); } + public ExifDescriptorBase(@NotNull T directory, @Nullable Locale locale) + { + super(directory); + _locale = locale; + } + @Nullable @Override public String getDescription(int tagType) @@ -610,7 +618,7 @@ public String getFNumberDescription() Rational value = _directory.getRational(TAG_FNUMBER); if (value == null) return null; - return getFStopDescription(value.doubleValue()); + return getFStopDescription(value.doubleValue(), _locale); } @Nullable diff --git a/Source/com/drew/metadata/exif/ExifReader.java b/Source/com/drew/metadata/exif/ExifReader.java index ff2e9a954..7c6c97cfc 100644 --- a/Source/com/drew/metadata/exif/ExifReader.java +++ b/Source/com/drew/metadata/exif/ExifReader.java @@ -33,6 +33,7 @@ import java.io.IOException; import java.util.Collections; +import java.util.Locale; /** * Decodes Exif binary data, populating a {@link Metadata} object with tag values in {@link ExifSubIFDDirectory}, @@ -53,14 +54,14 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APP1); } - public void readJpegSegments(@NotNull final Iterable segments, @NotNull final Metadata metadata, @NotNull final JpegSegmentType segmentType) + public void readJpegSegments(@NotNull final Iterable segments, @NotNull final Metadata metadata, @NotNull final JpegSegmentType segmentType, @Nullable Locale locale) { assert(segmentType == JpegSegmentType.APP1); for (byte[] segmentBytes : segments) { // Segment must have the expected preamble if (startsWithJpegExifPreamble(segmentBytes)) { - extract(new ByteArrayReader(segmentBytes), metadata, JPEG_SEGMENT_PREAMBLE.length()); + extract(new ByteArrayReader(segmentBytes), metadata, JPEG_SEGMENT_PREAMBLE.length(), null, locale); } } } @@ -84,10 +85,16 @@ public void extract(@NotNull final RandomAccessReader reader, @NotNull final Met extract(reader, metadata, readerOffset, null); } - /** Reads TIFF formatted Exif data at a specified offset within a {@link RandomAccessReader}. */ + /** Reads TIFF formatted Exif data a specified offset within a {@link RandomAccessReader}. */ public void extract(@NotNull final RandomAccessReader reader, @NotNull final Metadata metadata, int readerOffset, @Nullable Directory parentDirectory) { - ExifTiffHandler exifTiffHandler = new ExifTiffHandler(metadata, parentDirectory); + extract(reader, metadata, readerOffset, parentDirectory, null); + } + + /** Reads TIFF formatted Exif data at a specified offset within a {@link RandomAccessReader}. */ + public void extract(@NotNull final RandomAccessReader reader, @NotNull final Metadata metadata, int readerOffset, @Nullable Directory parentDirectory, @Nullable Locale locale) + { + ExifTiffHandler exifTiffHandler = new ExifTiffHandler(metadata, parentDirectory, locale); try { // Read the TIFF-formatted Exif data diff --git a/Source/com/drew/metadata/exif/ExifSubIFDDescriptor.java b/Source/com/drew/metadata/exif/ExifSubIFDDescriptor.java index 6943a9a29..e25f92bae 100644 --- a/Source/com/drew/metadata/exif/ExifSubIFDDescriptor.java +++ b/Source/com/drew/metadata/exif/ExifSubIFDDescriptor.java @@ -21,6 +21,9 @@ package com.drew.metadata.exif; import com.drew.lang.annotations.NotNull; +import com.drew.lang.annotations.Nullable; + +import java.util.Locale; /** * Provides human-readable string representations of tag values stored in a {@link ExifSubIFDDirectory}. @@ -32,6 +35,11 @@ public class ExifSubIFDDescriptor extends ExifDescriptorBase _tagNameMap = new HashMap(); diff --git a/Source/com/drew/metadata/exif/ExifTiffHandler.java b/Source/com/drew/metadata/exif/ExifTiffHandler.java index a7e793aa5..7ebe2dfe2 100644 --- a/Source/com/drew/metadata/exif/ExifTiffHandler.java +++ b/Source/com/drew/metadata/exif/ExifTiffHandler.java @@ -59,9 +59,9 @@ */ public class ExifTiffHandler extends DirectoryTiffHandler { - public ExifTiffHandler(@NotNull Metadata metadata, @Nullable Directory parentDirectory) + public ExifTiffHandler(@NotNull Metadata metadata, @Nullable Directory parentDirectory, @Nullable Locale locale) { - super(metadata, parentDirectory); + super(metadata, parentDirectory, locale); } public void setTiffMarker(int marker) throws TiffProcessingException diff --git a/Source/com/drew/metadata/exif/GpsDescriptor.java b/Source/com/drew/metadata/exif/GpsDescriptor.java index 72062b206..ad3269b92 100644 --- a/Source/com/drew/metadata/exif/GpsDescriptor.java +++ b/Source/com/drew/metadata/exif/GpsDescriptor.java @@ -27,6 +27,7 @@ import com.drew.metadata.TagDescriptor; import java.text.DecimalFormat; +import java.util.Locale; import static com.drew.metadata.exif.GpsDirectory.*; @@ -38,9 +39,13 @@ @SuppressWarnings("WeakerAccess") public class GpsDescriptor extends TagDescriptor { - public GpsDescriptor(@NotNull GpsDirectory directory) + private Locale _locale; + + public GpsDescriptor(@NotNull GpsDirectory directory, @Nullable Locale locale) { super(directory); + // TODO add locale to TagDescriptor superclass? + _locale = locale; } @Override @@ -111,14 +116,14 @@ private String getGpsVersionIdDescription() public String getGpsLatitudeDescription() { GeoLocation location = _directory.getGeoLocation(); - return location == null ? null : GeoLocation.decimalToDegreesMinutesSecondsString(location.getLatitude()); + return location == null ? null : GeoLocation.decimalToDegreesMinutesSecondsString(location.getLatitude(), _locale); } @Nullable public String getGpsLongitudeDescription() { GeoLocation location = _directory.getGeoLocation(); - return location == null ? null : GeoLocation.decimalToDegreesMinutesSecondsString(location.getLongitude()); + return location == null ? null : GeoLocation.decimalToDegreesMinutesSecondsString(location.getLongitude(), _locale); } @Nullable @@ -159,7 +164,7 @@ private String getGeoLocationDimension(int tagValue, int tagRef, String positive Double dec = GeoLocation.degreesMinutesSecondsToDecimal( values[0], values[1], values[2], ref.equalsIgnoreCase(positiveRef)); - return dec == null ? null : GeoLocation.decimalToDegreesMinutesSecondsString(dec); + return dec == null ? null : GeoLocation.decimalToDegreesMinutesSecondsString(dec, _locale); } @Nullable diff --git a/Source/com/drew/metadata/exif/GpsDirectory.java b/Source/com/drew/metadata/exif/GpsDirectory.java index d89f1d7b4..797d56c5e 100644 --- a/Source/com/drew/metadata/exif/GpsDirectory.java +++ b/Source/com/drew/metadata/exif/GpsDirectory.java @@ -146,9 +146,14 @@ public class GpsDirectory extends ExifDirectoryBase _tagNameMap.put(TAG_H_POSITIONING_ERROR, "GPS H Positioning Error"); } + // TODO remove this constructor? public GpsDirectory() { - this.setDescriptor(new GpsDescriptor(this)); + this(null); + } + + public GpsDirectory(@Nullable Locale locale) { + this.setDescriptor(new GpsDescriptor(this, locale)); } @Override diff --git a/Source/com/drew/metadata/icc/IccReader.java b/Source/com/drew/metadata/icc/IccReader.java index 46b59bf10..d3223d767 100644 --- a/Source/com/drew/metadata/icc/IccReader.java +++ b/Source/com/drew/metadata/icc/IccReader.java @@ -33,6 +33,7 @@ import java.io.IOException; import java.util.Collections; +import java.util.Locale; /** * Reads an ICC profile. @@ -57,7 +58,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APP2); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, Locale locale) { final int preambleLength = JPEG_SEGMENT_PREAMBLE.length(); diff --git a/Source/com/drew/metadata/iptc/IptcReader.java b/Source/com/drew/metadata/iptc/IptcReader.java index c1956c4fb..74ca9d9b3 100644 --- a/Source/com/drew/metadata/iptc/IptcReader.java +++ b/Source/com/drew/metadata/iptc/IptcReader.java @@ -33,6 +33,7 @@ import java.io.IOException; import java.nio.charset.Charset; import java.util.Collections; +import java.util.Locale; /** * Decodes IPTC binary data, populating a {@link Metadata} object with tag values in an {@link IptcDirectory}. @@ -65,7 +66,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APPD); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, Locale locale) { for (byte[] segmentBytes : segments) { // Ensure data starts with the IPTC marker byte diff --git a/Source/com/drew/metadata/jfif/JfifReader.java b/Source/com/drew/metadata/jfif/JfifReader.java index 5923ee20b..844e358d9 100644 --- a/Source/com/drew/metadata/jfif/JfifReader.java +++ b/Source/com/drew/metadata/jfif/JfifReader.java @@ -30,6 +30,7 @@ import java.io.IOException; import java.util.Collections; +import java.util.Locale; /** * Reader for JFIF data, found in the APP0 JPEG segment. @@ -51,7 +52,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APP0); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, Locale locale) { for (byte[] segmentBytes : segments) { // Skip segments not starting with the required header diff --git a/Source/com/drew/metadata/jfxx/JfxxReader.java b/Source/com/drew/metadata/jfxx/JfxxReader.java index 63fbb9ab7..f0e8ff121 100644 --- a/Source/com/drew/metadata/jfxx/JfxxReader.java +++ b/Source/com/drew/metadata/jfxx/JfxxReader.java @@ -30,6 +30,7 @@ import java.io.IOException; import java.util.Collections; +import java.util.Locale; /** * Reader for JFXX (JFIF extensions) data, found in the APP0 JPEG segment. @@ -51,7 +52,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APP0); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, Locale locale) { for (byte[] segmentBytes : segments) { // Skip segments not starting with the required header diff --git a/Source/com/drew/metadata/jpeg/JpegCommentReader.java b/Source/com/drew/metadata/jpeg/JpegCommentReader.java index f50bbf742..b4eda4880 100644 --- a/Source/com/drew/metadata/jpeg/JpegCommentReader.java +++ b/Source/com/drew/metadata/jpeg/JpegCommentReader.java @@ -27,6 +27,7 @@ import com.drew.metadata.StringValue; import java.util.Collections; +import java.util.Locale; /** * Decodes the comment stored within JPEG files, populating a {@link Metadata} object with tag values in a @@ -42,7 +43,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.COM); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, Locale locale) { for (byte[] segmentBytes : segments) { JpegCommentDirectory directory = new JpegCommentDirectory(); diff --git a/Source/com/drew/metadata/jpeg/JpegDhtReader.java b/Source/com/drew/metadata/jpeg/JpegDhtReader.java index cba2dda87..7844cacfa 100644 --- a/Source/com/drew/metadata/jpeg/JpegDhtReader.java +++ b/Source/com/drew/metadata/jpeg/JpegDhtReader.java @@ -30,6 +30,7 @@ import com.drew.metadata.jpeg.HuffmanTablesDirectory.HuffmanTable.HuffmanTableClass; import java.io.IOException; import java.util.Collections; +import java.util.Locale; /** * Reader for JPEG Huffman tables, found in the DHT JPEG segment. @@ -44,7 +45,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.DHT); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, Locale locale) { for (byte[] segmentBytes : segments) { extract(new SequentialByteArrayReader(segmentBytes), metadata); diff --git a/Source/com/drew/metadata/jpeg/JpegDnlReader.java b/Source/com/drew/metadata/jpeg/JpegDnlReader.java index 784a2ef16..bebbca448 100644 --- a/Source/com/drew/metadata/jpeg/JpegDnlReader.java +++ b/Source/com/drew/metadata/jpeg/JpegDnlReader.java @@ -30,6 +30,7 @@ import java.io.IOException; import java.util.Collections; +import java.util.Locale; /** * Decodes JPEG DNL data, adjusting the image height with information missing from the JPEG SOFx segment. @@ -44,7 +45,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.DNL); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, Locale locale) { for (byte[] segmentBytes : segments) { extract(segmentBytes, metadata, segmentType); diff --git a/Source/com/drew/metadata/jpeg/JpegReader.java b/Source/com/drew/metadata/jpeg/JpegReader.java index 077ee21aa..b8e3bede1 100644 --- a/Source/com/drew/metadata/jpeg/JpegReader.java +++ b/Source/com/drew/metadata/jpeg/JpegReader.java @@ -29,6 +29,7 @@ import java.io.IOException; import java.util.Arrays; +import java.util.Locale; /** * Decodes JPEG SOFn data, populating a {@link Metadata} object with tag values in a {@link JpegDirectory}. @@ -62,7 +63,7 @@ public Iterable getSegmentTypes() ); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, Locale locale) { for (byte[] segmentBytes : segments) { extract(segmentBytes, metadata, segmentType); diff --git a/Source/com/drew/metadata/mov/atoms/canon/CanonThumbnailAtom.java b/Source/com/drew/metadata/mov/atoms/canon/CanonThumbnailAtom.java index c5a5d86c1..44f868599 100644 --- a/Source/com/drew/metadata/mov/atoms/canon/CanonThumbnailAtom.java +++ b/Source/com/drew/metadata/mov/atoms/canon/CanonThumbnailAtom.java @@ -59,7 +59,7 @@ private void readCNDA(SequentialReader reader) throws IOException // TODO should we keep all extracted metadata here? Metadata metadata = new Metadata(); for (JpegSegmentType segmentType : exifReader.getSegmentTypes()) { - exifReader.readJpegSegments(segmentData.getSegments(segmentType), metadata, segmentType); + exifReader.readJpegSegments(segmentData.getSegments(segmentType), metadata, segmentType, null); } Directory directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class); diff --git a/Source/com/drew/metadata/photoshop/DuckyReader.java b/Source/com/drew/metadata/photoshop/DuckyReader.java index b8e90fad9..f938b2699 100644 --- a/Source/com/drew/metadata/photoshop/DuckyReader.java +++ b/Source/com/drew/metadata/photoshop/DuckyReader.java @@ -30,6 +30,7 @@ import java.io.IOException; import java.util.Collections; +import java.util.Locale; /** * Reads Photoshop "ducky" segments, created during Save-for-Web. @@ -48,7 +49,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APPC); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, Locale locale) { final int preambleLength = JPEG_SEGMENT_PREAMBLE.length(); diff --git a/Source/com/drew/metadata/photoshop/PhotoshopReader.java b/Source/com/drew/metadata/photoshop/PhotoshopReader.java index 90ef156f7..9a74c9634 100644 --- a/Source/com/drew/metadata/photoshop/PhotoshopReader.java +++ b/Source/com/drew/metadata/photoshop/PhotoshopReader.java @@ -37,6 +37,7 @@ import java.util.Arrays; import java.util.Collections; +import java.util.Locale; /** * Reads metadata created by Photoshop and stored in the APPD segment of JPEG files. @@ -58,7 +59,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APPD); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, Locale locale) { final int preambleLength = JPEG_SEGMENT_PREAMBLE.length(); diff --git a/Source/com/drew/metadata/photoshop/PhotoshopTiffHandler.java b/Source/com/drew/metadata/photoshop/PhotoshopTiffHandler.java index b5de35ea8..a0d51a89a 100644 --- a/Source/com/drew/metadata/photoshop/PhotoshopTiffHandler.java +++ b/Source/com/drew/metadata/photoshop/PhotoshopTiffHandler.java @@ -33,7 +33,7 @@ public class PhotoshopTiffHandler extends ExifTiffHandler public PhotoshopTiffHandler(Metadata metadata, Directory parentDirectory) { - super(metadata, parentDirectory); + super(metadata, parentDirectory, null); } public boolean customProcessTag(final int tagOffset, diff --git a/Source/com/drew/metadata/tiff/DirectoryTiffHandler.java b/Source/com/drew/metadata/tiff/DirectoryTiffHandler.java index a327bd808..69acac254 100644 --- a/Source/com/drew/metadata/tiff/DirectoryTiffHandler.java +++ b/Source/com/drew/metadata/tiff/DirectoryTiffHandler.java @@ -29,6 +29,9 @@ import com.drew.metadata.Metadata; import com.drew.metadata.StringValue; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.Locale; import java.util.Stack; /** @@ -43,11 +46,13 @@ public abstract class DirectoryTiffHandler implements TiffHandler @Nullable private Directory _rootParentDirectory; @Nullable protected Directory _currentDirectory; protected final Metadata _metadata; + @Nullable private Locale _locale; - protected DirectoryTiffHandler(Metadata metadata, @Nullable Directory parentDirectory) + protected DirectoryTiffHandler(Metadata metadata, @Nullable Directory parentDirectory, @Nullable Locale locale) { _metadata = metadata; _rootParentDirectory = parentDirectory; + _locale = locale; } public void endingIFD() @@ -57,15 +62,7 @@ public void endingIFD() protected void pushDirectory(@NotNull Class directoryClass) { - Directory newDirectory; - - try { - newDirectory = directoryClass.newInstance(); - } catch (InstantiationException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } + Directory newDirectory = getDirectoryInstance(directoryClass); // If this is the first directory, don't add to the stack if (_currentDirectory == null) { @@ -85,6 +82,29 @@ protected void pushDirectory(@NotNull Class directoryClass) _metadata.addDirectory(_currentDirectory); } + private Directory getDirectoryInstance(Class directoryClass) { + Constructor[] constructors = directoryClass.getConstructors(); + + try { + // pass locale to directory, if it has a constructor that can receive it + // TODO improve? + for (Constructor constructor : constructors) { + Class[] parameterTypes = constructor.getParameterTypes(); + if (parameterTypes.length == 1 && parameterTypes[0] == Locale.class) { + return (Directory) constructor.newInstance(_locale); + } + } + + return directoryClass.newInstance(); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + } + public void warn(@NotNull String message) { getCurrentOrErrorDirectory().addError(message); diff --git a/Source/com/drew/metadata/xmp/XmpReader.java b/Source/com/drew/metadata/xmp/XmpReader.java index 0935ee6ce..56be5eb18 100644 --- a/Source/com/drew/metadata/xmp/XmpReader.java +++ b/Source/com/drew/metadata/xmp/XmpReader.java @@ -40,6 +40,7 @@ import java.io.IOException; import java.util.Collection; import java.util.Collections; +import java.util.Locale; /** * Extracts XMP data from JPEG APP1 segments. @@ -85,12 +86,12 @@ public Iterable getSegmentTypes() /** * Version specifically for dealing with XMP found in JPEG segments. This form of XMP has a peculiar preamble, which * must be removed before parsing the XML. - * * @param segments The byte array from which the metadata should be extracted. * @param metadata The {@link Metadata} object into which extracted values should be merged. * @param segmentType The {@link JpegSegmentType} being read. + * @param locale */ - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, Locale locale) { final int preambleLength = XMP_JPEG_PREAMBLE.length(); final int extensionPreambleLength = XMP_EXTENSION_JPEG_PREAMBLE.length(); diff --git a/Tests/com/drew/imaging/jpeg/JpegMetadataReaderTest.java b/Tests/com/drew/imaging/jpeg/JpegMetadataReaderTest.java index 3327783d9..a63ac9723 100644 --- a/Tests/com/drew/imaging/jpeg/JpegMetadataReaderTest.java +++ b/Tests/com/drew/imaging/jpeg/JpegMetadataReaderTest.java @@ -22,7 +22,9 @@ import com.drew.metadata.Directory; import com.drew.metadata.Metadata; +import com.drew.metadata.exif.ExifDirectoryBase; import com.drew.metadata.exif.ExifSubIFDDirectory; +import com.drew.metadata.exif.GpsDirectory; import com.drew.metadata.jpeg.HuffmanTablesDirectory; import com.drew.metadata.jpeg.HuffmanTablesDirectory.HuffmanTable; import com.drew.metadata.xmp.XmpDirectory; @@ -30,6 +32,7 @@ import java.io.File; import java.io.FileInputStream; +import java.util.Locale; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -94,4 +97,50 @@ private void validate(Metadata metadata) assertNotNull(directory); assertTrue(((HuffmanTablesDirectory) directory).isOptimized()); } + + @Test + public void testConfigurableLocaleEnglish() throws Exception { + Locale defaultLocale = Locale.getDefault(); + try { + // set default Locale to Dutch, configure English -> expect period + Locale.setDefault(new Locale("nl")); + Locale configuredLocale = Locale.ENGLISH; + Metadata metadata = JpegMetadataReader.readMetadata(new File("Tests/Data/withIptcExifGps.jpg"), configuredLocale); + + Directory gps = metadata.getFirstDirectoryOfType(GpsDirectory.class); + assertEquals("54° 59' 22.8\"", gps.getDescription(GpsDirectory.TAG_LATITUDE)); + assertEquals("-1° 54' 51\"", gps.getDescription(GpsDirectory.TAG_LONGITUDE)); + + Directory subIFD = metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class); + assertEquals("f/0.6", subIFD.getDescription(ExifDirectoryBase.TAG_FNUMBER)); + + } + finally { + // reset default locale + Locale.setDefault(defaultLocale); + } + } + + @Test + public void testConfigurableLocaleDutch() throws Exception { + Locale defaultLocale = Locale.getDefault(); + try { + // set default Locale to Dutch, configure English -> expect comma + Locale.setDefault(Locale.ENGLISH); + Locale configuredLocale = new Locale("nl"); + Metadata metadata = JpegMetadataReader.readMetadata(new File("Tests/Data/withIptcExifGps.jpg"), configuredLocale); + + Directory gps = metadata.getFirstDirectoryOfType(GpsDirectory.class); + assertEquals("54° 59' 22,8\"", gps.getDescription(GpsDirectory.TAG_LATITUDE)); + assertEquals("-1° 54' 51\"", gps.getDescription(GpsDirectory.TAG_LONGITUDE)); + + Directory subIFD = metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class); + assertEquals("f/0,6", subIFD.getDescription(ExifDirectoryBase.TAG_FNUMBER)); + + } + finally { + // reset default locale + Locale.setDefault(defaultLocale); + } + } } diff --git a/Tests/com/drew/metadata/exif/ExifReaderTest.java b/Tests/com/drew/metadata/exif/ExifReaderTest.java index 3cd95547b..f71d3874a 100644 --- a/Tests/com/drew/metadata/exif/ExifReaderTest.java +++ b/Tests/com/drew/metadata/exif/ExifReaderTest.java @@ -63,7 +63,7 @@ public static T processBytes(@NotNull String filePath, @No public void testExtractWithNullDataThrows() throws Exception { try{ - new ExifReader().readJpegSegments(null, new Metadata(), JpegSegmentType.APP1); + new ExifReader().readJpegSegments(null, new Metadata(), JpegSegmentType.APP1, null); fail("Exception expected"); } catch (NullPointerException npe) { // passed @@ -89,7 +89,7 @@ public void testReadJpegSegmentWithNoExifData() throws Exception Metadata metadata = new Metadata(); ArrayList segments = new ArrayList(); segments.add(badExifData); - new ExifReader().readJpegSegments(segments, metadata, JpegSegmentType.APP1); + new ExifReader().readJpegSegments(segments, metadata, JpegSegmentType.APP1, null); assertEquals(0, metadata.getDirectoryCount()); assertFalse(metadata.hasErrors()); } diff --git a/Tests/com/drew/metadata/icc/IccReaderTest.java b/Tests/com/drew/metadata/icc/IccReaderTest.java index 6ed5e5678..f46372935 100644 --- a/Tests/com/drew/metadata/icc/IccReaderTest.java +++ b/Tests/com/drew/metadata/icc/IccReaderTest.java @@ -62,7 +62,7 @@ public void testReadJpegSegments_InvalidData() throws Exception byte[] app2Bytes = FileUtil.readBytes("Tests/Data/iccDataInvalid1.jpg.app2"); Metadata metadata = new Metadata(); - new IccReader().readJpegSegments(Arrays.asList(app2Bytes), metadata, JpegSegmentType.APP2); + new IccReader().readJpegSegments(Arrays.asList(app2Bytes), metadata, JpegSegmentType.APP2, null); IccDirectory directory = metadata.getFirstDirectoryOfType(IccDirectory.class); @@ -76,7 +76,7 @@ public void testExtract_ProfileDateTime() throws Exception byte[] app2Bytes = FileUtil.readBytes("Tests/Data/withExifAndIptc.jpg.app2"); Metadata metadata = new Metadata(); - new IccReader().readJpegSegments(Arrays.asList(app2Bytes), metadata, JpegSegmentType.APP2); + new IccReader().readJpegSegments(Arrays.asList(app2Bytes), metadata, JpegSegmentType.APP2, null); IccDirectory directory = metadata.getFirstDirectoryOfType(IccDirectory.class); diff --git a/Tests/com/drew/metadata/xmp/XmpReaderTest.java b/Tests/com/drew/metadata/xmp/XmpReaderTest.java index e5c81b5bc..0facde6a2 100644 --- a/Tests/com/drew/metadata/xmp/XmpReaderTest.java +++ b/Tests/com/drew/metadata/xmp/XmpReaderTest.java @@ -43,7 +43,7 @@ public void setUp() throws Exception Metadata metadata = new Metadata(); List jpegSegments = new ArrayList(); jpegSegments.add(FileUtil.readBytes("Tests/Data/withXmpAndIptc.jpg.app1.1")); - new XmpReader().readJpegSegments(jpegSegments, metadata, JpegSegmentType.APP1); + new XmpReader().readJpegSegments(jpegSegments, metadata, JpegSegmentType.APP1, null); Collection xmpDirectories = metadata.getDirectoriesOfType(XmpDirectory.class); From ed768a5e1bde5c67288234c2fe1df75dedbf36ca Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 21 May 2021 14:41:12 +0200 Subject: [PATCH 02/34] Restore Javadoc. --- Source/com/drew/metadata/exif/ExifReader.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/com/drew/metadata/exif/ExifReader.java b/Source/com/drew/metadata/exif/ExifReader.java index 7c6c97cfc..1638fcfa4 100644 --- a/Source/com/drew/metadata/exif/ExifReader.java +++ b/Source/com/drew/metadata/exif/ExifReader.java @@ -79,13 +79,13 @@ public void extract(@NotNull final RandomAccessReader reader, @NotNull final Met extract(reader, metadata, 0); } - /** Reads TIFF formatted Exif data a specified offset within a {@link RandomAccessReader}. */ + /** Reads TIFF formatted Exif data at a specified offset within a {@link RandomAccessReader}. */ public void extract(@NotNull final RandomAccessReader reader, @NotNull final Metadata metadata, int readerOffset) { extract(reader, metadata, readerOffset, null); } - /** Reads TIFF formatted Exif data a specified offset within a {@link RandomAccessReader}. */ + /** Reads TIFF formatted Exif data at a specified offset within a {@link RandomAccessReader}. */ public void extract(@NotNull final RandomAccessReader reader, @NotNull final Metadata metadata, int readerOffset, @Nullable Directory parentDirectory) { extract(reader, metadata, readerOffset, parentDirectory, null); From c594940e90334cc7484d3807a573fa34ca271c1a Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 21 May 2021 14:43:58 +0200 Subject: [PATCH 03/34] Fix missing import. --- Source/com/drew/metadata/exif/ExifTiffHandler.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/com/drew/metadata/exif/ExifTiffHandler.java b/Source/com/drew/metadata/exif/ExifTiffHandler.java index 7ebe2dfe2..cd1433e7c 100644 --- a/Source/com/drew/metadata/exif/ExifTiffHandler.java +++ b/Source/com/drew/metadata/exif/ExifTiffHandler.java @@ -24,6 +24,7 @@ import java.io.IOException; import java.util.Arrays; import java.util.HashMap; +import java.util.Locale; import java.util.Map; import java.util.Set; From e93e7df2353debc1806888755281414d6abcef52 Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 21 May 2021 14:47:12 +0200 Subject: [PATCH 04/34] Add Nullable annotation to new Locale parameter. --- Source/com/drew/metadata/adobe/AdobeJpegReader.java | 3 ++- Source/com/drew/metadata/icc/IccReader.java | 2 +- Source/com/drew/metadata/iptc/IptcReader.java | 2 +- Source/com/drew/metadata/jfif/JfifReader.java | 3 ++- Source/com/drew/metadata/jfxx/JfxxReader.java | 3 ++- Source/com/drew/metadata/jpeg/JpegCommentReader.java | 3 ++- Source/com/drew/metadata/jpeg/JpegDhtReader.java | 3 ++- Source/com/drew/metadata/jpeg/JpegDnlReader.java | 3 ++- Source/com/drew/metadata/jpeg/JpegReader.java | 3 ++- Source/com/drew/metadata/photoshop/DuckyReader.java | 3 ++- Source/com/drew/metadata/photoshop/PhotoshopReader.java | 2 +- Source/com/drew/metadata/xmp/XmpReader.java | 2 +- 12 files changed, 20 insertions(+), 12 deletions(-) diff --git a/Source/com/drew/metadata/adobe/AdobeJpegReader.java b/Source/com/drew/metadata/adobe/AdobeJpegReader.java index 7e58ef678..8cdf18713 100644 --- a/Source/com/drew/metadata/adobe/AdobeJpegReader.java +++ b/Source/com/drew/metadata/adobe/AdobeJpegReader.java @@ -26,6 +26,7 @@ import com.drew.lang.SequentialByteArrayReader; import com.drew.lang.SequentialReader; import com.drew.lang.annotations.NotNull; +import com.drew.lang.annotations.Nullable; import com.drew.metadata.Directory; import com.drew.metadata.Metadata; @@ -50,7 +51,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APPE); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, Locale locale) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable Locale locale) { for (byte[] bytes : segments) { if (bytes.length == 12 && PREAMBLE.equalsIgnoreCase(new String(bytes, 0, PREAMBLE.length()))) diff --git a/Source/com/drew/metadata/icc/IccReader.java b/Source/com/drew/metadata/icc/IccReader.java index d3223d767..50481c000 100644 --- a/Source/com/drew/metadata/icc/IccReader.java +++ b/Source/com/drew/metadata/icc/IccReader.java @@ -58,7 +58,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APP2); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, Locale locale) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable Locale locale) { final int preambleLength = JPEG_SEGMENT_PREAMBLE.length(); diff --git a/Source/com/drew/metadata/iptc/IptcReader.java b/Source/com/drew/metadata/iptc/IptcReader.java index 74ca9d9b3..7f05336cc 100644 --- a/Source/com/drew/metadata/iptc/IptcReader.java +++ b/Source/com/drew/metadata/iptc/IptcReader.java @@ -66,7 +66,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APPD); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, Locale locale) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable Locale locale) { for (byte[] segmentBytes : segments) { // Ensure data starts with the IPTC marker byte diff --git a/Source/com/drew/metadata/jfif/JfifReader.java b/Source/com/drew/metadata/jfif/JfifReader.java index 844e358d9..9006258e5 100644 --- a/Source/com/drew/metadata/jfif/JfifReader.java +++ b/Source/com/drew/metadata/jfif/JfifReader.java @@ -25,6 +25,7 @@ import com.drew.lang.ByteArrayReader; import com.drew.lang.RandomAccessReader; import com.drew.lang.annotations.NotNull; +import com.drew.lang.annotations.Nullable; import com.drew.metadata.Metadata; import com.drew.metadata.MetadataReader; @@ -52,7 +53,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APP0); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, Locale locale) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable Locale locale) { for (byte[] segmentBytes : segments) { // Skip segments not starting with the required header diff --git a/Source/com/drew/metadata/jfxx/JfxxReader.java b/Source/com/drew/metadata/jfxx/JfxxReader.java index f0e8ff121..e3ae1c211 100644 --- a/Source/com/drew/metadata/jfxx/JfxxReader.java +++ b/Source/com/drew/metadata/jfxx/JfxxReader.java @@ -25,6 +25,7 @@ import com.drew.lang.ByteArrayReader; import com.drew.lang.RandomAccessReader; import com.drew.lang.annotations.NotNull; +import com.drew.lang.annotations.Nullable; import com.drew.metadata.Metadata; import com.drew.metadata.MetadataReader; @@ -52,7 +53,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APP0); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, Locale locale) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable Locale locale) { for (byte[] segmentBytes : segments) { // Skip segments not starting with the required header diff --git a/Source/com/drew/metadata/jpeg/JpegCommentReader.java b/Source/com/drew/metadata/jpeg/JpegCommentReader.java index b4eda4880..7878b7c64 100644 --- a/Source/com/drew/metadata/jpeg/JpegCommentReader.java +++ b/Source/com/drew/metadata/jpeg/JpegCommentReader.java @@ -23,6 +23,7 @@ import com.drew.imaging.jpeg.JpegSegmentMetadataReader; import com.drew.imaging.jpeg.JpegSegmentType; import com.drew.lang.annotations.NotNull; +import com.drew.lang.annotations.Nullable; import com.drew.metadata.Metadata; import com.drew.metadata.StringValue; @@ -43,7 +44,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.COM); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, Locale locale) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable Locale locale) { for (byte[] segmentBytes : segments) { JpegCommentDirectory directory = new JpegCommentDirectory(); diff --git a/Source/com/drew/metadata/jpeg/JpegDhtReader.java b/Source/com/drew/metadata/jpeg/JpegDhtReader.java index 7844cacfa..bdc77b1a1 100644 --- a/Source/com/drew/metadata/jpeg/JpegDhtReader.java +++ b/Source/com/drew/metadata/jpeg/JpegDhtReader.java @@ -25,6 +25,7 @@ import com.drew.lang.SequentialByteArrayReader; import com.drew.lang.SequentialReader; import com.drew.lang.annotations.NotNull; +import com.drew.lang.annotations.Nullable; import com.drew.metadata.Metadata; import com.drew.metadata.jpeg.HuffmanTablesDirectory.HuffmanTable; import com.drew.metadata.jpeg.HuffmanTablesDirectory.HuffmanTable.HuffmanTableClass; @@ -45,7 +46,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.DHT); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, Locale locale) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable Locale locale) { for (byte[] segmentBytes : segments) { extract(new SequentialByteArrayReader(segmentBytes), metadata); diff --git a/Source/com/drew/metadata/jpeg/JpegDnlReader.java b/Source/com/drew/metadata/jpeg/JpegDnlReader.java index bebbca448..ce6a21c0a 100644 --- a/Source/com/drew/metadata/jpeg/JpegDnlReader.java +++ b/Source/com/drew/metadata/jpeg/JpegDnlReader.java @@ -25,6 +25,7 @@ import com.drew.lang.SequentialByteArrayReader; import com.drew.lang.SequentialReader; import com.drew.lang.annotations.NotNull; +import com.drew.lang.annotations.Nullable; import com.drew.metadata.ErrorDirectory; import com.drew.metadata.Metadata; @@ -45,7 +46,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.DNL); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, Locale locale) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable Locale locale) { for (byte[] segmentBytes : segments) { extract(segmentBytes, metadata, segmentType); diff --git a/Source/com/drew/metadata/jpeg/JpegReader.java b/Source/com/drew/metadata/jpeg/JpegReader.java index b8e3bede1..bb15c90fc 100644 --- a/Source/com/drew/metadata/jpeg/JpegReader.java +++ b/Source/com/drew/metadata/jpeg/JpegReader.java @@ -25,6 +25,7 @@ import com.drew.lang.SequentialByteArrayReader; import com.drew.lang.SequentialReader; import com.drew.lang.annotations.NotNull; +import com.drew.lang.annotations.Nullable; import com.drew.metadata.Metadata; import java.io.IOException; @@ -63,7 +64,7 @@ public Iterable getSegmentTypes() ); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, Locale locale) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable Locale locale) { for (byte[] segmentBytes : segments) { extract(segmentBytes, metadata, segmentType); diff --git a/Source/com/drew/metadata/photoshop/DuckyReader.java b/Source/com/drew/metadata/photoshop/DuckyReader.java index f938b2699..46f4ffce4 100644 --- a/Source/com/drew/metadata/photoshop/DuckyReader.java +++ b/Source/com/drew/metadata/photoshop/DuckyReader.java @@ -26,6 +26,7 @@ import com.drew.lang.SequentialByteArrayReader; import com.drew.lang.SequentialReader; import com.drew.lang.annotations.NotNull; +import com.drew.lang.annotations.Nullable; import com.drew.metadata.Metadata; import java.io.IOException; @@ -49,7 +50,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APPC); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, Locale locale) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable Locale locale) { final int preambleLength = JPEG_SEGMENT_PREAMBLE.length(); diff --git a/Source/com/drew/metadata/photoshop/PhotoshopReader.java b/Source/com/drew/metadata/photoshop/PhotoshopReader.java index 9a74c9634..5715841f2 100644 --- a/Source/com/drew/metadata/photoshop/PhotoshopReader.java +++ b/Source/com/drew/metadata/photoshop/PhotoshopReader.java @@ -59,7 +59,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APPD); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, Locale locale) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable Locale locale) { final int preambleLength = JPEG_SEGMENT_PREAMBLE.length(); diff --git a/Source/com/drew/metadata/xmp/XmpReader.java b/Source/com/drew/metadata/xmp/XmpReader.java index 56be5eb18..ede115669 100644 --- a/Source/com/drew/metadata/xmp/XmpReader.java +++ b/Source/com/drew/metadata/xmp/XmpReader.java @@ -91,7 +91,7 @@ public Iterable getSegmentTypes() * @param segmentType The {@link JpegSegmentType} being read. * @param locale */ - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, Locale locale) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable Locale locale) { final int preambleLength = XMP_JPEG_PREAMBLE.length(); final int extensionPreambleLength = XMP_EXTENSION_JPEG_PREAMBLE.length(); From bbf2cf9310c4528b796ffc46ec0263adb57cb7d8 Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 21 May 2021 14:48:20 +0200 Subject: [PATCH 05/34] Add Nullable annotation to new Locale parameter in interface. --- Source/com/drew/imaging/jpeg/JpegSegmentMetadataReader.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/com/drew/imaging/jpeg/JpegSegmentMetadataReader.java b/Source/com/drew/imaging/jpeg/JpegSegmentMetadataReader.java index 44d6f6762..bd3e36e35 100644 --- a/Source/com/drew/imaging/jpeg/JpegSegmentMetadataReader.java +++ b/Source/com/drew/imaging/jpeg/JpegSegmentMetadataReader.java @@ -1,6 +1,7 @@ package com.drew.imaging.jpeg; import com.drew.lang.annotations.NotNull; +import com.drew.lang.annotations.Nullable; import com.drew.metadata.Metadata; import java.util.Locale; @@ -25,5 +26,5 @@ public interface JpegSegmentMetadataReader * @param segmentType The {@link JpegSegmentType} being read. * @param locale TODO document this */ - void readJpegSegments(@NotNull final Iterable segments, @NotNull final Metadata metadata, @NotNull final JpegSegmentType segmentType, Locale locale); + void readJpegSegments(@NotNull final Iterable segments, @NotNull final Metadata metadata, @NotNull final JpegSegmentType segmentType, @Nullable Locale locale); } From 2fe5f8f6cf68add667ea2af75d11e0d049f0cddf Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 21 May 2021 15:02:24 +0200 Subject: [PATCH 06/34] Fix missing import. --- Source/com/drew/metadata/TagDescriptor.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/com/drew/metadata/TagDescriptor.java b/Source/com/drew/metadata/TagDescriptor.java index 4e16817eb..54645aeb6 100644 --- a/Source/com/drew/metadata/TagDescriptor.java +++ b/Source/com/drew/metadata/TagDescriptor.java @@ -36,6 +36,7 @@ import java.util.Date; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; /** From 60e67a6a96add1802e3edd74219ba9e6d551725e Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 21 May 2021 18:08:02 +0200 Subject: [PATCH 07/34] Fix comment in test. --- Tests/com/drew/imaging/jpeg/JpegMetadataReaderTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/com/drew/imaging/jpeg/JpegMetadataReaderTest.java b/Tests/com/drew/imaging/jpeg/JpegMetadataReaderTest.java index a63ac9723..29e8c7cef 100644 --- a/Tests/com/drew/imaging/jpeg/JpegMetadataReaderTest.java +++ b/Tests/com/drew/imaging/jpeg/JpegMetadataReaderTest.java @@ -125,7 +125,7 @@ public void testConfigurableLocaleEnglish() throws Exception { public void testConfigurableLocaleDutch() throws Exception { Locale defaultLocale = Locale.getDefault(); try { - // set default Locale to Dutch, configure English -> expect comma + // set default Locale to English, configure Dutch -> expect comma Locale.setDefault(Locale.ENGLISH); Locale configuredLocale = new Locale("nl"); Metadata metadata = JpegMetadataReader.readMetadata(new File("Tests/Data/withIptcExifGps.jpg"), configuredLocale); From 44aaa41b75a557f68e572f3d3747aac42c4ac491 Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 28 May 2021 16:02:38 +0200 Subject: [PATCH 08/34] Introduce MetadataContext class to hold Locale to use for formatting tags. --- Source/com/drew/metadata/MetadataContext.java | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 Source/com/drew/metadata/MetadataContext.java diff --git a/Source/com/drew/metadata/MetadataContext.java b/Source/com/drew/metadata/MetadataContext.java new file mode 100644 index 000000000..837ed3fd7 --- /dev/null +++ b/Source/com/drew/metadata/MetadataContext.java @@ -0,0 +1,49 @@ +package com.drew.metadata; + +import com.drew.lang.annotations.NotNull; + +import java.util.Locale; + +/** + * Context class for metadata. Contains settings used while parsing and formatting metadata. + * + * @author Roel van Dijk + */ +public class MetadataContext +{ + /** + * Locale used to format metadata. + */ + private Locale _locale; + + /** + * Initialize a context using the system default {@link Locale}. + */ + public MetadataContext() + { + _locale = Locale.getDefault(); + } + + /** + * Gets the configured {@link Locale}. + * + * @return the configured locale. + */ + public Locale locale() + { + return _locale; + } + + /** + * Configure the {@link Locale} to use for parsing and formatting metadata. + * + * @param locale the locale to use + * @return this context + */ + public MetadataContext locale(@NotNull final Locale locale) + { + _locale = locale; + return this; + } + +} From 63532a62135d76eb023b4e8405558effaf6ebca9 Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 28 May 2021 16:05:13 +0200 Subject: [PATCH 09/34] Replace Locale with MetadataContext class, which supplies the Locale. --- .../drew/imaging/jpeg/JpegMetadataReader.java | 28 +++++++++---------- .../jpeg/JpegSegmentMetadataReader.java | 7 ++--- Source/com/drew/metadata/TagDescriptor.java | 10 +++++++ .../drew/metadata/adobe/AdobeJpegReader.java | 4 +-- .../metadata/exif/ExifDescriptorBase.java | 11 ++++---- Source/com/drew/metadata/exif/ExifReader.java | 10 +++---- .../metadata/exif/ExifSubIFDDescriptor.java | 5 ++-- .../metadata/exif/ExifSubIFDDirectory.java | 5 ++-- .../drew/metadata/exif/ExifTiffHandler.java | 5 ++-- .../com/drew/metadata/exif/GpsDescriptor.java | 14 ++++------ .../com/drew/metadata/exif/GpsDirectory.java | 8 ++++-- Source/com/drew/metadata/icc/IccReader.java | 4 +-- Source/com/drew/metadata/iptc/IptcReader.java | 4 +-- Source/com/drew/metadata/jfif/JfifReader.java | 4 +-- Source/com/drew/metadata/jfxx/JfxxReader.java | 4 +-- .../drew/metadata/jpeg/JpegCommentReader.java | 4 +-- .../com/drew/metadata/jpeg/JpegDhtReader.java | 4 +-- .../com/drew/metadata/jpeg/JpegDnlReader.java | 4 +-- Source/com/drew/metadata/jpeg/JpegReader.java | 4 +-- .../drew/metadata/photoshop/DuckyReader.java | 4 +-- .../metadata/photoshop/PhotoshopReader.java | 4 +-- .../metadata/tiff/DirectoryTiffHandler.java | 13 +++++---- Source/com/drew/metadata/xmp/XmpReader.java | 6 ++-- .../imaging/jpeg/JpegMetadataReaderTest.java | 9 +++--- 24 files changed, 94 insertions(+), 81 deletions(-) diff --git a/Source/com/drew/imaging/jpeg/JpegMetadataReader.java b/Source/com/drew/imaging/jpeg/JpegMetadataReader.java index 859236a96..cbe30e4a3 100644 --- a/Source/com/drew/imaging/jpeg/JpegMetadataReader.java +++ b/Source/com/drew/imaging/jpeg/JpegMetadataReader.java @@ -24,6 +24,7 @@ import com.drew.lang.annotations.NotNull; import com.drew.lang.annotations.Nullable; import com.drew.metadata.Metadata; +import com.drew.metadata.MetadataContext; import com.drew.metadata.adobe.AdobeJpegReader; import com.drew.metadata.exif.ExifReader; import com.drew.metadata.file.FileSystemMetadataReader; @@ -45,7 +46,6 @@ import java.io.InputStream; import java.util.Arrays; import java.util.HashSet; -import java.util.Locale; import java.util.Set; /** @@ -72,11 +72,10 @@ public class JpegMetadataReader ); @NotNull - public static Metadata readMetadata(@NotNull InputStream inputStream, @Nullable Iterable readers, @Nullable Locale locale) throws JpegProcessingException, IOException + public static Metadata readMetadata(@NotNull InputStream inputStream, @Nullable Iterable readers, @NotNull MetadataContext context) throws JpegProcessingException, IOException { - // TODO idea: store Locale in Metadata, since that is passed everywhere anyway? (for now: pass along as parameter) Metadata metadata = new Metadata(); - process(metadata, inputStream, readers, locale); + process(metadata, inputStream, readers, context); return metadata; } @@ -87,9 +86,9 @@ public static Metadata readMetadata(@NotNull InputStream inputStream, @Nullable } @NotNull - public static Metadata readMetadata(@NotNull InputStream inputStream, @Nullable Locale locale) throws JpegProcessingException, IOException + public static Metadata readMetadata(@NotNull InputStream inputStream, @NotNull MetadataContext context) throws JpegProcessingException, IOException { - return readMetadata(inputStream, null, locale); + return readMetadata(inputStream, null, context); } @NotNull @@ -99,12 +98,12 @@ public static Metadata readMetadata(@NotNull InputStream inputStream) throws Jpe } @NotNull - public static Metadata readMetadata(@NotNull File file, @Nullable Iterable readers, @Nullable Locale locale) throws JpegProcessingException, IOException + public static Metadata readMetadata(@NotNull File file, @Nullable Iterable readers, @NotNull MetadataContext context) throws JpegProcessingException, IOException { InputStream inputStream = new FileInputStream(file); Metadata metadata; try { - metadata = readMetadata(inputStream, readers, locale); + metadata = readMetadata(inputStream, readers, context); } finally { inputStream.close(); } @@ -120,9 +119,9 @@ public static Metadata readMetadata(@NotNull File file, @Nullable Iterable readers, @Nullable Locale locale) throws JpegProcessingException, IOException + public static void process(@NotNull Metadata metadata, @NotNull InputStream inputStream, @Nullable Iterable readers, @NotNull MetadataContext context) throws JpegProcessingException, IOException { if (readers == null) readers = ALL_READERS; @@ -151,16 +150,17 @@ public static void process(@NotNull Metadata metadata, @NotNull InputStream inpu JpegSegmentData segmentData = JpegSegmentReader.readSegments(new StreamReader(inputStream), segmentTypes); - processJpegSegmentData(metadata, readers, segmentData, locale); + processJpegSegmentData(metadata, readers, segmentData, context); } // TODO create method with original signature for backwards compatibility - public static void processJpegSegmentData(Metadata metadata, Iterable readers, JpegSegmentData segmentData, Locale locale) + // TODO consider @NotNull / @Nullable annotations + public static void processJpegSegmentData(Metadata metadata, Iterable readers, JpegSegmentData segmentData, MetadataContext context) { // Pass the appropriate byte arrays to each reader. for (JpegSegmentMetadataReader reader : readers) { for (JpegSegmentType segmentType : reader.getSegmentTypes()) { - reader.readJpegSegments(segmentData.getSegments(segmentType), metadata, segmentType, locale); + reader.readJpegSegments(segmentData.getSegments(segmentType), metadata, segmentType, context); } } } diff --git a/Source/com/drew/imaging/jpeg/JpegSegmentMetadataReader.java b/Source/com/drew/imaging/jpeg/JpegSegmentMetadataReader.java index bd3e36e35..481c40ad9 100644 --- a/Source/com/drew/imaging/jpeg/JpegSegmentMetadataReader.java +++ b/Source/com/drew/imaging/jpeg/JpegSegmentMetadataReader.java @@ -3,8 +3,7 @@ import com.drew.lang.annotations.NotNull; import com.drew.lang.annotations.Nullable; import com.drew.metadata.Metadata; - -import java.util.Locale; +import com.drew.metadata.MetadataContext; /** * Defines an object that extracts metadata from in JPEG segments. @@ -24,7 +23,7 @@ public interface JpegSegmentMetadataReader * encountered in the original file. * @param metadata The {@link Metadata} object into which extracted values should be merged. * @param segmentType The {@link JpegSegmentType} being read. - * @param locale TODO document this + * @param context The {@link MetadataContext} to use for parsing and formatting. */ - void readJpegSegments(@NotNull final Iterable segments, @NotNull final Metadata metadata, @NotNull final JpegSegmentType segmentType, @Nullable Locale locale); + void readJpegSegments(@NotNull final Iterable segments, @NotNull final Metadata metadata, @NotNull final JpegSegmentType segmentType, @Nullable MetadataContext context); } diff --git a/Source/com/drew/metadata/TagDescriptor.java b/Source/com/drew/metadata/TagDescriptor.java index 54645aeb6..03ac8d6b5 100644 --- a/Source/com/drew/metadata/TagDescriptor.java +++ b/Source/com/drew/metadata/TagDescriptor.java @@ -50,10 +50,20 @@ public class TagDescriptor { @NotNull protected final T _directory; + @NotNull + protected final MetadataContext _context; + // TODO remove contructor once all sub-classes actually use MetadataContext? public TagDescriptor(@NotNull T directory) + { + // TODO discuss: acceptable to use default here? + this(directory, new MetadataContext()); + } + + public TagDescriptor(@NotNull T directory, @NotNull MetadataContext context) { _directory = directory; + _context = context; } /** diff --git a/Source/com/drew/metadata/adobe/AdobeJpegReader.java b/Source/com/drew/metadata/adobe/AdobeJpegReader.java index 8cdf18713..2e6ca656a 100644 --- a/Source/com/drew/metadata/adobe/AdobeJpegReader.java +++ b/Source/com/drew/metadata/adobe/AdobeJpegReader.java @@ -29,10 +29,10 @@ import com.drew.lang.annotations.Nullable; import com.drew.metadata.Directory; import com.drew.metadata.Metadata; +import com.drew.metadata.MetadataContext; import java.io.IOException; import java.util.Collections; -import java.util.Locale; /** * Decodes Adobe formatted data stored in JPEG files, normally in the APPE (App14) segment. @@ -51,7 +51,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APPE); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable Locale locale) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable MetadataContext context) { for (byte[] bytes : segments) { if (bytes.length == 12 && PREAMBLE.equalsIgnoreCase(new String(bytes, 0, PREAMBLE.length()))) diff --git a/Source/com/drew/metadata/exif/ExifDescriptorBase.java b/Source/com/drew/metadata/exif/ExifDescriptorBase.java index e57dd43fe..655dd33cc 100644 --- a/Source/com/drew/metadata/exif/ExifDescriptorBase.java +++ b/Source/com/drew/metadata/exif/ExifDescriptorBase.java @@ -27,12 +27,12 @@ import com.drew.lang.annotations.Nullable; import com.drew.lang.ByteArrayReader; import com.drew.metadata.Directory; +import com.drew.metadata.MetadataContext; import com.drew.metadata.TagDescriptor; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.text.DecimalFormat; -import java.util.Locale; import static com.drew.metadata.exif.ExifDirectoryBase.*; @@ -49,7 +49,6 @@ public abstract class ExifDescriptorBase extends TagDescrip * where decimal notation is elegant (such as 1/2 -> 0.5, but not 1/3). */ private final boolean _allowDecimalRepresentationOfRationals = true; - private Locale _locale; // Note for the potential addition of brightness presentation in eV: // Brightness of taken subject. To calculate Exposure(Ev) from BrightnessValue(Bv), @@ -57,15 +56,15 @@ public abstract class ExifDescriptorBase extends TagDescrip // Ev=BV+Sv Sv=log2(ISOSpeedRating/3.125) // ISO100:Sv=5, ISO200:Sv=6, ISO400:Sv=7, ISO125:Sv=5.32. + // TODO can be removed once context has been added to all sub-classes public ExifDescriptorBase(@NotNull T directory) { super(directory); } - public ExifDescriptorBase(@NotNull T directory, @Nullable Locale locale) + public ExifDescriptorBase(@NotNull T directory, @NotNull MetadataContext context) { - super(directory); - _locale = locale; + super(directory, context); } @Nullable @@ -618,7 +617,7 @@ public String getFNumberDescription() Rational value = _directory.getRational(TAG_FNUMBER); if (value == null) return null; - return getFStopDescription(value.doubleValue(), _locale); + return getFStopDescription(value.doubleValue(), _context.locale()); } @Nullable diff --git a/Source/com/drew/metadata/exif/ExifReader.java b/Source/com/drew/metadata/exif/ExifReader.java index 1638fcfa4..c0ad40436 100644 --- a/Source/com/drew/metadata/exif/ExifReader.java +++ b/Source/com/drew/metadata/exif/ExifReader.java @@ -30,10 +30,10 @@ import com.drew.lang.annotations.Nullable; import com.drew.metadata.Directory; import com.drew.metadata.Metadata; +import com.drew.metadata.MetadataContext; import java.io.IOException; import java.util.Collections; -import java.util.Locale; /** * Decodes Exif binary data, populating a {@link Metadata} object with tag values in {@link ExifSubIFDDirectory}, @@ -54,14 +54,14 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APP1); } - public void readJpegSegments(@NotNull final Iterable segments, @NotNull final Metadata metadata, @NotNull final JpegSegmentType segmentType, @Nullable Locale locale) + public void readJpegSegments(@NotNull final Iterable segments, @NotNull final Metadata metadata, @NotNull final JpegSegmentType segmentType, @Nullable MetadataContext context) { assert(segmentType == JpegSegmentType.APP1); for (byte[] segmentBytes : segments) { // Segment must have the expected preamble if (startsWithJpegExifPreamble(segmentBytes)) { - extract(new ByteArrayReader(segmentBytes), metadata, JPEG_SEGMENT_PREAMBLE.length(), null, locale); + extract(new ByteArrayReader(segmentBytes), metadata, JPEG_SEGMENT_PREAMBLE.length(), null, context); } } } @@ -92,9 +92,9 @@ public void extract(@NotNull final RandomAccessReader reader, @NotNull final Met } /** Reads TIFF formatted Exif data at a specified offset within a {@link RandomAccessReader}. */ - public void extract(@NotNull final RandomAccessReader reader, @NotNull final Metadata metadata, int readerOffset, @Nullable Directory parentDirectory, @Nullable Locale locale) + public void extract(@NotNull final RandomAccessReader reader, @NotNull final Metadata metadata, int readerOffset, @Nullable Directory parentDirectory, @NotNull MetadataContext context) { - ExifTiffHandler exifTiffHandler = new ExifTiffHandler(metadata, parentDirectory, locale); + ExifTiffHandler exifTiffHandler = new ExifTiffHandler(metadata, parentDirectory, context); try { // Read the TIFF-formatted Exif data diff --git a/Source/com/drew/metadata/exif/ExifSubIFDDescriptor.java b/Source/com/drew/metadata/exif/ExifSubIFDDescriptor.java index e25f92bae..c58e49be1 100644 --- a/Source/com/drew/metadata/exif/ExifSubIFDDescriptor.java +++ b/Source/com/drew/metadata/exif/ExifSubIFDDescriptor.java @@ -22,6 +22,7 @@ import com.drew.lang.annotations.NotNull; import com.drew.lang.annotations.Nullable; +import com.drew.metadata.MetadataContext; import java.util.Locale; @@ -38,8 +39,8 @@ public ExifSubIFDDescriptor(@NotNull ExifSubIFDDirectory directory) this(directory, null); } - public ExifSubIFDDescriptor(@NotNull ExifSubIFDDirectory directory, @Nullable Locale locale) + public ExifSubIFDDescriptor(@NotNull ExifSubIFDDirectory directory, @NotNull MetadataContext context) { - super(directory, locale); + super(directory, context); } } diff --git a/Source/com/drew/metadata/exif/ExifSubIFDDirectory.java b/Source/com/drew/metadata/exif/ExifSubIFDDirectory.java index 02d0d57ba..ce34d4f70 100644 --- a/Source/com/drew/metadata/exif/ExifSubIFDDirectory.java +++ b/Source/com/drew/metadata/exif/ExifSubIFDDirectory.java @@ -23,6 +23,7 @@ import com.drew.lang.annotations.NotNull; import com.drew.lang.annotations.Nullable; import com.drew.metadata.Directory; +import com.drew.metadata.MetadataContext; import java.util.Date; import java.util.HashMap; @@ -45,9 +46,9 @@ public ExifSubIFDDirectory() this.setDescriptor(new ExifSubIFDDescriptor(this)); } - public ExifSubIFDDirectory(@Nullable Locale locale) + public ExifSubIFDDirectory(@NotNull MetadataContext context) { - this.setDescriptor(new ExifSubIFDDescriptor(this, locale)); + this.setDescriptor(new ExifSubIFDDescriptor(this, context)); } @NotNull diff --git a/Source/com/drew/metadata/exif/ExifTiffHandler.java b/Source/com/drew/metadata/exif/ExifTiffHandler.java index cd1433e7c..2d59f7bc5 100644 --- a/Source/com/drew/metadata/exif/ExifTiffHandler.java +++ b/Source/com/drew/metadata/exif/ExifTiffHandler.java @@ -41,6 +41,7 @@ import com.drew.lang.annotations.Nullable; import com.drew.metadata.Directory; import com.drew.metadata.Metadata; +import com.drew.metadata.MetadataContext; import com.drew.metadata.StringValue; import com.drew.metadata.exif.makernotes.*; import com.drew.metadata.icc.IccReader; @@ -60,9 +61,9 @@ */ public class ExifTiffHandler extends DirectoryTiffHandler { - public ExifTiffHandler(@NotNull Metadata metadata, @Nullable Directory parentDirectory, @Nullable Locale locale) + public ExifTiffHandler(@NotNull Metadata metadata, @Nullable Directory parentDirectory, @NotNull MetadataContext context) { - super(metadata, parentDirectory, locale); + super(metadata, parentDirectory, context); } public void setTiffMarker(int marker) throws TiffProcessingException diff --git a/Source/com/drew/metadata/exif/GpsDescriptor.java b/Source/com/drew/metadata/exif/GpsDescriptor.java index ad3269b92..79524a189 100644 --- a/Source/com/drew/metadata/exif/GpsDescriptor.java +++ b/Source/com/drew/metadata/exif/GpsDescriptor.java @@ -24,6 +24,7 @@ import com.drew.lang.Rational; import com.drew.lang.annotations.NotNull; import com.drew.lang.annotations.Nullable; +import com.drew.metadata.MetadataContext; import com.drew.metadata.TagDescriptor; import java.text.DecimalFormat; @@ -39,13 +40,10 @@ @SuppressWarnings("WeakerAccess") public class GpsDescriptor extends TagDescriptor { - private Locale _locale; - public GpsDescriptor(@NotNull GpsDirectory directory, @Nullable Locale locale) + public GpsDescriptor(@NotNull GpsDirectory directory, @NotNull MetadataContext context) { - super(directory); - // TODO add locale to TagDescriptor superclass? - _locale = locale; + super(directory, context); } @Override @@ -116,14 +114,14 @@ private String getGpsVersionIdDescription() public String getGpsLatitudeDescription() { GeoLocation location = _directory.getGeoLocation(); - return location == null ? null : GeoLocation.decimalToDegreesMinutesSecondsString(location.getLatitude(), _locale); + return location == null ? null : GeoLocation.decimalToDegreesMinutesSecondsString(location.getLatitude(), _context.locale()); } @Nullable public String getGpsLongitudeDescription() { GeoLocation location = _directory.getGeoLocation(); - return location == null ? null : GeoLocation.decimalToDegreesMinutesSecondsString(location.getLongitude(), _locale); + return location == null ? null : GeoLocation.decimalToDegreesMinutesSecondsString(location.getLongitude(), _context.locale()); } @Nullable @@ -164,7 +162,7 @@ private String getGeoLocationDimension(int tagValue, int tagRef, String positive Double dec = GeoLocation.degreesMinutesSecondsToDecimal( values[0], values[1], values[2], ref.equalsIgnoreCase(positiveRef)); - return dec == null ? null : GeoLocation.decimalToDegreesMinutesSecondsString(dec, _locale); + return dec == null ? null : GeoLocation.decimalToDegreesMinutesSecondsString(dec, _context.locale()); } @Nullable diff --git a/Source/com/drew/metadata/exif/GpsDirectory.java b/Source/com/drew/metadata/exif/GpsDirectory.java index 797d56c5e..f0676a48e 100644 --- a/Source/com/drew/metadata/exif/GpsDirectory.java +++ b/Source/com/drew/metadata/exif/GpsDirectory.java @@ -24,6 +24,7 @@ import com.drew.lang.Rational; import com.drew.lang.annotations.NotNull; import com.drew.lang.annotations.Nullable; +import com.drew.metadata.MetadataContext; import java.text.DateFormat; import java.text.ParseException; @@ -149,11 +150,12 @@ public class GpsDirectory extends ExifDirectoryBase // TODO remove this constructor? public GpsDirectory() { - this(null); + this(new MetadataContext()); } - public GpsDirectory(@Nullable Locale locale) { - this.setDescriptor(new GpsDescriptor(this, locale)); + public GpsDirectory(@NotNull MetadataContext context) + { + this.setDescriptor(new GpsDescriptor(this, context)); } @Override diff --git a/Source/com/drew/metadata/icc/IccReader.java b/Source/com/drew/metadata/icc/IccReader.java index 50481c000..745122225 100644 --- a/Source/com/drew/metadata/icc/IccReader.java +++ b/Source/com/drew/metadata/icc/IccReader.java @@ -29,11 +29,11 @@ import com.drew.lang.annotations.Nullable; import com.drew.metadata.Directory; import com.drew.metadata.Metadata; +import com.drew.metadata.MetadataContext; import com.drew.metadata.MetadataReader; import java.io.IOException; import java.util.Collections; -import java.util.Locale; /** * Reads an ICC profile. @@ -58,7 +58,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APP2); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable Locale locale) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable MetadataContext context) { final int preambleLength = JPEG_SEGMENT_PREAMBLE.length(); diff --git a/Source/com/drew/metadata/iptc/IptcReader.java b/Source/com/drew/metadata/iptc/IptcReader.java index 7f05336cc..fe7e20ece 100644 --- a/Source/com/drew/metadata/iptc/IptcReader.java +++ b/Source/com/drew/metadata/iptc/IptcReader.java @@ -28,12 +28,12 @@ import com.drew.lang.annotations.Nullable; import com.drew.metadata.Directory; import com.drew.metadata.Metadata; +import com.drew.metadata.MetadataContext; import com.drew.metadata.StringValue; import java.io.IOException; import java.nio.charset.Charset; import java.util.Collections; -import java.util.Locale; /** * Decodes IPTC binary data, populating a {@link Metadata} object with tag values in an {@link IptcDirectory}. @@ -66,7 +66,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APPD); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable Locale locale) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable MetadataContext context) { for (byte[] segmentBytes : segments) { // Ensure data starts with the IPTC marker byte diff --git a/Source/com/drew/metadata/jfif/JfifReader.java b/Source/com/drew/metadata/jfif/JfifReader.java index 9006258e5..c7a4f9b07 100644 --- a/Source/com/drew/metadata/jfif/JfifReader.java +++ b/Source/com/drew/metadata/jfif/JfifReader.java @@ -27,11 +27,11 @@ import com.drew.lang.annotations.NotNull; import com.drew.lang.annotations.Nullable; import com.drew.metadata.Metadata; +import com.drew.metadata.MetadataContext; import com.drew.metadata.MetadataReader; import java.io.IOException; import java.util.Collections; -import java.util.Locale; /** * Reader for JFIF data, found in the APP0 JPEG segment. @@ -53,7 +53,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APP0); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable Locale locale) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable MetadataContext context) { for (byte[] segmentBytes : segments) { // Skip segments not starting with the required header diff --git a/Source/com/drew/metadata/jfxx/JfxxReader.java b/Source/com/drew/metadata/jfxx/JfxxReader.java index e3ae1c211..a814284ad 100644 --- a/Source/com/drew/metadata/jfxx/JfxxReader.java +++ b/Source/com/drew/metadata/jfxx/JfxxReader.java @@ -27,11 +27,11 @@ import com.drew.lang.annotations.NotNull; import com.drew.lang.annotations.Nullable; import com.drew.metadata.Metadata; +import com.drew.metadata.MetadataContext; import com.drew.metadata.MetadataReader; import java.io.IOException; import java.util.Collections; -import java.util.Locale; /** * Reader for JFXX (JFIF extensions) data, found in the APP0 JPEG segment. @@ -53,7 +53,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APP0); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable Locale locale) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable MetadataContext context) { for (byte[] segmentBytes : segments) { // Skip segments not starting with the required header diff --git a/Source/com/drew/metadata/jpeg/JpegCommentReader.java b/Source/com/drew/metadata/jpeg/JpegCommentReader.java index 7878b7c64..f9cd927cb 100644 --- a/Source/com/drew/metadata/jpeg/JpegCommentReader.java +++ b/Source/com/drew/metadata/jpeg/JpegCommentReader.java @@ -25,10 +25,10 @@ import com.drew.lang.annotations.NotNull; import com.drew.lang.annotations.Nullable; import com.drew.metadata.Metadata; +import com.drew.metadata.MetadataContext; import com.drew.metadata.StringValue; import java.util.Collections; -import java.util.Locale; /** * Decodes the comment stored within JPEG files, populating a {@link Metadata} object with tag values in a @@ -44,7 +44,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.COM); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable Locale locale) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable MetadataContext context) { for (byte[] segmentBytes : segments) { JpegCommentDirectory directory = new JpegCommentDirectory(); diff --git a/Source/com/drew/metadata/jpeg/JpegDhtReader.java b/Source/com/drew/metadata/jpeg/JpegDhtReader.java index bdc77b1a1..ef55b2db5 100644 --- a/Source/com/drew/metadata/jpeg/JpegDhtReader.java +++ b/Source/com/drew/metadata/jpeg/JpegDhtReader.java @@ -27,11 +27,11 @@ import com.drew.lang.annotations.NotNull; import com.drew.lang.annotations.Nullable; import com.drew.metadata.Metadata; +import com.drew.metadata.MetadataContext; import com.drew.metadata.jpeg.HuffmanTablesDirectory.HuffmanTable; import com.drew.metadata.jpeg.HuffmanTablesDirectory.HuffmanTable.HuffmanTableClass; import java.io.IOException; import java.util.Collections; -import java.util.Locale; /** * Reader for JPEG Huffman tables, found in the DHT JPEG segment. @@ -46,7 +46,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.DHT); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable Locale locale) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable MetadataContext context) { for (byte[] segmentBytes : segments) { extract(new SequentialByteArrayReader(segmentBytes), metadata); diff --git a/Source/com/drew/metadata/jpeg/JpegDnlReader.java b/Source/com/drew/metadata/jpeg/JpegDnlReader.java index ce6a21c0a..677ec0db2 100644 --- a/Source/com/drew/metadata/jpeg/JpegDnlReader.java +++ b/Source/com/drew/metadata/jpeg/JpegDnlReader.java @@ -28,10 +28,10 @@ import com.drew.lang.annotations.Nullable; import com.drew.metadata.ErrorDirectory; import com.drew.metadata.Metadata; +import com.drew.metadata.MetadataContext; import java.io.IOException; import java.util.Collections; -import java.util.Locale; /** * Decodes JPEG DNL data, adjusting the image height with information missing from the JPEG SOFx segment. @@ -46,7 +46,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.DNL); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable Locale locale) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable MetadataContext context) { for (byte[] segmentBytes : segments) { extract(segmentBytes, metadata, segmentType); diff --git a/Source/com/drew/metadata/jpeg/JpegReader.java b/Source/com/drew/metadata/jpeg/JpegReader.java index bb15c90fc..8e89afe39 100644 --- a/Source/com/drew/metadata/jpeg/JpegReader.java +++ b/Source/com/drew/metadata/jpeg/JpegReader.java @@ -27,10 +27,10 @@ import com.drew.lang.annotations.NotNull; import com.drew.lang.annotations.Nullable; import com.drew.metadata.Metadata; +import com.drew.metadata.MetadataContext; import java.io.IOException; import java.util.Arrays; -import java.util.Locale; /** * Decodes JPEG SOFn data, populating a {@link Metadata} object with tag values in a {@link JpegDirectory}. @@ -64,7 +64,7 @@ public Iterable getSegmentTypes() ); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable Locale locale) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable MetadataContext context) { for (byte[] segmentBytes : segments) { extract(segmentBytes, metadata, segmentType); diff --git a/Source/com/drew/metadata/photoshop/DuckyReader.java b/Source/com/drew/metadata/photoshop/DuckyReader.java index 46f4ffce4..661ba7868 100644 --- a/Source/com/drew/metadata/photoshop/DuckyReader.java +++ b/Source/com/drew/metadata/photoshop/DuckyReader.java @@ -28,10 +28,10 @@ import com.drew.lang.annotations.NotNull; import com.drew.lang.annotations.Nullable; import com.drew.metadata.Metadata; +import com.drew.metadata.MetadataContext; import java.io.IOException; import java.util.Collections; -import java.util.Locale; /** * Reads Photoshop "ducky" segments, created during Save-for-Web. @@ -50,7 +50,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APPC); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable Locale locale) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable MetadataContext context) { final int preambleLength = JPEG_SEGMENT_PREAMBLE.length(); diff --git a/Source/com/drew/metadata/photoshop/PhotoshopReader.java b/Source/com/drew/metadata/photoshop/PhotoshopReader.java index 5715841f2..8279225e5 100644 --- a/Source/com/drew/metadata/photoshop/PhotoshopReader.java +++ b/Source/com/drew/metadata/photoshop/PhotoshopReader.java @@ -30,6 +30,7 @@ import com.drew.lang.annotations.Nullable; import com.drew.metadata.Directory; import com.drew.metadata.Metadata; +import com.drew.metadata.MetadataContext; import com.drew.metadata.exif.ExifReader; import com.drew.metadata.icc.IccReader; import com.drew.metadata.iptc.IptcReader; @@ -37,7 +38,6 @@ import java.util.Arrays; import java.util.Collections; -import java.util.Locale; /** * Reads metadata created by Photoshop and stored in the APPD segment of JPEG files. @@ -59,7 +59,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APPD); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable Locale locale) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable MetadataContext context) { final int preambleLength = JPEG_SEGMENT_PREAMBLE.length(); diff --git a/Source/com/drew/metadata/tiff/DirectoryTiffHandler.java b/Source/com/drew/metadata/tiff/DirectoryTiffHandler.java index 69acac254..8eb00ba20 100644 --- a/Source/com/drew/metadata/tiff/DirectoryTiffHandler.java +++ b/Source/com/drew/metadata/tiff/DirectoryTiffHandler.java @@ -27,6 +27,7 @@ import com.drew.metadata.Directory; import com.drew.metadata.ErrorDirectory; import com.drew.metadata.Metadata; +import com.drew.metadata.MetadataContext; import com.drew.metadata.StringValue; import java.lang.reflect.Constructor; @@ -46,13 +47,13 @@ public abstract class DirectoryTiffHandler implements TiffHandler @Nullable private Directory _rootParentDirectory; @Nullable protected Directory _currentDirectory; protected final Metadata _metadata; - @Nullable private Locale _locale; + private MetadataContext _context; - protected DirectoryTiffHandler(Metadata metadata, @Nullable Directory parentDirectory, @Nullable Locale locale) + protected DirectoryTiffHandler(Metadata metadata, @Nullable Directory parentDirectory, @Nullable MetadataContext context) { _metadata = metadata; _rootParentDirectory = parentDirectory; - _locale = locale; + _context = context; } public void endingIFD() @@ -86,12 +87,12 @@ private Directory getDirectoryInstance(Class directoryClass Constructor[] constructors = directoryClass.getConstructors(); try { - // pass locale to directory, if it has a constructor that can receive it + // pass context to directory, if it has a constructor that can receive it // TODO improve? for (Constructor constructor : constructors) { Class[] parameterTypes = constructor.getParameterTypes(); - if (parameterTypes.length == 1 && parameterTypes[0] == Locale.class) { - return (Directory) constructor.newInstance(_locale); + if (parameterTypes.length == 1 && parameterTypes[0] == MetadataContext.class) { + return (Directory) constructor.newInstance(_context); } } diff --git a/Source/com/drew/metadata/xmp/XmpReader.java b/Source/com/drew/metadata/xmp/XmpReader.java index ede115669..a2d3b43a4 100644 --- a/Source/com/drew/metadata/xmp/XmpReader.java +++ b/Source/com/drew/metadata/xmp/XmpReader.java @@ -35,12 +35,12 @@ import com.drew.lang.annotations.NotNull; import com.drew.lang.annotations.Nullable; import com.drew.metadata.Metadata; +import com.drew.metadata.MetadataContext; import com.drew.metadata.StringValue; import java.io.IOException; import java.util.Collection; import java.util.Collections; -import java.util.Locale; /** * Extracts XMP data from JPEG APP1 segments. @@ -89,9 +89,9 @@ public Iterable getSegmentTypes() * @param segments The byte array from which the metadata should be extracted. * @param metadata The {@link Metadata} object into which extracted values should be merged. * @param segmentType The {@link JpegSegmentType} being read. - * @param locale + * @param context */ - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable Locale locale) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable MetadataContext context) { final int preambleLength = XMP_JPEG_PREAMBLE.length(); final int extensionPreambleLength = XMP_EXTENSION_JPEG_PREAMBLE.length(); diff --git a/Tests/com/drew/imaging/jpeg/JpegMetadataReaderTest.java b/Tests/com/drew/imaging/jpeg/JpegMetadataReaderTest.java index 29e8c7cef..112d5aa62 100644 --- a/Tests/com/drew/imaging/jpeg/JpegMetadataReaderTest.java +++ b/Tests/com/drew/imaging/jpeg/JpegMetadataReaderTest.java @@ -22,6 +22,7 @@ import com.drew.metadata.Directory; import com.drew.metadata.Metadata; +import com.drew.metadata.MetadataContext; import com.drew.metadata.exif.ExifDirectoryBase; import com.drew.metadata.exif.ExifSubIFDDirectory; import com.drew.metadata.exif.GpsDirectory; @@ -104,8 +105,8 @@ public void testConfigurableLocaleEnglish() throws Exception { try { // set default Locale to Dutch, configure English -> expect period Locale.setDefault(new Locale("nl")); - Locale configuredLocale = Locale.ENGLISH; - Metadata metadata = JpegMetadataReader.readMetadata(new File("Tests/Data/withIptcExifGps.jpg"), configuredLocale); + MetadataContext context = new MetadataContext().locale(Locale.ENGLISH); + Metadata metadata = JpegMetadataReader.readMetadata(new File("Tests/Data/withIptcExifGps.jpg"), context); Directory gps = metadata.getFirstDirectoryOfType(GpsDirectory.class); assertEquals("54° 59' 22.8\"", gps.getDescription(GpsDirectory.TAG_LATITUDE)); @@ -127,8 +128,8 @@ public void testConfigurableLocaleDutch() throws Exception { try { // set default Locale to English, configure Dutch -> expect comma Locale.setDefault(Locale.ENGLISH); - Locale configuredLocale = new Locale("nl"); - Metadata metadata = JpegMetadataReader.readMetadata(new File("Tests/Data/withIptcExifGps.jpg"), configuredLocale); + MetadataContext context = new MetadataContext().locale(new Locale("nl")); + Metadata metadata = JpegMetadataReader.readMetadata(new File("Tests/Data/withIptcExifGps.jpg"), context); Directory gps = metadata.getFirstDirectoryOfType(GpsDirectory.class); assertEquals("54° 59' 22,8\"", gps.getDescription(GpsDirectory.TAG_LATITUDE)); From 9608080068998642228622fb3062b223b316dc04 Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 28 May 2021 16:06:11 +0200 Subject: [PATCH 10/34] Add missing Javadoc for new parameter. --- Source/com/drew/metadata/xmp/XmpReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/com/drew/metadata/xmp/XmpReader.java b/Source/com/drew/metadata/xmp/XmpReader.java index a2d3b43a4..bb12b567f 100644 --- a/Source/com/drew/metadata/xmp/XmpReader.java +++ b/Source/com/drew/metadata/xmp/XmpReader.java @@ -89,7 +89,7 @@ public Iterable getSegmentTypes() * @param segments The byte array from which the metadata should be extracted. * @param metadata The {@link Metadata} object into which extracted values should be merged. * @param segmentType The {@link JpegSegmentType} being read. - * @param context + * @param context The {@link MetadataContext} to use for parsing and formatting. */ public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable MetadataContext context) { From 88497e28d5b17795e2aab0a329a6d5bd66385948 Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 28 May 2021 17:28:30 +0200 Subject: [PATCH 11/34] Apply Locale in Directory and TagDescriptor base classes. Add overloaded methods to TagDescriptor to supply Locale where needed. Deprecate overloaded methods that now need a Locale, and are unused. --- Source/com/drew/metadata/Directory.java | 24 ++++- Source/com/drew/metadata/TagDescriptor.java | 96 +++++++++++++++---- .../metadata/exif/ExifDescriptorBase.java | 12 +-- .../makernotes/CanonMakernoteDescriptor.java | 6 +- .../CasioType1MakernoteDescriptor.java | 2 +- .../CasioType2MakernoteDescriptor.java | 2 +- .../NikonType2MakernoteDescriptor.java | 2 +- ...mpusCameraSettingsMakernoteDescriptor.java | 2 +- .../OlympusMakernoteDescriptor.java | 10 +- .../metadata/tiff/DirectoryTiffHandler.java | 2 +- .../imaging/jpeg/JpegMetadataReaderTest.java | 2 - 11 files changed, 118 insertions(+), 42 deletions(-) diff --git a/Source/com/drew/metadata/Directory.java b/Source/com/drew/metadata/Directory.java index b8e9d7eb8..cf991b4fb 100644 --- a/Source/com/drew/metadata/Directory.java +++ b/Source/com/drew/metadata/Directory.java @@ -29,6 +29,7 @@ import java.lang.reflect.Array; import java.text.DateFormat; import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; @@ -192,6 +193,12 @@ public void setParent(@NotNull Directory parent) _parent = parent; } + private Locale getLocale() + { + // TODO discuss: is it acceptable to use a default here? + return _descriptor != null ? _descriptor.getContext().locale() : new MetadataContext().locale(); + } + // TAG SETTERS /** @@ -1024,7 +1031,7 @@ public String getString(int tagType) string.append(Array.getLong(o, i)); } } else if (componentType.getName().equals("float")) { - DecimalFormat format = new DecimalFormat(_floatFormatPattern); + DecimalFormat format = getFloatFormat(); for (int i = 0; i < arrayLength; i++) { if (i != 0) string.append(' '); @@ -1032,7 +1039,7 @@ public String getString(int tagType) string.append(s.equals("-0") ? "0" : s); } } else if (componentType.getName().equals("double")) { - DecimalFormat format = new DecimalFormat(_floatFormatPattern); + DecimalFormat format = getFloatFormat(); for (int i = 0; i < arrayLength; i++) { if (i != 0) string.append(' '); @@ -1053,10 +1060,10 @@ public String getString(int tagType) } if (o instanceof Double) - return new DecimalFormat(_floatFormatPattern).format(((Double)o).doubleValue()); + return getFloatFormat().format(((Double) o).doubleValue()); if (o instanceof Float) - return new DecimalFormat(_floatFormatPattern).format(((Float)o).floatValue()); + return getFloatFormat().format(((Float) o).floatValue()); // Note that several cameras leave trailing spaces (Olympus, Nikon) but this library is intended to show // the actual data within the file. It is not inconceivable that whitespace may be significant here, so we @@ -1065,6 +1072,12 @@ public String getString(int tagType) return o.toString(); } + private DecimalFormat getFloatFormat() + { + DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(getLocale()); + return new DecimalFormat(_floatFormatPattern, symbols); + } + @Nullable public String getString(int tagType, String charset) { @@ -1155,6 +1168,7 @@ public String toString() _tagMap.size(), _tagMap.size() == 1 ? "tag" - : "tags"); + : "tags", + getLocale()); } } diff --git a/Source/com/drew/metadata/TagDescriptor.java b/Source/com/drew/metadata/TagDescriptor.java index 03ac8d6b5..43818b425 100644 --- a/Source/com/drew/metadata/TagDescriptor.java +++ b/Source/com/drew/metadata/TagDescriptor.java @@ -53,7 +53,7 @@ public class TagDescriptor @NotNull protected final MetadataContext _context; - // TODO remove contructor once all sub-classes actually use MetadataContext? + // TODO remove constructor once all sub-classes actually use MetadataContext? public TagDescriptor(@NotNull T directory) { // TODO discuss: acceptable to use default here? @@ -88,13 +88,13 @@ public String getDescription(int tagType) if (object.getClass().isArray()) { final int length = Array.getLength(object); if (length > 16) { - return String.format("[%d values]", length); + return String.format("[%d values]", length, getContext().locale()); } } if (object instanceof Date) { // Produce a date string having a format that includes the offset in form "+00:00" - return new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy") + return new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", getContext().locale()) .format((Date) object) .replaceAll("([0-9]{2} [^ ]+)$", ":$1"); } @@ -103,6 +103,17 @@ public String getDescription(int tagType) return _directory.getString(tagType); } + /** + * Gets the {@link MetadataContext}. + * + * @return the metadata context. + */ + @NotNull + public MetadataContext getContext() + { + return _context; + } + /** * Takes a series of 4 bytes from the specified offset, and converts these to a * well-known version number, where possible. @@ -170,7 +181,7 @@ protected String getByteLengthDescription(final int tagType) byte[] bytes = _directory.getByteArray(tagType); if (bytes == null) return null; - return String.format("(%d byte%s)", bytes.length, bytes.length == 1 ? "" : "s"); + return String.format("(%d byte%s)", bytes.length, bytes.length == 1 ? "" : "s", getContext().locale()); } @Nullable @@ -188,7 +199,7 @@ protected String getDecimalRational(final int tagType, final int decimalPlaces) Rational value = _directory.getRational(tagType); if (value == null) return null; - return String.format("%." + decimalPlaces + "f", value.doubleValue()); + return String.format("%." + decimalPlaces + "f", value.doubleValue(), getContext().locale()); } @Nullable @@ -197,7 +208,7 @@ protected String getFormattedInt(final int tagType, @NotNull final String format Integer value = _directory.getInteger(tagType); if (value == null) return null; - return String.format(format, value); + return String.format(format, value, getContext().locale()); } @Nullable @@ -206,7 +217,7 @@ protected String getFormattedFloat(final int tagType, @NotNull final String form Float value = _directory.getFloatObject(tagType); if (value == null) return null; - return String.format(format, value); + return String.format(format, value, getContext().locale()); } @Nullable @@ -215,7 +226,7 @@ protected String getFormattedString(final int tagType, @NotNull final String for String value = _directory.getString(tagType); if (value == null) return null; - return String.format(format, value); + return String.format(format, value, getContext().locale()); } @Nullable @@ -296,8 +307,19 @@ protected String getStringFromBytes(int tag, Charset cs) } } + // TODO: discuss deprecation + @Deprecated @Nullable + /** + * @deprecated Use {@link #getRationalOrDoubleString(int, Locale)}. + */ protected String getRationalOrDoubleString(int tagType) + { + return getRationalOrDoubleString(tagType, null); + } + + @Nullable + protected String getRationalOrDoubleString(int tagType, Locale locale) { Rational rational = _directory.getRational(tagType); if (rational != null) @@ -305,14 +327,19 @@ protected String getRationalOrDoubleString(int tagType) Double d = _directory.getDoubleObject(tagType); if (d != null) { - DecimalFormat format = new DecimalFormat("0.###"); + DecimalFormat format = new DecimalFormat("0.###", getDecimalFormatSymbols(locale)); return format.format(d); } return null; } + // TODO: discuss deprecation + @Deprecated @Nullable + /** + * @deprecated Use {@link #getFStopDescription(double, Locale)}. + */ protected static String getFStopDescription(double fStop) { return getFStopDescription(fStop, null); @@ -321,22 +348,42 @@ protected static String getFStopDescription(double fStop) @Nullable protected static String getFStopDescription(double fStop, Locale locale) { - DecimalFormatSymbols symbols = locale == null ? DecimalFormatSymbols.getInstance() : DecimalFormatSymbols.getInstance(locale); - DecimalFormat format = new DecimalFormat("0.0", symbols); + DecimalFormat format = new DecimalFormat("0.0", getDecimalFormatSymbols(locale)); format.setRoundingMode(RoundingMode.HALF_UP); return "f/" + format.format(fStop); } - + // TODO: discuss deprecation + @Deprecated @Nullable + /** + * @deprecated Use {@link #getFocalLengthDescription(double, Locale)}. + */ protected static String getFocalLengthDescription(double mm) { - DecimalFormat format = new DecimalFormat("0.#"); + return getFocalLengthDescription(mm, null); + } + + @Nullable + protected static String getFocalLengthDescription(double mm, Locale locale) + { + DecimalFormat format = new DecimalFormat("0.#", getDecimalFormatSymbols(locale)); format.setRoundingMode(RoundingMode.HALF_UP); return format.format(mm) + " mm"; } + // TODO: discuss deprecation + @Deprecated @Nullable + /** + * @deprecated Use {@link #getLensSpecificationDescription(int, Locale)}. + */ protected String getLensSpecificationDescription(int tag) + { + return getLensSpecificationDescription(tag, null); + } + + @Nullable + protected String getLensSpecificationDescription(int tag, Locale locale) { Rational[] values = _directory.getRationalArray(tag); @@ -353,11 +400,11 @@ protected String getLensSpecificationDescription(int tag) if (!values[2].isZero()) { sb.append(' '); - DecimalFormat format = new DecimalFormat("0.0"); + DecimalFormat format = new DecimalFormat("0.0", getDecimalFormatSymbols(locale)); format.setRoundingMode(RoundingMode.HALF_UP); if (values[2].equals(values[3])) - sb.append(getFStopDescription(values[2].doubleValue())); + sb.append(getFStopDescription(values[2].doubleValue(), getContext().locale())); else sb.append("f/").append(format.format(values[2].doubleValue())).append('-').append(format.format(values[3].doubleValue())); } @@ -379,8 +426,19 @@ protected String getOrientationDescription(int tag) "Left side, bottom (Rotate 270 CW)"); } + // TODO: discuss deprecation + @Deprecated @Nullable + /** + * @deprecated Use {@link #getShutterSpeedDescription(int, Locale)}. + */ protected String getShutterSpeedDescription(int tag) + { + return getShutterSpeedDescription(tag, null); + } + + @Nullable + protected String getShutterSpeedDescription(int tag, Locale locale) { // I believe this method to now be stable, but am leaving some alternative snippets of // code in here, to assist anyone who's looking into this (given that I don't have a public CVS). @@ -399,7 +457,7 @@ protected String getShutterSpeedDescription(int tag) float apexPower = (float)(1 / (Math.exp(apexValue * Math.log(2)))); long apexPower10 = Math.round((double)apexPower * 10.0); float fApexPower = (float)apexPower10 / 10.0f; - DecimalFormat format = new DecimalFormat("0.##"); + DecimalFormat format = new DecimalFormat("0.##", getDecimalFormatSymbols(locale)); format.setRoundingMode(RoundingMode.HALF_UP); return format.format(fApexPower) + " sec"; } else { @@ -468,4 +526,10 @@ protected String getEncodedTextDescription(int tagType) return null; } } + + private static DecimalFormatSymbols getDecimalFormatSymbols(Locale locale) + { + return locale == null ? DecimalFormatSymbols.getInstance() : DecimalFormatSymbols.getInstance(locale); + } + } diff --git a/Source/com/drew/metadata/exif/ExifDescriptorBase.java b/Source/com/drew/metadata/exif/ExifDescriptorBase.java index 655dd33cc..14bf565c7 100644 --- a/Source/com/drew/metadata/exif/ExifDescriptorBase.java +++ b/Source/com/drew/metadata/exif/ExifDescriptorBase.java @@ -701,7 +701,7 @@ public String getCompressedAverageBitsPerPixelDescription() @Nullable public String getShutterSpeedDescription() { - return super.getShutterSpeedDescription(TAG_SHUTTER_SPEED); + return super.getShutterSpeedDescription(TAG_SHUTTER_SPEED, getContext().locale()); } @Nullable @@ -711,7 +711,7 @@ public String getApertureValueDescription() if (aperture == null) return null; double fStop = PhotographicConversions.apertureToFStop(aperture); - return getFStopDescription(fStop); + return getFStopDescription(fStop, getContext().locale()); } @Nullable @@ -742,7 +742,7 @@ public String getMaxApertureValueDescription() if (aperture == null) return null; double fStop = PhotographicConversions.apertureToFStop(aperture); - return getFStopDescription(fStop); + return getFStopDescription(fStop, getContext().locale()); } @Nullable @@ -870,7 +870,7 @@ public String getFlashDescription() public String getFocalLengthDescription() { Rational value = _directory.getRational(TAG_FOCAL_LENGTH); - return value == null ? null : getFocalLengthDescription(value.doubleValue()); + return value == null ? null : getFocalLengthDescription(value.doubleValue(), getContext().locale()); } @Nullable @@ -1233,7 +1233,7 @@ public String get35mmFilmEquivFocalLengthDescription() ? null : value == 0 ? "Unknown" - : getFocalLengthDescription(value); + : getFocalLengthDescription(value, getContext().locale()); } @Nullable @@ -1303,6 +1303,6 @@ public String getSubjectDistanceRangeDescription() @Nullable public String getLensSpecificationDescription() { - return getLensSpecificationDescription(TAG_LENS_SPECIFICATION); + return getLensSpecificationDescription(TAG_LENS_SPECIFICATION, getContext().locale()); } } diff --git a/Source/com/drew/metadata/exif/makernotes/CanonMakernoteDescriptor.java b/Source/com/drew/metadata/exif/makernotes/CanonMakernoteDescriptor.java index 665e81129..b56be7f60 100644 --- a/Source/com/drew/metadata/exif/makernotes/CanonMakernoteDescriptor.java +++ b/Source/com/drew/metadata/exif/makernotes/CanonMakernoteDescriptor.java @@ -521,7 +521,7 @@ public String getMaxApertureDescription() return null; if (value > 512) return String.format("Unknown (%d)", value); - return getFStopDescription(Math.exp(decodeCanonEv(value) * Math.log(2.0) / 2.0)); + return getFStopDescription(Math.exp(decodeCanonEv(value) * Math.log(2.0) / 2.0), getContext().locale()); } @Nullable @@ -532,7 +532,7 @@ public String getMinApertureDescription() return null; if (value > 512) return String.format("Unknown (%d)", value); - return getFStopDescription(Math.exp(decodeCanonEv(value) * Math.log(2.0) / 2.0)); + return getFStopDescription(Math.exp(decodeCanonEv(value) * Math.log(2.0) / 2.0), getContext().locale()); } @Nullable @@ -849,7 +849,7 @@ public String getDisplayApertureDescription() if (value == 0xFFFF) return value.toString(); - return getFStopDescription(value / 10f); + return getFStopDescription(value / 10f, getContext().locale()); } @Nullable diff --git a/Source/com/drew/metadata/exif/makernotes/CasioType1MakernoteDescriptor.java b/Source/com/drew/metadata/exif/makernotes/CasioType1MakernoteDescriptor.java index e4fc056d0..7b46451dc 100644 --- a/Source/com/drew/metadata/exif/makernotes/CasioType1MakernoteDescriptor.java +++ b/Source/com/drew/metadata/exif/makernotes/CasioType1MakernoteDescriptor.java @@ -155,7 +155,7 @@ public String getWhiteBalanceDescription() public String getObjectDistanceDescription() { Integer value = _directory.getInteger(TAG_OBJECT_DISTANCE); - return value == null ? null : getFocalLengthDescription(value); + return value == null ? null : getFocalLengthDescription(value, getContext().locale()); } @Nullable diff --git a/Source/com/drew/metadata/exif/makernotes/CasioType2MakernoteDescriptor.java b/Source/com/drew/metadata/exif/makernotes/CasioType2MakernoteDescriptor.java index 853edbddf..98809876c 100644 --- a/Source/com/drew/metadata/exif/makernotes/CasioType2MakernoteDescriptor.java +++ b/Source/com/drew/metadata/exif/makernotes/CasioType2MakernoteDescriptor.java @@ -231,7 +231,7 @@ public String getSaturationDescription() public String getFocalLengthDescription() { Double value = _directory.getDoubleObject(TAG_FOCAL_LENGTH); - return value == null ? null : getFocalLengthDescription(value / 10d); + return value == null ? null : getFocalLengthDescription(value / 10d, getContext().locale()); } @Nullable diff --git a/Source/com/drew/metadata/exif/makernotes/NikonType2MakernoteDescriptor.java b/Source/com/drew/metadata/exif/makernotes/NikonType2MakernoteDescriptor.java index 2df3f28ef..e86e8016c 100644 --- a/Source/com/drew/metadata/exif/makernotes/NikonType2MakernoteDescriptor.java +++ b/Source/com/drew/metadata/exif/makernotes/NikonType2MakernoteDescriptor.java @@ -338,7 +338,7 @@ public String getIsoSettingDescription() @Nullable public String getLensDescription() { - return getLensSpecificationDescription(TAG_LENS); + return getLensSpecificationDescription(TAG_LENS, getContext().locale()); } @Nullable diff --git a/Source/com/drew/metadata/exif/makernotes/OlympusCameraSettingsMakernoteDescriptor.java b/Source/com/drew/metadata/exif/makernotes/OlympusCameraSettingsMakernoteDescriptor.java index 3c9347888..1a4f582f7 100644 --- a/Source/com/drew/metadata/exif/makernotes/OlympusCameraSettingsMakernoteDescriptor.java +++ b/Source/com/drew/metadata/exif/makernotes/OlympusCameraSettingsMakernoteDescriptor.java @@ -231,7 +231,7 @@ public String getMeteringModeDescription() @Nullable public String getExposureShiftDescription() { - return getRationalOrDoubleString(TagExposureShift); + return getRationalOrDoubleString(TagExposureShift, getContext().locale()); } @Nullable diff --git a/Source/com/drew/metadata/exif/makernotes/OlympusMakernoteDescriptor.java b/Source/com/drew/metadata/exif/makernotes/OlympusMakernoteDescriptor.java index 112bcd105..0374576ee 100644 --- a/Source/com/drew/metadata/exif/makernotes/OlympusMakernoteDescriptor.java +++ b/Source/com/drew/metadata/exif/makernotes/OlympusMakernoteDescriptor.java @@ -321,7 +321,7 @@ public String getApexApertureDescription() return null; double fStop = Math.pow((value/16d) - 0.5, 2); - return getFStopDescription(fStop); + return getFStopDescription(fStop, getContext().locale()); } @Nullable @@ -374,7 +374,7 @@ public String getIntervalNumberDescription() public String getFocalLengthDescription() { Long value = _directory.getLongObject(CameraSettings.TAG_FOCAL_LENGTH); - return value == null ? null : getFocalLengthDescription(value/256d); + return value == null ? null : getFocalLengthDescription(value/256d, getContext().locale()); } @Nullable @@ -442,7 +442,7 @@ public String getMaxApertureAtFocalLengthDescription() if (value == null) return null; double fStop = Math.pow((value/16d) - 0.5, 2); - return getFStopDescription(fStop); + return getFStopDescription(fStop, getContext().locale()); } @Nullable @@ -828,7 +828,7 @@ public String getOneTouchWbDescription() @Nullable public String getShutterSpeedDescription() { - return super.getShutterSpeedDescription(TAG_SHUTTER_SPEED_VALUE); + return super.getShutterSpeedDescription(TAG_SHUTTER_SPEED_VALUE, getContext().locale()); } @Nullable @@ -848,7 +848,7 @@ public String getApertureValueDescription() if (aperture == null) return null; double fStop = PhotographicConversions.apertureToFStop(aperture); - return getFStopDescription(fStop); + return getFStopDescription(fStop, getContext().locale()); } @Nullable diff --git a/Source/com/drew/metadata/tiff/DirectoryTiffHandler.java b/Source/com/drew/metadata/tiff/DirectoryTiffHandler.java index 8eb00ba20..f863667f4 100644 --- a/Source/com/drew/metadata/tiff/DirectoryTiffHandler.java +++ b/Source/com/drew/metadata/tiff/DirectoryTiffHandler.java @@ -47,7 +47,7 @@ public abstract class DirectoryTiffHandler implements TiffHandler @Nullable private Directory _rootParentDirectory; @Nullable protected Directory _currentDirectory; protected final Metadata _metadata; - private MetadataContext _context; + protected MetadataContext _context; protected DirectoryTiffHandler(Metadata metadata, @Nullable Directory parentDirectory, @Nullable MetadataContext context) { diff --git a/Tests/com/drew/imaging/jpeg/JpegMetadataReaderTest.java b/Tests/com/drew/imaging/jpeg/JpegMetadataReaderTest.java index 112d5aa62..fa3c2daa4 100644 --- a/Tests/com/drew/imaging/jpeg/JpegMetadataReaderTest.java +++ b/Tests/com/drew/imaging/jpeg/JpegMetadataReaderTest.java @@ -114,7 +114,6 @@ public void testConfigurableLocaleEnglish() throws Exception { Directory subIFD = metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class); assertEquals("f/0.6", subIFD.getDescription(ExifDirectoryBase.TAG_FNUMBER)); - } finally { // reset default locale @@ -137,7 +136,6 @@ public void testConfigurableLocaleDutch() throws Exception { Directory subIFD = metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class); assertEquals("f/0,6", subIFD.getDescription(ExifDirectoryBase.TAG_FNUMBER)); - } finally { // reset default locale From aa71ef4b9b3de403dae4861acb629dd120f6bf08 Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 28 May 2021 17:30:54 +0200 Subject: [PATCH 12/34] Add TODOs for two non-EXIF Locale use cases. --- Tests/com/drew/imaging/png/PngMetadataReaderTest.java | 4 ++++ Tests/com/drew/metadata/icc/IccReaderTest.java | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/Tests/com/drew/imaging/png/PngMetadataReaderTest.java b/Tests/com/drew/imaging/png/PngMetadataReaderTest.java index a32f6e469..ab400b298 100644 --- a/Tests/com/drew/imaging/png/PngMetadataReaderTest.java +++ b/Tests/com/drew/imaging/png/PngMetadataReaderTest.java @@ -114,4 +114,8 @@ public void testGimpGreyscaleWithManyChunks() throws Exception TimeZone.setDefault(timeZone); } } + + // TODO [locale tests] Double use case: + // PngDirectory.TAG_GAMMA in Tests/Data/gimp-8x12-greyscale-alpha-time-background.png + } diff --git a/Tests/com/drew/metadata/icc/IccReaderTest.java b/Tests/com/drew/metadata/icc/IccReaderTest.java index f46372935..c4a3b1c55 100644 --- a/Tests/com/drew/metadata/icc/IccReaderTest.java +++ b/Tests/com/drew/metadata/icc/IccReaderTest.java @@ -84,4 +84,10 @@ public void testExtract_ProfileDateTime() throws Exception assertEquals("1998:02:09 06:49:00", directory.getString(IccDirectory.TAG_PROFILE_DATETIME)); assertEquals(887006940000L, directory.getDate(IccDirectory.TAG_PROFILE_DATETIME).getTime()); } + + // TODO [locale tests] Float array use case: + // IccDirectory.TAG_XYZ_VALUES in Tests/Data/withIptcExifGps.jpg + // Directory icc = metadata.getFirstDirectoryOfType(IccDirectory.class); + // assertEquals("0,964 1 0,825", icc.getString(IccDirectory.TAG_XYZ_VALUES)); + } From ffc5c932a92207d362780dde30b6be9d5f1bf181 Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 28 May 2021 18:10:04 +0200 Subject: [PATCH 13/34] Use context Locale in ExifDescriptorBase. --- .../metadata/exif/ExifDescriptorBase.java | 45 ++++++++++++------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/Source/com/drew/metadata/exif/ExifDescriptorBase.java b/Source/com/drew/metadata/exif/ExifDescriptorBase.java index 14bf565c7..a281388e5 100644 --- a/Source/com/drew/metadata/exif/ExifDescriptorBase.java +++ b/Source/com/drew/metadata/exif/ExifDescriptorBase.java @@ -33,6 +33,8 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.Locale; import static com.drew.metadata.exif.ExifDirectoryBase.*; @@ -429,9 +431,11 @@ public String getXResolutionDescription() if (value == null) return null; final String unit = getResolutionDescription(); + final Locale locale = getContext().locale(); return String.format("%s dots per %s", value.toSimpleString(_allowDecimalRepresentationOfRationals), - unit == null ? "unit" : unit.toLowerCase()); + unit == null ? "unit" : unit.toLowerCase(locale), + locale); } @Nullable @@ -441,9 +445,11 @@ public String getYResolutionDescription() if (value==null) return null; final String unit = getResolutionDescription(); + final Locale locale = getContext().locale(); return String.format("%s dots per %s", value.toSimpleString(_allowDecimalRepresentationOfRationals), - unit == null ? "unit" : unit.toLowerCase()); + unit == null ? "unit" : unit.toLowerCase(locale), + locale); } @Nullable @@ -531,7 +537,7 @@ public String getReferenceBlackWhiteDescription() int whiteG = ints[3]; int blackB = ints[4]; int whiteB = ints[5]; - return String.format("[%d,%d,%d] [%d,%d,%d]", blackR, blackG, blackB, whiteR, whiteG, whiteB); + return String.format("[%d,%d,%d] [%d,%d,%d]", blackR, blackG, blackB, whiteR, whiteG, whiteB, getContext().locale()); } /** @@ -552,7 +558,7 @@ public String getCfaPattern2Description() int[] repeatPattern = _directory.getIntArray(TAG_CFA_REPEAT_PATTERN_DIM); if (repeatPattern == null) - return String.format("Repeat Pattern not found for CFAPattern (%s)", super.getDescription(TAG_CFA_PATTERN_2)); + return String.format("Repeat Pattern not found for CFAPattern (%s)", super.getDescription(TAG_CFA_PATTERN_2), getContext().locale()); if (repeatPattern.length == 2 && values.length == (repeatPattern[0] * repeatPattern[1])) { @@ -566,7 +572,7 @@ public String getCfaPattern2Description() return formatCFAPattern(intpattern); } - return String.format("Unknown Pattern (%s)", super.getDescription(TAG_CFA_PATTERN_2)); + return String.format("Unknown Pattern (%s)", super.getDescription(TAG_CFA_PATTERN_2), getContext().locale()); } @Nullable @@ -617,7 +623,7 @@ public String getFNumberDescription() Rational value = _directory.getRational(TAG_FNUMBER); if (value == null) return null; - return getFStopDescription(value.doubleValue(), _context.locale()); + return getFStopDescription(value.doubleValue(), getContext().locale()); } @Nullable @@ -722,7 +728,7 @@ public String getBrightnessValueDescription() return null; if (value.getNumerator() == 0xFFFFFFFFL) return "Unknown"; - DecimalFormat formatter = new DecimalFormat("0.0##"); + DecimalFormat formatter = new DecimalFormat("0.0##", getDecimalFormatSymbols()); return formatter.format(value.doubleValue()); } @@ -755,7 +761,7 @@ public String getSubjectDistanceDescription() return "Infinity"; if (value.getNumerator() == 0) return "Unknown"; - DecimalFormat formatter = new DecimalFormat("0.0##"); + DecimalFormat formatter = new DecimalFormat("0.0##", getDecimalFormatSymbols()); return formatter.format(value.doubleValue()) + " metres"; } @@ -887,7 +893,7 @@ public String getTemperatureDescription() return null; if (value.getDenominator() == 0xFFFFFFFFL) return "Unknown"; - DecimalFormat formatter = new DecimalFormat("0.0"); + DecimalFormat formatter = new DecimalFormat("0.0", getDecimalFormatSymbols()); return formatter.format(value.doubleValue()) + " °C"; } @@ -899,7 +905,7 @@ public String getHumidityDescription() return null; if (value.getDenominator() == 0xFFFFFFFFL) return "Unknown"; - DecimalFormat formatter = new DecimalFormat("0.0"); + DecimalFormat formatter = new DecimalFormat("0.0", getDecimalFormatSymbols()); return formatter.format(value.doubleValue()) + " %"; } @@ -911,7 +917,7 @@ public String getPressureDescription() return null; if (value.getDenominator() == 0xFFFFFFFFL) return "Unknown"; - DecimalFormat formatter = new DecimalFormat("0.0"); + DecimalFormat formatter = new DecimalFormat("0.0", getDecimalFormatSymbols()); return formatter.format(value.doubleValue()) + " hPa"; } @@ -923,7 +929,7 @@ public String getWaterDepthDescription() return null; if (value.getDenominator() == 0xFFFFFFFFL) return "Unknown"; - DecimalFormat formatter = new DecimalFormat("0.0##"); + DecimalFormat formatter = new DecimalFormat("0.0##", getDecimalFormatSymbols()); return formatter.format(value.doubleValue()) + " metres"; } @@ -935,7 +941,7 @@ public String getAccelerationDescription() return null; if (value.getDenominator() == 0xFFFFFFFFL) return "Unknown"; - DecimalFormat formatter = new DecimalFormat("0.0##"); + DecimalFormat formatter = new DecimalFormat("0.0##", getDecimalFormatSymbols()); return formatter.format(value.doubleValue()) + " mGal"; } @@ -947,7 +953,7 @@ public String getCameraElevationAngleDescription() return null; if (value.getDenominator() == 0xFFFFFFFFL) return "Unknown"; - DecimalFormat formatter = new DecimalFormat("0.##"); + DecimalFormat formatter = new DecimalFormat("0.##", getDecimalFormatSymbols()); return formatter.format(value.doubleValue()) + " degrees"; } @@ -1037,7 +1043,7 @@ public String getFocalPlaneXResolutionDescription() return null; final String unit = getFocalPlaneResolutionUnitDescription(); return rational.getReciprocal().toSimpleString(_allowDecimalRepresentationOfRationals) - + (unit == null ? "" : " " + unit.toLowerCase()); + + (unit == null ? "" : " " + unit.toLowerCase(getContext().locale())); } @Nullable @@ -1048,7 +1054,7 @@ public String getFocalPlaneYResolutionDescription() return null; final String unit = getFocalPlaneResolutionUnitDescription(); return rational.getReciprocal().toSimpleString(_allowDecimalRepresentationOfRationals) - + (unit == null ? "" : " " + unit.toLowerCase()); + + (unit == null ? "" : " " + unit.toLowerCase(getContext().locale())); } @Nullable @@ -1222,7 +1228,7 @@ public String getDigitalZoomRatioDescription() ? null : value.getNumerator() == 0 ? "Digital zoom not used" - : new DecimalFormat("0.#").format(value.doubleValue()); + : new DecimalFormat("0.#", getDecimalFormatSymbols()).format(value.doubleValue()); } @Nullable @@ -1305,4 +1311,9 @@ public String getLensSpecificationDescription() { return getLensSpecificationDescription(TAG_LENS_SPECIFICATION, getContext().locale()); } + + private DecimalFormatSymbols getDecimalFormatSymbols() + { + return DecimalFormatSymbols.getInstance(getContext().locale()); + } } From a0b3508194bc67e9e6cb1dd8b574d425494478b4 Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 18 Jun 2021 14:34:58 +0200 Subject: [PATCH 14/34] Fix locale passing to String.format. --- Source/com/drew/metadata/TagDescriptor.java | 12 ++++++------ .../drew/metadata/exif/ExifDescriptorBase.java | 18 +++++++++--------- .../drew/metadata/exif/ExifTiffHandler.java | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Source/com/drew/metadata/TagDescriptor.java b/Source/com/drew/metadata/TagDescriptor.java index 43818b425..64ca29853 100644 --- a/Source/com/drew/metadata/TagDescriptor.java +++ b/Source/com/drew/metadata/TagDescriptor.java @@ -88,7 +88,7 @@ public String getDescription(int tagType) if (object.getClass().isArray()) { final int length = Array.getLength(object); if (length > 16) { - return String.format("[%d values]", length, getContext().locale()); + return String.format(getContext().locale(), "[%d values]", length); } } @@ -181,7 +181,7 @@ protected String getByteLengthDescription(final int tagType) byte[] bytes = _directory.getByteArray(tagType); if (bytes == null) return null; - return String.format("(%d byte%s)", bytes.length, bytes.length == 1 ? "" : "s", getContext().locale()); + return String.format(getContext().locale(), "(%d byte%s)", bytes.length, bytes.length == 1 ? "" : "s"); } @Nullable @@ -199,7 +199,7 @@ protected String getDecimalRational(final int tagType, final int decimalPlaces) Rational value = _directory.getRational(tagType); if (value == null) return null; - return String.format("%." + decimalPlaces + "f", value.doubleValue(), getContext().locale()); + return String.format(getContext().locale(), "%." + decimalPlaces + "f", value.doubleValue()); } @Nullable @@ -208,7 +208,7 @@ protected String getFormattedInt(final int tagType, @NotNull final String format Integer value = _directory.getInteger(tagType); if (value == null) return null; - return String.format(format, value, getContext().locale()); + return String.format(getContext().locale(), format, value); } @Nullable @@ -217,7 +217,7 @@ protected String getFormattedFloat(final int tagType, @NotNull final String form Float value = _directory.getFloatObject(tagType); if (value == null) return null; - return String.format(format, value, getContext().locale()); + return String.format(getContext().locale(), format, value); } @Nullable @@ -226,7 +226,7 @@ protected String getFormattedString(final int tagType, @NotNull final String for String value = _directory.getString(tagType); if (value == null) return null; - return String.format(format, value, getContext().locale()); + return String.format(getContext().locale(), format, value); } @Nullable diff --git a/Source/com/drew/metadata/exif/ExifDescriptorBase.java b/Source/com/drew/metadata/exif/ExifDescriptorBase.java index a281388e5..b88ac63d3 100644 --- a/Source/com/drew/metadata/exif/ExifDescriptorBase.java +++ b/Source/com/drew/metadata/exif/ExifDescriptorBase.java @@ -432,10 +432,10 @@ public String getXResolutionDescription() return null; final String unit = getResolutionDescription(); final Locale locale = getContext().locale(); - return String.format("%s dots per %s", + return String.format(locale, + "%s dots per %s", value.toSimpleString(_allowDecimalRepresentationOfRationals), - unit == null ? "unit" : unit.toLowerCase(locale), - locale); + unit == null ? "unit" : unit.toLowerCase(locale)); } @Nullable @@ -446,10 +446,10 @@ public String getYResolutionDescription() return null; final String unit = getResolutionDescription(); final Locale locale = getContext().locale(); - return String.format("%s dots per %s", + return String.format(locale, + "%s dots per %s", value.toSimpleString(_allowDecimalRepresentationOfRationals), - unit == null ? "unit" : unit.toLowerCase(locale), - locale); + unit == null ? "unit" : unit.toLowerCase(locale)); } @Nullable @@ -537,7 +537,7 @@ public String getReferenceBlackWhiteDescription() int whiteG = ints[3]; int blackB = ints[4]; int whiteB = ints[5]; - return String.format("[%d,%d,%d] [%d,%d,%d]", blackR, blackG, blackB, whiteR, whiteG, whiteB, getContext().locale()); + return String.format(getContext().locale(), "[%d,%d,%d] [%d,%d,%d]", blackR, blackG, blackB, whiteR, whiteG, whiteB); } /** @@ -558,7 +558,7 @@ public String getCfaPattern2Description() int[] repeatPattern = _directory.getIntArray(TAG_CFA_REPEAT_PATTERN_DIM); if (repeatPattern == null) - return String.format("Repeat Pattern not found for CFAPattern (%s)", super.getDescription(TAG_CFA_PATTERN_2), getContext().locale()); + return String.format(getContext().locale(), "Repeat Pattern not found for CFAPattern (%s)", super.getDescription(TAG_CFA_PATTERN_2)); if (repeatPattern.length == 2 && values.length == (repeatPattern[0] * repeatPattern[1])) { @@ -572,7 +572,7 @@ public String getCfaPattern2Description() return formatCFAPattern(intpattern); } - return String.format("Unknown Pattern (%s)", super.getDescription(TAG_CFA_PATTERN_2), getContext().locale()); + return String.format(getContext().locale(), "Unknown Pattern (%s)", super.getDescription(TAG_CFA_PATTERN_2)); } @Nullable diff --git a/Source/com/drew/metadata/exif/ExifTiffHandler.java b/Source/com/drew/metadata/exif/ExifTiffHandler.java index 2d59f7bc5..271a3c73a 100644 --- a/Source/com/drew/metadata/exif/ExifTiffHandler.java +++ b/Source/com/drew/metadata/exif/ExifTiffHandler.java @@ -83,7 +83,7 @@ public void setTiffMarker(int marker) throws TiffProcessingException pushDirectory(PanasonicRawIFD0Directory.class); break; default: - throw new TiffProcessingException(String.format("Unexpected TIFF marker: 0x%X", marker)); + throw new TiffProcessingException(String.format(_context.locale(), "Unexpected TIFF marker: 0x%X", marker)); } } From 06904a99213b7d781b0f6c4e5d8987803c76a6df Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 25 Jun 2021 11:54:49 +0200 Subject: [PATCH 15/34] Provide Locale to all GpsDescriptor and related classes. --- Source/com/drew/lang/GeoLocation.java | 14 ++++++--- Source/com/drew/metadata/TagDescriptor.java | 2 +- Source/com/drew/metadata/exif/ExifReader.java | 3 +- .../drew/metadata/exif/ExifTiffHandler.java | 1 - .../com/drew/metadata/exif/GpsDescriptor.java | 29 +++++++++++-------- .../com/drew/metadata/exif/GpsDirectory.java | 11 +++++-- 6 files changed, 38 insertions(+), 22 deletions(-) diff --git a/Source/com/drew/lang/GeoLocation.java b/Source/com/drew/lang/GeoLocation.java index 60d6cead5..9b9ded34c 100644 --- a/Source/com/drew/lang/GeoLocation.java +++ b/Source/com/drew/lang/GeoLocation.java @@ -23,6 +23,7 @@ import com.drew.lang.annotations.NotNull; import com.drew.lang.annotations.Nullable; +import com.drew.metadata.MetadataContext; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; @@ -39,17 +40,20 @@ public final class GeoLocation { private final double _latitude; private final double _longitude; + private final MetadataContext _context; /** * Instantiates a new instance of {@link GeoLocation}. * * @param latitude the latitude, in degrees * @param longitude the longitude, in degrees + * @param context the current metadata context */ - public GeoLocation(double latitude, double longitude) + public GeoLocation(double latitude, double longitude, MetadataContext context) { _latitude = latitude; _longitude = longitude; + _context = context; } /** @@ -76,8 +80,9 @@ public boolean isZero() return _latitude == 0 && _longitude == 0; } - // TODO document this + // TODO document this deprecation @NotNull + @Deprecated public static String decimalToDegreesMinutesSecondsString(double decimal) { return decimalToDegreesMinutesSecondsString(decimal, null); @@ -168,7 +173,8 @@ public String toString() @NotNull public String toDMSString() { - // TODO add a Locale version of this method? - return decimalToDegreesMinutesSecondsString(_latitude) + ", " + decimalToDegreesMinutesSecondsString(_longitude); + return decimalToDegreesMinutesSecondsString(_latitude, _context.locale()) + + ", " + + decimalToDegreesMinutesSecondsString(_longitude, _context.locale()); } } diff --git a/Source/com/drew/metadata/TagDescriptor.java b/Source/com/drew/metadata/TagDescriptor.java index 64ca29853..29e7e9b3e 100644 --- a/Source/com/drew/metadata/TagDescriptor.java +++ b/Source/com/drew/metadata/TagDescriptor.java @@ -527,7 +527,7 @@ protected String getEncodedTextDescription(int tagType) } } - private static DecimalFormatSymbols getDecimalFormatSymbols(Locale locale) + protected static DecimalFormatSymbols getDecimalFormatSymbols(Locale locale) { return locale == null ? DecimalFormatSymbols.getInstance() : DecimalFormatSymbols.getInstance(locale); } diff --git a/Source/com/drew/metadata/exif/ExifReader.java b/Source/com/drew/metadata/exif/ExifReader.java index c0ad40436..5be311f78 100644 --- a/Source/com/drew/metadata/exif/ExifReader.java +++ b/Source/com/drew/metadata/exif/ExifReader.java @@ -88,7 +88,8 @@ public void extract(@NotNull final RandomAccessReader reader, @NotNull final Met /** Reads TIFF formatted Exif data at a specified offset within a {@link RandomAccessReader}. */ public void extract(@NotNull final RandomAccessReader reader, @NotNull final Metadata metadata, int readerOffset, @Nullable Directory parentDirectory) { - extract(reader, metadata, readerOffset, parentDirectory, null); + // TODO document this default context? + extract(reader, metadata, readerOffset, parentDirectory, new MetadataContext()); } /** Reads TIFF formatted Exif data at a specified offset within a {@link RandomAccessReader}. */ diff --git a/Source/com/drew/metadata/exif/ExifTiffHandler.java b/Source/com/drew/metadata/exif/ExifTiffHandler.java index 271a3c73a..3b3169ab6 100644 --- a/Source/com/drew/metadata/exif/ExifTiffHandler.java +++ b/Source/com/drew/metadata/exif/ExifTiffHandler.java @@ -24,7 +24,6 @@ import java.io.IOException; import java.util.Arrays; import java.util.HashMap; -import java.util.Locale; import java.util.Map; import java.util.Set; diff --git a/Source/com/drew/metadata/exif/GpsDescriptor.java b/Source/com/drew/metadata/exif/GpsDescriptor.java index 79524a189..c6e19183e 100644 --- a/Source/com/drew/metadata/exif/GpsDescriptor.java +++ b/Source/com/drew/metadata/exif/GpsDescriptor.java @@ -28,7 +28,7 @@ import com.drew.metadata.TagDescriptor; import java.text.DecimalFormat; -import java.util.Locale; +import java.text.DecimalFormatSymbols; import static com.drew.metadata.exif.GpsDirectory.*; @@ -129,10 +129,11 @@ public String getGpsTimeStampDescription() { // time in hour, min, sec Rational[] timeComponents = _directory.getRationalArray(TAG_TIME_STAMP); - DecimalFormat df = new DecimalFormat("00.000"); + DecimalFormat df = new DecimalFormat("00.000", getDecimalFormatSymbols(_context.locale())); return timeComponents == null ? null - : String.format("%02d:%02d:%s UTC", + : String.format(_context.locale(), + "%02d:%02d:%s UTC", timeComponents[0].intValue(), timeComponents[1].intValue(), df.format(timeComponents[2].doubleValue())); @@ -190,9 +191,10 @@ public String getGpsDestDistanceDescription() if (value == null) return null; final String unit = getGpsDestinationReferenceDescription(); - return String.format("%s %s", - new DecimalFormat("0.##").format(value.doubleValue()), - unit == null ? "unit" : unit.toLowerCase()); + return String.format(_context.locale(), + "%s %s", + new DecimalFormat("0.##", getDecimalFormatSymbols(_context.locale())).format(value.doubleValue()), + unit == null ? "unit" : unit.toLowerCase(_context.locale())); } @Nullable @@ -201,7 +203,7 @@ public String getGpsDirectionDescription(int tagType) Rational angle = _directory.getRational(tagType); // provide a decimal version of rational numbers in the description, to avoid strings like "35334/199 degrees" String value = angle != null - ? new DecimalFormat("0.##").format(angle.doubleValue()) + ? new DecimalFormat("0.##", getDecimalFormatSymbols(_context.locale())).format(angle.doubleValue()) : _directory.getString(tagType); return value == null || value.trim().length() == 0 ? null : value.trim() + " degrees"; } @@ -226,7 +228,8 @@ public String getGpsDirectionReferenceDescription(int tagType) public String getGpsDopDescription() { final Rational value = _directory.getRational(TAG_DOP); - return value == null ? null : new DecimalFormat("0.##").format(value.doubleValue()); + final DecimalFormatSymbols symbols = getDecimalFormatSymbols(_context.locale()); + return value == null ? null : new DecimalFormat("0.##", symbols).format(value.doubleValue()); } @Nullable @@ -255,8 +258,8 @@ public String getGpsSpeedDescription() return null; final String unit = getGpsSpeedRefDescription(); return String.format("%s %s", - new DecimalFormat("0.##").format(value.doubleValue()), - unit == null ? "unit" : unit.toLowerCase()); + new DecimalFormat("0.##", getDecimalFormatSymbols(_context.locale())).format(value.doubleValue()), + unit == null ? "unit" : unit.toLowerCase(_context.locale())); } @Nullable @@ -301,7 +304,8 @@ public String getGpsAltitudeRefDescription() public String getGpsAltitudeDescription() { final Rational value = _directory.getRational(TAG_ALTITUDE); - return value == null ? null : new DecimalFormat("0.##").format(value.doubleValue()) + " metres"; + final DecimalFormatSymbols symbols = getDecimalFormatSymbols(_context.locale()); + return value == null ? null : new DecimalFormat("0.##", symbols).format(value.doubleValue()) + " metres"; } @Nullable @@ -326,7 +330,8 @@ public String getGpsDifferentialDescription() public String getGpsHPositioningErrorDescription() { final Rational value = _directory.getRational(TAG_H_POSITIONING_ERROR); - return value == null ? null : new DecimalFormat("0.##").format(value.doubleValue()) + " metres"; + final DecimalFormatSymbols symbols = getDecimalFormatSymbols(_context.locale()); + return value == null ? null : new DecimalFormat("0.##", symbols).format(value.doubleValue()) + " metres"; } @Nullable diff --git a/Source/com/drew/metadata/exif/GpsDirectory.java b/Source/com/drew/metadata/exif/GpsDirectory.java index f0676a48e..02ec3cd9a 100644 --- a/Source/com/drew/metadata/exif/GpsDirectory.java +++ b/Source/com/drew/metadata/exif/GpsDirectory.java @@ -147,7 +147,11 @@ public class GpsDirectory extends ExifDirectoryBase _tagNameMap.put(TAG_H_POSITIONING_ERROR, "GPS H Positioning Error"); } - // TODO remove this constructor? + @NotNull + private final MetadataContext _context; + + // TODO remove this constructor, or document its deprecation? + @Deprecated public GpsDirectory() { this(new MetadataContext()); @@ -156,6 +160,7 @@ public GpsDirectory() public GpsDirectory(@NotNull MetadataContext context) { this.setDescriptor(new GpsDescriptor(this, context)); + _context = context; } @Override @@ -201,7 +206,7 @@ public GeoLocation getGeoLocation() if (lat == null || lon == null) return null; - return new GeoLocation(lat, lon); + return new GeoLocation(lat, lon, _context); } /** @@ -225,7 +230,7 @@ public Date getGpsDate() String dateTime = String.format(Locale.US, "%s %02d:%02d:%02.3f UTC", date, timeComponents[0].intValue(), timeComponents[1].intValue(), timeComponents[2].doubleValue()); try { - DateFormat parser = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss.S z"); + DateFormat parser = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss.S z", _context.locale()); return parser.parse(dateTime); } catch (ParseException e) { return null; From 0e567cff92fd0f81bc91271118f3ad5fb61e1206 Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 25 Jun 2021 12:05:01 +0200 Subject: [PATCH 16/34] Pass Locale instead of full MetadataContext to Gps related classes. --- Source/com/drew/lang/GeoLocation.java | 13 ++++++------- Source/com/drew/metadata/Directory.java | 2 +- Source/com/drew/metadata/exif/GpsDirectory.java | 8 ++------ 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/Source/com/drew/lang/GeoLocation.java b/Source/com/drew/lang/GeoLocation.java index 9b9ded34c..3f469dc72 100644 --- a/Source/com/drew/lang/GeoLocation.java +++ b/Source/com/drew/lang/GeoLocation.java @@ -23,7 +23,6 @@ import com.drew.lang.annotations.NotNull; import com.drew.lang.annotations.Nullable; -import com.drew.metadata.MetadataContext; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; @@ -40,20 +39,20 @@ public final class GeoLocation { private final double _latitude; private final double _longitude; - private final MetadataContext _context; + private final Locale _locale; /** * Instantiates a new instance of {@link GeoLocation}. * * @param latitude the latitude, in degrees * @param longitude the longitude, in degrees - * @param context the current metadata context + * @param locale the locale to use */ - public GeoLocation(double latitude, double longitude, MetadataContext context) + public GeoLocation(double latitude, double longitude, Locale locale) { _latitude = latitude; _longitude = longitude; - _context = context; + _locale = locale; } /** @@ -173,8 +172,8 @@ public String toString() @NotNull public String toDMSString() { - return decimalToDegreesMinutesSecondsString(_latitude, _context.locale()) + return decimalToDegreesMinutesSecondsString(_latitude, _locale) + ", " - + decimalToDegreesMinutesSecondsString(_longitude, _context.locale()); + + decimalToDegreesMinutesSecondsString(_longitude, _locale); } } diff --git a/Source/com/drew/metadata/Directory.java b/Source/com/drew/metadata/Directory.java index cf991b4fb..da681b75d 100644 --- a/Source/com/drew/metadata/Directory.java +++ b/Source/com/drew/metadata/Directory.java @@ -193,7 +193,7 @@ public void setParent(@NotNull Directory parent) _parent = parent; } - private Locale getLocale() + protected Locale getLocale() { // TODO discuss: is it acceptable to use a default here? return _descriptor != null ? _descriptor.getContext().locale() : new MetadataContext().locale(); diff --git a/Source/com/drew/metadata/exif/GpsDirectory.java b/Source/com/drew/metadata/exif/GpsDirectory.java index 02ec3cd9a..2e3d011a5 100644 --- a/Source/com/drew/metadata/exif/GpsDirectory.java +++ b/Source/com/drew/metadata/exif/GpsDirectory.java @@ -147,9 +147,6 @@ public class GpsDirectory extends ExifDirectoryBase _tagNameMap.put(TAG_H_POSITIONING_ERROR, "GPS H Positioning Error"); } - @NotNull - private final MetadataContext _context; - // TODO remove this constructor, or document its deprecation? @Deprecated public GpsDirectory() @@ -160,7 +157,6 @@ public GpsDirectory() public GpsDirectory(@NotNull MetadataContext context) { this.setDescriptor(new GpsDescriptor(this, context)); - _context = context; } @Override @@ -206,7 +202,7 @@ public GeoLocation getGeoLocation() if (lat == null || lon == null) return null; - return new GeoLocation(lat, lon, _context); + return new GeoLocation(lat, lon, getLocale()); } /** @@ -230,7 +226,7 @@ public Date getGpsDate() String dateTime = String.format(Locale.US, "%s %02d:%02d:%02.3f UTC", date, timeComponents[0].intValue(), timeComponents[1].intValue(), timeComponents[2].doubleValue()); try { - DateFormat parser = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss.S z", _context.locale()); + DateFormat parser = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss.S z", getLocale()); return parser.parse(dateTime); } catch (ParseException e) { return null; From e1bcae9ecd6d294af9fd4ddb946d5145fec6a0b2 Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 25 Jun 2021 12:25:20 +0200 Subject: [PATCH 17/34] Provide Locale to all JpegReader and related classes. --- Source/com/drew/metadata/jpeg/JpegDescriptor.java | 5 +++-- Source/com/drew/metadata/jpeg/JpegDirectory.java | 10 +++++++++- Source/com/drew/metadata/jpeg/JpegReader.java | 6 +++--- Tests/com/drew/metadata/jpeg/JpegDescriptorTest.java | 6 ++++-- Tests/com/drew/metadata/jpeg/JpegDirectoryTest.java | 4 +++- Tests/com/drew/metadata/jpeg/JpegReaderTest.java | 4 +++- 6 files changed, 25 insertions(+), 10 deletions(-) diff --git a/Source/com/drew/metadata/jpeg/JpegDescriptor.java b/Source/com/drew/metadata/jpeg/JpegDescriptor.java index 2f2d964c3..6c2711bd0 100644 --- a/Source/com/drew/metadata/jpeg/JpegDescriptor.java +++ b/Source/com/drew/metadata/jpeg/JpegDescriptor.java @@ -22,6 +22,7 @@ import com.drew.lang.annotations.NotNull; import com.drew.lang.annotations.Nullable; +import com.drew.metadata.MetadataContext; import com.drew.metadata.TagDescriptor; import static com.drew.metadata.jpeg.JpegDirectory.*; @@ -35,9 +36,9 @@ @SuppressWarnings("WeakerAccess") public class JpegDescriptor extends TagDescriptor { - public JpegDescriptor(@NotNull JpegDirectory directory) + public JpegDescriptor(@NotNull JpegDirectory directory, MetadataContext context) { - super(directory); + super(directory, context); } @Override diff --git a/Source/com/drew/metadata/jpeg/JpegDirectory.java b/Source/com/drew/metadata/jpeg/JpegDirectory.java index 22201d364..5f2bd3dc1 100644 --- a/Source/com/drew/metadata/jpeg/JpegDirectory.java +++ b/Source/com/drew/metadata/jpeg/JpegDirectory.java @@ -23,6 +23,7 @@ import com.drew.lang.annotations.NotNull; import com.drew.lang.annotations.Nullable; import com.drew.metadata.Directory; +import com.drew.metadata.MetadataContext; import com.drew.metadata.MetadataException; import java.util.HashMap; @@ -79,9 +80,16 @@ public class JpegDirectory extends Directory _tagNameMap.put(TAG_COMPONENT_DATA_4, "Component 4"); } + // TODO remove this constructor, or document its deprecation? + @Deprecated public JpegDirectory() { - this.setDescriptor(new JpegDescriptor(this)); + this(new MetadataContext()); + } + + public JpegDirectory(@NotNull MetadataContext context) + { + this.setDescriptor(new JpegDescriptor(this, context)); } @Override diff --git a/Source/com/drew/metadata/jpeg/JpegReader.java b/Source/com/drew/metadata/jpeg/JpegReader.java index 8e89afe39..4ca9d2f39 100644 --- a/Source/com/drew/metadata/jpeg/JpegReader.java +++ b/Source/com/drew/metadata/jpeg/JpegReader.java @@ -67,13 +67,13 @@ public Iterable getSegmentTypes() public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable MetadataContext context) { for (byte[] segmentBytes : segments) { - extract(segmentBytes, metadata, segmentType); + extract(segmentBytes, metadata, segmentType, context); } } - public void extract(byte[] segmentBytes, Metadata metadata, JpegSegmentType segmentType) + public void extract(byte[] segmentBytes, Metadata metadata, JpegSegmentType segmentType, MetadataContext context) { - JpegDirectory directory = new JpegDirectory(); + JpegDirectory directory = new JpegDirectory(context); metadata.addDirectory(directory); // The value of TAG_COMPRESSION_TYPE is determined by the segment type found diff --git a/Tests/com/drew/metadata/jpeg/JpegDescriptorTest.java b/Tests/com/drew/metadata/jpeg/JpegDescriptorTest.java index 357cd96d7..1d81ae265 100644 --- a/Tests/com/drew/metadata/jpeg/JpegDescriptorTest.java +++ b/Tests/com/drew/metadata/jpeg/JpegDescriptorTest.java @@ -20,6 +20,7 @@ */ package com.drew.metadata.jpeg; +import com.drew.metadata.MetadataContext; import com.drew.metadata.MetadataException; import org.junit.Before; import org.junit.Test; @@ -39,8 +40,9 @@ public class JpegDescriptorTest @Before public void setUp() throws Exception { - _directory = new JpegDirectory(); - _descriptor = new JpegDescriptor(_directory); + MetadataContext context = new MetadataContext(); + _directory = new JpegDirectory(context); + _descriptor = new JpegDescriptor(_directory, context); } @Test diff --git a/Tests/com/drew/metadata/jpeg/JpegDirectoryTest.java b/Tests/com/drew/metadata/jpeg/JpegDirectoryTest.java index a7c4c131d..702e5e72b 100644 --- a/Tests/com/drew/metadata/jpeg/JpegDirectoryTest.java +++ b/Tests/com/drew/metadata/jpeg/JpegDirectoryTest.java @@ -20,6 +20,7 @@ */ package com.drew.metadata.jpeg; +import com.drew.metadata.MetadataContext; import org.junit.Before; import org.junit.Test; @@ -35,7 +36,8 @@ public class JpegDirectoryTest @Before public void setUp() { - _directory = new JpegDirectory(); + MetadataContext context = new MetadataContext(); + _directory = new JpegDirectory(context); } @Test diff --git a/Tests/com/drew/metadata/jpeg/JpegReaderTest.java b/Tests/com/drew/metadata/jpeg/JpegReaderTest.java index f0e87a15d..1d35c7470 100644 --- a/Tests/com/drew/metadata/jpeg/JpegReaderTest.java +++ b/Tests/com/drew/metadata/jpeg/JpegReaderTest.java @@ -24,6 +24,7 @@ import com.drew.imaging.jpeg.JpegSegmentType; import com.drew.lang.annotations.NotNull; import com.drew.metadata.Metadata; +import com.drew.metadata.MetadataContext; import com.drew.tools.FileUtil; import org.junit.Before; import org.junit.Test; @@ -42,7 +43,8 @@ public class JpegReaderTest public static JpegDirectory processBytes(String filePath) throws IOException { Metadata metadata = new Metadata(); - new JpegReader().extract(FileUtil.readBytes(filePath), metadata, JpegSegmentType.SOF0); + MetadataContext context = new MetadataContext(); + new JpegReader().extract(FileUtil.readBytes(filePath), metadata, JpegSegmentType.SOF0, context); JpegDirectory directory = metadata.getFirstDirectoryOfType(JpegDirectory.class); assertNotNull(directory); From 4b517702440fba476daf3e95a3982ab2e7d7a1c3 Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 25 Jun 2021 12:28:42 +0200 Subject: [PATCH 18/34] Provide MetadataContext to all JpegCommentReader and related classes. --- .../com/drew/metadata/jpeg/JpegCommentDescriptor.java | 5 +++-- .../com/drew/metadata/jpeg/JpegCommentDirectory.java | 10 +++++++++- Source/com/drew/metadata/jpeg/JpegCommentReader.java | 2 +- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Source/com/drew/metadata/jpeg/JpegCommentDescriptor.java b/Source/com/drew/metadata/jpeg/JpegCommentDescriptor.java index e44014cf5..70b29e595 100644 --- a/Source/com/drew/metadata/jpeg/JpegCommentDescriptor.java +++ b/Source/com/drew/metadata/jpeg/JpegCommentDescriptor.java @@ -22,6 +22,7 @@ import com.drew.lang.annotations.NotNull; import com.drew.lang.annotations.Nullable; +import com.drew.metadata.MetadataContext; import com.drew.metadata.TagDescriptor; /** @@ -32,9 +33,9 @@ @SuppressWarnings("WeakerAccess") public class JpegCommentDescriptor extends TagDescriptor { - public JpegCommentDescriptor(@NotNull JpegCommentDirectory directory) + public JpegCommentDescriptor(@NotNull JpegCommentDirectory directory, @NotNull MetadataContext context) { - super(directory); + super(directory, context); } @Nullable diff --git a/Source/com/drew/metadata/jpeg/JpegCommentDirectory.java b/Source/com/drew/metadata/jpeg/JpegCommentDirectory.java index 2eb92f6b0..bf1066a64 100644 --- a/Source/com/drew/metadata/jpeg/JpegCommentDirectory.java +++ b/Source/com/drew/metadata/jpeg/JpegCommentDirectory.java @@ -22,6 +22,7 @@ import com.drew.lang.annotations.NotNull; import com.drew.metadata.Directory; +import com.drew.metadata.MetadataContext; import java.util.HashMap; @@ -46,9 +47,16 @@ public class JpegCommentDirectory extends Directory _tagNameMap.put(TAG_COMMENT, "JPEG Comment"); } + // TODO remove this constructor, or document its deprecation? + @Deprecated public JpegCommentDirectory() { - this.setDescriptor(new JpegCommentDescriptor(this)); + this(new MetadataContext()); + } + + public JpegCommentDirectory(@NotNull MetadataContext context) + { + this.setDescriptor(new JpegCommentDescriptor(this, context)); } @Override diff --git a/Source/com/drew/metadata/jpeg/JpegCommentReader.java b/Source/com/drew/metadata/jpeg/JpegCommentReader.java index f9cd927cb..ab0e2dfb0 100644 --- a/Source/com/drew/metadata/jpeg/JpegCommentReader.java +++ b/Source/com/drew/metadata/jpeg/JpegCommentReader.java @@ -47,7 +47,7 @@ public Iterable getSegmentTypes() public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable MetadataContext context) { for (byte[] segmentBytes : segments) { - JpegCommentDirectory directory = new JpegCommentDirectory(); + JpegCommentDirectory directory = new JpegCommentDirectory(context); metadata.addDirectory(directory); // The entire contents of the directory are the comment From 0d1b49b9126d9d3f06f450b23d8aef8842722828 Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 25 Jun 2021 12:43:10 +0200 Subject: [PATCH 19/34] Initialize a default MetadataContext in JpegMetadataReader. --- Source/com/drew/imaging/jpeg/JpegMetadataReader.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/com/drew/imaging/jpeg/JpegMetadataReader.java b/Source/com/drew/imaging/jpeg/JpegMetadataReader.java index cbe30e4a3..9a0743ad0 100644 --- a/Source/com/drew/imaging/jpeg/JpegMetadataReader.java +++ b/Source/com/drew/imaging/jpeg/JpegMetadataReader.java @@ -94,7 +94,7 @@ public static Metadata readMetadata(@NotNull InputStream inputStream, @NotNull M @NotNull public static Metadata readMetadata(@NotNull InputStream inputStream) throws JpegProcessingException, IOException { - return readMetadata(inputStream, null, null); + return readMetadata(inputStream, null, new MetadataContext()); } @NotNull @@ -115,7 +115,7 @@ public static Metadata readMetadata(@NotNull File file, @Nullable Iterable readers) throws JpegProcessingException, IOException { - return readMetadata(file, readers, null); + return readMetadata(file, readers, new MetadataContext()); } @NotNull @@ -127,12 +127,12 @@ public static Metadata readMetadata(@NotNull File file, @NotNull MetadataContext @NotNull public static Metadata readMetadata(@NotNull File file) throws JpegProcessingException, IOException { - return readMetadata(file, null, null); + return readMetadata(file, null, new MetadataContext()); } public static void process(@NotNull Metadata metadata, @NotNull InputStream inputStream) throws JpegProcessingException, IOException { - process(metadata, inputStream, null, null); + process(metadata, inputStream, null, new MetadataContext()); } // TODO create method with original signature for backwards compatibility From ffb182995b28f0b1a236496636695632ccc9b87c Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 25 Jun 2021 12:44:17 +0200 Subject: [PATCH 20/34] Provide MetadataContext to all JpegDhtReader and related classes. --- .../drew/metadata/jpeg/HuffmanTablesDescriptor.java | 5 +++-- .../com/drew/metadata/jpeg/HuffmanTablesDirectory.java | 10 +++++++++- Source/com/drew/metadata/jpeg/JpegDhtReader.java | 6 +++--- .../metadata/jpeg/HuffmanTablesDescriptorTest.java | 6 ++++-- Tests/com/drew/metadata/jpeg/JpegDhtReaderTest.java | 4 +++- 5 files changed, 22 insertions(+), 9 deletions(-) diff --git a/Source/com/drew/metadata/jpeg/HuffmanTablesDescriptor.java b/Source/com/drew/metadata/jpeg/HuffmanTablesDescriptor.java index 4b1d14527..658722d91 100644 --- a/Source/com/drew/metadata/jpeg/HuffmanTablesDescriptor.java +++ b/Source/com/drew/metadata/jpeg/HuffmanTablesDescriptor.java @@ -22,6 +22,7 @@ import com.drew.lang.annotations.NotNull; import com.drew.lang.annotations.Nullable; +import com.drew.metadata.MetadataContext; import com.drew.metadata.TagDescriptor; import static com.drew.metadata.jpeg.HuffmanTablesDirectory.*; @@ -39,9 +40,9 @@ @SuppressWarnings("WeakerAccess") public class HuffmanTablesDescriptor extends TagDescriptor { - public HuffmanTablesDescriptor(@NotNull HuffmanTablesDirectory directory) + public HuffmanTablesDescriptor(@NotNull HuffmanTablesDirectory directory, @NotNull MetadataContext context) { - super(directory); + super(directory, context); } @Override diff --git a/Source/com/drew/metadata/jpeg/HuffmanTablesDirectory.java b/Source/com/drew/metadata/jpeg/HuffmanTablesDirectory.java index 2b975f494..9c184369a 100644 --- a/Source/com/drew/metadata/jpeg/HuffmanTablesDirectory.java +++ b/Source/com/drew/metadata/jpeg/HuffmanTablesDirectory.java @@ -27,6 +27,7 @@ import com.drew.lang.annotations.NotNull; import com.drew.metadata.Directory; +import com.drew.metadata.MetadataContext; import com.drew.metadata.MetadataException; /** @@ -128,9 +129,16 @@ public class HuffmanTablesDirectory extends Directory _tagNameMap.put(TAG_NUMBER_OF_TABLES, "Number of Tables"); } + // TODO remove this constructor, or document its deprecation? + @Deprecated public HuffmanTablesDirectory() { - this.setDescriptor(new HuffmanTablesDescriptor(this)); + this(new MetadataContext()); + } + + public HuffmanTablesDirectory(@NotNull MetadataContext context) + { + this.setDescriptor(new HuffmanTablesDescriptor(this, context)); } @Override diff --git a/Source/com/drew/metadata/jpeg/JpegDhtReader.java b/Source/com/drew/metadata/jpeg/JpegDhtReader.java index ef55b2db5..79f688bff 100644 --- a/Source/com/drew/metadata/jpeg/JpegDhtReader.java +++ b/Source/com/drew/metadata/jpeg/JpegDhtReader.java @@ -49,7 +49,7 @@ public Iterable getSegmentTypes() public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable MetadataContext context) { for (byte[] segmentBytes : segments) { - extract(new SequentialByteArrayReader(segmentBytes), metadata); + extract(new SequentialByteArrayReader(segmentBytes), metadata, context); } } @@ -57,11 +57,11 @@ public void readJpegSegments(@NotNull Iterable segments, @NotNull Metada * Performs the DHT tables extraction, adding found tables to the specified * instance of {@link Metadata}. */ - public void extract(@NotNull final SequentialReader reader, @NotNull final Metadata metadata) + public void extract(@NotNull final SequentialReader reader, @NotNull final Metadata metadata, @NotNull MetadataContext context) { HuffmanTablesDirectory directory = metadata.getFirstDirectoryOfType(HuffmanTablesDirectory.class); if (directory == null) { - directory = new HuffmanTablesDirectory(); + directory = new HuffmanTablesDirectory(context); metadata.addDirectory(directory); } diff --git a/Tests/com/drew/metadata/jpeg/HuffmanTablesDescriptorTest.java b/Tests/com/drew/metadata/jpeg/HuffmanTablesDescriptorTest.java index 19f59d273..16c138e90 100644 --- a/Tests/com/drew/metadata/jpeg/HuffmanTablesDescriptorTest.java +++ b/Tests/com/drew/metadata/jpeg/HuffmanTablesDescriptorTest.java @@ -20,6 +20,7 @@ */ package com.drew.metadata.jpeg; +import com.drew.metadata.MetadataContext; import org.junit.Before; import org.junit.Test; @@ -38,8 +39,9 @@ public class HuffmanTablesDescriptorTest @Before public void setUp() throws Exception { - _directory = new HuffmanTablesDirectory(); - _descriptor = new HuffmanTablesDescriptor(_directory); + MetadataContext context = new MetadataContext(); + _directory = new HuffmanTablesDirectory(context); + _descriptor = new HuffmanTablesDescriptor(_directory, context); } @Test diff --git a/Tests/com/drew/metadata/jpeg/JpegDhtReaderTest.java b/Tests/com/drew/metadata/jpeg/JpegDhtReaderTest.java index 97fdf58d9..2203ede5e 100644 --- a/Tests/com/drew/metadata/jpeg/JpegDhtReaderTest.java +++ b/Tests/com/drew/metadata/jpeg/JpegDhtReaderTest.java @@ -26,6 +26,7 @@ import com.drew.lang.SequentialByteArrayReader; import com.drew.lang.annotations.NotNull; import com.drew.metadata.Metadata; +import com.drew.metadata.MetadataContext; import com.drew.metadata.jpeg.HuffmanTablesDirectory.HuffmanTable.HuffmanTableClass; import org.junit.Before; import org.junit.Test; @@ -43,13 +44,14 @@ public class JpegDhtReaderTest public static HuffmanTablesDirectory processBytes(String filePath) throws Exception { Metadata metadata = new Metadata(); + MetadataContext context = new MetadataContext(); JpegSegmentData segmentData = JpegSegmentReader.readSegments( new File(filePath), Collections.singletonList(JpegSegmentType.DHT)); Iterable segments = segmentData.getSegments(JpegSegmentType.DHT); for (byte[] segment : segments) { - new JpegDhtReader().extract(new SequentialByteArrayReader(segment), metadata); + new JpegDhtReader().extract(new SequentialByteArrayReader(segment), metadata, context); } From dcae803c0ac1805188c83eeb09a07fc84b49e7ec Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 25 Jun 2021 12:49:36 +0200 Subject: [PATCH 21/34] Provide MetadataContext to JpegDnlReader extract method. --- Source/com/drew/metadata/jpeg/JpegDnlReader.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/com/drew/metadata/jpeg/JpegDnlReader.java b/Source/com/drew/metadata/jpeg/JpegDnlReader.java index 677ec0db2..249be6123 100644 --- a/Source/com/drew/metadata/jpeg/JpegDnlReader.java +++ b/Source/com/drew/metadata/jpeg/JpegDnlReader.java @@ -49,11 +49,11 @@ public Iterable getSegmentTypes() public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable MetadataContext context) { for (byte[] segmentBytes : segments) { - extract(segmentBytes, metadata, segmentType); + extract(segmentBytes, metadata, segmentType, context); } } - public void extract(byte[] segmentBytes, Metadata metadata, JpegSegmentType segmentType) + public void extract(byte[] segmentBytes, Metadata metadata, JpegSegmentType segmentType, MetadataContext context) { JpegDirectory directory = metadata.getFirstDirectoryOfType(JpegDirectory.class); if (directory == null) { From 88f8fa9fc4ab4972ff0657bd28a1b5325834f604 Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 25 Jun 2021 13:14:36 +0200 Subject: [PATCH 22/34] Provide MetadataContext to all JfifReader and related classes. --- Source/com/drew/metadata/jfif/JfifDescriptor.java | 13 ++++++++----- Source/com/drew/metadata/jfif/JfifDirectory.java | 5 +++-- Source/com/drew/metadata/jfif/JfifReader.java | 10 +++++++--- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/Source/com/drew/metadata/jfif/JfifDescriptor.java b/Source/com/drew/metadata/jfif/JfifDescriptor.java index 1ab9a2c3e..0d9e767ca 100644 --- a/Source/com/drew/metadata/jfif/JfifDescriptor.java +++ b/Source/com/drew/metadata/jfif/JfifDescriptor.java @@ -22,6 +22,7 @@ import com.drew.lang.annotations.NotNull; import com.drew.lang.annotations.Nullable; +import com.drew.metadata.MetadataContext; import com.drew.metadata.TagDescriptor; import static com.drew.metadata.jfif.JfifDirectory.*; @@ -39,9 +40,9 @@ @SuppressWarnings("WeakerAccess") public class JfifDescriptor extends TagDescriptor { - public JfifDescriptor(@NotNull JfifDirectory directory) + public JfifDescriptor(@NotNull JfifDirectory directory, @NotNull MetadataContext context) { - super(directory); + super(directory, context); } @Override @@ -68,7 +69,7 @@ public String getImageVersionDescription() Integer value = _directory.getInteger(TAG_VERSION); if (value==null) return null; - return String.format("%d.%d", (value & 0xFF00) >> 8, value & 0xFF); + return String.format(getContext().locale(), "%d.%d", (value & 0xFF00) >> 8, value & 0xFF); } @Nullable @@ -77,7 +78,8 @@ public String getImageResYDescription() Integer value = _directory.getInteger(TAG_RESY); if (value==null) return null; - return String.format("%d dot%s", + return String.format(getContext().locale(), + "%d dot%s", value, value==1 ? "" : "s"); } @@ -88,7 +90,8 @@ public String getImageResXDescription() Integer value = _directory.getInteger(TAG_RESX); if (value==null) return null; - return String.format("%d dot%s", + return String.format(getContext().locale(), + "%d dot%s", value, value==1 ? "" : "s"); } diff --git a/Source/com/drew/metadata/jfif/JfifDirectory.java b/Source/com/drew/metadata/jfif/JfifDirectory.java index b8ea3f87f..9f7f6ba83 100644 --- a/Source/com/drew/metadata/jfif/JfifDirectory.java +++ b/Source/com/drew/metadata/jfif/JfifDirectory.java @@ -22,6 +22,7 @@ import com.drew.lang.annotations.NotNull; import com.drew.metadata.Directory; +import com.drew.metadata.MetadataContext; import com.drew.metadata.MetadataException; import java.util.HashMap; @@ -55,9 +56,9 @@ public class JfifDirectory extends Directory _tagNameMap.put(TAG_THUMB_HEIGHT, "Thumbnail Height Pixels"); } - public JfifDirectory() + public JfifDirectory(@NotNull MetadataContext context) { - this.setDescriptor(new JfifDescriptor(this)); + this.setDescriptor(new JfifDescriptor(this, context)); } @Override diff --git a/Source/com/drew/metadata/jfif/JfifReader.java b/Source/com/drew/metadata/jfif/JfifReader.java index c7a4f9b07..c4f7a5266 100644 --- a/Source/com/drew/metadata/jfif/JfifReader.java +++ b/Source/com/drew/metadata/jfif/JfifReader.java @@ -58,17 +58,21 @@ public void readJpegSegments(@NotNull Iterable segments, @NotNull Metada for (byte[] segmentBytes : segments) { // Skip segments not starting with the required header if (segmentBytes.length >= PREAMBLE.length() && PREAMBLE.equals(new String(segmentBytes, 0, PREAMBLE.length()))) - extract(new ByteArrayReader(segmentBytes), metadata); + extract(new ByteArrayReader(segmentBytes), metadata, context); } } + public void extract(@NotNull final RandomAccessReader reader, @NotNull final Metadata metadata) { + extract(reader, metadata, new MetadataContext()); + } + /** * Performs the Jfif data extraction, adding found values to the specified * instance of {@link Metadata}. */ - public void extract(@NotNull final RandomAccessReader reader, @NotNull final Metadata metadata) + public void extract(@NotNull final RandomAccessReader reader, @NotNull final Metadata metadata, @NotNull final MetadataContext context) { - JfifDirectory directory = new JfifDirectory(); + JfifDirectory directory = new JfifDirectory(context); metadata.addDirectory(directory); try { From 1b1ed9d17c14babd51bae61e6b809bc7d1531d98 Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 25 Jun 2021 13:27:09 +0200 Subject: [PATCH 23/34] Provide MetadataContext to all IccReader and related classes. --- .../com/drew/metadata/icc/IccDescriptor.java | 25 ++++++++++--------- .../com/drew/metadata/icc/IccDirectory.java | 5 ++-- Source/com/drew/metadata/icc/IccReader.java | 17 +++++++++---- .../com/drew/metadata/icc/IccReaderTest.java | 7 ++++-- 4 files changed, 33 insertions(+), 21 deletions(-) diff --git a/Source/com/drew/metadata/icc/IccDescriptor.java b/Source/com/drew/metadata/icc/IccDescriptor.java index 98b11393c..26fb33c60 100644 --- a/Source/com/drew/metadata/icc/IccDescriptor.java +++ b/Source/com/drew/metadata/icc/IccDescriptor.java @@ -25,6 +25,7 @@ import com.drew.lang.RandomAccessReader; import com.drew.lang.annotations.NotNull; import com.drew.lang.annotations.Nullable; +import com.drew.metadata.MetadataContext; import com.drew.metadata.TagDescriptor; import java.io.IOException; @@ -40,9 +41,9 @@ @SuppressWarnings("WeakerAccess") public class IccDescriptor extends TagDescriptor { - public IccDescriptor(@NotNull IccDirectory directory) + public IccDescriptor(@NotNull IccDirectory directory, @NotNull MetadataContext context) { - super(directory); + super(directory, context); } @Override @@ -114,7 +115,7 @@ private String getTagDataString(int tagType) observerString = "1964 10\u00B0"; break; default: - observerString = String.format("Unknown %d", observerType); + observerString = String.format(getContext().locale(), "Unknown %d", observerType); } String geometryString; switch (geometryType) { @@ -128,7 +129,7 @@ private String getTagDataString(int tagType) geometryString = "0/d or d/0"; break; default: - geometryString = String.format("Unknown %d", observerType); + geometryString = String.format(getContext().locale(), "Unknown %d", observerType); } String illuminantString; switch (illuminantType) { @@ -160,16 +161,16 @@ private String getTagDataString(int tagType) illuminantString = "F8"; break; default: - illuminantString = String.format("Unknown %d", illuminantType); + illuminantString = String.format(getContext().locale(), "Unknown %d", illuminantType); break; } - DecimalFormat format = new DecimalFormat("0.###"); - return String.format("%s Observer, Backing (%s, %s, %s), Geometry %s, Flare %d%%, Illuminant %s", + DecimalFormat format = new DecimalFormat("0.###", getDecimalFormatSymbols(getContext().locale())); + return String.format(getContext().locale(), "%s Observer, Backing (%s, %s, %s), Geometry %s, Flare %d%%, Illuminant %s", observerString, format.format(x), format.format(y), format.format(z), geometryString, Math.round(flare * 100), illuminantString); } case ICC_TAG_TYPE_XYZ_ARRAY: { StringBuilder res = new StringBuilder(); - DecimalFormat format = new DecimalFormat("0.####"); + DecimalFormat format = new DecimalFormat("0.####", getDecimalFormatSymbols(getContext().locale())); int count = (bytes.length - 8) / 12; for (int i = 0; i < count; i++) { float x = reader.getS15Fixed16(8 + i * 12); @@ -214,7 +215,7 @@ private String getTagDataString(int tagType) return res.toString(); } default: - return String.format("%s (0x%08X): %d bytes", IccReader.getStringFromInt32(iccTagType), iccTagType, bytes.length); + return String.format(getContext().locale(), "%s (0x%08X): %d bytes", IccReader.getStringFromInt32(iccTagType), iccTagType, bytes.length); } } catch (IOException e) { // TODO decode these values during IccReader.extract so we can report any errors at that time @@ -281,7 +282,7 @@ private String getPlatformDescription() case 0x54474E54: return "Taligent, Inc."; default: - return String.format("Unknown (%s)", str); + return String.format(getContext().locale(), "Unknown (%s)", str); } } @@ -315,7 +316,7 @@ private String getProfileClassDescription() case 0x6E6D636C: return "Named Color"; default: - return String.format("Unknown (%s)", str); + return String.format(getContext().locale(), "Unknown (%s)", str); } } @@ -331,7 +332,7 @@ private String getProfileVersionDescription() int r = (value & 0x00F00000) >> 20; int R = (value & 0x000F0000) >> 16; - return String.format("%d.%d.%d", m, r, R); + return String.format(getContext().locale(), "%d.%d.%d", m, r, R); } private static int getInt32FromString(@NotNull String string) throws IOException diff --git a/Source/com/drew/metadata/icc/IccDirectory.java b/Source/com/drew/metadata/icc/IccDirectory.java index 4b25f5795..20ad369ac 100644 --- a/Source/com/drew/metadata/icc/IccDirectory.java +++ b/Source/com/drew/metadata/icc/IccDirectory.java @@ -22,6 +22,7 @@ import com.drew.lang.annotations.NotNull; import com.drew.metadata.Directory; +import com.drew.metadata.MetadataContext; import java.util.HashMap; @@ -187,9 +188,9 @@ public class IccDirectory extends Directory _tagNameMap.put(TAG_APPLE_MULTI_LANGUAGE_PROFILE_NAME, "Apple Multi-language Profile Name"); } - public IccDirectory() + public IccDirectory(@NotNull MetadataContext context) { - this.setDescriptor(new IccDescriptor(this)); + this.setDescriptor(new IccDescriptor(this, context)); } @Override diff --git a/Source/com/drew/metadata/icc/IccReader.java b/Source/com/drew/metadata/icc/IccReader.java index 745122225..0ff16f8cc 100644 --- a/Source/com/drew/metadata/icc/IccReader.java +++ b/Source/com/drew/metadata/icc/IccReader.java @@ -34,6 +34,7 @@ import java.io.IOException; import java.util.Collections; +import java.util.Locale; /** * Reads an ICC profile. @@ -87,7 +88,7 @@ public void readJpegSegments(@NotNull Iterable segments, @NotNull Metada } if (buffer != null) - extract(new ByteArrayReader(buffer), metadata); + extract(new ByteArrayReader(buffer), metadata, null, context); } public void extract(@NotNull final RandomAccessReader reader, @NotNull final Metadata metadata) @@ -96,10 +97,15 @@ public void extract(@NotNull final RandomAccessReader reader, @NotNull final Met } public void extract(@NotNull final RandomAccessReader reader, @NotNull final Metadata metadata, @Nullable Directory parentDirectory) + { + extract(reader, metadata, parentDirectory, new MetadataContext()); + } + + public void extract(@NotNull final RandomAccessReader reader, @NotNull final Metadata metadata, @Nullable Directory parentDirectory, @NotNull final MetadataContext context) { // TODO review whether the 'tagPtr' values below really do require RandomAccessReader or whether SequentialReader may be used instead - IccDirectory directory = new IccDirectory(); + IccDirectory directory = new IccDirectory(context); if (parentDirectory != null) directory.setParent(parentDirectory); @@ -114,7 +120,7 @@ public void extract(@NotNull final RandomAccessReader reader, @NotNull final Met set4ByteString(directory, IccDirectory.TAG_PROFILE_CLASS, reader); set4ByteString(directory, IccDirectory.TAG_COLOR_SPACE, reader); set4ByteString(directory, IccDirectory.TAG_PROFILE_CONNECTION_SPACE, reader); - setDate(directory, IccDirectory.TAG_PROFILE_DATETIME, reader); + setDate(directory, IccDirectory.TAG_PROFILE_DATETIME, reader, context.locale()); set4ByteString(directory, IccDirectory.TAG_SIGNATURE, reader); set4ByteString(directory, IccDirectory.TAG_PLATFORM, reader); setInt32(directory, IccDirectory.TAG_CMM_FLAGS, reader); @@ -181,7 +187,7 @@ private void setInt64(@NotNull Directory directory, int tagType, @NotNull Random } @SuppressWarnings({"SameParameterValue", "MagicConstant"}) - private void setDate(@NotNull final IccDirectory directory, final int tagType, @NotNull RandomAccessReader reader) throws IOException + private void setDate(@NotNull final IccDirectory directory, final int tagType, @NotNull RandomAccessReader reader, @NotNull Locale locale) throws IOException { final int y = reader.getUInt16(tagType); final int m = reader.getUInt16(tagType + 2); @@ -192,12 +198,13 @@ private void setDate(@NotNull final IccDirectory directory, final int tagType, @ if (DateUtil.isValidDate(y, m - 1, d) && DateUtil.isValidTime(h, M, s)) { - String dateString = String.format("%04d:%02d:%02d %02d:%02d:%02d", y, m, d, h, M, s); + String dateString = String.format(locale, "%04d:%02d:%02d %02d:%02d:%02d", y, m, d, h, M, s); directory.setString(tagType, dateString); } else { directory.addError(String.format( + locale, "ICC data describes an invalid date/time: year=%d month=%d day=%d hour=%d minute=%d second=%d", y, m, d, h, M, s)); } diff --git a/Tests/com/drew/metadata/icc/IccReaderTest.java b/Tests/com/drew/metadata/icc/IccReaderTest.java index c4a3b1c55..604d80072 100644 --- a/Tests/com/drew/metadata/icc/IccReaderTest.java +++ b/Tests/com/drew/metadata/icc/IccReaderTest.java @@ -24,6 +24,7 @@ import com.drew.imaging.jpeg.JpegSegmentType; import com.drew.lang.ByteArrayReader; import com.drew.metadata.Metadata; +import com.drew.metadata.MetadataContext; import com.drew.testing.TestHelper; import com.drew.tools.FileUtil; import org.junit.Test; @@ -62,7 +63,8 @@ public void testReadJpegSegments_InvalidData() throws Exception byte[] app2Bytes = FileUtil.readBytes("Tests/Data/iccDataInvalid1.jpg.app2"); Metadata metadata = new Metadata(); - new IccReader().readJpegSegments(Arrays.asList(app2Bytes), metadata, JpegSegmentType.APP2, null); + MetadataContext context = new MetadataContext(); + new IccReader().readJpegSegments(Arrays.asList(app2Bytes), metadata, JpegSegmentType.APP2, context); IccDirectory directory = metadata.getFirstDirectoryOfType(IccDirectory.class); @@ -76,7 +78,8 @@ public void testExtract_ProfileDateTime() throws Exception byte[] app2Bytes = FileUtil.readBytes("Tests/Data/withExifAndIptc.jpg.app2"); Metadata metadata = new Metadata(); - new IccReader().readJpegSegments(Arrays.asList(app2Bytes), metadata, JpegSegmentType.APP2, null); + MetadataContext context = new MetadataContext(); + new IccReader().readJpegSegments(Arrays.asList(app2Bytes), metadata, JpegSegmentType.APP2, context); IccDirectory directory = metadata.getFirstDirectoryOfType(IccDirectory.class); From 15e6bb7d6e0d2230da53ced70e49e1d1492bc5d0 Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 25 Jun 2021 13:29:46 +0200 Subject: [PATCH 24/34] Provide MetadataContext to all JfxxReader and related classes. --- Source/com/drew/metadata/jfxx/JfxxDescriptor.java | 5 +++-- Source/com/drew/metadata/jfxx/JfxxDirectory.java | 5 +++-- Source/com/drew/metadata/jfxx/JfxxReader.java | 12 +++++++++--- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/Source/com/drew/metadata/jfxx/JfxxDescriptor.java b/Source/com/drew/metadata/jfxx/JfxxDescriptor.java index 3623736cb..50aaa1d93 100644 --- a/Source/com/drew/metadata/jfxx/JfxxDescriptor.java +++ b/Source/com/drew/metadata/jfxx/JfxxDescriptor.java @@ -22,6 +22,7 @@ import com.drew.lang.annotations.NotNull; import com.drew.lang.annotations.Nullable; +import com.drew.metadata.MetadataContext; import com.drew.metadata.TagDescriptor; import static com.drew.metadata.jfxx.JfxxDirectory.*; @@ -39,9 +40,9 @@ @SuppressWarnings("WeakerAccess") public class JfxxDescriptor extends TagDescriptor { - public JfxxDescriptor(@NotNull JfxxDirectory directory) + public JfxxDescriptor(@NotNull JfxxDirectory directory, MetadataContext context) { - super(directory); + super(directory, context); } @Override diff --git a/Source/com/drew/metadata/jfxx/JfxxDirectory.java b/Source/com/drew/metadata/jfxx/JfxxDirectory.java index 7acbe1c3f..6fe5fb55a 100644 --- a/Source/com/drew/metadata/jfxx/JfxxDirectory.java +++ b/Source/com/drew/metadata/jfxx/JfxxDirectory.java @@ -22,6 +22,7 @@ import com.drew.lang.annotations.NotNull; import com.drew.metadata.Directory; +import com.drew.metadata.MetadataContext; import com.drew.metadata.MetadataException; import java.util.HashMap; @@ -44,9 +45,9 @@ public class JfxxDirectory extends Directory _tagNameMap.put(TAG_EXTENSION_CODE, "Extension Code"); } - public JfxxDirectory() + public JfxxDirectory(MetadataContext context) { - this.setDescriptor(new JfxxDescriptor(this)); + this.setDescriptor(new JfxxDescriptor(this, context)); } @Override diff --git a/Source/com/drew/metadata/jfxx/JfxxReader.java b/Source/com/drew/metadata/jfxx/JfxxReader.java index a814284ad..4078e31bf 100644 --- a/Source/com/drew/metadata/jfxx/JfxxReader.java +++ b/Source/com/drew/metadata/jfxx/JfxxReader.java @@ -58,17 +58,23 @@ public void readJpegSegments(@NotNull Iterable segments, @NotNull Metada for (byte[] segmentBytes : segments) { // Skip segments not starting with the required header if (segmentBytes.length >= PREAMBLE.length() && PREAMBLE.equals(new String(segmentBytes, 0, PREAMBLE.length()))) - extract(new ByteArrayReader(segmentBytes), metadata); + extract(new ByteArrayReader(segmentBytes), metadata, context); } } + @Override + public void extract(RandomAccessReader reader, Metadata metadata) + { + extract(reader, metadata, new MetadataContext()); + } + /** * Performs the JFXX data extraction, adding found values to the specified * instance of {@link Metadata}. */ - public void extract(@NotNull final RandomAccessReader reader, @NotNull final Metadata metadata) + public void extract(@NotNull final RandomAccessReader reader, @NotNull final Metadata metadata, @NotNull final MetadataContext context) { - JfxxDirectory directory = new JfxxDirectory(); + JfxxDirectory directory = new JfxxDirectory(context); metadata.addDirectory(directory); try { From a38da7876bf1f1580d59d45a0901c64a0a1cb954 Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 25 Jun 2021 13:39:47 +0200 Subject: [PATCH 25/34] Provide MetadataContext to all XmpReader and related classes. --- .../com/drew/metadata/xmp/XmpDescriptor.java | 5 +-- .../com/drew/metadata/xmp/XmpDirectory.java | 5 +-- Source/com/drew/metadata/xmp/XmpReader.java | 35 +++++++++++++------ 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/Source/com/drew/metadata/xmp/XmpDescriptor.java b/Source/com/drew/metadata/xmp/XmpDescriptor.java index 0158c61af..16887e1a4 100644 --- a/Source/com/drew/metadata/xmp/XmpDescriptor.java +++ b/Source/com/drew/metadata/xmp/XmpDescriptor.java @@ -21,6 +21,7 @@ package com.drew.metadata.xmp; import com.drew.lang.annotations.NotNull; +import com.drew.metadata.MetadataContext; import com.drew.metadata.TagDescriptor; /** @@ -32,8 +33,8 @@ @SuppressWarnings("WeakerAccess") public class XmpDescriptor extends TagDescriptor { - public XmpDescriptor(@NotNull XmpDirectory directory) + public XmpDescriptor(@NotNull XmpDirectory directory, MetadataContext context) { - super(directory); + super(directory, context); } } diff --git a/Source/com/drew/metadata/xmp/XmpDirectory.java b/Source/com/drew/metadata/xmp/XmpDirectory.java index 4824d5f74..ad0b5431c 100644 --- a/Source/com/drew/metadata/xmp/XmpDirectory.java +++ b/Source/com/drew/metadata/xmp/XmpDirectory.java @@ -29,6 +29,7 @@ import com.drew.lang.annotations.NotNull; import com.drew.lang.annotations.Nullable; import com.drew.metadata.Directory; +import com.drew.metadata.MetadataContext; import java.util.Collections; import java.util.HashMap; @@ -59,9 +60,9 @@ public class XmpDirectory extends Directory @Nullable private XMPMeta _xmpMeta; - public XmpDirectory() + public XmpDirectory(MetadataContext context) { - this.setDescriptor(new XmpDescriptor(this)); + this.setDescriptor(new XmpDescriptor(this, context)); } @Override diff --git a/Source/com/drew/metadata/xmp/XmpReader.java b/Source/com/drew/metadata/xmp/XmpReader.java index bb12b567f..aafa83d42 100644 --- a/Source/com/drew/metadata/xmp/XmpReader.java +++ b/Source/com/drew/metadata/xmp/XmpReader.java @@ -66,7 +66,7 @@ public class XmpReader implements JpegSegmentMetadataReader private static final String SCHEMA_XMP_NOTES = "http://ns.adobe.com/xmp/note/"; @NotNull private static final String ATTRIBUTE_EXTENDED_XMP = "xmpNote:HasExtendedXMP"; - // Limit photoshop:DocumentAncestors node as it can reach over 100000 items and make parsing extremely slow. + // Limit photoshop:DocumentAncestors node as it can reach over 100000 items and make parsing extremely slow. // This is not a typical value but it may happen https://forums.adobe.com/thread/2081839 @NotNull private static final ParseOptions PARSE_OPTIONS = new ParseOptions().setXMPNodesToLimit(Collections.singletonMap("photoshop:DocumentAncestors", 1000)); @@ -121,7 +121,7 @@ public void readJpegSegments(@NotNull Iterable segments, @NotNull Metada segmentBytes.length >= extensionPreambleLength && XMP_EXTENSION_JPEG_PREAMBLE.equalsIgnoreCase(new String(segmentBytes, 0, extensionPreambleLength))) { - extendedXMPBuffer = processExtendedXMPChunk(metadata, segmentBytes, extendedXMPGUID, extendedXMPBuffer); + extendedXMPBuffer = processExtendedXMPChunk(metadata, segmentBytes, extendedXMPGUID, extendedXMPBuffer, context); } } @@ -148,7 +148,8 @@ public void extract(@NotNull final byte[] xmpBytes, @NotNull Metadata metadata) */ public void extract(@NotNull final byte[] xmpBytes, @NotNull Metadata metadata, @Nullable Directory parentDirectory) { - extract(xmpBytes, 0, xmpBytes.length, metadata, parentDirectory); + // TODO document this default context? + extract(xmpBytes, 0, xmpBytes.length, metadata, parentDirectory, new MetadataContext()); } /** @@ -158,7 +159,18 @@ public void extract(@NotNull final byte[] xmpBytes, @NotNull Metadata metadata, */ public void extract(@NotNull final byte[] xmpBytes, int offset, int length, @NotNull Metadata metadata, @Nullable Directory parentDirectory) { - XmpDirectory directory = new XmpDirectory(); + // TODO document this default context? + extract(xmpBytes, offset, length, metadata, parentDirectory, new MetadataContext()); + } + + /** + * Performs the XMP data extraction, adding found values to the specified instance of {@link Metadata}. + *

+ * The extraction is done with Adobe's XMPCore library. + */ + public void extract(@NotNull final byte[] xmpBytes, int offset, int length, @NotNull Metadata metadata, @Nullable Directory parentDirectory, @NotNull MetadataContext context) + { + XmpDirectory directory = new XmpDirectory(context); if (parentDirectory != null) directory.setParent(parentDirectory); @@ -190,7 +202,8 @@ public void extract(@NotNull final byte[] xmpBytes, int offset, int length, @Not */ public void extract(@NotNull final String xmpString, @NotNull Metadata metadata) { - extract(xmpString, metadata, null); + // TODO document this default context? + extract(xmpString, metadata, null, new MetadataContext()); } /** @@ -208,9 +221,9 @@ public void extract(@NotNull final StringValue xmpString, @NotNull Metadata meta *

* The extraction is done with Adobe's XMPCore library. */ - public void extract(@NotNull final String xmpString, @NotNull Metadata metadata, @Nullable Directory parentDirectory) + public void extract(@NotNull final String xmpString, @NotNull Metadata metadata, @Nullable Directory parentDirectory, @NotNull MetadataContext context) { - XmpDirectory directory = new XmpDirectory(); + XmpDirectory directory = new XmpDirectory(context); if (parentDirectory != null) directory.setParent(parentDirectory); @@ -265,7 +278,7 @@ private static String getExtendedXMPGUID(@NotNull Metadata metadata) * at page 19 */ @Nullable - private static byte[] processExtendedXMPChunk(@NotNull Metadata metadata, @NotNull byte[] segmentBytes, @NotNull String extendedXMPGUID, @Nullable byte[] extendedXMPBuffer) + private static byte[] processExtendedXMPChunk(@NotNull Metadata metadata, @NotNull byte[] segmentBytes, @NotNull String extendedXMPGUID, @Nullable byte[] extendedXMPBuffer, MetadataContext context) { final int extensionPreambleLength = XMP_EXTENSION_JPEG_PREAMBLE.length(); final int segmentLength = segmentBytes.length; @@ -296,13 +309,13 @@ private static byte[] processExtendedXMPChunk(@NotNull Metadata metadata, @NotNu if (extendedXMPBuffer.length == fullLength) { System.arraycopy(segmentBytes, totalOffset, extendedXMPBuffer, chunkOffset, segmentLength - totalOffset); } else { - XmpDirectory directory = new XmpDirectory(); - directory.addError(String.format("Inconsistent length for the Extended XMP buffer: %d instead of %d", fullLength, extendedXMPBuffer.length)); + XmpDirectory directory = new XmpDirectory(context); + directory.addError(String.format(context.locale(), "Inconsistent length for the Extended XMP buffer: %d instead of %d", fullLength, extendedXMPBuffer.length)); metadata.addDirectory(directory); } } } catch (IOException ex) { - XmpDirectory directory = new XmpDirectory(); + XmpDirectory directory = new XmpDirectory(context); directory.addError(ex.getMessage()); metadata.addDirectory(directory); } From 6d9c38df0c6d1f8ee008e85edd474a4f29c81cb9 Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 25 Jun 2021 13:59:30 +0200 Subject: [PATCH 26/34] Provide MetadataContext to all PhotoshopReader and related classes. --- .../photoshop/PhotoshopDescriptor.java | 29 ++++++++++--------- .../photoshop/PhotoshopDirectory.java | 5 ++-- .../metadata/photoshop/PhotoshopReader.java | 26 ++++++++++++----- Source/com/drew/metadata/xmp/XmpReader.java | 12 +++++++- 4 files changed, 48 insertions(+), 24 deletions(-) diff --git a/Source/com/drew/metadata/photoshop/PhotoshopDescriptor.java b/Source/com/drew/metadata/photoshop/PhotoshopDescriptor.java index 9977994f5..76a5873a1 100644 --- a/Source/com/drew/metadata/photoshop/PhotoshopDescriptor.java +++ b/Source/com/drew/metadata/photoshop/PhotoshopDescriptor.java @@ -25,6 +25,7 @@ import com.drew.lang.RandomAccessReader; import com.drew.lang.annotations.NotNull; import com.drew.lang.annotations.Nullable; +import com.drew.metadata.MetadataContext; import com.drew.metadata.TagDescriptor; import java.io.IOException; @@ -41,9 +42,9 @@ @SuppressWarnings("WeakerAccess") public class PhotoshopDescriptor extends TagDescriptor { - public PhotoshopDescriptor(@NotNull PhotoshopDirectory directory) + public PhotoshopDescriptor(@NotNull PhotoshopDirectory directory, MetadataContext context) { - super(directory); + super(directory, context); } @Override @@ -144,14 +145,14 @@ public String getJpegQualityString() format = "Progressive"; break; default: - format = String.format("Unknown 0x%04X", f); + format = String.format(getContext().locale(), "Unknown 0x%04X", f); } String scans = s >= 1 && s <= 3 - ? String.format("%d", s + 2) - : String.format("Unknown 0x%04X", s); + ? String.format(getContext().locale(), "%d", s + 2) + : String.format(getContext().locale(), "Unknown 0x%04X", s); - return String.format("%d (%s), %s format, %s scans", q1, quality, format, scans); + return String.format(getContext().locale(), "%d (%s), %s format, %s scans", q1, quality, format, scans); } catch (IOException e) { return null; } @@ -190,9 +191,9 @@ public String getPrintScaleDescription() case 1: return "Size to fit"; case 2: - return String.format("User defined, X:%s Y:%s, Scale:%s", locX, locY, scale); + return String.format(getContext().locale(), "User defined, X:%s Y:%s, Scale:%s", locX, locY, scale); default: - return String.format("Unknown %04X, X:%s Y:%s, Scale:%s", style, locX, locY, scale); + return String.format(getContext().locale(), "Unknown %04X, X:%s Y:%s, Scale:%s", style, locX, locY, scale); } } catch (Exception e) { return null; @@ -209,7 +210,7 @@ public String getResolutionInfoDescription() RandomAccessReader reader = new ByteArrayReader(bytes); float resX = reader.getS15Fixed16(0); float resY = reader.getS15Fixed16(8); // is this the correct offset? it's only reading 4 bytes each time - DecimalFormat format = new DecimalFormat("0.##"); + DecimalFormat format = new DecimalFormat("0.##", getDecimalFormatSymbols(getContext().locale())); return format.format(resX) + "x" + format.format(resY) + " DPI"; } catch (Exception e) { return null; @@ -237,7 +238,7 @@ public String getVersionDescription() String writerStr = reader.getString(pos, writerLength * 2, "UTF-16"); pos += writerLength * 2; int fileVersion = reader.getInt32(pos); - return String.format("%d (%s, %s) %d", ver, readerStr, writerStr, fileVersion); + return String.format(getContext().locale(), "%d (%s, %s) %d", ver, readerStr, writerStr, fileVersion); } catch (IOException e) { return null; } @@ -255,7 +256,7 @@ public String getSlicesDescription() String name = reader.getString(24, nameLength * 2, "UTF-16"); int pos = 24 + nameLength * 2; int sliceCount = reader.getInt32(pos); - return String.format("%s (%d,%d,%d,%d) %d Slices", + return String.format(getContext().locale(), "%s (%d,%d,%d,%d) %d Slices", name, reader.getInt32(4), reader.getInt32(8), reader.getInt32(12), reader.getInt32(16), sliceCount); } catch (IOException e) { return null; @@ -278,7 +279,7 @@ public String getThumbnailDescription(int tagType) int compSize = reader.getInt32(20); int bpp = reader.getInt32(24); //skip Number of planes - return String.format("%s, %dx%d, Decomp %d bytes, %d bpp, %d bytes", + return String.format(getContext().locale(), "%s, %dx%d, Decomp %d bytes, %d bpp, %d bytes", format == 1 ? "JpegRGB" : "RawRGB", width, height, totalSize, bpp, compSize); } catch (IOException e) { @@ -303,7 +304,7 @@ private String get32BitNumberString(int tag) return null; RandomAccessReader reader = new ByteArrayReader(bytes); try { - return String.format("%d", reader.getInt32(0)); + return String.format(getContext().locale(), "%d", reader.getInt32(0)); } catch (IOException e) { return null; } @@ -324,7 +325,7 @@ private String getBinaryDataString(int tagType) final byte[] bytes = _directory.getByteArray(tagType); if (bytes == null) return null; - return String.format("%d bytes binary data", bytes.length); + return String.format(getContext().locale(), "%d bytes binary data", bytes.length); } @Nullable diff --git a/Source/com/drew/metadata/photoshop/PhotoshopDirectory.java b/Source/com/drew/metadata/photoshop/PhotoshopDirectory.java index cc03e82b0..3dabcc49b 100644 --- a/Source/com/drew/metadata/photoshop/PhotoshopDirectory.java +++ b/Source/com/drew/metadata/photoshop/PhotoshopDirectory.java @@ -24,6 +24,7 @@ import com.drew.lang.annotations.NotNull; import com.drew.lang.annotations.Nullable; import com.drew.metadata.Directory; +import com.drew.metadata.MetadataContext; import java.util.HashMap; @@ -224,9 +225,9 @@ public class PhotoshopDirectory extends Directory _tagNameMap.put(TAG_PRINT_FLAGS_INFO, "Print Flags Information"); } - public PhotoshopDirectory() + public PhotoshopDirectory(MetadataContext context) { - this.setDescriptor(new PhotoshopDescriptor(this)); + this.setDescriptor(new PhotoshopDescriptor(this, context)); } @Override diff --git a/Source/com/drew/metadata/photoshop/PhotoshopReader.java b/Source/com/drew/metadata/photoshop/PhotoshopReader.java index 8279225e5..e8fd7d6af 100644 --- a/Source/com/drew/metadata/photoshop/PhotoshopReader.java +++ b/Source/com/drew/metadata/photoshop/PhotoshopReader.java @@ -71,18 +71,30 @@ public void readJpegSegments(@NotNull Iterable segments, @NotNull Metada extract( new SequentialByteArrayReader(segmentBytes, preambleLength + 1), segmentBytes.length - preambleLength - 1, - metadata); + metadata, + context); } } public void extract(@NotNull final SequentialReader reader, int length, @NotNull final Metadata metadata) { - extract(reader, length, metadata, null); + extract(reader, length, metadata, null, null); } public void extract(@NotNull final SequentialReader reader, int length, @NotNull final Metadata metadata, @Nullable final Directory parentDirectory) { - PhotoshopDirectory directory = new PhotoshopDirectory(); + // TODO document this default context? + extract(reader, length, metadata, parentDirectory, new MetadataContext()); + } + + public void extract(@NotNull final SequentialReader reader, int length, @NotNull final Metadata metadata, @NotNull MetadataContext context) + { + extract(reader, length, metadata, null, context); + } + + public void extract(@NotNull final SequentialReader reader, int length, @NotNull final Metadata metadata, @Nullable final Directory parentDirectory, @NotNull MetadataContext context) + { + PhotoshopDirectory directory = new PhotoshopDirectory(context); metadata.addDirectory(directory); if (parentDirectory != null) @@ -148,11 +160,11 @@ public void extract(@NotNull final SequentialReader reader, int length, @NotNull if (tagType == PhotoshopDirectory.TAG_IPTC) new IptcReader().extract(new SequentialByteArrayReader(tagBytes), metadata, tagBytes.length, directory); else if (tagType == PhotoshopDirectory.TAG_ICC_PROFILE_BYTES) - new IccReader().extract(new ByteArrayReader(tagBytes), metadata, directory); + new IccReader().extract(new ByteArrayReader(tagBytes), metadata, directory, context); else if (tagType == PhotoshopDirectory.TAG_EXIF_DATA_1 || tagType == PhotoshopDirectory.TAG_EXIF_DATA_3) - new ExifReader().extract(new ByteArrayReader(tagBytes), metadata, 0, directory); + new ExifReader().extract(new ByteArrayReader(tagBytes), metadata, 0, directory, context); else if (tagType == PhotoshopDirectory.TAG_XMP_DATA) - new XmpReader().extract(tagBytes, metadata, directory); + new XmpReader().extract(tagBytes, metadata, directory, context); else if (tagType >= 0x07D0 && tagType <= 0x0BB6) { clippingPathCount++; tagBytes = Arrays.copyOf(tagBytes, tagBytes.length + description.length() + 1); @@ -170,7 +182,7 @@ else if (tagType >= 0x07D0 && tagType <= 0x0BB6) { directory.setByteArray(tagType, tagBytes); if (tagType >= 0x0fa0 && tagType <= 0x1387) - PhotoshopDirectory._tagNameMap.put(tagType, String.format("Plug-in %d Data", tagType - 0x0fa0 + 1)); + PhotoshopDirectory._tagNameMap.put(tagType, String.format(context.locale(), "Plug-in %d Data", tagType - 0x0fa0 + 1)); } } catch (Exception ex) { directory.addError(ex.getMessage()); diff --git a/Source/com/drew/metadata/xmp/XmpReader.java b/Source/com/drew/metadata/xmp/XmpReader.java index aafa83d42..83a1ecb52 100644 --- a/Source/com/drew/metadata/xmp/XmpReader.java +++ b/Source/com/drew/metadata/xmp/XmpReader.java @@ -149,7 +149,17 @@ public void extract(@NotNull final byte[] xmpBytes, @NotNull Metadata metadata) public void extract(@NotNull final byte[] xmpBytes, @NotNull Metadata metadata, @Nullable Directory parentDirectory) { // TODO document this default context? - extract(xmpBytes, 0, xmpBytes.length, metadata, parentDirectory, new MetadataContext()); + extract(xmpBytes, metadata, parentDirectory, new MetadataContext()); + } + + /** + * Performs the XMP data extraction, adding found values to the specified instance of {@link Metadata}. + *

+ * The extraction is done with Adobe's XMPCore library. + */ + public void extract(@NotNull final byte[] xmpBytes, @NotNull Metadata metadata, @Nullable Directory parentDirectory, @NotNull MetadataContext context) + { + extract(xmpBytes, 0, xmpBytes.length, metadata, parentDirectory, context); } /** From 0e3655b446cb7cdeb16456751bba5347135e2dab Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 25 Jun 2021 14:11:09 +0200 Subject: [PATCH 27/34] Make MetadataContext @NotNull instead of @Nullable in JpegSegmentMetadataReader#readJpegSegments. --- .../drew/imaging/jpeg/JpegMetadataReader.java | 3 +-- .../jpeg/JpegSegmentMetadataReader.java | 2 +- .../drew/metadata/adobe/AdobeJpegReader.java | 2 +- Source/com/drew/metadata/exif/ExifReader.java | 2 +- Source/com/drew/metadata/icc/IccReader.java | 2 +- Source/com/drew/metadata/iptc/IptcReader.java | 2 +- Source/com/drew/metadata/jfif/JfifReader.java | 2 +- Source/com/drew/metadata/jfxx/JfxxReader.java | 2 +- .../drew/metadata/jpeg/JpegCommentReader.java | 2 +- .../com/drew/metadata/jpeg/JpegDhtReader.java | 2 +- .../com/drew/metadata/jpeg/JpegDnlReader.java | 2 +- Source/com/drew/metadata/jpeg/JpegReader.java | 2 +- .../metadata/photoshop/PhotoshopReader.java | 2 +- Source/com/drew/metadata/xmp/XmpReader.java | 21 ++++++++++++++----- 14 files changed, 29 insertions(+), 19 deletions(-) diff --git a/Source/com/drew/imaging/jpeg/JpegMetadataReader.java b/Source/com/drew/imaging/jpeg/JpegMetadataReader.java index 9a0743ad0..9cbbee0c3 100644 --- a/Source/com/drew/imaging/jpeg/JpegMetadataReader.java +++ b/Source/com/drew/imaging/jpeg/JpegMetadataReader.java @@ -154,8 +154,7 @@ public static void process(@NotNull Metadata metadata, @NotNull InputStream inpu } // TODO create method with original signature for backwards compatibility - // TODO consider @NotNull / @Nullable annotations - public static void processJpegSegmentData(Metadata metadata, Iterable readers, JpegSegmentData segmentData, MetadataContext context) + public static void processJpegSegmentData(@NotNull Metadata metadata, @NotNull Iterable readers, @NotNull JpegSegmentData segmentData, @NotNull MetadataContext context) { // Pass the appropriate byte arrays to each reader. for (JpegSegmentMetadataReader reader : readers) { diff --git a/Source/com/drew/imaging/jpeg/JpegSegmentMetadataReader.java b/Source/com/drew/imaging/jpeg/JpegSegmentMetadataReader.java index 481c40ad9..4586d4334 100644 --- a/Source/com/drew/imaging/jpeg/JpegSegmentMetadataReader.java +++ b/Source/com/drew/imaging/jpeg/JpegSegmentMetadataReader.java @@ -25,5 +25,5 @@ public interface JpegSegmentMetadataReader * @param segmentType The {@link JpegSegmentType} being read. * @param context The {@link MetadataContext} to use for parsing and formatting. */ - void readJpegSegments(@NotNull final Iterable segments, @NotNull final Metadata metadata, @NotNull final JpegSegmentType segmentType, @Nullable MetadataContext context); + void readJpegSegments(@NotNull final Iterable segments, @NotNull final Metadata metadata, @NotNull final JpegSegmentType segmentType, @NotNull MetadataContext context); } diff --git a/Source/com/drew/metadata/adobe/AdobeJpegReader.java b/Source/com/drew/metadata/adobe/AdobeJpegReader.java index 2e6ca656a..733cf24c4 100644 --- a/Source/com/drew/metadata/adobe/AdobeJpegReader.java +++ b/Source/com/drew/metadata/adobe/AdobeJpegReader.java @@ -51,7 +51,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APPE); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable MetadataContext context) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @NotNull MetadataContext context) { for (byte[] bytes : segments) { if (bytes.length == 12 && PREAMBLE.equalsIgnoreCase(new String(bytes, 0, PREAMBLE.length()))) diff --git a/Source/com/drew/metadata/exif/ExifReader.java b/Source/com/drew/metadata/exif/ExifReader.java index 5be311f78..9905368e0 100644 --- a/Source/com/drew/metadata/exif/ExifReader.java +++ b/Source/com/drew/metadata/exif/ExifReader.java @@ -54,7 +54,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APP1); } - public void readJpegSegments(@NotNull final Iterable segments, @NotNull final Metadata metadata, @NotNull final JpegSegmentType segmentType, @Nullable MetadataContext context) + public void readJpegSegments(@NotNull final Iterable segments, @NotNull final Metadata metadata, @NotNull final JpegSegmentType segmentType, @NotNull MetadataContext context) { assert(segmentType == JpegSegmentType.APP1); diff --git a/Source/com/drew/metadata/icc/IccReader.java b/Source/com/drew/metadata/icc/IccReader.java index 0ff16f8cc..820260f0a 100644 --- a/Source/com/drew/metadata/icc/IccReader.java +++ b/Source/com/drew/metadata/icc/IccReader.java @@ -59,7 +59,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APP2); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable MetadataContext context) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @NotNull MetadataContext context) { final int preambleLength = JPEG_SEGMENT_PREAMBLE.length(); diff --git a/Source/com/drew/metadata/iptc/IptcReader.java b/Source/com/drew/metadata/iptc/IptcReader.java index fe7e20ece..e80893954 100644 --- a/Source/com/drew/metadata/iptc/IptcReader.java +++ b/Source/com/drew/metadata/iptc/IptcReader.java @@ -66,7 +66,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APPD); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable MetadataContext context) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @NotNull MetadataContext context) { for (byte[] segmentBytes : segments) { // Ensure data starts with the IPTC marker byte diff --git a/Source/com/drew/metadata/jfif/JfifReader.java b/Source/com/drew/metadata/jfif/JfifReader.java index c4f7a5266..5aba7a8ad 100644 --- a/Source/com/drew/metadata/jfif/JfifReader.java +++ b/Source/com/drew/metadata/jfif/JfifReader.java @@ -53,7 +53,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APP0); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable MetadataContext context) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @NotNull MetadataContext context) { for (byte[] segmentBytes : segments) { // Skip segments not starting with the required header diff --git a/Source/com/drew/metadata/jfxx/JfxxReader.java b/Source/com/drew/metadata/jfxx/JfxxReader.java index 4078e31bf..f86407192 100644 --- a/Source/com/drew/metadata/jfxx/JfxxReader.java +++ b/Source/com/drew/metadata/jfxx/JfxxReader.java @@ -53,7 +53,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APP0); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable MetadataContext context) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @NotNull MetadataContext context) { for (byte[] segmentBytes : segments) { // Skip segments not starting with the required header diff --git a/Source/com/drew/metadata/jpeg/JpegCommentReader.java b/Source/com/drew/metadata/jpeg/JpegCommentReader.java index ab0e2dfb0..3c4ee4f9f 100644 --- a/Source/com/drew/metadata/jpeg/JpegCommentReader.java +++ b/Source/com/drew/metadata/jpeg/JpegCommentReader.java @@ -44,7 +44,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.COM); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable MetadataContext context) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @NotNull MetadataContext context) { for (byte[] segmentBytes : segments) { JpegCommentDirectory directory = new JpegCommentDirectory(context); diff --git a/Source/com/drew/metadata/jpeg/JpegDhtReader.java b/Source/com/drew/metadata/jpeg/JpegDhtReader.java index 79f688bff..d8eeb96b6 100644 --- a/Source/com/drew/metadata/jpeg/JpegDhtReader.java +++ b/Source/com/drew/metadata/jpeg/JpegDhtReader.java @@ -46,7 +46,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.DHT); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable MetadataContext context) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @NotNull MetadataContext context) { for (byte[] segmentBytes : segments) { extract(new SequentialByteArrayReader(segmentBytes), metadata, context); diff --git a/Source/com/drew/metadata/jpeg/JpegDnlReader.java b/Source/com/drew/metadata/jpeg/JpegDnlReader.java index 249be6123..0cace4fc7 100644 --- a/Source/com/drew/metadata/jpeg/JpegDnlReader.java +++ b/Source/com/drew/metadata/jpeg/JpegDnlReader.java @@ -46,7 +46,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.DNL); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable MetadataContext context) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @NotNull MetadataContext context) { for (byte[] segmentBytes : segments) { extract(segmentBytes, metadata, segmentType, context); diff --git a/Source/com/drew/metadata/jpeg/JpegReader.java b/Source/com/drew/metadata/jpeg/JpegReader.java index 4ca9d2f39..973f69f02 100644 --- a/Source/com/drew/metadata/jpeg/JpegReader.java +++ b/Source/com/drew/metadata/jpeg/JpegReader.java @@ -64,7 +64,7 @@ public Iterable getSegmentTypes() ); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable MetadataContext context) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @NotNull MetadataContext context) { for (byte[] segmentBytes : segments) { extract(segmentBytes, metadata, segmentType, context); diff --git a/Source/com/drew/metadata/photoshop/PhotoshopReader.java b/Source/com/drew/metadata/photoshop/PhotoshopReader.java index e8fd7d6af..fa3ecff5f 100644 --- a/Source/com/drew/metadata/photoshop/PhotoshopReader.java +++ b/Source/com/drew/metadata/photoshop/PhotoshopReader.java @@ -59,7 +59,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APPD); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable MetadataContext context) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @NotNull MetadataContext context) { final int preambleLength = JPEG_SEGMENT_PREAMBLE.length(); diff --git a/Source/com/drew/metadata/xmp/XmpReader.java b/Source/com/drew/metadata/xmp/XmpReader.java index 83a1ecb52..fe12249e8 100644 --- a/Source/com/drew/metadata/xmp/XmpReader.java +++ b/Source/com/drew/metadata/xmp/XmpReader.java @@ -91,7 +91,7 @@ public Iterable getSegmentTypes() * @param segmentType The {@link JpegSegmentType} being read. * @param context The {@link MetadataContext} to use for parsing and formatting. */ - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable MetadataContext context) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @NotNull MetadataContext context) { final int preambleLength = XMP_JPEG_PREAMBLE.length(); final int extensionPreambleLength = XMP_EXTENSION_JPEG_PREAMBLE.length(); @@ -127,7 +127,7 @@ public void readJpegSegments(@NotNull Iterable segments, @NotNull Metada // Now that the Extended XMP chunks have been concatenated, let's parse and merge with the Standard XMP. if (extendedXMPBuffer != null) { - extract(extendedXMPBuffer, metadata); + extract(extendedXMPBuffer, metadata, context); } } @@ -138,7 +138,7 @@ public void readJpegSegments(@NotNull Iterable segments, @NotNull Metada */ public void extract(@NotNull final byte[] xmpBytes, @NotNull Metadata metadata) { - extract(xmpBytes, metadata, null); + extract(xmpBytes, metadata, null, null); } /** @@ -152,6 +152,17 @@ public void extract(@NotNull final byte[] xmpBytes, @NotNull Metadata metadata, extract(xmpBytes, metadata, parentDirectory, new MetadataContext()); } + /** + * Performs the XMP data extraction, adding found values to the specified instance of {@link Metadata}. + *

+ * The extraction is done with Adobe's XMPCore library. + */ + public void extract(@NotNull final byte[] xmpBytes, @NotNull Metadata metadata, @NotNull MetadataContext context) + { + // TODO document this default context? + extract(xmpBytes, metadata, null, context); + } + /** * Performs the XMP data extraction, adding found values to the specified instance of {@link Metadata}. *

@@ -223,7 +234,7 @@ public void extract(@NotNull final String xmpString, @NotNull Metadata metadata) */ public void extract(@NotNull final StringValue xmpString, @NotNull Metadata metadata) { - extract(xmpString.getBytes(), metadata, null); + extract(xmpString.getBytes(), metadata, null, null); } /** @@ -288,7 +299,7 @@ private static String getExtendedXMPGUID(@NotNull Metadata metadata) * at page 19 */ @Nullable - private static byte[] processExtendedXMPChunk(@NotNull Metadata metadata, @NotNull byte[] segmentBytes, @NotNull String extendedXMPGUID, @Nullable byte[] extendedXMPBuffer, MetadataContext context) + private static byte[] processExtendedXMPChunk(@NotNull Metadata metadata, @NotNull byte[] segmentBytes, @NotNull String extendedXMPGUID, @Nullable byte[] extendedXMPBuffer, @NotNull MetadataContext context) { final int extensionPreambleLength = XMP_EXTENSION_JPEG_PREAMBLE.length(); final int segmentLength = segmentBytes.length; From 17f839c00bab0287c911f7c1fba37d0aed9c4dbe Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 25 Jun 2021 14:11:39 +0200 Subject: [PATCH 28/34] Provide MetadataContext to all DuckyReader and related classes. --- Source/com/drew/metadata/photoshop/DuckyDirectory.java | 5 +++-- Source/com/drew/metadata/photoshop/DuckyReader.java | 9 +++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Source/com/drew/metadata/photoshop/DuckyDirectory.java b/Source/com/drew/metadata/photoshop/DuckyDirectory.java index 9c6d69050..9edd58c7b 100644 --- a/Source/com/drew/metadata/photoshop/DuckyDirectory.java +++ b/Source/com/drew/metadata/photoshop/DuckyDirectory.java @@ -23,6 +23,7 @@ import com.drew.lang.annotations.NotNull; import com.drew.metadata.Directory; +import com.drew.metadata.MetadataContext; import com.drew.metadata.TagDescriptor; import java.util.HashMap; @@ -48,9 +49,9 @@ public class DuckyDirectory extends Directory _tagNameMap.put(TAG_COPYRIGHT, "Copyright"); } - public DuckyDirectory() + public DuckyDirectory(@NotNull MetadataContext context) { - this.setDescriptor(new TagDescriptor(this)); + this.setDescriptor(new TagDescriptor(this, context)); } @Override diff --git a/Source/com/drew/metadata/photoshop/DuckyReader.java b/Source/com/drew/metadata/photoshop/DuckyReader.java index 661ba7868..f0cca387d 100644 --- a/Source/com/drew/metadata/photoshop/DuckyReader.java +++ b/Source/com/drew/metadata/photoshop/DuckyReader.java @@ -50,7 +50,7 @@ public Iterable getSegmentTypes() return Collections.singletonList(JpegSegmentType.APPC); } - public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @Nullable MetadataContext context) + public void readJpegSegments(@NotNull Iterable segments, @NotNull Metadata metadata, @NotNull JpegSegmentType segmentType, @NotNull MetadataContext context) { final int preambleLength = JPEG_SEGMENT_PREAMBLE.length(); @@ -61,13 +61,14 @@ public void readJpegSegments(@NotNull Iterable segments, @NotNull Metada extract( new SequentialByteArrayReader(segmentBytes, preambleLength), - metadata); + metadata, + context); } } - public void extract(@NotNull final SequentialReader reader, @NotNull final Metadata metadata) + public void extract(@NotNull final SequentialReader reader, @NotNull final Metadata metadata, @NotNull MetadataContext context) { - DuckyDirectory directory = new DuckyDirectory(); + DuckyDirectory directory = new DuckyDirectory(context); metadata.addDirectory(directory); try From f8035fb0c963799b3c6b3a50698bbde638c8b849 Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 25 Jun 2021 14:19:34 +0200 Subject: [PATCH 29/34] Provide MetadataContext to all IptcReader and related classes. --- .../drew/metadata/iptc/IptcDescriptor.java | 5 ++-- .../com/drew/metadata/iptc/IptcDirectory.java | 5 ++-- Source/com/drew/metadata/iptc/IptcReader.java | 24 ++++++++++++++++--- .../metadata/photoshop/PhotoshopReader.java | 2 +- .../drew/metadata/iptc/IptcDirectoryTest.java | 4 +++- 5 files changed, 31 insertions(+), 9 deletions(-) diff --git a/Source/com/drew/metadata/iptc/IptcDescriptor.java b/Source/com/drew/metadata/iptc/IptcDescriptor.java index 139d15b2a..b57b0e17e 100644 --- a/Source/com/drew/metadata/iptc/IptcDescriptor.java +++ b/Source/com/drew/metadata/iptc/IptcDescriptor.java @@ -23,6 +23,7 @@ import com.drew.lang.StringUtil; import com.drew.lang.annotations.NotNull; import com.drew.lang.annotations.Nullable; +import com.drew.metadata.MetadataContext; import com.drew.metadata.TagDescriptor; import static com.drew.metadata.iptc.IptcDirectory.*; @@ -37,9 +38,9 @@ @SuppressWarnings("WeakerAccess") public class IptcDescriptor extends TagDescriptor { - public IptcDescriptor(@NotNull IptcDirectory directory) + public IptcDescriptor(@NotNull IptcDirectory directory, @NotNull MetadataContext context) { - super(directory); + super(directory, context); } @Override diff --git a/Source/com/drew/metadata/iptc/IptcDirectory.java b/Source/com/drew/metadata/iptc/IptcDirectory.java index 626e6070a..1816339b7 100644 --- a/Source/com/drew/metadata/iptc/IptcDirectory.java +++ b/Source/com/drew/metadata/iptc/IptcDirectory.java @@ -23,6 +23,7 @@ import com.drew.lang.annotations.NotNull; import com.drew.lang.annotations.Nullable; import com.drew.metadata.Directory; +import com.drew.metadata.MetadataContext; import java.text.DateFormat; import java.text.ParseException; @@ -210,9 +211,9 @@ public class IptcDirectory extends Directory _tagNameMap.put(TAG_OBJECT_PREVIEW_DATA, "Object Data Preview Data"); } - public IptcDirectory() + public IptcDirectory(@NotNull MetadataContext context) { - this.setDescriptor(new IptcDescriptor(this)); + this.setDescriptor(new IptcDescriptor(this, context)); } @Override diff --git a/Source/com/drew/metadata/iptc/IptcReader.java b/Source/com/drew/metadata/iptc/IptcReader.java index e80893954..d31366ca2 100644 --- a/Source/com/drew/metadata/iptc/IptcReader.java +++ b/Source/com/drew/metadata/iptc/IptcReader.java @@ -71,7 +71,7 @@ public void readJpegSegments(@NotNull Iterable segments, @NotNull Metada for (byte[] segmentBytes : segments) { // Ensure data starts with the IPTC marker byte if (segmentBytes.length != 0 && segmentBytes[0] == IptcMarkerByte) { - extract(new SequentialByteArrayReader(segmentBytes), metadata, segmentBytes.length); + extract(new SequentialByteArrayReader(segmentBytes), metadata, segmentBytes.length, context); } } } @@ -81,7 +81,8 @@ public void readJpegSegments(@NotNull Iterable segments, @NotNull Metada */ public void extract(@NotNull final SequentialReader reader, @NotNull final Metadata metadata, long length) { - extract(reader, metadata, length, null); + // TODO document this default context? + extract(reader, metadata, length, null, new MetadataContext()); } /** @@ -89,7 +90,24 @@ public void extract(@NotNull final SequentialReader reader, @NotNull final Metad */ public void extract(@NotNull final SequentialReader reader, @NotNull final Metadata metadata, long length, @Nullable Directory parentDirectory) { - IptcDirectory directory = new IptcDirectory(); + // TODO document this default context? + extract(reader, metadata, length, parentDirectory, new MetadataContext()); + } + + /** + * Performs the IPTC data extraction, adding found values to the specified instance of {@link Metadata}. + */ + public void extract(@NotNull final SequentialReader reader, @NotNull final Metadata metadata, long length, @NotNull MetadataContext context) + { + extract(reader, metadata, length, null, context); + } + + /** + * Performs the IPTC data extraction, adding found values to the specified instance of {@link Metadata}. + */ + public void extract(@NotNull final SequentialReader reader, @NotNull final Metadata metadata, long length, @Nullable Directory parentDirectory, @NotNull MetadataContext context) + { + IptcDirectory directory = new IptcDirectory(context); metadata.addDirectory(directory); if (parentDirectory != null) diff --git a/Source/com/drew/metadata/photoshop/PhotoshopReader.java b/Source/com/drew/metadata/photoshop/PhotoshopReader.java index fa3ecff5f..9fe2510a2 100644 --- a/Source/com/drew/metadata/photoshop/PhotoshopReader.java +++ b/Source/com/drew/metadata/photoshop/PhotoshopReader.java @@ -158,7 +158,7 @@ public void extract(@NotNull final SequentialReader reader, int length, @NotNull if (signature.equals("8BIM")) { if (tagType == PhotoshopDirectory.TAG_IPTC) - new IptcReader().extract(new SequentialByteArrayReader(tagBytes), metadata, tagBytes.length, directory); + new IptcReader().extract(new SequentialByteArrayReader(tagBytes), metadata, tagBytes.length, directory, context); else if (tagType == PhotoshopDirectory.TAG_ICC_PROFILE_BYTES) new IccReader().extract(new ByteArrayReader(tagBytes), metadata, directory, context); else if (tagType == PhotoshopDirectory.TAG_EXIF_DATA_1 || tagType == PhotoshopDirectory.TAG_EXIF_DATA_3) diff --git a/Tests/com/drew/metadata/iptc/IptcDirectoryTest.java b/Tests/com/drew/metadata/iptc/IptcDirectoryTest.java index c7a14f4ca..35101810e 100644 --- a/Tests/com/drew/metadata/iptc/IptcDirectoryTest.java +++ b/Tests/com/drew/metadata/iptc/IptcDirectoryTest.java @@ -21,6 +21,7 @@ package com.drew.metadata.iptc; +import com.drew.metadata.MetadataContext; import org.junit.Before; import org.junit.Test; @@ -39,7 +40,8 @@ public class IptcDirectoryTest @Before public void setUp() { - _directory = new IptcDirectory(); + MetadataContext context = new MetadataContext(); + _directory = new IptcDirectory(context); } @Test From 866081cbc1ee2c1fca39e23cbe8d2d8ce6b765c0 Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 25 Jun 2021 14:21:39 +0200 Subject: [PATCH 30/34] Remove unused imports. --- Source/com/drew/metadata/adobe/AdobeJpegReader.java | 1 - Source/com/drew/metadata/jfif/JfifReader.java | 1 - Source/com/drew/metadata/jpeg/JpegCommentReader.java | 1 - Source/com/drew/metadata/jpeg/JpegDnlReader.java | 1 - Source/com/drew/metadata/photoshop/DuckyReader.java | 1 - 5 files changed, 5 deletions(-) diff --git a/Source/com/drew/metadata/adobe/AdobeJpegReader.java b/Source/com/drew/metadata/adobe/AdobeJpegReader.java index 733cf24c4..5f62f636b 100644 --- a/Source/com/drew/metadata/adobe/AdobeJpegReader.java +++ b/Source/com/drew/metadata/adobe/AdobeJpegReader.java @@ -26,7 +26,6 @@ import com.drew.lang.SequentialByteArrayReader; import com.drew.lang.SequentialReader; import com.drew.lang.annotations.NotNull; -import com.drew.lang.annotations.Nullable; import com.drew.metadata.Directory; import com.drew.metadata.Metadata; import com.drew.metadata.MetadataContext; diff --git a/Source/com/drew/metadata/jfif/JfifReader.java b/Source/com/drew/metadata/jfif/JfifReader.java index 5aba7a8ad..3af2e6ed8 100644 --- a/Source/com/drew/metadata/jfif/JfifReader.java +++ b/Source/com/drew/metadata/jfif/JfifReader.java @@ -25,7 +25,6 @@ import com.drew.lang.ByteArrayReader; import com.drew.lang.RandomAccessReader; import com.drew.lang.annotations.NotNull; -import com.drew.lang.annotations.Nullable; import com.drew.metadata.Metadata; import com.drew.metadata.MetadataContext; import com.drew.metadata.MetadataReader; diff --git a/Source/com/drew/metadata/jpeg/JpegCommentReader.java b/Source/com/drew/metadata/jpeg/JpegCommentReader.java index 3c4ee4f9f..66ab7e632 100644 --- a/Source/com/drew/metadata/jpeg/JpegCommentReader.java +++ b/Source/com/drew/metadata/jpeg/JpegCommentReader.java @@ -23,7 +23,6 @@ import com.drew.imaging.jpeg.JpegSegmentMetadataReader; import com.drew.imaging.jpeg.JpegSegmentType; import com.drew.lang.annotations.NotNull; -import com.drew.lang.annotations.Nullable; import com.drew.metadata.Metadata; import com.drew.metadata.MetadataContext; import com.drew.metadata.StringValue; diff --git a/Source/com/drew/metadata/jpeg/JpegDnlReader.java b/Source/com/drew/metadata/jpeg/JpegDnlReader.java index 0cace4fc7..50e06c0ec 100644 --- a/Source/com/drew/metadata/jpeg/JpegDnlReader.java +++ b/Source/com/drew/metadata/jpeg/JpegDnlReader.java @@ -25,7 +25,6 @@ import com.drew.lang.SequentialByteArrayReader; import com.drew.lang.SequentialReader; import com.drew.lang.annotations.NotNull; -import com.drew.lang.annotations.Nullable; import com.drew.metadata.ErrorDirectory; import com.drew.metadata.Metadata; import com.drew.metadata.MetadataContext; diff --git a/Source/com/drew/metadata/photoshop/DuckyReader.java b/Source/com/drew/metadata/photoshop/DuckyReader.java index f0cca387d..e0b01688c 100644 --- a/Source/com/drew/metadata/photoshop/DuckyReader.java +++ b/Source/com/drew/metadata/photoshop/DuckyReader.java @@ -26,7 +26,6 @@ import com.drew.lang.SequentialByteArrayReader; import com.drew.lang.SequentialReader; import com.drew.lang.annotations.NotNull; -import com.drew.lang.annotations.Nullable; import com.drew.metadata.Metadata; import com.drew.metadata.MetadataContext; From 3b6dbe72850018ed0e48929efc65a8b24cf3a597 Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 25 Jun 2021 14:24:27 +0200 Subject: [PATCH 31/34] Provide MetadataContext to all AdobeJpegReader and related classes. --- Source/com/drew/metadata/adobe/AdobeJpegDescriptor.java | 5 +++-- Source/com/drew/metadata/adobe/AdobeJpegDirectory.java | 5 +++-- Source/com/drew/metadata/adobe/AdobeJpegReader.java | 6 +++--- Tests/com/drew/metadata/adobe/AdobeJpegReaderTest.java | 4 +++- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Source/com/drew/metadata/adobe/AdobeJpegDescriptor.java b/Source/com/drew/metadata/adobe/AdobeJpegDescriptor.java index 3427f82e9..f6d6e790d 100644 --- a/Source/com/drew/metadata/adobe/AdobeJpegDescriptor.java +++ b/Source/com/drew/metadata/adobe/AdobeJpegDescriptor.java @@ -22,6 +22,7 @@ package com.drew.metadata.adobe; import com.drew.lang.annotations.Nullable; +import com.drew.metadata.MetadataContext; import com.drew.metadata.TagDescriptor; import static com.drew.metadata.adobe.AdobeJpegDirectory.*; @@ -32,9 +33,9 @@ @SuppressWarnings("WeakerAccess") public class AdobeJpegDescriptor extends TagDescriptor { - public AdobeJpegDescriptor(AdobeJpegDirectory directory) + public AdobeJpegDescriptor(AdobeJpegDirectory directory, MetadataContext context) { - super(directory); + super(directory, context); } @Override diff --git a/Source/com/drew/metadata/adobe/AdobeJpegDirectory.java b/Source/com/drew/metadata/adobe/AdobeJpegDirectory.java index 6f44c0ede..b744cb187 100644 --- a/Source/com/drew/metadata/adobe/AdobeJpegDirectory.java +++ b/Source/com/drew/metadata/adobe/AdobeJpegDirectory.java @@ -23,6 +23,7 @@ import com.drew.lang.annotations.NotNull; import com.drew.metadata.Directory; +import com.drew.metadata.MetadataContext; import java.util.HashMap; @@ -57,8 +58,8 @@ public class AdobeJpegDirectory extends Directory { _tagNameMap.put(TAG_COLOR_TRANSFORM, "Color Transform"); } - public AdobeJpegDirectory() { - this.setDescriptor(new AdobeJpegDescriptor(this)); + public AdobeJpegDirectory(MetadataContext context) { + this.setDescriptor(new AdobeJpegDescriptor(this, context)); } @NotNull diff --git a/Source/com/drew/metadata/adobe/AdobeJpegReader.java b/Source/com/drew/metadata/adobe/AdobeJpegReader.java index 5f62f636b..b8ee2ef65 100644 --- a/Source/com/drew/metadata/adobe/AdobeJpegReader.java +++ b/Source/com/drew/metadata/adobe/AdobeJpegReader.java @@ -54,13 +54,13 @@ public void readJpegSegments(@NotNull Iterable segments, @NotNull Metada { for (byte[] bytes : segments) { if (bytes.length == 12 && PREAMBLE.equalsIgnoreCase(new String(bytes, 0, PREAMBLE.length()))) - extract(new SequentialByteArrayReader(bytes), metadata); + extract(new SequentialByteArrayReader(bytes), metadata, context); } } - public void extract(@NotNull SequentialReader reader, @NotNull Metadata metadata) + public void extract(@NotNull SequentialReader reader, @NotNull Metadata metadata, @NotNull MetadataContext context) { - Directory directory = new AdobeJpegDirectory(); + Directory directory = new AdobeJpegDirectory(context); metadata.addDirectory(directory); try { diff --git a/Tests/com/drew/metadata/adobe/AdobeJpegReaderTest.java b/Tests/com/drew/metadata/adobe/AdobeJpegReaderTest.java index ee9baf3b7..4ee46a0d2 100644 --- a/Tests/com/drew/metadata/adobe/AdobeJpegReaderTest.java +++ b/Tests/com/drew/metadata/adobe/AdobeJpegReaderTest.java @@ -25,6 +25,7 @@ import com.drew.lang.SequentialByteArrayReader; import com.drew.lang.annotations.NotNull; import com.drew.metadata.Metadata; +import com.drew.metadata.MetadataContext; import com.drew.tools.FileUtil; import org.junit.Test; @@ -42,7 +43,8 @@ public class AdobeJpegReaderTest public static AdobeJpegDirectory processBytes(@NotNull String filePath) throws IOException { Metadata metadata = new Metadata(); - new AdobeJpegReader().extract(new SequentialByteArrayReader(FileUtil.readBytes(filePath)), metadata); + MetadataContext context = new MetadataContext(); + new AdobeJpegReader().extract(new SequentialByteArrayReader(FileUtil.readBytes(filePath)), metadata, context); AdobeJpegDirectory directory = metadata.getFirstDirectoryOfType(AdobeJpegDirectory.class); assertNotNull(directory); From dfea3db9bf17cbd4d8c02d7c69738c214a7c35b9 Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 25 Jun 2021 15:18:56 +0200 Subject: [PATCH 32/34] Miscellaneous changes after self-review: remove or address TODOs, add tests. --- .../drew/imaging/jpeg/JpegMetadataReader.java | 11 ++++- .../jpeg/JpegSegmentMetadataReader.java | 1 - .../drew/imaging/png/PngMetadataReader.java | 2 +- .../drew/imaging/tiff/TiffMetadataReader.java | 2 +- Source/com/drew/lang/GeoLocation.java | 7 +++ Source/com/drew/metadata/Directory.java | 6 +-- Source/com/drew/metadata/MetadataContext.java | 4 +- Source/com/drew/metadata/TagDescriptor.java | 7 +-- .../metadata/exif/ExifSubIFDDescriptor.java | 5 --- .../metadata/exif/ExifSubIFDDirectory.java | 5 --- .../drew/metadata/exif/ExifTiffHandler.java | 6 +++ .../com/drew/metadata/exif/GpsDirectory.java | 7 --- .../drew/metadata/jfxx/JfxxDescriptor.java | 2 +- .../com/drew/metadata/jfxx/JfxxDirectory.java | 2 +- .../metadata/jpeg/JpegCommentDirectory.java | 7 --- .../drew/metadata/jpeg/JpegDescriptor.java | 2 +- .../com/drew/metadata/jpeg/JpegDirectory.java | 7 --- .../mov/atoms/canon/CanonThumbnailAtom.java | 5 ++- .../photoshop/PhotoshopDescriptor.java | 2 +- .../photoshop/PhotoshopDirectory.java | 2 +- .../photoshop/PhotoshopTiffHandler.java | 2 +- .../com/drew/metadata/xmp/XmpDescriptor.java | 2 +- .../imaging/png/PngMetadataReaderTest.java | 4 -- Tests/com/drew/metadata/MetadataTest.java | 18 +++++--- .../drew/metadata/exif/ExifDirectoryTest.java | 13 +++++- .../drew/metadata/exif/ExifReaderTest.java | 9 ++-- .../exif/ExifSubIFDDescriptorTest.java | 38 ++++++++++------ .../com/drew/metadata/icc/IccReaderTest.java | 45 +++++++++++++++++-- .../drew/metadata/jpeg/JpegDirectoryTest.java | 3 +- .../com/drew/metadata/xmp/XmpReaderTest.java | 4 +- 30 files changed, 140 insertions(+), 90 deletions(-) diff --git a/Source/com/drew/imaging/jpeg/JpegMetadataReader.java b/Source/com/drew/imaging/jpeg/JpegMetadataReader.java index 9cbbee0c3..0a82725ee 100644 --- a/Source/com/drew/imaging/jpeg/JpegMetadataReader.java +++ b/Source/com/drew/imaging/jpeg/JpegMetadataReader.java @@ -94,6 +94,7 @@ public static Metadata readMetadata(@NotNull InputStream inputStream, @NotNull M @NotNull public static Metadata readMetadata(@NotNull InputStream inputStream) throws JpegProcessingException, IOException { + // TODO document this default context? return readMetadata(inputStream, null, new MetadataContext()); } @@ -115,6 +116,7 @@ public static Metadata readMetadata(@NotNull File file, @Nullable Iterable readers) throws JpegProcessingException, IOException { + // TODO document this default context? return readMetadata(file, readers, new MetadataContext()); } @@ -127,15 +129,22 @@ public static Metadata readMetadata(@NotNull File file, @NotNull MetadataContext @NotNull public static Metadata readMetadata(@NotNull File file) throws JpegProcessingException, IOException { + // TODO document this default context? return readMetadata(file, null, new MetadataContext()); } public static void process(@NotNull Metadata metadata, @NotNull InputStream inputStream) throws JpegProcessingException, IOException { + // TODO document this default context? process(metadata, inputStream, null, new MetadataContext()); } - // TODO create method with original signature for backwards compatibility + public static void process(@NotNull Metadata metadata, @NotNull InputStream inputStream, @Nullable Iterable readers) throws JpegProcessingException, IOException + { + // TODO document this default context? + process(metadata, inputStream, readers, new MetadataContext()); + } + public static void process(@NotNull Metadata metadata, @NotNull InputStream inputStream, @Nullable Iterable readers, @NotNull MetadataContext context) throws JpegProcessingException, IOException { if (readers == null) diff --git a/Source/com/drew/imaging/jpeg/JpegSegmentMetadataReader.java b/Source/com/drew/imaging/jpeg/JpegSegmentMetadataReader.java index 4586d4334..f6f27d703 100644 --- a/Source/com/drew/imaging/jpeg/JpegSegmentMetadataReader.java +++ b/Source/com/drew/imaging/jpeg/JpegSegmentMetadataReader.java @@ -1,7 +1,6 @@ package com.drew.imaging.jpeg; import com.drew.lang.annotations.NotNull; -import com.drew.lang.annotations.Nullable; import com.drew.metadata.Metadata; import com.drew.metadata.MetadataContext; diff --git a/Source/com/drew/imaging/png/PngMetadataReader.java b/Source/com/drew/imaging/png/PngMetadataReader.java index 261b30e55..cb1c50dfa 100644 --- a/Source/com/drew/imaging/png/PngMetadataReader.java +++ b/Source/com/drew/imaging/png/PngMetadataReader.java @@ -329,7 +329,7 @@ private static void processChunk(@NotNull Metadata metadata, @NotNull PngChunk c metadata.addDirectory(directory); } else if (chunkType.equals(PngChunkType.eXIf)) { try { - ExifTiffHandler handler = new ExifTiffHandler(metadata, null, null); + ExifTiffHandler handler = new ExifTiffHandler(metadata, null); new TiffReader().processTiff(new ByteArrayReader(bytes), handler, 0); } catch (TiffProcessingException ex) { PngDirectory directory = new PngDirectory(PngChunkType.eXIf); diff --git a/Source/com/drew/imaging/tiff/TiffMetadataReader.java b/Source/com/drew/imaging/tiff/TiffMetadataReader.java index 491622d13..7137a0384 100644 --- a/Source/com/drew/imaging/tiff/TiffMetadataReader.java +++ b/Source/com/drew/imaging/tiff/TiffMetadataReader.java @@ -67,7 +67,7 @@ public static Metadata readMetadata(@NotNull InputStream inputStream) throws IOE public static Metadata readMetadata(@NotNull RandomAccessReader reader) throws IOException, TiffProcessingException { Metadata metadata = new Metadata(); - ExifTiffHandler handler = new ExifTiffHandler(metadata, null, null); + ExifTiffHandler handler = new ExifTiffHandler(metadata, null); new TiffReader().processTiff(reader, handler, 0); return metadata; } diff --git a/Source/com/drew/lang/GeoLocation.java b/Source/com/drew/lang/GeoLocation.java index 3f469dc72..a2b51839c 100644 --- a/Source/com/drew/lang/GeoLocation.java +++ b/Source/com/drew/lang/GeoLocation.java @@ -80,6 +80,13 @@ public boolean isZero() } // TODO document this deprecation + + /** + * Converts a decimal degree angle into its corresponding DMS (degrees-minutes-seconds) representation as a string, + * of format: {@code -1° 23' 4.56"} + * + * @deprecated Use {@link #decimalToDegreesMinutesSecondsString(double, Locale)} instead + */ @NotNull @Deprecated public static String decimalToDegreesMinutesSecondsString(double decimal) diff --git a/Source/com/drew/metadata/Directory.java b/Source/com/drew/metadata/Directory.java index da681b75d..a8468ce0c 100644 --- a/Source/com/drew/metadata/Directory.java +++ b/Source/com/drew/metadata/Directory.java @@ -1163,12 +1163,12 @@ public String getDescription(int tagType) @Override public String toString() { - return String.format("%s Directory (%d %s)", + return String.format(getLocale(), + "%s Directory (%d %s)", getName(), _tagMap.size(), _tagMap.size() == 1 ? "tag" - : "tags", - getLocale()); + : "tags"); } } diff --git a/Source/com/drew/metadata/MetadataContext.java b/Source/com/drew/metadata/MetadataContext.java index 837ed3fd7..5c6fd1c29 100644 --- a/Source/com/drew/metadata/MetadataContext.java +++ b/Source/com/drew/metadata/MetadataContext.java @@ -5,7 +5,7 @@ import java.util.Locale; /** - * Context class for metadata. Contains settings used while parsing and formatting metadata. + * Context class for metadata. Contains settings used while extracting and formatting metadata. * * @author Roel van Dijk */ @@ -35,7 +35,7 @@ public Locale locale() } /** - * Configure the {@link Locale} to use for parsing and formatting metadata. + * Configure the {@link Locale} to use for extracting and formatting metadata. * * @param locale the locale to use * @return this context diff --git a/Source/com/drew/metadata/TagDescriptor.java b/Source/com/drew/metadata/TagDescriptor.java index 29e7e9b3e..2c17ea212 100644 --- a/Source/com/drew/metadata/TagDescriptor.java +++ b/Source/com/drew/metadata/TagDescriptor.java @@ -307,7 +307,6 @@ protected String getStringFromBytes(int tag, Charset cs) } } - // TODO: discuss deprecation @Deprecated @Nullable /** @@ -334,7 +333,6 @@ protected String getRationalOrDoubleString(int tagType, Locale locale) return null; } - // TODO: discuss deprecation @Deprecated @Nullable /** @@ -352,7 +350,7 @@ protected static String getFStopDescription(double fStop, Locale locale) format.setRoundingMode(RoundingMode.HALF_UP); return "f/" + format.format(fStop); } - // TODO: discuss deprecation + @Deprecated @Nullable /** @@ -371,7 +369,6 @@ protected static String getFocalLengthDescription(double mm, Locale locale) return format.format(mm) + " mm"; } - // TODO: discuss deprecation @Deprecated @Nullable /** @@ -426,7 +423,6 @@ protected String getOrientationDescription(int tag) "Left side, bottom (Rotate 270 CW)"); } - // TODO: discuss deprecation @Deprecated @Nullable /** @@ -531,5 +527,4 @@ protected static DecimalFormatSymbols getDecimalFormatSymbols(Locale locale) { return locale == null ? DecimalFormatSymbols.getInstance() : DecimalFormatSymbols.getInstance(locale); } - } diff --git a/Source/com/drew/metadata/exif/ExifSubIFDDescriptor.java b/Source/com/drew/metadata/exif/ExifSubIFDDescriptor.java index c58e49be1..a6072fddf 100644 --- a/Source/com/drew/metadata/exif/ExifSubIFDDescriptor.java +++ b/Source/com/drew/metadata/exif/ExifSubIFDDescriptor.java @@ -34,11 +34,6 @@ @SuppressWarnings("WeakerAccess") public class ExifSubIFDDescriptor extends ExifDescriptorBase { - public ExifSubIFDDescriptor(@NotNull ExifSubIFDDirectory directory) - { - this(directory, null); - } - public ExifSubIFDDescriptor(@NotNull ExifSubIFDDirectory directory, @NotNull MetadataContext context) { super(directory, context); diff --git a/Source/com/drew/metadata/exif/ExifSubIFDDirectory.java b/Source/com/drew/metadata/exif/ExifSubIFDDirectory.java index ce34d4f70..0cfe28c3e 100644 --- a/Source/com/drew/metadata/exif/ExifSubIFDDirectory.java +++ b/Source/com/drew/metadata/exif/ExifSubIFDDirectory.java @@ -41,11 +41,6 @@ public class ExifSubIFDDirectory extends ExifDirectoryBase /** This tag is a pointer to the Exif Interop IFD. */ public static final int TAG_INTEROP_OFFSET = 0xA005; - public ExifSubIFDDirectory() - { - this.setDescriptor(new ExifSubIFDDescriptor(this)); - } - public ExifSubIFDDirectory(@NotNull MetadataContext context) { this.setDescriptor(new ExifSubIFDDescriptor(this, context)); diff --git a/Source/com/drew/metadata/exif/ExifTiffHandler.java b/Source/com/drew/metadata/exif/ExifTiffHandler.java index 3b3169ab6..b2b4327a9 100644 --- a/Source/com/drew/metadata/exif/ExifTiffHandler.java +++ b/Source/com/drew/metadata/exif/ExifTiffHandler.java @@ -60,6 +60,12 @@ */ public class ExifTiffHandler extends DirectoryTiffHandler { + public ExifTiffHandler(@NotNull Metadata metadata, @Nullable Directory parentDirectory) + { + // TODO document this default context? + super(metadata, parentDirectory, new MetadataContext()); + } + public ExifTiffHandler(@NotNull Metadata metadata, @Nullable Directory parentDirectory, @NotNull MetadataContext context) { super(metadata, parentDirectory, context); diff --git a/Source/com/drew/metadata/exif/GpsDirectory.java b/Source/com/drew/metadata/exif/GpsDirectory.java index 2e3d011a5..9ae041d61 100644 --- a/Source/com/drew/metadata/exif/GpsDirectory.java +++ b/Source/com/drew/metadata/exif/GpsDirectory.java @@ -147,13 +147,6 @@ public class GpsDirectory extends ExifDirectoryBase _tagNameMap.put(TAG_H_POSITIONING_ERROR, "GPS H Positioning Error"); } - // TODO remove this constructor, or document its deprecation? - @Deprecated - public GpsDirectory() - { - this(new MetadataContext()); - } - public GpsDirectory(@NotNull MetadataContext context) { this.setDescriptor(new GpsDescriptor(this, context)); diff --git a/Source/com/drew/metadata/jfxx/JfxxDescriptor.java b/Source/com/drew/metadata/jfxx/JfxxDescriptor.java index 50aaa1d93..cf05b665f 100644 --- a/Source/com/drew/metadata/jfxx/JfxxDescriptor.java +++ b/Source/com/drew/metadata/jfxx/JfxxDescriptor.java @@ -40,7 +40,7 @@ @SuppressWarnings("WeakerAccess") public class JfxxDescriptor extends TagDescriptor { - public JfxxDescriptor(@NotNull JfxxDirectory directory, MetadataContext context) + public JfxxDescriptor(@NotNull JfxxDirectory directory, @NotNull MetadataContext context) { super(directory, context); } diff --git a/Source/com/drew/metadata/jfxx/JfxxDirectory.java b/Source/com/drew/metadata/jfxx/JfxxDirectory.java index 6fe5fb55a..05fc63b71 100644 --- a/Source/com/drew/metadata/jfxx/JfxxDirectory.java +++ b/Source/com/drew/metadata/jfxx/JfxxDirectory.java @@ -45,7 +45,7 @@ public class JfxxDirectory extends Directory _tagNameMap.put(TAG_EXTENSION_CODE, "Extension Code"); } - public JfxxDirectory(MetadataContext context) + public JfxxDirectory(@NotNull MetadataContext context) { this.setDescriptor(new JfxxDescriptor(this, context)); } diff --git a/Source/com/drew/metadata/jpeg/JpegCommentDirectory.java b/Source/com/drew/metadata/jpeg/JpegCommentDirectory.java index bf1066a64..4d6213c25 100644 --- a/Source/com/drew/metadata/jpeg/JpegCommentDirectory.java +++ b/Source/com/drew/metadata/jpeg/JpegCommentDirectory.java @@ -47,13 +47,6 @@ public class JpegCommentDirectory extends Directory _tagNameMap.put(TAG_COMMENT, "JPEG Comment"); } - // TODO remove this constructor, or document its deprecation? - @Deprecated - public JpegCommentDirectory() - { - this(new MetadataContext()); - } - public JpegCommentDirectory(@NotNull MetadataContext context) { this.setDescriptor(new JpegCommentDescriptor(this, context)); diff --git a/Source/com/drew/metadata/jpeg/JpegDescriptor.java b/Source/com/drew/metadata/jpeg/JpegDescriptor.java index 6c2711bd0..c5bd029e3 100644 --- a/Source/com/drew/metadata/jpeg/JpegDescriptor.java +++ b/Source/com/drew/metadata/jpeg/JpegDescriptor.java @@ -36,7 +36,7 @@ @SuppressWarnings("WeakerAccess") public class JpegDescriptor extends TagDescriptor { - public JpegDescriptor(@NotNull JpegDirectory directory, MetadataContext context) + public JpegDescriptor(@NotNull JpegDirectory directory, @NotNull MetadataContext context) { super(directory, context); } diff --git a/Source/com/drew/metadata/jpeg/JpegDirectory.java b/Source/com/drew/metadata/jpeg/JpegDirectory.java index 5f2bd3dc1..f792129c8 100644 --- a/Source/com/drew/metadata/jpeg/JpegDirectory.java +++ b/Source/com/drew/metadata/jpeg/JpegDirectory.java @@ -80,13 +80,6 @@ public class JpegDirectory extends Directory _tagNameMap.put(TAG_COMPONENT_DATA_4, "Component 4"); } - // TODO remove this constructor, or document its deprecation? - @Deprecated - public JpegDirectory() - { - this(new MetadataContext()); - } - public JpegDirectory(@NotNull MetadataContext context) { this.setDescriptor(new JpegDescriptor(this, context)); diff --git a/Source/com/drew/metadata/mov/atoms/canon/CanonThumbnailAtom.java b/Source/com/drew/metadata/mov/atoms/canon/CanonThumbnailAtom.java index 44f868599..4e7d4a02e 100644 --- a/Source/com/drew/metadata/mov/atoms/canon/CanonThumbnailAtom.java +++ b/Source/com/drew/metadata/mov/atoms/canon/CanonThumbnailAtom.java @@ -15,6 +15,7 @@ import com.drew.lang.StreamReader; import com.drew.metadata.Directory; import com.drew.metadata.Metadata; +import com.drew.metadata.MetadataContext; import com.drew.metadata.Tag; import com.drew.metadata.exif.ExifDirectoryBase; import com.drew.metadata.exif.ExifIFD0Directory; @@ -58,8 +59,10 @@ private void readCNDA(SequentialReader reader) throws IOException // TODO should we keep all extracted metadata here? Metadata metadata = new Metadata(); + // TODO document this default context? + MetadataContext context = new MetadataContext(); for (JpegSegmentType segmentType : exifReader.getSegmentTypes()) { - exifReader.readJpegSegments(segmentData.getSegments(segmentType), metadata, segmentType, null); + exifReader.readJpegSegments(segmentData.getSegments(segmentType), metadata, segmentType, context); } Directory directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class); diff --git a/Source/com/drew/metadata/photoshop/PhotoshopDescriptor.java b/Source/com/drew/metadata/photoshop/PhotoshopDescriptor.java index 76a5873a1..2f5d46ae3 100644 --- a/Source/com/drew/metadata/photoshop/PhotoshopDescriptor.java +++ b/Source/com/drew/metadata/photoshop/PhotoshopDescriptor.java @@ -42,7 +42,7 @@ @SuppressWarnings("WeakerAccess") public class PhotoshopDescriptor extends TagDescriptor { - public PhotoshopDescriptor(@NotNull PhotoshopDirectory directory, MetadataContext context) + public PhotoshopDescriptor(@NotNull PhotoshopDirectory directory, @NotNull MetadataContext context) { super(directory, context); } diff --git a/Source/com/drew/metadata/photoshop/PhotoshopDirectory.java b/Source/com/drew/metadata/photoshop/PhotoshopDirectory.java index 3dabcc49b..a3670cd2d 100644 --- a/Source/com/drew/metadata/photoshop/PhotoshopDirectory.java +++ b/Source/com/drew/metadata/photoshop/PhotoshopDirectory.java @@ -225,7 +225,7 @@ public class PhotoshopDirectory extends Directory _tagNameMap.put(TAG_PRINT_FLAGS_INFO, "Print Flags Information"); } - public PhotoshopDirectory(MetadataContext context) + public PhotoshopDirectory(@NotNull MetadataContext context) { this.setDescriptor(new PhotoshopDescriptor(this, context)); } diff --git a/Source/com/drew/metadata/photoshop/PhotoshopTiffHandler.java b/Source/com/drew/metadata/photoshop/PhotoshopTiffHandler.java index a0d51a89a..b5de35ea8 100644 --- a/Source/com/drew/metadata/photoshop/PhotoshopTiffHandler.java +++ b/Source/com/drew/metadata/photoshop/PhotoshopTiffHandler.java @@ -33,7 +33,7 @@ public class PhotoshopTiffHandler extends ExifTiffHandler public PhotoshopTiffHandler(Metadata metadata, Directory parentDirectory) { - super(metadata, parentDirectory, null); + super(metadata, parentDirectory); } public boolean customProcessTag(final int tagOffset, diff --git a/Source/com/drew/metadata/xmp/XmpDescriptor.java b/Source/com/drew/metadata/xmp/XmpDescriptor.java index 16887e1a4..dd5893bdf 100644 --- a/Source/com/drew/metadata/xmp/XmpDescriptor.java +++ b/Source/com/drew/metadata/xmp/XmpDescriptor.java @@ -33,7 +33,7 @@ @SuppressWarnings("WeakerAccess") public class XmpDescriptor extends TagDescriptor { - public XmpDescriptor(@NotNull XmpDirectory directory, MetadataContext context) + public XmpDescriptor(@NotNull XmpDirectory directory, @NotNull MetadataContext context) { super(directory, context); } diff --git a/Tests/com/drew/imaging/png/PngMetadataReaderTest.java b/Tests/com/drew/imaging/png/PngMetadataReaderTest.java index ab400b298..a32f6e469 100644 --- a/Tests/com/drew/imaging/png/PngMetadataReaderTest.java +++ b/Tests/com/drew/imaging/png/PngMetadataReaderTest.java @@ -114,8 +114,4 @@ public void testGimpGreyscaleWithManyChunks() throws Exception TimeZone.setDefault(timeZone); } } - - // TODO [locale tests] Double use case: - // PngDirectory.TAG_GAMMA in Tests/Data/gimp-8x12-greyscale-alpha-time-background.png - } diff --git a/Tests/com/drew/metadata/MetadataTest.java b/Tests/com/drew/metadata/MetadataTest.java index 7a10e52a2..d258e1011 100644 --- a/Tests/com/drew/metadata/MetadataTest.java +++ b/Tests/com/drew/metadata/MetadataTest.java @@ -38,6 +38,12 @@ */ public class MetadataTest { + private MetadataContext _context; + + public void setUp() { + _context = new MetadataContext(); + } + @Test public void testGetDirectoryWhenNotExists() { @@ -47,7 +53,7 @@ public void testGetDirectoryWhenNotExists() @Test public void testHasErrors() throws Exception { - ExifSubIFDDirectory directory = new ExifSubIFDDirectory(); + ExifSubIFDDirectory directory = new ExifSubIFDDirectory(_context); directory.addError("Test Error 1"); Metadata metadata = new Metadata(); @@ -66,7 +72,7 @@ public void testToString() metadata.addDirectory(new ExifIFD0Directory()); assertEquals("Metadata (1 directory)", metadata.toString()); - metadata.addDirectory(new ExifSubIFDDirectory()); + metadata.addDirectory(new ExifSubIFDDirectory(_context)); assertEquals("Metadata (2 directories)", metadata.toString()); } @@ -74,9 +80,9 @@ public void testToString() public void testOrderOfSameType() { Metadata metadata = new Metadata(); - Directory directory2 = new ExifSubIFDDirectory(); - Directory directory3 = new ExifSubIFDDirectory(); - Directory directory1 = new ExifSubIFDDirectory(); + Directory directory2 = new ExifSubIFDDirectory(_context); + Directory directory3 = new ExifSubIFDDirectory(_context); + Directory directory1 = new ExifSubIFDDirectory(_context); metadata.addDirectory(directory1); metadata.addDirectory(directory2); @@ -95,7 +101,7 @@ public void testOrderOfSameType() public void testOrderOfDifferentTypes() { Metadata metadata = new Metadata(); - Directory directory1 = new ExifSubIFDDirectory(); + Directory directory1 = new ExifSubIFDDirectory(_context); Directory directory2 = new ExifThumbnailDirectory(); Directory directory3 = new ExifIFD0Directory(); diff --git a/Tests/com/drew/metadata/exif/ExifDirectoryTest.java b/Tests/com/drew/metadata/exif/ExifDirectoryTest.java index d818dcbac..803660fb6 100644 --- a/Tests/com/drew/metadata/exif/ExifDirectoryTest.java +++ b/Tests/com/drew/metadata/exif/ExifDirectoryTest.java @@ -24,7 +24,9 @@ import com.drew.lang.GeoLocation; import com.drew.metadata.Directory; import com.drew.metadata.Metadata; +import com.drew.metadata.MetadataContext; import com.drew.metadata.MetadataException; +import org.junit.Before; import org.junit.Test; import java.io.IOException; @@ -41,13 +43,20 @@ @SuppressWarnings("ConstantConditions") public class ExifDirectoryTest { + private MetadataContext _context; + + @Before + public void setUp() { + _context = new MetadataContext(); + } + @Test public void testGetDirectoryName() throws Exception { - Directory subIFDDirectory = new ExifSubIFDDirectory(); + Directory subIFDDirectory = new ExifSubIFDDirectory(_context); Directory ifd0Directory = new ExifIFD0Directory(); Directory thumbDirectory = new ExifThumbnailDirectory(); - Directory gpsDirectory = new GpsDirectory(); + Directory gpsDirectory = new GpsDirectory(_context); assertFalse(subIFDDirectory.hasErrors()); assertFalse(ifd0Directory.hasErrors()); diff --git a/Tests/com/drew/metadata/exif/ExifReaderTest.java b/Tests/com/drew/metadata/exif/ExifReaderTest.java index f71d3874a..144abe7ce 100644 --- a/Tests/com/drew/metadata/exif/ExifReaderTest.java +++ b/Tests/com/drew/metadata/exif/ExifReaderTest.java @@ -26,7 +26,9 @@ import com.drew.lang.annotations.NotNull; import com.drew.metadata.Directory; import com.drew.metadata.Metadata; +import com.drew.metadata.MetadataContext; import com.drew.tools.FileUtil; +import org.junit.Before; import org.junit.Test; import java.io.IOException; @@ -46,7 +48,7 @@ public static Metadata processBytes(@NotNull String filePath) throws IOException { Metadata metadata = new Metadata(); byte[] bytes = FileUtil.readBytes(filePath); - new ExifReader().extract(new ByteArrayReader(bytes), metadata, ExifReader.JPEG_SEGMENT_PREAMBLE.length(), null); + new ExifReader().extract(new ByteArrayReader(bytes), metadata, ExifReader.JPEG_SEGMENT_PREAMBLE.length()); return metadata; } @@ -63,7 +65,7 @@ public static T processBytes(@NotNull String filePath, @No public void testExtractWithNullDataThrows() throws Exception { try{ - new ExifReader().readJpegSegments(null, new Metadata(), JpegSegmentType.APP1, null); + new ExifReader().readJpegSegments(null, new Metadata(), JpegSegmentType.APP1, new MetadataContext()); fail("Exception expected"); } catch (NullPointerException npe) { // passed @@ -87,9 +89,10 @@ public void testReadJpegSegmentWithNoExifData() throws Exception { byte[] badExifData = new byte[]{ 1,2,3,4,5,6,7,8,9,10 }; Metadata metadata = new Metadata(); + MetadataContext context = new MetadataContext(); ArrayList segments = new ArrayList(); segments.add(badExifData); - new ExifReader().readJpegSegments(segments, metadata, JpegSegmentType.APP1, null); + new ExifReader().readJpegSegments(segments, metadata, JpegSegmentType.APP1, context); assertEquals(0, metadata.getDirectoryCount()); assertFalse(metadata.hasErrors()); } diff --git a/Tests/com/drew/metadata/exif/ExifSubIFDDescriptorTest.java b/Tests/com/drew/metadata/exif/ExifSubIFDDescriptorTest.java index e05dc5afd..7b72b58f9 100644 --- a/Tests/com/drew/metadata/exif/ExifSubIFDDescriptorTest.java +++ b/Tests/com/drew/metadata/exif/ExifSubIFDDescriptorTest.java @@ -20,6 +20,8 @@ */ package com.drew.metadata.exif; +import com.drew.metadata.MetadataContext; +import org.junit.Before; import org.junit.Test; import static com.drew.metadata.exif.ExifSubIFDDirectory.*; @@ -32,13 +34,21 @@ */ public class ExifSubIFDDescriptorTest { + private MetadataContext _context; + + @Before + public void setUp() + { + _context = new MetadataContext(); + } + @Test public void testUserCommentDescription_EmptyEncoding() throws Exception { byte[] commentBytes = "\0\0\0\0\0\0\0\0This is a comment".getBytes(); - ExifSubIFDDirectory directory = new ExifSubIFDDirectory(); + ExifSubIFDDirectory directory = new ExifSubIFDDirectory(_context); directory.setByteArray(TAG_USER_COMMENT, commentBytes); - ExifSubIFDDescriptor descriptor = new ExifSubIFDDescriptor(directory); + ExifSubIFDDescriptor descriptor = new ExifSubIFDDescriptor(directory, _context); assertEquals("This is a comment", descriptor.getDescription(TAG_USER_COMMENT)); } @@ -46,9 +56,9 @@ public void testUserCommentDescription_EmptyEncoding() throws Exception public void testUserCommentDescription_AsciiHeaderAsciiEncoding() throws Exception { byte[] commentBytes = "ASCII\0\0This is a comment".getBytes(); - ExifSubIFDDirectory directory = new ExifSubIFDDirectory(); + ExifSubIFDDirectory directory = new ExifSubIFDDirectory(_context); directory.setByteArray(TAG_USER_COMMENT, commentBytes); - ExifSubIFDDescriptor descriptor = new ExifSubIFDDescriptor(directory); + ExifSubIFDDescriptor descriptor = new ExifSubIFDDescriptor(directory, _context); assertEquals("This is a comment", descriptor.getDescription(TAG_USER_COMMENT)); } @@ -56,9 +66,9 @@ public void testUserCommentDescription_AsciiHeaderAsciiEncoding() throws Excepti public void testUserCommentDescription_BlankAscii() throws Exception { byte[] commentBytes = "ASCII\0\0\0 ".getBytes(); - ExifSubIFDDirectory directory = new ExifSubIFDDirectory(); + ExifSubIFDDirectory directory = new ExifSubIFDDirectory(_context); directory.setByteArray(TAG_USER_COMMENT, commentBytes); - ExifSubIFDDescriptor descriptor = new ExifSubIFDDescriptor(directory); + ExifSubIFDDescriptor descriptor = new ExifSubIFDDescriptor(directory, _context); assertEquals("", descriptor.getDescription(TAG_USER_COMMENT)); } @@ -67,9 +77,9 @@ public void testUserCommentDescription_ZeroLengthAscii1() throws Exception { // the 10-byte encoding region is only partially full byte[] commentBytes = "ASCII\0\0\0".getBytes(); - ExifSubIFDDirectory directory = new ExifSubIFDDirectory(); + ExifSubIFDDirectory directory = new ExifSubIFDDirectory(_context); directory.setByteArray(TAG_USER_COMMENT, commentBytes); - ExifSubIFDDescriptor descriptor = new ExifSubIFDDescriptor(directory); + ExifSubIFDDescriptor descriptor = new ExifSubIFDDescriptor(directory, _context); assertEquals("ASCII", descriptor.getDescription(TAG_USER_COMMENT)); } @@ -78,9 +88,9 @@ public void testUserCommentDescription_ZeroLengthAscii2() throws Exception { // fill the 10-byte encoding region byte[] commentBytes = "ASCII\0\0\0\0\0".getBytes(); - ExifSubIFDDirectory directory = new ExifSubIFDDirectory(); + ExifSubIFDDirectory directory = new ExifSubIFDDirectory(_context); directory.setByteArray(TAG_USER_COMMENT, commentBytes); - ExifSubIFDDescriptor descriptor = new ExifSubIFDDescriptor(directory); + ExifSubIFDDescriptor descriptor = new ExifSubIFDDescriptor(directory, _context); assertEquals("", descriptor.getDescription(TAG_USER_COMMENT)); } @@ -88,9 +98,9 @@ public void testUserCommentDescription_ZeroLengthAscii2() throws Exception public void testUnicodeComment_ActualBytes() throws Exception { byte[] commentBytes = new byte[] { 85, 78, 73, 67, 79, 68, 69, 0, 84, 0, 104, 0, 105, 0, 115, 0, 32, 0, 109, 0, 97, 0, 114, 0, 109, 0, 111, 0, 116, 0, 32, 0, 105, 0, 115, 0, 32, 0, 103, 0, 101, 0, 116, 0, 116, 0, 105, 0, 110, 0, 103, 0, 32, 0, 99, 0, 108, 0, 111, 0, 115, 0, 101, 0, 46, 0, 46, 0, 46, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0, 32, 0 }; - ExifSubIFDDirectory directory = new ExifSubIFDDirectory(); + ExifSubIFDDirectory directory = new ExifSubIFDDirectory(_context); directory.setByteArray(TAG_USER_COMMENT, commentBytes); - ExifSubIFDDescriptor descriptor = new ExifSubIFDDescriptor(directory); + ExifSubIFDDescriptor descriptor = new ExifSubIFDDescriptor(directory, _context); assertEquals("This marmot is getting close...", descriptor.getDescription(TAG_USER_COMMENT)); } @@ -98,9 +108,9 @@ public void testUnicodeComment_ActualBytes() throws Exception public void testUnicodeComment_Ascii() throws Exception { byte[] commentBytes = new byte[] { 65, 83, 67, 73, 73, 0, 0, 0, 73, 32, 97, 109, 32, 97, 32, 99, 111, 109, 109, 101, 110, 116, 46, 32, 89, 101, 121, 46, 0 }; - ExifSubIFDDirectory directory = new ExifSubIFDDirectory(); + ExifSubIFDDirectory directory = new ExifSubIFDDirectory(_context); directory.setByteArray(TAG_USER_COMMENT, commentBytes); - ExifSubIFDDescriptor descriptor = new ExifSubIFDDescriptor(directory); + ExifSubIFDDescriptor descriptor = new ExifSubIFDDescriptor(directory, _context); assertEquals("I am a comment. Yey.", descriptor.getDescription(TAG_USER_COMMENT)); } } diff --git a/Tests/com/drew/metadata/icc/IccReaderTest.java b/Tests/com/drew/metadata/icc/IccReaderTest.java index 604d80072..087a01a74 100644 --- a/Tests/com/drew/metadata/icc/IccReaderTest.java +++ b/Tests/com/drew/metadata/icc/IccReaderTest.java @@ -21,15 +21,22 @@ package com.drew.metadata.icc; +import com.drew.imaging.jpeg.JpegMetadataReader; import com.drew.imaging.jpeg.JpegSegmentType; import com.drew.lang.ByteArrayReader; +import com.drew.metadata.Directory; import com.drew.metadata.Metadata; import com.drew.metadata.MetadataContext; +import com.drew.metadata.exif.ExifDirectoryBase; +import com.drew.metadata.exif.ExifSubIFDDirectory; +import com.drew.metadata.exif.GpsDirectory; import com.drew.testing.TestHelper; import com.drew.tools.FileUtil; import org.junit.Test; +import java.io.File; import java.util.Arrays; +import java.util.Locale; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -88,9 +95,39 @@ public void testExtract_ProfileDateTime() throws Exception assertEquals(887006940000L, directory.getDate(IccDirectory.TAG_PROFILE_DATETIME).getTime()); } - // TODO [locale tests] Float array use case: - // IccDirectory.TAG_XYZ_VALUES in Tests/Data/withIptcExifGps.jpg - // Directory icc = metadata.getFirstDirectoryOfType(IccDirectory.class); - // assertEquals("0,964 1 0,825", icc.getString(IccDirectory.TAG_XYZ_VALUES)); + @Test + public void testConfigurableLocaleEnglish() throws Exception { + Locale defaultLocale = Locale.getDefault(); + try { + // set default Locale to Dutch, configure English -> expect period + Locale.setDefault(new Locale("nl")); + MetadataContext context = new MetadataContext().locale(Locale.ENGLISH); + Metadata metadata = JpegMetadataReader.readMetadata(new File("Tests/Data/withIptcExifGps.jpg"), context); + + Directory icc = metadata.getFirstDirectoryOfType(IccDirectory.class); + assertEquals("0.964 1 0.825", icc.getString(IccDirectory.TAG_XYZ_VALUES)); + } + finally { + // reset default locale + Locale.setDefault(defaultLocale); + } + } + @Test + public void testConfigurableLocaleDutch() throws Exception { + Locale defaultLocale = Locale.getDefault(); + try { + // set default Locale to English, configure Dutch -> expect comma + Locale.setDefault(Locale.ENGLISH); + MetadataContext context = new MetadataContext().locale(new Locale("nl")); + Metadata metadata = JpegMetadataReader.readMetadata(new File("Tests/Data/withIptcExifGps.jpg"), context); + + Directory icc = metadata.getFirstDirectoryOfType(IccDirectory.class); + assertEquals("0,964 1 0,825", icc.getString(IccDirectory.TAG_XYZ_VALUES)); + } + finally { + // reset default locale + Locale.setDefault(defaultLocale); + } + } } diff --git a/Tests/com/drew/metadata/jpeg/JpegDirectoryTest.java b/Tests/com/drew/metadata/jpeg/JpegDirectoryTest.java index 702e5e72b..b036440ff 100644 --- a/Tests/com/drew/metadata/jpeg/JpegDirectoryTest.java +++ b/Tests/com/drew/metadata/jpeg/JpegDirectoryTest.java @@ -36,8 +36,7 @@ public class JpegDirectoryTest @Before public void setUp() { - MetadataContext context = new MetadataContext(); - _directory = new JpegDirectory(context); + _directory = new JpegDirectory(new MetadataContext()); } @Test diff --git a/Tests/com/drew/metadata/xmp/XmpReaderTest.java b/Tests/com/drew/metadata/xmp/XmpReaderTest.java index 0facde6a2..47243bf7d 100644 --- a/Tests/com/drew/metadata/xmp/XmpReaderTest.java +++ b/Tests/com/drew/metadata/xmp/XmpReaderTest.java @@ -22,6 +22,7 @@ import com.drew.imaging.jpeg.JpegSegmentType; import com.drew.metadata.Metadata; +import com.drew.metadata.MetadataContext; import com.drew.tools.FileUtil; import org.junit.Before; import org.junit.Test; @@ -41,9 +42,10 @@ public class XmpReaderTest public void setUp() throws Exception { Metadata metadata = new Metadata(); + MetadataContext context = new MetadataContext(); List jpegSegments = new ArrayList(); jpegSegments.add(FileUtil.readBytes("Tests/Data/withXmpAndIptc.jpg.app1.1")); - new XmpReader().readJpegSegments(jpegSegments, metadata, JpegSegmentType.APP1, null); + new XmpReader().readJpegSegments(jpegSegments, metadata, JpegSegmentType.APP1, context); Collection xmpDirectories = metadata.getDirectoriesOfType(XmpDirectory.class); From a314058b490b78c152a9a273417b93862c9604e3 Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 25 Jun 2021 15:31:10 +0200 Subject: [PATCH 33/34] Minor changes after self-review: inline variables, address or move TODOs. --- Source/com/drew/lang/GeoLocation.java | 2 -- Source/com/drew/metadata/adobe/AdobeJpegDirectory.java | 2 +- Source/com/drew/metadata/xmp/XmpDirectory.java | 2 +- Source/com/drew/metadata/xmp/XmpReader.java | 7 ++++--- Tests/com/drew/metadata/iptc/IptcDirectoryTest.java | 3 +-- 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/Source/com/drew/lang/GeoLocation.java b/Source/com/drew/lang/GeoLocation.java index a2b51839c..d264cf140 100644 --- a/Source/com/drew/lang/GeoLocation.java +++ b/Source/com/drew/lang/GeoLocation.java @@ -79,8 +79,6 @@ public boolean isZero() return _latitude == 0 && _longitude == 0; } - // TODO document this deprecation - /** * Converts a decimal degree angle into its corresponding DMS (degrees-minutes-seconds) representation as a string, * of format: {@code -1° 23' 4.56"} diff --git a/Source/com/drew/metadata/adobe/AdobeJpegDirectory.java b/Source/com/drew/metadata/adobe/AdobeJpegDirectory.java index b744cb187..34682b43f 100644 --- a/Source/com/drew/metadata/adobe/AdobeJpegDirectory.java +++ b/Source/com/drew/metadata/adobe/AdobeJpegDirectory.java @@ -58,7 +58,7 @@ public class AdobeJpegDirectory extends Directory { _tagNameMap.put(TAG_COLOR_TRANSFORM, "Color Transform"); } - public AdobeJpegDirectory(MetadataContext context) { + public AdobeJpegDirectory(@NotNull MetadataContext context) { this.setDescriptor(new AdobeJpegDescriptor(this, context)); } diff --git a/Source/com/drew/metadata/xmp/XmpDirectory.java b/Source/com/drew/metadata/xmp/XmpDirectory.java index ad0b5431c..41c78bf60 100644 --- a/Source/com/drew/metadata/xmp/XmpDirectory.java +++ b/Source/com/drew/metadata/xmp/XmpDirectory.java @@ -60,7 +60,7 @@ public class XmpDirectory extends Directory @Nullable private XMPMeta _xmpMeta; - public XmpDirectory(MetadataContext context) + public XmpDirectory(@NotNull MetadataContext context) { this.setDescriptor(new XmpDescriptor(this, context)); } diff --git a/Source/com/drew/metadata/xmp/XmpReader.java b/Source/com/drew/metadata/xmp/XmpReader.java index fe12249e8..346814414 100644 --- a/Source/com/drew/metadata/xmp/XmpReader.java +++ b/Source/com/drew/metadata/xmp/XmpReader.java @@ -138,7 +138,8 @@ public void readJpegSegments(@NotNull Iterable segments, @NotNull Metada */ public void extract(@NotNull final byte[] xmpBytes, @NotNull Metadata metadata) { - extract(xmpBytes, metadata, null, null); + // TODO document this default context? + extract(xmpBytes, metadata, null, new MetadataContext()); } /** @@ -159,7 +160,6 @@ public void extract(@NotNull final byte[] xmpBytes, @NotNull Metadata metadata, */ public void extract(@NotNull final byte[] xmpBytes, @NotNull Metadata metadata, @NotNull MetadataContext context) { - // TODO document this default context? extract(xmpBytes, metadata, null, context); } @@ -234,7 +234,8 @@ public void extract(@NotNull final String xmpString, @NotNull Metadata metadata) */ public void extract(@NotNull final StringValue xmpString, @NotNull Metadata metadata) { - extract(xmpString.getBytes(), metadata, null, null); + // TODO document this default context? + extract(xmpString.getBytes(), metadata, null, new MetadataContext()); } /** diff --git a/Tests/com/drew/metadata/iptc/IptcDirectoryTest.java b/Tests/com/drew/metadata/iptc/IptcDirectoryTest.java index 35101810e..6a8a42f47 100644 --- a/Tests/com/drew/metadata/iptc/IptcDirectoryTest.java +++ b/Tests/com/drew/metadata/iptc/IptcDirectoryTest.java @@ -40,8 +40,7 @@ public class IptcDirectoryTest @Before public void setUp() { - MetadataContext context = new MetadataContext(); - _directory = new IptcDirectory(context); + _directory = new IptcDirectory(new MetadataContext()); } @Test From 02cf06f4cd26bf04b6cef594bf7ef654e07b5bbe Mon Sep 17 00:00:00 2001 From: Roel van Dijk Date: Fri, 25 Jun 2021 16:05:20 +0200 Subject: [PATCH 34/34] Add TODOs to a few more default contexts. Remove unused constructor. --- Source/com/drew/metadata/icc/IccReader.java | 1 + Source/com/drew/metadata/jfif/JfifReader.java | 1 + Source/com/drew/metadata/jfxx/JfxxReader.java | 1 + Source/com/drew/metadata/jpeg/HuffmanTablesDirectory.java | 7 ------- .../com/drew/metadata/jpeg/HuffmanTablesDirectoryTest.java | 3 ++- 5 files changed, 5 insertions(+), 8 deletions(-) diff --git a/Source/com/drew/metadata/icc/IccReader.java b/Source/com/drew/metadata/icc/IccReader.java index 820260f0a..68734006d 100644 --- a/Source/com/drew/metadata/icc/IccReader.java +++ b/Source/com/drew/metadata/icc/IccReader.java @@ -98,6 +98,7 @@ public void extract(@NotNull final RandomAccessReader reader, @NotNull final Met public void extract(@NotNull final RandomAccessReader reader, @NotNull final Metadata metadata, @Nullable Directory parentDirectory) { + // TODO document this default context? extract(reader, metadata, parentDirectory, new MetadataContext()); } diff --git a/Source/com/drew/metadata/jfif/JfifReader.java b/Source/com/drew/metadata/jfif/JfifReader.java index 3af2e6ed8..32532b1fc 100644 --- a/Source/com/drew/metadata/jfif/JfifReader.java +++ b/Source/com/drew/metadata/jfif/JfifReader.java @@ -62,6 +62,7 @@ public void readJpegSegments(@NotNull Iterable segments, @NotNull Metada } public void extract(@NotNull final RandomAccessReader reader, @NotNull final Metadata metadata) { + // TODO document this default context? extract(reader, metadata, new MetadataContext()); } diff --git a/Source/com/drew/metadata/jfxx/JfxxReader.java b/Source/com/drew/metadata/jfxx/JfxxReader.java index f86407192..2c586e226 100644 --- a/Source/com/drew/metadata/jfxx/JfxxReader.java +++ b/Source/com/drew/metadata/jfxx/JfxxReader.java @@ -65,6 +65,7 @@ public void readJpegSegments(@NotNull Iterable segments, @NotNull Metada @Override public void extract(RandomAccessReader reader, Metadata metadata) { + // TODO document this default context? extract(reader, metadata, new MetadataContext()); } diff --git a/Source/com/drew/metadata/jpeg/HuffmanTablesDirectory.java b/Source/com/drew/metadata/jpeg/HuffmanTablesDirectory.java index 9c184369a..dd8ef9d83 100644 --- a/Source/com/drew/metadata/jpeg/HuffmanTablesDirectory.java +++ b/Source/com/drew/metadata/jpeg/HuffmanTablesDirectory.java @@ -129,13 +129,6 @@ public class HuffmanTablesDirectory extends Directory _tagNameMap.put(TAG_NUMBER_OF_TABLES, "Number of Tables"); } - // TODO remove this constructor, or document its deprecation? - @Deprecated - public HuffmanTablesDirectory() - { - this(new MetadataContext()); - } - public HuffmanTablesDirectory(@NotNull MetadataContext context) { this.setDescriptor(new HuffmanTablesDescriptor(this, context)); diff --git a/Tests/com/drew/metadata/jpeg/HuffmanTablesDirectoryTest.java b/Tests/com/drew/metadata/jpeg/HuffmanTablesDirectoryTest.java index 288e9dd69..0bfaf5cdc 100644 --- a/Tests/com/drew/metadata/jpeg/HuffmanTablesDirectoryTest.java +++ b/Tests/com/drew/metadata/jpeg/HuffmanTablesDirectoryTest.java @@ -20,6 +20,7 @@ */ package com.drew.metadata.jpeg; +import com.drew.metadata.MetadataContext; import org.junit.Before; import org.junit.Test; @@ -38,7 +39,7 @@ public class HuffmanTablesDirectoryTest @Before public void setUp() { - _directory = new HuffmanTablesDirectory(); + _directory = new HuffmanTablesDirectory(new MetadataContext()); } @Test