001/* 002 * $RCSfile: RawRenderedImage.java,v $ 003 * 004 * 005 * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved. 006 * 007 * Redistribution and use in source and binary forms, with or without 008 * modification, are permitted provided that the following conditions 009 * are met: 010 * 011 * - Redistribution of source code must retain the above copyright 012 * notice, this list of conditions and the following disclaimer. 013 * 014 * - Redistribution in binary form must reproduce the above copyright 015 * notice, this list of conditions and the following disclaimer in 016 * the documentation and/or other materials provided with the 017 * distribution. 018 * 019 * Neither the name of Sun Microsystems, Inc. or the names of 020 * contributors may be used to endorse or promote products derived 021 * from this software without specific prior written permission. 022 * 023 * This software is provided "AS IS," without a warranty of any 024 * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND 025 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, 026 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY 027 * EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL 028 * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF 029 * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS 030 * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR 031 * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, 032 * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND 033 * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR 034 * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE 035 * POSSIBILITY OF SUCH DAMAGES. 036 * 037 * You acknowledge that this software is not designed or intended for 038 * use in the design, construction, operation or maintenance of any 039 * nuclear facility. 040 * 041 * $Revision: 1.2 $ 042 * $Date: 2006/04/21 23:19:13 $ 043 * $State: Exp $ 044 */ 045package com.github.jaiimageio.impl.plugins.raw; 046 047import java.awt.Dimension; 048import java.awt.Point; 049import java.awt.Rectangle; 050import java.awt.image.BandedSampleModel; 051import java.awt.image.BufferedImage; 052import java.awt.image.ComponentSampleModel; 053import java.awt.image.DataBuffer; 054import java.awt.image.DataBufferByte; 055import java.awt.image.DataBufferDouble; 056import java.awt.image.DataBufferFloat; 057import java.awt.image.DataBufferInt; 058import java.awt.image.DataBufferShort; 059import java.awt.image.DataBufferUShort; 060import java.awt.image.MultiPixelPackedSampleModel; 061import java.awt.image.PixelInterleavedSampleModel; 062import java.awt.image.Raster; 063import java.awt.image.SampleModel; 064import java.awt.image.SinglePixelPackedSampleModel; 065import java.awt.image.WritableRaster; 066import java.io.IOException; 067 068import javax.imageio.ImageReadParam; 069import javax.imageio.ImageTypeSpecifier; 070 071import com.github.jaiimageio.impl.common.ImageUtil; 072import com.github.jaiimageio.impl.common.SimpleRenderedImage; 073import com.github.jaiimageio.stream.RawImageInputStream; 074 075public class RawRenderedImage extends SimpleRenderedImage { 076 /** The sample model for the original image. */ 077 private SampleModel originalSampleModel; 078 079 private Raster currentTile; 080 private Point currentTileGrid; 081 082 /** The input stream we read from */ 083 private RawImageInputStream iis = null; 084 085 /** Caches the <code>RawImageReader</code> which creates this object. This 086 * variable is used to monitor the abortion. 087 */ 088 private RawImageReader reader; 089 090 /** The <code>ImageReadParam</code> to create this 091 * <code>renderedImage</code>. 092 */ 093 private ImageReadParam param = null; 094 095 // The image index in the stream 096 private int imageIndex; 097 098 /** The destination bounds. */ 099 private Rectangle destinationRegion; 100 private Rectangle originalRegion; 101 private Point sourceOrigin; 102 private Dimension originalDimension; 103 private int maxXTile, maxYTile; 104 105 /** The subsampling parameters. */ 106 private int scaleX, scaleY, xOffset, yOffset; 107 private int[] destinationBands = null; 108 private int[] sourceBands = null; 109 private int nComp; 110 111 /** Coordinate transform is not needed from the source (image stream) 112 * to the destination. 113 */ 114 private boolean noTransform = true; 115 116 /** The raster for medialib tiles to share. */ 117 private WritableRaster rasForATile; 118 119 private BufferedImage destImage; 120 121 /** The position of the first sample of this image in the stream. */ 122 private long position; 123 124 /** cache the size of the data for each tile in the stream. */ 125 private long tileDataSize; 126 127 /** The orginal number tiles in X direction. */ 128 private int originalNumXTiles; 129 130 public RawRenderedImage(RawImageInputStream iis, 131 RawImageReader reader, 132 ImageReadParam param, 133 int imageIndex) throws IOException { 134 this.iis = iis; 135 this.reader = reader; 136 this.param = param; 137 this.imageIndex = imageIndex; 138 this.position = iis.getImageOffset(imageIndex); 139 this.originalDimension = iis.getImageDimension(imageIndex); 140 141 ImageTypeSpecifier type = iis.getImageType(); 142 sampleModel = originalSampleModel = type.getSampleModel(); 143 colorModel = type.getColorModel(); 144 145 // If the destination band is set used it 146 sourceBands = (param == null) ? null : param.getSourceBands(); 147 148 if (sourceBands == null) { 149 nComp = originalSampleModel.getNumBands(); 150 sourceBands = new int[nComp]; 151 for (int i = 0; i < nComp; i++) 152 sourceBands[i] = i; 153 } else { 154 sampleModel = 155 originalSampleModel.createSubsetSampleModel(sourceBands); 156 colorModel = ImageUtil.createColorModel(null, sampleModel); 157 } 158 159 nComp = sourceBands.length; 160 161 destinationBands = (param == null) ? null : param.getDestinationBands(); 162 if (destinationBands == null) { 163 destinationBands = new int[nComp]; 164 for (int i = 0; i < nComp; i++) 165 destinationBands[i] = i; 166 } 167 168 Dimension dim = iis.getImageDimension(imageIndex); 169 this.width = dim.width; 170 this.height = dim.height; 171 172 Rectangle sourceRegion = 173 new Rectangle(0, 0, this.width, this.height); 174 175 originalRegion = (Rectangle)sourceRegion.clone(); 176 177 destinationRegion = (Rectangle)sourceRegion.clone(); 178 179 if (param != null) { 180 RawImageReader.computeRegionsWrapper(param, 181 this.width, this.height, 182 param.getDestination(), 183 sourceRegion, 184 destinationRegion); 185 scaleX = param.getSourceXSubsampling(); 186 scaleY = param.getSourceYSubsampling(); 187 xOffset = param.getSubsamplingXOffset(); 188 yOffset = param.getSubsamplingYOffset(); 189 } 190 191 sourceOrigin = new Point(sourceRegion.x, sourceRegion.y); 192 if (!destinationRegion.equals(sourceRegion)) 193 noTransform = false; 194 195 this.tileDataSize = ImageUtil.getTileSize(originalSampleModel); 196 197 this.tileWidth = originalSampleModel.getWidth(); 198 this.tileHeight = originalSampleModel.getHeight(); 199 this.tileGridXOffset = destinationRegion.x; 200 this.tileGridYOffset = destinationRegion.y; 201 this.originalNumXTiles = getNumXTiles(); 202 203 this.width = destinationRegion.width; 204 this.height = destinationRegion.height; 205 this.minX = destinationRegion.x; 206 this.minY = destinationRegion.y; 207 208 sampleModel = 209 sampleModel.createCompatibleSampleModel(tileWidth, tileHeight); 210 211 maxXTile = originalDimension.width / tileWidth; 212 maxYTile = originalDimension.height / tileHeight; 213 } 214 215 public synchronized Raster getTile(int tileX, int tileY) { 216 if (currentTile != null && 217 currentTileGrid.x == tileX && 218 currentTileGrid.y == tileY) 219 return currentTile; 220 221 if (tileX >= getNumXTiles() || tileY >= getNumYTiles()) 222 throw new IllegalArgumentException(I18N.getString("RawRenderedImage0")); 223 224 try { 225 iis.seek(position + (tileY * originalNumXTiles + tileX) * tileDataSize); 226 227 int x = tileXToX(tileX); 228 int y = tileYToY(tileY); 229 currentTile = Raster.createWritableRaster(sampleModel, new Point(x, y)); 230 231 if (noTransform) { 232 switch (sampleModel.getDataType()) { 233 case DataBuffer.TYPE_BYTE: 234 byte[][] buf = 235 ((DataBufferByte)currentTile.getDataBuffer()).getBankData(); 236 for (int i = 0; i < buf.length; i++) 237 iis.readFully(buf[i], 0, buf[i].length); 238 break; 239 240 case DataBuffer.TYPE_SHORT: 241 short[][] sbuf = 242 ((DataBufferShort)currentTile.getDataBuffer()).getBankData(); 243 for (int i = 0; i < sbuf.length; i++) 244 iis.readFully(sbuf[i], 0, sbuf[i].length); 245 break; 246 247 case DataBuffer.TYPE_USHORT: 248 short[][] usbuf = 249 ((DataBufferUShort)currentTile.getDataBuffer()).getBankData(); 250 for (int i = 0; i < usbuf.length; i++) 251 iis.readFully(usbuf[i], 0, usbuf[i].length); 252 break; 253 case DataBuffer.TYPE_INT: 254 int[][] ibuf = 255 ((DataBufferInt)currentTile.getDataBuffer()).getBankData(); 256 for (int i = 0; i < ibuf.length; i++) 257 iis.readFully(ibuf[i], 0, ibuf[i].length); 258 break; 259 case DataBuffer.TYPE_FLOAT: 260 float[][] fbuf = 261 ((DataBufferFloat)currentTile.getDataBuffer()).getBankData(); 262 for (int i = 0; i < fbuf.length; i++) 263 iis.readFully(fbuf[i], 0, fbuf[i].length); 264 break; 265 case DataBuffer.TYPE_DOUBLE: 266 double[][] dbuf = 267 ((DataBufferDouble)currentTile.getDataBuffer()).getBankData(); 268 for (int i = 0; i < dbuf.length; i++) 269 iis.readFully(dbuf[i], 0, dbuf[i].length); 270 break; 271 } 272 } else { 273 currentTile = readSubsampledRaster((WritableRaster)currentTile); 274 } 275 } catch (IOException e) { 276 throw new RuntimeException(e); 277 } 278 279 if (currentTileGrid == null) 280 currentTileGrid = new Point(tileX, tileY); 281 else { 282 currentTileGrid.x = tileX; 283 currentTileGrid.y = tileY; 284 } 285 286 return currentTile; 287 } 288 289 public void readAsRaster(WritableRaster raster) throws java.io.IOException { 290 readSubsampledRaster(raster); 291 } 292 293 private Raster readSubsampledRaster(WritableRaster raster) throws IOException { 294 if (raster == null) 295 raster = Raster.createWritableRaster( 296 sampleModel.createCompatibleSampleModel(destinationRegion.x + 297 destinationRegion.width, 298 destinationRegion.y + 299 destinationRegion.height), 300 new Point(destinationRegion.x, destinationRegion.y)); 301 302 int numBands = sourceBands.length; 303 int dataType = sampleModel.getDataType(); 304 int sampleSizeBit = DataBuffer.getDataTypeSize(dataType); 305 int sampleSizeByte = (sampleSizeBit + 7) / 8; 306 307 Rectangle destRect = raster.getBounds().intersection(destinationRegion); 308 309 int offx = destinationRegion.x; 310 int offy = destinationRegion.y; 311 312 int sourceSX = (destRect.x - offx) * scaleX + sourceOrigin.x; 313 int sourceSY = (destRect.y - offy) * scaleY + sourceOrigin.y; 314 int sourceEX = (destRect.width - 1) * scaleX + sourceSX; 315 int sourceEY = (destRect.height - 1) * scaleY + sourceSY; 316 int startXTile = sourceSX / tileWidth; 317 int startYTile = sourceSY / tileHeight; 318 int endXTile = sourceEX / tileWidth; 319 int endYTile = sourceEY / tileHeight; 320 321 startXTile = clip(startXTile, 0, maxXTile); 322 startYTile = clip(startYTile, 0, maxYTile); 323 endXTile = clip(endXTile, 0, maxXTile); 324 endYTile = clip(endYTile, 0, maxYTile); 325 326 int totalXTiles = getNumXTiles(); 327 int totalYTiles = getNumYTiles(); 328 int totalTiles = totalXTiles * totalYTiles; 329 330 //The line buffer for the source 331 byte[] pixbuf = null; // byte buffer for the decoded pixels. 332 short[] spixbuf = null; // byte buffer for the decoded pixels. 333 int[] ipixbuf = null; // byte buffer for the decoded pixels. 334 float[] fpixbuf = null; // byte buffer for the decoded pixels. 335 double[] dpixbuf = null; // byte buffer for the decoded pixels. 336 337 // A flag to show the ComponentSampleModel has a single data bank 338 boolean singleBank = true; 339 int pixelStride = 0; 340 int scanlineStride = 0; 341 int bandStride = 0; 342 int[] bandOffsets = null; 343 int[] bankIndices = null; 344 345 if (originalSampleModel instanceof ComponentSampleModel) { 346 ComponentSampleModel csm = (ComponentSampleModel)originalSampleModel; 347 bankIndices = csm.getBankIndices(); 348 int maxBank = 0; 349 for (int i = 0; i < bankIndices.length; i++) 350 if (maxBank > bankIndices[i]) 351 maxBank = bankIndices[i]; 352 353 if (maxBank > 0) 354 singleBank = false; 355 pixelStride = csm.getPixelStride(); 356 357 scanlineStride = csm.getScanlineStride(); 358 bandOffsets = csm.getBandOffsets(); 359 for (int i = 0; i < bandOffsets.length; i++) 360 if (bandStride < bandOffsets[i]) 361 bandStride = bandOffsets[i]; 362 } else if (originalSampleModel instanceof MultiPixelPackedSampleModel) { 363 scanlineStride = 364 ((MultiPixelPackedSampleModel)originalSampleModel).getScanlineStride(); 365 } else if(originalSampleModel instanceof SinglePixelPackedSampleModel) { 366 pixelStride = 1; 367 scanlineStride = 368 ((SinglePixelPackedSampleModel)originalSampleModel).getScanlineStride(); 369 } 370 371 // The dstination buffer for the raster 372 byte[] destPixbuf = null; // byte buffer for the decoded pixels. 373 short[] destSPixbuf = null; // byte buffer for the decoded pixels. 374 int[] destIPixbuf = null; // byte buffer for the decoded pixels. 375 float[] destFPixbuf = null; // byte buffer for the decoded pixels. 376 double[] destDPixbuf = null; // byte buffer for the decoded pixels. 377 int[] destBandOffsets = null; 378 int destPixelStride = 0; 379 int destScanlineStride = 0; 380 int destSX = 0; // The first pixel for the destionation 381 382 if (raster.getSampleModel() instanceof ComponentSampleModel) { 383 ComponentSampleModel csm = 384 (ComponentSampleModel)raster.getSampleModel(); 385 bankIndices = csm.getBankIndices(); 386 destBandOffsets = csm.getBandOffsets(); 387 destPixelStride = csm.getPixelStride(); 388 destScanlineStride = csm.getScanlineStride(); 389 destSX = csm.getOffset(raster.getMinX() - 390 raster.getSampleModelTranslateX(), 391 raster.getMinY() - 392 raster.getSampleModelTranslateY()) 393 - destBandOffsets[0]; 394 395 switch(dataType) { 396 case DataBuffer.TYPE_BYTE: 397 destPixbuf = ((DataBufferByte)raster.getDataBuffer()).getData(); 398 break; 399 case DataBuffer.TYPE_SHORT: 400 destSPixbuf = 401 ((DataBufferShort)raster.getDataBuffer()).getData(); 402 break; 403 404 case DataBuffer.TYPE_USHORT: 405 destSPixbuf = 406 ((DataBufferUShort)raster.getDataBuffer()).getData(); 407 break; 408 409 case DataBuffer.TYPE_INT: 410 destIPixbuf = 411 ((DataBufferInt)raster.getDataBuffer()).getData(); 412 break; 413 414 case DataBuffer.TYPE_FLOAT: 415 destFPixbuf = 416 ((DataBufferFloat)raster.getDataBuffer()).getData(); 417 break; 418 419 case DataBuffer.TYPE_DOUBLE: 420 destDPixbuf = 421 ((DataBufferDouble)raster.getDataBuffer()).getData(); 422 break; 423 } 424 } else if (raster.getSampleModel() instanceof SinglePixelPackedSampleModel) { 425 numBands = 1; 426 bankIndices = new int[]{0}; 427 destBandOffsets = new int[numBands]; 428 for (int i = 0; i < numBands; i++) 429 destBandOffsets[i] = 0; 430 destPixelStride = 1; 431 destScanlineStride = 432 ((SinglePixelPackedSampleModel)raster.getSampleModel()).getScanlineStride(); 433 } 434 435 // Start the data delivery to the cached consumers tile by tile 436 for(int y = startYTile; y <= endYTile; y++){ 437 if (reader.getAbortRequest()) 438 break; 439 440 // Loop on horizontal tiles 441 for(int x=startXTile; x <= endXTile; x++){ 442 if (reader.getAbortRequest()) 443 break; 444 445 long tilePosition = 446 position + (y * originalNumXTiles + x) * tileDataSize; 447 iis.seek(tilePosition); 448 float percentage = 449 (x - startXTile + y * totalXTiles) / totalXTiles; 450 451 int startX = x * tileWidth; 452 int startY = y * tileHeight; 453 454 int cTileHeight = tileHeight; 455 int cTileWidth = tileWidth; 456 457 if (startY + cTileHeight >= originalDimension.height) 458 cTileHeight = originalDimension.height - startY; 459 460 if (startX + cTileWidth >= originalDimension.width) 461 cTileWidth = originalDimension.width - startX; 462 463 int tx = startX; 464 int ty = startY; 465 466 // If source start position calculated by taking subsampling 467 // into account is after the tile's start X position, adjust 468 // the start position accordingly 469 if (sourceSX > startX) { 470 cTileWidth += startX - sourceSX; 471 tx = sourceSX; 472 startX = sourceSX; 473 } 474 475 if (sourceSY > startY) { 476 cTileHeight += startY - sourceSY; 477 ty = sourceSY; 478 startY = sourceSY; 479 } 480 481 // If source end position calculated by taking subsampling 482 // into account is prior to the tile's end X position, adjust 483 // the tile width to read accordingly 484 if (sourceEX < startX + cTileWidth -1) { 485 cTileWidth += sourceEX - startX - cTileWidth + 1; 486 } 487 488 if (sourceEY < startY + cTileHeight - 1) { 489 cTileHeight += sourceEY - startY - cTileHeight + 1; 490 } 491 492 // The start X in the destination 493 int x1 = (startX + scaleX - 1 - sourceOrigin.x) / scaleX; 494 int x2 = (startX + scaleX - 1 + cTileWidth - sourceOrigin.x) / 495 scaleX; 496 int lineLength = x2 - x1; 497 x2 = (x2 - 1) * scaleX + sourceOrigin.x; 498 499 int y1 = (startY + scaleY -1 - sourceOrigin.y) /scaleY; 500 startX = x1 * scaleX + sourceOrigin.x; 501 startY = y1 * scaleY + sourceOrigin.y; 502 503 // offx is destination.x 504 x1 += offx; 505 y1 += offy; 506 507 tx -= x * tileWidth; 508 ty -= y * tileHeight; 509 510 if (sampleModel instanceof MultiPixelPackedSampleModel) { 511 MultiPixelPackedSampleModel mppsm = 512 (MultiPixelPackedSampleModel)originalSampleModel; 513 514 iis.skipBytes(mppsm.getOffset(tx, ty) * sampleSizeByte); 515 516 int readBytes = (mppsm.getOffset(x2, 0) - 517 mppsm.getOffset(startX, 0) + 1) * 518 sampleSizeByte; 519 520 int skipLength = (scanlineStride * scaleY - readBytes) * 521 sampleSizeByte; 522 readBytes *= sampleSizeByte; 523 524 if (pixbuf == null || pixbuf.length < readBytes) 525 pixbuf = new byte[readBytes]; 526 527 int bitoff = mppsm.getBitOffset(tx); 528 529 for (int l = 0, m = y1; l < cTileHeight; 530 l += scaleY, m++) { 531 if (reader.getAbortRequest()) 532 break; 533 iis.readFully(pixbuf, 0, readBytes); 534 if (scaleX == 1) { 535 536 if (bitoff != 0) { 537 int mask1 = (255 << bitoff) & 255; 538 int mask2 = ~mask1 & 255; 539 int shift = 8 - bitoff; 540 541 int n = 0; 542 for (; n < readBytes -1; n++) 543 pixbuf[n] = (byte)(((pixbuf[n] & mask2) << shift) | 544 (pixbuf[n + 1] & mask1) >>bitoff); 545 pixbuf[n] = (byte)((pixbuf[n] & mask2) << shift); 546 } 547 } else { 548 549 int bit = 7 ; 550 int pos = 0 ; 551 int mask = 128; 552 553 for (int n = 0, n1 = startX & 7; 554 n < lineLength; n++, n1 += scaleX) { 555 pixbuf[pos] = (byte)((pixbuf[pos] & ~(1 << bit)) | 556 (((pixbuf[n1 >> 3] >> (7 - (n1 & 7))) & 1) << bit)); 557 bit--; 558 if (bit == -1) { 559 bit = 7; 560 pos++; 561 } 562 } 563 } 564 565 ImageUtil.setPackedBinaryData(pixbuf, raster, 566 new Rectangle(x1, m, 567 lineLength, 568 1)); 569 iis.skipBytes(skipLength); 570 if (destImage != null) 571 reader.processImageUpdateWrapper(destImage, x1, m, 572 cTileWidth, 1, 1, 1, 573 destinationBands); 574 575 reader.processImageProgressWrapper(percentage + 576 (l - startY + 1.0F) / 577 cTileHeight / totalTiles); 578 } 579 } else { 580 581 int readLength, skipLength; 582 if (pixelStride < scanlineStride) { 583 readLength = cTileWidth * pixelStride; 584 skipLength = (scanlineStride * scaleY - readLength) * 585 sampleSizeByte; 586 } else { 587 readLength = cTileHeight * scanlineStride; 588 skipLength = (pixelStride * scaleX - readLength) * 589 sampleSizeByte; 590 } 591 592 //Allocate buffer for all the types 593 switch (sampleModel.getDataType()) { 594 case DataBuffer.TYPE_BYTE: 595 if (pixbuf == null || pixbuf.length < readLength) 596 pixbuf = new byte[readLength]; 597 break; 598 599 case DataBuffer.TYPE_SHORT: 600 case DataBuffer.TYPE_USHORT: 601 if (spixbuf == null || spixbuf.length < readLength) 602 spixbuf = new short[readLength]; 603 break; 604 605 case DataBuffer.TYPE_INT: 606 if (ipixbuf == null || ipixbuf.length < readLength) 607 ipixbuf = new int[readLength]; 608 break; 609 610 case DataBuffer.TYPE_FLOAT: 611 if (fpixbuf == null || fpixbuf.length < readLength) 612 fpixbuf = new float[readLength]; 613 break; 614 615 case DataBuffer.TYPE_DOUBLE: 616 if (dpixbuf == null || dpixbuf.length < readLength) 617 dpixbuf = new double[readLength]; 618 break; 619 } 620 621 if (sampleModel instanceof PixelInterleavedSampleModel) { 622 iis.skipBytes((tx * pixelStride + ty * scanlineStride) * 623 sampleSizeByte); 624 625 // variables for ther loop 626 int outerFirst, outerSecond, outerStep, outerBound; 627 int innerStep, innerStep1, outerStep1; 628 if (pixelStride < scanlineStride) { 629 outerFirst = 0; 630 outerSecond = y1; 631 outerStep = scaleY; 632 outerBound = cTileHeight; 633 innerStep = scaleX * pixelStride; 634 innerStep1 = destPixelStride; 635 outerStep1 = destScanlineStride; 636 } else { 637 outerFirst = 0; 638 outerSecond = x1; 639 outerStep = scaleX; 640 outerBound = cTileWidth; 641 innerStep = scaleY * scanlineStride; 642 innerStep1 = destScanlineStride; 643 outerStep1 = destPixelStride; 644 } 645 646 int destPos = 647 destSX + (y1 - raster.getSampleModelTranslateY()) 648 * destScanlineStride + 649 (x1 - raster.getSampleModelTranslateX()) 650 * destPixelStride; 651 652 for (int l = outerFirst, m = outerSecond; l < outerBound; 653 l += outerStep, m++) { 654 if (reader.getAbortRequest()) 655 break; 656 657 switch(dataType) { 658 case DataBuffer.TYPE_BYTE: 659 if (innerStep == numBands && 660 innerStep1 == numBands) 661 iis.readFully(destPixbuf, destPos, readLength); 662 else 663 iis.readFully(pixbuf, 0, readLength); 664 break; 665 case DataBuffer.TYPE_SHORT: 666 case DataBuffer.TYPE_USHORT: 667 if (innerStep == numBands && 668 innerStep1 == numBands) { 669 iis.readFully(destSPixbuf, destPos, readLength); 670 } else 671 iis.readFully(spixbuf, 0, readLength); 672 break; 673 case DataBuffer.TYPE_INT: 674 if (innerStep == numBands && 675 innerStep1 == numBands) 676 iis.readFully(destIPixbuf, destPos, readLength); 677 else 678 iis.readFully(ipixbuf, 0, readLength); 679 break; 680 case DataBuffer.TYPE_FLOAT: 681 if (innerStep == numBands && 682 innerStep1 == numBands) 683 iis.readFully(destFPixbuf, destPos, readLength); 684 else 685 iis.readFully(fpixbuf, 0, readLength); 686 break; 687 case DataBuffer.TYPE_DOUBLE: 688 if (innerStep == numBands && 689 innerStep1 == numBands) 690 iis.readFully(destDPixbuf, destPos, readLength); 691 else 692 iis.readFully(dpixbuf, 0, readLength); 693 break; 694 } 695 696 if (innerStep != numBands || innerStep1 != numBands) 697 for (int b = 0; b < numBands; b++) { 698 int destBandOffset = 699 destBandOffsets[destinationBands[b]]; 700 destPos += destBandOffset; 701 702 int sourceBandOffset = 703 bandOffsets[sourceBands[b]]; 704 705 switch(dataType) { 706 case DataBuffer.TYPE_BYTE: 707 for (int m1 = 0, n = destPos; m1 < readLength; 708 m1 += innerStep, n += innerStep1) { 709 destPixbuf[n] 710 = pixbuf[m1 + sourceBandOffset]; 711 } 712 break; 713 case DataBuffer.TYPE_SHORT: 714 case DataBuffer.TYPE_USHORT: 715 for (int m1 = 0, n = destPos; m1 < readLength; 716 m1 += innerStep, n += innerStep1) { 717 destSPixbuf[n] 718 = spixbuf[m1 + sourceBandOffset]; 719 } 720 break; 721 case DataBuffer.TYPE_INT: 722 for (int m1 = 0, n = destPos; m1 < readLength; 723 m1 += innerStep, n += innerStep1) { 724 destIPixbuf[n] 725 = ipixbuf[m1 + sourceBandOffset]; 726 } 727 break; 728 case DataBuffer.TYPE_FLOAT: 729 for (int m1 = 0, n = destPos; m1 < readLength; 730 m1 += innerStep, n += innerStep1) { 731 destFPixbuf[n] 732 = fpixbuf[m1 + sourceBandOffset]; 733 } 734 break; 735 case DataBuffer.TYPE_DOUBLE: 736 for (int m1 = 0, n = destPos; m1 < readLength; 737 m1 += innerStep, n += innerStep1) { 738 destDPixbuf[n] 739 = dpixbuf[m1 + sourceBandOffset]; 740 } 741 break; 742 } 743 destPos -= destBandOffset; 744 } 745 746 iis.skipBytes(skipLength); 747 destPos += outerStep1; 748 749 if (destImage != null) 750 if (pixelStride < scanlineStride) 751 reader.processImageUpdateWrapper(destImage, 752 x1, m, 753 outerBound, 754 1, 1, 1, 755 destinationBands); 756 else 757 reader.processImageUpdateWrapper(destImage, 758 m, y1, 759 1, outerBound, 760 1, 1, 761 destinationBands); 762 763 reader.processImageProgressWrapper(percentage + 764 (l + 1.0F) / 765 outerBound / 766 totalTiles); 767 } 768 } else if (sampleModel instanceof BandedSampleModel || 769 sampleModel instanceof SinglePixelPackedSampleModel || 770 bandStride == 0) { 771 boolean isBanded = sampleModel instanceof BandedSampleModel; 772 773 int bandSize = 774 (int)ImageUtil.getBandSize(originalSampleModel); 775 776 for (int b = 0; b < numBands; b++) { 777 iis.seek(tilePosition + bandSize * sourceBands[b] * 778 sampleSizeByte); 779 int destBandOffset = 780 destBandOffsets[destinationBands[b]]; 781 782 iis.skipBytes((ty * scanlineStride + tx * pixelStride) * 783 sampleSizeByte); 784 785 // variables for ther loop 786 int outerFirst, outerSecond, outerStep, outerBound; 787 int innerStep, innerStep1, outerStep1; 788 if (pixelStride < scanlineStride) { 789 outerFirst = 0; 790 outerSecond = y1; 791 outerStep = scaleY; 792 outerBound = cTileHeight; 793 innerStep = scaleX * pixelStride; 794 innerStep1 = destPixelStride; 795 outerStep1 = destScanlineStride; 796 } else { 797 outerFirst = 0; 798 outerSecond = x1; 799 outerStep = scaleX; 800 outerBound = cTileWidth; 801 innerStep = scaleY * scanlineStride; 802 innerStep1 = destScanlineStride; 803 outerStep1 = destPixelStride; 804 } 805 806 int destPos = destSX + (y1 - raster.getSampleModelTranslateY())* destScanlineStride + 807 (x1 - raster.getSampleModelTranslateX()) * destPixelStride + destBandOffset; 808 809 int bank = bankIndices[destinationBands[b]]; 810 811 switch(dataType) { 812 case DataBuffer.TYPE_BYTE: 813 destPixbuf = 814 ((DataBufferByte)raster.getDataBuffer()).getData(bank); 815 break; 816 case DataBuffer.TYPE_SHORT: 817 destSPixbuf = 818 ((DataBufferShort)raster.getDataBuffer()).getData(bank); 819 break; 820 821 case DataBuffer.TYPE_USHORT: 822 destSPixbuf = 823 ((DataBufferUShort)raster.getDataBuffer()).getData(bank); 824 break; 825 826 case DataBuffer.TYPE_INT: 827 destIPixbuf = 828 ((DataBufferInt)raster.getDataBuffer()).getData(bank); 829 break; 830 831 case DataBuffer.TYPE_FLOAT: 832 destFPixbuf = 833 ((DataBufferFloat)raster.getDataBuffer()).getData(bank); 834 break; 835 836 case DataBuffer.TYPE_DOUBLE: 837 destDPixbuf = 838 ((DataBufferDouble)raster.getDataBuffer()).getData(bank); 839 break; 840 } 841 842 for (int l = outerFirst, m = outerSecond; l < outerBound; 843 l += outerStep, m++) { 844 if (reader.getAbortRequest()) 845 break; 846 847 switch(dataType) { 848 case DataBuffer.TYPE_BYTE: 849 if (innerStep == 1 && innerStep1 == 1) { 850 iis.readFully(destPixbuf, destPos, readLength); 851 } else { 852 iis.readFully(pixbuf, 0, readLength); 853 for (int m1 = 0, n = destPos; m1 < readLength; 854 m1 += innerStep, n += innerStep1) { 855 destPixbuf[n] = pixbuf[m1]; 856 } 857 } 858 break; 859 case DataBuffer.TYPE_SHORT: 860 case DataBuffer.TYPE_USHORT: 861 if (innerStep == 1 && innerStep1 == 1) { 862 iis.readFully(destSPixbuf, destPos, readLength); 863 } else { 864 iis.readFully(spixbuf, 0, readLength); 865 for (int m1 = 0, n = destPos; m1 < readLength; 866 m1 += innerStep, n += innerStep1) { 867 destSPixbuf[n] = spixbuf[m1]; 868 } 869 } 870 break; 871 case DataBuffer.TYPE_INT: 872 if (innerStep == 1 && innerStep1 == 1) { 873 iis.readFully(destIPixbuf, destPos, readLength); 874 } else { 875 iis.readFully(ipixbuf, 0, readLength); 876 for (int m1 = 0, n = destPos; m1 < readLength; 877 m1 += innerStep, n += innerStep1) { 878 destIPixbuf[n] = ipixbuf[m1]; 879 } 880 } 881 break; 882 case DataBuffer.TYPE_FLOAT: 883 if (innerStep == 1 && innerStep1 == 1) { 884 iis.readFully(destFPixbuf, destPos, readLength); 885 } else { 886 iis.readFully(fpixbuf, 0, readLength); 887 for (int m1 = 0, n = destPos; m1 < readLength; 888 m1 += innerStep, n += innerStep1) { 889 destFPixbuf[n] = fpixbuf[m1]; 890 } 891 } 892 break; 893 case DataBuffer.TYPE_DOUBLE: 894 if (innerStep == 1 && innerStep1 == 1) { 895 iis.readFully(destDPixbuf, destPos, readLength); 896 } else { 897 iis.readFully(dpixbuf, 0, readLength); 898 for (int m1 = 0, n = destPos; m1 < readLength; 899 m1 += innerStep, n += innerStep1) { 900 destDPixbuf[n] = dpixbuf[m1]; 901 } 902 } 903 break; 904 } 905 906 iis.skipBytes(skipLength); 907 destPos += outerStep1; 908 909 if (destImage != null) { 910 int[] destBands = 911 new int[] {destinationBands[b]}; 912 if (pixelStride < scanlineStride) 913 reader.processImageUpdateWrapper(destImage, 914 x1, m, 915 outerBound, 916 1, 1, 1, 917 destBands); 918 else 919 reader.processImageUpdateWrapper(destImage, 920 m, y1, 1, 921 outerBound, 922 1, 1, 923 destBands); 924 } 925 926 reader.processImageProgressWrapper( 927 (percentage + 928 (l+1.0F)/outerBound/numBands/totalTiles) * 929 100.0F); 930 } 931 } 932 } else if (sampleModel instanceof ComponentSampleModel) { 933 //for the other case, may slow 934 //Allocate buffer for all the types 935 int bufferSize = (int)tileDataSize; 936 937 switch (sampleModel.getDataType()) { 938 case DataBuffer.TYPE_BYTE: 939 if (pixbuf == null || pixbuf.length < tileDataSize) 940 pixbuf = new byte[(int)tileDataSize]; 941 iis.readFully(pixbuf, 0, (int)tileDataSize); 942 break; 943 944 case DataBuffer.TYPE_SHORT: 945 case DataBuffer.TYPE_USHORT: 946 bufferSize /= 2; 947 if (spixbuf == null || spixbuf.length < bufferSize) 948 spixbuf = new short[(int)bufferSize]; 949 iis.readFully(spixbuf, 0, (int)bufferSize); 950 break; 951 952 case DataBuffer.TYPE_INT: 953 bufferSize /= 4; 954 if (ipixbuf == null || ipixbuf.length < bufferSize) 955 ipixbuf = new int[(int)bufferSize]; 956 iis.readFully(ipixbuf, 0, (int)bufferSize); 957 break; 958 959 case DataBuffer.TYPE_FLOAT: 960 bufferSize /= 4; 961 if (fpixbuf == null || fpixbuf.length < bufferSize) 962 fpixbuf = new float[(int)bufferSize]; 963 iis.readFully(fpixbuf, 0, (int)bufferSize); 964 break; 965 966 case DataBuffer.TYPE_DOUBLE: 967 bufferSize /= 8; 968 if (dpixbuf == null || dpixbuf.length < bufferSize) 969 dpixbuf = new double[(int)bufferSize]; 970 iis.readFully(dpixbuf, 0, (int)bufferSize); 971 break; 972 } 973 974 for (int b = 0; b < numBands; b++) { 975 int destBandOffset = 976 destBandOffsets[destinationBands[b]]; 977 978 int destPos = 979 ((ComponentSampleModel)raster.getSampleModel()).getOffset( 980 x1-raster.getSampleModelTranslateX(), 981 y1-raster.getSampleModelTranslateY(), 982 destinationBands[b]); 983 984 int bank = bankIndices[destinationBands[b]]; 985 986 switch(dataType) { 987 case DataBuffer.TYPE_BYTE: 988 destPixbuf = 989 ((DataBufferByte)raster.getDataBuffer()).getData(bank); 990 break; 991 case DataBuffer.TYPE_SHORT: 992 destSPixbuf = 993 ((DataBufferShort)raster.getDataBuffer()).getData(bank); 994 break; 995 996 case DataBuffer.TYPE_USHORT: 997 destSPixbuf = 998 ((DataBufferUShort)raster.getDataBuffer()).getData(bank); 999 break; 1000 1001 case DataBuffer.TYPE_INT: 1002 destIPixbuf = 1003 ((DataBufferInt)raster.getDataBuffer()).getData(bank); 1004 break; 1005 1006 case DataBuffer.TYPE_FLOAT: 1007 destFPixbuf = 1008 ((DataBufferFloat)raster.getDataBuffer()).getData(bank); 1009 break; 1010 1011 case DataBuffer.TYPE_DOUBLE: 1012 destDPixbuf = 1013 ((DataBufferDouble)raster.getDataBuffer()).getData(bank); 1014 break; 1015 } 1016 1017 int srcPos = 1018 ((ComponentSampleModel)originalSampleModel).getOffset(tx, ty, sourceBands[b]); 1019 int skipX = scaleX * pixelStride;; 1020 for (int l = 0, m = y1; l < cTileHeight; 1021 l += scaleY, m++) { 1022 if (reader.getAbortRequest()) 1023 break; 1024 1025 switch(dataType) { 1026 case DataBuffer.TYPE_BYTE: 1027 for (int n = 0, m1 = srcPos, m2 = destPos; 1028 n < lineLength; 1029 n++, m1 += skipX, m2 += destPixelStride) 1030 destPixbuf[m2] = pixbuf[m1]; 1031 break; 1032 case DataBuffer.TYPE_SHORT: 1033 case DataBuffer.TYPE_USHORT: 1034 for (int n = 0, m1 = srcPos, m2 = destPos; 1035 n < lineLength; 1036 n++, m1 += skipX, m2 += destPixelStride) 1037 destSPixbuf[m2] = spixbuf[m1]; 1038 break; 1039 case DataBuffer.TYPE_INT: 1040 for (int n = 0, m1 = srcPos, m2 = destPos; 1041 n < lineLength; 1042 n++, m1 += skipX, m2 += destPixelStride) 1043 destIPixbuf[m2] = ipixbuf[m1]; 1044 break; 1045 case DataBuffer.TYPE_FLOAT: 1046 for (int n = 0, m1 = srcPos, m2 = destPos; 1047 n < lineLength; 1048 n++, m1 += skipX, m2 += destPixelStride) 1049 destFPixbuf[m2] = fpixbuf[m1]; 1050 break; 1051 case DataBuffer.TYPE_DOUBLE: 1052 for (int n = 0, m1 = srcPos, m2 = destPos; 1053 n < lineLength; 1054 n++, m1 += skipX, m2 += destPixelStride) 1055 destDPixbuf[m2] = dpixbuf[m1]; 1056 break; 1057 } 1058 1059 destPos += destScanlineStride; 1060 srcPos += scanlineStride * scaleY; 1061 1062 if (destImage != null) { 1063 int[] destBands = 1064 new int[] {destinationBands[b]}; 1065 reader.processImageUpdateWrapper(destImage, 1066 x1, m, 1067 cTileHeight, 1068 1, 1, 1, 1069 destBands); 1070 } 1071 1072 reader.processImageProgressWrapper(percentage + 1073 (l + 1.0F) / 1074 cTileHeight / 1075 numBands / 1076 totalTiles); 1077 } 1078 } 1079 } else { 1080 throw new IllegalArgumentException(I18N.getString("RawRenderedImage1")); 1081 } 1082 } 1083 } // End loop on horizontal tiles 1084 } // End loop on vertical tiles 1085 1086 return raster; 1087 } 1088 1089 public void setDestImage(BufferedImage image) { 1090 destImage = image; 1091 } 1092 1093 public void clearDestImage() { 1094 destImage = null; 1095 } 1096 1097 private int getTileNum(int x, int y) { 1098 int num = (y - getMinTileY()) * getNumXTiles() + x - getMinTileX(); 1099 1100 if (num < 0 || num >= getNumXTiles() * getNumYTiles()) 1101 throw new IllegalArgumentException(I18N.getString("RawRenderedImage0")); 1102 1103 return num; 1104 } 1105 1106 private int clip(int value, int min, int max) { 1107 if (value < min) 1108 value = min; 1109 if (value > max) 1110 value = max; 1111 return value; 1112 } 1113}