History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/java2d/pipe/BufferedBufImgOps.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/java2d/pipe/BufferedBufImgOps.java+393−0
@@ -0,0 +1,393 @@
1+/*
2+ * Copyright (c) 2007, 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+
26+package sun.java2d.pipe;
27+
28+import java.awt.color.ColorSpace;
29+import java.awt.image.AffineTransformOp;
30+import java.awt.image.BufferedImage;
31+import java.awt.image.BufferedImageOp;
32+import java.awt.image.BufferedImageOp;
33+import java.awt.image.ByteLookupTable;
34+import java.awt.image.ColorModel;
35+import java.awt.image.ConvolveOp;
36+import java.awt.image.IndexColorModel;
37+import java.awt.image.Kernel;
38+import java.awt.image.LookupOp;
39+import java.awt.image.LookupTable;
40+import java.awt.image.RescaleOp;
41+import java.awt.image.ShortLookupTable;
42+import sun.java2d.SurfaceData;
43+import sun.java2d.loops.CompositeType;
44+import static sun.java2d.pipe.BufferedOpCodes.*;
45+
46+public class BufferedBufImgOps {
47+
48+ public static void enableBufImgOp(RenderQueue rq, SurfaceData srcData,
49+ BufferedImage srcImg,
50+ BufferedImageOp biop)
51+ {
52+ if (biop instanceof ConvolveOp) {
53+ enableConvolveOp(rq, srcData, (ConvolveOp)biop);
54+ } else if (biop instanceof RescaleOp) {
55+ enableRescaleOp(rq, srcData, srcImg, (RescaleOp)biop);
56+ } else if (biop instanceof LookupOp) {
57+ enableLookupOp(rq, srcData, srcImg, (LookupOp)biop);
58+ } else {
59+ throw new InternalError("Unknown BufferedImageOp");
60+ }
61+ }
62+
63+ public static void disableBufImgOp(RenderQueue rq, BufferedImageOp biop) {
64+ if (biop instanceof ConvolveOp) {
65+ disableConvolveOp(rq);
66+ } else if (biop instanceof RescaleOp) {
67+ disableRescaleOp(rq);
68+ } else if (biop instanceof LookupOp) {
69+ disableLookupOp(rq);
70+ } else {
71+ throw new InternalError("Unknown BufferedImageOp");
72+ }
73+ }
74+
75+/**************************** ConvolveOp support ****************************/
76+
77+ public static boolean isConvolveOpValid(ConvolveOp cop) {
78+ Kernel kernel = cop.getKernel();
79+ int kw = kernel.getWidth();
80+ int kh = kernel.getHeight();
81+ // REMIND: we currently can only handle 3x3 and 5x5 kernels,
82+ // but hopefully this is just a temporary restriction;
83+ // see native shader comments for more details
84+ if (!(kw == 3 && kh == 3) && !(kw == 5 && kh == 5)) {
85+ return false;
86+ }
87+ return true;
88+ }
89+
90+ private static void enableConvolveOp(RenderQueue rq,
91+ SurfaceData srcData,
92+ ConvolveOp cop)
93+ {
94+ // assert rq.lock.isHeldByCurrentThread();
95+ boolean edgeZero =
96+ cop.getEdgeCondition() == ConvolveOp.EDGE_ZERO_FILL;
97+ Kernel kernel = cop.getKernel();
98+ int kernelWidth = kernel.getWidth();
99+ int kernelHeight = kernel.getHeight();
100+ int kernelSize = kernelWidth * kernelHeight;
101+ int sizeofFloat = 4;
102+ int totalBytesRequired = 4 + 8 + 12 + (kernelSize * sizeofFloat);
103+
104+ RenderBuffer buf = rq.getBuffer();
105+ rq.ensureCapacityAndAlignment(totalBytesRequired, 4);
106+ buf.putInt(ENABLE_CONVOLVE_OP);
107+ buf.putLong(srcData.getNativeOps());
108+ buf.putInt(edgeZero ? 1 : 0);
109+ buf.putInt(kernelWidth);
110+ buf.putInt(kernelHeight);
111+ buf.put(kernel.getKernelData(null));
112+ }
113+
114+ private static void disableConvolveOp(RenderQueue rq) {
115+ // assert rq.lock.isHeldByCurrentThread();
116+ RenderBuffer buf = rq.getBuffer();
117+ rq.ensureCapacity(4);
118+ buf.putInt(DISABLE_CONVOLVE_OP);
119+ }
120+
121+/**************************** RescaleOp support *****************************/
122+
123+ public static boolean isRescaleOpValid(RescaleOp rop,
124+ BufferedImage srcImg)
125+ {
126+ int numFactors = rop.getNumFactors();
127+ ColorModel srcCM = srcImg.getColorModel();
128+
129+ if (srcCM instanceof IndexColorModel) {
130+ throw new
131+ IllegalArgumentException("Rescaling cannot be "+
132+ "performed on an indexed image");
133+ }
134+ if (numFactors != 1 &&
135+ numFactors != srcCM.getNumColorComponents() &&
136+ numFactors != srcCM.getNumComponents())
137+ {
138+ throw new IllegalArgumentException("Number of scaling constants "+
139+ "does not equal the number of"+
140+ " of color or color/alpha "+
141+ " components");
142+ }
143+
144+ int csType = srcCM.getColorSpace().getType();
145+ if (csType != ColorSpace.TYPE_RGB &&
146+ csType != ColorSpace.TYPE_GRAY)
147+ {
148+ // Not prepared to deal with other color spaces
149+ return false;
150+ }
151+
152+ if (numFactors == 2 || numFactors > 4) {
153+ // Not really prepared to handle this at the native level, so...
154+ return false;
155+ }
156+
157+ return true;
158+ }
159+
160+ private static void enableRescaleOp(RenderQueue rq,
161+ SurfaceData srcData,
162+ BufferedImage srcImg,
163+ RescaleOp rop)
164+ {
165+ // assert rq.lock.isHeldByCurrentThread();
166+ ColorModel srcCM = srcImg.getColorModel();
167+ boolean nonPremult =
168+ srcCM.hasAlpha() &&
169+ srcCM.isAlphaPremultiplied();
170+
171+ /*
172+ * Note: The user-provided scale factors and offsets are arranged
173+ * in R/G/B/A order, regardless of the raw data order of the
174+ * underlying Raster/DataBuffer. The source image data is ultimately
175+ * converted into RGBA data when uploaded to an OpenGL texture
176+ * (even for TYPE_GRAY), so the scale factors and offsets are already
177+ * in the order expected by the native OpenGL code.
178+ *
179+ * However, the offsets provided by the user are in a range dictated
180+ * by the size of each color/alpha band in the source image. For
181+ * example, for 8/8/8 data each offset is in the range [0,255],
182+ * for 5/5/5 data each offset is in the range [0,31], and so on.
183+ * The OpenGL shader only thinks in terms of [0,1], so below we need
184+ * to normalize the user-provided offset values into the range [0,1].
185+ */
186+ int numFactors = rop.getNumFactors();
187+ float[] origScaleFactors = rop.getScaleFactors(null);
188+ float[] origOffsets = rop.getOffsets(null);
189+
190+ // To make things easier, we will always pass all four bands
191+ // down to native code...
192+ float[] normScaleFactors;
193+ float[] normOffsets;
194+
195+ if (numFactors == 1) {
196+ normScaleFactors = new float[4];
197+ normOffsets = new float[4];
198+ for (int i = 0; i < 3; i++) {
199+ normScaleFactors[i] = origScaleFactors[0];
200+ normOffsets[i] = origOffsets[0];
201+ }
202+ // Leave alpha untouched...
203+ normScaleFactors[3] = 1.0f;
204+ normOffsets[3] = 0.0f;
205+ } else if (numFactors == 3) {
206+ normScaleFactors = new float[4];
207+ normOffsets = new float[4];
208+ for (int i = 0; i < 3; i++) {
209+ normScaleFactors[i] = origScaleFactors[i];
210+ normOffsets[i] = origOffsets[i];
211+ }
212+ // Leave alpha untouched...
213+ normScaleFactors[3] = 1.0f;
214+ normOffsets[3] = 0.0f;
215+ } else { // (numFactors == 4)
216+ normScaleFactors = origScaleFactors;
217+ normOffsets = origOffsets;
218+ }
219+
220+ // The user-provided offsets are specified in the range
221+ // of each source color band, but the OpenGL shader only wants
222+ // to deal with data in the range [0,1], so we need to normalize
223+ // each offset value to the range [0,1] here.
224+ if (srcCM.getNumComponents() == 1) {
225+ // Gray data
226+ int nBits = srcCM.getComponentSize(0);
227+ int maxValue = (1 << nBits) - 1;
228+ for (int i = 0; i < 3; i++) {
229+ normOffsets[i] /= maxValue;
230+ }
231+ } else {
232+ // RGB(A) data
233+ for (int i = 0; i < srcCM.getNumComponents(); i++) {
234+ int nBits = srcCM.getComponentSize(i);
235+ int maxValue = (1 << nBits) - 1;
236+ normOffsets[i] /= maxValue;
237+ }
238+ }
239+
240+ int sizeofFloat = 4;
241+ int totalBytesRequired = 4 + 8 + 4 + (4 * sizeofFloat * 2);
242+
243+ RenderBuffer buf = rq.getBuffer();
244+ rq.ensureCapacityAndAlignment(totalBytesRequired, 4);
245+ buf.putInt(ENABLE_RESCALE_OP);
246+ buf.putLong(srcData.getNativeOps());
247+ buf.putInt(nonPremult ? 1 : 0);
248+ buf.put(normScaleFactors);
249+ buf.put(normOffsets);
250+ }
251+
252+ private static void disableRescaleOp(RenderQueue rq) {
253+ // assert rq.lock.isHeldByCurrentThread();
254+ RenderBuffer buf = rq.getBuffer();
255+ rq.ensureCapacity(4);
256+ buf.putInt(DISABLE_RESCALE_OP);
257+ }
258+
259+/**************************** LookupOp support ******************************/
260+
261+ public static boolean isLookupOpValid(LookupOp lop,
262+ BufferedImage srcImg)
263+ {
264+ LookupTable table = lop.getTable();
265+ int numComps = table.getNumComponents();
266+ ColorModel srcCM = srcImg.getColorModel();
267+
268+ if (srcCM instanceof IndexColorModel) {
269+ throw new
270+ IllegalArgumentException("LookupOp cannot be "+
271+ "performed on an indexed image");
272+ }
273+ if (numComps != 1 &&
274+ numComps != srcCM.getNumComponents() &&
275+ numComps != srcCM.getNumColorComponents())
276+ {
277+ throw new IllegalArgumentException("Number of arrays in the "+
278+ " lookup table ("+
279+ numComps+
280+ ") is not compatible with"+
281+ " the src image: "+srcImg);
282+ }
283+
284+ int csType = srcCM.getColorSpace().getType();
285+ if (csType != ColorSpace.TYPE_RGB &&
286+ csType != ColorSpace.TYPE_GRAY)
287+ {
288+ // Not prepared to deal with other color spaces
289+ return false;
290+ }
291+
292+ if (numComps == 2 || numComps > 4) {
293+ // Not really prepared to handle this at the native level, so...
294+ return false;
295+ }
296+
297+ // The LookupTable spec says that "all arrays must be the
298+ // same size" but unfortunately the constructors do not
299+ // enforce that. Also, our native code only works with
300+ // arrays no larger than 256 elements, so check both of
301+ // these restrictions here.
302+ if (table instanceof ByteLookupTable) {
303+ byte[][] data = ((ByteLookupTable)table).getTable();
304+ for (int i = 1; i < data.length; i++) {
305+ if (data[i].length > 256 ||
306+ data[i].length != data[i-1].length)
307+ {
308+ return false;
309+ }
310+ }
311+ } else if (table instanceof ShortLookupTable) {
312+ short[][] data = ((ShortLookupTable)table).getTable();
313+ for (int i = 1; i < data.length; i++) {
314+ if (data[i].length > 256 ||
315+ data[i].length != data[i-1].length)
316+ {
317+ return false;
318+ }
319+ }
320+ } else {
321+ return false;
322+ }
323+
324+ return true;
325+ }
326+
327+ private static void enableLookupOp(RenderQueue rq,
328+ SurfaceData srcData,
329+ BufferedImage srcImg,
330+ LookupOp lop)
331+ {
332+ // assert rq.lock.isHeldByCurrentThread();
333+ boolean nonPremult =
334+ srcImg.getColorModel().hasAlpha() &&
335+ srcImg.isAlphaPremultiplied();
336+
337+ LookupTable table = lop.getTable();
338+ int numBands = table.getNumComponents();
339+ int offset = table.getOffset();
340+ int bandLength;
341+ int bytesPerElem;
342+ boolean shortData;
343+
344+ if (table instanceof ShortLookupTable) {
345+ short[][] data = ((ShortLookupTable)table).getTable();
346+ bandLength = data[0].length;
347+ bytesPerElem = 2;
348+ shortData = true;
349+ } else { // (table instanceof ByteLookupTable)
350+ byte[][] data = ((ByteLookupTable)table).getTable();
351+ bandLength = data[0].length;
352+ bytesPerElem = 1;
353+ shortData = false;
354+ }
355+
356+ // Adjust the LUT length so that it ends on a 4-byte boundary
357+ int totalLutBytes = numBands * bandLength * bytesPerElem;
358+ int paddedLutBytes = (totalLutBytes + 3) & (~3);
359+ int padding = paddedLutBytes - totalLutBytes;
360+ int totalBytesRequired = 4 + 8 + 20 + paddedLutBytes;
361+
362+ RenderBuffer buf = rq.getBuffer();
363+ rq.ensureCapacityAndAlignment(totalBytesRequired, 4);
364+ buf.putInt(ENABLE_LOOKUP_OP);
365+ buf.putLong(srcData.getNativeOps());
366+ buf.putInt(nonPremult ? 1 : 0);
367+ buf.putInt(shortData ? 1 : 0);
368+ buf.putInt(numBands);
369+ buf.putInt(bandLength);
370+ buf.putInt(offset);
371+ if (shortData) {
372+ short[][] data = ((ShortLookupTable)table).getTable();
373+ for (int i = 0; i < numBands; i++) {
374+ buf.put(data[i]);
375+ }
376+ } else {
377+ byte[][] data = ((ByteLookupTable)table).getTable();
378+ for (int i = 0; i < numBands; i++) {
379+ buf.put(data[i]);
380+ }
381+ }
382+ if (padding != 0) {
383+ buf.position(buf.position() + padding);
384+ }
385+ }
386+
387+ private static void disableLookupOp(RenderQueue rq) {
388+ // assert rq.lock.isHeldByCurrentThread();
389+ RenderBuffer buf = rq.getBuffer();
390+ rq.ensureCapacity(4);
391+ buf.putInt(DISABLE_LOOKUP_OP);
392+ }
393+}