    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      http://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017package org.apache.commons.imaging.formats.tiff;
    018
    019import java.io.IOException;
    020import java.nio.ByteOrder;
    021
    022import org.apache.commons.imaging.ImagingException;
    023import org.apache.commons.imaging.formats.tiff.constants.TiffPlanarConfiguration;
    024import org.apache.commons.imaging.formats.tiff.constants.TiffTagConstants;
    025import org.apache.commons.imaging.formats.tiff.datareaders.AbstractImageDataReader;
    026import org.apache.commons.imaging.formats.tiff.datareaders.DataReaderStrips;
    027import org.apache.commons.imaging.formats.tiff.datareaders.DataReaderTiled;
    028import org.apache.commons.imaging.formats.tiff.photometricinterpreters.AbstractPhotometricInterpreter;
    029
    030public abstract class AbstractTiffImageData {
    031
    032    public static class Data extends AbstractTiffElement.DataElement {
    033
    034        public Data(final long offset, final int length, final byte[] data) {
    035            super(offset, length, data);
    036        }
    037
    038        @Override
    039        public String getElementDescription() {
    040            return "TIFF image data: " + getDataLength() + " bytes";
    041        }
    042
    043    }
    044
    045    public static class Strips extends AbstractTiffImageData {
    046
    047        private final AbstractTiffElement.DataElement[] strips;
    048        // public final byte strips[][];
    049        public final int rowsPerStrip;
    050
    051        public Strips(final AbstractTiffElement.DataElement[] strips, final int rowsPerStrip) {
    052            this.strips = strips;
    053            this.rowsPerStrip = rowsPerStrip;
    054        }
    055
    056        @Override
    057        public AbstractImageDataReader getDataReader(final TiffDirectory directory, final AbstractPhotometricInterpreter photometricInterpreter,
    058                final int bitsPerPixel, final int[] bitsPerSample, final int predictor, final int samplesPerPixel, final int width, final int height,
    059                final int compression, final TiffPlanarConfiguration planarConfiguration, final ByteOrder byteorder) throws IOException, ImagingException {
    060            final int sampleFormat = extractSampleFormat(directory);
    061            return new DataReaderStrips(directory, photometricInterpreter, bitsPerPixel, bitsPerSample, predictor, samplesPerPixel, sampleFormat, width, height,
    062                    compression, planarConfiguration, byteorder, rowsPerStrip, this);
    063        }
    064
    065        @Override
    066        public AbstractTiffElement.DataElement[] getImageData() {
    067            return strips;
    068        }
    069
    070        public AbstractTiffElement.DataElement getImageData(final int offset) {
    071            return strips[offset];
    072        }
    073
    074        public int getImageDataLength() {
    075            return strips.length;
    076        }
    077
    078        @Override
    079        public boolean stripsNotTiles() {
    080            return true;
    081        }
    082
    083    }
    084
    085    public static class Tiles extends AbstractTiffImageData {
    086
    087        public final AbstractTiffElement.DataElement[] tiles;
    088
    089        // public final byte tiles[][];
    090        private final int tileWidth;
    091        private final int tileLength;
    092
    093        public Tiles(final AbstractTiffElement.DataElement[] tiles, final int tileWidth, final int tileLength) {
    094            this.tiles = tiles;
    095            this.tileWidth = tileWidth;
    096            this.tileLength = tileLength;
    097        }
    098
    099        @Override
    100        public AbstractImageDataReader getDataReader(final TiffDirectory directory, final AbstractPhotometricInterpreter photometricInterpreter,
    101                final int bitsPerPixel, final int[] bitsPerSample, final int predictor, final int samplesPerPixel, final int width, final int height,
    102                final int compression, final TiffPlanarConfiguration planarConfiguration, final ByteOrder byteOrder) throws IOException, ImagingException {
    103            final int sampleFormat = extractSampleFormat(directory);
    104            return new DataReaderTiled(directory, photometricInterpreter, tileWidth, tileLength, bitsPerPixel, bitsPerSample, predictor, samplesPerPixel,
    105                    sampleFormat, width, height, compression, planarConfiguration, byteOrder, this);
    106        }
    107
    108        @Override
    109        public AbstractTiffElement.DataElement[] getImageData() {
    110            return tiles;
    111        }
    112
    113        /**
    114         * 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
    115         * extend beyond the image height.
    116         *
    117         * @return an integer value greater than zero
    118         */
    119        public int getTileHeight() {
    120            return tileLength;
    121        }
    122
    123        /**
    124         * 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
    125         * extend beyond the image width.
    126         *
    127         * @return an integer value greater than zero
    128         */
    129        public int getTileWidth() {
    130            return tileWidth;
    131        }
    132
    133        @Override
    134        public boolean stripsNotTiles() {
    135            return false;
    136        }
    137
    138        // public TiffElement[] getElements()
    139        // {
    140        // return tiles;
    141        // }
    142    }
    143
    144    private static int extractSampleFormat(final TiffDirectory directory) throws ImagingException {
    145        final short[] sSampleFmt = directory.getFieldValue(TiffTagConstants.TIFF_TAG_SAMPLE_FORMAT, false);
    146        if (sSampleFmt != null && sSampleFmt.length > 0) {
    147            return sSampleFmt[0];
    148        }
    149        return 0; // unspecified format
    150    }
    151
    152    public abstract AbstractImageDataReader getDataReader(TiffDirectory directory, AbstractPhotometricInterpreter photometricInterpreter, int bitsPerPixel,
    153            int[] bitsPerSample, int predictor, int samplesPerPixel, int width, int height, int compression, TiffPlanarConfiguration planarConfiguration,
    154            ByteOrder byteOrder) throws IOException, ImagingException;
    155
    156    public abstract AbstractTiffElement.DataElement[] getImageData();
    157
    158    public abstract boolean stripsNotTiles();
    159}