public PlanarImage gridToEmage(double[][] dataGrid, String imageName) throws IOException {
    // creates a gray-scale image of the values
    int width = dataGrid[0].length;
    int height = dataGrid.length;

    // Get the number of bands on the image.
    URL imgURL = new URL(Config.getProperty("imgURL"));
    PlanarImage dummyImage = JAI.create("URL", imgURL); // dummy loaded. date to be edited.
    SampleModel sm = dummyImage.getSampleModel();
    int nbands = sm.getNumBands();

    // We assume that we can get the pixels values in a integer array.
    double[] pixelTemp = new double[nbands];

    // Get an iterator for the image.
    RandomIterFactory.create(dummyImage, null);
    WritableRaster rasterData =
        RasterFactory.createBandedRaster(
            DataBuffer.TYPE_BYTE, width, height, nbands, new Point(0, 0));

    for (int i = 0; i < height; i++) {
      for (int j = 0; j < width; j++) {
        dataGrid[i][j] = (dataGrid[i][j] <= 255) ? dataGrid[i][j] : 255;

        pixelTemp[0] = dataGrid[i][j];
        pixelTemp[1] = dataGrid[i][j];
        pixelTemp[2] = dataGrid[i][j];

        rasterData.setPixel(j, i, pixelTemp);
      }
    }

    SampleModel sModel2 =
        RasterFactory.createBandedSampleModel(DataBuffer.TYPE_BYTE, width, height, nbands);

    // Try to create a compatible ColorModel - if the number of bands is
    // larger than 4, it will be null.
    ColorModel cModel2 = PlanarImage.createColorModel(sModel2);

    // Create a TiledImage using the sample and color models.
    TiledImage rectImage = new TiledImage(0, 0, width, height, 0, 0, sModel2, cModel2);

    // Set the data of the tiled image to be the raster.
    rectImage.setData(rasterData);

    // Save the image on a file.
    try {
      ImageIO.write(rectImage, "jpg", new File(imageName + ".jpg"));
      log.info("debug save image : " + imageName + ".jpg");

    } catch (IOException e) {
      log.error(e.getMessage());
      log.error("Error in rectifying  image");
    }

    return rectImage;
  }
  protected RenderedImage createRenderedImage(
      RenderedImage renderedImage, int height, int width, DataBuffer dataBuffer) {

    SampleModel sampleModel =
        RasterFactory.createPixelInterleavedSampleModel(
            DataBuffer.TYPE_BYTE, width, height, _NUM_OF_BANDS);
    ColorModel colorModel = PlanarImage.createColorModel(sampleModel);

    TiledImage tiledImage = new TiledImage(0, 0, width, height, 0, 0, sampleModel, colorModel);

    Raster raster = RasterFactory.createWritableRaster(sampleModel, dataBuffer, new Point(0, 0));

    tiledImage.setData(raster);

    /*javax.media.jai.JAI.create(
    	"filestore", tiledImage, "test.png", "PNG");

    printImage(renderedImage);
    printImage(tiledImage);}*/

    return tiledImage;
  }
  public TiledImage makeQuadCurve(
      int lineBeginningX,
      int lineBeginningY,
      int lineEndingX,
      int lineEndingY,
      double slope1st,
      double slope2nd,
      Inspiram inspiram) {
    int width = inspiram.layers[inspiram.currentLayer].getWidth();
    int height = inspiram.layers[inspiram.currentLayer].getHeight();
    SampleModel mySampleModel =
        inspiram.layers[inspiram.currentLayer].getLayerImage().getSampleModel();
    int nbands = mySampleModel.getNumBands();
    Raster readableRaster = inspiram.layers[inspiram.currentLayer].getLayerImage().getData();
    WritableRaster writableRaster = readableRaster.createCompatibleWritableRaster();
    int[] pixels = new int[nbands * width * height];
    readableRaster.getPixels(0, 0, width, height, pixels);
    double yIntercept1st = findYIntercept(p1X, p1Y, slope1st);
    double yIntercept2nd = findYIntercept(p2X, p2Y, slope2nd);
    System.out.println(
        "Y-Intercept of 1st: "
            + findYIntercept(p0X, p0Y, slope1st)
            + "     Y-Intercept of 2nd: "
            + findYIntercept(p1X, p1Y, slope1st));
    int pixelIndexQ = 0;

    double x1first = p0X;
    double x2first = p1X;
    double y1first = p0Y;
    double y2first = p1Y;
    double x1second = p1X;
    double x2second = p2X;
    double y1second = p1Y;
    double y2second = p2Y;
    if (p0X >= p1X) {
      x1first = p1X;
      x2first = p0X;
      y1first = p1Y;
      y2first = p0Y;
    }
    if (p1X >= p2X) {
      x1second = p2X;
      x2second = p1X;
      y1second = p2Y;
      y2second = p1Y;
    }

    double repeatingXs1st = Math.abs(slope1st);
    double yPlus1st = 0;
    double repeatingXs2nd = Math.abs(slope2nd);
    double yPlus2nd = 0;

    Change change = new Change("QUAD Bezier Creation", inspiram.currentLayer);
    change.undoChange.addActionListener(change.createChangeUndoListener(inspiram));
    System.out.println("SLOPE: " + slope1st);
    for (double dub = .01; dub < 1.0; dub += .001) {

      // P's//
      double x1st = (x1first + ((x2first - x1first) * dub)); // X coordinate for 1st line
      double x2nd = (x1second + ((x2second - x1second) * dub)); // X coordinate for 2nd line
      double y1st =
          (slope1st * (x1first + ((x2first - x1first) * dub))
              + yIntercept1st); // Y coordinate for 1st line
      double y2nd =
          (slope2nd * (x1second + ((x2second - x1second) * dub))
              + yIntercept2nd); // Y coordinate for 2nd line.
      // End of P's//

      // Q's//
      double yDifferenceQ = y2nd - y1st;
      double xDifferenceQ = x2nd - x1st;
      double slopeQ = (((yDifferenceQ) / (xDifferenceQ)));
      double yInterceptQ = findYIntercept(x2nd, y2nd, slopeQ);
      double x1Q = x1st;
      double x2Q = x2nd;
      double y1Q = y1st;
      double y2Q = y2nd;
      if (x1st >= x2nd) {
        x1Q = x2nd;
        x2Q = x1st;
        y1Q = y2nd;
        y2Q = y1st;
      }
      double repeatingXsQ = Math.abs(slopeQ);
      double yPlusQ = 0;

      double xQ = (x1Q + ((x2Q - x1Q) * dub)); // X coordinate for q line
      double yQ = (slopeQ * (x1Q + ((x2Q - x1Q) * dub)) + yInterceptQ); // Y coordinate for q line
      // End of Q's//

      pixelIndexQ = (int) yQ * width * nbands + (int) xQ * nbands;

      PixelHistory pixelHistory = new PixelHistory((int) xQ, (int) yQ);
      if (!change.getAllPixelHistory().contains(pixelHistory.x)
          && !change.getAllPixelHistory().contains(pixelHistory.y)) {
        pixelHistory.setPrevR(pixels[(pixelIndexQ - 0) + (0)]);
        pixelHistory.setPrevG(pixels[(pixelIndexQ - 0) + (1)]);
        pixelHistory.setPrevB(pixels[(pixelIndexQ - 0) + (2)]);
        pixels[(pixelIndexQ - 0) + (0)] = 255;
        pixels[(pixelIndexQ - 0) + (1)] = 255;
        pixels[(pixelIndexQ - 0) + (2)] = 255;
        pixelHistory.setNewR(255);
        pixelHistory.setNewG(255);
        pixelHistory.setNewB(255);
        if (!change.getAllPixelHistory().contains(pixelHistory.x)
            && !change.getAllPixelHistory().contains(pixelHistory.y)) {
          change.getAllPixelHistory().add(pixelHistory);
        }
      }
    }
    inspiram.inspiramHistory.addChange(change);
    writableRaster.setPixels(0, 0, width, height, pixels);
    TiledImage ti = new TiledImage(inspiram.layers[inspiram.currentLayer].getLayerImage(), 1, 1);
    ti.setData(writableRaster);
    return ti;
  }
  public PlanarImage PostProcessEmage(PlanarImage img) {
    if (maskImgFName != null) {
      int width = img.getWidth();
      int height = img.getHeight();

      // Get the number of bands on the image.
      SampleModel sm = img.getSampleModel();
      int nbands = sm.getNumBands();

      // We assume that we can get the pixels values in a integer array.
      double[] pixel = new double[nbands];

      // Get an iterator for the image.
      RandomIter iterator = RandomIterFactory.create(img, null);
      WritableRaster rasterImage =
          RasterFactory.createBandedRaster(
              DataBuffer.TYPE_BYTE, width, height, nbands, new Point(0, 0));

      double[] pixelNeighb = new double[nbands];
      double[] pixelblack = new double[nbands];
      for (int i = 0; i < nbands; i++) {
        pixelNeighb[i] = 0;
        pixelblack[i] = 0;
      }

      PlanarImage mask = JAI.create("FileLoad", maskImgFName);
      RandomIter iteratorMask = RandomIterFactory.create(mask, null);
      double[] pixelMask = new double[mask.getSampleModel().getNumBands()];

      for (int i = 0; i < width; i++) {
        for (int j = 0; j < height; j++) {
          iteratorMask.getPixel(i, j, pixelMask);
          if (!isBlack(pixelMask)) {
            iterator.getPixel(i, j, pixel);
            if (isWhite(pixel)) {;
            } else {
              rasterImage.setPixel(i, j, pixel);
            }
          } else {
            rasterImage.setPixel(i, j, pixelblack);
          }
        }
      }
      SampleModel sModel2 =
          RasterFactory.createBandedSampleModel(DataBuffer.TYPE_BYTE, width, height, nbands);

      // Try to create a compatible ColorModel - if the number of bands is
      // larger than 4, it will be null.
      ColorModel cModel2 = PlanarImage.createColorModel(sModel2);

      // Create a TiledImage using the sample and color models.
      TiledImage processedImage = new TiledImage(0, 0, width, height, 0, 0, sModel2, cModel2);

      // Set the data of the tiled image to be the raster.
      processedImage.setData(rasterImage);

      // Save the image to a file.
      try {
        ImageIO.write(processedImage, "jpg", new File("proc_" + theme + ".jpg"));
      } catch (IOException e) {
        log.error(e.getMessage());
      }

      // Save the image on a file.
      return processedImage;
    } else {
      // Save the image to a file.
      try {
        ImageIO.write(img, "jpg", new File("NOTproc_" + theme + ".jpg"));
      } catch (IOException e) {
        log.error(e.getMessage());
      }
      return img;
    }
  }
  public PlanarImage createRectifiedImage(PlanarImage Image) {
    int nRows = params.getNumOfRows();
    int nCols = params.getNumOfColumns();
    Point rectifiedPoint;

    // Get the image dimensions of the unrectified image
    int width = Image.getWidth();
    int height = Image.getHeight();
    log.info(nRows + ", " + nCols + "\t" + width + ", " + height);
    // Get an iterator for the image.
    RandomIter iterator = RandomIterFactory.create(Image, null);

    // Get the number of bands on the image.
    SampleModel smO = Image.getSampleModel();
    int nbandsO = smO.getNumBands();

    // We assume that we can get the pixels values in a integer array.
    double[] pixelO = new double[nbandsO];

    // Get an iterator for the image.
    WritableRaster rasterPollenO =
        RasterFactory.createBandedRaster(
            DataBuffer.TYPE_BYTE, nCols, nRows, nbandsO, new Point(0, 0));

    for (int i = 0; i < nCols; i++) {
      for (int j = 0; j < nRows; j++) {
        rectifiedPoint =
            this.getMatchingCoord(
                new Point(i + 1, j + 1)); // coz java array start at 0 matlab its 1.
        if (rectifiedPoint.x >= 1
            && rectifiedPoint.x < width
            && rectifiedPoint.y >= 1
            && rectifiedPoint.y < height) {
          iterator.getPixel(rectifiedPoint.x - 1, rectifiedPoint.y - 1, pixelO);
          rasterPollenO.setPixel(i, j, pixelO);
          // log.info("setpixel: " + i + ", " + j  + ", value " + pixelO[0] + ", " + pixelO[1] + ",
          // " + pixelO[2] + ", " + pixelO[3]);
        } else {

        }
      }
    }

    SampleModel sModel2 =
        RasterFactory.createBandedSampleModel(DataBuffer.TYPE_BYTE, nCols, nRows, nbandsO);

    // Try to create a compatible ColorModel - if the number of bands is
    // larger than 4, it will be null.
    ColorModel cModel2 = PlanarImage.createColorModel(sModel2);

    // Create a TiledImage using the sample and color models.
    TiledImage rectPollenImage = new TiledImage(0, 0, nCols, nRows, 0, 0, sModel2, cModel2);

    // log.info(rasterPollenO.getMinX() + ", " + rasterPollenO.getMinY() );
    // Set the data of the tiled image to be the raster.
    rectPollenImage.setData(rasterPollenO);

    // Save the image to a file.
    try {
      ImageIO.write(rectPollenImage, "jpg", new File("rect" + theme + ".jpg"));
    } catch (IOException e) {
      log.error(e.getMessage());
    }
    return rectPollenImage;
  }