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/medialib/mlib_ImageAffine.c
38918 views
1
/*
2
* Copyright (c) 2003, 2011, 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_ImageAffine - image affine transformation with edge condition
30
*
31
* SYNOPSIS
32
* mlib_status mlib_ImageAffine(mlib_image *dst,
33
* const mlib_image *src,
34
* const mlib_d64 *mtx,
35
* mlib_filter filter,
36
* mlib_edge edge)
37
*
38
* ARGUMENTS
39
* dst Pointer to destination image
40
* src Pointer to source image
41
* mtx Transformation matrix, where
42
* mtx[0] holds a; mtx[1] holds b;
43
* mtx[2] holds tx; mtx[3] holds c;
44
* mtx[4] holds d; mtx[5] holds ty.
45
* filter Type of resampling filter.
46
* edge Type of edge condition.
47
*
48
* DESCRIPTION
49
* xd = a*xs + b*ys + tx
50
* yd = c*xs + d*ys + ty
51
*
52
* The upper-left corner pixel of an image is located at (0.5, 0.5).
53
*
54
* The resampling filter can be one of the following:
55
* MLIB_NEAREST
56
* MLIB_BILINEAR
57
* MLIB_BICUBIC
58
* MLIB_BICUBIC2
59
*
60
* The edge condition can be one of the following:
61
* MLIB_EDGE_DST_NO_WRITE (default)
62
* MLIB_EDGE_DST_FILL_ZERO
63
* MLIB_EDGE_OP_NEAREST
64
* MLIB_EDGE_SRC_EXTEND
65
* MLIB_EDGE_SRC_PADDED
66
*
67
* RESTRICTION
68
* src and dst must be the same type and the same number of channels.
69
* They can have 1, 2, 3 or 4 channels. They can be in MLIB_BIT, MLIB_BYTE,
70
* MLIB_SHORT, MLIB_USHORT or MLIB_INT data type.
71
*
72
* src image can not have width or height larger than 32767.
73
*/
74
75
#include "mlib_ImageCheck.h"
76
#include "mlib_ImageColormap.h"
77
#include "mlib_ImageAffine.h"
78
79
80
/***************************************************************/
81
#define BUFF_SIZE 600
82
83
/***************************************************************/
84
const type_affine_fun mlib_AffineFunArr_nn[] = {
85
mlib_ImageAffine_u8_1ch_nn, mlib_ImageAffine_u8_2ch_nn,
86
mlib_ImageAffine_u8_3ch_nn, mlib_ImageAffine_u8_4ch_nn,
87
mlib_ImageAffine_s16_1ch_nn, mlib_ImageAffine_s16_2ch_nn,
88
mlib_ImageAffine_s16_3ch_nn, mlib_ImageAffine_s16_4ch_nn,
89
mlib_ImageAffine_s32_1ch_nn, mlib_ImageAffine_s32_2ch_nn,
90
mlib_ImageAffine_s32_3ch_nn, mlib_ImageAffine_s32_4ch_nn,
91
mlib_ImageAffine_d64_1ch_nn, mlib_ImageAffine_d64_2ch_nn,
92
mlib_ImageAffine_d64_3ch_nn, mlib_ImageAffine_d64_4ch_nn,
93
};
94
95
/***************************************************************/
96
const type_affine_fun mlib_AffineFunArr_bl[] = {
97
mlib_ImageAffine_u8_1ch_bl, mlib_ImageAffine_u8_2ch_bl,
98
mlib_ImageAffine_u8_3ch_bl, mlib_ImageAffine_u8_4ch_bl,
99
mlib_ImageAffine_s16_1ch_bl, mlib_ImageAffine_s16_2ch_bl,
100
mlib_ImageAffine_s16_3ch_bl, mlib_ImageAffine_s16_4ch_bl,
101
mlib_ImageAffine_s32_1ch_bl, mlib_ImageAffine_s32_2ch_bl,
102
mlib_ImageAffine_s32_3ch_bl, mlib_ImageAffine_s32_4ch_bl,
103
mlib_ImageAffine_u16_1ch_bl, mlib_ImageAffine_u16_2ch_bl,
104
mlib_ImageAffine_u16_3ch_bl, mlib_ImageAffine_u16_4ch_bl,
105
mlib_ImageAffine_f32_1ch_bl, mlib_ImageAffine_f32_2ch_bl,
106
mlib_ImageAffine_f32_3ch_bl, mlib_ImageAffine_f32_4ch_bl,
107
mlib_ImageAffine_d64_1ch_bl, mlib_ImageAffine_d64_2ch_bl,
108
mlib_ImageAffine_d64_3ch_bl, mlib_ImageAffine_d64_4ch_bl
109
};
110
111
/***************************************************************/
112
const type_affine_fun mlib_AffineFunArr_bc[] = {
113
mlib_ImageAffine_u8_1ch_bc, mlib_ImageAffine_u8_2ch_bc,
114
mlib_ImageAffine_u8_3ch_bc, mlib_ImageAffine_u8_4ch_bc,
115
mlib_ImageAffine_s16_1ch_bc, mlib_ImageAffine_s16_2ch_bc,
116
mlib_ImageAffine_s16_3ch_bc, mlib_ImageAffine_s16_4ch_bc,
117
mlib_ImageAffine_s32_1ch_bc, mlib_ImageAffine_s32_2ch_bc,
118
mlib_ImageAffine_s32_3ch_bc, mlib_ImageAffine_s32_4ch_bc,
119
mlib_ImageAffine_u16_1ch_bc, mlib_ImageAffine_u16_2ch_bc,
120
mlib_ImageAffine_u16_3ch_bc, mlib_ImageAffine_u16_4ch_bc,
121
mlib_ImageAffine_f32_1ch_bc, mlib_ImageAffine_f32_2ch_bc,
122
mlib_ImageAffine_f32_3ch_bc, mlib_ImageAffine_f32_4ch_bc,
123
mlib_ImageAffine_d64_1ch_bc, mlib_ImageAffine_d64_2ch_bc,
124
mlib_ImageAffine_d64_3ch_bc, mlib_ImageAffine_d64_4ch_bc
125
};
126
127
/***************************************************************/
128
const type_affine_i_fun mlib_AffineFunArr_bc_i[] = {
129
mlib_ImageAffineIndex_U8_U8_3CH_BC,
130
mlib_ImageAffineIndex_U8_U8_4CH_BC,
131
mlib_ImageAffineIndex_S16_U8_3CH_BC,
132
mlib_ImageAffineIndex_S16_U8_4CH_BC,
133
mlib_ImageAffineIndex_U8_S16_3CH_BC,
134
mlib_ImageAffineIndex_U8_S16_4CH_BC,
135
mlib_ImageAffineIndex_S16_S16_3CH_BC,
136
mlib_ImageAffineIndex_S16_S16_4CH_BC
137
};
138
139
/***************************************************************/
140
#ifdef i386 /* do not perform the coping by mlib_d64 data type for x86 */
141
#define MAX_T_IND 2
142
#else
143
#define MAX_T_IND 3
144
#endif /* i386 ( do not perform the coping by mlib_d64 data type for x86 ) */
145
146
/***************************************************************/
147
mlib_status mlib_ImageAffine_alltypes(mlib_image *dst,
148
const mlib_image *src,
149
const mlib_d64 *mtx,
150
mlib_filter filter,
151
mlib_edge edge,
152
const void *colormap)
153
{
154
mlib_affine_param param[1];
155
mlib_status res;
156
mlib_type type;
157
mlib_s32 nchan, t_ind, kw, kw1;
158
mlib_addr align;
159
mlib_d64 buff_lcl[BUFF_SIZE / 8];
160
mlib_u8 **lineAddr = NULL;
161
162
/* check for obvious errors */
163
MLIB_IMAGE_TYPE_EQUAL(src, dst);
164
MLIB_IMAGE_CHAN_EQUAL(src, dst);
165
166
type = mlib_ImageGetType(dst);
167
nchan = mlib_ImageGetChannels(dst);
168
169
switch (filter) {
170
case MLIB_NEAREST:
171
kw = 1;
172
kw1 = 0;
173
break;
174
175
case MLIB_BILINEAR:
176
kw = 2;
177
kw1 = 0;
178
break;
179
180
case MLIB_BICUBIC:
181
case MLIB_BICUBIC2:
182
kw = 4;
183
kw1 = 1;
184
break;
185
186
default:
187
return MLIB_FAILURE;
188
}
189
190
STORE_PARAM(param, lineAddr);
191
STORE_PARAM(param, filter);
192
193
res = mlib_AffineEdges(param, dst, src, buff_lcl, BUFF_SIZE,
194
kw, kw, kw1, kw1, edge, mtx, MLIB_SHIFT, MLIB_SHIFT);
195
196
if (res != MLIB_SUCCESS)
197
return res;
198
199
lineAddr = param->lineAddr;
200
201
if (type == MLIB_BYTE)
202
t_ind = 0;
203
else if (type == MLIB_SHORT)
204
t_ind = 1;
205
else if (type == MLIB_INT)
206
t_ind = 2;
207
else if (type == MLIB_USHORT)
208
t_ind = 3;
209
else if (type == MLIB_FLOAT)
210
t_ind = 4;
211
else if (type == MLIB_DOUBLE)
212
t_ind = 5;
213
else
214
return MLIB_FAILURE; /* unknown image type */
215
216
if (colormap != NULL && filter != MLIB_NEAREST) {
217
if (t_ind != 0 && t_ind != 1)
218
return MLIB_FAILURE;
219
220
if (mlib_ImageGetLutType(colormap) == MLIB_SHORT)
221
t_ind += 2;
222
t_ind = 2 * t_ind;
223
224
if (mlib_ImageGetLutChannels(colormap) == 4)
225
t_ind++;
226
}
227
228
if (type == MLIB_BIT) {
229
mlib_s32 s_bitoff = mlib_ImageGetBitOffset(src);
230
mlib_s32 d_bitoff = mlib_ImageGetBitOffset(dst);
231
232
if (nchan != 1 || filter != MLIB_NEAREST)
233
return MLIB_FAILURE;
234
mlib_ImageAffine_bit_1ch_nn(param, s_bitoff, d_bitoff);
235
}
236
else {
237
switch (filter) {
238
case MLIB_NEAREST:
239
240
if (t_ind >= 3)
241
t_ind -= 2; /* correct types USHORT, FLOAT, DOUBLE; new values: 1, 2, 3 */
242
243
/* two channels as one channel of next type */
244
align = (mlib_addr) (param->dstData) | (mlib_addr) lineAddr[0];
245
align |= param->dstYStride | param->srcYStride;
246
while (((nchan | (align >> t_ind)) & 1) == 0 && t_ind < MAX_T_IND) {
247
nchan >>= 1;
248
t_ind++;
249
}
250
251
res = mlib_AffineFunArr_nn[4 * t_ind + (nchan - 1)] (param);
252
break;
253
254
case MLIB_BILINEAR:
255
256
if (colormap != NULL) {
257
res = mlib_AffineFunArr_bl_i[t_ind] (param, colormap);
258
}
259
else {
260
res = mlib_AffineFunArr_bl[4 * t_ind + (nchan - 1)] (param);
261
}
262
263
break;
264
265
case MLIB_BICUBIC:
266
case MLIB_BICUBIC2:
267
268
if (colormap != NULL) {
269
res = mlib_AffineFunArr_bc_i[t_ind] (param, colormap);
270
}
271
else {
272
res = mlib_AffineFunArr_bc[4 * t_ind + (nchan - 1)] (param);
273
}
274
275
break;
276
}
277
278
if (res != MLIB_SUCCESS) {
279
if (param->buff_malloc != NULL)
280
mlib_free(param->buff_malloc);
281
return res;
282
}
283
}
284
285
if (edge == MLIB_EDGE_SRC_PADDED)
286
edge = MLIB_EDGE_DST_NO_WRITE;
287
288
if (filter != MLIB_NEAREST && edge != MLIB_EDGE_DST_NO_WRITE) {
289
mlib_affine_param param_e[1];
290
mlib_d64 buff_lcl1[BUFF_SIZE / 8];
291
292
STORE_PARAM(param_e, lineAddr);
293
STORE_PARAM(param_e, filter);
294
295
res = mlib_AffineEdges(param_e, dst, src, buff_lcl1, BUFF_SIZE,
296
kw, kw, kw1, kw1, -1, mtx, MLIB_SHIFT, MLIB_SHIFT);
297
298
if (res != MLIB_SUCCESS) {
299
if (param->buff_malloc != NULL)
300
mlib_free(param->buff_malloc);
301
return res;
302
}
303
304
switch (edge) {
305
case MLIB_EDGE_DST_FILL_ZERO:
306
mlib_ImageAffineEdgeZero(param, param_e, colormap);
307
break;
308
309
case MLIB_EDGE_OP_NEAREST:
310
mlib_ImageAffineEdgeNearest(param, param_e);
311
break;
312
313
case MLIB_EDGE_SRC_EXTEND:
314
315
if (filter == MLIB_BILINEAR) {
316
res = mlib_ImageAffineEdgeExtend_BL(param, param_e, colormap);
317
}
318
else {
319
res = mlib_ImageAffineEdgeExtend_BC(param, param_e, colormap);
320
}
321
322
break;
323
324
default:
325
/* nothing to do for other edge types. */
326
break;
327
}
328
329
if (param_e->buff_malloc != NULL)
330
mlib_free(param_e->buff_malloc);
331
}
332
333
if (param->buff_malloc != NULL)
334
mlib_free(param->buff_malloc);
335
336
return res;
337
}
338
339
/***************************************************************/
340
mlib_status mlib_ImageAffine(mlib_image *dst,
341
const mlib_image *src,
342
const mlib_d64 *mtx,
343
mlib_filter filter,
344
mlib_edge edge)
345
{
346
mlib_type type;
347
348
MLIB_IMAGE_CHECK(src);
349
MLIB_IMAGE_CHECK(dst);
350
351
type = mlib_ImageGetType(dst);
352
353
if (type != MLIB_BIT && type != MLIB_BYTE &&
354
type != MLIB_SHORT && type != MLIB_USHORT && type != MLIB_INT) {
355
return MLIB_FAILURE;
356
}
357
358
return mlib_ImageAffine_alltypes(dst, src, mtx, filter, edge, NULL);
359
}
360
361
/***************************************************************/
362
363