From ae89182d88f4ef1e24b653fd783eeb526f44abd6 Mon Sep 17 00:00:00 2001 From: benfry Date: Sun, 25 Nov 2012 19:45:21 +0000 Subject: [PATCH] re-implement get/set handling (issue 925) --- core/src/processing/core/PGraphicsJava2D.java | 61 +++++++++++++------ core/src/processing/core/PImage.java | 52 +++++++++------- .../processing/opengl/PGraphicsOpenGL.java | 16 +++-- 3 files changed, 84 insertions(+), 45 deletions(-) diff --git a/core/src/processing/core/PGraphicsJava2D.java b/core/src/processing/core/PGraphicsJava2D.java index ac2f6116c..e6f790ee0 100644 --- a/core/src/processing/core/PGraphicsJava2D.java +++ b/core/src/processing/core/PGraphicsJava2D.java @@ -2145,17 +2145,32 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ { @Override - 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 +// public PImage getImpl(int x, int y, int w, int h) { + protected void getImpl(int sourceX, int sourceY, + int sourceWidth, int sourceHeight, + PImage target, int targetX, int targetY) { + // last parameter to getRGB() 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(); -// WritableRaster raster = image.getRaster(); - raster.getDataElements(x, y, w, h, output.pixels); + WritableRaster raster = + ((BufferedImage) (primarySurface ? offscreen : image)).getRaster(); - return output; + if (sourceWidth == target.width && sourceHeight == target.height) { + raster.getDataElements(sourceX, sourceY, sourceWidth, sourceHeight, target.pixels); + + } else { + // TODO optimize, incredibly inefficient to reallocate this much memory + int[] temp = new int[sourceWidth * sourceHeight]; + raster.getDataElements(sourceX, sourceY, sourceWidth, sourceHeight, temp); + + // Copy the temporary output pixels over to the outgoing image + int sourceOffset = 0; + int targetOffset = targetY*target.width + targetX; + for (int y = 0; y < sourceHeight; y++) { + System.arraycopy(temp, sourceOffset, target.pixels, targetOffset, sourceWidth); + sourceOffset += sourceWidth; + targetOffset += target.width; + } + } } @@ -2176,17 +2191,27 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ { } + +// protected void setImpl(int dx, int dy, int sx, int sy, int sw, int sh, +// PImage src) { @Override - protected void setImpl(int dx, int dy, int sx, int sy, int sw, int sh, - PImage src) { - WritableRaster raster = ((BufferedImage) (primarySurface ? offscreen : image)).getRaster(); -// WritableRaster raster = image.getRaster(); - if ((sx == 0) && (sy == 0) && (sw == src.width) && (sh == src.height)) { - raster.setDataElements(dx, dy, src.width, src.height, src.pixels); + protected void setImpl(PImage sourceImage, + int sourceX, int sourceY, + int sourceWidth, int sourceHeight, + int targetX, int targetY) { + WritableRaster raster = + ((BufferedImage) (primarySurface ? offscreen : image)).getRaster(); + + if ((sourceX == 0) && (sourceY == 0) && + (sourceWidth == sourceImage.width) && + (sourceHeight == sourceImage.height)) { + raster.setDataElements(targetX, targetY, + sourceImage.width, sourceImage.height, + sourceImage.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); + // TODO optimize, incredibly inefficient to reallocate this much memory + PImage temp = sourceImage.get(sourceX, sourceY, sourceWidth, sourceHeight); + raster.setDataElements(targetX, targetY, temp.width, temp.height, temp.pixels); } } diff --git a/core/src/processing/core/PImage.java b/core/src/processing/core/PImage.java index 160127199..d7307c36f 100644 --- a/core/src/processing/core/PImage.java +++ b/core/src/processing/core/PImage.java @@ -767,12 +767,17 @@ public class PImage implements PConstants, Cloneable { * @param h height of pixel rectangle to get */ public PImage get(int x, int y, int w, int h) { + int targetX = 0; + int targetY = 0; + if (x < 0) { w += x; // clip off the left edge + targetX = -x; x = 0; } if (y < 0) { h += y; // clip off some of the height + targetY = -y; y = 0; } @@ -786,7 +791,10 @@ public class PImage implements PConstants, Cloneable { h = 0; } - return getImpl(x, y, w, h); + PImage target = new PImage(w, h, format); + target.parent = parent; + getImpl(x, y, w, h, target, targetX, targetY); + return target; } @@ -796,18 +804,16 @@ public class PImage implements PConstants, Cloneable { * are guaranteed to be inside the image space, so the implementation can * use the fastest possible pixel copying method. */ - protected PImage getImpl(int x, int y, int w, int h) { - PImage newbie = new PImage(w, h, format); - newbie.parent = parent; - - int index = y*width + x; - int index2 = 0; - for (int row = y; row < y+h; row++) { - System.arraycopy(pixels, index, newbie.pixels, index2, w); - index += width; - index2 += w; + protected void getImpl(int sourceX, int sourceY, + int sourceWidth, int sourceHeight, + PImage target, int targetX, int targetY) { + int sourceIndex = sourceY*width + sourceX; + int targetIndex = targetY*target.width + targetX; + for (int row = sourceY; row < sourceY+sourceHeight; row++) { + System.arraycopy(pixels, sourceIndex, target.pixels, targetIndex, sourceWidth); + sourceIndex += width; + targetIndex += target.width; } - return newbie; } @@ -897,7 +903,7 @@ public class PImage implements PConstants, Cloneable { // this could be nonexistant if ((sw <= 0) || (sh <= 0)) return; - setImpl(x, y, sx, sy, sw, sh, img); + setImpl(img, sx, sy, sw, sh, x, y); } @@ -905,17 +911,19 @@ public class PImage implements PConstants, Cloneable { * Internal function to actually handle setting a block of pixels that * has already been properly cropped from the image to a valid region. */ - protected void setImpl(int dx, int dy, int sx, int sy, int sw, int sh, - PImage img) { - int srcOffset = sy * img.width + sx; - int dstOffset = dy * width + dx; + protected void setImpl(PImage sourceImage, + int sourceX, int sourceY, + int sourceWidth, int sourceHeight, + int targetX, int targetY) { + int sourceOffset = sourceY * sourceImage.width + sourceX; + int targetOffset = targetY * width + targetX; - for (int y = sy; y < sy + sh; y++) { - System.arraycopy(img.pixels, srcOffset, pixels, dstOffset, sw); - srcOffset += img.width; - dstOffset += width; + for (int y = sourceY; y < sourceY + sourceHeight; y++) { + System.arraycopy(sourceImage.pixels, sourceOffset, pixels, targetOffset, sourceWidth); + sourceOffset += sourceImage.width; + targetOffset += width; } - updatePixelsImpl(sx, sy, sw, sh); + updatePixelsImpl(sourceX, sourceY, sourceWidth, sourceHeight); } diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index 61a64286e..037b4dfdf 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -5239,10 +5239,13 @@ public class PGraphicsOpenGL extends PGraphics { @Override - protected PImage getImpl(int x, int y, int w, int h) { + protected void getImpl(int sourceX, int sourceY, + int sourceWidth, int sourceHeight, + PImage target, int targetX, int targetY) { loadPixels(); setgetPixels = true; - return super.getImpl(x, y, w, h); + super.getImpl(sourceX, sourceY, sourceWidth, sourceHeight, + target, targetX, targetY); } @@ -5255,11 +5258,14 @@ public class PGraphicsOpenGL extends PGraphics { @Override - protected void setImpl(int dx, int dy, int sx, int sy, int sw, int sh, - PImage src) { + protected void setImpl(PImage sourceImage, + int sourceX, int sourceY, + int sourceWidth, int sourceHeight, + int targetX, int targetY) { loadPixels(); setgetPixels = true; - super.setImpl(dx, dy, sx, sy, sw, sh, src); + super.setImpl(sourceImage, sourceX, sourceY, sourceWidth, sourceHeight, + targetX, targetY); }