1 /*
  2  * Copyright (c) 2024, 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
 23  * questions.
 24  */
 25 package experiments;
 26 
 27 import javax.swing.JFrame;
 28 import java.awt.BorderLayout;
 29 import java.awt.Canvas;
 30 import java.awt.Graphics;
 31 import java.awt.Graphics2D;
 32 import java.awt.RenderingHints;
 33 import java.awt.Transparency;
 34 import java.awt.color.ColorSpace;
 35 import java.awt.event.WindowAdapter;
 36 import java.awt.event.WindowEvent;
 37 import java.awt.image.BufferedImage;
 38 import java.awt.image.ColorModel;
 39 import java.awt.image.ComponentColorModel;
 40 import java.awt.image.DataBuffer;
 41 import java.awt.image.DataBufferFloat;
 42 import java.awt.image.PixelInterleavedSampleModel;
 43 import java.awt.image.Raster;
 44 import java.awt.image.SampleModel;
 45 import java.awt.image.WritableRaster;
 46 import java.util.stream.IntStream;
 47 
 48 public class FloatFrame {
 49 
 50     public static BufferedImage createFloatImage(int width, int height) {
 51         // 1. Define the Color Space (sRGB is standard)
 52         ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
 53 
 54         // 2. Create the Color Model
 55         // We use 32 bits per component, no alpha, non-premultiplied
 56         ColorModel cm = new ComponentColorModel(cs, false, false,
 57                 Transparency.OPAQUE, DataBuffer.TYPE_FLOAT);
 58 
 59         // 3. Create the Sample Model (Pixel Interleaved)
 60         // 3 bands for RGB, scanline stride is width * 3
 61         SampleModel sm = new PixelInterleavedSampleModel(DataBuffer.TYPE_FLOAT,
 62                 width, height, 3, width * 3, new int[]{0, 1, 2});
 63 
 64         // 4. Create the DataBuffer (the actual float array)
 65         DataBufferFloat db = new DataBufferFloat(width * height * 3);
 66 
 67         // 5. Create the Raster and the BufferedImage
 68         WritableRaster raster = Raster.createWritableRaster(sm, db, null);
 69         return new BufferedImage(cm, raster, false, null);
 70     }
 71 
 72 
 73     public static long  fillWithData(BufferedImage img) {
 74         WritableRaster raster = img.getRaster();
 75         DataBufferFloat buffer = (DataBufferFloat) raster.getDataBuffer();
 76         float[] data = buffer.getData();
 77         int width = img.getWidth();
 78         int height = img.getHeight();
 79         long start = System.nanoTime();
 80         boolean useIntStream = false;
 81 
 82         if (useIntStream) {
 83             boolean useParallel = false;
 84             if (useParallel) {
 85                 IntStream.range(0, width * height).parallel().forEach(i -> {
 86                     //    var y = i / width;
 87                     var x = i % width;
 88                     int offset = i * 3;
 89                     // Example: Create a horizontal gradient
 90                     float intensity = (float) x / width;
 91                     data[offset] = intensity; // Red
 92                     data[offset + 1] = 0.5f;      // Green
 93                     data[offset + 2] = 1.0f;
 94                 });
 95             }else{
 96                 IntStream.range(0, width * height).forEach(i -> {
 97                     //    var y = i / width;
 98                     var x = i % width;
 99                     int offset = i * 3;
100                     // Example: Create a horizontal gradient
101                     float intensity = (float) x / width;
102                     data[offset] = intensity; // Red
103                     data[offset + 1] = 0.5f;      // Green
104                     data[offset + 2] = 1.0f;
105                 });
106             }
107         } else {
108             // Old school
109             for (int y = 0; y < height; y++) {
110                 for (int x = 0; x < width; x++) {
111                     // Calculate the array index for the current pixel
112                     int offset = (y * width + x) * 3;
113                     // Example: Create a horizontal gradient
114                     float intensity = (float) x / width;
115                     data[offset] = intensity; // Red
116                     data[offset + 1] = 0.5f;      // Green
117                     data[offset + 2] = 1.0f;      // Blue
118                 }
119             }
120         }
121 
122         long end = System.nanoTime();
123         return end-start;
124     }
125 
126     static class Frame extends JFrame{
127         final Canvas canvas;
128         Frame(String name, BufferedImage image){
129             super(name);
130             addWindowListener(new WindowAdapter() {
131                 public void windowClosing(WindowEvent we) {
132                     System.exit(0);
133                 }
134             });
135             setLayout(new BorderLayout());
136             canvas = new Canvas() {
137                 public void paint(Graphics g) {
138                     Graphics2D g2 = (Graphics2D)g;
139 
140                      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
141                     g2.drawImage(image, 0, 0, null);
142                    // System.out.print(".");
143                 }
144             };
145             canvas.setSize(image.getWidth(), image.getHeight());
146             add(canvas, BorderLayout.CENTER);
147             pack();
148             setVisible(true);
149         }
150     }
151 
152 
153     static void main(String[] args) {
154         final int width = 1024;
155         final int height = 1024;
156         var image = createFloatImage(width, height);
157         System.out.println(fillWithData(image)/ 1000000 + " ms");;
158         var frame = new Frame("FloatFrame",image);
159     }
160 }