@Test
  public void testReadBandRasterData() {
    Date startDate = Calendar.getInstance().getTime();
    // Product product = new Product("name", "desc", 100, 200);
    File file =
        TestUtil.getTestFile(
            productsFolder + "SP04_HRI1_X__1O_20050605T090007_20050605T090016_DLR_70_PREU.BIL.ZIP");
    // File rasterFile = TestUtil.getTestFile(productsFolder + "mediumImage.tif");
    System.setProperty("snap.dataio.reader.tileWidth", "100");
    System.setProperty("snap.dataio.reader.tileHeight", "200");
    try {

      Product finalProduct = reader.readProductNodes(file, null);
      ProductData data = ProductData.createInstance(ProductData.TYPE_UINT16, 20000);
      data.setElemFloatAt(3, 5);
      reader.readBandRasterData(
          finalProduct.getBandAt(0), 2000, 2000, 100, 200, data, new NullProgressMonitor());
      assertNotEquals(0, data.getElemFloatAt(0));
      assertNotEquals(-1000, data.getElemFloatAt(0));
      assertNotEquals(0, data.getElemFloatAt(1999));
      assertNotEquals(-1000, data.getElemFloatAt(1999));
      assertNotEquals(5, data.getElemFloatAt(3));
      Date endDate = Calendar.getInstance().getTime();
      assertTrue(
          "The load time for the product is too big!",
          (endDate.getTime() - startDate.getTime()) / (60 * 1000) < 30);
    } catch (IOException e) {
      e.printStackTrace();
      assertTrue(e.getMessage(), false);
    }
  }
  /**
   * Writes raster data from the given in-memory source buffer into the data sink specified by the
   * given source band and region.
   *
   * <p>
   *
   * <h3>Source band</h3>
   *
   * The source band is used to identify the data sink in which this method transfers the sample
   * values given in the source buffer. The method does not modify the pixel data of the given
   * source band at all.
   *
   * <p>
   *
   * <h3>Source buffer</h3>
   *
   * The first element of the source buffer corresponds to the given <code>sourceOffsetX</code> and
   * <code>sourceOffsetY</code> of the source region. These parameters are an offset within the
   * band's raster data and <b>not</b> an offset within the source buffer.<br>
   * The number of elements in the buffer must be exactly be <code>sourceWidth * sourceHeight</code>
   * . The pixel values to be writte are considered to be stored in line-by-line order, so the
   * raster X co-ordinate varies faster than the Y.
   *
   * <p>
   *
   * <h3>Source region</h3>
   *
   * The given destination region specified by the <code>sourceOffsetX</code>, <code>sourceOffsetY
   * </code>, <code>sourceWidth</code> and <code>sourceHeight</code> parameters is given in the
   * source band's raster co-ordinates. These co-ordinates are identical with the destination raster
   * co-ordinates since product writers do not support spectral or spatial subsets.
   *
   * @param sourceBand the source band which identifies the data sink to which to write the sample
   *     values
   * @param regionData the data buffer which provides the sample values to be written
   * @param regionX the X-offset in the band's raster co-ordinates
   * @param regionY the Y-offset in the band's raster co-ordinates
   * @param regionWidth the width of region to be written given in the band's raster co-ordinates
   * @param regionHeight the height of region to be written given in the band's raster co-ordinates
   * @throws java.io.IOException if an I/O error occurs
   * @throws IllegalArgumentException if the number of elements source buffer not equals <code>
   *     sourceWidth *
   *                                  sourceHeight</code> or the source region is out of the band's
   *     raster
   * @see Band#getRasterWidth()
   * @see Band#getRasterHeight()
   */
  public void writeBandRasterData(
      final Band sourceBand,
      final int regionX,
      final int regionY,
      final int regionWidth,
      final int regionHeight,
      final ProductData regionData,
      ProgressMonitor pm)
      throws IOException {
    if (!tempProduct.containsBand(sourceBand.getName())) {
      throw new IllegalArgumentException(
          "'" + sourceBand.getName() + "' is not a band of the product");
    }
    final int bandDataType = ifd.getBandDataType();
    final int stripIndex = getStripIndex(sourceBand);
    final TiffValue[] offsetValues = ifd.getEntry(TiffTag.STRIP_OFFSETS).getValues();
    final long stripOffset = ((TiffLong) offsetValues[stripIndex]).getValue();
    final TiffValue[] bitsPerSampleValues = ifd.getEntry(TiffTag.BITS_PER_SAMPLE).getValues();
    final long elemSize = ((TiffShort) bitsPerSampleValues[stripIndex]).getValue() / 8;
    final long sourceWidthBytes = sourceBand.getSceneRasterWidth() * elemSize;
    final long regionOffsetXInBytes = regionX * elemSize;
    final long pixelOffset = sourceWidthBytes * regionY + regionOffsetXInBytes;
    final long startOffset = stripOffset + pixelOffset;

    pm.beginTask("Writing band '" + sourceBand.getName() + "'...", regionHeight);
    try {
      for (int y = 0; y < regionHeight; y++) {
        ios.seek(startOffset + y * sourceWidthBytes);
        final int stride = y * regionWidth;
        if (bandDataType == ProductData.TYPE_UINT8) {
          final byte[] data = new byte[regionWidth];
          for (int x = 0; x < regionWidth; x++) {
            data[x] = (byte) regionData.getElemUIntAt(stride + x);
          }
          ios.write(data);
        } else if (bandDataType == ProductData.TYPE_INT8) {
          final byte[] data = new byte[regionWidth];
          for (int x = 0; x < regionWidth; x++) {
            data[x] = (byte) regionData.getElemIntAt(stride + x);
          }
          ios.write(data);
        } else if (bandDataType == ProductData.TYPE_UINT16) {
          final short[] data = new short[regionWidth];
          for (int x = 0; x < regionWidth; x++) {
            data[x] = (short) regionData.getElemUIntAt(stride + x);
          }
          ios.writeShorts(data, 0, regionWidth);
        } else if (bandDataType == ProductData.TYPE_INT16) {
          final short[] data = new short[regionWidth];
          for (int x = 0; x < regionWidth; x++) {
            data[x] = (short) regionData.getElemIntAt(stride + x);
          }
          ios.writeShorts(data, 0, regionWidth);
        } else if (bandDataType == ProductData.TYPE_UINT32) {
          final int[] data = new int[regionWidth];
          for (int x = 0; x < regionWidth; x++) {
            data[x] = (int) regionData.getElemUIntAt(stride + x);
          }
          ios.writeInts(data, 0, regionWidth);
        } else if (bandDataType == ProductData.TYPE_INT32) {
          final int[] data = new int[regionWidth];
          for (int x = 0; x < regionWidth; x++) {
            data[x] = regionData.getElemIntAt(stride + x);
          }
          ios.writeInts(data, 0, regionWidth);
        } else if (bandDataType == ProductData.TYPE_FLOAT32) {
          final float[] data = new float[regionWidth];
          for (int x = 0; x < regionWidth; x++) {
            data[x] = regionData.getElemFloatAt(stride + x);
          }
          ios.writeFloats(data, 0, regionWidth);
        } else if (bandDataType == ProductData.TYPE_FLOAT64) {
          final double[] data = new double[regionWidth];
          for (int x = 0; x < regionWidth; x++) {
            data[x] = regionData.getElemDoubleAt(stride + x);
          }
          ios.writeDoubles(data, 0, regionWidth);
        }
        pm.worked(1);
      }
    } finally {
      pm.done();
    }
  }