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 }