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_ImageAffineEdge.c
41152 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_ImageAffine.h"
77
78
/***************************************************************/
79
#define FLT_SHIFT_U8 4
80
#define FLT_MASK_U8 (((1 << 8) - 1) << 4)
81
#define FLT_SHIFT_S16 3
82
#define FLT_MASK_S16 (((1 << 9) - 1) << 4)
83
84
#define MLIB_SIGN_SHIFT 31
85
86
/***************************************************************/
87
#define D64mlib_u8(X) mlib_U82D64[X]
88
#define D64mlib_s16(X) ((mlib_d64)(X))
89
#define D64mlib_u16(X) ((mlib_d64)(X))
90
#define D64mlib_s32(X) ((mlib_d64)(X))
91
#define D64mlib_f32(X) ((mlib_d64)(X))
92
#define D64mlib_d64(X) ((mlib_d64)(X))
93
94
/***************************************************************/
95
#ifdef MLIB_USE_FTOI_CLAMPING
96
97
#define SATmlib_u8(DST, val0) \
98
DST = ((mlib_s32)(val0 - sat) >> 24) ^ 0x80
99
100
#define SATmlib_s16(DST, val0) \
101
DST = ((mlib_s32)val0) >> 16
102
103
#define SATmlib_u16(DST, val0) \
104
DST = ((mlib_s32)(val0 - sat) >> 16) ^ 0x8000
105
106
#define SATmlib_s32(DST, val0) \
107
DST = val0
108
109
#else
110
111
#define SATmlib_u8(DST, val0) \
112
val0 -= sat; \
113
if (val0 >= MLIB_S32_MAX) \
114
val0 = MLIB_S32_MAX; \
115
if (val0 <= MLIB_S32_MIN) \
116
val0 = MLIB_S32_MIN; \
117
DST = ((mlib_s32) val0 >> 24) ^ 0x80
118
119
#define SATmlib_s16(DST, val0) \
120
if (val0 >= MLIB_S32_MAX) \
121
val0 = MLIB_S32_MAX; \
122
if (val0 <= MLIB_S32_MIN) \
123
val0 = MLIB_S32_MIN; \
124
DST = (mlib_s32)val0 >> 16
125
126
#define SATmlib_u16(DST, val0) \
127
val0 -= sat; \
128
if (val0 >= MLIB_S32_MAX) \
129
val0 = MLIB_S32_MAX; \
130
if (val0 <= MLIB_S32_MIN) \
131
val0 = MLIB_S32_MIN; \
132
DST = ((mlib_s32)val0 >> 16) ^ 0x8000
133
134
#define SATmlib_s32(DST, val0) \
135
if (val0 >= MLIB_S32_MAX) \
136
val0 = MLIB_S32_MAX; \
137
if (val0 <= MLIB_S32_MIN) \
138
val0 = MLIB_S32_MIN; \
139
DST = (mlib_s32)val0
140
141
#endif
142
143
/***************************************************************/
144
#define SATmlib_f32(DST, val0) \
145
DST = (mlib_f32)val0
146
147
/***************************************************************/
148
#define SATmlib_d64(DST, val0) \
149
DST = val0
150
151
/***************************************************************/
152
#define MLIB_EDGE_ZERO_LINE(TYPE, Left, Right) \
153
dp = (TYPE*)data + channels * Left; \
154
dstLineEnd = (TYPE*)data + channels * Right; \
155
\
156
for (; dp < dstLineEnd; dp++) { \
157
*dp = zero; \
158
}
159
160
/***************************************************************/
161
#define MLIB_EDGE_NEAREST_LINE(TYPE, Left, Right) \
162
dp = (TYPE*)data + channels * Left; \
163
size = Right - Left; \
164
\
165
for (j = 0; j < size; j++) { \
166
ySrc = Y >> MLIB_SHIFT; \
167
xSrc = X >> MLIB_SHIFT; \
168
sp = (TYPE*)lineAddr[ySrc] + xSrc * channels; \
169
\
170
for (k = 0; k < channels; k++) dp[k] = sp[k]; \
171
\
172
Y += dY; \
173
X += dX; \
174
dp += channels; \
175
}
176
177
/***************************************************************/
178
#define MLIB_EDGE_BL(TYPE, Left, Right) \
179
dp = (TYPE*)data + channels * Left; \
180
size = Right - Left; \
181
\
182
for (j = 0; j < size; j++) { \
183
ySrc = ((Y - 32768) >> MLIB_SHIFT); \
184
xSrc = ((X - 32768) >> MLIB_SHIFT); \
185
\
186
t = ((X - 32768) & MLIB_MASK) * scale; \
187
u = ((Y - 32768) & MLIB_MASK) * scale; \
188
\
189
xDelta = (((xSrc + 1 - srcWidth )) >> MLIB_SIGN_SHIFT) & channels; \
190
yDelta = (((ySrc + 1 - srcHeight)) >> MLIB_SIGN_SHIFT) & srcStride; \
191
\
192
xFlag = (xSrc >> (MLIB_SIGN_SHIFT - MLIB_SHIFT)); \
193
xSrc = xSrc + (1 & xFlag); \
194
xDelta = xDelta &~ xFlag; \
195
\
196
yFlag = (ySrc >> (MLIB_SIGN_SHIFT - MLIB_SHIFT)); \
197
ySrc = ySrc + (1 & yFlag); \
198
yDelta = yDelta &~ yFlag; \
199
\
200
sp = (TYPE*)lineAddr[ySrc] + xSrc * channels; \
201
\
202
for (k = 0; k < channels; k++) { \
203
a00 = D64##TYPE(sp[0]); \
204
a01 = D64##TYPE(sp[xDelta]); \
205
a10 = D64##TYPE(sp[yDelta]); \
206
a11 = D64##TYPE(sp[yDelta + xDelta]); \
207
pix0 = (a00 * (1 - t) + a01 * t) * (1 - u) + \
208
(a10 * (1 - t) + a11 * t) * u; \
209
\
210
dp[k] = (TYPE)pix0; \
211
sp++; \
212
} \
213
\
214
X += dX; \
215
Y += dY; \
216
dp += channels; \
217
}
218
219
/***************************************************************/
220
#define GET_FLT_TBL(X, xf0, xf1, xf2, xf3) \
221
filterpos = ((X - 32768) >> flt_shift) & flt_mask; \
222
fptr = (mlib_f32 *) ((mlib_u8 *)flt_tbl + filterpos); \
223
\
224
xf0 = fptr[0]; \
225
xf1 = fptr[1]; \
226
xf2 = fptr[2]; \
227
xf3 = fptr[3]
228
229
/***************************************************************/
230
#define GET_FLT_BC(X, xf0, xf1, xf2, xf3) \
231
dx = ((X - 32768) & MLIB_MASK) * scale; \
232
dx_2 = 0.5 * dx; \
233
dx2 = dx * dx; \
234
dx3_2 = dx_2 * dx2; \
235
dx3_3 = 3.0 * dx3_2; \
236
\
237
xf0 = dx2 - dx3_2 - dx_2; \
238
xf1 = dx3_3 - 2.5 * dx2 + 1.0; \
239
xf2 = 2.0 * dx2 - dx3_3 + dx_2; \
240
xf3 = dx3_2 - 0.5 * dx2
241
242
/***************************************************************/
243
#define GET_FLT_BC2(X, xf0, xf1, xf2, xf3) \
244
dx = ((X - 32768) & MLIB_MASK) * scale; \
245
dx2 = dx * dx; \
246
dx3_2 = dx * dx2; \
247
dx3_3 = 2.0 * dx2; \
248
\
249
xf0 = - dx3_2 + dx3_3 - dx; \
250
xf1 = dx3_2 - dx3_3 + 1.0; \
251
xf2 = - dx3_2 + dx2 + dx; \
252
xf3 = dx3_2 - dx2
253
254
/***************************************************************/
255
#define CALC_SRC_POS(X, Y, channels, srcStride) \
256
xSrc = ((X - 32768) >> MLIB_SHIFT); \
257
ySrc = ((Y - 32768) >> MLIB_SHIFT); \
258
\
259
xDelta0 = ((~((xSrc - 1) >> MLIB_SIGN_SHIFT)) & (- channels)); \
260
yDelta0 = ((~((ySrc - 1) >> MLIB_SIGN_SHIFT)) & (- srcStride)); \
261
xDelta1 = ((xSrc + 1 - srcWidth) >> MLIB_SIGN_SHIFT) & (channels); \
262
yDelta1 = ((ySrc + 1 - srcHeight) >> MLIB_SIGN_SHIFT) & (srcStride); \
263
xDelta2 = xDelta1 + (((xSrc + 2 - srcWidth) >> MLIB_SIGN_SHIFT) & (channels)); \
264
yDelta2 = yDelta1 + (((ySrc + 2 - srcHeight) >> MLIB_SIGN_SHIFT) & (srcStride)); \
265
\
266
xFlag = (xSrc >> (MLIB_SIGN_SHIFT - MLIB_SHIFT)); \
267
xSrc = xSrc + (1 & xFlag); \
268
xDelta2 -= (xDelta1 & xFlag); \
269
xDelta1 = (xDelta1 &~ xFlag); \
270
\
271
yFlag = (ySrc >> (MLIB_SIGN_SHIFT - MLIB_SHIFT)); \
272
ySrc = ySrc + (1 & yFlag); \
273
yDelta2 -= (yDelta1 & yFlag); \
274
yDelta1 = yDelta1 &~ yFlag
275
276
/***************************************************************/
277
#define MLIB_EDGE_BC_LINE(TYPE, Left, Right, GET_FILTER) \
278
dp = (TYPE*)data + channels * Left; \
279
size = Right - Left; \
280
\
281
for (j = 0; j < size; j++) { \
282
GET_FILTER(X, xf0, xf1, xf2, xf3); \
283
GET_FILTER(Y, yf0, yf1, yf2, yf3); \
284
\
285
CALC_SRC_POS(X, Y, channels, srcStride); \
286
\
287
sp = (TYPE*)lineAddr[ySrc] + channels*xSrc; \
288
\
289
for (k = 0; k < channels; k++) { \
290
c0 = D64##TYPE(sp[yDelta0 + xDelta0]) * xf0 + \
291
D64##TYPE(sp[yDelta0 ]) * xf1 + \
292
D64##TYPE(sp[yDelta0 + xDelta1]) * xf2 + \
293
D64##TYPE(sp[yDelta0 + xDelta2]) * xf3; \
294
\
295
c1 = D64##TYPE(sp[xDelta0]) * xf0 + \
296
D64##TYPE(sp[ 0]) * xf1 + \
297
D64##TYPE(sp[xDelta1]) * xf2 + \
298
D64##TYPE(sp[xDelta2]) * xf3; \
299
\
300
c2 = D64##TYPE(sp[yDelta1 + xDelta0]) * xf0 + \
301
D64##TYPE(sp[yDelta1 ]) * xf1 + \
302
D64##TYPE(sp[yDelta1 + xDelta1]) * xf2 + \
303
D64##TYPE(sp[yDelta1 + xDelta2]) * xf3; \
304
\
305
c3 = D64##TYPE(sp[yDelta2 + xDelta0]) * xf0 + \
306
D64##TYPE(sp[yDelta2 ]) * xf1 + \
307
D64##TYPE(sp[yDelta2 + xDelta1]) * xf2 + \
308
D64##TYPE(sp[yDelta2 + xDelta2]) * xf3; \
309
\
310
val0 = c0*yf0 + c1*yf1 + c2*yf2 + c3*yf3; \
311
\
312
SAT##TYPE(dp[k], val0); \
313
\
314
sp++; \
315
} \
316
\
317
X += dX; \
318
Y += dY; \
319
dp += channels; \
320
}
321
322
/***************************************************************/
323
#define MLIB_EDGE_BC_TBL(TYPE, Left, Right) \
324
MLIB_EDGE_BC_LINE(TYPE, Left, Right, GET_FLT_TBL)
325
326
/***************************************************************/
327
#define MLIB_EDGE_BC(TYPE, Left, Right) \
328
MLIB_EDGE_BC_LINE(TYPE, Left, Right, GET_FLT_BC)
329
330
/***************************************************************/
331
#define MLIB_EDGE_BC2(TYPE, Left, Right) \
332
MLIB_EDGE_BC_LINE(TYPE, Left, Right, GET_FLT_BC2)
333
334
/***************************************************************/
335
#define MLIB_PROCESS_EDGES_ZERO(TYPE) { \
336
TYPE *dp, *dstLineEnd; \
337
\
338
for (i = yStartE; i < yStart; i++) { \
339
xLeftE = leftEdgesE[i]; \
340
xRightE = rightEdgesE[i] + 1; \
341
data += dstStride; \
342
\
343
MLIB_EDGE_ZERO_LINE(TYPE, xLeftE, xRightE); \
344
} \
345
\
346
for (; i <= yFinish; i++) { \
347
xLeftE = leftEdgesE[i]; \
348
xRightE = rightEdgesE[i] + 1; \
349
xLeft = leftEdges[i]; \
350
xRight = rightEdges[i] + 1; \
351
data += dstStride; \
352
\
353
if (xLeft < xRight) { \
354
MLIB_EDGE_ZERO_LINE(TYPE, xLeftE, xLeft); \
355
} else { \
356
xRight = xLeftE; \
357
} \
358
\
359
MLIB_EDGE_ZERO_LINE(TYPE, xRight, xRightE); \
360
} \
361
\
362
for (; i <= yFinishE; i++) { \
363
xLeftE = leftEdgesE[i]; \
364
xRightE = rightEdgesE[i] + 1; \
365
data += dstStride; \
366
\
367
MLIB_EDGE_ZERO_LINE(TYPE, xLeftE, xRightE); \
368
} \
369
}
370
371
/***************************************************************/
372
#define MLIB_PROCESS_EDGES(PROCESS_LINE, TYPE) { \
373
TYPE *sp, *dp; \
374
mlib_s32 k, size; \
375
\
376
for (i = yStartE; i < yStart; i++) { \
377
xLeftE = leftEdgesE[i]; \
378
xRightE = rightEdgesE[i] + 1; \
379
X = xStartsE[i]; \
380
Y = yStartsE[i]; \
381
data += dstStride; \
382
\
383
PROCESS_LINE(TYPE, xLeftE, xRightE); \
384
} \
385
\
386
for (; i <= yFinish; i++) { \
387
xLeftE = leftEdgesE[i]; \
388
xRightE = rightEdgesE[i] + 1; \
389
xLeft = leftEdges[i]; \
390
xRight = rightEdges[i] + 1; \
391
X = xStartsE[i]; \
392
Y = yStartsE[i]; \
393
data += dstStride; \
394
\
395
if (xLeft < xRight) { \
396
PROCESS_LINE(TYPE, xLeftE, xLeft); \
397
} else { \
398
xRight = xLeftE; \
399
} \
400
\
401
X = xStartsE[i] + dX * (xRight - xLeftE); \
402
Y = yStartsE[i] + dY * (xRight - xLeftE); \
403
PROCESS_LINE(TYPE, xRight, xRightE); \
404
} \
405
\
406
for (; i <= yFinishE; i++) { \
407
xLeftE = leftEdgesE[i]; \
408
xRightE = rightEdgesE[i] + 1; \
409
X = xStartsE[i]; \
410
Y = yStartsE[i]; \
411
data += dstStride; \
412
\
413
PROCESS_LINE(TYPE, xLeftE, xRightE); \
414
} \
415
}
416
417
/***************************************************************/
418
#define GET_EDGE_PARAMS_ZERO() \
419
mlib_image *dst = param -> dst; \
420
mlib_s32 *leftEdges = param -> leftEdges; \
421
mlib_s32 *rightEdges = param -> rightEdges; \
422
mlib_s32 *leftEdgesE = param_e -> leftEdges; \
423
mlib_s32 *rightEdgesE = param_e -> rightEdges; \
424
mlib_type type = mlib_ImageGetType(dst); \
425
mlib_s32 channels = mlib_ImageGetChannels(dst); \
426
mlib_s32 dstStride = mlib_ImageGetStride(dst); \
427
mlib_s32 yStart = param -> yStart; \
428
mlib_s32 yFinish = param -> yFinish; \
429
mlib_s32 yStartE = param_e -> yStart; \
430
mlib_s32 yFinishE = param_e -> yFinish; \
431
mlib_u8 *data = param_e -> dstData; \
432
mlib_s32 xLeft, xRight, xLeftE, xRightE; \
433
mlib_s32 i
434
435
/***************************************************************/
436
#define GET_EDGE_PARAMS_NN() \
437
GET_EDGE_PARAMS_ZERO(); \
438
mlib_s32 *xStartsE = param_e -> xStarts; \
439
mlib_s32 *yStartsE = param_e -> yStarts; \
440
mlib_u8 **lineAddr = param -> lineAddr; \
441
mlib_s32 dX = param_e -> dX; \
442
mlib_s32 dY = param_e -> dY; \
443
mlib_s32 xSrc, ySrc, X, Y; \
444
mlib_s32 j
445
446
/***************************************************************/
447
#define GET_EDGE_PARAMS() \
448
GET_EDGE_PARAMS_NN(); \
449
mlib_image *src = param -> src; \
450
mlib_s32 srcWidth = mlib_ImageGetWidth(src); \
451
mlib_s32 srcHeight = mlib_ImageGetHeight(src); \
452
mlib_s32 srcStride = mlib_ImageGetStride(src)
453
454
/***************************************************************/
455
void mlib_ImageAffineEdgeZero(mlib_affine_param *param,
456
mlib_affine_param *param_e)
457
{
458
GET_EDGE_PARAMS_ZERO();
459
mlib_s32 zero = 0;
460
461
switch (type) {
462
case MLIB_BYTE:
463
MLIB_PROCESS_EDGES_ZERO(mlib_u8);
464
break;
465
466
case MLIB_SHORT:
467
case MLIB_USHORT:
468
MLIB_PROCESS_EDGES_ZERO(mlib_s16);
469
break;
470
471
case MLIB_INT:
472
case MLIB_FLOAT:
473
MLIB_PROCESS_EDGES_ZERO(mlib_s32);
474
break;
475
476
case MLIB_DOUBLE:{
477
mlib_d64 zero = 0;
478
MLIB_PROCESS_EDGES_ZERO(mlib_d64);
479
break;
480
}
481
default:
482
/* Image type MLIB_BIT is not used in java, so we can ignore it. */
483
break;
484
}
485
}
486
487
/***************************************************************/
488
void mlib_ImageAffineEdgeNearest(mlib_affine_param *param,
489
mlib_affine_param *param_e)
490
{
491
GET_EDGE_PARAMS_NN();
492
493
switch (type) {
494
case MLIB_BYTE:
495
MLIB_PROCESS_EDGES(MLIB_EDGE_NEAREST_LINE, mlib_u8);
496
break;
497
498
case MLIB_SHORT:
499
case MLIB_USHORT:
500
MLIB_PROCESS_EDGES(MLIB_EDGE_NEAREST_LINE, mlib_s16);
501
break;
502
503
case MLIB_INT:
504
case MLIB_FLOAT:
505
MLIB_PROCESS_EDGES(MLIB_EDGE_NEAREST_LINE, mlib_s32);
506
break;
507
508
case MLIB_DOUBLE:
509
MLIB_PROCESS_EDGES(MLIB_EDGE_NEAREST_LINE, mlib_d64);
510
break;
511
default:
512
/* Image type MLIB_BIT is not used in java, so we can ignore it. */
513
break;
514
}
515
}
516
517
/***************************************************************/
518
mlib_status mlib_ImageAffineEdgeExtend_BL(mlib_affine_param *param,
519
mlib_affine_param *param_e)
520
{
521
GET_EDGE_PARAMS();
522
mlib_d64 scale = 1.0 / (mlib_d64) MLIB_PREC;
523
mlib_s32 xDelta, yDelta, xFlag, yFlag;
524
mlib_d64 t, u, pix0;
525
mlib_d64 a00, a01, a10, a11;
526
527
switch (type) {
528
case MLIB_BYTE:
529
MLIB_PROCESS_EDGES(MLIB_EDGE_BL, mlib_u8);
530
break;
531
532
case MLIB_SHORT:
533
srcStride >>= 1;
534
MLIB_PROCESS_EDGES(MLIB_EDGE_BL, mlib_s16);
535
break;
536
537
case MLIB_USHORT:
538
srcStride >>= 1;
539
MLIB_PROCESS_EDGES(MLIB_EDGE_BL, mlib_u16);
540
break;
541
542
case MLIB_INT:
543
srcStride >>= 2;
544
MLIB_PROCESS_EDGES(MLIB_EDGE_BL, mlib_s32);
545
break;
546
547
case MLIB_FLOAT:
548
srcStride >>= 2;
549
MLIB_PROCESS_EDGES(MLIB_EDGE_BL, mlib_f32);
550
break;
551
552
case MLIB_DOUBLE:
553
srcStride >>= 3;
554
MLIB_PROCESS_EDGES(MLIB_EDGE_BL, mlib_d64);
555
break;
556
557
default:
558
/* Image type MLIB_BIT is not supported, ignore it. */
559
break;
560
}
561
562
return MLIB_SUCCESS;
563
}
564
565
/***************************************************************/
566
mlib_status mlib_ImageAffineEdgeExtend_BC(mlib_affine_param *param,
567
mlib_affine_param *param_e)
568
{
569
GET_EDGE_PARAMS();
570
mlib_d64 scale = 1.0 / (mlib_d64) MLIB_PREC;
571
mlib_s32 xFlag, yFlag;
572
mlib_d64 dx, dx_2, dx2, dx3_2, dx3_3;
573
mlib_d64 xf0, xf1, xf2, xf3;
574
mlib_d64 yf0, yf1, yf2, yf3;
575
mlib_d64 c0, c1, c2, c3, val0;
576
mlib_filter filter = param->filter;
577
mlib_f32 *fptr;
578
mlib_f32 const *flt_tbl;
579
mlib_s32 filterpos, flt_shift, flt_mask;
580
mlib_s32 xDelta0, xDelta1, xDelta2;
581
mlib_s32 yDelta0, yDelta1, yDelta2;
582
mlib_d64 sat;
583
584
if (type == MLIB_BYTE) {
585
flt_shift = FLT_SHIFT_U8;
586
flt_mask = FLT_MASK_U8;
587
flt_tbl = (filter == MLIB_BICUBIC) ? mlib_filters_u8f_bc : mlib_filters_u8f_bc2;
588
sat = (mlib_d64) 0x7F800000; /* saturation for U8 */
589
}
590
else {
591
flt_shift = FLT_SHIFT_S16;
592
flt_mask = FLT_MASK_S16;
593
flt_tbl = (filter == MLIB_BICUBIC) ? mlib_filters_s16f_bc : mlib_filters_s16f_bc2;
594
sat = (mlib_d64) 0x7FFF8000; /* saturation for U16 */
595
}
596
597
598
switch (type) {
599
case MLIB_BYTE:
600
MLIB_PROCESS_EDGES(MLIB_EDGE_BC_TBL, mlib_u8);
601
break;
602
603
case MLIB_SHORT:
604
srcStride >>= 1;
605
MLIB_PROCESS_EDGES(MLIB_EDGE_BC_TBL, mlib_s16);
606
break;
607
608
case MLIB_USHORT:
609
srcStride >>= 1;
610
MLIB_PROCESS_EDGES(MLIB_EDGE_BC_TBL, mlib_u16);
611
break;
612
613
case MLIB_INT:
614
srcStride >>= 2;
615
616
if (filter == MLIB_BICUBIC) {
617
MLIB_PROCESS_EDGES(MLIB_EDGE_BC, mlib_s32);
618
}
619
else {
620
MLIB_PROCESS_EDGES(MLIB_EDGE_BC2, mlib_s32);
621
}
622
623
break;
624
625
case MLIB_FLOAT:
626
srcStride >>= 2;
627
628
if (filter == MLIB_BICUBIC) {
629
MLIB_PROCESS_EDGES(MLIB_EDGE_BC, mlib_f32);
630
}
631
else {
632
MLIB_PROCESS_EDGES(MLIB_EDGE_BC2, mlib_f32);
633
}
634
635
break;
636
637
case MLIB_DOUBLE:
638
srcStride >>= 3;
639
640
if (filter == MLIB_BICUBIC) {
641
MLIB_PROCESS_EDGES(MLIB_EDGE_BC, mlib_d64);
642
}
643
else {
644
MLIB_PROCESS_EDGES(MLIB_EDGE_BC2, mlib_d64);
645
}
646
647
break;
648
649
default:
650
/* Ignore unsupported image type MLIB_BIT */
651
break;
652
}
653
654
return MLIB_SUCCESS;
655
}
656
657
/***************************************************************/
658
659