1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.imaging.formats.tiff; 18 19 /** 20 * 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 21 * intended to support access to those TIFF files. 22 * <p> 23 * <strong>Note:</strong> The getData() and getIntData() methods can return direct references to the internal arrays stored in instances of this class. Because 24 * 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. 25 * This approach is used for purposes of efficiency when dealing with very large TIFF images. 26 * <p> 27 * <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 28 * 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 29 * 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 30 * 31 * <pre> 32 * index = y * width + x + iSample * width * height; 33 * </pre> 34 */ 35 public abstract class TiffRasterData { 36 37 protected final int width; 38 protected final int height; 39 protected final int samplesPerPixel; 40 protected final int nCells; 41 protected final int planarOffset; 42 43 /** 44 * Constructs an instance allocating memory for the specified dimensions. 45 * 46 * @param width a value of 1 or greater 47 * @param height a value of 1 or greater 48 * @param samplesPerPixel a value of 1 or greater 49 */ 50 public TiffRasterData(final int width, final int height, final int samplesPerPixel) { 51 if (width <= 0 || height <= 0) { 52 throw new IllegalArgumentException("Raster dimensions less than or equal to zero are not supported"); 53 } 54 if (samplesPerPixel <= 0) { 55 throw new IllegalArgumentException("Raster samples-per-pixel specification must be at least 1"); 56 } 57 this.width = width; 58 this.height = height; 59 this.samplesPerPixel = samplesPerPixel; 60 nCells = width * height * samplesPerPixel; 61 planarOffset = width * height; 62 } 63 64 protected final int checkCoordinatesAndComputeIndex(final int x, final int y, final int i) { 65 if (x < 0 || x >= width || y < 0 || y >= height) { 66 throw new IllegalArgumentException("Coordinates out of range (" + x + ", " + y + ")"); 67 } 68 if (i < 0 || i >= samplesPerPixel) { 69 throw new IllegalArgumentException("Sample index out of range, value " + i + " where valid range is (0," + (samplesPerPixel - 1) + ")"); 70 } 71 return y * width + x + i * planarOffset; 72 } 73 74 /** 75 * 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 76 * a direct reference to the member element. In such cases, modifying it would directly affect the content of the instance. While this design approach 77 * carries some risk in terms of data security, it was chosen for reasons of performance and memory conservation. TIFF images that contain floating-point 78 * 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 79 * resources available to a Java application. 80 * <p> 81 * See the class API documentation above for notes on accessing array elements. 82 * 83 * @return the data content stored in this instance. 84 */ 85 public abstract float[] getData(); 86 87 /** 88 * Gets the raster data type from the instance. 89 * 90 * @return a valid enumeration value. 91 */ 92 public abstract TiffRasterDataType getDataType(); 93 94 /** 95 * Gets the height (number of rows) of the raster. 96 * 97 * @return the height of the raster. 98 */ 99 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 }