public PImage getImpl(int x, int y, int w, int h) {
    PImage output = new PImage(w, h);
    output.parent = parent;

    // oops, the last parameter is the scan size of the *target* buffer
    // ((BufferedImage) image).getRGB(x, y, w, h, output.pixels, 0, w);
    WritableRaster raster = ((BufferedImage) (primarySurface ? offscreen : image)).getRaster();
    raster.getDataElements(x, y, w, h, output.pixels);

    return output;
  }
 protected void setImpl(int dx, int dy, int sx, int sy, int sw, int sh, PImage src) {
   WritableRaster raster = ((BufferedImage) (primarySurface ? offscreen : image)).getRaster();
   if ((sx == 0) && (sy == 0) && (sw == src.width) && (sh == src.height)) {
     raster.setDataElements(dx, dy, src.width, src.height, src.pixels);
   } else {
     // TODO Optimize, incredibly inefficient to reallocate this much memory
     PImage temp = src.get(sx, sy, sw, sh);
     raster.setDataElements(dx, dy, temp.width, temp.height, temp.pixels);
   }
 }
  /** Handle renderer-specific image drawing. */
  protected void imageImpl(
      PImage who, float x1, float y1, float x2, float y2, int u1, int v1, int u2, int v2) {
    // Image not ready yet, or an error
    if (who.width <= 0 || who.height <= 0) return;

    if (who.getCache(this) == null) {
      // System.out.println("making new image cache");
      who.setCache(this, new ImageCache(who));
      who.updatePixels(); // mark the whole thing for update
      who.modified = true;
    }

    ImageCache cash = (ImageCache) who.getCache(this);
    // if image previously was tinted, or the color changed
    // or the image was tinted, and tint is now disabled
    if ((tint && !cash.tinted)
        || (tint && (cash.tintedColor != tintColor))
        || (!tint && cash.tinted)) {
      // for tint change, mark all pixels as needing update
      who.updatePixels();
    }

    if (who.modified) {
      cash.update(tint, tintColor);
      who.modified = false;
    }

    g2.drawImage(
        ((ImageCache) who.getCache(this)).image,
        (int) x1,
        (int) y1,
        (int) x2,
        (int) y2,
        u1,
        v1,
        u2,
        v2,
        null);
  }