예제 #1
0
  /**
   * Constructs a BytePackedRaster with the given SampleModel, DataBuffer, and parent. DataBuffer
   * must be a DataBufferByte and SampleModel must be of type MultiPixelPackedSampleModel. When
   * translated into the base Raster's coordinate system, aRegion must be contained by the base
   * Raster. Origin is the coordinate in the new Raster's coordinate system of the origin of the
   * base Raster. (The base Raster is the Raster's ancestor which has no parent.)
   *
   * <p>Note that this constructor should generally be called by other constructors or create
   * methods, it should not be used directly.
   *
   * @param sampleModel The SampleModel that specifies the layout.
   * @param dataBuffer The DataBufferShort that contains the image data.
   * @param aRegion The Rectangle that specifies the image area.
   * @param origin The Point that specifies the origin.
   * @param parent The parent (if any) of this raster.
   * @exception RasterFormatException if the parameters do not conform to requirements of this
   *     Raster type.
   */
  public BytePackedRaster(
      SampleModel sampleModel,
      DataBuffer dataBuffer,
      Rectangle aRegion,
      Point origin,
      BytePackedRaster parent) {
    super(sampleModel, dataBuffer, aRegion, origin, parent);
    this.maxX = minX + width;
    this.maxY = minY + height;

    if (!(dataBuffer instanceof DataBufferByte)) {
      throw new RasterFormatException("BytePackedRasters must have" + "byte DataBuffers");
    }
    DataBufferByte dbb = (DataBufferByte) dataBuffer;
    this.data = stealData(dbb, 0);
    if (dbb.getNumBanks() != 1) {
      throw new RasterFormatException(
          "DataBuffer for BytePackedRasters" + " must only have 1 bank.");
    }
    int dbOffset = dbb.getOffset();

    if (sampleModel instanceof MultiPixelPackedSampleModel) {
      MultiPixelPackedSampleModel mppsm = (MultiPixelPackedSampleModel) sampleModel;
      this.type = IntegerComponentRaster.TYPE_BYTE_BINARY_SAMPLES;
      pixelBitStride = mppsm.getPixelBitStride();
      if (pixelBitStride != 1 && pixelBitStride != 2 && pixelBitStride != 4) {
        throw new RasterFormatException("BytePackedRasters must have a bit depth of 1, 2, or 4");
      }
      scanlineStride = mppsm.getScanlineStride();
      dataBitOffset = mppsm.getDataBitOffset() + dbOffset * 8;
      int xOffset = aRegion.x - origin.x;
      int yOffset = aRegion.y - origin.y;
      dataBitOffset += xOffset * pixelBitStride + yOffset * scanlineStride * 8;
      bitMask = (1 << pixelBitStride) - 1;
      shiftOffset = 8 - pixelBitStride;
    } else {
      throw new RasterFormatException(
          "BytePackedRasters must have" + "MultiPixelPackedSampleModel");
    }
    verify(false);
  }
예제 #2
0
  public RenderedImage decodeAsRenderedImage(int page) throws IOException {
    if (page != 0) {
      throw new IOException(JaiI18N.getString(JaiI18N.getString("WBMPImageDecoder0")));
    }

    input.read(); // TypeField
    input.read(); // FixHeaderField

    // Image width
    int value = input.read();
    int width = value & 0x7f;
    while ((value & 0x80) == 0x80) {
      width <<= 7;
      value = input.read();
      width |= (value & 0x7f);
    }

    // Image height
    value = input.read();
    int height = value & 0x7f;
    while ((value & 0x80) == 0x80) {
      height <<= 7;
      value = input.read();
      height |= (value & 0x7f);
    }

    // Create byte-packed bilevel image width an IndexColorModel
    BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY);

    // Get the image tile.
    WritableRaster tile = bi.getWritableTile(0, 0);

    // Get the SampleModel.
    MultiPixelPackedSampleModel sm = (MultiPixelPackedSampleModel) bi.getSampleModel();

    // Read the data.
    input.readFully(
        ((DataBufferByte) tile.getDataBuffer()).getData(), 0, height * sm.getScanlineStride());

    return bi;
  }
예제 #3
0
  /** Constructs a DirectRasterAccessor object */
  public DirectRasterAccessor(Raster raster, ColorModel cm) {
    DataBuffer db = raster.getDataBuffer();

    offsetX = raster.getMinX() - raster.getSampleModelTranslateX();
    offsetY = raster.getMinY() - raster.getSampleModelTranslateY();

    if (!(db instanceof DataBufferByte)) {
      throw new RuntimeException(
          "DataBuffer of Raster not of correct type "
              + "(expected DataBufferByte, got "
              + db.getClass().getName()
              + ")");
    }

    DataBufferByte dbb = (DataBufferByte) db;

    SampleModel sm = raster.getSampleModel();

    if (!(sm instanceof MultiPixelPackedSampleModel)) {
      throw new RuntimeException(
          "SampleModel of Raster not of correct type "
              + "(expected MultiPixelPackedSampleModel, got "
              + sm.getClass().getName()
              + ")");
    }

    MultiPixelPackedSampleModel mppsm = (MultiPixelPackedSampleModel) sm;

    data = dbb.getData();
    scanlineStride = mppsm.getScanlineStride();

    if (cm.getRGB(0) == Color.white.getRGB()) {
      white = 0;
      black = 1;
    } else {
      white = 1;
      black = 0;
    }
  }
예제 #4
0
  private Raster readSubsampledRaster(WritableRaster raster) throws IOException {
    if (raster == null)
      raster =
          Raster.createWritableRaster(
              sampleModel.createCompatibleSampleModel(
                  destinationRegion.x + destinationRegion.width,
                  destinationRegion.y + destinationRegion.height),
              new Point(destinationRegion.x, destinationRegion.y));

    int numBands = sourceBands.length;
    int dataType = sampleModel.getDataType();
    int sampleSizeBit = DataBuffer.getDataTypeSize(dataType);
    int sampleSizeByte = (sampleSizeBit + 7) / 8;

    Rectangle destRect = raster.getBounds().intersection(destinationRegion);

    int offx = destinationRegion.x;
    int offy = destinationRegion.y;

    int sourceSX = (destRect.x - offx) * scaleX + sourceOrigin.x;
    int sourceSY = (destRect.y - offy) * scaleY + sourceOrigin.y;
    int sourceEX = (destRect.width - 1) * scaleX + sourceSX;
    int sourceEY = (destRect.height - 1) * scaleY + sourceSY;
    int startXTile = sourceSX / tileWidth;
    int startYTile = sourceSY / tileHeight;
    int endXTile = sourceEX / tileWidth;
    int endYTile = sourceEY / tileHeight;

    startXTile = clip(startXTile, 0, maxXTile);
    startYTile = clip(startYTile, 0, maxYTile);
    endXTile = clip(endXTile, 0, maxXTile);
    endYTile = clip(endYTile, 0, maxYTile);

    int totalXTiles = getNumXTiles();
    int totalYTiles = getNumYTiles();
    int totalTiles = totalXTiles * totalYTiles;

    // The line buffer for the source
    byte[] pixbuf = null; // byte buffer for the decoded pixels.
    short[] spixbuf = null; // byte buffer for the decoded pixels.
    int[] ipixbuf = null; // byte buffer for the decoded pixels.
    float[] fpixbuf = null; // byte buffer for the decoded pixels.
    double[] dpixbuf = null; // byte buffer for the decoded pixels.

    // A flag to show the ComponentSampleModel has a single data bank
    boolean singleBank = true;
    int pixelStride = 0;
    int scanlineStride = 0;
    int bandStride = 0;
    int[] bandOffsets = null;
    int[] bankIndices = null;

    if (originalSampleModel instanceof ComponentSampleModel) {
      ComponentSampleModel csm = (ComponentSampleModel) originalSampleModel;
      bankIndices = csm.getBankIndices();
      int maxBank = 0;
      for (int i = 0; i < bankIndices.length; i++)
        if (maxBank > bankIndices[i]) maxBank = bankIndices[i];

      if (maxBank > 0) singleBank = false;
      pixelStride = csm.getPixelStride();

      scanlineStride = csm.getScanlineStride();
      bandOffsets = csm.getBandOffsets();
      for (int i = 0; i < bandOffsets.length; i++)
        if (bandStride < bandOffsets[i]) bandStride = bandOffsets[i];
    } else if (originalSampleModel instanceof MultiPixelPackedSampleModel) {
      scanlineStride = ((MultiPixelPackedSampleModel) originalSampleModel).getScanlineStride();
    } else if (originalSampleModel instanceof SinglePixelPackedSampleModel) {
      pixelStride = 1;
      scanlineStride = ((SinglePixelPackedSampleModel) originalSampleModel).getScanlineStride();
    }

    // The dstination buffer for the raster
    byte[] destPixbuf = null; // byte buffer for the decoded pixels.
    short[] destSPixbuf = null; // byte buffer for the decoded pixels.
    int[] destIPixbuf = null; // byte buffer for the decoded pixels.
    float[] destFPixbuf = null; // byte buffer for the decoded pixels.
    double[] destDPixbuf = null; // byte buffer for the decoded pixels.
    int[] destBandOffsets = null;
    int destPixelStride = 0;
    int destScanlineStride = 0;
    int destSX = 0; // The first pixel for the destionation

    if (raster.getSampleModel() instanceof ComponentSampleModel) {
      ComponentSampleModel csm = (ComponentSampleModel) raster.getSampleModel();
      bankIndices = csm.getBankIndices();
      destBandOffsets = csm.getBandOffsets();
      destPixelStride = csm.getPixelStride();
      destScanlineStride = csm.getScanlineStride();
      destSX =
          csm.getOffset(
                  raster.getMinX() - raster.getSampleModelTranslateX(),
                  raster.getMinY() - raster.getSampleModelTranslateY())
              - destBandOffsets[0];

      switch (dataType) {
        case DataBuffer.TYPE_BYTE:
          destPixbuf = ((DataBufferByte) raster.getDataBuffer()).getData();
          break;
        case DataBuffer.TYPE_SHORT:
          destSPixbuf = ((DataBufferShort) raster.getDataBuffer()).getData();
          break;

        case DataBuffer.TYPE_USHORT:
          destSPixbuf = ((DataBufferUShort) raster.getDataBuffer()).getData();
          break;

        case DataBuffer.TYPE_INT:
          destIPixbuf = ((DataBufferInt) raster.getDataBuffer()).getData();
          break;

        case DataBuffer.TYPE_FLOAT:
          destFPixbuf = ((DataBufferFloat) raster.getDataBuffer()).getData();
          break;

        case DataBuffer.TYPE_DOUBLE:
          destDPixbuf = ((DataBufferDouble) raster.getDataBuffer()).getData();
          break;
      }
    } else if (raster.getSampleModel() instanceof SinglePixelPackedSampleModel) {
      numBands = 1;
      bankIndices = new int[] {0};
      destBandOffsets = new int[numBands];
      for (int i = 0; i < numBands; i++) destBandOffsets[i] = 0;
      destPixelStride = 1;
      destScanlineStride =
          ((SinglePixelPackedSampleModel) raster.getSampleModel()).getScanlineStride();
    }

    // Start the data delivery to the cached consumers tile by tile
    for (int y = startYTile; y <= endYTile; y++) {
      if (reader.getAbortRequest()) break;

      // Loop on horizontal tiles
      for (int x = startXTile; x <= endXTile; x++) {
        if (reader.getAbortRequest()) break;

        long tilePosition = position + (y * originalNumXTiles + x) * tileDataSize;
        iis.seek(tilePosition);
        float percentage = (x - startXTile + y * totalXTiles) / totalXTiles;

        int startX = x * tileWidth;
        int startY = y * tileHeight;

        int cTileHeight = tileHeight;
        int cTileWidth = tileWidth;

        if (startY + cTileHeight >= originalDimension.height)
          cTileHeight = originalDimension.height - startY;

        if (startX + cTileWidth >= originalDimension.width)
          cTileWidth = originalDimension.width - startX;

        int tx = startX;
        int ty = startY;

        // If source start position calculated by taking subsampling
        // into account is after the tile's start X position, adjust
        // the start position accordingly
        if (sourceSX > startX) {
          cTileWidth += startX - sourceSX;
          tx = sourceSX;
          startX = sourceSX;
        }

        if (sourceSY > startY) {
          cTileHeight += startY - sourceSY;
          ty = sourceSY;
          startY = sourceSY;
        }

        // If source end position calculated by taking subsampling
        // into account is prior to the tile's end X position, adjust
        // the tile width to read accordingly
        if (sourceEX < startX + cTileWidth - 1) {
          cTileWidth += sourceEX - startX - cTileWidth + 1;
        }

        if (sourceEY < startY + cTileHeight - 1) {
          cTileHeight += sourceEY - startY - cTileHeight + 1;
        }

        // The start X in the destination
        int x1 = (startX + scaleX - 1 - sourceOrigin.x) / scaleX;
        int x2 = (startX + scaleX - 1 + cTileWidth - sourceOrigin.x) / scaleX;
        int lineLength = x2 - x1;
        x2 = (x2 - 1) * scaleX + sourceOrigin.x;

        int y1 = (startY + scaleY - 1 - sourceOrigin.y) / scaleY;
        startX = x1 * scaleX + sourceOrigin.x;
        startY = y1 * scaleY + sourceOrigin.y;

        // offx is destination.x
        x1 += offx;
        y1 += offy;

        tx -= x * tileWidth;
        ty -= y * tileHeight;

        if (sampleModel instanceof MultiPixelPackedSampleModel) {
          MultiPixelPackedSampleModel mppsm = (MultiPixelPackedSampleModel) originalSampleModel;

          iis.skipBytes(mppsm.getOffset(tx, ty) * sampleSizeByte);

          int readBytes =
              (mppsm.getOffset(x2, 0) - mppsm.getOffset(startX, 0) + 1) * sampleSizeByte;

          int skipLength = (scanlineStride * scaleY - readBytes) * sampleSizeByte;
          readBytes *= sampleSizeByte;

          if (pixbuf == null || pixbuf.length < readBytes) pixbuf = new byte[readBytes];

          int bitoff = mppsm.getBitOffset(tx);

          for (int l = 0, m = y1; l < cTileHeight; l += scaleY, m++) {
            if (reader.getAbortRequest()) break;
            iis.readFully(pixbuf, 0, readBytes);
            if (scaleX == 1) {

              if (bitoff != 0) {
                int mask1 = (255 << bitoff) & 255;
                int mask2 = ~mask1 & 255;
                int shift = 8 - bitoff;

                int n = 0;
                for (; n < readBytes - 1; n++)
                  pixbuf[n] =
                      (byte) (((pixbuf[n] & mask2) << shift) | (pixbuf[n + 1] & mask1) >> bitoff);
                pixbuf[n] = (byte) ((pixbuf[n] & mask2) << shift);
              }
            } else {

              int bit = 7;
              int pos = 0;
              int mask = 128;

              for (int n = 0, n1 = startX & 7; n < lineLength; n++, n1 += scaleX) {
                pixbuf[pos] =
                    (byte)
                        ((pixbuf[pos] & ~(1 << bit))
                            | (((pixbuf[n1 >> 3] >> (7 - (n1 & 7))) & 1) << bit));
                bit--;
                if (bit == -1) {
                  bit = 7;
                  pos++;
                }
              }
            }

            ImageUtil.setPackedBinaryData(pixbuf, raster, new Rectangle(x1, m, lineLength, 1));
            iis.skipBytes(skipLength);
            if (destImage != null)
              reader.processImageUpdateWrapper(
                  destImage, x1, m, cTileWidth, 1, 1, 1, destinationBands);

            reader.processImageProgressWrapper(
                percentage + (l - startY + 1.0F) / cTileHeight / totalTiles);
          }
        } else {

          int readLength, skipLength;
          if (pixelStride < scanlineStride) {
            readLength = cTileWidth * pixelStride;
            skipLength = (scanlineStride * scaleY - readLength) * sampleSizeByte;
          } else {
            readLength = cTileHeight * scanlineStride;
            skipLength = (pixelStride * scaleX - readLength) * sampleSizeByte;
          }

          // Allocate buffer for all the types
          switch (sampleModel.getDataType()) {
            case DataBuffer.TYPE_BYTE:
              if (pixbuf == null || pixbuf.length < readLength) pixbuf = new byte[readLength];
              break;

            case DataBuffer.TYPE_SHORT:
            case DataBuffer.TYPE_USHORT:
              if (spixbuf == null || spixbuf.length < readLength) spixbuf = new short[readLength];
              break;

            case DataBuffer.TYPE_INT:
              if (ipixbuf == null || ipixbuf.length < readLength) ipixbuf = new int[readLength];
              break;

            case DataBuffer.TYPE_FLOAT:
              if (fpixbuf == null || fpixbuf.length < readLength) fpixbuf = new float[readLength];
              break;

            case DataBuffer.TYPE_DOUBLE:
              if (dpixbuf == null || dpixbuf.length < readLength) dpixbuf = new double[readLength];
              break;
          }

          if (sampleModel instanceof PixelInterleavedSampleModel) {
            iis.skipBytes((tx * pixelStride + ty * scanlineStride) * sampleSizeByte);

            // variables for ther loop
            int outerFirst, outerSecond, outerStep, outerBound;
            int innerStep, innerStep1, outerStep1;
            if (pixelStride < scanlineStride) {
              outerFirst = 0;
              outerSecond = y1;
              outerStep = scaleY;
              outerBound = cTileHeight;
              innerStep = scaleX * pixelStride;
              innerStep1 = destPixelStride;
              outerStep1 = destScanlineStride;
            } else {
              outerFirst = 0;
              outerSecond = x1;
              outerStep = scaleX;
              outerBound = cTileWidth;
              innerStep = scaleY * scanlineStride;
              innerStep1 = destScanlineStride;
              outerStep1 = destPixelStride;
            }

            int destPos =
                destSX
                    + (y1 - raster.getSampleModelTranslateY()) * destScanlineStride
                    + (x1 - raster.getSampleModelTranslateX()) * destPixelStride;

            for (int l = outerFirst, m = outerSecond; l < outerBound; l += outerStep, m++) {
              if (reader.getAbortRequest()) break;

              switch (dataType) {
                case DataBuffer.TYPE_BYTE:
                  if (innerStep == numBands && innerStep1 == numBands)
                    iis.readFully(destPixbuf, destPos, readLength);
                  else iis.readFully(pixbuf, 0, readLength);
                  break;
                case DataBuffer.TYPE_SHORT:
                case DataBuffer.TYPE_USHORT:
                  if (innerStep == numBands && innerStep1 == numBands) {
                    iis.readFully(destSPixbuf, destPos, readLength);
                  } else iis.readFully(spixbuf, 0, readLength);
                  break;
                case DataBuffer.TYPE_INT:
                  if (innerStep == numBands && innerStep1 == numBands)
                    iis.readFully(destIPixbuf, destPos, readLength);
                  else iis.readFully(ipixbuf, 0, readLength);
                  break;
                case DataBuffer.TYPE_FLOAT:
                  if (innerStep == numBands && innerStep1 == numBands)
                    iis.readFully(destFPixbuf, destPos, readLength);
                  else iis.readFully(fpixbuf, 0, readLength);
                  break;
                case DataBuffer.TYPE_DOUBLE:
                  if (innerStep == numBands && innerStep1 == numBands)
                    iis.readFully(destDPixbuf, destPos, readLength);
                  else iis.readFully(dpixbuf, 0, readLength);
                  break;
              }

              if (innerStep != numBands || innerStep1 != numBands)
                for (int b = 0; b < numBands; b++) {
                  int destBandOffset = destBandOffsets[destinationBands[b]];
                  destPos += destBandOffset;

                  int sourceBandOffset = bandOffsets[sourceBands[b]];

                  switch (dataType) {
                    case DataBuffer.TYPE_BYTE:
                      for (int m1 = 0, n = destPos;
                          m1 < readLength;
                          m1 += innerStep, n += innerStep1) {
                        destPixbuf[n] = pixbuf[m1 + sourceBandOffset];
                      }
                      break;
                    case DataBuffer.TYPE_SHORT:
                    case DataBuffer.TYPE_USHORT:
                      for (int m1 = 0, n = destPos;
                          m1 < readLength;
                          m1 += innerStep, n += innerStep1) {
                        destSPixbuf[n] = spixbuf[m1 + sourceBandOffset];
                      }
                      break;
                    case DataBuffer.TYPE_INT:
                      for (int m1 = 0, n = destPos;
                          m1 < readLength;
                          m1 += innerStep, n += innerStep1) {
                        destIPixbuf[n] = ipixbuf[m1 + sourceBandOffset];
                      }
                      break;
                    case DataBuffer.TYPE_FLOAT:
                      for (int m1 = 0, n = destPos;
                          m1 < readLength;
                          m1 += innerStep, n += innerStep1) {
                        destFPixbuf[n] = fpixbuf[m1 + sourceBandOffset];
                      }
                      break;
                    case DataBuffer.TYPE_DOUBLE:
                      for (int m1 = 0, n = destPos;
                          m1 < readLength;
                          m1 += innerStep, n += innerStep1) {
                        destDPixbuf[n] = dpixbuf[m1 + sourceBandOffset];
                      }
                      break;
                  }
                  destPos -= destBandOffset;
                }

              iis.skipBytes(skipLength);
              destPos += outerStep1;

              if (destImage != null)
                if (pixelStride < scanlineStride)
                  reader.processImageUpdateWrapper(
                      destImage, x1, m, outerBound, 1, 1, 1, destinationBands);
                else
                  reader.processImageUpdateWrapper(
                      destImage, m, y1, 1, outerBound, 1, 1, destinationBands);

              reader.processImageProgressWrapper(percentage + (l + 1.0F) / outerBound / totalTiles);
            }
          } else if (sampleModel instanceof BandedSampleModel
              || sampleModel instanceof SinglePixelPackedSampleModel
              || bandStride == 0) {
            boolean isBanded = sampleModel instanceof BandedSampleModel;

            int bandSize = (int) ImageUtil.getBandSize(originalSampleModel);

            for (int b = 0; b < numBands; b++) {
              iis.seek(tilePosition + bandSize * sourceBands[b] * sampleSizeByte);
              int destBandOffset = destBandOffsets[destinationBands[b]];

              iis.skipBytes((ty * scanlineStride + tx * pixelStride) * sampleSizeByte);

              // variables for ther loop
              int outerFirst, outerSecond, outerStep, outerBound;
              int innerStep, innerStep1, outerStep1;
              if (pixelStride < scanlineStride) {
                outerFirst = 0;
                outerSecond = y1;
                outerStep = scaleY;
                outerBound = cTileHeight;
                innerStep = scaleX * pixelStride;
                innerStep1 = destPixelStride;
                outerStep1 = destScanlineStride;
              } else {
                outerFirst = 0;
                outerSecond = x1;
                outerStep = scaleX;
                outerBound = cTileWidth;
                innerStep = scaleY * scanlineStride;
                innerStep1 = destScanlineStride;
                outerStep1 = destPixelStride;
              }

              int destPos =
                  destSX
                      + (y1 - raster.getSampleModelTranslateY()) * destScanlineStride
                      + (x1 - raster.getSampleModelTranslateX()) * destPixelStride
                      + destBandOffset;

              int bank = bankIndices[destinationBands[b]];

              switch (dataType) {
                case DataBuffer.TYPE_BYTE:
                  destPixbuf = ((DataBufferByte) raster.getDataBuffer()).getData(bank);
                  break;
                case DataBuffer.TYPE_SHORT:
                  destSPixbuf = ((DataBufferShort) raster.getDataBuffer()).getData(bank);
                  break;

                case DataBuffer.TYPE_USHORT:
                  destSPixbuf = ((DataBufferUShort) raster.getDataBuffer()).getData(bank);
                  break;

                case DataBuffer.TYPE_INT:
                  destIPixbuf = ((DataBufferInt) raster.getDataBuffer()).getData(bank);
                  break;

                case DataBuffer.TYPE_FLOAT:
                  destFPixbuf = ((DataBufferFloat) raster.getDataBuffer()).getData(bank);
                  break;

                case DataBuffer.TYPE_DOUBLE:
                  destDPixbuf = ((DataBufferDouble) raster.getDataBuffer()).getData(bank);
                  break;
              }

              for (int l = outerFirst, m = outerSecond; l < outerBound; l += outerStep, m++) {
                if (reader.getAbortRequest()) break;

                switch (dataType) {
                  case DataBuffer.TYPE_BYTE:
                    if (innerStep == 1 && innerStep1 == 1) {
                      iis.readFully(destPixbuf, destPos, readLength);
                    } else {
                      iis.readFully(pixbuf, 0, readLength);
                      for (int m1 = 0, n = destPos;
                          m1 < readLength;
                          m1 += innerStep, n += innerStep1) {
                        destPixbuf[n] = pixbuf[m1];
                      }
                    }
                    break;
                  case DataBuffer.TYPE_SHORT:
                  case DataBuffer.TYPE_USHORT:
                    if (innerStep == 1 && innerStep1 == 1) {
                      iis.readFully(destSPixbuf, destPos, readLength);
                    } else {
                      iis.readFully(spixbuf, 0, readLength);
                      for (int m1 = 0, n = destPos;
                          m1 < readLength;
                          m1 += innerStep, n += innerStep1) {
                        destSPixbuf[n] = spixbuf[m1];
                      }
                    }
                    break;
                  case DataBuffer.TYPE_INT:
                    if (innerStep == 1 && innerStep1 == 1) {
                      iis.readFully(destIPixbuf, destPos, readLength);
                    } else {
                      iis.readFully(ipixbuf, 0, readLength);
                      for (int m1 = 0, n = destPos;
                          m1 < readLength;
                          m1 += innerStep, n += innerStep1) {
                        destIPixbuf[n] = ipixbuf[m1];
                      }
                    }
                    break;
                  case DataBuffer.TYPE_FLOAT:
                    if (innerStep == 1 && innerStep1 == 1) {
                      iis.readFully(destFPixbuf, destPos, readLength);
                    } else {
                      iis.readFully(fpixbuf, 0, readLength);
                      for (int m1 = 0, n = destPos;
                          m1 < readLength;
                          m1 += innerStep, n += innerStep1) {
                        destFPixbuf[n] = fpixbuf[m1];
                      }
                    }
                    break;
                  case DataBuffer.TYPE_DOUBLE:
                    if (innerStep == 1 && innerStep1 == 1) {
                      iis.readFully(destDPixbuf, destPos, readLength);
                    } else {
                      iis.readFully(dpixbuf, 0, readLength);
                      for (int m1 = 0, n = destPos;
                          m1 < readLength;
                          m1 += innerStep, n += innerStep1) {
                        destDPixbuf[n] = dpixbuf[m1];
                      }
                    }
                    break;
                }

                iis.skipBytes(skipLength);
                destPos += outerStep1;

                if (destImage != null) {
                  int[] destBands = new int[] {destinationBands[b]};
                  if (pixelStride < scanlineStride)
                    reader.processImageUpdateWrapper(
                        destImage, x1, m, outerBound, 1, 1, 1, destBands);
                  else
                    reader.processImageUpdateWrapper(
                        destImage, m, y1, 1, outerBound, 1, 1, destBands);
                }

                reader.processImageProgressWrapper(
                    (percentage + (l + 1.0F) / outerBound / numBands / totalTiles) * 100.0F);
              }
            }
          } else if (sampleModel instanceof ComponentSampleModel) {
            // for the other case, may slow
            // Allocate buffer for all the types
            int bufferSize = (int) tileDataSize;

            switch (sampleModel.getDataType()) {
              case DataBuffer.TYPE_BYTE:
                if (pixbuf == null || pixbuf.length < tileDataSize)
                  pixbuf = new byte[(int) tileDataSize];
                iis.readFully(pixbuf, 0, (int) tileDataSize);
                break;

              case DataBuffer.TYPE_SHORT:
              case DataBuffer.TYPE_USHORT:
                bufferSize /= 2;
                if (spixbuf == null || spixbuf.length < bufferSize)
                  spixbuf = new short[(int) bufferSize];
                iis.readFully(spixbuf, 0, (int) bufferSize);
                break;

              case DataBuffer.TYPE_INT:
                bufferSize /= 4;
                if (ipixbuf == null || ipixbuf.length < bufferSize)
                  ipixbuf = new int[(int) bufferSize];
                iis.readFully(ipixbuf, 0, (int) bufferSize);
                break;

              case DataBuffer.TYPE_FLOAT:
                bufferSize /= 4;
                if (fpixbuf == null || fpixbuf.length < bufferSize)
                  fpixbuf = new float[(int) bufferSize];
                iis.readFully(fpixbuf, 0, (int) bufferSize);
                break;

              case DataBuffer.TYPE_DOUBLE:
                bufferSize /= 8;
                if (dpixbuf == null || dpixbuf.length < bufferSize)
                  dpixbuf = new double[(int) bufferSize];
                iis.readFully(dpixbuf, 0, (int) bufferSize);
                break;
            }

            for (int b = 0; b < numBands; b++) {
              int destBandOffset = destBandOffsets[destinationBands[b]];

              int destPos =
                  ((ComponentSampleModel) raster.getSampleModel())
                      .getOffset(
                          x1 - raster.getSampleModelTranslateX(),
                          y1 - raster.getSampleModelTranslateY(),
                          destinationBands[b]);

              int bank = bankIndices[destinationBands[b]];

              switch (dataType) {
                case DataBuffer.TYPE_BYTE:
                  destPixbuf = ((DataBufferByte) raster.getDataBuffer()).getData(bank);
                  break;
                case DataBuffer.TYPE_SHORT:
                  destSPixbuf = ((DataBufferShort) raster.getDataBuffer()).getData(bank);
                  break;

                case DataBuffer.TYPE_USHORT:
                  destSPixbuf = ((DataBufferUShort) raster.getDataBuffer()).getData(bank);
                  break;

                case DataBuffer.TYPE_INT:
                  destIPixbuf = ((DataBufferInt) raster.getDataBuffer()).getData(bank);
                  break;

                case DataBuffer.TYPE_FLOAT:
                  destFPixbuf = ((DataBufferFloat) raster.getDataBuffer()).getData(bank);
                  break;

                case DataBuffer.TYPE_DOUBLE:
                  destDPixbuf = ((DataBufferDouble) raster.getDataBuffer()).getData(bank);
                  break;
              }

              int srcPos =
                  ((ComponentSampleModel) originalSampleModel).getOffset(tx, ty, sourceBands[b]);
              int skipX = scaleX * pixelStride;
              ;
              for (int l = 0, m = y1; l < cTileHeight; l += scaleY, m++) {
                if (reader.getAbortRequest()) break;

                switch (dataType) {
                  case DataBuffer.TYPE_BYTE:
                    for (int n = 0, m1 = srcPos, m2 = destPos;
                        n < lineLength;
                        n++, m1 += skipX, m2 += destPixelStride) destPixbuf[m2] = pixbuf[m1];
                    break;
                  case DataBuffer.TYPE_SHORT:
                  case DataBuffer.TYPE_USHORT:
                    for (int n = 0, m1 = srcPos, m2 = destPos;
                        n < lineLength;
                        n++, m1 += skipX, m2 += destPixelStride) destSPixbuf[m2] = spixbuf[m1];
                    break;
                  case DataBuffer.TYPE_INT:
                    for (int n = 0, m1 = srcPos, m2 = destPos;
                        n < lineLength;
                        n++, m1 += skipX, m2 += destPixelStride) destIPixbuf[m2] = ipixbuf[m1];
                    break;
                  case DataBuffer.TYPE_FLOAT:
                    for (int n = 0, m1 = srcPos, m2 = destPos;
                        n < lineLength;
                        n++, m1 += skipX, m2 += destPixelStride) destFPixbuf[m2] = fpixbuf[m1];
                    break;
                  case DataBuffer.TYPE_DOUBLE:
                    for (int n = 0, m1 = srcPos, m2 = destPos;
                        n < lineLength;
                        n++, m1 += skipX, m2 += destPixelStride) destDPixbuf[m2] = dpixbuf[m1];
                    break;
                }

                destPos += destScanlineStride;
                srcPos += scanlineStride * scaleY;

                if (destImage != null) {
                  int[] destBands = new int[] {destinationBands[b]};
                  reader.processImageUpdateWrapper(
                      destImage, x1, m, cTileHeight, 1, 1, 1, destBands);
                }

                reader.processImageProgressWrapper(
                    percentage + (l + 1.0F) / cTileHeight / numBands / totalTiles);
              }
            }
          } else {
            throw new IllegalArgumentException(I18N.getString("RawRenderedImage1"));
          }
        }
      } // End loop on horizontal tiles
    } // End loop on vertical tiles

    return raster;
  }