< prev index next >

src/java.desktop/share/classes/java/awt/image/RescaleOp.java

Print this page

        

@@ -25,10 +25,11 @@
 
 package java.awt.image;
 
 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;
 import sun.awt.image.ImagingLib;
 

@@ -191,13 +192,14 @@
     private ByteLookupTable createByteLut(float scale[],
                                           float off[],
                                           int   nBands,
                                           int   nElems) {
 
-        byte[][]        lutData = new byte[scale.length][nElems];
+        byte[][]        lutData = new byte[nBands][nElems];
+        int band;
 
-        for (int band=0; band<scale.length; band++) {
+        for (band=0; band<scale.length; band++) {
             float  bandScale   = scale[band];
             float  bandOff     = off[band];
             byte[] bandLutData = lutData[band];
             for (int i=0; i<nElems; i++) {
                 int val = (int)(i*bandScale + bandOff);

@@ -210,10 +212,21 @@
                 }
                 bandLutData[i] = (byte)val;
             }
 
         }
+        int maxToCopy = (nBands == 4 && scale.length == 4) ? 4 : 3;
+        while (band < lutData.length && band < maxToCopy) {
+           System.arraycopy(lutData[band-1], 0, lutData[band], 0, nElems);
+           band++;
+        }
+        if (nBands == 4 && band < nBands) {
+           byte[] bandLutData = lutData[band];
+           for (int i=0; i<nElems; i++) {
+              bandLutData[i] = (byte)i;
+           }
+        }
 
         return new ByteLookupTable(0, lutData);
     }
 
     /**

@@ -226,13 +239,14 @@
     private ShortLookupTable createShortLut(float scale[],
                                             float off[],
                                             int   nBands,
                                             int   nElems) {
 
-        short[][]        lutData = new short[scale.length][nElems];
+        short[][]        lutData = new short[nBands][nElems];
+        int band = 0;
 
-        for (int band=0; band<scale.length; band++) {
+        for (band=0; band<scale.length; band++) {
             float   bandScale   = scale[band];
             float   bandOff     = off[band];
             short[] bandLutData = lutData[band];
             for (int i=0; i<nElems; i++) {
                 int val = (int)(i*bandScale + bandOff);

@@ -244,10 +258,21 @@
                     }
                 }
                 bandLutData[i] = (short)val;
             }
         }
+        int maxToCopy = (nBands == 4 && scale.length == 4) ? 4 : 3;
+        while (band < lutData.length && band < maxToCopy) {
+           System.arraycopy(lutData[band-1], 0, lutData[band], 0, nElems);
+           band++;
+        }
+        if (nBands == 4 && band < nBands) {
+           short[] bandLutData = lutData[band];
+           for (int i=0; i<nElems; i++) {
+              bandLutData[i] = (short)i;
+           }
+        }
 
         return new ShortLookupTable(0, lutData);
     }
 
 

@@ -298,10 +323,23 @@
             if (bandSize != srcNbits) {
                 return false;
             }
         }
 
+      if (dstSM instanceof ComponentSampleModel) {
+           ComponentSampleModel dsm = (ComponentSampleModel)dstSM;
+           if (dsm.getPixelStride() != dst.getNumBands()) {
+               return false;
+           }
+        }
+        if (srcSM instanceof ComponentSampleModel) {
+           ComponentSampleModel csm = (ComponentSampleModel)srcSM;
+           if (csm.getPixelStride() != src.getNumBands()) {
+               return false;
+           }
+        }
+
         return true;
     }
 
     /**
      * Rescales the source BufferedImage.

@@ -342,10 +380,11 @@
                                                " of color or color/alpha "+
                                                " components");
         }
 
         boolean needToConvert = false;
+        boolean needToDraw = false;
 
         // Include alpha
         if (scaleConst > numSrcColorComp && srcCM.hasAlpha()) {
             scaleConst = numSrcColorComp+1;
         }

@@ -379,99 +418,37 @@
                 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();
+            filterRasterImpl(srcRaster, dstRaster, scaleConst, false);
                 }
-                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);
-                            }
-                        }
-                    }
-                }
+        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);
             dst = ccop.filter(dst, origDst);
         }

@@ -495,14 +472,15 @@
      *         or if the number of scaling factors and offsets in this
      *         {@code RescaleOp} do not meet the requirements
      *         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();
         int[] srcPix = null;
         int step = 0;

@@ -525,11 +503,11 @@
                             + dst.getNumBands());
         }
 
         // 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");
         }
 

@@ -596,12 +574,17 @@
                 for (int x = 0; x < width; x++, sX++, dX++) {
                     // Get data for all bands at this x,y position
                     srcPix = src.getPixel(sX, sY, srcPix);
                     tidx = 0;
                     for (int z=0; z<numBands; z++, tidx += step) {
+                        if ((scaleConst == 1 || scaleConst == 3) && (z == 3)) {
+                           val = srcPix[z];
+                        } else {
                         val = (int)(srcPix[z]*scaleFactors[tidx]
                                           + offsets[tidx]);
+
+                        }
                         // Clamp
                         if ((val & dstMask[z]) != 0) {
                             if (val < 0) {
                                 val = 0;
                             } else {
< prev index next >