Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/native/libsplashscreen/splashscreen_gfx_impl.c
41149 views
1
/*
2
* Copyright (c) 2005, 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 "splashscreen_gfx_impl.h"
27
28
/* *INDENT-OFF* */
29
const byte_t baseDitherMatrix[DITHER_SIZE][DITHER_SIZE] = {
30
/* Bayer's order-4 dither array. Generated by the code given in
31
* Stephen Hawley's article "Ordered Dithering" in Graphics Gems I.
32
*/
33
{ 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 },
34
{ 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 },
35
{ 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 },
36
{ 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 },
37
{ 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 },
38
{ 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 },
39
{ 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 },
40
{ 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 },
41
{ 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 },
42
{ 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 },
43
{ 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 },
44
{ 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 },
45
{ 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 },
46
{ 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 },
47
{ 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 },
48
{ 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 }
49
};
50
/* *INDENT-ON* */
51
52
// FIXME: tinting on some colormaps (e.g. 1-2-1) means something is slightly wrong with
53
// colormap calculation... probably it's some rounding error
54
55
/* calculates the colorTable for mapping from 0..255 to 0..numColors-1
56
also calculates the dithering matrix, scaling baseDitherMatrix accordingly */
57
void
58
initDither(DitherSettings * pDither, int numColors, int scale)
59
{
60
int i, j;
61
62
pDither->numColors = numColors;
63
for (i = 0; i < (MAX_COLOR_VALUE + 1) * 2; i++) {
64
pDither->colorTable[i] =
65
(((i > MAX_COLOR_VALUE) ? MAX_COLOR_VALUE : i) *
66
(numColors - 1) / MAX_COLOR_VALUE) * scale;
67
}
68
for (i = 0; i < DITHER_SIZE; i++)
69
for (j = 0; j < DITHER_SIZE; j++)
70
pDither->matrix[i][j] =
71
(int) baseDitherMatrix[i][j] / (numColors - 1);
72
}
73
74
/* scale a number on the range of 0..numColorsIn-1 to 0..numColorsOut-1
75
0 maps to 0 and numColorsIn-1 maps to numColorsOut-1
76
intermediate values are spread evenly between 0 and numColorsOut-1 */
77
INLINE int
78
scaleColor(int color, int numColorsIn, int numColorsOut)
79
{
80
return (color * (numColorsOut - 1) + (numColorsIn - 1) / 2)
81
/ (numColorsIn - 1);
82
}
83
84
/* build a colormap for a color cube and a dithering matrix. color cube is quantized
85
according to the provided maximum number of colors */
86
int
87
quantizeColors(int maxNumColors, int *numColors)
88
{
89
90
// static const int scale[3]={10000/11,10000/69,10000/30};
91
// FIXME: sort out the adaptive color cube subdivision... realistic 11:69:30 is good on photos,
92
// but would be bad on other pictures. A stupid approximation is used now.
93
94
static const int scale[3] = { 8, 4, 6 };
95
96
// maxNumColors should be at least 2x2x2=8, or we lose some color components completely
97
numColors[0] = numColors[1] = numColors[2] = 2;
98
99
while (1) {
100
int idx[3] = { 0, 1, 2 };
101
/* bubble sort the three indexes according to scaled numColors values */
102
#define SORT(i,j) \
103
if (numColors[idx[i]]*scale[idx[i]]>numColors[idx[j]]*scale[idx[j]]) \
104
{ int t = idx[i]; idx[i] = idx[j]; idx[j] = t; }
105
SORT(0, 1);
106
SORT(1, 2);
107
SORT(0, 1);
108
/* try increasing numColors for the first color */
109
if ((numColors[idx[0]] + 1) * numColors[idx[1]] *
110
numColors[idx[2]] <= maxNumColors) {
111
numColors[idx[0]]++;
112
} else if (numColors[idx[0]] * (numColors[idx[1]] + 1) *
113
numColors[idx[2]] <= maxNumColors) {
114
numColors[idx[1]]++;
115
} else if (numColors[idx[0]] * numColors[idx[1]] *
116
(numColors[idx[2]] + 1) <= maxNumColors) {
117
numColors[idx[2]]++;
118
} else {
119
break;
120
}
121
}
122
return numColors[0] * numColors[1] * numColors[2];
123
}
124
125
void
126
initColorCube(int *numColors, rgbquad_t * pColorMap, DitherSettings * pDithers,
127
rgbquad_t * colorIndex)
128
{
129
int r, g, b, n;
130
131
n = 0;
132
for (r = 0; r < numColors[2]; r++) {
133
for (g = 0; g < numColors[1]; g++)
134
for (b = 0; b < numColors[0]; b++) {
135
pColorMap[colorIndex[n++]] =
136
scaleColor(b, numColors[0], MAX_COLOR_VALUE) +
137
(scaleColor(g, numColors[1], MAX_COLOR_VALUE) << 8) +
138
(scaleColor(r, numColors[2], MAX_COLOR_VALUE) << 16);
139
}
140
}
141
initDither(pDithers + 0, numColors[0], 1);
142
initDither(pDithers + 1, numColors[1], numColors[0]);
143
initDither(pDithers + 2, numColors[2], numColors[1] * numColors[0]);
144
}
145
146
/*
147
the function below is a line conversion loop
148
149
incSrc and incDst are pSrc and pDst increment values for the loop, in bytes
150
mode defines how the pixels should be processed
151
152
mode==CVT_COPY means the pixels should be copied as is
153
mode==CVT_ALPHATEST means pixels should be skipped when source pixel alpha is above the threshold
154
mode==CVT_BLEND means alpha blending between source and destination should be performed, while
155
destination alpha should be retained. source alpha is used for blending.
156
*/
157
void
158
convertLine(void *pSrc, int incSrc, void *pDst, int incDst, int numSamples,
159
ImageFormat * srcFormat, ImageFormat * dstFormat, int doAlpha,
160
void *pSrc2, int incSrc2, ImageFormat * srcFormat2,
161
int row, int col)
162
{
163
int i;
164
165
switch (doAlpha) {
166
case CVT_COPY:
167
for (i = 0; i < numSamples; ++i) {
168
putRGBADither(getRGBA(pSrc, srcFormat), pDst, dstFormat,
169
row, col++);
170
INCPN(byte_t, pSrc, incSrc);
171
INCPN(byte_t, pDst, incDst);
172
}
173
break;
174
case CVT_ALPHATEST:
175
for (i = 0; i < numSamples; ++i) {
176
rgbquad_t color = getRGBA(pSrc, srcFormat);
177
178
if (color >= ALPHA_THRESHOLD) { // test for alpha component >50%. that's an extra branch, and it's bad...
179
putRGBADither(color, pDst, dstFormat, row, col++);
180
}
181
INCPN(byte_t, pSrc, incSrc);
182
INCPN(byte_t, pDst, incDst);
183
}
184
break;
185
case CVT_BLEND:
186
for (i = 0; i < numSamples; ++i) {
187
rgbquad_t src = getRGBA(pSrc, srcFormat);
188
rgbquad_t src2 = getRGBA(pSrc2, srcFormat);
189
190
putRGBADither(blendRGB(src, src2,
191
QUAD_ALPHA(src2)) | (src & QUAD_ALPHA_MASK), pDst, dstFormat,
192
row, col++);
193
INCPN(byte_t, pSrc, incSrc);
194
INCPN(byte_t, pDst, incDst);
195
INCPN(byte_t, pSrc2, incSrc2);
196
}
197
break;
198
}
199
}
200
201
/* initialize ImageRect structure according to function arguments */
202
void
203
initRect(ImageRect * pRect, int x, int y, int width, int height, int jump,
204
int stride, void *pBits, ImageFormat * format)
205
{
206
int depthBytes = format->depthBytes;
207
208
pRect->pBits = pBits;
209
INCPN(byte_t, pRect->pBits, (intptr_t) y * stride + x * depthBytes);
210
pRect->numLines = height;
211
pRect->numSamples = width;
212
pRect->stride = stride * jump;
213
pRect->depthBytes = depthBytes;
214
pRect->format = format;
215
pRect->row = y;
216
pRect->col = x;
217
pRect->jump = jump;
218
}
219
220
/* copy image rectangle from source to destination, or from two sources with blending */
221
222
int
223
convertRect(ImageRect * pSrcRect, ImageRect * pDstRect, int mode)
224
{
225
return convertRect2(pSrcRect, pDstRect, mode, NULL);
226
}
227
228
int
229
convertRect2(ImageRect * pSrcRect, ImageRect * pDstRect, int mode,
230
ImageRect * pSrcRect2)
231
{
232
int numLines = pSrcRect->numLines;
233
int numSamples = pSrcRect->numSamples;
234
void *pSrc = pSrcRect->pBits;
235
void *pDst = pDstRect->pBits;
236
void *pSrc2 = NULL;
237
int j, row;
238
239
if (pDstRect->numLines < numLines)
240
numLines = pDstRect->numLines;
241
if (pDstRect->numSamples < numSamples) {
242
numSamples = pDstRect->numSamples;
243
}
244
if (pSrcRect2) {
245
if (pSrcRect2->numLines < numLines) {
246
numLines = pSrcRect2->numLines;
247
}
248
if (pSrcRect2->numSamples < numSamples) {
249
numSamples = pSrcRect2->numSamples;
250
}
251
pSrc2 = pSrcRect2->pBits;
252
}
253
row = pDstRect->row;
254
for (j = 0; j < numLines; j++) {
255
convertLine(pSrc, pSrcRect->depthBytes, pDst, pDstRect->depthBytes,
256
numSamples, pSrcRect->format, pDstRect->format, mode,
257
pSrc2, pSrcRect2 ? pSrcRect2->depthBytes : 0,
258
pSrcRect2 ? pSrcRect2->format : 0, row, pDstRect->col);
259
INCPN(byte_t, pSrc, pSrcRect->stride);
260
INCPN(byte_t, pDst, pDstRect->stride);
261
if (pSrcRect2) {
262
INCPN(byte_t, pSrc2, pSrcRect2->stride);
263
}
264
row += pDstRect->jump;
265
}
266
return numLines * pSrcRect->stride;
267
}
268
269
int
270
fillRect(rgbquad_t color, ImageRect * pDstRect)
271
{
272
int numLines = pDstRect->numLines;
273
int numSamples = pDstRect->numSamples;
274
void *pDst = pDstRect->pBits;
275
int j, row;
276
277
row = pDstRect->row;
278
for (j = 0; j < numLines; j++) {
279
fillLine(color, pDst, pDstRect->depthBytes, numSamples,
280
pDstRect->format, row, pDstRect->col);
281
INCPN(byte_t, pDst, pDstRect->stride);
282
row += pDstRect->jump;
283
}
284
return numLines * pDstRect->stride;
285
}
286
287
/* init the masks; all other parameters are initialized to default values */
288
void
289
initFormat(ImageFormat * format, int redMask, int greenMask, int blueMask,
290
int alphaMask)
291
{
292
int i, shift, numBits;
293
294
format->byteOrder = BYTE_ORDER_NATIVE;
295
format->colorMap = NULL;
296
format->depthBytes = 4;
297
format->fixedBits = 0;
298
format->premultiplied = 0;
299
format->mask[0] = blueMask;
300
format->mask[1] = greenMask;
301
format->mask[2] = redMask;
302
format->mask[3] = alphaMask;
303
for (i = 0; i < 4; i++) {
304
getMaskShift(format->mask[i], &shift, &numBits);
305
format->shift[i] = shift + numBits - i * 8 - 8;
306
}
307
}
308
309
/* dump the visual format */
310
void
311
dumpFormat(ImageFormat * format)
312
{
313
#ifdef _DEBUG
314
int i;
315
316
printf("byteorder=%d colormap=%08x depthBytes=%d fixedBits=%08x transparentColor=%u ",
317
format->byteOrder, (unsigned) format->colorMap, format->depthBytes,
318
(unsigned) format->fixedBits, (unsigned) format->transparentColor);
319
for (i = 0; i < 4; i++) {
320
printf("mask[%d]=%08x shift[%d]=%d\n", i, (unsigned) format->mask[i], i,
321
format->shift[i]);
322
}
323
printf("\n");
324
#endif
325
}
326
327
/* optimize the format */
328
void
329
optimizeFormat(ImageFormat * format)
330
{
331
if (platformByteOrder() == format->byteOrder && format->depthBytes != 3) {
332
format->byteOrder = BYTE_ORDER_NATIVE;
333
}
334
/* FIXME: some advanced optimizations are possible, especially for format pairs */
335
}
336
337
int
338
platformByteOrder()
339
{
340
int test = 1;
341
342
*(char *) &test = 0;
343
return test ? BYTE_ORDER_MSBFIRST : BYTE_ORDER_LSBFIRST;
344
}
345
346