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_ImageAffineEdge.c
38918 views
1
/*
2
* Copyright (c) 1998, 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_ImageAffineEdgeZero - implementation of MLIB_EDGE_DST_FILL_ZERO
30
* edge condition
31
* mlib_ImageAffineEdgeNearest - implementation of MLIB_EDGE_OP_NEAREST
32
* edge condition
33
* void mlib_ImageAffineEdgeExtend_BL - implementation of MLIB_EDGE_SRC_EXTEND
34
* edge condition for MLIB_BILINEAR filter
35
* void mlib_ImageAffineEdgeExtend_BC - implementation of MLIB_EDGE_SRC_EXTEND
36
* edge condition for MLIB_BICUBIC filter
37
* void mlib_ImageAffineEdgeExtend_BC2 - implementation of MLIB_EDGE_SRC_EXTEND
38
* edge condition for MLIB_BICUBIC2 filter
39
*
40
* DESCRIPTION
41
* mlib_ImageAffineEdgeZero:
42
* This function fills the edge pixels (i.e. thouse one which can not
43
* be interpolated with given resampling filter because their prototypes
44
* in the source image lie too close to the border) in the destination
45
* image with zeroes.
46
*
47
* mlib_ImageAffineEdgeNearest:
48
* This function fills the edge pixels (i.e. thouse one which can not
49
* be interpolated with given resampling filter because their prototypes
50
* in the source image lie too close to the border) in the destination
51
* image according to the nearest neighbour interpolation.
52
*
53
* mlib_ImageAffineEdgeExtend_BL:
54
* This function fills the edge pixels (i.e. thouse one which can not
55
* be interpolated with given resampling filter because their prototypes
56
* in the source image lie too close to the border) in the destination
57
* image according to the bilinear interpolation with border pixels extend
58
* of source image.
59
*
60
* mlib_ImageAffineEdgeExtend_BC:
61
* This function fills the edge pixels (i.e. thouse one which can not
62
* be interpolated with given resampling filter because their prototypes
63
* in the source image lie too close to the border) in the destination
64
* image according to the bicubic interpolation with border pixels extend
65
* of source image.
66
*
67
* mlib_ImageAffineEdgeExtend_BC2:
68
* This function fills the edge pixels (i.e. thouse one which can not
69
* be interpolated with given resampling filter because their prototypes
70
* in the source image lie too close to the border) in the destination
71
* image according to the bicubic2 interpolation with border pixels extend
72
* of source image.
73
*/
74
75
#include "mlib_image.h"
76
#include "mlib_ImageColormap.h"
77
#include "mlib_ImageAffine.h"
78
79
/***************************************************************/
80
#define FLT_SHIFT_U8 4
81
#define FLT_MASK_U8 (((1 << 8) - 1) << 4)
82
#define FLT_SHIFT_S16 3
83
#define FLT_MASK_S16 (((1 << 9) - 1) << 4)
84
85
#define MLIB_SIGN_SHIFT 31
86
87
/***************************************************************/
88
#define D64mlib_u8(X) mlib_U82D64[X]
89
#define D64mlib_s16(X) ((mlib_d64)(X))
90
#define D64mlib_u16(X) ((mlib_d64)(X))
91
#define D64mlib_s32(X) ((mlib_d64)(X))
92
#define D64mlib_f32(X) ((mlib_d64)(X))
93
#define D64mlib_d64(X) ((mlib_d64)(X))
94
95
/***************************************************************/
96
#ifdef MLIB_USE_FTOI_CLAMPING
97
98
#define SATmlib_u8(DST, val0) \
99
DST = ((mlib_s32)(val0 - sat) >> 24) ^ 0x80
100
101
#define SATmlib_s16(DST, val0) \
102
DST = ((mlib_s32)val0) >> 16
103
104
#define SATmlib_u16(DST, val0) \
105
DST = ((mlib_s32)(val0 - sat) >> 16) ^ 0x8000
106
107
#define SATmlib_s32(DST, val0) \
108
DST = val0
109
110
#else
111
112
#define SATmlib_u8(DST, val0) \
113
val0 -= sat; \
114
if (val0 >= MLIB_S32_MAX) \
115
val0 = MLIB_S32_MAX; \
116
if (val0 <= MLIB_S32_MIN) \
117
val0 = MLIB_S32_MIN; \
118
DST = ((mlib_s32) val0 >> 24) ^ 0x80
119
120
#define SATmlib_s16(DST, val0) \
121
if (val0 >= MLIB_S32_MAX) \
122
val0 = MLIB_S32_MAX; \
123
if (val0 <= MLIB_S32_MIN) \
124
val0 = MLIB_S32_MIN; \
125
DST = (mlib_s32)val0 >> 16
126
127
#define SATmlib_u16(DST, val0) \
128
val0 -= sat; \
129
if (val0 >= MLIB_S32_MAX) \
130
val0 = MLIB_S32_MAX; \
131
if (val0 <= MLIB_S32_MIN) \
132
val0 = MLIB_S32_MIN; \
133
DST = ((mlib_s32)val0 >> 16) ^ 0x8000
134
135
#define SATmlib_s32(DST, val0) \
136
if (val0 >= MLIB_S32_MAX) \
137
val0 = MLIB_S32_MAX; \
138
if (val0 <= MLIB_S32_MIN) \
139
val0 = MLIB_S32_MIN; \
140
DST = (mlib_s32)val0
141
142
#endif
143
144
/***************************************************************/
145
#define SATmlib_f32(DST, val0) \
146
DST = (mlib_f32)val0
147
148
/***************************************************************/
149
#define SATmlib_d64(DST, val0) \
150
DST = val0
151
152
/***************************************************************/
153
#define MLIB_EDGE_ZERO_LINE(TYPE, Left, Right) \
154
dp = (TYPE*)data + channels * Left; \
155
dstLineEnd = (TYPE*)data + channels * Right; \
156
\
157
for (; dp < dstLineEnd; dp++) { \
158
*dp = zero; \
159
}
160
161
/***************************************************************/
162
#define MLIB_EDGE_NEAREST_LINE(TYPE, Left, Right) \
163
dp = (TYPE*)data + channels * Left; \
164
size = Right - Left; \
165
\
166
for (j = 0; j < size; j++) { \
167
ySrc = Y >> MLIB_SHIFT; \
168
xSrc = X >> MLIB_SHIFT; \
169
sp = (TYPE*)lineAddr[ySrc] + xSrc * channels; \
170
\
171
for (k = 0; k < channels; k++) dp[k] = sp[k]; \
172
\
173
Y += dY; \
174
X += dX; \
175
dp += channels; \
176
}
177
178
/***************************************************************/
179
#define MLIB_EDGE_BL(TYPE, Left, Right) \
180
dp = (TYPE*)data + channels * Left; \
181
size = Right - Left; \
182
\
183
for (j = 0; j < size; j++) { \
184
ySrc = ((Y - 32768) >> MLIB_SHIFT); \
185
xSrc = ((X - 32768) >> MLIB_SHIFT); \
186
\
187
t = ((X - 32768) & MLIB_MASK) * scale; \
188
u = ((Y - 32768) & MLIB_MASK) * scale; \
189
\
190
xDelta = (((xSrc + 1 - srcWidth )) >> MLIB_SIGN_SHIFT) & channels; \
191
yDelta = (((ySrc + 1 - srcHeight)) >> MLIB_SIGN_SHIFT) & srcStride; \
192
\
193
xFlag = (xSrc >> (MLIB_SIGN_SHIFT - MLIB_SHIFT)); \
194
xSrc = xSrc + (1 & xFlag); \
195
xDelta = xDelta &~ xFlag; \
196
\
197
yFlag = (ySrc >> (MLIB_SIGN_SHIFT - MLIB_SHIFT)); \
198
ySrc = ySrc + (1 & yFlag); \
199
yDelta = yDelta &~ yFlag; \
200
\
201
sp = (TYPE*)lineAddr[ySrc] + xSrc * channels; \
202
\
203
for (k = 0; k < channels; k++) { \
204
a00 = D64##TYPE(sp[0]); \
205
a01 = D64##TYPE(sp[xDelta]); \
206
a10 = D64##TYPE(sp[yDelta]); \
207
a11 = D64##TYPE(sp[yDelta + xDelta]); \
208
pix0 = (a00 * (1 - t) + a01 * t) * (1 - u) + \
209
(a10 * (1 - t) + a11 * t) * u; \
210
\
211
dp[k] = (TYPE)pix0; \
212
sp++; \
213
} \
214
\
215
X += dX; \
216
Y += dY; \
217
dp += channels; \
218
}
219
220
/***************************************************************/
221
#define LUT(k, ind) plut[channels*sp[ind] + k]
222
223
/***************************************************************/
224
#define MLIB_EDGE_INDEX(ITYPE, DTYPE, size) \
225
for (j = 0; j < size; j++) { \
226
ySrc = ((Y - 32768) >> MLIB_SHIFT); \
227
xSrc = ((X - 32768) >> MLIB_SHIFT); \
228
\
229
t = ((X - 32768) & MLIB_MASK) * scale; \
230
u = ((Y - 32768) & MLIB_MASK) * scale; \
231
\
232
xDelta = (((xSrc + 1 - srcWidth )) >> MLIB_SIGN_SHIFT) & 1; \
233
yDelta = (((ySrc + 1 - srcHeight)) >> MLIB_SIGN_SHIFT) & srcStride; \
234
\
235
xFlag = (xSrc >> (MLIB_SIGN_SHIFT - MLIB_SHIFT)); \
236
xSrc = xSrc + (1 & xFlag); \
237
xDelta = xDelta &~ xFlag; \
238
\
239
yFlag = (ySrc >> (MLIB_SIGN_SHIFT - MLIB_SHIFT)); \
240
ySrc = ySrc + (1 & yFlag); \
241
yDelta = yDelta &~ yFlag; \
242
\
243
sp = (ITYPE*)lineAddr[ySrc] + xSrc; \
244
\
245
for (k = 0; k < channels; k++) { \
246
a00 = LUT(k, 0); \
247
a01 = LUT(k, xDelta); \
248
a10 = LUT(k, yDelta); \
249
a11 = LUT(k, yDelta + xDelta); \
250
pix0 = (a00 * (1 - t) + a01 * t) * (1 - u) + \
251
(a10 * (1 - t) + a11 * t) * u; \
252
\
253
pbuff[k] = (mlib_s32)pix0; \
254
} \
255
pbuff += channels; \
256
\
257
X += dX; \
258
Y += dY; \
259
}
260
261
/***************************************************************/
262
#define MLIB_EDGE_INDEX_u8i(ITYPE, Left, Right) { \
263
mlib_u8 *pbuff = buff; \
264
\
265
size = Right - Left; \
266
\
267
MLIB_EDGE_INDEX(ITYPE, mlib_u8, size); \
268
\
269
dp = (ITYPE*)data + Left; \
270
\
271
if (channels == 3) { \
272
if (sizeof(ITYPE) == 1) { \
273
mlib_ImageColorTrue2IndexLine_U8_U8_3 (buff, (void*)dp, size, colormap); \
274
} else { \
275
mlib_ImageColorTrue2IndexLine_U8_S16_3(buff, (void*)dp, size, colormap); \
276
} \
277
} else { \
278
if (sizeof(ITYPE) == 1) { \
279
mlib_ImageColorTrue2IndexLine_U8_U8_4 (buff, (void*)dp, size, colormap); \
280
} else { \
281
mlib_ImageColorTrue2IndexLine_U8_S16_4(buff, (void*)dp, size, colormap); \
282
} \
283
} \
284
}
285
286
/***************************************************************/
287
#define MLIB_EDGE_INDEX_s16i(ITYPE, Left, Right) { \
288
mlib_s16 *pbuff = buff; \
289
\
290
size = Right - Left; \
291
\
292
MLIB_EDGE_INDEX(ITYPE, mlib_s16, size); \
293
\
294
dp = (ITYPE*)data + Left; \
295
\
296
if (channels == 3) { \
297
if (sizeof(ITYPE) == 1) { \
298
mlib_ImageColorTrue2IndexLine_S16_U8_3 (buff, (void*)dp, size, colormap); \
299
} else { \
300
mlib_ImageColorTrue2IndexLine_S16_S16_3(buff, (void*)dp, size, colormap); \
301
} \
302
} else { \
303
if (sizeof(ITYPE) == 1) { \
304
mlib_ImageColorTrue2IndexLine_S16_U8_4 (buff, (void*)dp, size, colormap); \
305
} else { \
306
mlib_ImageColorTrue2IndexLine_S16_S16_4(buff, (void*)dp, size, colormap); \
307
} \
308
} \
309
}
310
311
/***************************************************************/
312
#define GET_FLT_TBL(X, xf0, xf1, xf2, xf3) \
313
filterpos = ((X - 32768) >> flt_shift) & flt_mask; \
314
fptr = (mlib_f32 *) ((mlib_u8 *)flt_tbl + filterpos); \
315
\
316
xf0 = fptr[0]; \
317
xf1 = fptr[1]; \
318
xf2 = fptr[2]; \
319
xf3 = fptr[3]
320
321
/***************************************************************/
322
#define GET_FLT_BC(X, xf0, xf1, xf2, xf3) \
323
dx = ((X - 32768) & MLIB_MASK) * scale; \
324
dx_2 = 0.5 * dx; \
325
dx2 = dx * dx; \
326
dx3_2 = dx_2 * dx2; \
327
dx3_3 = 3.0 * dx3_2; \
328
\
329
xf0 = dx2 - dx3_2 - dx_2; \
330
xf1 = dx3_3 - 2.5 * dx2 + 1.0; \
331
xf2 = 2.0 * dx2 - dx3_3 + dx_2; \
332
xf3 = dx3_2 - 0.5 * dx2
333
334
/***************************************************************/
335
#define GET_FLT_BC2(X, xf0, xf1, xf2, xf3) \
336
dx = ((X - 32768) & MLIB_MASK) * scale; \
337
dx2 = dx * dx; \
338
dx3_2 = dx * dx2; \
339
dx3_3 = 2.0 * dx2; \
340
\
341
xf0 = - dx3_2 + dx3_3 - dx; \
342
xf1 = dx3_2 - dx3_3 + 1.0; \
343
xf2 = - dx3_2 + dx2 + dx; \
344
xf3 = dx3_2 - dx2
345
346
/***************************************************************/
347
#define CALC_SRC_POS(X, Y, channels, srcStride) \
348
xSrc = ((X - 32768) >> MLIB_SHIFT); \
349
ySrc = ((Y - 32768) >> MLIB_SHIFT); \
350
\
351
xDelta0 = ((~((xSrc - 1) >> MLIB_SIGN_SHIFT)) & (- channels)); \
352
yDelta0 = ((~((ySrc - 1) >> MLIB_SIGN_SHIFT)) & (- srcStride)); \
353
xDelta1 = ((xSrc + 1 - srcWidth) >> MLIB_SIGN_SHIFT) & (channels); \
354
yDelta1 = ((ySrc + 1 - srcHeight) >> MLIB_SIGN_SHIFT) & (srcStride); \
355
xDelta2 = xDelta1 + (((xSrc + 2 - srcWidth) >> MLIB_SIGN_SHIFT) & (channels)); \
356
yDelta2 = yDelta1 + (((ySrc + 2 - srcHeight) >> MLIB_SIGN_SHIFT) & (srcStride)); \
357
\
358
xFlag = (xSrc >> (MLIB_SIGN_SHIFT - MLIB_SHIFT)); \
359
xSrc = xSrc + (1 & xFlag); \
360
xDelta2 -= (xDelta1 & xFlag); \
361
xDelta1 = (xDelta1 &~ xFlag); \
362
\
363
yFlag = (ySrc >> (MLIB_SIGN_SHIFT - MLIB_SHIFT)); \
364
ySrc = ySrc + (1 & yFlag); \
365
yDelta2 -= (yDelta1 & yFlag); \
366
yDelta1 = yDelta1 &~ yFlag
367
368
/***************************************************************/
369
#define MLIB_EDGE_BC_LINE(TYPE, Left, Right, GET_FILTER) \
370
dp = (TYPE*)data + channels * Left; \
371
size = Right - Left; \
372
\
373
for (j = 0; j < size; j++) { \
374
GET_FILTER(X, xf0, xf1, xf2, xf3); \
375
GET_FILTER(Y, yf0, yf1, yf2, yf3); \
376
\
377
CALC_SRC_POS(X, Y, channels, srcStride); \
378
\
379
sp = (TYPE*)lineAddr[ySrc] + channels*xSrc; \
380
\
381
for (k = 0; k < channels; k++) { \
382
c0 = D64##TYPE(sp[yDelta0 + xDelta0]) * xf0 + \
383
D64##TYPE(sp[yDelta0 ]) * xf1 + \
384
D64##TYPE(sp[yDelta0 + xDelta1]) * xf2 + \
385
D64##TYPE(sp[yDelta0 + xDelta2]) * xf3; \
386
\
387
c1 = D64##TYPE(sp[xDelta0]) * xf0 + \
388
D64##TYPE(sp[ 0]) * xf1 + \
389
D64##TYPE(sp[xDelta1]) * xf2 + \
390
D64##TYPE(sp[xDelta2]) * xf3; \
391
\
392
c2 = D64##TYPE(sp[yDelta1 + xDelta0]) * xf0 + \
393
D64##TYPE(sp[yDelta1 ]) * xf1 + \
394
D64##TYPE(sp[yDelta1 + xDelta1]) * xf2 + \
395
D64##TYPE(sp[yDelta1 + xDelta2]) * xf3; \
396
\
397
c3 = D64##TYPE(sp[yDelta2 + xDelta0]) * xf0 + \
398
D64##TYPE(sp[yDelta2 ]) * xf1 + \
399
D64##TYPE(sp[yDelta2 + xDelta1]) * xf2 + \
400
D64##TYPE(sp[yDelta2 + xDelta2]) * xf3; \
401
\
402
val0 = c0*yf0 + c1*yf1 + c2*yf2 + c3*yf3; \
403
\
404
SAT##TYPE(dp[k], val0); \
405
\
406
sp++; \
407
} \
408
\
409
X += dX; \
410
Y += dY; \
411
dp += channels; \
412
}
413
414
/***************************************************************/
415
#define MLIB_EDGE_BC_TBL(TYPE, Left, Right) \
416
MLIB_EDGE_BC_LINE(TYPE, Left, Right, GET_FLT_TBL)
417
418
/***************************************************************/
419
#define MLIB_EDGE_BC(TYPE, Left, Right) \
420
MLIB_EDGE_BC_LINE(TYPE, Left, Right, GET_FLT_BC)
421
422
/***************************************************************/
423
#define MLIB_EDGE_BC2(TYPE, Left, Right) \
424
MLIB_EDGE_BC_LINE(TYPE, Left, Right, GET_FLT_BC2)
425
426
/***************************************************************/
427
#define MLIB_EDGE_INDEX_BC(ITYPE, DTYPE, size) \
428
for (j = 0; j < size; j++) { \
429
GET_FLT_TBL(X, xf0, xf1, xf2, xf3); \
430
GET_FLT_TBL(Y, yf0, yf1, yf2, yf3); \
431
\
432
CALC_SRC_POS(X, Y, 1, srcStride); \
433
\
434
sp = (ITYPE*)lineAddr[ySrc] + xSrc; \
435
\
436
for (k = 0; k < channels; k++) { \
437
c0 = LUT(k, yDelta0 + xDelta0) * xf0 + \
438
LUT(k, yDelta0 ) * xf1 + \
439
LUT(k, yDelta0 + xDelta1) * xf2 + \
440
LUT(k, yDelta0 + xDelta2) * xf3; \
441
\
442
c1 = LUT(k, xDelta0) * xf0 + \
443
LUT(k, 0 ) * xf1 + \
444
LUT(k, xDelta1) * xf2 + \
445
LUT(k, xDelta2) * xf3; \
446
\
447
c2 = LUT(k, yDelta1 + xDelta0) * xf0 + \
448
LUT(k, yDelta1 ) * xf1 + \
449
LUT(k, yDelta1 + xDelta1) * xf2 + \
450
LUT(k, yDelta1 + xDelta2) * xf3; \
451
\
452
c3 = LUT(k, yDelta2 + xDelta0) * xf0 + \
453
LUT(k, yDelta2 ) * xf1 + \
454
LUT(k, yDelta2 + xDelta1) * xf2 + \
455
LUT(k, yDelta2 + xDelta2) * xf3; \
456
\
457
val0 = c0*yf0 + c1*yf1 + c2*yf2 + c3*yf3; \
458
\
459
SAT##DTYPE(pbuff[k], val0); \
460
} \
461
pbuff += channels; \
462
\
463
X += dX; \
464
Y += dY; \
465
}
466
467
/***************************************************************/
468
#define MLIB_PROCESS_EDGES_ZERO(TYPE) { \
469
TYPE *dp, *dstLineEnd; \
470
\
471
for (i = yStartE; i < yStart; i++) { \
472
xLeftE = leftEdgesE[i]; \
473
xRightE = rightEdgesE[i] + 1; \
474
data += dstStride; \
475
\
476
MLIB_EDGE_ZERO_LINE(TYPE, xLeftE, xRightE); \
477
} \
478
\
479
for (; i <= yFinish; i++) { \
480
xLeftE = leftEdgesE[i]; \
481
xRightE = rightEdgesE[i] + 1; \
482
xLeft = leftEdges[i]; \
483
xRight = rightEdges[i] + 1; \
484
data += dstStride; \
485
\
486
if (xLeft < xRight) { \
487
MLIB_EDGE_ZERO_LINE(TYPE, xLeftE, xLeft); \
488
} else { \
489
xRight = xLeftE; \
490
} \
491
\
492
MLIB_EDGE_ZERO_LINE(TYPE, xRight, xRightE); \
493
} \
494
\
495
for (; i <= yFinishE; i++) { \
496
xLeftE = leftEdgesE[i]; \
497
xRightE = rightEdgesE[i] + 1; \
498
data += dstStride; \
499
\
500
MLIB_EDGE_ZERO_LINE(TYPE, xLeftE, xRightE); \
501
} \
502
}
503
504
/***************************************************************/
505
#define MLIB_PROCESS_EDGES(PROCESS_LINE, TYPE) { \
506
TYPE *sp, *dp; \
507
mlib_s32 k, size; \
508
\
509
for (i = yStartE; i < yStart; i++) { \
510
xLeftE = leftEdgesE[i]; \
511
xRightE = rightEdgesE[i] + 1; \
512
X = xStartsE[i]; \
513
Y = yStartsE[i]; \
514
data += dstStride; \
515
\
516
PROCESS_LINE(TYPE, xLeftE, xRightE); \
517
} \
518
\
519
for (; i <= yFinish; i++) { \
520
xLeftE = leftEdgesE[i]; \
521
xRightE = rightEdgesE[i] + 1; \
522
xLeft = leftEdges[i]; \
523
xRight = rightEdges[i] + 1; \
524
X = xStartsE[i]; \
525
Y = yStartsE[i]; \
526
data += dstStride; \
527
\
528
if (xLeft < xRight) { \
529
PROCESS_LINE(TYPE, xLeftE, xLeft); \
530
} else { \
531
xRight = xLeftE; \
532
} \
533
\
534
X = xStartsE[i] + dX * (xRight - xLeftE); \
535
Y = yStartsE[i] + dY * (xRight - xLeftE); \
536
PROCESS_LINE(TYPE, xRight, xRightE); \
537
} \
538
\
539
for (; i <= yFinishE; i++) { \
540
xLeftE = leftEdgesE[i]; \
541
xRightE = rightEdgesE[i] + 1; \
542
X = xStartsE[i]; \
543
Y = yStartsE[i]; \
544
data += dstStride; \
545
\
546
PROCESS_LINE(TYPE, xLeftE, xRightE); \
547
} \
548
}
549
550
/***************************************************************/
551
#define GET_EDGE_PARAMS_ZERO() \
552
mlib_image *dst = param -> dst; \
553
mlib_s32 *leftEdges = param -> leftEdges; \
554
mlib_s32 *rightEdges = param -> rightEdges; \
555
mlib_s32 *leftEdgesE = param_e -> leftEdges; \
556
mlib_s32 *rightEdgesE = param_e -> rightEdges; \
557
mlib_type type = mlib_ImageGetType(dst); \
558
mlib_s32 channels = mlib_ImageGetChannels(dst); \
559
mlib_s32 dstStride = mlib_ImageGetStride(dst); \
560
mlib_s32 yStart = param -> yStart; \
561
mlib_s32 yFinish = param -> yFinish; \
562
mlib_s32 yStartE = param_e -> yStart; \
563
mlib_s32 yFinishE = param_e -> yFinish; \
564
mlib_u8 *data = param_e -> dstData; \
565
mlib_s32 xLeft, xRight, xLeftE, xRightE; \
566
mlib_s32 i
567
568
/***************************************************************/
569
#define GET_EDGE_PARAMS_NN() \
570
GET_EDGE_PARAMS_ZERO(); \
571
mlib_s32 *xStartsE = param_e -> xStarts; \
572
mlib_s32 *yStartsE = param_e -> yStarts; \
573
mlib_u8 **lineAddr = param -> lineAddr; \
574
mlib_s32 dX = param_e -> dX; \
575
mlib_s32 dY = param_e -> dY; \
576
mlib_s32 xSrc, ySrc, X, Y; \
577
mlib_s32 j
578
579
/***************************************************************/
580
#define GET_EDGE_PARAMS() \
581
GET_EDGE_PARAMS_NN(); \
582
mlib_image *src = param -> src; \
583
mlib_s32 srcWidth = mlib_ImageGetWidth(src); \
584
mlib_s32 srcHeight = mlib_ImageGetHeight(src); \
585
mlib_s32 srcStride = mlib_ImageGetStride(src)
586
587
/***************************************************************/
588
void mlib_ImageAffineEdgeZero(mlib_affine_param *param,
589
mlib_affine_param *param_e,
590
const void *colormap)
591
{
592
GET_EDGE_PARAMS_ZERO();
593
mlib_s32 zero = 0;
594
595
if (colormap != NULL) {
596
zero = mlib_ImageGetLutOffset(colormap);
597
}
598
599
switch (type) {
600
case MLIB_BYTE:
601
MLIB_PROCESS_EDGES_ZERO(mlib_u8);
602
break;
603
604
case MLIB_SHORT:
605
case MLIB_USHORT:
606
MLIB_PROCESS_EDGES_ZERO(mlib_s16);
607
break;
608
609
case MLIB_INT:
610
case MLIB_FLOAT:
611
MLIB_PROCESS_EDGES_ZERO(mlib_s32);
612
break;
613
614
case MLIB_DOUBLE:{
615
mlib_d64 zero = 0;
616
MLIB_PROCESS_EDGES_ZERO(mlib_d64);
617
break;
618
}
619
default:
620
/* Image type MLIB_BIT is not used in java, so we can ignore it. */
621
break;
622
}
623
}
624
625
/***************************************************************/
626
void mlib_ImageAffineEdgeNearest(mlib_affine_param *param,
627
mlib_affine_param *param_e)
628
{
629
GET_EDGE_PARAMS_NN();
630
631
switch (type) {
632
case MLIB_BYTE:
633
MLIB_PROCESS_EDGES(MLIB_EDGE_NEAREST_LINE, mlib_u8);
634
break;
635
636
case MLIB_SHORT:
637
case MLIB_USHORT:
638
MLIB_PROCESS_EDGES(MLIB_EDGE_NEAREST_LINE, mlib_s16);
639
break;
640
641
case MLIB_INT:
642
case MLIB_FLOAT:
643
MLIB_PROCESS_EDGES(MLIB_EDGE_NEAREST_LINE, mlib_s32);
644
break;
645
646
case MLIB_DOUBLE:
647
MLIB_PROCESS_EDGES(MLIB_EDGE_NEAREST_LINE, mlib_d64);
648
break;
649
default:
650
/* Image type MLIB_BIT is not used in java, so we can ignore it. */
651
break;
652
}
653
}
654
655
/***************************************************************/
656
mlib_status mlib_ImageAffineEdgeExtend_BL(mlib_affine_param *param,
657
mlib_affine_param *param_e,
658
const void *colormap)
659
{
660
GET_EDGE_PARAMS();
661
mlib_d64 scale = 1.0 / (mlib_d64) MLIB_PREC;
662
mlib_s32 xDelta, yDelta, xFlag, yFlag;
663
mlib_d64 t, u, pix0;
664
mlib_d64 a00, a01, a10, a11;
665
666
if (colormap != NULL) {
667
mlib_s32 max_xsize = param_e->max_xsize;
668
mlib_type ltype = mlib_ImageGetLutType(colormap);
669
mlib_d64 *plut = (mlib_d64 *) mlib_ImageGetLutDoubleData(colormap);
670
void *buff;
671
672
channels = mlib_ImageGetLutChannels(colormap);
673
plut -= channels * mlib_ImageGetLutOffset(colormap);
674
675
if (max_xsize == 0) {
676
return MLIB_SUCCESS;
677
}
678
679
if (ltype == MLIB_BYTE) {
680
buff = mlib_malloc(channels * max_xsize);
681
}
682
else if (ltype == MLIB_SHORT) {
683
buff = mlib_malloc(channels * max_xsize * sizeof(mlib_s16));
684
} else {
685
/* Unsupported type of lookup table. Report a failure */
686
return MLIB_FAILURE;
687
}
688
689
if (buff == NULL)
690
return MLIB_FAILURE;
691
692
switch (ltype) {
693
case MLIB_BYTE:
694
switch (type) {
695
case MLIB_BYTE:
696
MLIB_PROCESS_EDGES(MLIB_EDGE_INDEX_u8i, mlib_u8);
697
break;
698
699
case MLIB_SHORT:
700
srcStride >>= 1;
701
MLIB_PROCESS_EDGES(MLIB_EDGE_INDEX_u8i, mlib_s16);
702
break;
703
default:
704
/* Incompatible image type. Ignore it for now. */
705
break;
706
}
707
708
break;
709
710
case MLIB_SHORT:
711
switch (type) {
712
case MLIB_BYTE:
713
MLIB_PROCESS_EDGES(MLIB_EDGE_INDEX_s16i, mlib_u8);
714
break;
715
716
case MLIB_SHORT:
717
srcStride >>= 1;
718
MLIB_PROCESS_EDGES(MLIB_EDGE_INDEX_s16i, mlib_s16);
719
break;
720
default:
721
/* Incompatible image type. Ignore it for now. */
722
break;
723
}
724
725
break;
726
default:
727
/* Unsupported type of lookup table.
728
* Can not be here due to check on line 685,
729
* so just ignore it.
730
*/
731
break;
732
}
733
734
mlib_free(buff);
735
736
return MLIB_SUCCESS;
737
}
738
739
switch (type) {
740
case MLIB_BYTE:
741
MLIB_PROCESS_EDGES(MLIB_EDGE_BL, mlib_u8);
742
break;
743
744
case MLIB_SHORT:
745
srcStride >>= 1;
746
MLIB_PROCESS_EDGES(MLIB_EDGE_BL, mlib_s16);
747
break;
748
749
case MLIB_USHORT:
750
srcStride >>= 1;
751
MLIB_PROCESS_EDGES(MLIB_EDGE_BL, mlib_u16);
752
break;
753
754
case MLIB_INT:
755
srcStride >>= 2;
756
MLIB_PROCESS_EDGES(MLIB_EDGE_BL, mlib_s32);
757
break;
758
759
case MLIB_FLOAT:
760
srcStride >>= 2;
761
MLIB_PROCESS_EDGES(MLIB_EDGE_BL, mlib_f32);
762
break;
763
764
case MLIB_DOUBLE:
765
srcStride >>= 3;
766
MLIB_PROCESS_EDGES(MLIB_EDGE_BL, mlib_d64);
767
break;
768
769
default:
770
/* Image type MLIB_BIT is not supported, ignore it. */
771
break;
772
}
773
774
return MLIB_SUCCESS;
775
}
776
777
/***************************************************************/
778
#undef MLIB_EDGE_INDEX
779
#define MLIB_EDGE_INDEX MLIB_EDGE_INDEX_BC
780
781
mlib_status mlib_ImageAffineEdgeExtend_BC(mlib_affine_param *param,
782
mlib_affine_param *param_e,
783
const void *colormap)
784
{
785
GET_EDGE_PARAMS();
786
mlib_d64 scale = 1.0 / (mlib_d64) MLIB_PREC;
787
mlib_s32 xFlag, yFlag;
788
mlib_d64 dx, dx_2, dx2, dx3_2, dx3_3;
789
mlib_d64 xf0, xf1, xf2, xf3;
790
mlib_d64 yf0, yf1, yf2, yf3;
791
mlib_d64 c0, c1, c2, c3, val0;
792
mlib_type ltype;
793
mlib_filter filter = param->filter;
794
mlib_f32 *fptr;
795
mlib_f32 const *flt_tbl;
796
mlib_s32 filterpos, flt_shift, flt_mask;
797
mlib_s32 xDelta0, xDelta1, xDelta2;
798
mlib_s32 yDelta0, yDelta1, yDelta2;
799
mlib_d64 sat;
800
801
ltype = (colormap != NULL) ? mlib_ImageGetLutType(colormap) : type;
802
803
if (ltype == MLIB_BYTE) {
804
flt_shift = FLT_SHIFT_U8;
805
flt_mask = FLT_MASK_U8;
806
flt_tbl = (filter == MLIB_BICUBIC) ? mlib_filters_u8f_bc : mlib_filters_u8f_bc2;
807
sat = (mlib_d64) 0x7F800000; /* saturation for U8 */
808
}
809
else {
810
flt_shift = FLT_SHIFT_S16;
811
flt_mask = FLT_MASK_S16;
812
flt_tbl = (filter == MLIB_BICUBIC) ? mlib_filters_s16f_bc : mlib_filters_s16f_bc2;
813
sat = (mlib_d64) 0x7FFF8000; /* saturation for U16 */
814
}
815
816
if (colormap != NULL) {
817
mlib_s32 max_xsize = param_e->max_xsize;
818
mlib_d64 *plut = (mlib_d64 *) mlib_ImageGetLutDoubleData(colormap);
819
void *buff;
820
821
channels = mlib_ImageGetLutChannels(colormap);
822
plut -= channels * mlib_ImageGetLutOffset(colormap);
823
824
if (max_xsize == 0) {
825
return MLIB_SUCCESS;
826
}
827
828
if (ltype == MLIB_BYTE) {
829
buff = mlib_malloc(channels * max_xsize);
830
}
831
else if (ltype == MLIB_SHORT) {
832
buff = mlib_malloc(channels * max_xsize * sizeof(mlib_s16));
833
} else {
834
/* Unsupported type of lookup table. */
835
return MLIB_FAILURE;
836
}
837
838
if (buff == NULL)
839
return MLIB_FAILURE;
840
841
switch (ltype) {
842
case MLIB_BYTE:
843
switch (type) {
844
case MLIB_BYTE:
845
MLIB_PROCESS_EDGES(MLIB_EDGE_INDEX_u8i, mlib_u8);
846
break;
847
848
case MLIB_SHORT:
849
srcStride >>= 1;
850
MLIB_PROCESS_EDGES(MLIB_EDGE_INDEX_u8i, mlib_s16);
851
break;
852
default:
853
/* Ignore incomatible image type. */
854
break;
855
}
856
857
break;
858
859
case MLIB_SHORT:
860
switch (type) {
861
case MLIB_BYTE:
862
MLIB_PROCESS_EDGES(MLIB_EDGE_INDEX_s16i, mlib_u8);
863
break;
864
865
case MLIB_SHORT:
866
srcStride >>= 1;
867
MLIB_PROCESS_EDGES(MLIB_EDGE_INDEX_s16i, mlib_s16);
868
break;
869
default:
870
/* Ignore incomatible image type. */
871
break;
872
}
873
874
break;
875
876
default:
877
/* Unsupported type of lookup table.
878
* Can not be here due to check on line 836,
879
* so just ignore it.
880
*/
881
break;
882
}
883
884
mlib_free(buff);
885
886
return MLIB_SUCCESS;
887
}
888
889
switch (type) {
890
case MLIB_BYTE:
891
MLIB_PROCESS_EDGES(MLIB_EDGE_BC_TBL, mlib_u8);
892
break;
893
894
case MLIB_SHORT:
895
srcStride >>= 1;
896
MLIB_PROCESS_EDGES(MLIB_EDGE_BC_TBL, mlib_s16);
897
break;
898
899
case MLIB_USHORT:
900
srcStride >>= 1;
901
MLIB_PROCESS_EDGES(MLIB_EDGE_BC_TBL, mlib_u16);
902
break;
903
904
case MLIB_INT:
905
srcStride >>= 2;
906
907
if (filter == MLIB_BICUBIC) {
908
MLIB_PROCESS_EDGES(MLIB_EDGE_BC, mlib_s32);
909
}
910
else {
911
MLIB_PROCESS_EDGES(MLIB_EDGE_BC2, mlib_s32);
912
}
913
914
break;
915
916
case MLIB_FLOAT:
917
srcStride >>= 2;
918
919
if (filter == MLIB_BICUBIC) {
920
MLIB_PROCESS_EDGES(MLIB_EDGE_BC, mlib_f32);
921
}
922
else {
923
MLIB_PROCESS_EDGES(MLIB_EDGE_BC2, mlib_f32);
924
}
925
926
break;
927
928
case MLIB_DOUBLE:
929
srcStride >>= 3;
930
931
if (filter == MLIB_BICUBIC) {
932
MLIB_PROCESS_EDGES(MLIB_EDGE_BC, mlib_d64);
933
}
934
else {
935
MLIB_PROCESS_EDGES(MLIB_EDGE_BC2, mlib_d64);
936
}
937
938
break;
939
940
default:
941
/* Ignore unsupported image type MLIB_BIT */
942
break;
943
}
944
945
return MLIB_SUCCESS;
946
}
947
948
/***************************************************************/
949
950