--- old/src/java.desktop/share/classes/java/awt/image/RescaleOp.java 2017-05-16 14:31:55.489327136 -0700 +++ new/src/java.desktop/share/classes/java/awt/image/RescaleOp.java 2017-05-16 14:31:55.337327136 -0700 @@ -27,6 +27,7 @@ import java.awt.color.ColorSpace; import java.awt.geom.Rectangle2D; +import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.geom.Point2D; import java.awt.RenderingHints; @@ -193,9 +194,10 @@ int nBands, int nElems) { - byte[][] lutData = new byte[scale.length][nElems]; + byte[][] lutData = new byte[nBands][nElems]; + int band; - for (int band=0; band numSrcColorComp && srcCM.hasAlpha()) { @@ -374,102 +413,40 @@ dstCM = dst.getColorModel(); if(srcCM.getColorSpace().getType() != - dstCM.getColorSpace().getType()) { + dstCM.getColorSpace().getType()) { needToConvert = true; dst = createCompatibleDestImage(src, null); } } - boolean scaleAlpha = true; - - // - // The number of sets of scaling constants may be one, - // in which case the same constants are applied to all color - // (but NOT alpha) components. Otherwise, the number of sets - // of scaling constants may equal the number of Source color - // components, in which case NO rescaling of the alpha component - // (if present) is performed. - // - if (numSrcColorComp == scaleConst || scaleConst == 1) { - scaleAlpha = false; - } - // // Try to use a native BI rescale operation first // if (ImagingLib.filter(this, src, dst) == null) { + if (src.getRaster().getNumBands() != + dst.getRaster().getNumBands()) { + needToDraw = true; + dst = createCompatibleDestImage(src, null); + } + // // Native BI rescale failed - convert to rasters // WritableRaster srcRaster = src.getRaster(); WritableRaster dstRaster = dst.getRaster(); - if (!scaleAlpha) { - if (srcCM.hasAlpha()) { - // Do not rescale Alpha component - int minx = srcRaster.getMinX(); - int miny = srcRaster.getMinY(); - int[] bands = new int[numSrcColorComp]; - for (int i=0; i < numSrcColorComp; i++) { - bands[i] = i; - } - srcRaster = - srcRaster.createWritableChild(minx, miny, - srcRaster.getWidth(), - srcRaster.getHeight(), - minx, miny, - bands); - } - if (dstCM.hasAlpha()) { - int minx = dstRaster.getMinX(); - int miny = dstRaster.getMinY(); - int[] bands = new int[numSrcColorComp]; - for (int i=0; i < numSrcColorComp; i++) { - bands[i] = i; - } - dstRaster = - dstRaster.createWritableChild(minx, miny, - dstRaster.getWidth(), - dstRaster.getHeight(), - minx, miny, - bands); - } - } - // // Call the raster filter method // - filterRasterImpl(srcRaster, dstRaster, scaleConst); - - // - // here copy the unscaled src alpha to destination alpha channel - // - if (!scaleAlpha) { - Raster srcAlphaRaster = null; - WritableRaster dstAlphaRaster = null; - - if (srcCM.hasAlpha()) { - srcAlphaRaster = src.getAlphaRaster(); - } - if (dstCM.hasAlpha()) { - dstAlphaRaster = dst.getAlphaRaster(); - if (srcAlphaRaster != null) { - dstAlphaRaster.setRect(srcAlphaRaster); - } else { - int alpha = 0xff << 24; - for (int cy=0; cy < dst.getHeight(); cy++) { - for (int cx=0; cx < dst.getWidth(); cx++) { - int color = dst.getRGB(cx, cy); - - dst.setRGB(cx, cy, color | alpha); - } - } - } - } - } + filterRasterImpl(srcRaster, dstRaster, scaleConst, false); } + if (needToDraw) { + Graphics2D g = origDst.createGraphics(); + g.drawImage(dst, 0, 0, width, height, null); + g.dispose(); + } if (needToConvert) { // ColorModels are not the same ColorConvertOp ccop = new ColorConvertOp(hints); @@ -497,10 +474,11 @@ * stated in the class comments. */ public final WritableRaster filter (Raster src, WritableRaster dst) { - return filterRasterImpl(src, dst, length); + return filterRasterImpl(src, dst, length, true); } - private WritableRaster filterRasterImpl(Raster src, WritableRaster dst, int scaleConst) { + private WritableRaster filterRasterImpl(Raster src, WritableRaster dst, + int scaleConst, boolean sCheck) { int numBands = src.getNumBands(); int width = src.getWidth(); int height = src.getHeight(); @@ -527,7 +505,7 @@ // Make sure that the arrays match // Make sure that the low/high/constant arrays match - if (scaleConst != 1 && scaleConst != src.getNumBands()) { + if (sCheck && scaleConst != 1 && scaleConst != src.getNumBands()) { throw new IllegalArgumentException("Number of scaling constants "+ "does not equal the number of"+ " of bands in the src raster"); @@ -598,8 +576,13 @@ srcPix = src.getPixel(sX, sY, srcPix); tidx = 0; for (int z=0; z 0; + ImageRescaleOpTest test = new ImageRescaleOpTest(); + test.startTest(); + } + + String getFileName(int s, int d) { + return textFor(s)+"_to_"+textFor(d)+".png"; + } + + String getMsgText(int s, int d) { + return textFor(s)+"->"+textFor(d)+": "; + } + + String textFor(int t) { + switch (t) { + case TYPE_INT_ARGB : return "ARGB"; + case TYPE_INT_RGB : return "RGB"; + case TYPE_4BYTE_ABGR : return "4BYTEABGR"; + case TYPE_3BYTE_BGR : return "3BYTEBGR"; + case TYPE_USHORT_555_RGB : return "USHORT_555_RGB"; + case TYPE_USHORT_565_RGB : return "USHORT_565_RGB"; + case TYPE_USHORT_GRAY : return "USHORT_GRAY"; + default : return "OTHER"; + } + } + + private void startTest() throws Exception { + + int expect = 0xff7f7f7f; + runTest(TYPE_INT_RGB, TYPE_INT_RGB, expect); + runTest(TYPE_INT_ARGB, TYPE_INT_ARGB, expect); + runTest(TYPE_INT_ARGB, TYPE_INT_RGB, expect); + runTest(TYPE_INT_RGB, TYPE_INT_ARGB, expect); + + runTest(TYPE_3BYTE_BGR, TYPE_3BYTE_BGR, expect); + runTest(TYPE_3BYTE_BGR, TYPE_4BYTE_ABGR, expect); + runTest(TYPE_4BYTE_ABGR, TYPE_3BYTE_BGR, expect); + runTest(TYPE_4BYTE_ABGR, TYPE_4BYTE_ABGR, expect); + + /* Slightly different values here due to limited precision */ + runTest(TYPE_USHORT_555_RGB, TYPE_USHORT_555_RGB, 0xff7b7b7b); + runTest(TYPE_USHORT_565_RGB, TYPE_USHORT_565_RGB, 0xff7b7d7b); + + /* 565->555 and 555->565 results are wrong as the slow code + * path used is not accounting for the difference in the range. + */ + //runTest(TYPE_USHORT_555_RGB, TYPE_USHORT_565_RGB, expect); + //runTest(TYPE_USHORT_565_RGB, TYPE_USHORT_555_RGB, expect); + + runTest(TYPE_USHORT_GRAY, TYPE_USHORT_GRAY, 0xffbcbcbc); + + } + + private void check(BufferedImage bi, int expect, String msg) { + int argb = bi.getRGB(w-1, h-1); + System.out.println(msg + Integer.toHexString(argb)); + if (argb != expect) { + throw new RuntimeException(msg + + " expected " + Integer.toHexString(expect) + + " but got " + Integer.toHexString(argb)); + } + } + + private void runTest(int sType, int dType, int expect) { + + BufferedImage src = new BufferedImage(w, h, sType); + BufferedImage dst = new BufferedImage(w, h, dType); + String msg = getMsgText(sType, dType); + + Graphics2D g2d = src.createGraphics(); + g2d.setColor(Color.WHITE); + g2d.fillRect(0, 0, w, h); + RescaleOp res = new RescaleOp(scaleFactor, offset, null); + res.filter(src, dst); + if (saveImage) { + try { + String fname = getFileName(sType, dType); + ImageIO.write(dst, "png", new File(fname)); + } catch (IOException e) { + } + } + check(dst, expect, msg); + } +}