This is an automated email from the ASF dual-hosted git repository. ggregory pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-imaging.git
commit eb79d179dd02be8cc0920776ca4e7f21c3dd3cdc Author: Gary Gregory <[email protected]> AuthorDate: Mon Jan 5 06:59:59 2026 -0500 Javadoc --- .../imaging/formats/jpeg/JpegImageParser.java | 46 ++- .../imaging/formats/jpeg/iptc/IptcParser.java | 2 +- .../imaging/formats/jpeg/xmp/JpegRewriter.java | 21 ++ .../imaging/formats/psd/PsdImageParser.java | 3 + .../commons/imaging/formats/tiff/TiffContents.java | 39 +++ .../imaging/formats/tiff/TiffDirectory.java | 355 ++++++++++++++++++++- .../formats/tiff/constants/Tiff4TagConstants.java | 12 + .../formats/tiff/constants/TiffConstants.java | 51 ++- .../commons/imaging/icc/IccProfileParser.java | 14 + 9 files changed, 535 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/apache/commons/imaging/formats/jpeg/JpegImageParser.java b/src/main/java/org/apache/commons/imaging/formats/jpeg/JpegImageParser.java index fa6bc1a0..dc7cf05b 100644 --- a/src/main/java/org/apache/commons/imaging/formats/jpeg/JpegImageParser.java +++ b/src/main/java/org/apache/commons/imaging/formats/jpeg/JpegImageParser.java @@ -689,6 +689,15 @@ public class JpegImageParser extends AbstractImageParser<JpegImagingParameters> return "Jpeg-Custom"; } + /** + * Gets Photoshop metadata. + * + * @param byteSource the byte source. + * @param params the imaging parameters. + * @return the Photoshop metadata or null if not found. + * @throws ImagingException if an imaging error occurs. + * @throws IOException if an I/O error occurs. + */ public JpegPhotoshopMetadata getPhotoshopMetadata(final ByteSource byteSource, final JpegImagingParameters params) throws ImagingException, IOException { final List<AbstractSegment> abstractSegments = readSegments(byteSource, new int[] { JpegConstants.JPEG_APP13_MARKER, }, false); @@ -718,11 +727,12 @@ public class JpegImageParser extends AbstractImageParser<JpegImagingParameters> /** * Extracts embedded XML metadata as XML string. - * <p> * * @param byteSource File containing image data. * @param params Map of optional parameters, defined in ImagingConstants. * @return Xmp Xml as String, if present. Otherwise, returns null. + * @throws ImagingException if an imaging error occurs. + * @throws IOException if an I/O error occurs. */ @Override public String getXmpXml(final ByteSource byteSource, final XmpImagingParameters<JpegImagingParameters> params) throws ImagingException, IOException { @@ -768,6 +778,14 @@ public class JpegImageParser extends AbstractImageParser<JpegImagingParameters> return result.get(0); } + /** + * Checks if the image has an EXIF segment. + * + * @param byteSource the byte source. + * @return true if EXIF segment is present, false otherwise. + * @throws ImagingException if an imaging error occurs. + * @throws IOException if an I/O error occurs. + */ public boolean hasExifSegment(final ByteSource byteSource) throws ImagingException, IOException { final boolean[] result = { false, }; @@ -805,6 +823,14 @@ public class JpegImageParser extends AbstractImageParser<JpegImagingParameters> return result[0]; } + /** + * Checks if the image has an IPTC segment. + * + * @param byteSource the byte source. + * @return true if IPTC segment is present, false otherwise. + * @throws ImagingException if an imaging error occurs. + * @throws IOException if an I/O error occurs. + */ public boolean hasIptcSegment(final ByteSource byteSource) throws ImagingException, IOException { final boolean[] result = { false, }; @@ -842,6 +868,14 @@ public class JpegImageParser extends AbstractImageParser<JpegImagingParameters> return result[0]; } + /** + * Checks if the image has an XMP segment. + * + * @param byteSource the byte source. + * @return true if XMP segment is present, false otherwise. + * @throws ImagingException if an imaging error occurs. + * @throws IOException if an I/O error occurs. + */ public boolean hasXmpSegment(final ByteSource byteSource) throws ImagingException, IOException { final boolean[] result = { false, }; @@ -882,6 +916,16 @@ public class JpegImageParser extends AbstractImageParser<JpegImagingParameters> return ArrayUtils.contains(markers, marker); } + /** + * Reads segments from JPEG image. + * + * @param byteSource the byte source. + * @param markers the markers to read. + * @param returnAfterFirst whether to return after first match. + * @return the list of segments. + * @throws ImagingException if an imaging error occurs. + * @throws IOException if an I/O error occurs. + */ public List<AbstractSegment> readSegments(final ByteSource byteSource, final int[] markers, final boolean returnAfterFirst) throws ImagingException, IOException { final List<AbstractSegment> result = new ArrayList<>(); diff --git a/src/main/java/org/apache/commons/imaging/formats/jpeg/iptc/IptcParser.java b/src/main/java/org/apache/commons/imaging/formats/jpeg/iptc/IptcParser.java index 71c7b356..855e06ff 100644 --- a/src/main/java/org/apache/commons/imaging/formats/jpeg/iptc/IptcParser.java +++ b/src/main/java/org/apache/commons/imaging/formats/jpeg/iptc/IptcParser.java @@ -372,7 +372,7 @@ public class IptcParser extends BinaryFileParser { // private void writeIPTCRecord(BinaryOutputStream bos, ) - /* + /** * In practice, App13 segments are only used for Photoshop/IPTC metadata. However, we should not treat App13 signatures without Photoshop's signature as * Photoshop/IPTC segments. * diff --git a/src/main/java/org/apache/commons/imaging/formats/jpeg/xmp/JpegRewriter.java b/src/main/java/org/apache/commons/imaging/formats/jpeg/xmp/JpegRewriter.java index d69f34c9..790c0bd7 100644 --- a/src/main/java/org/apache/commons/imaging/formats/jpeg/xmp/JpegRewriter.java +++ b/src/main/java/org/apache/commons/imaging/formats/jpeg/xmp/JpegRewriter.java @@ -35,6 +35,10 @@ import org.apache.commons.imaging.formats.jpeg.iptc.IptcParser; * Interface for Exif write/update/remove functionality for Jpeg/JFIF images. */ public class JpegRewriter extends BinaryFileParser { + + /** + * Abstracts JFIF pieces. + */ protected abstract static class JFIFPiece { @Override public String toString() { @@ -293,10 +297,27 @@ public class JpegRewriter extends BinaryFileParser { return new JFIFPieces(pieces, segmentPieces); } + /** + * Filters segments using a filter. + * + * @param <T> the piece type. + * @param segments the segments. + * @param filter the filter. + * @return the filtered segments. + */ protected <T extends JFIFPiece> List<T> filterSegments(final List<T> segments, final SegmentFilter filter) { return filterSegments(segments, filter, false); } + /** + * Filters segments using a filter with optional reverse logic. + * + * @param <T> the piece type. + * @param segments the segments. + * @param filter the filter. + * @param reverse whether to reverse the filter logic. + * @return the filtered segments. + */ protected <T extends JFIFPiece> List<T> filterSegments(final List<T> segments, final SegmentFilter filter, final boolean reverse) { final List<T> result = new ArrayList<>(); diff --git a/src/main/java/org/apache/commons/imaging/formats/psd/PsdImageParser.java b/src/main/java/org/apache/commons/imaging/formats/psd/PsdImageParser.java index 90247d1e..007379b1 100644 --- a/src/main/java/org/apache/commons/imaging/formats/psd/PsdImageParser.java +++ b/src/main/java/org/apache/commons/imaging/formats/psd/PsdImageParser.java @@ -49,6 +49,9 @@ import org.apache.commons.imaging.formats.psd.datareaders.UncompressedDataReader import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.ArrayUtils; +/** + * Parses Adobe Photoshop PSD image files. + */ public class PsdImageParser extends AbstractImageParser<PsdImagingParameters> implements XmpEmbeddable { private static final String DEFAULT_EXTENSION = ImageFormats.PSD.getDefaultExtension(); diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/TiffContents.java b/src/main/java/org/apache/commons/imaging/formats/tiff/TiffContents.java index dec9f4b1..8588a0ac 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/TiffContents.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/TiffContents.java @@ -24,18 +24,44 @@ import org.apache.commons.imaging.ImagingException; import org.apache.commons.imaging.formats.tiff.taginfos.TagInfo; import org.apache.commons.imaging.internal.Debug; +/** + * The contents of a TIFF file including header, directories, and fields. + */ public class TiffContents { + /** + * The TIFF header. + */ public final TiffHeader header; + + /** + * The list of TIFF directories. + */ public final List<TiffDirectory> directories; + + /** + * The list of TIFF fields. + */ public final List<TiffField> tiffFields; + /** + * Constructs a new instance. + * + * @param tiffHeader the TIFF header. + * @param directories the list of directories. + * @param tiffFields the list of fields. + */ public TiffContents(final TiffHeader tiffHeader, final List<TiffDirectory> directories, final List<TiffField> tiffFields) { this.header = tiffHeader; this.directories = Collections.unmodifiableList(directories); this.tiffFields = Collections.unmodifiableList(tiffFields); } + /** + * Dissects the TIFF structure for debugging purposes. + * + * @throws ImagingException if an error occurs during dissection. + */ public void dissect() throws ImagingException { final List<AbstractTiffElement> elements = getElements(); @@ -63,6 +89,13 @@ public class TiffContents { Debug.debug(); } + /** + * Finds a field by tag. + * + * @param tag the tag to search for. + * @return the field, or null if not found. + * @throws ImagingException if an error occurs during search. + */ public TiffField findField(final TagInfo tag) throws ImagingException { for (final TiffDirectory directory : directories) { final TiffField field = directory.findField(tag); @@ -74,6 +107,12 @@ public class TiffContents { return null; } + /** + * Gets all TIFF elements including header, directories, and field data. + * + * @return the list of elements. + * @throws ImagingException if an error occurs. + */ public List<AbstractTiffElement> getElements() throws ImagingException { final List<AbstractTiffElement> result = new ArrayList<>(); diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/TiffDirectory.java b/src/main/java/org/apache/commons/imaging/formats/tiff/TiffDirectory.java index d08138d5..0b7fa4df 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/TiffDirectory.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/TiffDirectory.java @@ -65,6 +65,13 @@ import org.apache.commons.imaging.formats.tiff.taginfos.TagInfoXpString; public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffField> { public static final class ImageDataElement extends AbstractTiffElement { + + /** + * Constructs a new instance. + * + * @param offset the offset. + * @param length the length. + */ public ImageDataElement(final long offset, final int length) { super(offset, length); } @@ -75,6 +82,12 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF } } + /** + * Gets a description for a directory type. + * + * @param type the directory type. + * @return the description. + */ public static String description(final int type) { switch (type) { case TiffDirectoryConstants.DIRECTORY_TYPE_UNKNOWN: @@ -104,14 +117,35 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF */ private final ByteOrder headerByteOrder; + /** + * JPEG image data if present. + */ private JpegImageData jpegImageData; + /** + * Offset to the next directory. + */ private final long nextDirectoryOffset; + /** + * TIFF image data if present. + */ private AbstractTiffImageData abstractTiffImageData; + /** + * The directory type. + */ public final int type; + /** + * Constructs a new instance. + * + * @param type the directory type. + * @param entries the list of fields. + * @param offset the offset. + * @param nextDirectoryOffset the next directory offset. + * @param byteOrder the byte order. + */ public TiffDirectory(final int type, final List<TiffField> entries, final long offset, final long nextDirectoryOffset, final ByteOrder byteOrder) { super(offset, TiffConstants.DIRECTORY_HEADER_LENGTH + entries.size() * TiffConstants.ENTRY_LENGTH + TiffConstants.DIRECTORY_FOOTER_LENGTH); @@ -122,19 +156,42 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF this.headerByteOrder = byteOrder; } + /** + * Gets a description of this directory's type. + * + * @return the description. + */ public String description() { return description(type); } + /** + * Dumps all field information for debugging. + */ public void dump() { entries.forEach(TiffField::dump); } + /** + * Finds a field by tag. + * + * @param tag the tag to search for. + * @return the field, or null if not found. + * @throws ImagingException if an error occurs. + */ public TiffField findField(final TagInfo tag) throws ImagingException { final boolean failIfMissing = false; return findField(tag, failIfMissing); } + /** + * Finds a field by tag. + * + * @param tag the tag to search for. + * @param failIfMissing whether to throw an exception if not found. + * @return the field, or null if not found. + * @throws ImagingException if an error occurs or field is missing and failIfMissing is true. + */ public TiffField findField(final TagInfo tag, final boolean failIfMissing) throws ImagingException { for (final TiffField field : entries) { if (field.getTag() == tag.tag) { @@ -158,6 +215,11 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return headerByteOrder; } + /** + * Gets a copy of all directory entries. + * + * @return the list of fields. + */ public List<TiffField> getDirectoryEntries() { return new ArrayList<>(entries); } @@ -176,6 +238,13 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return result.toString(); } + /** + * Gets the value of a field. + * + * @param tag the tag. + * @return the field value, or null if not found. + * @throws ImagingException if an error occurs. + */ public Object getFieldValue(final TagInfo tag) throws ImagingException { final TiffField field = findField(tag); if (field == null) { @@ -184,6 +253,14 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return field.getValue(); } + /** + * Gets the value of an ASCII field. + * + * @param tag the tag. + * @param mustExist whether the field must exist. + * @return the field value, or null if not found. + * @throws ImagingException if an error occurs or field is missing and mustExist is true. + */ public String[] getFieldValue(final TagInfoAscii tag, final boolean mustExist) throws ImagingException { final TiffField field = findField(tag); if (field == null) { @@ -202,6 +279,13 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return tag.getValue(field.getByteOrder(), bytes); } + /** + * Gets the value of a byte field. + * + * @param tag the tag. + * @return the field value. + * @throws ImagingException if an error occurs or field is missing. + */ public byte getFieldValue(final TagInfoByte tag) throws ImagingException { final TiffField field = findField(tag); if (field == null) { @@ -216,6 +300,14 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return field.getByteArrayValue()[0]; } + /** + * Gets the value of a bytes field. + * + * @param tag the tag. + * @param mustExist whether the field must exist. + * @return the field value, or null if not found. + * @throws ImagingException if an error occurs or field is missing and mustExist is true. + */ public byte[] getFieldValue(final TagInfoBytes tag, final boolean mustExist) throws ImagingException { final TiffField field = findField(tag); if (field == null) { @@ -233,6 +325,13 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return field.getByteArrayValue(); } + /** + * Gets the value of a double field. + * + * @param tag the tag. + * @return the field value. + * @throws ImagingException if an error occurs or field is missing. + */ public double getFieldValue(final TagInfoDouble tag) throws ImagingException { final TiffField field = findField(tag); if (field == null) { @@ -248,6 +347,14 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return tag.getValue(field.getByteOrder(), bytes); } + /** + * Gets the value of a doubles field. + * + * @param tag the tag. + * @param mustExist whether the field must exist. + * @return the field value, or null if not found. + * @throws ImagingException if an error occurs or field is missing and mustExist is true. + */ public double[] getFieldValue(final TagInfoDoubles tag, final boolean mustExist) throws ImagingException { final TiffField field = findField(tag); if (field == null) { @@ -266,6 +373,13 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return tag.getValue(field.getByteOrder(), bytes); } + /** + * Gets the value of a float field. + * + * @param tag the tag. + * @return the field value. + * @throws ImagingException if an error occurs or field is missing. + */ public float getFieldValue(final TagInfoFloat tag) throws ImagingException { final TiffField field = findField(tag); if (field == null) { @@ -281,6 +395,14 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return tag.getValue(field.getByteOrder(), bytes); } + /** + * Gets the value of a floats field. + * + * @param tag the tag. + * @param mustExist whether the field must exist. + * @return the field value, or null if not found. + * @throws ImagingException if an error occurs or field is missing and mustExist is true. + */ public float[] getFieldValue(final TagInfoFloats tag, final boolean mustExist) throws ImagingException { final TiffField field = findField(tag); if (field == null) { @@ -299,6 +421,14 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return tag.getValue(field.getByteOrder(), bytes); } + /** + * Gets the value of a GPS text field. + * + * @param tag the tag. + * @param mustExist whether the field must exist. + * @return the field value, or null if not found. + * @throws ImagingException if an error occurs or field is missing and mustExist is true. + */ public String getFieldValue(final TagInfoGpsText tag, final boolean mustExist) throws ImagingException { final TiffField field = findField(tag); if (field == null) { @@ -307,9 +437,22 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF } return null; } + if (!tag.dataTypes.contains(field.getFieldType())) { + if (mustExist) { + throw new ImagingException("Required field \"" + tag.name + "\" has incorrect type " + field.getFieldType().getName()); + } + return null; + } return tag.getValue(field); } + /** + * Gets the value of a long field. + * + * @param tag the tag. + * @return the field value. + * @throws ImagingException if an error occurs or field is missing. + */ public int getFieldValue(final TagInfoLong tag) throws ImagingException { final TiffField field = findField(tag); if (field == null) { @@ -325,6 +468,14 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return tag.getValue(field.getByteOrder(), bytes); } + /** + * Gets the value of a longs field. + * + * @param tag the tag. + * @param mustExist whether the field must exist. + * @return the field value, or null if not found. + * @throws ImagingException if an error occurs or field is missing and mustExist is true. + */ public int[] getFieldValue(final TagInfoLongs tag, final boolean mustExist) throws ImagingException { final TiffField field = findField(tag); if (field == null) { @@ -343,6 +494,13 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return tag.getValue(field.getByteOrder(), bytes); } + /** + * Gets the value of a rational field. + * + * @param tag the tag. + * @return the field value. + * @throws ImagingException if an error occurs or field is missing. + */ public RationalNumber getFieldValue(final TagInfoRational tag) throws ImagingException { final TiffField field = findField(tag); if (field == null) { @@ -358,6 +516,14 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return tag.getValue(field.getByteOrder(), bytes); } + /** + * Gets the value of a rationals field. + * + * @param tag the tag. + * @param mustExist whether the field must exist. + * @return the field value, or null if not found. + * @throws ImagingException if an error occurs or field is missing and mustExist is true. + */ public RationalNumber[] getFieldValue(final TagInfoRationals tag, final boolean mustExist) throws ImagingException { final TiffField field = findField(tag); if (field == null) { @@ -376,6 +542,13 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return tag.getValue(field.getByteOrder(), bytes); } + /** + * Gets the value of a signed byte field. + * + * @param tag the tag. + * @return the field value. + * @throws ImagingException if an error occurs or field is missing. + */ public byte getFieldValue(final TagInfoSByte tag) throws ImagingException { final TiffField field = findField(tag); if (field == null) { @@ -390,6 +563,14 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return field.getByteArrayValue()[0]; } + /** + * Gets the value of a signed bytes field. + * + * @param tag the tag. + * @param mustExist whether the field must exist. + * @return the field value, or null if not found. + * @throws ImagingException if an error occurs or field is missing and mustExist is true. + */ public byte[] getFieldValue(final TagInfoSBytes tag, final boolean mustExist) throws ImagingException { final TiffField field = findField(tag); if (field == null) { @@ -407,6 +588,13 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return field.getByteArrayValue(); } + /** + * Gets the value of a short field. + * + * @param tag the tag. + * @return the field value. + * @throws ImagingException if an error occurs or field is missing. + */ public short getFieldValue(final TagInfoShort tag) throws ImagingException { final TiffField field = findField(tag); if (field == null) { @@ -422,6 +610,14 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return tag.getValue(field.getByteOrder(), bytes); } + /** + * Gets the value of a short or long field. + * + * @param tag the tag. + * @param mustExist whether the field must exist. + * @return the field value, or null if not found. + * @throws ImagingException if an error occurs or field is missing and mustExist is true. + */ public int[] getFieldValue(final TagInfoShortOrLong tag, final boolean mustExist) throws ImagingException { final TiffField field = findField(tag); if (field == null) { @@ -443,6 +639,14 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return ByteConversions.toInts(bytes, field.getByteOrder()); } + /** + * Gets the value of a shorts field. + * + * @param tag the tag. + * @param mustExist whether the field must exist. + * @return the field value, or null if not found. + * @throws ImagingException if an error occurs or field is missing and mustExist is true. + */ public short[] getFieldValue(final TagInfoShorts tag, final boolean mustExist) throws ImagingException { final TiffField field = findField(tag); if (field == null) { @@ -461,6 +665,13 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return tag.getValue(field.getByteOrder(), bytes); } + /** + * Gets the value of a signed long field. + * + * @param tag the tag. + * @return the field value. + * @throws ImagingException if an error occurs or field is missing. + */ public int getFieldValue(final TagInfoSLong tag) throws ImagingException { final TiffField field = findField(tag); if (field == null) { @@ -476,6 +687,14 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return tag.getValue(field.getByteOrder(), bytes); } + /** + * Gets the value of a signed longs field. + * + * @param tag the tag. + * @param mustExist whether the field must exist. + * @return the field value, or null if not found. + * @throws ImagingException if an error occurs or field is missing and mustExist is true. + */ public int[] getFieldValue(final TagInfoSLongs tag, final boolean mustExist) throws ImagingException { final TiffField field = findField(tag); if (field == null) { @@ -494,6 +713,13 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return tag.getValue(field.getByteOrder(), bytes); } + /** + * Gets the value of a signed rational field. + * + * @param tag the tag. + * @return the field value. + * @throws ImagingException if an error occurs or field is missing. + */ public RationalNumber getFieldValue(final TagInfoSRational tag) throws ImagingException { final TiffField field = findField(tag); if (field == null) { @@ -509,6 +735,14 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return tag.getValue(field.getByteOrder(), bytes); } + /** + * Gets the value of a signed rationals field. + * + * @param tag the tag. + * @param mustExist whether the field must exist. + * @return the field value, or null if not found. + * @throws ImagingException if an error occurs or field is missing and mustExist is true. + */ public RationalNumber[] getFieldValue(final TagInfoSRationals tag, final boolean mustExist) throws ImagingException { final TiffField field = findField(tag); if (field == null) { @@ -527,6 +761,13 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return tag.getValue(field.getByteOrder(), bytes); } + /** + * Gets the value of a signed short field. + * + * @param tag the tag. + * @return the field value. + * @throws ImagingException if an error occurs or field is missing. + */ public short getFieldValue(final TagInfoSShort tag) throws ImagingException { final TiffField field = findField(tag); if (field == null) { @@ -542,6 +783,14 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return tag.getValue(field.getByteOrder(), bytes); } + /** + * Gets the value of a signed shorts field. + * + * @param tag the tag. + * @param mustExist whether the field must exist. + * @return the field value, or null if not found. + * @throws ImagingException if an error occurs or field is missing and mustExist is true. + */ public short[] getFieldValue(final TagInfoSShorts tag, final boolean mustExist) throws ImagingException { final TiffField field = findField(tag); if (field == null) { @@ -560,6 +809,14 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return tag.getValue(field.getByteOrder(), bytes); } + /** + * Gets the value of an XP string field. + * + * @param tag the tag. + * @param mustExist whether the field must exist. + * @return the field value, or null if not found. + * @throws ImagingException if an error occurs or field is missing and mustExist is true. + */ public String getFieldValue(final TagInfoXpString tag, final boolean mustExist) throws ImagingException { final TiffField field = findField(tag); if (field == null) { @@ -568,13 +825,30 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF } return null; } + if (!tag.dataTypes.contains(field.getFieldType())) { + if (mustExist) { + throw new ImagingException("Required field \"" + tag.name + "\" has incorrect type " + field.getFieldType().getName()); + } + return null; + } return tag.getValue(field); } + /** + * Gets the JPEG image data. + * + * @return the JPEG image data, or null if not available. + */ public JpegImageData getJpegImageData() { return jpegImageData; } + /** + * Gets the JPEG raw image data element. + * + * @return the image data element. + * @throws ImagingException if an error occurs. + */ public ImageDataElement getJpegRawImageDataElement() throws ImagingException { final TiffField jpegInterchangeFormat = findField(TiffTagConstants.TIFF_TAG_JPEG_INTERCHANGE_FORMAT); final TiffField jpegInterchangeFormatLength = findField(TiffTagConstants.TIFF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH); @@ -588,6 +862,11 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF throw new ImagingException("Couldn't find image data."); } + /** + * Gets the offset to the next directory. + * + * @return the next directory offset. + */ public long getNextDirectoryOffset() { return nextDirectoryOffset; } @@ -599,9 +878,11 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF * TIFF directories that provide numerical data do not directly specify images, though it is possible to interpret the data as an image using this library. * TIFF files may contain multiple directories which are allowed to have different formats. Thus it is possible for a TIFF file to contain a mix of image * and floating-point raster data. + * </p> * <p> * If desired, sub-image data can be read from the file by using a Java Map instance to specify the subsection of the image that is required. The following * code illustrates the approach: + * </p> * * <pre> * int x; // coordinate (column) of corner of sub-image @@ -617,10 +898,10 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF * TiffRasterData raster = directory.readFloatingPointRasterData(params); * </pre> * - * @param params an optional parameter map instance - * @return a valid instance - * @throws ImagingException in the event of incompatible or malformed data - * @throws IOException in the event of an I/O error + * @param params an optional parameter map instance. + * @return a valid instance. + * @throws ImagingException in the event of incompatible or malformed data. + * @throws IOException in the event of an I/O error. */ public AbstractTiffRasterData getRasterData(final TiffImagingParameters params) throws ImagingException, IOException { @@ -628,6 +909,14 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return parser.getRasterData(this, headerByteOrder, params); } + /** + * Gets raw image data elements from offset and byte count fields. + * + * @param offsetsField the offsets field. + * @param byteCountsField the byte counts field. + * @return the list of image data elements. + * @throws ImagingException if an error occurs. + */ private List<ImageDataElement> getRawImageDataElements(final TiffField offsetsField, final TiffField byteCountsField) throws ImagingException { final long[] offsets = offsetsField.getLongArrayValue(); final int[] byteCounts = byteCountsField.getIntArrayValue(); @@ -643,6 +932,13 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return result; } + /** + * Gets a single ASCII field value. + * + * @param tag the tag. + * @return the field value. + * @throws ImagingException if an error occurs or field is missing. + */ public String getSingleFieldValue(final TagInfoAscii tag) throws ImagingException { final String[] result = getFieldValue(tag, true); if (result.length != 1) { @@ -651,6 +947,13 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return result[0]; } + /** + * Gets a single short or long field value. + * + * @param tag the tag. + * @return the field value. + * @throws ImagingException if an error occurs or field is missing. + */ public int getSingleFieldValue(final TagInfoShortOrLong tag) throws ImagingException { final int[] result = getFieldValue(tag, true); if (result.length != 1) { @@ -728,10 +1031,21 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return new TiffImageParser().getBufferedImage(this, headerByteOrder, params); } + /** + * Gets the TIFF image data. + * + * @return the TIFF image data, or null if not available. + */ public AbstractTiffImageData getTiffImageData() { return abstractTiffImageData; } + /** + * Gets the raw TIFF image data elements. + * + * @return the list of image data elements. + * @throws ImagingException if an error occurs. + */ public List<ImageDataElement> getTiffRawImageDataElements() throws ImagingException { final TiffField tileOffsets = findField(TiffTagConstants.TIFF_TAG_TILE_OFFSETS); final TiffField tileByteCounts = findField(TiffTagConstants.TIFF_TAG_TILE_BYTE_COUNTS); @@ -747,6 +1061,12 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF throw new ImagingException("Couldn't find image data."); } + /** + * Checks if this directory has JPEG image data. + * + * @return true if JPEG image data is present, false otherwise. + * @throws ImagingException if an error occurs. + */ public boolean hasJpegImageData() throws ImagingException { return null != findField(TiffTagConstants.TIFF_TAG_JPEG_INTERCHANGE_FORMAT); } @@ -766,6 +1086,12 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF } + /** + * Checks if this directory has TIFF image data. + * + * @return true if TIFF image data is present, false otherwise. + * @throws ImagingException if an error occurs. + */ public boolean hasTiffImageData() throws ImagingException { if (null != findField(TiffTagConstants.TIFF_TAG_TILE_OFFSETS)) { return true; @@ -790,6 +1116,12 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF || s[0] == TiffTagConstants.SAMPLE_FORMAT_VALUE_TWOS_COMPLEMENT_SIGNED_INTEGER); } + /** + * Checks if image data is stored in strips (as opposed to tiles). + * + * @return true if data is in strips, false if in tiles. + * @throws ImagingException if an error occurs. + */ public boolean imageDataInStrips() throws ImagingException { final TiffField tileOffsets = findField(TiffTagConstants.TIFF_TAG_TILE_OFFSETS); final TiffField tileByteCounts = findField(TiffTagConstants.TIFF_TAG_TILE_BYTE_COUNTS); @@ -810,14 +1142,29 @@ public class TiffDirectory extends AbstractTiffElement implements Iterable<TiffF return entries.iterator(); } + /** + * Sets the JPEG image data. + * + * @param value the JPEG image data. + */ public void setJpegImageData(final JpegImageData value) { this.jpegImageData = value; } + /** + * Sets the TIFF image data. + * + * @param rawImageData the TIFF image data. + */ public void setTiffImageData(final AbstractTiffImageData rawImageData) { this.abstractTiffImageData = rawImageData; } + /** + * Gets the number of fields in this directory. + * + * @return the number of fields. + */ public int size() { return entries.size(); } diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/constants/Tiff4TagConstants.java b/src/main/java/org/apache/commons/imaging/formats/tiff/constants/Tiff4TagConstants.java index dd220233..c102df31 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/constants/Tiff4TagConstants.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/constants/Tiff4TagConstants.java @@ -31,13 +31,25 @@ import org.apache.commons.imaging.formats.tiff.taginfos.TagInfoShort; */ public final class Tiff4TagConstants { + /** TIFF tag for color response unit. */ public static final TagInfoShort TIFF_TAG_COLOR_RESPONSE_UNIT = new TagInfoShort("ColorResponseUnit", 0x12C, TiffDirectoryType.TIFF_DIRECTORY_ROOT); + + /** Color response unit value 0.1. */ public static final int COLOR_RESPONSE_UNIT_VALUE_0_1 = 1; + + /** Color response unit value 0.01. */ public static final int COLOR_RESPONSE_UNIT_VALUE_0_01 = 2; + + /** Color response unit value 0.001. */ public static final int COLOR_RESPONSE_UNIT_VALUE_0_001 = 3; + + /** Color response unit value 0.0001. */ public static final int COLOR_RESPONSE_UNIT_VALUE_0_0001 = 4; + + /** Color response unit value 0.00001. */ public static final int COLOR_RESPONSE_UNIT_VALUE_0_00001 = 5; + /** List of all TIFF 4 tags. */ public static final List<TagInfo> ALL_TIFF_4_TAGS = Collections.unmodifiableList(Arrays.<TagInfo>asList(TIFF_TAG_COLOR_RESPONSE_UNIT)); private Tiff4TagConstants() { diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/constants/TiffConstants.java b/src/main/java/org/apache/commons/imaging/formats/tiff/constants/TiffConstants.java index 672f87e4..0428a014 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/constants/TiffConstants.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/constants/TiffConstants.java @@ -23,46 +23,93 @@ import java.nio.ByteOrder; */ public final class TiffConstants { + /** Default TIFF byte order (little-endian). */ public static final ByteOrder DEFAULT_TIFF_BYTE_ORDER = ByteOrder.LITTLE_ENDIAN; + /** TIFF standard version number. */ public static final int VERSION_STANDARD = 42; + + /** TIFF big version number. */ public static final int VERSION_BIG = 43; + /** TIFF header size. */ public static final int HEADER_SIZE = 8; + + /** TIFF directory header length. */ public static final int DIRECTORY_HEADER_LENGTH = 2; + + /** TIFF directory footer length. */ public static final int DIRECTORY_FOOTER_LENGTH = 4; + + /** TIFF entry length. */ public static final int ENTRY_LENGTH = 12; + + /** TIFF entry maximum value length. */ public static final int ENTRY_MAX_VALUE_LENGTH = 4; + + /** TIFF big entry length. */ public static final int ENTRY_LENGTH_BIG = 12; + + /** TIFF big entry maximum value length. */ public static final int ENTRY_MAX_VALUE_LENGTH_BIG = 8; + /** Compression type: uncompressed (1). */ public static final int COMPRESSION_UNCOMPRESSED_1 = 1; + + /** Compression type: uncompressed (alias). */ public static final int COMPRESSION_UNCOMPRESSED = COMPRESSION_UNCOMPRESSED_1; + + /** Compression type: CCITT 1D. */ public static final int COMPRESSION_CCITT_1D = 2; + + /** Compression type: CCITT Group 3. */ public static final int COMPRESSION_CCITT_GROUP_3 = 3; + + /** Compression type: CCITT Group 4. */ public static final int COMPRESSION_CCITT_GROUP_4 = 4; + + /** Compression type: LZW. */ public static final int COMPRESSION_LZW = 5; + + /** Compression type: JPEG (obsolete). */ public static final int COMPRESSION_JPEG_OBSOLETE = 6; + + /** Compression type: JPEG. */ public static final int COMPRESSION_JPEG = 7; + + /** Compression type: uncompressed (2). */ public static final int COMPRESSION_UNCOMPRESSED_2 = 32771; + + /** Compression type: PackBits. */ public static final int COMPRESSION_PACKBITS = 32773; + + /** Compression type: Deflate (PKZIP). */ public static final int COMPRESSION_DEFLATE_PKZIP = 32946; + + /** Compression type: Deflate (Adobe). */ public static final int COMPRESSION_DEFLATE_ADOBE = 8; + /** T4 options flag: 2D encoding. */ public static final int FLAG_T4_OPTIONS_2D = 1; + + /** T4 options flag: uncompressed mode. */ public static final int FLAG_T4_OPTIONS_UNCOMPRESSED_MODE = 2; + + /** T4 options flag: fill. */ public static final int FLAG_T4_OPTIONS_FILL = 4; + + /** T6 options flag: uncompressed mode. */ public static final int FLAG_T6_OPTIONS_UNCOMPRESSED_MODE = 2; /** * Specifies a larger strip-size to be used for compression. This setting generally produces smaller output files, but requires a slightly longer processing - * time. Used in conjunction with the PARAM_KEY_LZW_COMPRESSION_STRIP_SIZE + * time. Used in conjunction with the PARAM_KEY_LZW_COMPRESSION_STRIP_SIZE. */ public static final int LZW_COMPRESSION_BLOCK_SIZE_MEDIUM = 32768; /** * Specifies a larger strip-size to be used for compression. This setting generally produces smaller output files, but requires a slightly longer processing - * time. Used in conjunction with the PARAM_KEY_LZW_COMPRESSION_STRIP_SIZE + * time. Used in conjunction with the PARAM_KEY_LZW_COMPRESSION_STRIP_SIZE. */ public static final int LZW_COMPRESSION_BLOCK_SIZE_LARGE = 65536; diff --git a/src/main/java/org/apache/commons/imaging/icc/IccProfileParser.java b/src/main/java/org/apache/commons/imaging/icc/IccProfileParser.java index 35d91d85..74a096db 100644 --- a/src/main/java/org/apache/commons/imaging/icc/IccProfileParser.java +++ b/src/main/java/org/apache/commons/imaging/icc/IccProfileParser.java @@ -177,10 +177,24 @@ public class IccProfileParser extends BinaryFileParser { } } + /** + * Checks if the ICC profile from file is sRGB. + * + * @param file the file. + * @return true if sRGB, false otherwise. + * @throws IOException if an I/O error occurs. + */ public boolean isSrgb(final File file) throws IOException { return isSrgb(ByteSource.file(file)); } + /** + * Checks if the ICC_Profile is sRGB. + * + * @param iccProfile the ICC profile. + * @return true if sRGB, false otherwise. + * @throws IOException if an I/O error occurs. + */ public boolean isSrgb(final ICC_Profile iccProfile) throws IOException { return isSrgb(ByteSource.array(iccProfile.getData())); }
