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