Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/native/common/awt/medialib/mlib_ImageCreate.c
41161 views
1
/*
2
* Copyright (c) 1997, 2018, 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
27
/*
28
* FUNCTION
29
* mlib_ImageCreateStruct - create image data structure
30
* mlib_ImageCreate - create image data structure and allocate
31
* memory for image data
32
* mlib_ImageDelete - delete image
33
* mlib_ImageCreateSubimage - create sub-image
34
*
35
* mlib_ImageCreateRowTable - create row starts pointer table
36
* mlib_ImageDeleteRowTable - delete row starts pointer table
37
*
38
* mlib_ImageSetPaddings - set paddings for clipping box borders
39
*
40
* mlib_ImageSetFormat - set image format
41
*
42
* SYNOPSIS
43
* mlib_image *mlib_ImageCreateStruct(mlib_type type,
44
* mlib_s32 channels,
45
* mlib_s32 width,
46
* mlib_s32 height,
47
* mlib_s32 stride,
48
* const void *data)
49
*
50
* mlib_image *mlib_ImageCreate(mlib_type type,
51
* mlib_s32 channels,
52
* mlib_s32 width,
53
* mlib_s32 height)
54
*
55
* void mlib_ImageDelete(mlib_image *img)
56
*
57
* mlib_image *mlib_ImageCreateSubimage(mlib_image *img,
58
* mlib_s32 x,
59
* mlib_s32 y,
60
* mlib_s32 w,
61
* mlib_s32 h)
62
*
63
* void *mlib_ImageCreateRowTable(mlib_image *img)
64
*
65
* void mlib_ImageDeleteRowTable(mlib_image *img)
66
*
67
* mlib_status mlib_ImageSetPaddings(mlib_image *img,
68
* mlib_u8 left,
69
* mlib_u8 top,
70
* mlib_u8 right,
71
* mlib_u8 bottom)
72
*
73
* mlib_status mlib_ImageSetFormat(mlib_image *img,
74
* mlib_format format)
75
* ARGUMENTS
76
* img pointer to image data structure
77
* type image data type, one of MLIB_BIT, MLIB_BYTE, MLIB_SHORT,
78
* MLIB_USHORT, MLIB_INT, MLIB_FLOAT or MLIB_DOUBLE
79
* channels number of image channels
80
* width image width in pixels
81
* height image height in pixels
82
* stride linebytes( bytes to next row) of the image
83
* data pointer to image data allocated by user
84
* x x coordinate of the left border in the source image
85
* y y coordinate of the top border in the source image
86
* w width of the sub-image
87
* h height of the sub-image
88
* left clipping box left padding
89
* top clipping box top padding
90
* right clipping box right padding
91
* bottom clipping box bottom padding
92
* format image format
93
*
94
* DESCRIPTION
95
* mlib_ImageCreateStruct() creates a mediaLib image data structure
96
* using parameter supplied by user.
97
*
98
* mlib_ImageCreate() creates a mediaLib image data structure and
99
* allocates memory space for image data.
100
*
101
* mlib_ImageDelete() deletes the mediaLib image data structure
102
* and frees the memory space of the image data if it is allocated
103
* through mlib_ImageCreate().
104
*
105
* mlib_ImageCreateSubimage() creates a mediaLib image structure
106
* for a sub-image based on a source image.
107
*
108
* mlib_ImageCreateRowTable() creates row starts pointer table and
109
* puts it into mlib_image->state field.
110
*
111
* mlib_ImageDeleteRowTable() deletes row starts pointer table from
112
* image and puts NULL into mlib_image->state field.
113
*
114
* mlib_ImageSetPaddings() sets new values for the clipping box paddings
115
*
116
* mlib_ImageSetFormat() sets new value for the image format
117
*/
118
119
#include <stdlib.h>
120
#include "mlib_image.h"
121
#include "mlib_ImageRowTable.h"
122
#include "mlib_ImageCreate.h"
123
#include "safe_math.h"
124
125
/***************************************************************/
126
mlib_image* mlib_ImageSet(mlib_image *image,
127
mlib_type type,
128
mlib_s32 channels,
129
mlib_s32 width,
130
mlib_s32 height,
131
mlib_s32 stride,
132
const void *data)
133
{
134
mlib_s32 wb; /* width in bytes */
135
mlib_s32 mask; /* mask for check of stride */
136
137
if (image == NULL) return NULL;
138
139
/* for some ugly functions calling with incorrect parameters */
140
image -> type = type;
141
image -> channels = channels;
142
image -> width = width;
143
image -> height = height;
144
image -> stride = stride;
145
image -> data = (void *)data;
146
image -> state = NULL;
147
image -> format = MLIB_FORMAT_UNKNOWN;
148
149
image -> paddings[0] = 0;
150
image -> paddings[1] = 0;
151
image -> paddings[2] = 0;
152
image -> paddings[3] = 0;
153
154
image -> bitoffset = 0;
155
156
if (width <= 0 || height <= 0 || channels < 1 || channels > 4) {
157
return NULL;
158
}
159
160
/* Check if stride == width
161
* If it is then image can be treated as a 1-D vector
162
*/
163
164
if (!SAFE_TO_MULT(width, channels)) {
165
return NULL;
166
}
167
168
wb = width * channels;
169
170
switch (type) {
171
case MLIB_DOUBLE:
172
if (!SAFE_TO_MULT(wb, 8)) {
173
return NULL;
174
}
175
wb *= 8;
176
mask = 7;
177
break;
178
case MLIB_FLOAT:
179
case MLIB_INT:
180
if (!SAFE_TO_MULT(wb, 4)) {
181
return NULL;
182
}
183
wb *= 4;
184
mask = 3;
185
break;
186
case MLIB_USHORT:
187
case MLIB_SHORT:
188
if (!SAFE_TO_MULT(wb, 2)) {
189
return NULL;
190
}
191
wb *= 2;
192
mask = 1;
193
break;
194
case MLIB_BYTE:
195
// wb is ready
196
mask = 0;
197
break;
198
case MLIB_BIT:
199
if (!SAFE_TO_ADD(7, wb)) {
200
return NULL;
201
}
202
wb = (wb + 7) / 8;
203
mask = 0;
204
break;
205
default:
206
return NULL;
207
}
208
209
if (stride & mask) {
210
return NULL;
211
}
212
213
image -> flags = ((width & 0xf) << 8); /* set width field */
214
image -> flags |= ((stride & 0xf) << 16); /* set stride field */
215
image -> flags |= ((height & 0xf) << 12); /* set height field */
216
image -> flags |= (mlib_addr)data & 0xff;
217
image -> flags |= MLIB_IMAGE_USERALLOCATED; /* user allocated data */
218
219
if ((stride != wb) ||
220
((type == MLIB_BIT) && (stride * 8 != width * channels))) {
221
image -> flags |= MLIB_IMAGE_ONEDVECTOR;
222
}
223
224
image -> flags &= MLIB_IMAGE_ATTRIBUTESET;
225
226
return image;
227
}
228
229
/***************************************************************/
230
JNIEXPORT
231
mlib_image* mlib_ImageCreateStruct(mlib_type type,
232
mlib_s32 channels,
233
mlib_s32 width,
234
mlib_s32 height,
235
mlib_s32 stride,
236
const void *data)
237
{
238
mlib_image *image;
239
if (stride <= 0) {
240
return NULL;
241
}
242
243
image = (mlib_image *)mlib_malloc(sizeof(mlib_image));
244
if (image == NULL) {
245
return NULL;
246
}
247
248
if (mlib_ImageSet(image, type, channels, width, height, stride, data) == NULL) {
249
mlib_free(image);
250
image = NULL;
251
}
252
253
return image;
254
}
255
256
/***************************************************************/
257
JNIEXPORT
258
mlib_image* mlib_ImageCreate(mlib_type type,
259
mlib_s32 channels,
260
mlib_s32 width,
261
mlib_s32 height)
262
{
263
mlib_image *image;
264
mlib_s32 wb; /* width in bytes */
265
void *data;
266
267
/* sanity check */
268
if (width <= 0 || height <= 0 || channels < 1 || channels > 4) {
269
return NULL;
270
};
271
272
if (!SAFE_TO_MULT(width, channels)) {
273
return NULL;
274
}
275
276
wb = width * channels;
277
278
switch (type) {
279
case MLIB_DOUBLE:
280
if (!SAFE_TO_MULT(wb, 8)) {
281
return NULL;
282
}
283
wb *= 8;
284
break;
285
case MLIB_FLOAT:
286
case MLIB_INT:
287
if (!SAFE_TO_MULT(wb, 4)) {
288
return NULL;
289
}
290
wb *= 4;
291
break;
292
case MLIB_USHORT:
293
case MLIB_SHORT:
294
if (!SAFE_TO_MULT(wb, 2)) {
295
return NULL;
296
}
297
wb *= 2;
298
break;
299
case MLIB_BYTE:
300
// wb is ready
301
break;
302
case MLIB_BIT:
303
if (!SAFE_TO_ADD(7, wb)) {
304
return NULL;
305
}
306
wb = (wb + 7) / 8;
307
break;
308
default:
309
return NULL;
310
}
311
312
if (!SAFE_TO_MULT(wb, height)) {
313
return NULL;
314
}
315
316
data = mlib_malloc(wb * height);
317
if (data == NULL) {
318
return NULL;
319
}
320
321
image = (mlib_image *)mlib_malloc(sizeof(mlib_image));
322
if (image == NULL) {
323
mlib_free(data);
324
return NULL;
325
};
326
327
image -> type = type;
328
image -> channels = channels;
329
image -> width = width;
330
image -> height = height;
331
image -> stride = wb;
332
image -> data = data;
333
image -> flags = ((width & 0xf) << 8); /* set width field */
334
image -> flags |= ((height & 0xf) << 12); /* set height field */
335
image -> flags |= ((wb & 0xf) << 16); /* set stride field */
336
image -> flags |= (mlib_addr)data & 0xff;
337
image -> format = MLIB_FORMAT_UNKNOWN;
338
339
image -> paddings[0] = 0;
340
image -> paddings[1] = 0;
341
image -> paddings[2] = 0;
342
image -> paddings[3] = 0;
343
344
image -> bitoffset = 0;
345
346
if ((type == MLIB_BIT) && (wb * 8 != width * channels)) {
347
image -> flags |= MLIB_IMAGE_ONEDVECTOR; /* not 1-d vector */
348
}
349
350
image -> flags &= MLIB_IMAGE_ATTRIBUTESET;
351
image -> state = NULL;
352
353
return image;
354
}
355
356
/***************************************************************/
357
JNIEXPORT
358
void mlib_ImageDelete(mlib_image *img)
359
{
360
if (img == NULL) return;
361
if ((img -> flags & MLIB_IMAGE_USERALLOCATED) == 0) {
362
mlib_free(img -> data);
363
}
364
365
mlib_ImageDeleteRowTable(img);
366
mlib_free(img);
367
}
368
369
/***************************************************************/
370
mlib_image *mlib_ImageCreateSubimage(mlib_image *img,
371
mlib_s32 x,
372
mlib_s32 y,
373
mlib_s32 w,
374
mlib_s32 h)
375
{
376
mlib_image *subimage;
377
mlib_type type;
378
mlib_s32 channels;
379
mlib_s32 width; /* for parent image */
380
mlib_s32 height; /* for parent image */
381
mlib_s32 stride;
382
mlib_s32 bitoffset = 0;
383
void *data;
384
385
/* sanity check */
386
if (w <= 0 || h <= 0 || img == NULL) return NULL;
387
388
type = img -> type;
389
channels = img -> channels;
390
width = img -> width;
391
height = img -> height;
392
stride = img -> stride;
393
394
/* clip the sub-image with respect to the parent image */
395
if (((x + w) <= 0) || ((y + h) <= 0) ||
396
(x >= width) || (y >= height)) {
397
return NULL;
398
}
399
else {
400
if (x < 0) {
401
w += x; /* x is negative */
402
x = 0;
403
}
404
405
if (y < 0) {
406
h += y; /* y is negative */
407
y = 0;
408
}
409
410
if ((x + w) > width) {
411
w = width - x;
412
}
413
414
if ((y + h) > height) {
415
h = height - y;
416
}
417
}
418
419
/* compute sub-image origin */
420
data = (mlib_u8 *)(img -> data) + y * stride;
421
422
switch (type) {
423
case MLIB_DOUBLE:
424
data = (mlib_u8 *)data + x * channels * 8;
425
break;
426
case MLIB_FLOAT:
427
case MLIB_INT:
428
data = (mlib_u8 *)data + x * channels * 4;
429
break;
430
case MLIB_USHORT:
431
case MLIB_SHORT:
432
data = (mlib_u8 *)data + x * channels * 2;
433
break;
434
case MLIB_BYTE:
435
data = (mlib_u8 *)data + x * channels;
436
break;
437
case MLIB_BIT:
438
bitoffset = img -> bitoffset;
439
data = (mlib_u8 *)data + (x * channels + bitoffset) / 8;
440
bitoffset = (x * channels + bitoffset) & 7;
441
break;
442
default:
443
return NULL;
444
}
445
446
subimage = mlib_ImageCreateStruct(type,
447
channels,
448
w,
449
h,
450
stride,
451
data);
452
453
if (subimage != NULL && type == MLIB_BIT)
454
subimage -> bitoffset = bitoffset;
455
456
return subimage;
457
}
458
459
/***************************************************************/
460
mlib_image *mlib_ImageSetSubimage(mlib_image *dst,
461
const mlib_image *src,
462
mlib_s32 x,
463
mlib_s32 y,
464
mlib_s32 w,
465
mlib_s32 h)
466
{
467
mlib_type type = src -> type;
468
mlib_s32 channels = src -> channels;
469
mlib_s32 stride = src -> stride;
470
mlib_u8 *data = src -> data;
471
mlib_s32 bitoffset = 0;
472
473
data += y * stride;
474
475
switch (type) {
476
case MLIB_DOUBLE:
477
data += channels * x * 8;
478
break;
479
case MLIB_FLOAT:
480
case MLIB_INT:
481
data += channels * x * 4;
482
break;
483
case MLIB_USHORT:
484
case MLIB_SHORT:
485
data += channels * x * 2;
486
break;
487
case MLIB_BYTE:
488
data += channels * x;
489
break;
490
case MLIB_BIT:
491
bitoffset = src -> bitoffset + channels * x;
492
data += (bitoffset >= 0) ? bitoffset/8 : (bitoffset - 7)/8; /* with rounding toward -Inf */
493
bitoffset &= 7;
494
break;
495
default:
496
return NULL;
497
}
498
499
if (h > 0) {
500
dst = mlib_ImageSet(dst, type, channels, w, h, stride, data);
501
} else {
502
h = - h;
503
dst = mlib_ImageSet(dst, type, channels, w, h, - stride, data + (h - 1)*stride);
504
}
505
506
if (dst != NULL && type == MLIB_BIT) {
507
dst -> bitoffset = bitoffset;
508
}
509
510
return dst;
511
}
512
513
/***************************************************************/
514
void *mlib_ImageCreateRowTable(mlib_image *img)
515
{
516
mlib_u8 **rtable, *tline;
517
mlib_s32 i, im_height, im_stride;
518
519
if (img == NULL) return NULL;
520
if (img -> state) return img -> state;
521
522
im_height = mlib_ImageGetHeight(img);
523
im_stride = mlib_ImageGetStride(img);
524
tline = mlib_ImageGetData(img);
525
if (tline == NULL) return NULL;
526
rtable = mlib_malloc((3 + im_height)*sizeof(mlib_u8 *));
527
if (rtable == NULL) return NULL;
528
529
rtable[0] = 0;
530
rtable[1] = (mlib_u8*)((void **)rtable + 1);
531
rtable[2 + im_height] = (mlib_u8*)((void **)rtable + 1);
532
for (i = 0; i < im_height; i++) {
533
rtable[i+2] = tline;
534
tline += im_stride;
535
}
536
537
img -> state = ((void **)rtable + 2);
538
return img -> state;
539
}
540
541
/***************************************************************/
542
void mlib_ImageDeleteRowTable(mlib_image *img)
543
{
544
void **state;
545
546
if (img == NULL) return;
547
548
state = img -> state;
549
if (!state) return;
550
551
mlib_free(state - 2);
552
img -> state = 0;
553
}
554
555
/***************************************************************/
556
mlib_status mlib_ImageSetPaddings(mlib_image *img,
557
mlib_u8 left,
558
mlib_u8 top,
559
mlib_u8 right,
560
mlib_u8 bottom)
561
{
562
if (img == NULL) return MLIB_FAILURE;
563
564
if ((left + right) >= img -> width ||
565
(top + bottom) >= img -> height) return MLIB_OUTOFRANGE;
566
567
img -> paddings[0] = left;
568
img -> paddings[1] = top;
569
img -> paddings[2] = right;
570
img -> paddings[3] = bottom;
571
572
return MLIB_SUCCESS;
573
}
574
575
/***************************************************************/
576
mlib_status mlib_ImageSetFormat(mlib_image *img,
577
mlib_format format)
578
{
579
if (img == NULL) return MLIB_FAILURE;
580
581
img -> format = format;
582
583
return MLIB_SUCCESS;
584
}
585
586
/***************************************************************/
587
588