private void copyBandRasterDataSubSampling(
     Band sourceBand,
     int sourceOffsetX,
     int sourceOffsetY,
     int sourceWidth,
     int sourceHeight,
     int sourceStepX,
     int sourceStepY,
     ProductData destBuffer,
     int destWidth) {
   final int sourceMinY = sourceOffsetY;
   final int sourceMaxY = sourceOffsetY + sourceHeight - 1;
   int destPos = 0;
   for (int sourceY = sourceMinY; sourceY <= sourceMaxY; sourceY += sourceStepY) {
     // no subsampling in x-direction
     if (sourceStepX == 1) {
       copyData(
           sourceBand.getRasterData(),
           sourceY * sourceBand.getSceneRasterWidth() + sourceOffsetX,
           destBuffer,
           destPos,
           destWidth);
     } else {
       copyLine(
           sourceBand.getRasterData(),
           sourceY * sourceBand.getSceneRasterWidth() + sourceOffsetX,
           sourceWidth,
           sourceStepX,
           destBuffer,
           destPos);
     }
     destPos += destWidth;
   }
 }
 /**
  * The template method which is called by the <code>readBandRasterDataSubSampling</code> method
  * after an optional spatial subset has been applied to the input parameters.
  *
  * <p>
  *
  * <p>The destination band, buffer and region parameters are exactly the ones passed to the
  * original <code>readBandRasterDataSubSampling</code> call. Since the <code>destOffsetX</code>
  * and <code>destOffsetY</code> parameters are already taken into acount in the <code>
  * sourceOffsetX</code> and <code>sourceOffsetY</code> parameters, an implementor of this method
  * is free to ignore them.
  *
  * @param sourceOffsetX the absolute X-offset in source raster co-ordinates
  * @param sourceOffsetY the absolute Y-offset in source raster co-ordinates
  * @param sourceWidth the width of region providing samples to be read given in source raster
  *     co-ordinates
  * @param sourceHeight the height of region providing samples to be read given in source raster
  *     co-ordinates
  * @param sourceStepX the sub-sampling in X direction within the region providing samples to be
  *     read
  * @param sourceStepY the sub-sampling in Y direction within the region providing samples to be
  *     read
  * @param destBand the destination band which identifies the data source from which to read the
  *     sample values
  * @param destBuffer the destination buffer which receives the sample values to be read
  * @param destOffsetX the X-offset in the band's raster co-ordinates
  * @param destOffsetY the Y-offset in the band's raster co-ordinates
  * @param destWidth the width of region to be read given in the band's raster co-ordinates
  * @param destHeight the height of region to be read given in the band's raster co-ordinates
  * @throws IOException if an I/O error occurs
  * @see #getSubsetDef
  */
 @Override
 protected void readBandRasterDataImpl(
     int sourceOffsetX,
     int sourceOffsetY,
     int sourceWidth,
     int sourceHeight,
     int sourceStepX,
     int sourceStepY,
     Band destBand,
     int destOffsetX,
     int destOffsetY,
     int destWidth,
     int destHeight,
     ProductData destBuffer,
     ProgressMonitor pm)
     throws IOException {
   Band sourceBand = (Band) bandMap.get(destBand);
   // if the band already has an internal raster
   if (sourceBand.getRasterData() != null) {
     // if the destination region equals the entire raster
     if (sourceBand.getSceneRasterWidth() == destWidth
         && sourceBand.getSceneRasterHeight() == destHeight) {
       copyBandRasterDataFully(sourceBand, destBuffer, destWidth, destHeight);
       // else if the destination region is smaller than the entire raster
     } else {
       copyBandRasterDataSubSampling(
           sourceBand,
           sourceOffsetX,
           sourceOffsetY,
           sourceWidth,
           sourceHeight,
           sourceStepX,
           sourceStepY,
           destBuffer,
           destWidth);
     }
   } else {
     // if the desired destination region equals the source raster
     if (sourceWidth == destWidth && sourceHeight == destHeight) {
       readBandRasterDataRegion(
           sourceBand, sourceOffsetX, sourceOffsetY, sourceWidth, sourceHeight, destBuffer, pm);
       // else if the desired destination region is smaller than the source raster
     } else {
       readBandRasterDataSubSampling(
           sourceBand,
           sourceOffsetX,
           sourceOffsetY,
           sourceWidth,
           sourceHeight,
           sourceStepX,
           sourceStepY,
           destBuffer,
           destWidth,
           pm);
     }
   }
 }
 private void copyBandRasterDataFully(
     Band sourceBand, ProductData destBuffer, int destWidth, int destHeight) {
   copyData(sourceBand.getRasterData(), 0, destBuffer, 0, destWidth * destHeight);
 }