changeset 48964:f611f49a46c9

8194489: Incorrect size computation at BandedSampleModel.createDataBuffer() Reviewed-by: bpb, jdv Contributed-by: prahalad.kumar.narayanan@oracle.com
author pnarayanan
date Tue, 16 Jan 2018 10:49:49 +0530
parents 2ea3667af41d
children 6cfee3ad7a76
files src/java.desktop/share/classes/java/awt/image/BandedSampleModel.java test/jdk/java/awt/image/BandedSampleModel/BandedSampleModelSizeTest.java
diffstat 2 files changed, 166 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.desktop/share/classes/java/awt/image/BandedSampleModel.java	Wed Jan 10 12:45:14 2018 +0530
+++ b/src/java.desktop/share/classes/java/awt/image/BandedSampleModel.java	Tue Jan 16 10:49:49 2018 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -185,7 +185,33 @@
     public DataBuffer createDataBuffer() {
         DataBuffer dataBuffer = null;
 
+        // The minimum size required to store samples of one band
         int size = scanlineStride * height;
+
+        if (numBanks == 1) {
+            /*
+             * The sample model contains a single bank of data buffer. Hence
+             * we need to compute the size required to store samples of all
+             * bands including the respective offsets.
+             */
+            int sizePerBand = size;
+            size += bandOffsets[0];
+            for (int index = 1; index < bandOffsets.length; index++) {
+                size += (bandOffsets[index] - size) + sizePerBand;
+            }
+        } else {
+            /*
+             * The sample model contains multiple banks of data buffer where
+             * each bank would correspond to a particular band. Hence we need
+             * to compute only the additional space required for band offsets.
+             */
+            int maxBandOffset = bandOffsets[0];
+            for (int index = 1; index < bandOffsets.length; index++) {
+                maxBandOffset = Math.max(maxBandOffset, bandOffsets[index]);
+            }
+            size += maxBandOffset;
+        }
+
         switch (dataType) {
         case DataBuffer.TYPE_BYTE:
             dataBuffer = new DataBufferByte(size, numBanks);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/image/BandedSampleModel/BandedSampleModelSizeTest.java	Tue Jan 16 10:49:49 2018 +0530
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8194489
+ * @summary The test checks whether BandedSampleModel computes appropriate
+ *          size for allocating memory in DataBuffer.
+ * @run main BandedSampleModelSizeTest
+ */
+import java.awt.image.BandedSampleModel;
+import java.awt.image.DataBuffer;
+import java.util.Arrays;
+
+public class BandedSampleModelSizeTest {
+    // Constants
+    private static final int TEST_NUM_BANDS = 3;
+    private static final int TEST_SRC_IMG_DIM = 10;
+
+    // Required sample models
+    private static BandedSampleModel singleBankModel = null;
+    private static BandedSampleModel multiBankModel = null;
+
+    private static void initTest() {
+        int[] bandOffsets = new int[TEST_NUM_BANDS];
+        int[] bankIndices = new int[TEST_NUM_BANDS];
+
+        /*
+         * Create a BandedSampleModel to store samples of all bands in one
+         * bank of DataBuffer.
+         */
+        bandOffsets[0] = 0;
+        bandOffsets[1] = 120;
+        bandOffsets[2] = 240;
+        bankIndices[0] = 0;
+        bankIndices[1] = 0;
+        bankIndices[2] = 0;
+
+        singleBankModel = new BandedSampleModel(DataBuffer.TYPE_BYTE,
+                TEST_SRC_IMG_DIM, TEST_SRC_IMG_DIM, TEST_SRC_IMG_DIM,
+                bankIndices, bandOffsets);
+
+        /*
+         * Create a BandedSampleModel to store samples of all bands in
+         * different banks of DataBuffer.
+         */
+        bandOffsets[0] = 0;
+        bandOffsets[1] = 20;
+        bandOffsets[2] = 40;
+        bankIndices[0] = 0;
+        bankIndices[1] = 1;
+        bankIndices[2] = 2;
+
+        multiBankModel = new BandedSampleModel(DataBuffer.TYPE_BYTE,
+                TEST_SRC_IMG_DIM, TEST_SRC_IMG_DIM, TEST_SRC_IMG_DIM,
+                bankIndices, bandOffsets);
+    }
+
+    private static void testSingleBankModel() {
+        int[] srcSamples = new int[TEST_NUM_BANDS];
+        int[] resSamples = new int[TEST_NUM_BANDS];
+
+        // Create image buffer for the requried sample model
+        DataBuffer imgBuffer = singleBankModel.createDataBuffer();
+
+        // Test the sample model by setting a pixel value & inspecting the same.
+        Arrays.fill(srcSamples, 125);
+        singleBankModel.setPixel(0, 0, srcSamples, imgBuffer);
+        singleBankModel.getPixel(0, 0, resSamples, imgBuffer);
+        if (!Arrays.equals(srcSamples, resSamples)) {
+            throw new RuntimeException("Test Failed. Incorrect samples found"
+                    + " in the image");
+        }
+
+        Arrays.fill(srcSamples, 250);
+        singleBankModel.setPixel(9, 9, srcSamples, imgBuffer);
+        singleBankModel.getPixel(9, 9, resSamples, imgBuffer);
+        if (!Arrays.equals(srcSamples, resSamples)) {
+            throw new RuntimeException("Test Failed. Incorrect samples found"
+                    + " in the image");
+        }
+    }
+
+    private static void testMultiBankModel() {
+        int[] srcSamples = new int[TEST_NUM_BANDS];
+        int[] resSamples = new int[TEST_NUM_BANDS];
+
+        // Create image buffer for the required sample model
+        DataBuffer imgBuffer = multiBankModel.createDataBuffer();
+
+        // Test the sample model by setting a pixel value & inspecting the same.
+        Arrays.fill(srcSamples, 125);
+        multiBankModel.setPixel(0, 0, srcSamples, imgBuffer);
+        multiBankModel.getPixel(0, 0, resSamples, imgBuffer);
+        if (!Arrays.equals(srcSamples, resSamples)) {
+            throw new RuntimeException("Test Failed. Incorrect samples found"
+                    + " in the image");
+        }
+
+        Arrays.fill(srcSamples, 250);
+        multiBankModel.setPixel(9, 9, srcSamples, imgBuffer);
+        multiBankModel.getPixel(9, 9, resSamples, imgBuffer);
+        if (!Arrays.equals(srcSamples, resSamples)) {
+            throw new RuntimeException("Test Failed. Incorrect samples found"
+                    + " in the image");
+        }
+    }
+
+    public static void main(String args[]) {
+        // Initialize the test
+        initTest();
+
+        // Test banded sample model with single bank of data buffer
+        testSingleBankModel();
+
+        // Test banded sample model with multiple banks of data buffer
+        testMultiBankModel();
+    }
+}