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.awt.image.BufferedImage; 034import java.io.ByteArrayInputStream; 035import java.io.IOException; 036import java.io.InputStream; 037import java.nio.ByteOrder; 038import java.util.Arrays; 039 040import org.apache.commons.imaging.ImageReadException; 041import org.apache.commons.imaging.common.ImageBuilder; 042import org.apache.commons.imaging.common.PackBits; 043import org.apache.commons.imaging.common.itu_t4.T4AndT6Compression; 044import org.apache.commons.imaging.common.mylzw.MyLzwDecompressor; 045import org.apache.commons.imaging.common.ZlibDeflate; 046import org.apache.commons.imaging.formats.tiff.TiffRasterData; 047import org.apache.commons.imaging.formats.tiff.TiffDirectory; 048import org.apache.commons.imaging.formats.tiff.TiffField; 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 067 * range of floating-point data that can be processed as 068 * additional test data become available. When implementing extensions to this 069 * logic, developers are reminded that image processing requires 070 * the handling of literally millions of pixels, so attention to performance 071 * is essential to a successful implementation (please see the notes in 072 * DataReaderStrips.java for more information). 073 * <p> 074 * The TIFF floating-point specification is very 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 086 * f1, and f0 for the low-order byte. This designation should not be confused 087 * with the in-memory layout of the bytes (little-endian versus big-endian), but 088 * rather their numerical values. The sign bit and upper 7 bits of the exponent 089 * are given in the high-order byte, followed by the remaining sign bit and the 090 * mantissa in the lower. 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 order-of-magnitude. 098 * This splitting process takes place on a ROW-BY-ROW basis (note the emphasis, 099 * this point is not clearly documented in the spec). For example, for a row of 100 * length 3 pixels -- A, B, and C -- the data for two rows would be given as 101 * 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> 111 * To further improve the compression, the predictor takes the difference 112 * of each subsequent bytes. Again, the differences (deltas) are computed on a 113 * row-byte-row basis. For the most part, the differences combine bytes 114 * associated with the same order-of-magnitude, though there is a special 115 * transition at the end of each order-of-magnitude set (shown in parentheses): 116 * <pre> 117 * A3, B3-A3, C3-B3, (A2-C3), B2-A2, C2-B2, (A1-C2), etc. 118 * D3, E3-D3, F3-D3, (D2-F3), E3-D2, etc. 119 * </pre> 120 * Once the predictor transform is complete, the data is stored using 121 * conventional data compression techniques such as Deflate or LZW. In practice, 122 * floating point data does not compress especially well, but using the above 123 * technique, the TIFF process typically reduces the overall storage size by 20 124 * to 30 percent (depending on the data). The TIFF Technical Note 3 specifies 3 125 * data size formats for storing floating point values: 126 * <pre> 127 * 32 bits IEEE-754 single-precision standard 128 * 16 bits IEEE-754 half-precision standard 129 * 24 bits A non-standard representation 130 * </pre> 131 * At this time, we have not obtained data samples for the smaller 132 * representations used in combination with a predictor. 133 * <p> 134 * <strong>Interleaved formats</strong> 135 * <p> 136 * TIFF Technical Note 3 also provides sample code for interleaved data, such as 137 * a real-valued vector or a complex pair. At this time no samples of 138 * interleaved data were available. As a caveat, the specification that the 139 * document provides has disadvantages in terms of code complexity and 140 * performance. Because the interleaved evaluation is embedded inside the pixel 141 * row and column loops, it puts a lot of redundant conditional evaluations 142 * inside the double nested loops. It is recommended that when interleaved data 143 * is implemented, it should get their own block of code so as not to interfere 144 * with the processing of the more common non-interleaved variations. 145 */ 146@SuppressWarnings("PMD.TooManyStaticImports") 147public abstract class ImageDataReader { 148 protected final TiffDirectory directory; 149 protected final PhotometricInterpreter photometricInterpreter; 150 private final int[] bitsPerSample; 151 protected final int bitsPerSampleLength; 152 private final int[] last; 153 154 protected final int predictor; 155 protected final int samplesPerPixel; 156 protected final int width; 157 protected final int height; 158 protected final int sampleFormat; 159 160 public ImageDataReader(final TiffDirectory directory, 161 final PhotometricInterpreter photometricInterpreter, final int[] bitsPerSample, 162 final int predictor, final int samplesPerPixel, final int sampleFormat, 163 final int width, final int height) { 164 this.directory = directory; 165 this.photometricInterpreter = photometricInterpreter; 166 this.bitsPerSample = bitsPerSample; 167 this.bitsPerSampleLength = bitsPerSample.length; 168 this.samplesPerPixel = samplesPerPixel; 169 this.sampleFormat = sampleFormat; 170 this.predictor = predictor; 171 this.width = width; 172 this.height = height; 173 last = new int[samplesPerPixel]; 174 } 175 176 // public abstract void readImageData(BufferedImage bi, ByteSource 177 // byteSource) 178 public abstract void readImageData(ImageBuilder imageBuilder) 179 throws ImageReadException, IOException; 180 181 182 public abstract BufferedImage readImageData(Rectangle subImage) 183 throws ImageReadException, IOException; 184 185 /** 186 * Checks if all the bits per sample entries are the same size 187 * @param size the size to check 188 * @return true if all the bits per sample entries are the same 189 */ 190 protected boolean isHomogenous(final int size) { 191 for (final int element : bitsPerSample) { 192 if (element != size) { 193 return false; 194 } 195 } 196 return true; 197 } 198 199 /** 200 * Reads samples and returns them in an int array. 201 * 202 * @param bis 203 * the stream to read from 204 * @param result 205 * the samples array to populate, must be the same length as 206 * bitsPerSample.length 207 * @throws IOException 208 */ 209 void getSamplesAsBytes(final BitInputStream bis, final int[] result) throws IOException { 210 for (int i = 0; i < bitsPerSample.length; i++) { 211 final int bits = bitsPerSample[i]; 212 int sample = bis.readBits(bits); 213 if (bits < 8) { 214 final int sign = sample & 1; 215 sample = sample << (8 - bits); // scale to byte. 216 if (sign > 0) { 217 sample = sample | ((1 << (8 - bits)) - 1); // extend to byte 218 } 219 } else if (bits > 8) { 220 sample = sample >> (bits - 8); // extend to byte. 221 } 222 result[i] = sample; 223 } 224 } 225 226 protected void resetPredictor() { 227 Arrays.fill(last, 0); 228 } 229 230 protected int[] applyPredictor(final int[] samples) { 231 if (predictor == 2) { 232 // Horizontal differencing. 233 for (int i = 0; i < samples.length; i++) { 234 samples[i] = 0xff & (samples[i] + last[i]); 235 last[i] = samples[i]; 236 } 237 } 238 239 return samples; 240 } 241 242 protected byte[] decompress(final byte[] compressedInput, final int compression, 243 final int expectedSize, final int tileWidth, final int tileHeight) 244 throws ImageReadException, IOException { 245 final TiffField fillOrderField = directory.findField(TiffTagConstants.TIFF_TAG_FILL_ORDER); 246 int fillOrder = TiffTagConstants.FILL_ORDER_VALUE_NORMAL; 247 if (fillOrderField != null) { 248 fillOrder = fillOrderField.getIntValue(); 249 } 250 final byte[] compressedOrdered; // re-ordered bytes (if necessary) 251 if (fillOrder == TiffTagConstants.FILL_ORDER_VALUE_NORMAL) { 252 compressedOrdered = compressedInput; 253 // good 254 } else if (fillOrder == TiffTagConstants.FILL_ORDER_VALUE_REVERSED) { 255 compressedOrdered = new byte[compressedInput.length]; 256 for (int i = 0; i < compressedInput.length; i++) { 257 compressedOrdered[i] = (byte) (Integer.reverse(0xff & compressedInput[i]) >>> 24); 258 } 259 } else { 260 throw new ImageReadException("TIFF FillOrder=" + fillOrder 261 + " is invalid"); 262 } 263 264 switch (compression) { 265 case TIFF_COMPRESSION_UNCOMPRESSED: // None; 266 return compressedOrdered; 267 case TIFF_COMPRESSION_CCITT_1D: // CCITT Group 3 1-Dimensional Modified 268 // Huffman run-length encoding. 269 return T4AndT6Compression.decompressModifiedHuffman(compressedOrdered, 270 tileWidth, tileHeight); 271 case TIFF_COMPRESSION_CCITT_GROUP_3: { 272 int t4Options = 0; 273 final TiffField field = directory.findField(TiffTagConstants.TIFF_TAG_T4_OPTIONS); 274 if (field != null) { 275 t4Options = field.getIntValue(); 276 } 277 final boolean is2D = (t4Options & TIFF_FLAG_T4_OPTIONS_2D) != 0; 278 final boolean usesUncompressedMode = (t4Options & TIFF_FLAG_T4_OPTIONS_UNCOMPRESSED_MODE) != 0; 279 if (usesUncompressedMode) { 280 throw new ImageReadException( 281 "T.4 compression with the uncompressed mode extension is not yet supported"); 282 } 283 final boolean hasFillBitsBeforeEOL = (t4Options & TIFF_FLAG_T4_OPTIONS_FILL) != 0; 284 if (is2D) { 285 return T4AndT6Compression.decompressT4_2D(compressedOrdered, 286 tileWidth, tileHeight, hasFillBitsBeforeEOL); 287 } 288 return T4AndT6Compression.decompressT4_1D(compressedOrdered, 289 tileWidth, tileHeight, hasFillBitsBeforeEOL); 290 } 291 case TIFF_COMPRESSION_CCITT_GROUP_4: { 292 int t6Options = 0; 293 final TiffField field = directory.findField(TiffTagConstants.TIFF_TAG_T6_OPTIONS); 294 if (field != null) { 295 t6Options = field.getIntValue(); 296 } 297 final boolean usesUncompressedMode = (t6Options & TIFF_FLAG_T6_OPTIONS_UNCOMPRESSED_MODE) != 0; 298 if (usesUncompressedMode) { 299 throw new ImageReadException( 300 "T.6 compression with the uncompressed mode extension is not yet supported"); 301 } 302 return T4AndT6Compression.decompressT6(compressedOrdered, tileWidth, 303 tileHeight); 304 } 305 case TIFF_COMPRESSION_LZW: { 306 final InputStream is = new ByteArrayInputStream(compressedOrdered); 307 308 final int lzwMinimumCodeSize = 8; 309 310 final MyLzwDecompressor myLzwDecompressor = new MyLzwDecompressor( 311 lzwMinimumCodeSize, ByteOrder.BIG_ENDIAN); 312 313 myLzwDecompressor.setTiffLZWMode(); 314 315 return myLzwDecompressor.decompress(is, expectedSize); 316 } 317 318 // Packbits 319 case TIFF_COMPRESSION_PACKBITS: { 320 return new PackBits().decompress(compressedOrdered, expectedSize); 321 } 322 323 // deflate 324 case TIFF_COMPRESSION_DEFLATE_ADOBE: 325 case TIFF_COMPRESSION_DEFLATE_PKZIP: { 326 return ZlibDeflate.decompress(compressedInput, expectedSize); 327 } 328 329 default: 330 throw new ImageReadException("Tiff: unknown/unsupported compression: " + compression); 331 } 332 } 333 334 /** 335 * Given a source file that specifies the floating-point data format, unpack 336 * the raw bytes obtained from the source file and organize them into an 337 * array of integers containing the bit-equivalent of IEEE-754 32-bit 338 * floats. Source files containing 64 bit doubles are downcast to floats. 339 * <p> 340 * This method supports either the tile format or the strip format of TIFF 341 * source files. The scan size indicates the number of columns to be 342 * extracted. For strips, the width and the scan size are always the full 343 * width of the image. For tiles, the scan size is the full width of the 344 * tile, but the width may be smaller in the cases where the tiles do not 345 * evenly divide the width (for example, a 256 pixel wide tile in a 257 346 * pixel wide image would result in two columns of tiles, the second column 347 * having only one column of pixels that were worth extracting. 348 * 349 * @param width the width of the data block to be extracted 350 * @param height the height of the data block to be extracted 351 * @param scansize the number of pixels in a single row of the block 352 * @param bytes the raw bytes 353 * @param predictor the predictor specified by the source, only predictor 3 354 * is supported. 355 * @param bitsPerSample the number of bits per sample, 32 or 64. 356 * @param byteOrder the byte order for the source data 357 * @return a valid array of integers in row major order, dimensions 358 * scan-size wide and height height. 359 * @throws ImageReadException in the event of an invalid format. 360 */ 361 protected int[] unpackFloatingPointSamples( 362 int width, 363 int height, 364 int scansize, 365 byte[] bytes, 366 int predictor, 367 int bitsPerSample, ByteOrder byteOrder) 368 throws ImageReadException { 369 int bytesPerSample = bitsPerSample / 8; 370 int nBytes = bytesPerSample * scansize * height; 371 int length = bytes.length < nBytes ? nBytes / scansize : height; 372 373 int[] samples = new int[scansize * height]; 374 // floating-point differencing is indicated by a predictor value of 3. 375 if (predictor == TiffTagConstants.PREDICTOR_VALUE_FLOATING_POINT_DIFFERENCING) { 376 // at this time, this class supports the 32-bit format. The 377 // main reason for this is that we have not located sample data 378 // that can be used for testing and analysis. 379 if (bitsPerSample != 32) { 380 throw new ImageReadException( 381 "Imaging does not yet support floating-point data" 382 + " with predictor type 3 for " 383 + bitsPerSample + " bits per sample"); 384 } 385 int bytesInRow = scansize * 4; 386 for (int i = 0; i < length; i++) { 387 int aOffset = i * bytesInRow; 388 int bOffset = aOffset + scansize; 389 int cOffset = bOffset + scansize; 390 int dOffset = cOffset + scansize; 391 // in this loop, the source bytes give delta values. 392 // we adjust them to give true values. This operation is 393 // done on a row-by-row basis. 394 for (int j = 1; j < bytesInRow; j++) { 395 bytes[aOffset + j] += bytes[aOffset + j - 1]; 396 } 397 // pack the bytes into the integer bit-equivalent of 398 // floating point values 399 int index = i * scansize; 400 for (int j = 0; j < width; j++) { 401 int a = bytes[aOffset + j]; 402 int b = bytes[bOffset + j]; 403 int c = bytes[cOffset + j]; 404 int d = bytes[dOffset + j]; 405 // Pack the 4 byte components into a single integer 406 // in the byte order used by the TIFF standard 407 samples[index++] = ((a & 0xff) << 24) 408 | ((b & 0xff) << 16) 409 | ((c & 0xff) << 8) 410 | (d & 0xff); 411 } 412 } 413 return samples; 414 } // end of predictor==3 case. 415 416 // simple packing case, 64 or 32 bits -------------------------- 417 if (bitsPerSample == 64) { 418 int k = 0; 419 int index = 0; 420 for (int i = 0; i < length; i++) { 421 for (int j = 0; j < scansize; j++) { 422 long b0 = bytes[k++] & 0xffL; 423 long b1 = bytes[k++] & 0xffL; 424 long b2 = bytes[k++] & 0xffL; 425 long b3 = bytes[k++] & 0xffL; 426 long b4 = bytes[k++] & 0xffL; 427 long b5 = bytes[k++] & 0xffL; 428 long b6 = bytes[k++] & 0xffL; 429 long b7 = bytes[k++] & 0xffL; 430 long sbits; 431 if (byteOrder == ByteOrder.LITTLE_ENDIAN) { 432 sbits = (b7 << 56) 433 | (b6 << 48) 434 | (b5 << 40) 435 | (b4 << 32) 436 | (b3 << 24) 437 | (b2 << 16) 438 | (b1 << 8) 439 | b0; 440 441 } else { 442 sbits = (b0 << 56) 443 | (b1 << 48) 444 | (b2 << 40) 445 | (b3 << 32) 446 | (b4 << 24) 447 | (b5 << 16) 448 | (b6 << 8) 449 | b7; 450 } 451 // since the photometric interpreter does not 452 // currently support doubles, we need to replace this 453 // element with a float. This action is inefficient and 454 // should be improved. 455 float f = (float) Double.longBitsToDouble(sbits); 456 samples[index++] = Float.floatToRawIntBits(f); 457 } 458 } 459 } else if (bitsPerSample == 32) { 460 int k = 0; 461 int index = 0; 462 for (int i = 0; i < length; i++) { 463 for (int j = 0; j < scansize; j++) { 464 int b0 = bytes[k++] & 0xff; 465 int b1 = bytes[k++] & 0xff; 466 int b2 = bytes[k++] & 0xff; 467 int b3 = bytes[k++] & 0xff; 468 int sbits; 469 if (byteOrder == ByteOrder.LITTLE_ENDIAN) { 470 sbits 471 = (b3 << 24) 472 | (b2 << 16) 473 | (b1 << 8) 474 | b0; 475 476 } else { 477 sbits 478 = (b0 << 24) 479 | (b1 << 16) 480 | (b2 << 8) 481 | b3; 482 } 483 // since the photometric interpreter does not 484 // currently support doubles, we need to replace this 485 // element with a float. This action is inefficient and 486 // should be improved. 487 samples[index++] = sbits; 488 } 489 } 490 } else { 491 throw new ImageReadException( 492 "Imaging does not support floating-point samples with " 493 + bitsPerSample + " bits per sample"); 494 } 495 496 return samples; 497 } 498 499 /** 500 * 501 * @param xBlock coordinate of block relative to source data 502 * @param yBlock coordinate of block relative to source data 503 * @param blockWidth width of block, in pixels 504 * @param blockHeight height of block in pixels 505 * @param blockData the data for the block 506 * @param xRaster coordinate of raster relative to source data 507 * @param yRaster coordinate of raster relative to source data 508 * @param rasterWidth width of the raster (always smaller than source data) 509 * @param rasterHeight height of the raster (always smaller than source 510 * data) 511 * @param rasterData the raster data. 512 */ 513 void transferBlockToRaster(int xBlock, int yBlock, 514 int blockWidth, int blockHeight, int blockData[], 515 int xRaster, int yRaster, 516 int rasterWidth, int rasterHeight, float[] rasterData) { 517 518 // xR0, yR0 are the coordinates within the raster (upper-left corner) 519 // xR1, yR1 are ONE PAST the coordinates of the lower-right corner 520 int xR0 = xBlock - xRaster; // xR0, yR0 coordinates relative to 521 int yR0 = yBlock - yRaster; // the raster 522 int xR1 = xR0 + blockWidth; 523 int yR1 = yR0 + blockHeight; 524 if (xR0 < 0) { 525 xR0 = 0; 526 } 527 if (yR0 < 0) { 528 yR0 = 0; 529 } 530 if (xR1 > rasterWidth) { 531 xR1 = rasterWidth; 532 } 533 if (yR1 > rasterHeight) { 534 yR1 = rasterHeight; 535 } 536 537 // Recall that the above logic may have adjusted xR0, xY0 so that 538 // they are not necessarily point to the source pixel at xRaster, yRaster 539 // we compute xSource = xR0+xRaster. 540 // xOffset = xSource-xBlock 541 // since the block cannot be accessed with a negative offset, 542 // we check for negatives and adjust xR0, yR0 upward as necessary 543 int xB0 = xR0 + xRaster - xBlock; 544 int yB0 = yR0 + yRaster - yBlock; 545 if (xB0 < 0) { 546 xR0 -= xB0; 547 xB0 = 0; 548 } 549 if (yB0 < 0) { 550 yR0 -= yB0; 551 yB0 = 0; 552 } 553 554 int w = xR1 - xR0; 555 int h = yR1 - yR0; 556 if (w <= 0 || h <= 0) { 557 // The call to this method put the block outside the 558 // bounds of the raster. There is nothing to do. Ideally, 559 // this situation never arises, because it would mean that 560 // the data was read from the file unnecessarily. 561 return; 562 } 563 // see if the xR1, yR1 would extend past the limits of the block 564 if (w > blockWidth) { 565 w = blockWidth; 566 } 567 if (h > blockHeight) { 568 h = blockHeight; 569 } 570 571 for (int i = 0; i < h; i++) { 572 int yR = yR0 + i; 573 int yB = yB0 + i; 574 int rOffset = yR * rasterWidth + xR0; 575 int bOffset = yB * blockWidth + xB0; 576 for (int j = 0; j < w; j++) { 577 rasterData[rOffset + j] = Float.intBitsToFloat(blockData[bOffset + j]); 578 } 579 } 580 } 581 582 /** 583 * Defines a method for accessing the floating-point raster data in a TIFF 584 * image. These implementations of this method in DataReaderStrips and 585 * DataReaderTiled assume that this instance is of a compatible data type 586 * (floating-point) and that all access checks have already been performed. 587 * 588 * @param subImage if non-null, instructs the access method to retrieve only 589 * a sub-section of the image data. 590 * @return a valid instance 591 * @throws ImageReadException in the event of an incompatible data form. 592 * @throws IOException in the event of I/O error. 593 */ 594 public abstract TiffRasterData readRasterData(Rectangle subImage) 595 throws ImageReadException, IOException; 596}