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