< prev index next >

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

Print this page


   1 /*
   2  * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 127      * @param hints the specified {@code RenderingHints}, or
 128      *        {@code null}
 129      */
 130     public RescaleOp (float scaleFactor, float offset, RenderingHints hints) {
 131         length = 1;
 132         this.scaleFactors = new float[1];
 133         this.offsets      = new float[1];
 134         this.scaleFactors[0] = scaleFactor;
 135         this.offsets[0]       = offset;
 136         this.hints = hints;
 137     }
 138 
 139     /**
 140      * Returns the scale factors in the given array. The array is also
 141      * returned for convenience.  If scaleFactors is null, a new array
 142      * will be allocated.
 143      * @param scaleFactors the array to contain the scale factors of
 144      *        this {@code RescaleOp}
 145      * @return the scale factors of this {@code RescaleOp}.
 146      */
 147     public final float[] getScaleFactors (float scaleFactors[]) {
 148         if (scaleFactors == null) {
 149             return this.scaleFactors.clone();
 150         }
 151         System.arraycopy (this.scaleFactors, 0, scaleFactors, 0,
 152                           Math.min(this.scaleFactors.length,
 153                                    scaleFactors.length));
 154         return scaleFactors;
 155     }
 156 
 157     /**
 158      * Returns the offsets in the given array. The array is also returned
 159      * for convenience.  If offsets is null, a new array
 160      * will be allocated.
 161      * @param offsets the array to contain the offsets of
 162      *        this {@code RescaleOp}
 163      * @return the offsets of this {@code RescaleOp}.
 164      */
 165     public final float[] getOffsets(float offsets[]) {
 166         if (offsets == null) {
 167             return this.offsets.clone();
 168         }
 169 
 170         System.arraycopy (this.offsets, 0, offsets, 0,
 171                           Math.min(this.offsets.length, offsets.length));
 172         return offsets;
 173     }
 174 
 175     /**
 176      * Returns the number of scaling factors and offsets used in this
 177      * RescaleOp.
 178      * @return the number of scaling factors and offsets of this
 179      *         {@code RescaleOp}.
 180      */
 181     public final int getNumFactors() {
 182         return length;
 183     }
 184 
 185 
 186     /**
 187      * Creates a ByteLookupTable to implement the rescale.
 188      * The table may have either a SHORT or BYTE input.
 189      * @param nElems    Number of elements the table is to have.
 190      *                  This will generally be 256 for byte and
 191      *                  65536 for short.
 192      */
 193     private ByteLookupTable createByteLut(float scale[],
 194                                           float off[],
 195                                           int   nBands,
 196                                           int   nElems) {
 197 
 198         byte[][]        lutData = new byte[nBands][nElems];
 199         int band;
 200 
 201         for (band=0; band<scale.length; band++) {
 202             float  bandScale   = scale[band];
 203             float  bandOff     = off[band];
 204             byte[] bandLutData = lutData[band];
 205             for (int i=0; i<nElems; i++) {
 206                 int val = (int)(i*bandScale + bandOff);
 207                 if ((val & 0xffffff00) != 0) {
 208                     if (val < 0) {
 209                         val = 0;
 210                     } else {
 211                         val = 255;
 212                     }
 213                 }
 214                 bandLutData[i] = (byte)val;


 220            System.arraycopy(lutData[band-1], 0, lutData[band], 0, nElems);
 221            band++;
 222         }
 223         if (nBands == 4 && band < nBands) {
 224            byte[] bandLutData = lutData[band];
 225            for (int i=0; i<nElems; i++) {
 226               bandLutData[i] = (byte)i;
 227            }
 228         }
 229 
 230         return new ByteLookupTable(0, lutData);
 231     }
 232 
 233     /**
 234      * Creates a ShortLookupTable to implement the rescale.
 235      * The table may have either a SHORT or BYTE input.
 236      * @param nElems    Number of elements the table is to have.
 237      *                  This will generally be 256 for byte and
 238      *                  65536 for short.
 239      */
 240     private ShortLookupTable createShortLut(float scale[],
 241                                             float off[],
 242                                             int   nBands,
 243                                             int   nElems) {
 244 
 245         short[][]        lutData = new short[nBands][nElems];
 246         int band = 0;
 247 
 248         for (band=0; band<scale.length; band++) {
 249             float   bandScale   = scale[band];
 250             float   bandOff     = off[band];
 251             short[] bandLutData = lutData[band];
 252             for (int i=0; i<nElems; i++) {
 253                 int val = (int)(i*bandScale + bandOff);
 254                 if ((val & 0xffff0000) != 0) {
 255                     if (val < 0) {
 256                         val = 0;
 257                     } else {
 258                         val = 65535;
 259                     }
 260                 }
 261                 bandLutData[i] = (short)val;


 545             //
 546             // Fall back to the slow code
 547             //
 548             if (scaleConst > 1) {
 549                 step = 1;
 550             }
 551 
 552             int sminX = src.getMinX();
 553             int sY = src.getMinY();
 554             int dminX = dst.getMinX();
 555             int dY = dst.getMinY();
 556             int sX;
 557             int dX;
 558 
 559             //
 560             //  Determine bits per band to determine maxval for clamps.
 561             //  The min is assumed to be zero.
 562             //  REMIND: This must change if we ever support signed data types.
 563             //
 564             int nbits;
 565             int dstMax[] = new int[numBands];
 566             int dstMask[] = new int[numBands];
 567             SampleModel dstSM = dst.getSampleModel();
 568             for (int z=0; z<numBands; z++) {
 569                 nbits = dstSM.getSampleSize(z);
 570                 dstMax[z] = (1 << nbits) - 1;
 571                 dstMask[z] = ~(dstMax[z]);
 572             }
 573 
 574             int val;
 575             for (int y=0; y < height; y++, sY++, dY++) {
 576                 dX = dminX;
 577                 sX = sminX;
 578                 for (int x = 0; x < width; x++, sX++, dX++) {
 579                     // Get data for all bands at this x,y position
 580                     srcPix = src.getPixel(sX, sY, srcPix);
 581                     tidx = 0;
 582                     for (int z=0; z<numBands; z++, tidx += step) {
 583                         if ((scaleConst == 1 || scaleConst == 3) &&
 584                             (z == 3) && (numBands == 4)) {
 585                            val = srcPix[z];
 586                         } else {


   1 /*
   2  * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 127      * @param hints the specified {@code RenderingHints}, or
 128      *        {@code null}
 129      */
 130     public RescaleOp (float scaleFactor, float offset, RenderingHints hints) {
 131         length = 1;
 132         this.scaleFactors = new float[1];
 133         this.offsets      = new float[1];
 134         this.scaleFactors[0] = scaleFactor;
 135         this.offsets[0]       = offset;
 136         this.hints = hints;
 137     }
 138 
 139     /**
 140      * Returns the scale factors in the given array. The array is also
 141      * returned for convenience.  If scaleFactors is null, a new array
 142      * will be allocated.
 143      * @param scaleFactors the array to contain the scale factors of
 144      *        this {@code RescaleOp}
 145      * @return the scale factors of this {@code RescaleOp}.
 146      */
 147     public final float[] getScaleFactors (float[] scaleFactors) {
 148         if (scaleFactors == null) {
 149             return this.scaleFactors.clone();
 150         }
 151         System.arraycopy (this.scaleFactors, 0, scaleFactors, 0,
 152                           Math.min(this.scaleFactors.length,
 153                                    scaleFactors.length));
 154         return scaleFactors;
 155     }
 156 
 157     /**
 158      * Returns the offsets in the given array. The array is also returned
 159      * for convenience.  If offsets is null, a new array
 160      * will be allocated.
 161      * @param offsets the array to contain the offsets of
 162      *        this {@code RescaleOp}
 163      * @return the offsets of this {@code RescaleOp}.
 164      */
 165     public final float[] getOffsets(float[] offsets) {
 166         if (offsets == null) {
 167             return this.offsets.clone();
 168         }
 169 
 170         System.arraycopy (this.offsets, 0, offsets, 0,
 171                           Math.min(this.offsets.length, offsets.length));
 172         return offsets;
 173     }
 174 
 175     /**
 176      * Returns the number of scaling factors and offsets used in this
 177      * RescaleOp.
 178      * @return the number of scaling factors and offsets of this
 179      *         {@code RescaleOp}.
 180      */
 181     public final int getNumFactors() {
 182         return length;
 183     }
 184 
 185 
 186     /**
 187      * Creates a ByteLookupTable to implement the rescale.
 188      * The table may have either a SHORT or BYTE input.
 189      * @param nElems    Number of elements the table is to have.
 190      *                  This will generally be 256 for byte and
 191      *                  65536 for short.
 192      */
 193     private ByteLookupTable createByteLut(float[] scale,
 194                                           float[] off,
 195                                           int   nBands,
 196                                           int   nElems) {
 197 
 198         byte[][]        lutData = new byte[nBands][nElems];
 199         int band;
 200 
 201         for (band=0; band<scale.length; band++) {
 202             float  bandScale   = scale[band];
 203             float  bandOff     = off[band];
 204             byte[] bandLutData = lutData[band];
 205             for (int i=0; i<nElems; i++) {
 206                 int val = (int)(i*bandScale + bandOff);
 207                 if ((val & 0xffffff00) != 0) {
 208                     if (val < 0) {
 209                         val = 0;
 210                     } else {
 211                         val = 255;
 212                     }
 213                 }
 214                 bandLutData[i] = (byte)val;


 220            System.arraycopy(lutData[band-1], 0, lutData[band], 0, nElems);
 221            band++;
 222         }
 223         if (nBands == 4 && band < nBands) {
 224            byte[] bandLutData = lutData[band];
 225            for (int i=0; i<nElems; i++) {
 226               bandLutData[i] = (byte)i;
 227            }
 228         }
 229 
 230         return new ByteLookupTable(0, lutData);
 231     }
 232 
 233     /**
 234      * Creates a ShortLookupTable to implement the rescale.
 235      * The table may have either a SHORT or BYTE input.
 236      * @param nElems    Number of elements the table is to have.
 237      *                  This will generally be 256 for byte and
 238      *                  65536 for short.
 239      */
 240     private ShortLookupTable createShortLut(float[] scale,
 241                                             float[] off,
 242                                             int   nBands,
 243                                             int   nElems) {
 244 
 245         short[][]        lutData = new short[nBands][nElems];
 246         int band = 0;
 247 
 248         for (band=0; band<scale.length; band++) {
 249             float   bandScale   = scale[band];
 250             float   bandOff     = off[band];
 251             short[] bandLutData = lutData[band];
 252             for (int i=0; i<nElems; i++) {
 253                 int val = (int)(i*bandScale + bandOff);
 254                 if ((val & 0xffff0000) != 0) {
 255                     if (val < 0) {
 256                         val = 0;
 257                     } else {
 258                         val = 65535;
 259                     }
 260                 }
 261                 bandLutData[i] = (short)val;


 545             //
 546             // Fall back to the slow code
 547             //
 548             if (scaleConst > 1) {
 549                 step = 1;
 550             }
 551 
 552             int sminX = src.getMinX();
 553             int sY = src.getMinY();
 554             int dminX = dst.getMinX();
 555             int dY = dst.getMinY();
 556             int sX;
 557             int dX;
 558 
 559             //
 560             //  Determine bits per band to determine maxval for clamps.
 561             //  The min is assumed to be zero.
 562             //  REMIND: This must change if we ever support signed data types.
 563             //
 564             int nbits;
 565             int[] dstMax = new int[numBands];
 566             int[] dstMask = new int[numBands];
 567             SampleModel dstSM = dst.getSampleModel();
 568             for (int z=0; z<numBands; z++) {
 569                 nbits = dstSM.getSampleSize(z);
 570                 dstMax[z] = (1 << nbits) - 1;
 571                 dstMask[z] = ~(dstMax[z]);
 572             }
 573 
 574             int val;
 575             for (int y=0; y < height; y++, sY++, dY++) {
 576                 dX = dminX;
 577                 sX = sminX;
 578                 for (int x = 0; x < width; x++, sX++, dX++) {
 579                     // Get data for all bands at this x,y position
 580                     srcPix = src.getPixel(sX, sY, srcPix);
 581                     tidx = 0;
 582                     for (int z=0; z<numBands; z++, tidx += step) {
 583                         if ((scaleConst == 1 || scaleConst == 3) &&
 584                             (z == 3) && (numBands == 4)) {
 585                            val = srcPix[z];
 586                         } else {


< prev index next >