Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/native/libawt/awt/image/BufImgSurfaceData.c
41159 views
1
/*
2
* Copyright (c) 1999, 2019, 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
#include "BufImgSurfaceData.h"
27
#include <stdlib.h>
28
29
#include "sun_awt_image_BufImgSurfaceData.h"
30
31
#include "img_util_md.h"
32
#include "jni_util.h"
33
/* Define uintptr_t */
34
#include "gdefs.h"
35
#include "Disposer.h"
36
37
/**
38
* This include file contains support code for loops using the
39
* SurfaceData interface to talk to an X11 drawable from native
40
* code.
41
*/
42
43
static LockFunc BufImg_Lock;
44
static GetRasInfoFunc BufImg_GetRasInfo;
45
static ReleaseFunc BufImg_Release;
46
static DisposeFunc BufImg_Dispose;
47
48
static ColorData *BufImg_SetupICM(JNIEnv *env, BufImgSDOps *bisdo);
49
50
static jfieldID rgbID;
51
static jfieldID mapSizeID;
52
static jfieldID colorDataID;
53
static jfieldID pDataID;
54
static jfieldID allGrayID;
55
56
static jclass clsICMCD;
57
static jmethodID initICMCDmID;
58
/*
59
* Class: sun_awt_image_BufImgSurfaceData
60
* Method: initIDs
61
* Signature: ()V
62
*/
63
JNIEXPORT void JNICALL
64
Java_sun_awt_image_BufImgSurfaceData_initIDs
65
(JNIEnv *env, jclass bisd, jclass icm, jclass cd)
66
{
67
if (sizeof(BufImgRIPrivate) > SD_RASINFO_PRIVATE_SIZE) {
68
JNU_ThrowInternalError(env, "Private RasInfo structure too large!");
69
return;
70
}
71
72
clsICMCD = (*env)->NewWeakGlobalRef(env, cd);
73
JNU_CHECK_EXCEPTION(env);
74
CHECK_NULL(initICMCDmID = (*env)->GetMethodID(env, cd, "<init>", "(J)V"));
75
CHECK_NULL(pDataID = (*env)->GetFieldID(env, cd, "pData", "J"));
76
CHECK_NULL(rgbID = (*env)->GetFieldID(env, icm, "rgb", "[I"));
77
CHECK_NULL(allGrayID = (*env)->GetFieldID(env, icm, "allgrayopaque", "Z"));
78
CHECK_NULL(mapSizeID = (*env)->GetFieldID(env, icm, "map_size", "I"));
79
CHECK_NULL(colorDataID = (*env)->GetFieldID(env, icm, "colorData",
80
"Lsun/awt/image/BufImgSurfaceData$ICMColorData;"));
81
}
82
83
/*
84
* Class: sun_awt_image_BufImgSurfaceData
85
* Method: initOps
86
* Signature: (Ljava/lang/Object;IIIII)V
87
*/
88
JNIEXPORT void JNICALL
89
Java_sun_awt_image_BufImgSurfaceData_initRaster(JNIEnv *env, jobject bisd,
90
jobject array,
91
jint offset, jint bitoffset,
92
jint width, jint height,
93
jint pixStr, jint scanStr,
94
jobject icm)
95
{
96
BufImgSDOps *bisdo =
97
(BufImgSDOps*)SurfaceData_InitOps(env, bisd, sizeof(BufImgSDOps));
98
if (bisdo == NULL) {
99
JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed.");
100
return;
101
}
102
bisdo->sdOps.Lock = BufImg_Lock;
103
bisdo->sdOps.GetRasInfo = BufImg_GetRasInfo;
104
bisdo->sdOps.Release = BufImg_Release;
105
bisdo->sdOps.Unlock = NULL;
106
bisdo->sdOps.Dispose = BufImg_Dispose;
107
bisdo->array = (*env)->NewWeakGlobalRef(env, array);
108
JNU_CHECK_EXCEPTION(env);
109
bisdo->offset = offset;
110
bisdo->bitoffset = bitoffset;
111
bisdo->scanStr = scanStr;
112
bisdo->pixStr = pixStr;
113
if (JNU_IsNull(env, icm)) {
114
bisdo->lutarray = NULL;
115
bisdo->lutsize = 0;
116
bisdo->icm = NULL;
117
} else {
118
jobject lutarray = (*env)->GetObjectField(env, icm, rgbID);
119
bisdo->lutarray = (*env)->NewWeakGlobalRef(env, lutarray);
120
JNU_CHECK_EXCEPTION(env);
121
bisdo->lutsize = (*env)->GetIntField(env, icm, mapSizeID);
122
bisdo->icm = (*env)->NewWeakGlobalRef(env, icm);
123
}
124
bisdo->rasbounds.x1 = 0;
125
bisdo->rasbounds.y1 = 0;
126
bisdo->rasbounds.x2 = width;
127
bisdo->rasbounds.y2 = height;
128
}
129
130
/*
131
* Releases native structures associated with BufImgSurfaceData.ICMColorData.
132
*/
133
static void BufImg_Dispose_ICMColorData(JNIEnv *env, jlong pData)
134
{
135
ColorData *cdata = (ColorData*)jlong_to_ptr(pData);
136
freeICMColorData(cdata);
137
}
138
139
/*
140
* Method for disposing native BufImgSD
141
*/
142
static void BufImg_Dispose(JNIEnv *env, SurfaceDataOps *ops)
143
{
144
/* ops is assumed non-null as it is checked in SurfaceData_DisposeOps */
145
BufImgSDOps *bisdo = (BufImgSDOps *)ops;
146
(*env)->DeleteWeakGlobalRef(env, bisdo->array);
147
if (bisdo->lutarray != NULL) {
148
(*env)->DeleteWeakGlobalRef(env, bisdo->lutarray);
149
}
150
if (bisdo->icm != NULL) {
151
(*env)->DeleteWeakGlobalRef(env, bisdo->icm);
152
}
153
}
154
155
static jint BufImg_Lock(JNIEnv *env,
156
SurfaceDataOps *ops,
157
SurfaceDataRasInfo *pRasInfo,
158
jint lockflags)
159
{
160
BufImgSDOps *bisdo = (BufImgSDOps *)ops;
161
BufImgRIPrivate *bipriv = (BufImgRIPrivate *) &(pRasInfo->priv);
162
163
if ((lockflags & (SD_LOCK_LUT)) != 0 && JNU_IsNull(env, bisdo->lutarray)) {
164
/* REMIND: Should this be an InvalidPipe exception? */
165
JNU_ThrowNullPointerException(env, "Attempt to lock missing colormap");
166
return SD_FAILURE;
167
}
168
if ((lockflags & SD_LOCK_INVCOLOR) != 0 ||
169
(lockflags & SD_LOCK_INVGRAY) != 0)
170
{
171
bipriv->cData = BufImg_SetupICM(env, bisdo);
172
if (bipriv->cData == NULL) {
173
(*env)->ExceptionClear(env);
174
JNU_ThrowNullPointerException(env, "Could not initialize inverse tables");
175
return SD_FAILURE;
176
}
177
} else {
178
bipriv->cData = NULL;
179
}
180
181
bipriv->lockFlags = lockflags;
182
bipriv->base = NULL;
183
bipriv->lutbase = NULL;
184
185
SurfaceData_IntersectBounds(&pRasInfo->bounds, &bisdo->rasbounds);
186
187
return SD_SUCCESS;
188
}
189
190
static void BufImg_GetRasInfo(JNIEnv *env,
191
SurfaceDataOps *ops,
192
SurfaceDataRasInfo *pRasInfo)
193
{
194
BufImgSDOps *bisdo = (BufImgSDOps *)ops;
195
BufImgRIPrivate *bipriv = (BufImgRIPrivate *) &(pRasInfo->priv);
196
197
if ((bipriv->lockFlags & (SD_LOCK_RD_WR)) != 0) {
198
bipriv->base =
199
(*env)->GetPrimitiveArrayCritical(env, bisdo->array, NULL);
200
CHECK_NULL(bipriv->base);
201
}
202
if ((bipriv->lockFlags & (SD_LOCK_LUT)) != 0) {
203
bipriv->lutbase =
204
(*env)->GetPrimitiveArrayCritical(env, bisdo->lutarray, NULL);
205
}
206
207
if (bipriv->base == NULL) {
208
pRasInfo->rasBase = NULL;
209
pRasInfo->pixelStride = 0;
210
pRasInfo->pixelBitOffset = 0;
211
pRasInfo->scanStride = 0;
212
} else {
213
pRasInfo->rasBase = (void *)
214
(((uintptr_t) bipriv->base) + bisdo->offset);
215
pRasInfo->pixelStride = bisdo->pixStr;
216
pRasInfo->pixelBitOffset = bisdo->bitoffset;
217
pRasInfo->scanStride = bisdo->scanStr;
218
}
219
if (bipriv->lutbase == NULL) {
220
pRasInfo->lutBase = NULL;
221
pRasInfo->lutSize = 0;
222
} else {
223
pRasInfo->lutBase = bipriv->lutbase;
224
pRasInfo->lutSize = bisdo->lutsize;
225
}
226
if (bipriv->cData == NULL) {
227
pRasInfo->invColorTable = NULL;
228
pRasInfo->redErrTable = NULL;
229
pRasInfo->grnErrTable = NULL;
230
pRasInfo->bluErrTable = NULL;
231
pRasInfo->representsPrimaries = 0;
232
} else {
233
pRasInfo->invColorTable = bipriv->cData->img_clr_tbl;
234
pRasInfo->redErrTable = bipriv->cData->img_oda_red;
235
pRasInfo->grnErrTable = bipriv->cData->img_oda_green;
236
pRasInfo->bluErrTable = bipriv->cData->img_oda_blue;
237
pRasInfo->invGrayTable = bipriv->cData->pGrayInverseLutData;
238
pRasInfo->representsPrimaries = bipriv->cData->representsPrimaries;
239
}
240
}
241
242
static void BufImg_Release(JNIEnv *env,
243
SurfaceDataOps *ops,
244
SurfaceDataRasInfo *pRasInfo)
245
{
246
BufImgSDOps *bisdo = (BufImgSDOps *)ops;
247
BufImgRIPrivate *bipriv = (BufImgRIPrivate *) &(pRasInfo->priv);
248
249
if (bipriv->base != NULL) {
250
jint mode = (((bipriv->lockFlags & (SD_LOCK_WRITE)) != 0)
251
? 0 : JNI_ABORT);
252
(*env)->ReleasePrimitiveArrayCritical(env, bisdo->array,
253
bipriv->base, mode);
254
}
255
if (bipriv->lutbase != NULL) {
256
(*env)->ReleasePrimitiveArrayCritical(env, bisdo->lutarray,
257
bipriv->lutbase, JNI_ABORT);
258
}
259
}
260
261
static int calculatePrimaryColorsApproximation(int* cmap, unsigned char* cube, int cube_size) {
262
int i, j, k;
263
int index, value, color;
264
// values calculated from cmap
265
int r, g, b;
266
// maximum positive/negative variation allowed for r, g, b values for primary colors
267
int delta = 5;
268
// get the primary color cmap indices from corner of inverse color table
269
for (i = 0; i < cube_size; i += (cube_size - 1)) {
270
for (j = 0; j < cube_size; j += (cube_size - 1)) {
271
for (k = 0; k < cube_size; k += (cube_size - 1)) {
272
// calculate inverse color table index
273
index = i + cube_size * (j + cube_size * k);
274
// get value present in corners of inverse color table
275
value = cube[index];
276
// use the corner values as index for cmap
277
color = cmap[value];
278
// extract r,g,b values from cmap value
279
r = ((color) >> 16) & 0xff;
280
g = ((color) >> 8) & 0xff;
281
b = color & 0xff;
282
/*
283
* If i/j/k value is 0 optimum value of b/g/r should be 0 but we allow
284
* maximum positive variation of 5. If i/j/k value is 31 optimum value
285
* of b/g/r should be 255 but we allow maximum negative variation of 5.
286
*/
287
if (i == 0) {
288
if (b > delta)
289
return 0;
290
} else {
291
if (b < (255 - delta))
292
return 0;
293
}
294
if (j == 0) {
295
if (g > delta)
296
return 0;
297
} else {
298
if (g < (255 - delta))
299
return 0;
300
}
301
if (k == 0) {
302
if (r > delta)
303
return 0;
304
} else {
305
if (r < (255 - delta))
306
return 0;
307
}
308
}
309
}
310
}
311
return 1;
312
}
313
314
static ColorData *BufImg_SetupICM(JNIEnv *env,
315
BufImgSDOps *bisdo)
316
{
317
ColorData *cData = NULL;
318
jobject colorData;
319
320
if (JNU_IsNull(env, bisdo->icm)) {
321
return (ColorData *) NULL;
322
}
323
324
colorData = (*env)->GetObjectField(env, bisdo->icm, colorDataID);
325
326
if (JNU_IsNull(env, colorData)) {
327
if (JNU_IsNull(env, clsICMCD)) {
328
// we are unable to create a wrapper object
329
return (ColorData*)NULL;
330
}
331
} else {
332
cData = (ColorData*)JNU_GetLongFieldAsPtr(env, colorData, pDataID);
333
}
334
335
if (cData != NULL) {
336
return cData;
337
}
338
339
cData = (ColorData*)calloc(1, sizeof(ColorData));
340
341
if (cData != NULL) {
342
jboolean allGray
343
= (*env)->GetBooleanField(env, bisdo->icm, allGrayID);
344
int *pRgb = (int *)
345
((*env)->GetPrimitiveArrayCritical(env, bisdo->lutarray, NULL));
346
347
if (pRgb == NULL) {
348
free(cData);
349
return (ColorData*)NULL;
350
}
351
352
cData->img_clr_tbl = initCubemap(pRgb, bisdo->lutsize, 32);
353
if (cData->img_clr_tbl == NULL) {
354
(*env)->ReleasePrimitiveArrayCritical(env, bisdo->lutarray, pRgb, JNI_ABORT);
355
free(cData);
356
return (ColorData*)NULL;
357
}
358
cData->representsPrimaries = calculatePrimaryColorsApproximation(pRgb, cData->img_clr_tbl, 32);
359
if (allGray == JNI_TRUE) {
360
initInverseGrayLut(pRgb, bisdo->lutsize, cData);
361
}
362
(*env)->ReleasePrimitiveArrayCritical(env, bisdo->lutarray, pRgb,
363
JNI_ABORT);
364
365
initDitherTables(cData);
366
367
if (JNU_IsNull(env, colorData)) {
368
jlong pData = ptr_to_jlong(cData);
369
colorData = (*env)->NewObjectA(env, clsICMCD, initICMCDmID, (jvalue *)&pData);
370
371
if ((*env)->ExceptionCheck(env))
372
{
373
free(cData);
374
return (ColorData*)NULL;
375
}
376
377
(*env)->SetObjectField(env, bisdo->icm, colorDataID, colorData);
378
Disposer_AddRecord(env, colorData, BufImg_Dispose_ICMColorData, pData);
379
}
380
}
381
382
return cData;
383
}
384
385