Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/native/sun/awt/splashscreen/splashscreen_impl.c
38918 views
1
/*
2
* Copyright (c) 2005, 2006, 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_impl.h"
27
#include "splashscreen_gfx_impl.h"
28
29
int splashIsVisible = 0;
30
31
Splash *
32
SplashGetInstance()
33
{
34
static Splash splash;
35
static int preInitialized = 0;
36
if (!preInitialized) {
37
memset(&splash, 0, sizeof(Splash));
38
splash.currentFrame = -1;
39
preInitialized = 1;
40
}
41
return &splash;
42
}
43
44
SPLASHEXPORT void
45
SplashSetFileJarName(const char* fileName, const char* jarName) {
46
Splash *splash = SplashGetInstance();
47
48
free(splash->fileName);
49
splash->fileName = SplashConvertStringAlloc(fileName, &splash->fileNameLen);
50
51
free(splash->jarName);
52
splash->jarName = SplashConvertStringAlloc(jarName, &splash->jarNameLen);
53
}
54
55
SPLASHEXPORT void
56
SplashInit()
57
{
58
Splash *splash = SplashGetInstance();
59
60
memset(splash, 0, sizeof(Splash));
61
splash->currentFrame = -1;
62
splash->scaleFactor = 1;
63
initFormat(&splash->imageFormat, QUAD_RED_MASK, QUAD_GREEN_MASK,
64
QUAD_BLUE_MASK, QUAD_ALPHA_MASK);
65
SplashInitPlatform(splash);
66
}
67
68
SPLASHEXPORT void
69
SplashClose()
70
{
71
Splash *splash = SplashGetInstance();
72
73
if (splash->isVisible > 0) {
74
SplashLock(splash);
75
splash->isVisible = -1;
76
SplashClosePlatform(splash);
77
SplashUnlock(splash);
78
}
79
}
80
81
void
82
SplashCleanup(Splash * splash)
83
{
84
int i;
85
86
splash->currentFrame = -1;
87
SplashCleanupPlatform(splash);
88
if (splash->frames) {
89
for (i = 0; i < splash->frameCount; i++) {
90
if (splash->frames[i].bitmapBits) {
91
free(splash->frames[i].bitmapBits);
92
splash->frames[i].bitmapBits = NULL;
93
}
94
}
95
free(splash->frames);
96
splash->frames = NULL;
97
}
98
if (splash->overlayData) {
99
free(splash->overlayData);
100
splash->overlayData = NULL;
101
}
102
SplashSetFileJarName(NULL, NULL);
103
}
104
105
SPLASHEXPORT void
106
SplashSetScaleFactor(float scaleFactor)
107
{
108
Splash *splash = SplashGetInstance();
109
splash->scaleFactor = scaleFactor;
110
}
111
112
void
113
SplashDone(Splash * splash)
114
{
115
SplashCleanup(splash);
116
SplashDonePlatform(splash);
117
}
118
119
int
120
SplashIsStillLooping(Splash * splash)
121
{
122
if (splash->currentFrame < 0) {
123
return 0;
124
}
125
return splash->loopCount != 1 ||
126
splash->currentFrame + 1 < splash->frameCount;
127
}
128
129
void
130
SplashUpdateScreenData(Splash * splash)
131
{
132
ImageRect srcRect, dstRect;
133
if (splash->currentFrame < 0) {
134
return;
135
}
136
137
initRect(&srcRect, 0, 0, splash->width, splash->height, 1,
138
splash->width * sizeof(rgbquad_t),
139
splash->frames[splash->currentFrame].bitmapBits, &splash->imageFormat);
140
if (splash->screenData) {
141
free(splash->screenData);
142
}
143
splash->screenStride = splash->width * splash->screenFormat.depthBytes;
144
if (splash->byteAlignment > 1) {
145
splash->screenStride =
146
(splash->screenStride + splash->byteAlignment - 1) &
147
~(splash->byteAlignment - 1);
148
}
149
splash->screenData = malloc(splash->height * splash->screenStride);
150
initRect(&dstRect, 0, 0, splash->width, splash->height, 1,
151
splash->screenStride, splash->screenData, &splash->screenFormat);
152
if (splash->overlayData) {
153
convertRect2(&srcRect, &dstRect, CVT_BLEND, &splash->overlayRect);
154
}
155
else {
156
convertRect(&srcRect, &dstRect, CVT_COPY);
157
}
158
}
159
160
void
161
SplashNextFrame(Splash * splash)
162
{
163
if (splash->currentFrame < 0) {
164
return;
165
}
166
do {
167
if (!SplashIsStillLooping(splash)) {
168
return;
169
}
170
splash->time += splash->frames[splash->currentFrame].delay;
171
if (++splash->currentFrame >= splash->frameCount) {
172
splash->currentFrame = 0;
173
if (splash->loopCount > 0) {
174
splash->loopCount--;
175
}
176
}
177
} while (splash->time + splash->frames[splash->currentFrame].delay -
178
SplashTime() <= 0);
179
}
180
181
int
182
BitmapToYXBandedRectangles(ImageRect * pSrcRect, RECT_T * out)
183
{
184
RECT_T *pPrevLine = NULL, *pFirst = out, *pThis = pFirst;
185
int i, j, i0;
186
int length;
187
188
for (j = 0; j < pSrcRect->numLines; j++) {
189
190
/* generate data for a scanline */
191
192
byte_t *pSrc = (byte_t *) pSrcRect->pBits + j * pSrcRect->stride;
193
RECT_T *pLine = pThis;
194
195
i = 0;
196
197
do {
198
while (i < pSrcRect->numSamples &&
199
getRGBA(pSrc, pSrcRect->format) < ALPHA_THRESHOLD) {
200
pSrc += pSrcRect->depthBytes;
201
++i;
202
}
203
if (i >= pSrcRect->numSamples) {
204
break;
205
}
206
i0 = i;
207
while (i < pSrcRect->numSamples &&
208
getRGBA(pSrc, pSrcRect->format) >= ALPHA_THRESHOLD) {
209
pSrc += pSrcRect->depthBytes;
210
++i;
211
}
212
RECT_SET(*pThis, i0, j, i - i0, 1);
213
++pThis;
214
} while (i < pSrcRect->numSamples);
215
216
/* check if the previous scanline is exactly the same, merge if so
217
(this is the only optimization we can use for YXBanded rectangles, and win32 supports
218
YXBanded only */
219
220
length = pThis - pLine;
221
if (pPrevLine && pLine - pPrevLine == length) {
222
for (i = 0; i < length && RECT_EQ_X(pPrevLine[i], pLine[i]); ++i) {
223
}
224
if (i == pLine - pPrevLine) {
225
// do merge
226
for (i = 0; i < length; i++) {
227
RECT_INC_HEIGHT(pPrevLine[i]);
228
}
229
pThis = pLine;
230
continue;
231
}
232
}
233
/* or else use the generated scanline */
234
235
pPrevLine = pLine;
236
}
237
return pThis - pFirst;
238
}
239
240
typedef struct FILEFORMAT
241
{
242
int sign;
243
int (*decodeStream) (Splash * splash, SplashStream * stream);
244
} FILEFORMAT;
245
246
static const FILEFORMAT formats[] = {
247
{0x47, SplashDecodeGifStream},
248
{0x89, SplashDecodePngStream},
249
{0xFF, SplashDecodeJpegStream}
250
};
251
252
static int
253
SplashLoadStream(SplashStream * stream)
254
{
255
int success = 0;
256
int c;
257
size_t i;
258
259
Splash *splash = SplashGetInstance();
260
if (splash->isVisible < 0) {
261
return 0;
262
}
263
264
SplashLock(splash);
265
266
/* the formats we support can be easily distinguished by the first byte */
267
c = stream->peek(stream);
268
if (c != -1) {
269
for (i = 0; i < sizeof(formats) / sizeof(FILEFORMAT); i++) {
270
if (c == formats[i].sign) {
271
success = formats[i].decodeStream(splash, stream);
272
break;
273
}
274
}
275
}
276
stream->close(stream);
277
278
if (!success) { // failed to decode
279
if (splash->isVisible == 0) {
280
SplashCleanup(splash);
281
}
282
SplashUnlock(splash); // SplashClose locks
283
if (splash->isVisible == 0) {
284
SplashClose();
285
}
286
}
287
else {
288
splash->currentFrame = 0;
289
if (splash->isVisible == 0) {
290
SplashStart(splash);
291
} else {
292
SplashReconfigure(splash);
293
splash->time = SplashTime();
294
}
295
SplashUnlock(splash);
296
}
297
return success;
298
}
299
300
SPLASHEXPORT int
301
SplashLoadFile(const char *filename)
302
{
303
SplashStream stream;
304
return SplashStreamInitFile(&stream, filename) &&
305
SplashLoadStream(&stream);
306
}
307
308
SPLASHEXPORT int
309
SplashLoadMemory(void *data, int size)
310
{
311
SplashStream stream;
312
return SplashStreamInitMemory(&stream, data, size) &&
313
SplashLoadStream(&stream);
314
}
315
316
/* SplashStart MUST be called from under the lock */
317
318
void
319
SplashStart(Splash * splash)
320
{
321
if (splash->isVisible == 0) {
322
SplashCreateThread(splash);
323
splash->isVisible = 1;
324
}
325
}
326
327
/* SplashStream functions */
328
329
static int readFile(void* pStream, void* pData, int nBytes) {
330
FILE* f = ((SplashStream*)pStream)->arg.stdio.f;
331
return fread(pData, 1, nBytes, f);
332
}
333
static int peekFile(void* pStream) {
334
FILE* f = ((SplashStream*)pStream)->arg.stdio.f;
335
int c = fgetc(f);
336
if (c != EOF) {
337
ungetc(c, f);
338
return c;
339
} else {
340
return -1;
341
}
342
}
343
344
static void closeFile(void* pStream) {
345
FILE* f = ((SplashStream*)pStream)->arg.stdio.f;
346
fclose(f);
347
}
348
349
static int readMem(void* pStream, void* pData, int nBytes) {
350
unsigned char* pSrc = (unsigned char*)(((SplashStream*)pStream)->arg.mem.pData);
351
unsigned char* pSrcEnd = (unsigned char*)(((SplashStream*)pStream)->arg.mem.pDataEnd);
352
if (nBytes > pSrcEnd - pSrc) {
353
nBytes = pSrcEnd - pSrc;
354
}
355
if (nBytes>0) {
356
memcpy(pData, pSrc, nBytes);
357
pSrc += nBytes;
358
((SplashStream*)pStream)->arg.mem.pData = (void*)pSrc;
359
}
360
return nBytes;
361
}
362
363
static int peekMem(void* pStream) {
364
unsigned char* pSrc = (unsigned char*)(((SplashStream*)pStream)->arg.mem.pData);
365
unsigned char* pSrcEnd = (unsigned char*)(((SplashStream*)pStream)->arg.mem.pDataEnd);
366
if (pSrc >= pSrcEnd) {
367
return -1;
368
} else {
369
return (int)*pSrc;
370
}
371
}
372
373
static void closeMem(void* pStream) {
374
}
375
376
int SplashStreamInitFile(SplashStream * pStream, const char* filename) {
377
pStream->arg.stdio.f = fopen(filename, "rb");
378
pStream->read = readFile;
379
pStream->peek = peekFile;
380
pStream->close = closeFile;
381
return pStream->arg.stdio.f != 0;
382
}
383
384
int SplashStreamInitMemory(SplashStream * pStream, void* pData, int size) {
385
pStream->arg.mem.pData = (unsigned char*)pData;
386
pStream->arg.mem.pDataEnd = (unsigned char*)pData + size;
387
pStream->read = readMem;
388
pStream->peek = peekMem;
389
pStream->close = closeMem;
390
return 1;
391
}
392
393