Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/native/libmlib_image/mlib_ImageAffine.c
41152 views
1
/*
2
* Copyright (c) 2003, 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_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_ImageAffine.h"
77
78
79
/***************************************************************/
80
#define BUFF_SIZE 600
81
82
/***************************************************************/
83
const type_affine_fun mlib_AffineFunArr_nn[] = {
84
mlib_ImageAffine_u8_1ch_nn, mlib_ImageAffine_u8_2ch_nn,
85
mlib_ImageAffine_u8_3ch_nn, mlib_ImageAffine_u8_4ch_nn,
86
mlib_ImageAffine_s16_1ch_nn, mlib_ImageAffine_s16_2ch_nn,
87
mlib_ImageAffine_s16_3ch_nn, mlib_ImageAffine_s16_4ch_nn,
88
mlib_ImageAffine_s32_1ch_nn, mlib_ImageAffine_s32_2ch_nn,
89
mlib_ImageAffine_s32_3ch_nn, mlib_ImageAffine_s32_4ch_nn,
90
mlib_ImageAffine_d64_1ch_nn, mlib_ImageAffine_d64_2ch_nn,
91
mlib_ImageAffine_d64_3ch_nn, mlib_ImageAffine_d64_4ch_nn,
92
};
93
94
/***************************************************************/
95
const type_affine_fun mlib_AffineFunArr_bl[] = {
96
mlib_ImageAffine_u8_1ch_bl, mlib_ImageAffine_u8_2ch_bl,
97
mlib_ImageAffine_u8_3ch_bl, mlib_ImageAffine_u8_4ch_bl,
98
mlib_ImageAffine_s16_1ch_bl, mlib_ImageAffine_s16_2ch_bl,
99
mlib_ImageAffine_s16_3ch_bl, mlib_ImageAffine_s16_4ch_bl,
100
mlib_ImageAffine_s32_1ch_bl, mlib_ImageAffine_s32_2ch_bl,
101
mlib_ImageAffine_s32_3ch_bl, mlib_ImageAffine_s32_4ch_bl,
102
mlib_ImageAffine_u16_1ch_bl, mlib_ImageAffine_u16_2ch_bl,
103
mlib_ImageAffine_u16_3ch_bl, mlib_ImageAffine_u16_4ch_bl,
104
mlib_ImageAffine_f32_1ch_bl, mlib_ImageAffine_f32_2ch_bl,
105
mlib_ImageAffine_f32_3ch_bl, mlib_ImageAffine_f32_4ch_bl,
106
mlib_ImageAffine_d64_1ch_bl, mlib_ImageAffine_d64_2ch_bl,
107
mlib_ImageAffine_d64_3ch_bl, mlib_ImageAffine_d64_4ch_bl
108
};
109
110
/***************************************************************/
111
const type_affine_fun mlib_AffineFunArr_bc[] = {
112
mlib_ImageAffine_u8_1ch_bc, mlib_ImageAffine_u8_2ch_bc,
113
mlib_ImageAffine_u8_3ch_bc, mlib_ImageAffine_u8_4ch_bc,
114
mlib_ImageAffine_s16_1ch_bc, mlib_ImageAffine_s16_2ch_bc,
115
mlib_ImageAffine_s16_3ch_bc, mlib_ImageAffine_s16_4ch_bc,
116
mlib_ImageAffine_s32_1ch_bc, mlib_ImageAffine_s32_2ch_bc,
117
mlib_ImageAffine_s32_3ch_bc, mlib_ImageAffine_s32_4ch_bc,
118
mlib_ImageAffine_u16_1ch_bc, mlib_ImageAffine_u16_2ch_bc,
119
mlib_ImageAffine_u16_3ch_bc, mlib_ImageAffine_u16_4ch_bc,
120
mlib_ImageAffine_f32_1ch_bc, mlib_ImageAffine_f32_2ch_bc,
121
mlib_ImageAffine_f32_3ch_bc, mlib_ImageAffine_f32_4ch_bc,
122
mlib_ImageAffine_d64_1ch_bc, mlib_ImageAffine_d64_2ch_bc,
123
mlib_ImageAffine_d64_3ch_bc, mlib_ImageAffine_d64_4ch_bc
124
};
125
126
/***************************************************************/
127
#ifdef i386 /* do not perform the coping by mlib_d64 data type for x86 */
128
#define MAX_T_IND 2
129
#else
130
#define MAX_T_IND 3
131
#endif /* i386 ( do not perform the coping by mlib_d64 data type for x86 ) */
132
133
/***************************************************************/
134
mlib_status mlib_ImageAffine_alltypes(mlib_image *dst,
135
const mlib_image *src,
136
const mlib_d64 *mtx,
137
mlib_filter filter,
138
mlib_edge edge)
139
{
140
mlib_affine_param param[1];
141
mlib_status res;
142
mlib_type type;
143
mlib_s32 nchan, t_ind, kw, kw1;
144
mlib_addr align;
145
mlib_d64 buff_lcl[BUFF_SIZE / 8];
146
mlib_u8 **lineAddr = NULL;
147
148
/* check for obvious errors */
149
MLIB_IMAGE_TYPE_EQUAL(src, dst);
150
MLIB_IMAGE_CHAN_EQUAL(src, dst);
151
152
type = mlib_ImageGetType(dst);
153
nchan = mlib_ImageGetChannels(dst);
154
155
switch (filter) {
156
case MLIB_NEAREST:
157
kw = 1;
158
kw1 = 0;
159
break;
160
161
case MLIB_BILINEAR:
162
kw = 2;
163
kw1 = 0;
164
break;
165
166
case MLIB_BICUBIC:
167
case MLIB_BICUBIC2:
168
kw = 4;
169
kw1 = 1;
170
break;
171
172
default:
173
return MLIB_FAILURE;
174
}
175
176
STORE_PARAM(param, lineAddr);
177
STORE_PARAM(param, filter);
178
179
res = mlib_AffineEdges(param, dst, src, buff_lcl, BUFF_SIZE,
180
kw, kw, kw1, kw1, edge, mtx, MLIB_SHIFT, MLIB_SHIFT);
181
182
if (res != MLIB_SUCCESS)
183
return res;
184
185
lineAddr = param->lineAddr;
186
187
if (type == MLIB_BYTE)
188
t_ind = 0;
189
else if (type == MLIB_SHORT)
190
t_ind = 1;
191
else if (type == MLIB_INT)
192
t_ind = 2;
193
else if (type == MLIB_USHORT)
194
t_ind = 3;
195
else if (type == MLIB_FLOAT)
196
t_ind = 4;
197
else if (type == MLIB_DOUBLE)
198
t_ind = 5;
199
else
200
return MLIB_FAILURE; /* unknown image type */
201
202
if (type == MLIB_BIT) {
203
mlib_s32 s_bitoff = mlib_ImageGetBitOffset(src);
204
mlib_s32 d_bitoff = mlib_ImageGetBitOffset(dst);
205
206
if (nchan != 1 || filter != MLIB_NEAREST)
207
return MLIB_FAILURE;
208
mlib_ImageAffine_bit_1ch_nn(param, s_bitoff, d_bitoff);
209
}
210
else {
211
switch (filter) {
212
case MLIB_NEAREST:
213
214
if (t_ind >= 3)
215
t_ind -= 2; /* correct types USHORT, FLOAT, DOUBLE; new values: 1, 2, 3 */
216
217
/* two channels as one channel of next type */
218
align = (mlib_addr) (param->dstData) | (mlib_addr) lineAddr[0];
219
align |= param->dstYStride | param->srcYStride;
220
while (((nchan | (align >> t_ind)) & 1) == 0 && t_ind < MAX_T_IND) {
221
nchan >>= 1;
222
t_ind++;
223
}
224
225
res = mlib_AffineFunArr_nn[4 * t_ind + (nchan - 1)] (param);
226
break;
227
228
case MLIB_BILINEAR:
229
230
res = mlib_AffineFunArr_bl[4 * t_ind + (nchan - 1)] (param);
231
break;
232
233
case MLIB_BICUBIC:
234
case MLIB_BICUBIC2:
235
236
res = mlib_AffineFunArr_bc[4 * t_ind + (nchan - 1)] (param);
237
break;
238
}
239
240
if (res != MLIB_SUCCESS) {
241
if (param->buff_malloc != NULL)
242
mlib_free(param->buff_malloc);
243
return res;
244
}
245
}
246
247
if (edge == MLIB_EDGE_SRC_PADDED)
248
edge = MLIB_EDGE_DST_NO_WRITE;
249
250
if (filter != MLIB_NEAREST && edge != MLIB_EDGE_DST_NO_WRITE) {
251
mlib_affine_param param_e[1];
252
mlib_d64 buff_lcl1[BUFF_SIZE / 8];
253
254
STORE_PARAM(param_e, lineAddr);
255
STORE_PARAM(param_e, filter);
256
257
res = mlib_AffineEdges(param_e, dst, src, buff_lcl1, BUFF_SIZE,
258
kw, kw, kw1, kw1, -1, mtx, MLIB_SHIFT, MLIB_SHIFT);
259
260
if (res != MLIB_SUCCESS) {
261
if (param->buff_malloc != NULL)
262
mlib_free(param->buff_malloc);
263
return res;
264
}
265
266
switch (edge) {
267
case MLIB_EDGE_DST_FILL_ZERO:
268
mlib_ImageAffineEdgeZero(param, param_e);
269
break;
270
271
case MLIB_EDGE_OP_NEAREST:
272
mlib_ImageAffineEdgeNearest(param, param_e);
273
break;
274
275
case MLIB_EDGE_SRC_EXTEND:
276
277
if (filter == MLIB_BILINEAR) {
278
res = mlib_ImageAffineEdgeExtend_BL(param, param_e);
279
}
280
else {
281
res = mlib_ImageAffineEdgeExtend_BC(param, param_e);
282
}
283
284
break;
285
286
default:
287
/* nothing to do for other edge types. */
288
break;
289
}
290
291
if (param_e->buff_malloc != NULL)
292
mlib_free(param_e->buff_malloc);
293
}
294
295
if (param->buff_malloc != NULL)
296
mlib_free(param->buff_malloc);
297
298
return res;
299
}
300
301
/***************************************************************/
302
JNIEXPORT
303
mlib_status mlib_ImageAffine(mlib_image *dst,
304
const mlib_image *src,
305
const mlib_d64 *mtx,
306
mlib_filter filter,
307
mlib_edge edge)
308
{
309
mlib_type type;
310
311
MLIB_IMAGE_CHECK(src);
312
MLIB_IMAGE_CHECK(dst);
313
314
type = mlib_ImageGetType(dst);
315
316
if (type != MLIB_BIT && type != MLIB_BYTE &&
317
type != MLIB_SHORT && type != MLIB_USHORT && type != MLIB_INT) {
318
return MLIB_FAILURE;
319
}
320
321
return mlib_ImageAffine_alltypes(dst, src, mtx, filter, edge);
322
}
323
324
/***************************************************************/
325
326