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.ImageReadException;
023import org.apache.commons.imaging.common.bytesource.ByteSourceFile;
024import org.apache.commons.imaging.formats.tiff.datareaders.ImageDataReader;
025import org.apache.commons.imaging.formats.tiff.datareaders.DataReaderStrips;
026import org.apache.commons.imaging.formats.tiff.datareaders.DataReaderTiled;
027import org.apache.commons.imaging.formats.tiff.photometricinterpreters.PhotometricInterpreter;
028
029public abstract class TiffImageData {
030    public static class Tiles extends TiffImageData {
031        public final TiffElement.DataElement[] tiles;
032
033        // public final byte tiles[][];
034        private final int tileWidth;
035        private final int tileLength;
036
037        public Tiles(final TiffElement.DataElement[] tiles, final int tileWidth, final int tileLength) {
038            this.tiles = tiles;
039            this.tileWidth = tileWidth;
040            this.tileLength = tileLength;
041        }
042
043        @Override
044        public TiffElement.DataElement[] getImageData() {
045            return tiles;
046        }
047
048        @Override
049        public boolean stripsNotTiles() {
050            return false;
051        }
052
053        @Override
054        public ImageDataReader getDataReader(final TiffDirectory directory,
055                final PhotometricInterpreter photometricInterpreter,
056                final int bitsPerPixel, final int[] bitsPerSample, final int predictor,
057                final int samplesPerPixel, final int width, final int height, final int compression,
058                final ByteOrder byteOrder) throws IOException, ImageReadException {
059            return new DataReaderTiled(directory, photometricInterpreter,
060                    tileWidth, tileLength, bitsPerPixel, bitsPerSample,
061                    predictor, samplesPerPixel, width, height, compression,
062                    byteOrder, this);
063        }
064
065        /**
066         * Get the width of individual tiles.  Note that if the overall
067         * image width is not a multiple of the tile width, then
068         * the last column of tiles may extend beyond the image width.
069         * @return an integer value greater than zero
070         */
071        public int getTileWidth() {
072            return tileWidth;
073        }
074
075        /**
076         * Get the height of individual tiles.  Note that if the overall
077         * image height is not a multiple of the tile height, then
078         * the last row of tiles may extend beyond the image height.
079         * @return an integer value greater than zero
080         */
081        public int getTileHeight() {
082            return tileLength;
083        }
084
085        // public TiffElement[] getElements()
086        // {
087        // return tiles;
088        // }
089    }
090
091    public static class Strips extends TiffImageData {
092        private final TiffElement.DataElement[] strips;
093        // public final byte strips[][];
094        public final int rowsPerStrip;
095
096        public Strips(final TiffElement.DataElement[] strips, final int rowsPerStrip) {
097            this.strips = strips;
098            this.rowsPerStrip = rowsPerStrip;
099        }
100
101        @Override
102        public TiffElement.DataElement[] getImageData() {
103            return strips;
104        }
105
106        public TiffElement.DataElement getImageData(final int offset) {
107            return strips[offset];
108        }
109
110        public int getImageDataLength() {
111            return strips.length;
112        }
113
114        @Override
115        public boolean stripsNotTiles() {
116            return true;
117        }
118
119        @Override
120        public ImageDataReader getDataReader(final TiffDirectory directory,
121                final PhotometricInterpreter photometricInterpreter,
122                final int bitsPerPixel, final int[] bitsPerSample, final int predictor,
123                final int samplesPerPixel, final int width, final int height, final int compression,
124                final ByteOrder byteorder) throws IOException, ImageReadException {
125            return new DataReaderStrips(directory, photometricInterpreter,
126                    bitsPerPixel, bitsPerSample, predictor, samplesPerPixel,
127                    width, height, compression, byteorder, rowsPerStrip, this);
128        }
129
130    }
131
132    // public abstract TiffElement[] getElements();
133
134    public abstract TiffElement.DataElement[] getImageData();
135
136    public abstract boolean stripsNotTiles();
137
138    public abstract ImageDataReader getDataReader(TiffDirectory directory,
139            PhotometricInterpreter photometricInterpreter, int bitsPerPixel,
140            int[] bitsPerSample, int predictor, int samplesPerPixel, int width,
141            int height, int compression, ByteOrder byteOrder) throws IOException,
142            ImageReadException;
143
144    public static class Data extends TiffElement.DataElement {
145        public Data(final long offset, final int length, final byte[] data) {
146            super(offset, length, data);
147        }
148
149        @Override
150        public String getElementDescription() {
151            return "Tiff image data: " + getDataLength() + " bytes";
152        }
153
154    }
155
156    public static class ByteSourceData extends Data {
157        ByteSourceFile byteSourceFile;
158
159        public ByteSourceData(final long offset, final int length, final ByteSourceFile byteSource) {
160            super(offset, length, new byte[0]);
161            byteSourceFile = byteSource;
162        }
163
164        @Override
165        public String getElementDescription() {
166            return "Tiff image data: " + getDataLength() + " bytes";
167        }
168
169        @Override
170        public byte[] getData() {
171            try {
172                return byteSourceFile.getBlock(offset, length);
173            } catch (final IOException ioex) {
174                return new byte[0];
175            }
176        }
177    }
178}