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