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.datareaders; 018 019import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.TIFF_COMPRESSION_CCITT_1D; 020import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.TIFF_COMPRESSION_CCITT_GROUP_3; 021import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.TIFF_COMPRESSION_CCITT_GROUP_4; 022import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.TIFF_COMPRESSION_DEFLATE_PKZIP; 023import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.TIFF_COMPRESSION_DEFLATE_ADOBE; 024import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.TIFF_COMPRESSION_LZW; 025import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.TIFF_COMPRESSION_PACKBITS; 026import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.TIFF_COMPRESSION_UNCOMPRESSED; 027import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.TIFF_FLAG_T4_OPTIONS_2D; 028import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.TIFF_FLAG_T4_OPTIONS_FILL; 029import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.TIFF_FLAG_T4_OPTIONS_UNCOMPRESSED_MODE; 030import static org.apache.commons.imaging.formats.tiff.constants.TiffConstants.TIFF_FLAG_T6_OPTIONS_UNCOMPRESSED_MODE; 031 032import java.awt.Rectangle; 033import java.io.ByteArrayInputStream; 034import java.io.IOException; 035import java.io.InputStream; 036import java.nio.ByteOrder; 037import java.util.Arrays; 038 039import org.apache.commons.imaging.ImageReadException; 040import org.apache.commons.imaging.common.ImageBuilder; 041import org.apache.commons.imaging.common.PackBits; 042import org.apache.commons.imaging.common.itu_t4.T4AndT6Compression; 043import org.apache.commons.imaging.common.mylzw.MyLzwDecompressor; 044import org.apache.commons.imaging.common.ZlibDeflate; 045import org.apache.commons.imaging.formats.tiff.TiffRasterData; 046import org.apache.commons.imaging.formats.tiff.TiffDirectory; 047import org.apache.commons.imaging.formats.tiff.TiffField; 048import org.apache.commons.imaging.formats.tiff.constants.TiffPlanarConfiguration; 049import org.apache.commons.imaging.formats.tiff.constants.TiffTagConstants; 050import org.apache.commons.imaging.formats.tiff.photometricinterpreters.PhotometricInterpreter; 051 052/** 053 * Defines the base class for the TIFF file reader classes. The TIFF format 054 * defines two broad organizations for image pixel storage: strips and tiles. 055 * This class defines common elements for both representations. 056 * <p> 057 * <strong>The TIFF Floating-Point Formats </strong> 058 * <p> 059 * In addition to providing images, TIFF files can supply data in the form of 060 * numerical values. As of March 2020 the Commons Imaging library was extended 061 * to support some floating-point data formats. 062 * <p> 063 * Unfortunately, the TIFF floating-point format allows for a lot of different 064 * variations. At this time, only the most widely used of these are supported. 065 * When this code was written, only a small set of test data products were 066 * available. Thus it is likely that developers will wish to extend the range of 067 * floating-point data that can be processed as additional test data become 068 * available. When implementing extensions to this logic, developers are 069 * reminded that image processing requires the handling of literally millions of 070 * pixels, so attention to performance is essential to a successful 071 * implementation (please see the notes in {@link DataReaderStrips} for more 072 * information). 073 * <p> 074 * The TIFF floating-point specification is poorly documented. So these 075 * notes are included to provide clarification on at least some aspects of the 076 * format. Some documentation and C-code examples are available in "TIFF 077 * Technical Note 3, April 8, 2005)". 078 * <p> 079 * <strong>The Predictor==3 Case</strong> 080 * <p> 081 * TIFF specifies an extension for a predictor that is intended to improve data 082 * compression ratios for floating-point values. This predictor is specified 083 * using the TIFF predictor TAG with a value of 3 (see TIFF Technical Note 3). 084 * Consider a 4-byte floating point value given in IEEE-754 format. Let f3 be 085 * the high-order byte, with f2 the next highest, followed by f1, and f0 for the 086 * low-order byte. This designation should not be confused with the in-memory 087 * layout of the bytes (little-endian versus big-endian), but rather their 088 * numerical values. The sign bit and upper 7 bits of the exponent are given in 089 * the high-order byte, followed by the one remaining exponent bit and the 090 * mantissa in the lower-order bytes. 091 * <p> 092 * In many real-valued raster data sets, the sign and magnitude (exponent) of 093 * the values change slowly. But the bits in the mantissa vary rapidly in a 094 * semi-random manner. The information entropy in the mantissa tends to increase 095 * in the lowest ordered bytes. Thus, the high-order bytes have more redundancy 096 * than the low-order bytes and can compress more efficiently. To exploit this, 097 * the TIFF format splits the bytes into groups based on their 098 * order-of-magnitude. This splitting process takes place on a ROW-BY-ROW basis 099 * (note the emphasis, this point is not clearly documented in the spec). For 100 * example, for a row of length 3 pixels -- A, B, and C -- the data for two rows 101 * would be given as shown below (again, ignoring endian issues): 102 * <pre> 103 * Original: 104 * A3 A2 A1 A0 B3 B2 B1 B0 C3 C2 C1 C0 105 * D3 D3 D1 D0 E3 E2 E2 E0 F3 F2 F1 F0 106 * 107 * Bytes split into groups by order-of-magnitude: 108 * A3 B3 C3 A2 B2 C2 A1 B1 C1 A0 B0 C0 109 * D3 E3 F3 D2 E2 F2 D1 E1 F1 D0 E0 F0 110 * </pre> To further improve the compression, the predictor takes the difference 111 * of each subsequent bytes. Again, the differences (deltas) are computed on a 112 * row-byte-row basis. For the most part, the differences combine bytes 113 * associated with the same order-of-magnitude, though there is a special 114 * transition at the end of each order-of-magnitude set (shown in parentheses): 115 * <pre> 116 * A3, B3-A3, C3-B3, (A2-C3), B2-A2, C2-B2, (A1-C2), etc. 117 * D3, E3-D3, F3-D3, (D2-F3), E3-D2, etc. 118 * </pre> Once the predictor transform is complete, the data is stored using 119 * conventional data compression techniques such as Deflate or LZW. In practice, 120 * floating point data does not compress especially well, but using the above 121 * technique, the TIFF process typically reduces the overall storage size by 20 122 * to 30 percent (depending on the data). The TIFF Technical Note 3 specifies 3 123 * data size formats for storing floating point values: 124 * <pre> 125 * 32 bits IEEE-754 single-precision standard 126 * 16 bits IEEE-754 half-precision standard 127 * 24 bits A non-standard representation 128 * </pre> At this time, we have not obtained data samples for the smaller 129 * representations used in combination with a predictor. 130 * <p> 131 * <strong>Interleaved formats</strong> 132 * <p> 133 * TIFF Technical Note 3 also provides example code for cases where each pixel 134 * (or raster cell) in the image is associated with more than one floating-point 135 * samples. Data in this format might be used for real-valued vector data, 136 * complex-valued pairs, or other numerical applications). 137 * <p>At this time, we have encountered only a limited selection of the possible 138 * configurations for multi-variable data. The code below only supports those 139 * configurations for which we had actual images that could be used to verify 140 * our implementation. The implementation supports the following formats: 141 * <ul> 142 * <li>32-bit floating-point data</li> 143 * <li>Uncompressed, Deflate, or LZW compression</li> 144 * <li>Optional horizontal predictors used with compression</li> 145 * <li>PlanarConfiguration interleaved (CHUNKY) or non-interleaved (PLANAR)</li> 146 * </ul> 147 * <p> 148 * Note that integer formats are not supported at this time. 149 * <p> 150 * Often, the TIFF files store multi-variable data in so that samples are 151 * interleaved. For example, a configuration that gave two samples per pixel (or 152 * cell) would give the two values for the first pixel in order followed by the 153 * two values for the second pixel, etc. If a differencing approach were used 154 * for data compression, the byte-stream would begin with the high-order byte 155 * for each of the two samples for the first pixel, followed by the high-order 156 * byte for each of the next two samples, and so forth for the remainder of the 157 * row of pixels. It would then follow with the second-highest-order bytes for 158 * the first two samples, etc. 159 * <p> 160 * This implementation also supports the non-interleaved (PLANAR) configuration. 161 * One consideration in implementing this feature was that TIFF Technical Note 3 162 * does not address the case where a TIFF image uses the alternate planar 163 * configuration. For conventional images, the TIFF specification (Revision 6.0) 164 * recommends that the planar configuration should be avoided (see pg. 38). 165 * But for numerical data products, the planar configuration may yield better 166 * data compression in the case where different sample sets have different 167 * statistical properties. Because separated groups often have more 168 * uniformity and predictability than interleaved data sets, they sometimes lead 169 * to a small improvement in storage-size reduction when data compression is 170 * used. 171 */ 172public abstract class ImageDataReader { 173 174 protected final TiffDirectory directory; 175 protected final PhotometricInterpreter photometricInterpreter; 176 private final int[] bitsPerSample; 177 protected final int bitsPerSampleLength; 178 private final int[] last; 179 180 protected final int predictor; 181 protected final int samplesPerPixel; 182 protected final int width; 183 protected final int height; 184 protected final int sampleFormat; 185 186 protected final TiffPlanarConfiguration planarConfiguration; 187 188 public ImageDataReader(final TiffDirectory directory, 189 final PhotometricInterpreter photometricInterpreter, final int[] bitsPerSample, 190 final int predictor, final int samplesPerPixel, final int sampleFormat, 191 final int width, final int height, final TiffPlanarConfiguration planarConfiguration) { 192 this.directory = directory; 193 this.photometricInterpreter = photometricInterpreter; 194 this.bitsPerSample = bitsPerSample; 195 this.bitsPerSampleLength = bitsPerSample.length; 196 this.samplesPerPixel = samplesPerPixel; 197 this.sampleFormat = sampleFormat; 198 this.predictor = predictor; 199 this.width = width; 200 this.height = height; 201 this.planarConfiguration = planarConfiguration; 202 last = new int[samplesPerPixel]; 203 204 } 205 206 /** 207 * Read the image data from the IFD associated with this instance of 208 * ImageDataReader using the optional sub-image specification if desired. 209 * 210 * @param subImageSpecification a rectangle describing a sub-region of the 211 * image for reading, or a null if the whole image is to be read. 212 * @param hasAlpha indicates that the image has an alpha (transparency) 213 * channel (RGB color model only). 214 * @param isAlphaPremultiplied indicates that the image uses the associated 215 * alpha channel format (pre-multiplied alpha). 216 * @return a valid instance containing the pixel data from the image. 217 * @throws ImageReadException in the event of a data format error or other 218 * TIFF-specific failure. 219 * @throws IOException in the event of an unrecoverable I/O error. 220 */ 221 public abstract ImageBuilder readImageData( 222 Rectangle subImageSpecification, 223 boolean hasAlpha, 224 boolean isAlphaPremultiplied) 225 throws ImageReadException, IOException; 226 227 /** 228 * Checks if all the bits per sample entries are the same size 229 * 230 * @param size the size to check 231 * @return true if all the bits per sample entries are the same 232 */ 233 protected boolean isHomogenous(final int size) { 234 for (final int element : bitsPerSample) { 235 if (element != size) { 236 return false; 237 } 238 } 239 return true; 240 } 241 242 /** 243 * Reads samples and returns them in an int array. 244 * 245 * @param bis the stream to read from 246 * @param result the samples array to populate, must be the same length as 247 * bitsPerSample.length 248 * @throws IOException 249 */ 250 void getSamplesAsBytes(final BitInputStream bis, final int[] result) throws IOException { 251 for (int i = 0; i < bitsPerSample.length; i++) { 252 final int bits = bitsPerSample[i]; 253 int sample = bis.readBits(bits); 254 if (bits < 8) { 255 final int sign = sample & 1; 256 sample = sample << (8 - bits); // scale to byte. 257 if (sign > 0) { 258 sample = sample | ((1 << (8 - bits)) - 1); // extend to byte 259 } 260 } else if (bits > 8) { 261 sample = sample >> (bits - 8); // extend to byte. 262 } 263 result[i] = sample; 264 } 265 } 266 267 protected void resetPredictor() { 268 Arrays.fill(last, 0); 269 } 270 271 protected int[] applyPredictor(final int[] samples) { 272 if (predictor == 2) { 273 // Horizontal differencing. 274 for (int i = 0; i < samples.length; i++) { 275 samples[i] = 0xff & (samples[i] + last[i]); 276 last[i] = samples[i]; 277 } 278 } 279 280 return samples; 281 } 282 283 protected void applyPredictorToBlock(final int width, final int height, final int nSamplesPerPixel, final byte []p ){ 284 final int k = width*nSamplesPerPixel; 285 for(int i=0; i<height; i++){ 286 final int j0 = i*k+nSamplesPerPixel; 287 final int j1 = (i+1)*k; 288 for(int j=j0; j<j1; j++){ 289 p[j]+=p[j-nSamplesPerPixel]; 290 } 291 } 292 } 293 294 protected byte[] decompress(final byte[] compressedInput, final int compression, 295 final int expectedSize, final int tileWidth, final int tileHeight) 296 throws ImageReadException, IOException { 297 final TiffField fillOrderField = directory.findField(TiffTagConstants.TIFF_TAG_FILL_ORDER); 298 int fillOrder = TiffTagConstants.FILL_ORDER_VALUE_NORMAL; 299 if (fillOrderField != null) { 300 fillOrder = fillOrderField.getIntValue(); 301 } 302 final byte[] compressedOrdered; // re-ordered bytes (if necessary) 303 if (fillOrder == TiffTagConstants.FILL_ORDER_VALUE_NORMAL) { 304 compressedOrdered = compressedInput; 305 // good 306 } else if (fillOrder == TiffTagConstants.FILL_ORDER_VALUE_REVERSED) { 307 compressedOrdered = new byte[compressedInput.length]; 308 for (int i = 0; i < compressedInput.length; i++) { 309 compressedOrdered[i] = (byte) (Integer.reverse(0xff & compressedInput[i]) >>> 24); 310 } 311 } else { 312 throw new ImageReadException("TIFF FillOrder=" + fillOrder 313 + " is invalid"); 314 } 315 316 switch (compression) { 317 case TIFF_COMPRESSION_UNCOMPRESSED: // None; 318 return compressedOrdered; 319 case TIFF_COMPRESSION_CCITT_1D: // CCITT Group 3 1-Dimensional Modified 320 // Huffman run-length encoding. 321 return T4AndT6Compression.decompressModifiedHuffman(compressedOrdered, 322 tileWidth, tileHeight); 323 case TIFF_COMPRESSION_CCITT_GROUP_3: { 324 int t4Options = 0; 325 final TiffField field = directory.findField(TiffTagConstants.TIFF_TAG_T4_OPTIONS); 326 if (field != null) { 327 t4Options = field.getIntValue(); 328 } 329 final boolean is2D = (t4Options & TIFF_FLAG_T4_OPTIONS_2D) != 0; 330 final boolean usesUncompressedMode = (t4Options & TIFF_FLAG_T4_OPTIONS_UNCOMPRESSED_MODE) != 0; 331 if (usesUncompressedMode) { 332 throw new ImageReadException( 333 "T.4 compression with the uncompressed mode extension is not yet supported"); 334 } 335 final boolean hasFillBitsBeforeEOL = (t4Options & TIFF_FLAG_T4_OPTIONS_FILL) != 0; 336 if (is2D) { 337 return T4AndT6Compression.decompressT4_2D(compressedOrdered, 338 tileWidth, tileHeight, hasFillBitsBeforeEOL); 339 } 340 return T4AndT6Compression.decompressT4_1D(compressedOrdered, 341 tileWidth, tileHeight, hasFillBitsBeforeEOL); 342 } 343 case TIFF_COMPRESSION_CCITT_GROUP_4: { 344 int t6Options = 0; 345 final TiffField field = directory.findField(TiffTagConstants.TIFF_TAG_T6_OPTIONS); 346 if (field != null) { 347 t6Options = field.getIntValue(); 348 } 349 final boolean usesUncompressedMode = (t6Options & TIFF_FLAG_T6_OPTIONS_UNCOMPRESSED_MODE) != 0; 350 if (usesUncompressedMode) { 351 throw new ImageReadException( 352 "T.6 compression with the uncompressed mode extension is not yet supported"); 353 } 354 return T4AndT6Compression.decompressT6(compressedOrdered, tileWidth, 355 tileHeight); 356 } 357 case TIFF_COMPRESSION_LZW: { 358 final InputStream is = new ByteArrayInputStream(compressedOrdered); 359 360 final int lzwMinimumCodeSize = 8; 361 362 final MyLzwDecompressor myLzwDecompressor = new MyLzwDecompressor( 363 lzwMinimumCodeSize, ByteOrder.BIG_ENDIAN); 364 365 myLzwDecompressor.setTiffLZWMode(); 366 367 return myLzwDecompressor.decompress(is, expectedSize); 368 } 369 370 // Packbits 371 case TIFF_COMPRESSION_PACKBITS: { 372 return new PackBits().decompress(compressedOrdered, expectedSize); 373 } 374 375 // deflate 376 case TIFF_COMPRESSION_DEFLATE_ADOBE: 377 case TIFF_COMPRESSION_DEFLATE_PKZIP: { 378 return ZlibDeflate.decompress(compressedInput, expectedSize); 379 } 380 381 default: 382 throw new ImageReadException("Tiff: unknown/unsupported compression: " + compression); 383 } 384 } 385 386 /** 387 * Given a source file that specifies the floating-point data format, unpack 388 * the raw bytes obtained from the source file and organize them into an 389 * array of integers containing the bit-equivalent of IEEE-754 32-bit 390 * floats. Source files containing 64 bit doubles are downcast to floats. 391 * <p> 392 * This method supports either the tile format or the strip format of TIFF 393 * source files. The scan size indicates the number of columns to be 394 * extracted. For strips, the width and the scan size are always the full 395 * width of the image. For tiles, the scan size is the full width of the 396 * tile, but the width may be smaller in the cases where the tiles do not 397 * evenly divide the width (for example, a 256 pixel wide tile in a 257 398 * pixel wide image would result in two columns of tiles, the second column 399 * having only one column of pixels that were worth extracting. 400 * 401 * @param width the width of the data block to be extracted 402 * @param height the height of the data block to be extracted 403 * @param scanSize the number of pixels in a single row of the block 404 * @param bytes the raw bytes 405 * @param bitsPerPixel the number of bits per sample, 32 or 64. 406 * @param byteOrder the byte order for the source data 407 * @return a valid array of integers in row major order, dimensions 408 * scan-size wide and height height. 409 * @throws ImageReadException in the event of an invalid format. 410 */ 411 protected int[] unpackFloatingPointSamples( 412 final int width, 413 final int height, 414 final int scanSize, 415 final byte[] bytes, 416 final int bitsPerPixel, 417 final ByteOrder byteOrder) 418 throws ImageReadException { 419 final int bitsPerSample = bitsPerPixel / samplesPerPixel; 420 final int bytesPerSample = bitsPerSample / 8; 421 final int bytesPerScan = scanSize * samplesPerPixel * bytesPerSample; 422 final int nBytes = bytesPerScan * height; 423 final int length = bytes.length < nBytes ? nBytes / bytesPerScan : height; 424 final int[] samples = new int[scanSize * samplesPerPixel * height]; 425 // floating-point differencing is indicated by a predictor value of 3. 426 if (predictor == TiffTagConstants.PREDICTOR_VALUE_FLOATING_POINT_DIFFERENCING) { 427 // at this time, this class supports the 32-bit format. The 428 // main reason for this is that we have not located sample data 429 // that can be used for testing and analysis. 430 if (bitsPerPixel / samplesPerPixel != 32) { 431 throw new ImageReadException( 432 "Imaging does not yet support floating-point data" 433 + " with predictor type 3 for " 434 + bitsPerPixel + " bits per sample"); 435 } 436 437 if (planarConfiguration == TiffPlanarConfiguration.CHUNKY) { 438 final int bytesInRow = scanSize * 4 * samplesPerPixel; 439 for (int i = 0; i < length; i++) { 440 final int aOffset = i * bytesInRow; 441 final int bOffset = aOffset + scanSize * samplesPerPixel; 442 final int cOffset = bOffset + scanSize * samplesPerPixel; 443 final int dOffset = cOffset + scanSize * samplesPerPixel; 444 // in this loop, the source bytes give delta values. 445 // we adjust them to give true values. This operation is 446 // done on a row-by-row basis. 447 for (int j = 1; j < bytesInRow; j++) { 448 bytes[aOffset + j] += bytes[aOffset + j - 1]; 449 } 450 // pack the bytes into the integer bit-equivalent of 451 // floating point values 452 int index = i * scanSize; 453 for (int j = 0; j < width * samplesPerPixel; j++) { 454 final int a = bytes[aOffset + j]; 455 final int b = bytes[bOffset + j]; 456 final int c = bytes[cOffset + j]; 457 final int d = bytes[dOffset + j]; 458 // Pack the 4 byte components into a single integer 459 // in the byte order used by the TIFF standard 460 samples[index++] = ((a & 0xff) << 24) 461 | ((b & 0xff) << 16) 462 | ((c & 0xff) << 8) 463 | (d & 0xff); 464 } 465 } 466 } else { 467 final int bytesInRow = scanSize * 4; 468 for (int iPlane = 0; iPlane < samplesPerPixel; iPlane++) { 469 int planarIntOffset = iPlane * length * scanSize; 470 int planarByteOffset = planarIntOffset * 4; 471 472 for (int i = 0; i < length; i++) { 473 final int aOffset = i * bytesInRow + planarByteOffset; 474 final int bOffset = aOffset + scanSize; 475 final int cOffset = bOffset + scanSize; 476 final int dOffset = cOffset + scanSize; 477 // in this loop, the source bytes give delta values. 478 // we adjust them to give true values. This operation is 479 // done on a row-by-row basis. 480 for (int j = 1; j < bytesInRow; j++) { 481 bytes[aOffset + j] += bytes[aOffset + j - 1]; 482 } 483 // pack the bytes into the integer bit-equivalent of 484 // floating point values 485 int index = planarIntOffset + i * scanSize; 486 for (int j = 0; j < width; j++) { 487 final int a = bytes[aOffset + j]; 488 final int b = bytes[bOffset + j]; 489 final int c = bytes[cOffset + j]; 490 final int d = bytes[dOffset + j]; 491 // Pack the 4 byte components into a single integer 492 // in the byte order used by the TIFF standard 493 samples[index++] = ((a & 0xff) << 24) 494 | ((b & 0xff) << 16) 495 | ((c & 0xff) << 8) 496 | (d & 0xff); 497 } 498 } 499 } 500 501 } 502 return samples; 503 } // end of predictor==3 case. 504 505 // simple packing case, 64 or 32 bits -------------------------- 506 if (bitsPerSample == 64) { 507 int k = 0; 508 int index = 0; 509 for (int i = 0; i < length; i++) { 510 for (int j = 0; j < scanSize; j++) { 511 final long b0 = bytes[k++] & 0xffL; 512 final long b1 = bytes[k++] & 0xffL; 513 final long b2 = bytes[k++] & 0xffL; 514 final long b3 = bytes[k++] & 0xffL; 515 final long b4 = bytes[k++] & 0xffL; 516 final long b5 = bytes[k++] & 0xffL; 517 final long b6 = bytes[k++] & 0xffL; 518 final long b7 = bytes[k++] & 0xffL; 519 long sbits; 520 if (byteOrder == ByteOrder.LITTLE_ENDIAN) { 521 sbits = (b7 << 56) 522 | (b6 << 48) 523 | (b5 << 40) 524 | (b4 << 32) 525 | (b3 << 24) 526 | (b2 << 16) 527 | (b1 << 8) 528 | b0; 529 530 } else { 531 sbits = (b0 << 56) 532 | (b1 << 48) 533 | (b2 << 40) 534 | (b3 << 32) 535 | (b4 << 24) 536 | (b5 << 16) 537 | (b6 << 8) 538 | b7; 539 } 540 // since the photometric interpreter does not 541 // currently support doubles, we need to replace this 542 // element with a float. This action is inefficient and 543 // should be improved. 544 final float f = (float) Double.longBitsToDouble(sbits); 545 samples[index++] = Float.floatToRawIntBits(f); 546 } 547 } 548 } else if (bitsPerSample == 32) { 549 int k = 0; 550 int index = 0; 551 for (int i = 0; i < length; i++) { 552 for (int j = 0; j < scanSize * samplesPerPixel; j++) { 553 final int b0 = bytes[k++] & 0xff; 554 final int b1 = bytes[k++] & 0xff; 555 final int b2 = bytes[k++] & 0xff; 556 final int b3 = bytes[k++] & 0xff; 557 int sbits; 558 if (byteOrder == ByteOrder.LITTLE_ENDIAN) { 559 sbits 560 = (b3 << 24) 561 | (b2 << 16) 562 | (b1 << 8) 563 | b0; 564 565 } else { 566 sbits 567 = (b0 << 24) 568 | (b1 << 16) 569 | (b2 << 8) 570 | b3; 571 } 572 // since the photometric interpreter does not 573 // currently support doubles, we need to replace this 574 // element with a float. This action is inefficient and 575 // should be improved. 576 samples[index++] = sbits; 577 } 578 } 579 } else { 580 throw new ImageReadException( 581 "Imaging does not support floating-point samples with " 582 + bitsPerPixel + " bits per sample"); 583 } 584 585 return samples; 586 } 587 588 /** 589 * Given a source file that specifies numerical data as short integers, 590 * unpack the raw bytes obtained from the source file and organize them into 591 * an array of integers. 592 * <p> 593 * This method supports either the tile format or the strip format of TIFF 594 * source files. The scan size indicates the number of columns to be 595 * extracted. For strips, the width and the scan size are always the full 596 * width of the image. For tiles, the scan size is the full width of the 597 * tile, but the "width" parameter may be smaller in the cases where the 598 * tiles do not evenly divide the width (for example, a 256 pixel wide tile 599 * in a 257 pixel wide image would result in two columns of tiles, the 600 * second column having only one column of pixels that were worth 601 * extracting. 602 * 603 * @param width the width of the data block to be extracted 604 * @param height the height of the data block to be extracted 605 * @param scanSize the number of pixels in a single row of the block 606 * @param bytes the raw bytes 607 * @param predictor the predictor specified by the source, only predictor 3 608 * is supported. 609 * @param bitsPerSample the number of bits per sample, 32 or 64. 610 * @param byteOrder the byte order for the source data 611 * @return a valid array of integers in row major order, dimensions 612 * scan-size wide and height height. 613 */ 614 protected int[] unpackIntSamples( 615 final int width, 616 final int height, 617 final int scanSize, 618 final byte[] bytes, 619 final int predictor, 620 final int bitsPerSample, 621 final ByteOrder byteOrder) { 622 final int bytesPerSample = bitsPerSample / 8; 623 final int nBytes = bytesPerSample * scanSize * height; 624 final int length = bytes.length < nBytes ? nBytes / scanSize : height; 625 626 final int[] samples = new int[scanSize * height]; 627 // At this time, Commons Imaging only supports two-byte 628 // two's complement short integers. It is assumed that 629 // the calling module already checked the arguments for 630 // compliance, so this method simply assumes that they are correct. 631 632 // The logic that follows is simplified by the fact that 633 // the existing API only supports two-byte signed integers. 634 boolean useDifferencing 635 = predictor == TiffTagConstants.PREDICTOR_VALUE_HORIZONTAL_DIFFERENCING; 636 637 for (int i = 0; i < length; i++) { 638 int index = i * scanSize; 639 int offset = index * bytesPerSample; 640 if (bitsPerSample == 16) { 641 if (byteOrder == ByteOrder.LITTLE_ENDIAN) { 642 for (int j = 0; j < width; j++, offset += 2) { 643 samples[index + j] 644 = (bytes[offset + 1] << 8) | (bytes[offset] & 0xff); 645 } 646 } else { 647 for (int j = 0; j < width; j++, offset += 2) { 648 samples[index + j] 649 = (bytes[offset] << 8) | (bytes[offset + 1] & 0xff); 650 } 651 } 652 } else if (bitsPerSample == 32) { 653 if (byteOrder == ByteOrder.LITTLE_ENDIAN) { 654 for (int j = 0; j < width; j++, offset += 4) { 655 samples[index + j] 656 = (bytes[offset + 3] << 24) 657 | ((bytes[offset + 2] & 0xff) << 16) 658 | ((bytes[offset + 1] & 0xff) << 8) 659 | (bytes[offset] & 0xff); 660 } 661 } else { 662 for (int j = 0; j < width; j++, offset += 4) { 663 samples[index + j] 664 = (bytes[offset] << 24) 665 | ((bytes[offset + 1] & 0xff) << 16) 666 | ((bytes[offset + 2] & 0xff) << 8) 667 | (bytes[offset + 3] & 0xff); 668 } 669 } 670 } 671 if (useDifferencing) { 672 for (int j = 1; j < width; j++) { 673 samples[index + j] += samples[index + j - 1]; 674 } 675 } 676 } 677 678 return samples; 679 } 680 681 /** 682 * Transfer samples obtained from the TIFF file to a floating-point raster. 683 * 684 * @param xBlock coordinate of block relative to source data 685 * @param yBlock coordinate of block relative to source data 686 * @param blockWidth width of block, in pixels 687 * @param blockHeight height of block in pixels 688 * @param blockData the data for the block 689 * @param xRaster coordinate of raster relative to source data 690 * @param yRaster coordinate of raster relative to source data 691 * @param rasterWidth width of the raster (always smaller than source data) 692 * @param rasterHeight height of the raster (always smaller than source 693 * data) 694 * @param rasterData the raster data. 695 */ 696 void transferBlockToRaster(final int xBlock, final int yBlock, 697 final int blockWidth, final int blockHeight, final int[] blockData, 698 final int xRaster, final int yRaster, 699 final int rasterWidth, final int rasterHeight, int samplesPerPixel, 700 final float[] rasterData) { 701 702 // xR0, yR0 are the coordinates within the raster (upper-left corner) 703 // xR1, yR1 are ONE PAST the coordinates of the lower-right corner 704 int xR0 = xBlock - xRaster; // xR0, yR0 coordinates relative to 705 int yR0 = yBlock - yRaster; // the raster 706 int xR1 = xR0 + blockWidth; 707 int yR1 = yR0 + blockHeight; 708 if (xR0 < 0) { 709 xR0 = 0; 710 } 711 if (yR0 < 0) { 712 yR0 = 0; 713 } 714 if (xR1 > rasterWidth) { 715 xR1 = rasterWidth; 716 } 717 if (yR1 > rasterHeight) { 718 yR1 = rasterHeight; 719 } 720 721 // Recall that the above logic may have adjusted xR0, xY0 so that 722 // they are not necessarily point to the source pixel at xRaster, yRaster 723 // we compute xSource = xR0+xRaster. 724 // xOffset = xSource-xBlock 725 // since the block cannot be accessed with a negative offset, 726 // we check for negatives and adjust xR0, yR0 upward as necessary 727 int xB0 = xR0 + xRaster - xBlock; 728 int yB0 = yR0 + yRaster - yBlock; 729 if (xB0 < 0) { 730 xR0 -= xB0; 731 xB0 = 0; 732 } 733 if (yB0 < 0) { 734 yR0 -= yB0; 735 yB0 = 0; 736 } 737 738 int w = xR1 - xR0; 739 int h = yR1 - yR0; 740 if (w <= 0 || h <= 0) { 741 // The call to this method put the block outside the 742 // bounds of the raster. There is nothing to do. Ideally, 743 // this situation never arises, because it would mean that 744 // the data was read from the file unnecessarily. 745 return; 746 } 747 // see if the xR1, yR1 would extend past the limits of the block 748 if (w > blockWidth) { 749 w = blockWidth; 750 } 751 if (h > blockHeight) { 752 h = blockHeight; 753 } 754 755 // The TiffRasterData class expects data to be in the order 756 // corresponding to TiffPlanarConfiguration.PLANAR. So for the 757 // multivariable case, we must convert CHUNKY data to PLANAR. 758 if (samplesPerPixel == 1) { 759 for (int i = 0; i < h; i++) { 760 final int yR = yR0 + i; 761 final int yB = yB0 + i; 762 final int rOffset = yR * rasterWidth + xR0; 763 final int bOffset = yB * blockWidth + xB0; 764 for (int j = 0; j < w; j++) { 765 rasterData[rOffset + j] = Float.intBitsToFloat(blockData[bOffset + j]); 766 } 767 } 768 } else if (this.planarConfiguration == TiffPlanarConfiguration.CHUNKY) { 769 // The source data is in the interleaved (Chunky) order, 770 // but the TiffRasterData class expects non-interleaved order. 771 // So we transcribe the elements as appropriate. 772 int pixelsPerPlane = rasterWidth * rasterHeight; 773 for (int i = 0; i < h; i++) { 774 final int yR = yR0 + i; 775 final int yB = yB0 + i; 776 final int rOffset = yR * rasterWidth + xR0; 777 final int bOffset = yB * blockWidth + xB0; 778 for (int j = 0; j < w; j++) { 779 for (int k = 0; k < samplesPerPixel; k++) { 780 rasterData[k * pixelsPerPlane + rOffset + j] 781 = Float.intBitsToFloat(blockData[(bOffset + j) * samplesPerPixel + k]); 782 } 783 } 784 } 785 } else { 786 for (int iPlane = 0; iPlane < samplesPerPixel; iPlane++) { 787 int rPlanarOffset = iPlane * rasterWidth * rasterHeight; 788 int bPlanarOffset = iPlane * blockWidth * blockHeight; 789 for (int i = 0; i < h; i++) { 790 final int yR = yR0 + i; 791 final int yB = yB0 + i; 792 final int rOffset = rPlanarOffset + yR * rasterWidth + xR0; 793 final int bOffset = bPlanarOffset + yB * blockWidth + xB0; 794 for (int j = 0; j < w; j++) { 795 rasterData[rOffset + j] = Float.intBitsToFloat(blockData[bOffset + j]); 796 } 797 } 798 } 799 } 800 801 } 802 803 /** 804 * Transfer samples obtained from the TIFF file to an integer raster. 805 * 806 * @param xBlock coordinate of block relative to source data 807 * @param yBlock coordinate of block relative to source data 808 * @param blockWidth width of block, in pixels 809 * @param blockHeight height of block in pixels 810 * @param blockData the data for the block 811 * @param xRaster coordinate of raster relative to source data 812 * @param yRaster coordinate of raster relative to source data 813 * @param rasterWidth width of the raster (always smaller than source data) 814 * @param rasterHeight height of the raster (always smaller than source 815 * data) 816 * @param rasterData the raster data. 817 */ 818 void transferBlockToRaster(final int xBlock, final int yBlock, 819 final int blockWidth, final int blockHeight, final int[] blockData, 820 final int xRaster, final int yRaster, 821 final int rasterWidth, final int rasterHeight, final int[] rasterData) { 822 823 // xR0, yR0 are the coordinates within the raster (upper-left corner) 824 // xR1, yR1 are ONE PAST the coordinates of the lower-right corner 825 int xR0 = xBlock - xRaster; // xR0, yR0 coordinates relative to 826 int yR0 = yBlock - yRaster; // the raster 827 int xR1 = xR0 + blockWidth; 828 int yR1 = yR0 + blockHeight; 829 if (xR0 < 0) { 830 xR0 = 0; 831 } 832 if (yR0 < 0) { 833 yR0 = 0; 834 } 835 if (xR1 > rasterWidth) { 836 xR1 = rasterWidth; 837 } 838 if (yR1 > rasterHeight) { 839 yR1 = rasterHeight; 840 } 841 842 // Recall that the above logic may have adjusted xR0, xY0 so that 843 // they are not necessarily point to the source pixel at xRaster, yRaster 844 // we compute xSource = xR0+xRaster. 845 // xOffset = xSource-xBlock 846 // since the block cannot be accessed with a negative offset, 847 // we check for negatives and adjust xR0, yR0 upward as necessary 848 int xB0 = xR0 + xRaster - xBlock; 849 int yB0 = yR0 + yRaster - yBlock; 850 if (xB0 < 0) { 851 xR0 -= xB0; 852 xB0 = 0; 853 } 854 if (yB0 < 0) { 855 yR0 -= yB0; 856 yB0 = 0; 857 } 858 859 int w = xR1 - xR0; 860 int h = yR1 - yR0; 861 if (w <= 0 || h <= 0) { 862 // The call to this method puts the block outside the 863 // bounds of the raster. There is nothing to do. Ideally, 864 // this situation never arises, because it would mean that 865 // the data was read from the file unnecessarily. 866 return; 867 } 868 // see if the xR1, yR1 would extend past the limits of the block 869 if (w > blockWidth) { 870 w = blockWidth; 871 } 872 if (h > blockHeight) { 873 h = blockHeight; 874 } 875 876 for (int i = 0; i < h; i++) { 877 final int yR = yR0 + i; 878 final int yB = yB0 + i; 879 final int rOffset = yR * rasterWidth + xR0; 880 final int bOffset = yB * blockWidth + xB0; 881 System.arraycopy(blockData, bOffset, rasterData, rOffset, w); 882 } 883 } 884 885 /** 886 * Defines a method for accessing the floating-point raster data in a TIFF 887 * image. These implementations of this method in DataReaderStrips and 888 * DataReaderTiled assume that this instance is of a compatible data type 889 * (floating-point) and that all access checks have already been performed. 890 * 891 * @param subImage if non-null, instructs the access method to retrieve only 892 * a sub-section of the image data. 893 * @return a valid instance 894 * @throws ImageReadException in the event of an incompatible data form. 895 * @throws IOException in the event of I/O error. 896 */ 897 public abstract TiffRasterData readRasterData(Rectangle subImage) 898 throws ImageReadException, IOException; 899}