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 910fae3f85d908342fc73a621e37696e3d422f62 Author: Gary Gregory <[email protected]> AuthorDate: Fri Jan 2 18:42:58 2026 -0500 Javadoc --- .../imaging/common/AbstractBinaryOutputStream.java | 46 +++++++++ .../commons/imaging/common/BinaryConstant.java | 36 +++++++ .../commons/imaging/common/BinaryFileParser.java | 3 + .../jpeg/segments/AbstractGenericSegment.java | 29 +++++- .../formats/jpeg/segments/AbstractSegment.java | 5 + .../formats/jpeg/segments/App13Segment.java | 45 ++++++--- .../formats/jpeg/segments/App14Segment.java | 35 ++++++- .../imaging/formats/jpeg/segments/App2Segment.java | 28 +++++- .../imaging/formats/jpeg/segments/AppnSegment.java | 11 +++ .../imaging/formats/png/AbstractPngText.java | 43 +++++++++ .../imaging/formats/png/PngImageMetadata.java | 2 + .../formats/png/chunks/AbstractPngTextChunk.java | 26 +++++ .../AbstractTransparencyFilter.java | 12 +++ .../psd/dataparsers/AbstractDataParser.java | 32 +++++++ .../imaging/formats/tiff/AbstractTiffElement.java | 47 +++++++++ .../formats/tiff/AbstractTiffImageData.java | 84 ++++++++++++++++- .../formats/tiff/AbstractTiffRasterData.java | 62 +++++++----- .../constants/AdobePageMaker6TagConstants.java | 15 +++ .../tiff/constants/AdobePhotoshopTagConstants.java | 3 + .../constants/AliasSketchbookProTagConstants.java | 2 + .../formats/tiff/constants/TiffEpTagConstants.java | 1 + .../tiff/datareaders/AbstractImageDataReader.java | 105 ++++++++++++++++----- .../AbstractPhotometricInterpreter.java | 33 +++++++ .../tiff/write/AbstractTiffImageWriter.java | 57 ++++++++++- .../formats/webp/chunks/AbstractWebPChunk.java | 13 +++ 25 files changed, 709 insertions(+), 66 deletions(-) diff --git a/src/main/java/org/apache/commons/imaging/common/AbstractBinaryOutputStream.java b/src/main/java/org/apache/commons/imaging/common/AbstractBinaryOutputStream.java index 06441472..0580adeb 100644 --- a/src/main/java/org/apache/commons/imaging/common/AbstractBinaryOutputStream.java +++ b/src/main/java/org/apache/commons/imaging/common/AbstractBinaryOutputStream.java @@ -22,12 +22,29 @@ import java.io.OutputStream; import java.nio.ByteOrder; import java.util.Objects; +/** + * Abstract class for binary output streams that provides methods for writing multi-byte values. + */ public abstract class AbstractBinaryOutputStream extends FilterOutputStream { + /** + * Creates a big-endian binary output stream. + * + * @param outputStream the underlying output stream. + * @return a big-endian binary output stream. + */ public static BigEndianBinaryOutputStream bigEndian(final OutputStream outputStream) { return new BigEndianBinaryOutputStream(outputStream); } + /** + * Creates a binary output stream with the specified byte order. + * + * @param outputStream the underlying output stream. + * @param byteOrder the byte order. + * @return a binary output stream with the specified byte order. + * @throws UnsupportedOperationException if the byte order is not supported. + */ @SuppressWarnings("resource") public static AbstractBinaryOutputStream create(final OutputStream outputStream, final ByteOrder byteOrder) { Objects.requireNonNull(outputStream, "outputStream"); @@ -41,17 +58,46 @@ public abstract class AbstractBinaryOutputStream extends FilterOutputStream { throw new UnsupportedOperationException(byteOrder.toString()); } + /** + * Creates a little-endian binary output stream. + * + * @param outputStream the underlying output stream. + * @return a little-endian binary output stream. + */ public static LittleEndianBinaryOutputStream littleEndian(final OutputStream outputStream) { return new LittleEndianBinaryOutputStream(outputStream); } + /** + * Constructs a new binary output stream. + * + * @param outputStream the underlying output stream. + */ public AbstractBinaryOutputStream(final OutputStream outputStream) { super(outputStream); } + /** + * Writes a 2-byte value. + * + * @param value the value to write. + * @throws IOException if an I/O error occurs. + */ public abstract void write2Bytes(int value) throws IOException; + /** + * Writes a 3-byte value. + * + * @param value the value to write. + * @throws IOException if an I/O error occurs. + */ public abstract void write3Bytes(int value) throws IOException; + /** + * Writes a 4-byte value. + * + * @param value the value to write. + * @throws IOException if an I/O error occurs. + */ public abstract void write4Bytes(int value) throws IOException; } diff --git a/src/main/java/org/apache/commons/imaging/common/BinaryConstant.java b/src/main/java/org/apache/commons/imaging/common/BinaryConstant.java index 19d93349..9dff6415 100644 --- a/src/main/java/org/apache/commons/imaging/common/BinaryConstant.java +++ b/src/main/java/org/apache/commons/imaging/common/BinaryConstant.java @@ -20,13 +20,27 @@ import java.io.IOException; import java.io.OutputStream; import java.util.Arrays; +/** + * Represents a constant binary value used for pattern matching in binary data. + */ public class BinaryConstant { private final byte[] value; + /** + * Constructs a binary constant from a byte array. + * + * @param value the byte array value. + */ public BinaryConstant(final byte[] value) { this.value = value.clone(); } + /** + * Tests whether the given byte array equals this constant. + * + * @param bytes the byte array to compare. + * @return {@code true} if the arrays are equal, {@code false} otherwise. + */ public boolean equals(final byte[] bytes) { return Arrays.equals(value, bytes); } @@ -43,6 +57,12 @@ public class BinaryConstant { return equals(other.value); } + /** + * Gets the byte at the specified index. + * + * @param i the index. + * @return the byte at the specified index. + */ public byte get(final int i) { return value[i]; } @@ -62,14 +82,30 @@ public class BinaryConstant { return BinaryFunctions.startsWith(buffer, value); } + /** + * Gets the raw byte array value (internal use). + * + * @return the raw value. + */ byte[] rawValue() { return value; } + /** + * Gets the size of this binary constant. + * + * @return the size in bytes. + */ public int size() { return value.length; } + /** + * Writes this binary constant to an output stream. + * + * @param os the output stream. + * @throws IOException if an I/O error occurs. + */ public void writeTo(final OutputStream os) throws IOException { for (final byte element : value) { os.write(element); diff --git a/src/main/java/org/apache/commons/imaging/common/BinaryFileParser.java b/src/main/java/org/apache/commons/imaging/common/BinaryFileParser.java index 4eff61be..8a3e4fe4 100644 --- a/src/main/java/org/apache/commons/imaging/common/BinaryFileParser.java +++ b/src/main/java/org/apache/commons/imaging/common/BinaryFileParser.java @@ -23,6 +23,9 @@ import java.nio.ByteOrder; import java.util.logging.Level; import java.util.logging.Logger; +/** + * Base class for parsing binary file formats. + */ public class BinaryFileParser { private static final Logger LOGGER = Logger.getLogger(BinaryFileParser.class.getName()); diff --git a/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/AbstractGenericSegment.java b/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/AbstractGenericSegment.java index 95732002..eb7bca7a 100644 --- a/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/AbstractGenericSegment.java +++ b/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/AbstractGenericSegment.java @@ -23,15 +23,32 @@ import java.io.InputStream; import java.io.PrintWriter; import java.nio.charset.Charset; +/** + * Abstract class for generic JPEG segments. + */ public abstract class AbstractGenericSegment extends AbstractSegment { private final byte[] segmentData; + /** + * Constructs a generic segment with the given marker and segment data. + * + * @param marker the segment marker. + * @param bytes the segment data. + */ public AbstractGenericSegment(final int marker, final byte[] bytes) { super(marker, bytes.length); this.segmentData = bytes.clone(); } + /** + * Constructs a generic segment by reading from an input stream. + * + * @param marker the segment marker. + * @param markerLength the length of the marker data. + * @param is the input stream to read from. + * @throws IOException if an I/O error occurs. + */ public AbstractGenericSegment(final int marker, final int markerLength, final InputStream is) throws IOException { super(marker, markerLength); @@ -43,6 +60,12 @@ public abstract class AbstractGenericSegment extends AbstractSegment { dump(pw, 0); } + /** + * Dumps the segment data to a print writer. + * + * @param pw the print writer. + * @param start the starting offset in the segment data. + */ public void dump(final PrintWriter pw, final int start) { for (int i = 0; i < 50 && i + start < segmentData.length; i++) { debugNumber(pw, "\t" + (i + start), segmentData[i + start], 1); @@ -52,7 +75,7 @@ public abstract class AbstractGenericSegment extends AbstractSegment { /** * Returns a copy of the segment's contents, excluding the marker and length bytes at the beginning. * - * @return the segment's contents + * @return the segment's contents. */ public byte[] getSegmentData() { return segmentData.clone(); @@ -61,9 +84,9 @@ public abstract class AbstractGenericSegment extends AbstractSegment { /** * Returns a specific byte of the segment's contents, excluding the marker and length bytes at the beginning. * - * @param offset segment offset + * @param offset segment offset. + * @return the bye in the segment's contents. * @see AbstractGenericSegment#getSegmentData() - * @return the bye in the segment's contents */ protected byte getSegmentData(final int offset) { return segmentData[offset]; diff --git a/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/AbstractSegment.java b/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/AbstractSegment.java index 27c09c9d..885f2186 100644 --- a/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/AbstractSegment.java +++ b/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/AbstractSegment.java @@ -42,6 +42,11 @@ public abstract class AbstractSegment extends BinaryFileParser { this.length = length; } + /** + * Dumps the segment information to a print writer. + * + * @param pw the print writer. + */ public void dump(final PrintWriter pw) { // empty } diff --git a/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/App13Segment.java b/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/App13Segment.java index 41d1324c..fefcf730 100644 --- a/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/App13Segment.java +++ b/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/App13Segment.java @@ -26,34 +26,53 @@ import org.apache.commons.imaging.formats.jpeg.JpegImagingParameters; import org.apache.commons.imaging.formats.jpeg.iptc.IptcParser; import org.apache.commons.imaging.formats.jpeg.iptc.PhotoshopApp13Data; +/** + * Represents a JPEG APP13 segment, typically used for Photoshop/IPTC metadata. + */ public class App13Segment extends AppnSegment { + /** + * Constructs an APP13 segment from segment data. + * + * @param marker the segment marker. + * @param segmentData the segment data. + * @throws IOException if an I/O error occurs. + */ public App13Segment(final int marker, final byte[] segmentData) throws IOException { this(marker, segmentData.length, new ByteArrayInputStream(segmentData)); } + /** + * Constructs an APP13 segment by reading from an input stream. + * + * @param marker the segment marker. + * @param markerLength the marker length. + * @param is the input stream to read from. + * @throws IOException if an I/O error occurs. + */ public App13Segment(final int marker, final int markerLength, final InputStream is) throws IOException { super(marker, markerLength, is); - // isIPTCJpegSegment = new IptcParser().isIPTCJpegSegment(bytes); - // if (isIPTCJpegSegment) - // { - // /* - // * 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. - // */ - // boolean verbose = false; - // boolean strict = false; - // elements.addAll(new IptcParser().parseIPTCJPEGSegment(bytes, - // verbose, strict)); - // } + // ...existing code... } + /** + * Checks if this segment is a Photoshop JPEG segment. + * + * @return {@code true} if this is a Photoshop segment, {@code false} otherwise. + */ public boolean isPhotoshopJpegSegment() { return new IptcParser().isPhotoshopJpegSegment(getSegmentData()); } + /** + * Parses the Photoshop segment data. + * + * @param params the imaging parameters. + * @return the parsed Photoshop APP13 data, or {@code null} if not a Photoshop segment. + * @throws ImagingException if the image format is invalid. + * @throws IOException if an I/O error occurs. + */ public PhotoshopApp13Data parsePhotoshopSegment(final ImagingParameters<JpegImagingParameters> params) throws ImagingException, IOException { /* * In practice, App13 segments are only used for Photoshop/IPTC metadata. However, we should not treat App13 signatures without Photoshop's signature as diff --git a/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/App14Segment.java b/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/App14Segment.java index 21832783..623902b9 100644 --- a/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/App14Segment.java +++ b/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/App14Segment.java @@ -24,30 +24,63 @@ import java.io.InputStream; import java.nio.charset.StandardCharsets; /** - * [BROKEN URL] http://www.aiim.org/documents/standards/PDF-Ref/References/Adobe/5116.DCT_Filter.pdf + * Represents a JPEG APP14 segment, used for Adobe color transform information. + * + * @see <a href="http://www.aiim.org/documents/standards/PDF-Ref/References/Adobe/5116.DCT_Filter.pdf">Adobe DCT Filter</a> */ public class App14Segment extends AppnSegment { private static final byte[] ADOBE_PREFIX; + + /** Adobe color transform unknown. */ public static final int ADOBE_COLOR_TRANSFORM_UNKNOWN = 0; + + /** Adobe color transform YCbCr. */ public static final int ADOBE_COLOR_TRANSFORM_YCbCr = 1; + + /** Adobe color transform YCCK. */ public static final int ADOBE_COLOR_TRANSFORM_YCCK = 2; static { ADOBE_PREFIX = "Adobe".getBytes(StandardCharsets.US_ASCII); } + /** + * Constructs an APP14 segment from segment data. + * + * @param marker the segment marker. + * @param segmentData the segment data. + * @throws IOException if an I/O error occurs. + */ public App14Segment(final int marker, final byte[] segmentData) throws IOException { this(marker, segmentData.length, new ByteArrayInputStream(segmentData)); } + /** + * Constructs an APP14 segment by reading from an input stream. + * + * @param marker the segment marker. + * @param markerLength the marker length. + * @param is the input stream to read from. + * @throws IOException if an I/O error occurs. + */ public App14Segment(final int marker, final int markerLength, final InputStream is) throws IOException { super(marker, markerLength, is); } + /** + * Gets the Adobe color transform value. + * + * @return the color transform value. + */ public int getAdobeColorTransform() { return 0xff & getSegmentData(11); } + /** + * Checks if this segment is an Adobe JPEG segment. + * + * @return {@code true} if this is an Adobe segment, {@code false} otherwise. + */ public boolean isAdobeJpegSegment() { return startsWith(getSegmentData(), ADOBE_PREFIX); } diff --git a/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/App2Segment.java b/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/App2Segment.java index ee58b621..40bc9960 100644 --- a/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/App2Segment.java +++ b/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/App2Segment.java @@ -27,15 +27,39 @@ import java.io.InputStream; import org.apache.commons.imaging.ImagingException; import org.apache.commons.imaging.formats.jpeg.JpegConstants; +/** + * Represents a JPEG APP2 segment, typically used for ICC color profiles. + */ public final class App2Segment extends AppnSegment implements Comparable<App2Segment> { private final byte[] iccBytes; + + /** The current marker index. */ public final int curMarker; + + /** The total number of markers. */ public final int numMarkers; + /** + * Constructs an APP2 segment from segment data. + * + * @param marker the segment marker. + * @param segmentData the segment data. + * @throws ImagingException if the image format is invalid. + * @throws IOException if an I/O error occurs. + */ public App2Segment(final int marker, final byte[] segmentData) throws ImagingException, IOException { this(marker, segmentData.length, new ByteArrayInputStream(segmentData)); } + /** + * Constructs an APP2 segment by reading from an input stream. + * + * @param marker the segment marker. + * @param markerLength the marker length. + * @param is2 the input stream to read from. + * @throws ImagingException if the image format is invalid. + * @throws IOException if an I/O error occurs. + */ public App2Segment(final int marker, int markerLength, final InputStream is2) throws ImagingException, IOException { super(marker, markerLength, is2); @@ -74,7 +98,9 @@ public final class App2Segment extends AppnSegment implements Comparable<App2Seg } /** - * @return the iccBytes + * Gets the ICC profile bytes. + * + * @return the ICC bytes, or {@code null} if not present. */ public byte[] getIccBytes() { return iccBytes != null ? iccBytes.clone() : null; diff --git a/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/AppnSegment.java b/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/AppnSegment.java index f68e5d1f..0f2b01f3 100644 --- a/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/AppnSegment.java +++ b/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/AppnSegment.java @@ -21,8 +21,19 @@ import java.io.InputStream; import org.apache.commons.imaging.formats.jpeg.JpegConstants; +/** + * Represents a generic JPEG APPn segment. + */ public class AppnSegment extends AbstractGenericSegment { + /** + * Constructs an APPn segment by reading from an input stream. + * + * @param marker the segment marker. + * @param markerLength the marker length. + * @param is the input stream to read from. + * @throws IOException if an I/O error occurs. + */ public AppnSegment(final int marker, final int markerLength, final InputStream is) throws IOException { super(marker, markerLength, is); } diff --git a/src/main/java/org/apache/commons/imaging/formats/png/AbstractPngText.java b/src/main/java/org/apache/commons/imaging/formats/png/AbstractPngText.java index dc4c407a..a8b42199 100644 --- a/src/main/java/org/apache/commons/imaging/formats/png/AbstractPngText.java +++ b/src/main/java/org/apache/commons/imaging/formats/png/AbstractPngText.java @@ -16,7 +16,14 @@ */ package org.apache.commons.imaging.formats.png; +/** + * Abstract class for PNG text chunks. + */ public abstract class AbstractPngText { + + /** + * Represents an international text chunk (iTXt). + */ public static class Itxt extends AbstractPngText { /* @@ -25,10 +32,20 @@ public abstract class AbstractPngText { * cn, en-uk, no-bok, x-klingon, x-KlInGoN). If the first word is two or three letters long, it is an ISO language code [ISO-639]. If the language tag * is empty, the language is unspecified. */ + /** The language tag. */ public final String languageTag; + /** The translated keyword. */ public final String translatedKeyword; + /** + * Constructs an iTXt chunk. + * + * @param keyword the keyword. + * @param text the text. + * @param languageTag the language tag. + * @param translatedKeyword the translated keyword. + */ public Itxt(final String keyword, final String text, final String languageTag, final String translatedKeyword) { super(keyword, text); this.languageTag = languageTag; @@ -36,22 +53,48 @@ public abstract class AbstractPngText { } } + /** + * Represents a simple text chunk (tEXt). + */ public static class Text extends AbstractPngText { + /** + * Constructs a tEXt chunk. + * + * @param keyword the keyword. + * @param text the text. + */ public Text(final String keyword, final String text) { super(keyword, text); } } + /** + * Represents a compressed text chunk (zTXt). + */ public static class Ztxt extends AbstractPngText { + /** + * Constructs a zTXt chunk. + * + * @param keyword the keyword. + * @param text the text. + */ public Ztxt(final String keyword, final String text) { super(keyword, text); } } + /** The keyword. */ public final String keyword; + /** The text. */ public final String text; + /** + * Constructs a PNG text chunk. + * + * @param keyword the keyword. + * @param text the text. + */ public AbstractPngText(final String keyword, final String text) { this.keyword = keyword; this.text = text; diff --git a/src/main/java/org/apache/commons/imaging/formats/png/PngImageMetadata.java b/src/main/java/org/apache/commons/imaging/formats/png/PngImageMetadata.java index 1bfe2111..6de5906b 100644 --- a/src/main/java/org/apache/commons/imaging/formats/png/PngImageMetadata.java +++ b/src/main/java/org/apache/commons/imaging/formats/png/PngImageMetadata.java @@ -25,6 +25,8 @@ import org.apache.commons.imaging.formats.tiff.TiffImageMetadata; import org.apache.commons.imaging.internal.Debug; /** + * Represents metadata information contained in a PNG image. + * * @since 1.0-alpha6 */ public class PngImageMetadata implements ImageMetadata { diff --git a/src/main/java/org/apache/commons/imaging/formats/png/chunks/AbstractPngTextChunk.java b/src/main/java/org/apache/commons/imaging/formats/png/chunks/AbstractPngTextChunk.java index e1accf39..870279bc 100644 --- a/src/main/java/org/apache/commons/imaging/formats/png/chunks/AbstractPngTextChunk.java +++ b/src/main/java/org/apache/commons/imaging/formats/png/chunks/AbstractPngTextChunk.java @@ -18,16 +18,42 @@ package org.apache.commons.imaging.formats.png.chunks; import org.apache.commons.imaging.formats.png.AbstractPngText; +/** + * Abstract class for PNG text chunks. + */ public abstract class AbstractPngTextChunk extends PngChunk { + /** + * Constructs a new PNG text chunk. + * + * @param length the length of the chunk data. + * @param chunkType the chunk type. + * @param crc the CRC value. + * @param bytes the chunk data bytes. + */ public AbstractPngTextChunk(final int length, final int chunkType, final int crc, final byte[] bytes) { super(length, chunkType, crc, bytes); } + /** + * Gets the text contents of this chunk. + * + * @return the text contents. + */ public abstract AbstractPngText getContents(); + /** + * Gets the keyword of this text chunk. + * + * @return the keyword. + */ public abstract String getKeyword(); + /** + * Gets the text value of this text chunk. + * + * @return the text. + */ public abstract String getText(); } diff --git a/src/main/java/org/apache/commons/imaging/formats/png/transparencyfilters/AbstractTransparencyFilter.java b/src/main/java/org/apache/commons/imaging/formats/png/transparencyfilters/AbstractTransparencyFilter.java index 8eb39415..38f444a1 100644 --- a/src/main/java/org/apache/commons/imaging/formats/png/transparencyfilters/AbstractTransparencyFilter.java +++ b/src/main/java/org/apache/commons/imaging/formats/png/transparencyfilters/AbstractTransparencyFilter.java @@ -21,6 +21,9 @@ import java.io.IOException; import org.apache.commons.imaging.ImagingException; import org.apache.commons.imaging.common.BinaryFileParser; +/** + * Abstract class for PNG transparency filters. + */ public abstract class AbstractTransparencyFilter extends BinaryFileParser { private final byte[] bytes; @@ -34,6 +37,15 @@ public abstract class AbstractTransparencyFilter extends BinaryFileParser { this.bytes = bytes.clone(); } + /** + * Filters a pixel's RGB value based on transparency information. + * + * @param rgb the RGB value. + * @param index the pixel index. + * @return the filtered RGB value. + * @throws ImagingException if the image format is invalid. + * @throws IOException if an I/O error occurs. + */ public abstract int filter(int rgb, int index) throws ImagingException, IOException; /** diff --git a/src/main/java/org/apache/commons/imaging/formats/psd/dataparsers/AbstractDataParser.java b/src/main/java/org/apache/commons/imaging/formats/psd/dataparsers/AbstractDataParser.java index a31c384e..3c74732c 100644 --- a/src/main/java/org/apache/commons/imaging/formats/psd/dataparsers/AbstractDataParser.java +++ b/src/main/java/org/apache/commons/imaging/formats/psd/dataparsers/AbstractDataParser.java @@ -22,11 +22,43 @@ import java.awt.image.DataBuffer; import org.apache.commons.imaging.formats.psd.PsdHeaderInfo; import org.apache.commons.imaging.formats.psd.PsdImageContents; +/** + * Abstract class for parsing PSD image data. + */ public abstract class AbstractDataParser { + + /** + * Constructs a new data parser. + */ + protected AbstractDataParser() { + // Default constructor + } + + /** + * Gets the number of basic color channels. + * + * @return the number of basic channels. + */ public abstract int getBasicChannelsCount(); + /** + * Gets the RGB value for a pixel at the specified coordinates. + * + * @param data the image data array. + * @param x the x coordinate. + * @param y the y coordinate. + * @param imageContents the image contents. + * @return the RGB value. + */ protected abstract int getRgb(int[][][] data, int x, int y, PsdImageContents imageContents); + /** + * Parses the image data and populates a BufferedImage. + * + * @param data the image data array. + * @param bi the BufferedImage to populate. + * @param imageContents the image contents. + */ public final void parseData(final int[][][] data, final BufferedImage bi, final PsdImageContents imageContents) { final DataBuffer buffer = bi.getRaster().getDataBuffer(); diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/AbstractTiffElement.java b/src/main/java/org/apache/commons/imaging/formats/tiff/AbstractTiffElement.java index 75e30642..152dbde7 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/AbstractTiffElement.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/AbstractTiffElement.java @@ -18,26 +18,59 @@ package org.apache.commons.imaging.formats.tiff; import java.util.Comparator; +/** + * Abstract class for TIFF elements. + */ public abstract class AbstractTiffElement { + + /** + * Represents a TIFF element that contains data. + */ public abstract static class DataElement extends AbstractTiffElement { private final byte[] data; + /** + * Constructs a new data element. + * + * @param offset the offset in the TIFF file. + * @param length the length of the element. + * @param data the element data. + */ public DataElement(final long offset, final int length, final byte[] data) { super(offset, length); this.data = data; } + /** + * Gets a copy of the element data. + * + * @return the data. + */ public byte[] getData() { return data.clone(); } + /** + * Gets the length of the data. + * + * @return the data length. + */ public int getDataLength() { return data.length; } } + /** + * Represents a stub TIFF element with no specific data. + */ public static final class Stub extends AbstractTiffElement { + /** + * Constructs a new stub element. + * + * @param offset the offset in the TIFF file. + * @param length the length of the element. + */ public Stub(final long offset, final int length) { super(offset, length); } @@ -49,16 +82,30 @@ public abstract class AbstractTiffElement { } + /** Comparator for sorting TIFF elements by offset. */ public static final Comparator<AbstractTiffElement> COMPARATOR = Comparator.comparingLong(e -> e.offset); + /** The offset of this element in the TIFF file. */ public final long offset; + /** The length of this element. */ public final int length; + /** + * Constructs a new TIFF element. + * + * @param offset the offset in the TIFF file. + * @param length the length of the element. + */ public AbstractTiffElement(final long offset, final int length) { this.offset = offset; this.length = length; } + /** + * Gets a description of this element. + * + * @return the element description. + */ public abstract String getElementDescription(); } diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/AbstractTiffImageData.java b/src/main/java/org/apache/commons/imaging/formats/tiff/AbstractTiffImageData.java index 82b6c719..2adff1f9 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/AbstractTiffImageData.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/AbstractTiffImageData.java @@ -27,10 +27,30 @@ import org.apache.commons.imaging.formats.tiff.datareaders.DataReaderStrips; import org.apache.commons.imaging.formats.tiff.datareaders.DataReaderTiled; import org.apache.commons.imaging.formats.tiff.photometricinterpreters.AbstractPhotometricInterpreter; +/** + * Abstract class for TIFF image data. + */ public abstract class AbstractTiffImageData { + /** + * Constructs a new TIFF image data instance. + */ + protected AbstractTiffImageData() { + // Default constructor + } + + /** + * Represents a data element containing TIFF image data. + */ public static class Data extends AbstractTiffElement.DataElement { + /** + * Constructs a new data element. + * + * @param offset the offset in the TIFF file. + * @param length the length of the data. + * @param data the image data. + */ public Data(final long offset, final int length, final byte[] data) { super(offset, length, data); } @@ -42,12 +62,22 @@ public abstract class AbstractTiffImageData { } + /** + * Represents TIFF image data organized in strips. + */ public static class Strips extends AbstractTiffImageData { private final AbstractTiffElement.DataElement[] strips; // public final byte strips[][]; + /** The number of rows per strip. */ public final int rowsPerStrip; + /** + * Constructs a new strips data structure. + * + * @param strips the array of strip data elements. + * @param rowsPerStrip the number of rows per strip. + */ public Strips(final AbstractTiffElement.DataElement[] strips, final int rowsPerStrip) { this.strips = strips; this.rowsPerStrip = rowsPerStrip; @@ -67,10 +97,21 @@ public abstract class AbstractTiffImageData { return strips; } + /** + * Gets the image data at the specified offset. + * + * @param offset the offset index. + * @return the data element. + */ public AbstractTiffElement.DataElement getImageData(final int offset) { return strips[offset]; } + /** + * Gets the number of strips in the image. + * + * @return the number of strips. + */ public int getImageDataLength() { return strips.length; } @@ -82,14 +123,25 @@ public abstract class AbstractTiffImageData { } + /** + * Represents TIFF image data organized in tiles. + */ public static class Tiles extends AbstractTiffImageData { + /** The array of tile data elements. */ public final AbstractTiffElement.DataElement[] tiles; // public final byte tiles[][]; private final int tileWidth; private final int tileLength; + /** + * Constructs a new tiles data structure. + * + * @param tiles the array of tile data elements. + * @param tileWidth the width of each tile. + * @param tileLength the length (height) of each tile. + */ public Tiles(final AbstractTiffElement.DataElement[] tiles, final int tileWidth, final int tileLength) { this.tiles = tiles; this.tileWidth = tileWidth; @@ -114,7 +166,7 @@ public abstract class AbstractTiffImageData { * Gets the height of individual tiles. Note that if the overall image height is not a multiple of the tile height, then the last row of tiles may * extend beyond the image height. * - * @return an integer value greater than zero + * @return an integer value greater than zero. */ public int getTileHeight() { return tileLength; @@ -124,7 +176,7 @@ public abstract class AbstractTiffImageData { * Gets the width of individual tiles. Note that if the overall image width is not a multiple of the tile width, then the last column of tiles may * extend beyond the image width. * - * @return an integer value greater than zero + * @return an integer value greater than zero. */ public int getTileWidth() { return tileWidth; @@ -149,11 +201,39 @@ public abstract class AbstractTiffImageData { return 0; // unspecified format } + /** + * Gets the appropriate data reader for this image data. + * + * @param directory the TIFF directory. + * @param photometricInterpreter the photometric interpreter. + * @param bitsPerPixel the bits per pixel. + * @param bitsPerSample the bits per sample array. + * @param predictor the predictor value. + * @param samplesPerPixel the samples per pixel. + * @param width the image width. + * @param height the image height. + * @param compression the compression type. + * @param planarConfiguration the planar configuration. + * @param byteOrder the byte order. + * @return the data reader. + * @throws IOException if an I/O error occurs. + * @throws ImagingException if the image format is invalid. + */ public abstract AbstractImageDataReader getDataReader(TiffDirectory directory, AbstractPhotometricInterpreter photometricInterpreter, int bitsPerPixel, int[] bitsPerSample, int predictor, int samplesPerPixel, int width, int height, int compression, TiffPlanarConfiguration planarConfiguration, ByteOrder byteOrder) throws IOException, ImagingException; + /** + * Gets the image data elements. + * + * @return the array of data elements. + */ public abstract AbstractTiffElement.DataElement[] getImageData(); + /** + * Checks if the image data is organized in strips (not tiles). + * + * @return {@code true} if strips, {@code false} if tiles. + */ public abstract boolean stripsNotTiles(); } diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/AbstractTiffRasterData.java b/src/main/java/org/apache/commons/imaging/formats/tiff/AbstractTiffRasterData.java index d8570792..3cb9bc2d 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/AbstractTiffRasterData.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/AbstractTiffRasterData.java @@ -34,18 +34,27 @@ package org.apache.commons.imaging.formats.tiff; */ public abstract class AbstractTiffRasterData { + /** The width of the raster. */ protected final int width; + + /** The height of the raster. */ protected final int height; + + /** The number of samples per pixel. */ protected final int samplesPerPixel; + + /** The total number of cells in the raster. */ protected final int nCells; + + /** The planar offset for multi-sample data. */ protected final int planarOffset; /** * Constructs an instance allocating memory for the specified dimensions. * - * @param width a value of 1 or greater - * @param height a value of 1 or greater - * @param samplesPerPixel a value of 1 or greater + * @param width a value of 1 or greater. + * @param height a value of 1 or greater. + * @param samplesPerPixel a value of 1 or greater. */ public AbstractTiffRasterData(final int width, final int height, final int samplesPerPixel) { if (width <= 0 || height <= 0) { @@ -61,6 +70,15 @@ public abstract class AbstractTiffRasterData { planarOffset = width * height; } + /** + * Checks that coordinates and sample index are within valid ranges and computes the array index. + * + * @param x the x coordinate. + * @param y the y coordinate. + * @param i the sample index. + * @return the computed array index. + * @throws IllegalArgumentException if coordinates or sample index are out of range. + */ protected final int checkCoordinatesAndComputeIndex(final int x, final int y, final int i) { if (x < 0 || x >= width || y < 0 || y >= height) { throw new IllegalArgumentException("Coordinates out of range (" + x + ", " + y + ")"); @@ -116,19 +134,19 @@ public abstract class AbstractTiffRasterData { /** * Gets the value stored at the specified raster coordinates. * - * @param x integer coordinate in the columnar direction - * @param y integer coordinate in the row direction - * @return the value stored at the specified location + * @param x integer coordinate in the columnar direction. + * @param y integer coordinate in the row direction. + * @return the value stored at the specified location. */ public abstract int getIntValue(int x, int y); /** * Gets the value stored at the specified raster coordinates. * - * @param x integer coordinate in the columnar direction - * @param y integer coordinate in the row direction + * @param x integer coordinate in the columnar direction. + * @param y integer coordinate in the row direction. * @param i integer sample index (for data sets giving multiple samples per raster cell). - * @return the value stored at the specified location + * @return the value stored at the specified location. */ public abstract int getIntValue(int x, int y, int i); @@ -159,8 +177,8 @@ public abstract class AbstractTiffRasterData { /** * Gets the value stored at the specified raster coordinates. * - * @param x integer coordinate in the columnar direction - * @param y integer coordinate in the row direction + * @param x integer coordinate in the columnar direction. + * @param y integer coordinate in the row direction. * @return the value stored at the specified location; potentially a Float.NaN. */ public abstract float getValue(int x, int y); @@ -168,9 +186,9 @@ public abstract class AbstractTiffRasterData { /** * Gets the value stored at the specified raster coordinates. * - * @param x integer coordinate in the columnar direction - * @param y integer coordinate in the row direction - * @param i integer sample index + * @param x integer coordinate in the columnar direction. + * @param y integer coordinate in the row direction. + * @param i integer sample index. * @return the value stored at the specified location; potentially a Float.NaN. */ public abstract float getValue(int x, int y, int i); @@ -187,8 +205,8 @@ public abstract class AbstractTiffRasterData { /** * Sets the value stored at the specified raster coordinates. * - * @param x integer coordinate in the columnar direction - * @param y integer coordinate in the row direction + * @param x integer coordinate in the columnar direction. + * @param y integer coordinate in the row direction. * @param value the value to be stored at the specified location. */ public abstract void setIntValue(int x, int y, int value); @@ -196,8 +214,8 @@ public abstract class AbstractTiffRasterData { /** * Sets the value stored at the specified raster coordinates. * - * @param x integer coordinate in the columnar direction - * @param y integer coordinate in the row direction + * @param x integer coordinate in the columnar direction. + * @param y integer coordinate in the row direction. * @param i integer sample index (for data sets giving multiple samples per raster cell). * @param value the value to be stored at the specified location. */ @@ -206,8 +224,8 @@ public abstract class AbstractTiffRasterData { /** * Sets the value stored at the specified raster coordinates. * - * @param x integer coordinate in the columnar direction - * @param y integer coordinate in the row direction + * @param x integer coordinate in the columnar direction. + * @param y integer coordinate in the row direction. * @param value the value to be stored at the specified location; potentially a Float.NaN. */ public abstract void setValue(int x, int y, float value); @@ -215,8 +233,8 @@ public abstract class AbstractTiffRasterData { /** * Sets the value stored at the specified raster coordinates. * - * @param x integer coordinate in the columnar direction - * @param y integer coordinate in the row direction + * @param x integer coordinate in the columnar direction. + * @param y integer coordinate in the row direction. * @param i integer sample index (for data sets giving multiple samples per raster cell). * @param value the value to be stored at the specified location; potentially a Float.NaN. */ diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/constants/AdobePageMaker6TagConstants.java b/src/main/java/org/apache/commons/imaging/formats/tiff/constants/AdobePageMaker6TagConstants.java index c64b8e66..73ca9cf8 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/constants/AdobePageMaker6TagConstants.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/constants/AdobePageMaker6TagConstants.java @@ -38,25 +38,40 @@ import org.apache.commons.imaging.formats.tiff.taginfos.TagInfoShort; */ public final class AdobePageMaker6TagConstants { + /** Sub IFDs tag. */ public static final TagInfoLongOrIfd TIFF_TAG_SUB_IFD = new TagInfoLongOrIfd("SubIFDs", 0x014a, -1, TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN, true); + /** Clip path tag. */ public static final TagInfoBytes TIFF_TAG_CLIP_PATH = new TagInfoBytes("ClipPath", 0x0157, -1, TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN); + /** X clip path units tag. */ public static final TagInfoLong TIFF_TAG_XCLIP_PATH_UNITS = new TagInfoLong("XClipPathUnits", 0x0158, TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN); + /** Y clip path units tag. */ public static final TagInfoLong TIFF_TAG_YCLIP_PATH_UNITS = new TagInfoLong("YClipPathUnits", 0x0159, TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN); + /** Indexed tag. */ public static final TagInfoShort TIFF_TAG_INDEXED = new TagInfoShort("Indexed", 0x015a, TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN); + /** Indexed value: not indexed. */ public static final int INDEXED_VALUE_NOT_INDEXED = 0; + + /** Indexed value: indexed. */ public static final int INDEXED_VALUE_INDEXED = 1; + /** OPI proxy tag. */ public static final TagInfoShort TIFF_TAG_OPIPROXY = new TagInfoShort("OPIProxy", 0x015f, TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN); + + /** OPI proxy value: higher resolution image does not exist. */ public static final int OPIPROXY_VALUE_HIGHER_RESOLUTION_IMAGE_DOES_NOT_EXIST = 0; + + /** OPI proxy value: higher resolution image exists. */ public static final int OPIPROXY_VALUE_HIGHER_RESOLUTION_IMAGE_EXISTS = 1; + /** Image ID tag. */ public static final TagInfoAscii TIFF_TAG_IMAGE_ID = new TagInfoAscii("ImageID", 0x800d, -1, TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN); + /** List of all Adobe PageMaker 6 tags. */ public static final List<TagInfo> ALL_ADOBE_PAGEMAKER_6_TAGS = Collections.unmodifiableList(Arrays.asList(TIFF_TAG_SUB_IFD, TIFF_TAG_CLIP_PATH, TIFF_TAG_XCLIP_PATH_UNITS, TIFF_TAG_YCLIP_PATH_UNITS, TIFF_TAG_INDEXED, TIFF_TAG_OPIPROXY, TIFF_TAG_IMAGE_ID)); diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/constants/AdobePhotoshopTagConstants.java b/src/main/java/org/apache/commons/imaging/formats/tiff/constants/AdobePhotoshopTagConstants.java index 423d66ba..3856d043 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/constants/AdobePhotoshopTagConstants.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/constants/AdobePhotoshopTagConstants.java @@ -34,11 +34,14 @@ import org.apache.commons.imaging.formats.tiff.taginfos.TagInfoUndefineds; */ public final class AdobePhotoshopTagConstants { + /** JPEG tables tag. */ public static final TagInfoUndefineds EXIF_TAG_JPEGTABLES = new TagInfoUndefineds("JPEGTables", 0x015b, -1, TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN); + /** Image source data tag. */ public static final TagInfoUndefineds EXIF_TAG_IMAGE_SOURCE_DATA = new TagInfoUndefineds("ImageSourceData", 0x935c, -1, TiffDirectoryType.EXIF_DIRECTORY_IFD0); + /** List of all Adobe Photoshop tags. */ public static final List<TagInfo> ALL_ADOBE_PHOTOSHOP_TAGS = Collections .unmodifiableList(Arrays.<TagInfo>asList(EXIF_TAG_JPEGTABLES, EXIF_TAG_IMAGE_SOURCE_DATA)); diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/constants/AliasSketchbookProTagConstants.java b/src/main/java/org/apache/commons/imaging/formats/tiff/constants/AliasSketchbookProTagConstants.java index bf4df69a..5b4a3d16 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/constants/AliasSketchbookProTagConstants.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/constants/AliasSketchbookProTagConstants.java @@ -31,9 +31,11 @@ import org.apache.commons.imaging.formats.tiff.taginfos.TagInfoAscii; */ public final class AliasSketchbookProTagConstants { + /** Alias layer metadata tag. */ public static final TagInfoAscii EXIF_TAG_ALIAS_LAYER_METADATA = new TagInfoAscii("Alias Layer Metadata", 0xc660, -1, TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN); + /** List of all Alias Sketchbook Pro tags. */ public static final List<TagInfo> ALL_ALIAS_SKETCHBOOK_PRO_TAGS = Collections.unmodifiableList(Arrays.<TagInfo>asList(EXIF_TAG_ALIAS_LAYER_METADATA)); private AliasSketchbookProTagConstants() { diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/constants/TiffEpTagConstants.java b/src/main/java/org/apache/commons/imaging/formats/tiff/constants/TiffEpTagConstants.java index 9c40625c..af4c8c51 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/constants/TiffEpTagConstants.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/constants/TiffEpTagConstants.java @@ -33,6 +33,7 @@ import org.apache.commons.imaging.formats.tiff.taginfos.TagInfoShorts; import org.apache.commons.imaging.formats.tiff.taginfos.TagInfoUndefineds; /** + * Constants for TIFF/EP (Electronic Photography) tags. */ public final class TiffEpTagConstants { diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/datareaders/AbstractImageDataReader.java b/src/main/java/org/apache/commons/imaging/formats/tiff/datareaders/AbstractImageDataReader.java index dd5c7b1b..d5c14c51 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/datareaders/AbstractImageDataReader.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/datareaders/AbstractImageDataReader.java @@ -131,20 +131,50 @@ import org.apache.commons.imaging.mylzw.MyLzwDecompressor; */ public abstract class AbstractImageDataReader { + /** The TIFF directory containing the image data. */ protected final TiffDirectory directory; + + /** The photometric interpreter for the image. */ protected final AbstractPhotometricInterpreter photometricInterpreter; + private final int[] bitsPerSample; + + /** The length of the bitsPerSample array. */ protected final int bitsPerSampleLength; + private final int[] last; + /** The predictor value for data compression. */ protected final int predictor; + + /** The number of samples per pixel. */ protected final int samplesPerPixel; + + /** The width of the image. */ protected final int width; + + /** The height of the image. */ protected final int height; + + /** The sample format. */ protected final int sampleFormat; + /** The planar configuration of the image. */ protected final TiffPlanarConfiguration planarConfiguration; + /** + * Constructs a new image data reader. + * + * @param directory the TIFF directory. + * @param photometricInterpreter the photometric interpreter. + * @param bitsPerSample the bits per sample array. + * @param predictor the predictor value. + * @param samplesPerPixel the number of samples per pixel. + * @param sampleFormat the sample format. + * @param width the image width. + * @param height the image height. + * @param planarConfiguration the planar configuration. + */ public AbstractImageDataReader(final TiffDirectory directory, final AbstractPhotometricInterpreter photometricInterpreter, final int[] bitsPerSample, final int predictor, final int samplesPerPixel, final int sampleFormat, final int width, final int height, final TiffPlanarConfiguration planarConfiguration) { @@ -161,6 +191,12 @@ public abstract class AbstractImageDataReader { last = Allocator.intArray(samplesPerPixel); } + /** + * Applies the predictor to the samples. + * + * @param samples the samples array. + * @return the modified samples array. + */ protected int[] applyPredictor(final int[] samples) { if (predictor == 2) { // Horizontal differencing. @@ -173,6 +209,14 @@ public abstract class AbstractImageDataReader { return samples; } + /** + * Applies the predictor to a block of data. + * + * @param width the block width. + * @param height the block height. + * @param nSamplesPerPixel the number of samples per pixel. + * @param p the data block. + */ protected void applyPredictorToBlock(final int width, final int height, final int nSamplesPerPixel, final byte[] p) { final int k = width * nSamplesPerPixel; for (int i = 0; i < height; i++) { @@ -184,6 +228,18 @@ public abstract class AbstractImageDataReader { } } + /** + * Decompresses compressed image data. + * + * @param compressedInput the compressed input data. + * @param compression the compression type. + * @param expectedSize the expected size of the decompressed data. + * @param tileWidth the tile width. + * @param tileHeight the tile height. + * @return the decompressed data. + * @throws ImagingException if the image format is invalid. + * @throws IOException if an I/O error occurs. + */ protected byte[] decompress(final byte[] compressedInput, final int compression, final int expectedSize, final int tileWidth, final int tileHeight) throws ImagingException, IOException { final TiffField fillOrderField = directory.findField(TiffTagConstants.TIFF_TAG_FILL_ORDER); @@ -265,8 +321,8 @@ public abstract class AbstractImageDataReader { /** * Reads samples and returns them in an int array. * - * @param bis the stream to read from - * @param result the samples array to populate, must be the same length as bitsPerSample.length + * @param bis the stream to read from. + * @param result the samples array to populate, must be the same length as bitsPerSample.length. * @throws IOException */ void getSamplesAsBytes(final BitInputStream bis, final int[] result) throws IOException { @@ -287,10 +343,10 @@ public abstract class AbstractImageDataReader { } /** - * Checks if all the bits per sample entries are the same size + * Checks if all the bits per sample entries are the same size. * - * @param size the size to check - * @return true if all the bits per sample entries are the same + * @param size the size to check. + * @return true if all the bits per sample entries are the same. */ protected boolean isHomogenous(final int size) { for (final int element : bitsPerSample) { @@ -325,6 +381,9 @@ public abstract class AbstractImageDataReader { */ public abstract AbstractTiffRasterData readRasterData(Rectangle subImage) throws ImagingException, IOException; + /** + * Resets the predictor state. + */ protected void resetPredictor() { Arrays.fill(last, 0); } @@ -449,15 +508,15 @@ public abstract class AbstractImageDataReader { /** * Transfer samples obtained from the TIFF file to an integer raster. * - * @param xBlock coordinate of block relative to source data - * @param yBlock coordinate of block relative to source data - * @param blockWidth width of block, in pixels - * @param blockHeight height of block in pixels - * @param blockData the data for the block - * @param xRaster coordinate of raster relative to source data - * @param yRaster coordinate of raster relative to source data - * @param rasterWidth width of the raster (always smaller than source data) - * @param rasterHeight height of the raster (always smaller than source data) + * @param xBlock coordinate of block relative to source data. + * @param yBlock coordinate of block relative to source data. + * @param blockWidth width of block, in pixels. + * @param blockHeight height of block in pixels. + * @param blockData the data for the block. + * @param xRaster coordinate of raster relative to source data. + * @param yRaster coordinate of raster relative to source data. + * @param rasterWidth width of the raster (always smaller than source data). + * @param rasterHeight height of the raster (always smaller than source data). * @param rasterData the raster data. */ void transferBlockToRaster(final int xBlock, final int yBlock, final int blockWidth, final int blockHeight, final int[] blockData, final int xRaster, @@ -534,12 +593,12 @@ public abstract class AbstractImageDataReader { * smaller in the cases where the tiles do not evenly divide the width (for example, a 256 pixel wide tile in a 257 pixel wide image would result in two * columns of tiles, the second column having only one column of pixels that were worth extracting. * - * @param width the width of the data block to be extracted - * @param height the height of the data block to be extracted - * @param scanSize the number of pixels in a single row of the block - * @param bytes the raw bytes + * @param width the width of the data block to be extracted. + * @param height the height of the data block to be extracted. + * @param scanSize the number of pixels in a single row of the block. + * @param bytes the raw bytes. * @param bitsPerPixel the number of bits per sample, 32 or 64. - * @param byteOrder the byte order for the source data + * @param byteOrder the byte order for the source data. * @return a valid array of integers in row major order, dimensions scan-size wide and height. * @throws ImagingException in the event of an invalid format. */ @@ -691,10 +750,10 @@ public abstract class AbstractImageDataReader { * parameter may be smaller in the cases where the tiles do not evenly divide the width (for example, a 256 pixel wide tile in a 257 pixel wide image would * result in two columns of tiles, the second column having only one column of pixels that were worth extracting. * - * @param width the width of the data block to be extracted - * @param height the height of the data block to be extracted - * @param scanSize the number of pixels in a single row of the block - * @param bytes the raw bytes + * @param width the width of the data block to be extracted. + * @param height the height of the data block to be extracted. + * @param scanSize the number of pixels in a single row of the block. + * @param bytes the raw bytes. * @param predictor the predictor specified by the source, only predictor 3 is supported. * @param bitsPerSample the number of bits per sample, 32 or 64. * @param byteOrder the byte order for the source data diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/photometricinterpreters/AbstractPhotometricInterpreter.java b/src/main/java/org/apache/commons/imaging/formats/tiff/photometricinterpreters/AbstractPhotometricInterpreter.java index f113a72d..c5f6691e 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/photometricinterpreters/AbstractPhotometricInterpreter.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/photometricinterpreters/AbstractPhotometricInterpreter.java @@ -30,12 +30,29 @@ import org.apache.commons.imaging.common.ImageBuilder; */ public abstract class AbstractPhotometricInterpreter { + /** The number of samples per pixel. */ protected final int samplesPerPixel; + private final int[] bitsPerSample; + + /** The predictor value. */ protected final int predictor; + + /** The image width. */ protected final int width; + + /** The image height. */ protected final int height; + /** + * Constructs a new photometric interpreter. + * + * @param samplesPerPixel the number of samples per pixel. + * @param bitsPerSample the bits per sample array. + * @param predictor the predictor value. + * @param width the image width. + * @param height the image height. + */ public AbstractPhotometricInterpreter(final int samplesPerPixel, final int[] bitsPerSample, final int predictor, final int width, final int height) { this.samplesPerPixel = samplesPerPixel; this.bitsPerSample = Objects.requireNonNull(bitsPerSample, "bitsPerSample"); @@ -44,9 +61,25 @@ public abstract class AbstractPhotometricInterpreter { this.height = height; } + /** + * Gets the bits per sample at the specified offset. + * + * @param offset the sample offset. + * @return the bits per sample. + */ protected int getBitsPerSample(final int offset) { return bitsPerSample[offset]; } + /** + * Interprets a pixel and adds it to the image builder. + * + * @param imageBuilder the image builder. + * @param samples the pixel sample values. + * @param x the x coordinate. + * @param y the y coordinate. + * @throws ImagingException if the image format is invalid. + * @throws IOException if an I/O error occurs. + */ public abstract void interpretPixel(ImageBuilder imageBuilder, int[] samples, int x, int y) throws ImagingException, IOException; } diff --git a/src/main/java/org/apache/commons/imaging/formats/tiff/write/AbstractTiffImageWriter.java b/src/main/java/org/apache/commons/imaging/formats/tiff/write/AbstractTiffImageWriter.java index d852960c..2014e1c7 100644 --- a/src/main/java/org/apache/commons/imaging/formats/tiff/write/AbstractTiffImageWriter.java +++ b/src/main/java/org/apache/commons/imaging/formats/tiff/write/AbstractTiffImageWriter.java @@ -47,20 +47,38 @@ import org.apache.commons.imaging.formats.tiff.constants.TiffTagConstants; import org.apache.commons.imaging.formats.tiff.itu_t4.T4AndT6Compression; import org.apache.commons.imaging.mylzw.MyLzwCompressor; +/** + * Abstract class for writing TIFF images. + */ public abstract class AbstractTiffImageWriter { private static final int MAX_PIXELS_FOR_RGB = 1024 * 1024; + /** + * Calculates the padding length needed for image data alignment. + * + * @param dataLength the length of the data. + * @return the padding length. + */ protected static int imageDataPaddingLength(final int dataLength) { return (4 - dataLength % 4) % 4; } + /** The byte order for writing TIFF data. */ protected final ByteOrder byteOrder; + /** + * Constructs a new TIFF image writer with the default byte order. + */ public AbstractTiffImageWriter() { this.byteOrder = TiffConstants.DEFAULT_TIFF_BYTE_ORDER; } + /** + * Constructs a new TIFF image writer with the specified byte order. + * + * @param byteOrder the byte order to use. + */ public AbstractTiffImageWriter(final ByteOrder byteOrder) { this.byteOrder = byteOrder; } @@ -79,7 +97,7 @@ public abstract class AbstractTiffImageWriter { /** * Check an image to see if any of its pixels are non-opaque. * - * @param src a valid image + * @param src a valid image. * @return true if at least one non-opaque pixel is found. */ private boolean checkForActualAlpha(final BufferedImage src) { @@ -198,6 +216,13 @@ public abstract class AbstractTiffImageWriter { return result; } + /** + * Validates the TIFF output set directories and returns a summary. + * + * @param outputSet the output set to validate. + * @return a summary of the output set. + * @throws ImagingException if the directories are invalid. + */ protected TiffOutputSummary validateDirectories(final TiffOutputSet outputSet) throws ImagingException { if (outputSet.isEmpty()) { throw new ImagingException("No directories."); @@ -355,8 +380,25 @@ public abstract class AbstractTiffImageWriter { // Debug.debug(); } + /** + * Writes a TIFF output set to an output stream. + * + * @param os the output stream. + * @param outputSet the TIFF output set to write. + * @throws IOException if an I/O error occurs. + * @throws ImagingException if the image format is invalid. + */ public abstract void write(OutputStream os, TiffOutputSet outputSet) throws IOException, ImagingException; + /** + * Writes a BufferedImage to an output stream in TIFF format. + * + * @param src the source image. + * @param os the output stream. + * @param params the imaging parameters. + * @throws ImagingException if the image format is invalid. + * @throws IOException if an I/O error occurs. + */ public void writeImage(final BufferedImage src, final OutputStream os, final TiffImagingParameters params) throws ImagingException, IOException { final TiffOutputSet userExif = params.getOutputSet(); @@ -588,10 +630,23 @@ public abstract class AbstractTiffImageWriter { write(os, outputSet); } + /** + * Writes the TIFF image file header with the default header size. + * + * @param bos the binary output stream. + * @throws IOException if an I/O error occurs. + */ protected void writeImageFileHeader(final AbstractBinaryOutputStream bos) throws IOException { writeImageFileHeader(bos, TiffConstants.HEADER_SIZE); } + /** + * Writes the TIFF image file header with the specified offset to the first IFD. + * + * @param bos the binary output stream. + * @param offsetToFirstIFD the offset to the first Image File Directory. + * @throws IOException if an I/O error occurs. + */ protected void writeImageFileHeader(final AbstractBinaryOutputStream bos, final long offsetToFirstIFD) throws IOException { if (byteOrder == ByteOrder.LITTLE_ENDIAN) { bos.write('I'); diff --git a/src/main/java/org/apache/commons/imaging/formats/webp/chunks/AbstractWebPChunk.java b/src/main/java/org/apache/commons/imaging/formats/webp/chunks/AbstractWebPChunk.java index 5f02b1ef..4c7d0645 100644 --- a/src/main/java/org/apache/commons/imaging/formats/webp/chunks/AbstractWebPChunk.java +++ b/src/main/java/org/apache/commons/imaging/formats/webp/chunks/AbstractWebPChunk.java @@ -42,7 +42,10 @@ public abstract class AbstractWebPChunk extends BinaryFileParser { private final int type; private final int size; + + /** The chunk data bytes. */ protected final byte[] bytes; + private final int chunkSize; /** @@ -82,6 +85,8 @@ public abstract class AbstractWebPChunk extends BinaryFileParser { } /** + * Gets a copy of the chunk data as bytes. + * * @return a copy of the chunk data as bytes. */ public byte[] getBytes() { @@ -89,6 +94,8 @@ public abstract class AbstractWebPChunk extends BinaryFileParser { } /** + * Gets the chunk size. + * * @return the chunk size. */ public int getChunkSize() { @@ -96,6 +103,8 @@ public abstract class AbstractWebPChunk extends BinaryFileParser { } /** + * Gets the payload size. + * * @return the payload size. */ public int getPayloadSize() { @@ -103,6 +112,8 @@ public abstract class AbstractWebPChunk extends BinaryFileParser { } /** + * Gets the chunk type. + * * @return the chunk type. */ public int getType() { @@ -110,6 +121,8 @@ public abstract class AbstractWebPChunk extends BinaryFileParser { } /** + * Gets the description of the chunk type. + * * @return the description of the chunk type. */ public String getTypeDescription() {
