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 019/** 020 * Provides a simple container for numeric-raster data. Some TIFF files are used to store floating-point or integer data rather than images. This class is 021 * intended to support access to those TIFF files. 022 * <p> 023 * <strong>Note:</strong> The getData() and getIntData() methods can return direct references to the internal arrays stored in instances of this class. Because 024 * these are not safe copies of the data, an application that modified the arrays returned by these methods will change the content of the associated instance. 025 * This approach is used for purposes of efficiency when dealing with very large TIFF images. 026 * <p> 027 * <strong>Data layout:</strong> The elements in the returned array are stored in row-major order. In cases where the data contains multiple samples per raster 028 * cell (pixel), the data is organized into blocks of data one sample at a time. The first block contains width*height values for the first sample for each 029 * cell, the second block contains width*height values for the second sample for each cell, etc. Thus, the array index for a particular value is computed as 030 * 031 * <pre> 032 * index = y * width + x + iSample * width * height; 033 * </pre> 034 */ 035public abstract class TiffRasterData { 036 037 protected final int width; 038 protected final int height; 039 protected final int samplesPerPixel; 040 protected final int nCells; 041 protected final int planarOffset; 042 043 /** 044 * Constructs an instance allocating memory for the specified dimensions. 045 * 046 * @param width a value of 1 or greater 047 * @param height a value of 1 or greater 048 * @param samplesPerPixel a value of 1 or greater 049 */ 050 public TiffRasterData(final int width, final int height, final int samplesPerPixel) { 051 if (width <= 0 || height <= 0) { 052 throw new IllegalArgumentException("Raster dimensions less than or equal to zero are not supported"); 053 } 054 if (samplesPerPixel <= 0) { 055 throw new IllegalArgumentException("Raster samples-per-pixel specification must be at least 1"); 056 } 057 this.width = width; 058 this.height = height; 059 this.samplesPerPixel = samplesPerPixel; 060 nCells = width * height * samplesPerPixel; 061 planarOffset = width * height; 062 } 063 064 protected final int checkCoordinatesAndComputeIndex(final int x, final int y, final int i) { 065 if (x < 0 || x >= width || y < 0 || y >= height) { 066 throw new IllegalArgumentException("Coordinates out of range (" + x + ", " + y + ")"); 067 } 068 if (i < 0 || i >= samplesPerPixel) { 069 throw new IllegalArgumentException("Sample index out of range, value " + i + " where valid range is (0," + (samplesPerPixel - 1) + ")"); 070 } 071 return y * width + x + i * planarOffset; 072 } 073 074 /** 075 * Returns the content stored as an array in this instance. Note that in many cases, the returned array is <strong>not</strong> a safe copy of the data but 076 * a direct reference to the member element. In such cases, modifying it would directly affect the content of the instance. While this design approach 077 * carries some risk in terms of data security, it was chosen for reasons of performance and memory conservation. TIFF images that contain floating-point 078 * data are often quite large. Sizes of 100 million raster cells are common. Making a redundant copy of such a large in-memory object might exceed the 079 * resources available to a Java application. 080 * <p> 081 * See the class API documentation above for notes on accessing array elements. 082 * 083 * @return the data content stored in this instance. 084 */ 085 public abstract float[] getData(); 086 087 /** 088 * Gets the raster data type from the instance. 089 * 090 * @return a valid enumeration value. 091 */ 092 public abstract TiffRasterDataType getDataType(); 093 094 /** 095 * Gets the height (number of rows) of the raster. 096 * 097 * @return the height of the raster. 098 */ 099 public final int getHeight() { 100 return height; 101 } 102 103 /** 104 * Returns the content stored as an array in this instance. Note that in many cases, the returned array is <strong>not</strong> a safe copy of the data but 105 * a direct reference to the member element. In such cases, modifying it would directly affect the content of the instance. While this design approach 106 * carries some risk in terms of data security, it was chosen for reasons of performance and memory conservation. TIFF images that contain floating-point 107 * data are often quite large. Sizes of 100 million raster cells are common. Making a redundant copy of such a large in-memory object might exceed the 108 * resources available to a Java application. 109 * <p> 110 * See the class API documentation above for notes on accessing array elements. 111 * 112 * @return the data content stored in this instance. 113 */ 114 public abstract int[] getIntData(); 115 116 /** 117 * Gets the value stored at the specified raster coordinates. 118 * 119 * @param x integer coordinate in the columnar direction 120 * @param y integer coordinate in the row direction 121 * @return the value stored at the specified location 122 */ 123 public abstract int getIntValue(int x, int y); 124 125 /** 126 * Gets the value stored at the specified raster coordinates. 127 * 128 * @param x integer coordinate in the columnar direction 129 * @param y integer coordinate in the row direction 130 * @param i integer sample index (for data sets giving multiple samples per raster cell). 131 * @return the value stored at the specified location 132 */ 133 public abstract int getIntValue(int x, int y, int i); 134 135 /** 136 * Gets the number of samples per pixel. 137 * 138 * @return a value of 1 or greater. 139 */ 140 public final int getSamplesPerPixel() { 141 return samplesPerPixel; 142 } 143 144 /** 145 * Tabulates simple statistics for the raster and returns an instance containing general metadata. 146 * 147 * @return a valid instance containing a safe copy of the current simple statistics for the raster. 148 */ 149 public abstract TiffRasterStatistics getSimpleStatistics(); 150 151 /** 152 * Tabulates simple statistics for the raster excluding the specified value and returns an instance containing general metadata. 153 * 154 * @param valueToExclude exclude samples with this specified value. 155 * @return a valid instance. 156 */ 157 public abstract TiffRasterStatistics getSimpleStatistics(float valueToExclude); 158 159 /** 160 * Gets the value stored at the specified raster coordinates. 161 * 162 * @param x integer coordinate in the columnar direction 163 * @param y integer coordinate in the row direction 164 * @return the value stored at the specified location; potentially a Float.NaN. 165 */ 166 public abstract float getValue(int x, int y); 167 168 /** 169 * Gets the value stored at the specified raster coordinates. 170 * 171 * @param x integer coordinate in the columnar direction 172 * @param y integer coordinate in the row direction 173 * @param i integer sample index 174 * @return the value stored at the specified location; potentially a Float.NaN. 175 */ 176 public abstract float getValue(int x, int y, int i); 177 178 /** 179 * Gets the width (number of columns) of the raster. 180 * 181 * @return the width of the raster 182 */ 183 public final int getWidth() { 184 return width; 185 } 186 187 /** 188 * Sets the value stored at the specified raster coordinates. 189 * 190 * @param x integer coordinate in the columnar direction 191 * @param y integer coordinate in the row direction 192 * @param value the value to be stored at the specified location. 193 */ 194 public abstract void setIntValue(int x, int y, int value); 195 196 /** 197 * Sets the value stored at the specified raster coordinates. 198 * 199 * @param x integer coordinate in the columnar direction 200 * @param y integer coordinate in the row direction 201 * @param i integer sample index (for data sets giving multiple samples per raster cell). 202 * @param value the value to be stored at the specified location. 203 */ 204 public abstract void setIntValue(int x, int y, int i, int value); 205 206 /** 207 * Sets the value stored at the specified raster coordinates. 208 * 209 * @param x integer coordinate in the columnar direction 210 * @param y integer coordinate in the row direction 211 * @param value the value to be stored at the specified location; potentially a Float.NaN. 212 */ 213 public abstract void setValue(int x, int y, float value); 214 215 /** 216 * Sets the value stored at the specified raster coordinates. 217 * 218 * @param x integer coordinate in the columnar direction 219 * @param y integer coordinate in the row direction 220 * @param i integer sample index (for data sets giving multiple samples per raster cell). 221 * @param value the value to be stored at the specified location; potentially a Float.NaN. 222 */ 223 public abstract void setValue(int x, int y, int i, float value); 224}