1 /* 2 * Copyright (c) 1998, 2020, 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 * Image affine transformation with Bicubic filtering 30 * SYNOPSIS 31 * mlib_status mlib_ImageAffine_[u8|s16|u16]_?ch_bc(mlib_s32 *leftEdges, 32 * mlib_s32 *rightEdges, 33 * mlib_s32 *xStarts, 34 * mlib_s32 *yStarts, 35 * mlib_s32 *sides, 36 * mlib_u8 *dstData, 37 * mlib_u8 **lineAddr, 38 * mlib_s32 dstYStride, 39 * mlib_s32 is_affine, 40 * mlib_s32 srcYStride, 41 * mlib_filter filter) 42 * 43 * 44 * ARGUMENTS 45 * leftEdges array[dstHeight] of xLeft coordinates 46 * RightEdges array[dstHeight] of xRight coordinates 47 * xStarts array[dstHeight] of xStart * 65536 coordinates 48 * yStarts array[dstHeight] of yStart * 65536 coordinates 49 * sides output array[4]. sides[0] is yStart, sides[1] is yFinish, 50 * sides[2] is dx * 65536, sides[3] is dy * 65536 51 * dstData pointer to the first pixel on (yStart - 1) line 52 * lineAddr array[srcHeight] of pointers to the first pixel on 53 * the corresponding lines 54 * dstYStride stride of destination image 55 * is_affine indicator (Affine - GridWarp) 56 * srcYStride stride of source image 57 * filter type of resampling filter 58 * 59 * DESCRIPTION 60 * The functions step along the lines from xLeft to xRight and apply 61 * the bicubic filtering. 62 * 63 */ 64 65 #include "mlib_ImageAffine.h" 66 67 #define DTYPE mlib_u8 68 69 #define FUN_NAME(CHAN) mlib_ImageAffine_u8_##CHAN##_bc 70 71 #define FILTER_BITS 8 72 73 /***************************************************************/ 74 /* for x86, using integer multiplies is faster */ 75 76 #define SHIFT_X 12 77 #define ROUND_X 0 /* (1 << (SHIFT_X - 1)) */ 78 79 #define SHIFT_Y (14 + 14 - SHIFT_X) 80 #define ROUND_Y (1 << (SHIFT_Y - 1)) 81 82 /***************************************************************/ 83 /* Test for the presence of any "1" bit in bits 84 8 to 31 of val. If present, then val is either 85 negative or >255. If over/underflows of 8 bits 86 are uncommon, then this technique can be a win, 87 since only a single test, rather than two, is 88 necessary to determine if clamping is needed. 89 On the other hand, if over/underflows are common, 90 it adds an extra test. 91 */ 92 #define S32_TO_U8_SAT(DST) \ 93 if (val0 & 0xffffff00) { \ 94 if (val0 < MLIB_U8_MIN) \ 95 DST = MLIB_U8_MIN; \ 96 else \ 97 DST = MLIB_U8_MAX; \ 98 } else { \ 99 DST = (mlib_u8)val0; \ 100 } 101 102 /***************************************************************/ 103 mlib_status FUN_NAME(1ch)(mlib_affine_param *param) 104 { 105 DECLAREVAR_BC(); 106 DTYPE *dstLineEnd; 107 const mlib_s16 *mlib_filters_table; 108 109 if (filter == MLIB_BICUBIC) { 110 mlib_filters_table = (mlib_s16 *) mlib_filters_u8_bc; 111 } 112 else { 113 mlib_filters_table = (mlib_s16 *) mlib_filters_u8_bc2; 114 } 115 116 for (j = yStart; j <= yFinish; j++) { 117 mlib_s32 xf0, xf1, xf2, xf3; 118 mlib_s32 yf0, yf1, yf2, yf3; 119 mlib_s32 c0, c1, c2, c3, val0; 120 mlib_s32 filterpos; 121 mlib_s16 *fptr; 122 mlib_u8 s0, s1, s2, s3; 123 124 CLIP(1); 125 dstLineEnd = (DTYPE *) dstData + xRight; 126 127 filterpos = (X >> FILTER_SHIFT) & FILTER_MASK; 128 fptr = (mlib_s16 *) ((mlib_u8 *) mlib_filters_table + filterpos); 129 130 xf0 = fptr[0]; 131 xf1 = fptr[1]; 132 xf2 = fptr[2]; 133 xf3 = fptr[3]; 134 135 filterpos = (Y >> FILTER_SHIFT) & FILTER_MASK; 136 fptr = (mlib_s16 *) ((mlib_u8 *) mlib_filters_table + filterpos); 137 138 yf0 = fptr[0]; 139 yf1 = fptr[1]; 140 yf2 = fptr[2]; 141 yf3 = fptr[3]; 142 143 xSrc = (X >> MLIB_SHIFT) - 1; 144 ySrc = (Y >> MLIB_SHIFT) - 1; 145 146 srcPixelPtr = ((DTYPE **) lineAddr)[ySrc] + xSrc; 147 s0 = srcPixelPtr[0]; 148 s1 = srcPixelPtr[1]; 149 s2 = srcPixelPtr[2]; 150 s3 = srcPixelPtr[3]; 151 152 for (; dstPixelPtr <= (dstLineEnd - 1); dstPixelPtr++) { 153 X += dX; 154 Y += dY; 155 156 c0 = (s0 * xf0 + s1 * xf1 + s2 * xf2 + s3 * xf3 + ROUND_X) >> SHIFT_X; 157 srcPixelPtr = (DTYPE *) ((mlib_addr) srcPixelPtr + srcYStride); 158 c1 = (srcPixelPtr[0] * xf0 + srcPixelPtr[1] * xf1 + 159 srcPixelPtr[2] * xf2 + srcPixelPtr[3] * xf3 + ROUND_X) >> SHIFT_X; 160 srcPixelPtr = (DTYPE *) ((mlib_addr) srcPixelPtr + srcYStride); 161 c2 = (srcPixelPtr[0] * xf0 + srcPixelPtr[1] * xf1 + 162 srcPixelPtr[2] * xf2 + srcPixelPtr[3] * xf3 + ROUND_X) >> SHIFT_X; 163 srcPixelPtr = (DTYPE *) ((mlib_addr) srcPixelPtr + srcYStride); 164 c3 = (srcPixelPtr[0] * xf0 + srcPixelPtr[1] * xf1 + 165 srcPixelPtr[2] * xf2 + srcPixelPtr[3] * xf3 + ROUND_X) >> SHIFT_X; 166 167 filterpos = (X >> FILTER_SHIFT) & FILTER_MASK; 168 fptr = (mlib_s16 *) ((mlib_u8 *) mlib_filters_table + filterpos); 169 170 xf0 = fptr[0]; 171 xf1 = fptr[1]; 172 xf2 = fptr[2]; 173 xf3 = fptr[3]; 174 175 val0 = (c0 * yf0 + c1 * yf1 + c2 * yf2 + c3 * yf3 + ROUND_Y) >> SHIFT_Y; 176 177 filterpos = (Y >> FILTER_SHIFT) & FILTER_MASK; 178 fptr = (mlib_s16 *) ((mlib_u8 *) mlib_filters_table + filterpos); 179 180 yf0 = fptr[0]; 181 yf1 = fptr[1]; 182 yf2 = fptr[2]; 183 yf3 = fptr[3]; 184 185 S32_TO_U8_SAT(dstPixelPtr[0]); 186 187 xSrc = (X >> MLIB_SHIFT) - 1; 188 ySrc = (Y >> MLIB_SHIFT) - 1; 189 190 srcPixelPtr = ((DTYPE **) lineAddr)[ySrc] + xSrc; 191 s0 = srcPixelPtr[0]; 192 s1 = srcPixelPtr[1]; 193 s2 = srcPixelPtr[2]; 194 s3 = srcPixelPtr[3]; 195 } 196 197 c0 = (s0 * xf0 + s1 * xf1 + s2 * xf2 + s3 * xf3 + ROUND_X) >> SHIFT_X; 198 srcPixelPtr = (DTYPE *) ((mlib_addr) srcPixelPtr + srcYStride); 199 c1 = (srcPixelPtr[0] * xf0 + srcPixelPtr[1] * xf1 + 200 srcPixelPtr[2] * xf2 + srcPixelPtr[3] * xf3 + ROUND_X) >> SHIFT_X; 201 srcPixelPtr = (DTYPE *) ((mlib_addr) srcPixelPtr + srcYStride); 202 c2 = (srcPixelPtr[0] * xf0 + srcPixelPtr[1] * xf1 + 203 srcPixelPtr[2] * xf2 + srcPixelPtr[3] * xf3 + ROUND_X) >> SHIFT_X; 204 srcPixelPtr = (DTYPE *) ((mlib_addr) srcPixelPtr + srcYStride); 205 c3 = (srcPixelPtr[0] * xf0 + srcPixelPtr[1] * xf1 + 206 srcPixelPtr[2] * xf2 + srcPixelPtr[3] * xf3 + ROUND_X) >> SHIFT_X; 207 208 val0 = (c0 * yf0 + c1 * yf1 + c2 * yf2 + c3 * yf3 + ROUND_Y) >> SHIFT_Y; 209 210 S32_TO_U8_SAT(dstPixelPtr[0]); 211 } 212 213 return MLIB_SUCCESS; 214 } 215 216 /***************************************************************/ 217 mlib_status FUN_NAME(2ch)(mlib_affine_param *param) 218 { 219 DECLAREVAR_BC(); 220 DTYPE *dstLineEnd; 221 const mlib_s16 *mlib_filters_table; 222 223 if (filter == MLIB_BICUBIC) { 224 mlib_filters_table = (mlib_s16 *) mlib_filters_u8_bc; 225 } 226 else { 227 mlib_filters_table = (mlib_s16 *) mlib_filters_u8_bc2; 228 } 229 230 for (j = yStart; j <= yFinish; j++) { 231 mlib_s32 xf0, xf1, xf2, xf3; 232 mlib_s32 yf0, yf1, yf2, yf3; 233 mlib_s32 c0, c1, c2, c3, val0; 234 mlib_s32 filterpos, k; 235 mlib_s16 *fptr; 236 mlib_u8 s0, s1, s2, s3; 237 238 CLIP(2); 239 dstLineEnd = (DTYPE *) dstData + 2 * xRight; 240 241 for (k = 0; k < 2; k++) { 242 mlib_s32 X1 = X; 243 mlib_s32 Y1 = Y; 244 DTYPE *dPtr = dstPixelPtr + k; 245 246 filterpos = (X1 >> FILTER_SHIFT) & FILTER_MASK; 247 fptr = (mlib_s16 *) ((mlib_u8 *) mlib_filters_table + filterpos); 248 249 xf0 = fptr[0]; 250 xf1 = fptr[1]; 251 xf2 = fptr[2]; 252 xf3 = fptr[3]; 253 254 filterpos = (Y1 >> FILTER_SHIFT) & FILTER_MASK; 255 fptr = (mlib_s16 *) ((mlib_u8 *) mlib_filters_table + filterpos); 256 257 yf0 = fptr[0]; 258 yf1 = fptr[1]; 259 yf2 = fptr[2]; 260 yf3 = fptr[3]; 261 262 xSrc = (X1 >> MLIB_SHIFT) - 1; 263 ySrc = (Y1 >> MLIB_SHIFT) - 1; 264 265 srcPixelPtr = ((DTYPE **) lineAddr)[ySrc] + 2 * xSrc + k; 266 s0 = srcPixelPtr[0]; 267 s1 = srcPixelPtr[2]; 268 s2 = srcPixelPtr[4]; 269 s3 = srcPixelPtr[6]; 270 271 for (; dPtr <= (dstLineEnd - 1); dPtr += 2) { 272 X1 += dX; 273 Y1 += dY; 274 275 c0 = (s0 * xf0 + s1 * xf1 + s2 * xf2 + s3 * xf3 + ROUND_X) >> SHIFT_X; 276 srcPixelPtr = (DTYPE *) ((mlib_addr) srcPixelPtr + srcYStride); 277 c1 = (srcPixelPtr[0] * xf0 + srcPixelPtr[2] * xf1 + 278 srcPixelPtr[4] * xf2 + srcPixelPtr[6] * xf3 + ROUND_X) >> SHIFT_X; 279 srcPixelPtr = (DTYPE *) ((mlib_addr) srcPixelPtr + srcYStride); 280 c2 = (srcPixelPtr[0] * xf0 + srcPixelPtr[2] * xf1 + 281 srcPixelPtr[4] * xf2 + srcPixelPtr[6] * xf3 + ROUND_X) >> SHIFT_X; 282 srcPixelPtr = (DTYPE *) ((mlib_addr) srcPixelPtr + srcYStride); 283 c3 = (srcPixelPtr[0] * xf0 + srcPixelPtr[2] * xf1 + 284 srcPixelPtr[4] * xf2 + srcPixelPtr[6] * xf3 + ROUND_X) >> SHIFT_X; 285 286 filterpos = (X1 >> FILTER_SHIFT) & FILTER_MASK; 287 fptr = (mlib_s16 *) ((mlib_u8 *) mlib_filters_table + filterpos); 288 289 xf0 = fptr[0]; 290 xf1 = fptr[1]; 291 xf2 = fptr[2]; 292 xf3 = fptr[3]; 293 294 val0 = (c0 * yf0 + c1 * yf1 + c2 * yf2 + c3 * yf3 + ROUND_Y) >> SHIFT_Y; 295 296 filterpos = (Y1 >> FILTER_SHIFT) & FILTER_MASK; 297 fptr = (mlib_s16 *) ((mlib_u8 *) mlib_filters_table + filterpos); 298 299 yf0 = fptr[0]; 300 yf1 = fptr[1]; 301 yf2 = fptr[2]; 302 yf3 = fptr[3]; 303 304 S32_TO_U8_SAT(dPtr[0]); 305 306 xSrc = (X1 >> MLIB_SHIFT) - 1; 307 ySrc = (Y1 >> MLIB_SHIFT) - 1; 308 309 srcPixelPtr = ((DTYPE **) lineAddr)[ySrc] + 2 * xSrc + k; 310 s0 = srcPixelPtr[0]; 311 s1 = srcPixelPtr[2]; 312 s2 = srcPixelPtr[4]; 313 s3 = srcPixelPtr[6]; 314 } 315 316 c0 = (s0 * xf0 + s1 * xf1 + s2 * xf2 + s3 * xf3 + ROUND_X) >> SHIFT_X; 317 srcPixelPtr = (DTYPE *) ((mlib_addr) srcPixelPtr + srcYStride); 318 c1 = (srcPixelPtr[0] * xf0 + srcPixelPtr[2] * xf1 + 319 srcPixelPtr[4] * xf2 + srcPixelPtr[6] * xf3 + ROUND_X) >> SHIFT_X; 320 srcPixelPtr = (DTYPE *) ((mlib_addr) srcPixelPtr + srcYStride); 321 c2 = (srcPixelPtr[0] * xf0 + srcPixelPtr[2] * xf1 + 322 srcPixelPtr[4] * xf2 + srcPixelPtr[6] * xf3 + ROUND_X) >> SHIFT_X; 323 srcPixelPtr = (DTYPE *) ((mlib_addr) srcPixelPtr + srcYStride); 324 c3 = (srcPixelPtr[0] * xf0 + srcPixelPtr[2] * xf1 + 325 srcPixelPtr[4] * xf2 + srcPixelPtr[6] * xf3 + ROUND_X) >> SHIFT_X; 326 327 val0 = (c0 * yf0 + c1 * yf1 + c2 * yf2 + c3 * yf3 + ROUND_Y) >> SHIFT_Y; 328 329 S32_TO_U8_SAT(dPtr[0]); 330 } 331 } 332 333 return MLIB_SUCCESS; 334 } 335 336 /***************************************************************/ 337 mlib_status FUN_NAME(3ch)(mlib_affine_param *param) 338 { 339 DECLAREVAR_BC(); 340 DTYPE *dstLineEnd; 341 const mlib_s16 *mlib_filters_table; 342 343 if (filter == MLIB_BICUBIC) { 344 mlib_filters_table = (mlib_s16 *) mlib_filters_u8_bc; 345 } 346 else { 347 mlib_filters_table = (mlib_s16 *) mlib_filters_u8_bc2; 348 } 349 350 for (j = yStart; j <= yFinish; j++) { 351 mlib_s32 xf0, xf1, xf2, xf3; 352 mlib_s32 yf0, yf1, yf2, yf3; 353 mlib_s32 c0, c1, c2, c3, val0; 354 mlib_s32 filterpos, k; 355 mlib_s16 *fptr; 356 mlib_u8 s0, s1, s2, s3; 357 358 CLIP(3); 359 dstLineEnd = (DTYPE *) dstData + 3 * xRight; 360 361 for (k = 0; k < 3; k++) { 362 mlib_s32 X1 = X; 363 mlib_s32 Y1 = Y; 364 DTYPE *dPtr = dstPixelPtr + k; 365 366 filterpos = (X1 >> FILTER_SHIFT) & FILTER_MASK; 367 fptr = (mlib_s16 *) ((mlib_u8 *) mlib_filters_table + filterpos); 368 369 xf0 = fptr[0]; 370 xf1 = fptr[1]; 371 xf2 = fptr[2]; 372 xf3 = fptr[3]; 373 374 filterpos = (Y1 >> FILTER_SHIFT) & FILTER_MASK; 375 fptr = (mlib_s16 *) ((mlib_u8 *) mlib_filters_table + filterpos); 376 377 yf0 = fptr[0]; 378 yf1 = fptr[1]; 379 yf2 = fptr[2]; 380 yf3 = fptr[3]; 381 382 xSrc = (X1 >> MLIB_SHIFT) - 1; 383 ySrc = (Y1 >> MLIB_SHIFT) - 1; 384 385 srcPixelPtr = ((DTYPE **) lineAddr)[ySrc] + 3 * xSrc + k; 386 s0 = srcPixelPtr[0]; 387 s1 = srcPixelPtr[3]; 388 s2 = srcPixelPtr[6]; 389 s3 = srcPixelPtr[9]; 390 391 for (; dPtr <= (dstLineEnd - 1); dPtr += 3) { 392 X1 += dX; 393 Y1 += dY; 394 395 c0 = (s0 * xf0 + s1 * xf1 + s2 * xf2 + s3 * xf3 + ROUND_X) >> SHIFT_X; 396 srcPixelPtr = (DTYPE *) ((mlib_addr) srcPixelPtr + srcYStride); 397 c1 = (srcPixelPtr[0] * xf0 + srcPixelPtr[3] * xf1 + 398 srcPixelPtr[6] * xf2 + srcPixelPtr[9] * xf3 + ROUND_X) >> SHIFT_X; 399 srcPixelPtr = (DTYPE *) ((mlib_addr) srcPixelPtr + srcYStride); 400 c2 = (srcPixelPtr[0] * xf0 + srcPixelPtr[3] * xf1 + 401 srcPixelPtr[6] * xf2 + srcPixelPtr[9] * xf3 + ROUND_X) >> SHIFT_X; 402 srcPixelPtr = (DTYPE *) ((mlib_addr) srcPixelPtr + srcYStride); 403 c3 = (srcPixelPtr[0] * xf0 + srcPixelPtr[3] * xf1 + 404 srcPixelPtr[6] * xf2 + srcPixelPtr[9] * xf3 + ROUND_X) >> SHIFT_X; 405 406 filterpos = (X1 >> FILTER_SHIFT) & FILTER_MASK; 407 fptr = (mlib_s16 *) ((mlib_u8 *) mlib_filters_table + filterpos); 408 409 xf0 = fptr[0]; 410 xf1 = fptr[1]; 411 xf2 = fptr[2]; 412 xf3 = fptr[3]; 413 414 val0 = (c0 * yf0 + c1 * yf1 + c2 * yf2 + c3 * yf3 + ROUND_Y) >> SHIFT_Y; 415 416 filterpos = (Y1 >> FILTER_SHIFT) & FILTER_MASK; 417 fptr = (mlib_s16 *) ((mlib_u8 *) mlib_filters_table + filterpos); 418 419 yf0 = fptr[0]; 420 yf1 = fptr[1]; 421 yf2 = fptr[2]; 422 yf3 = fptr[3]; 423 424 S32_TO_U8_SAT(dPtr[0]); 425 426 xSrc = (X1 >> MLIB_SHIFT) - 1; 427 ySrc = (Y1 >> MLIB_SHIFT) - 1; 428 429 srcPixelPtr = ((DTYPE **) lineAddr)[ySrc] + 3 * xSrc + k; 430 s0 = srcPixelPtr[0]; 431 s1 = srcPixelPtr[3]; 432 s2 = srcPixelPtr[6]; 433 s3 = srcPixelPtr[9]; 434 } 435 436 c0 = (s0 * xf0 + s1 * xf1 + s2 * xf2 + s3 * xf3 + ROUND_X) >> SHIFT_X; 437 srcPixelPtr = (DTYPE *) ((mlib_addr) srcPixelPtr + srcYStride); 438 c1 = (srcPixelPtr[0] * xf0 + srcPixelPtr[3] * xf1 + 439 srcPixelPtr[6] * xf2 + srcPixelPtr[9] * xf3 + ROUND_X) >> SHIFT_X; 440 srcPixelPtr = (DTYPE *) ((mlib_addr) srcPixelPtr + srcYStride); 441 c2 = (srcPixelPtr[0] * xf0 + srcPixelPtr[3] * xf1 + 442 srcPixelPtr[6] * xf2 + srcPixelPtr[9] * xf3 + ROUND_X) >> SHIFT_X; 443 srcPixelPtr = (DTYPE *) ((mlib_addr) srcPixelPtr + srcYStride); 444 c3 = (srcPixelPtr[0] * xf0 + srcPixelPtr[3] * xf1 + 445 srcPixelPtr[6] * xf2 + srcPixelPtr[9] * xf3 + ROUND_X) >> SHIFT_X; 446 447 val0 = (c0 * yf0 + c1 * yf1 + c2 * yf2 + c3 * yf3 + ROUND_Y) >> SHIFT_Y; 448 449 S32_TO_U8_SAT(dPtr[0]); 450 } 451 } 452 453 return MLIB_SUCCESS; 454 } 455 456 /***************************************************************/ 457 mlib_status FUN_NAME(4ch)(mlib_affine_param *param) 458 { 459 DECLAREVAR_BC(); 460 DTYPE *dstLineEnd; 461 const mlib_s16 *mlib_filters_table; 462 463 if (filter == MLIB_BICUBIC) { 464 mlib_filters_table = (mlib_s16 *) mlib_filters_u8_bc; 465 } 466 else { 467 mlib_filters_table = (mlib_s16 *) mlib_filters_u8_bc2; 468 } 469 470 for (j = yStart; j <= yFinish; j++) { 471 mlib_s32 xf0, xf1, xf2, xf3; 472 mlib_s32 yf0, yf1, yf2, yf3; 473 mlib_s32 c0, c1, c2, c3, val0; 474 mlib_s32 filterpos, k; 475 mlib_s16 *fptr; 476 mlib_u8 s0, s1, s2, s3; 477 478 CLIP(4); 479 dstLineEnd = (DTYPE *) dstData + 4 * xRight; 480 481 for (k = 0; k < 4; k++) { 482 mlib_s32 X1 = X; 483 mlib_s32 Y1 = Y; 484 DTYPE *dPtr = dstPixelPtr + k; 485 486 filterpos = (X1 >> FILTER_SHIFT) & FILTER_MASK; 487 fptr = (mlib_s16 *) ((mlib_u8 *) mlib_filters_table + filterpos); 488 489 xf0 = fptr[0]; 490 xf1 = fptr[1]; 491 xf2 = fptr[2]; 492 xf3 = fptr[3]; 493 494 filterpos = (Y1 >> FILTER_SHIFT) & FILTER_MASK; 495 fptr = (mlib_s16 *) ((mlib_u8 *) mlib_filters_table + filterpos); 496 497 yf0 = fptr[0]; 498 yf1 = fptr[1]; 499 yf2 = fptr[2]; 500 yf3 = fptr[3]; 501 502 xSrc = (X1 >> MLIB_SHIFT) - 1; 503 ySrc = (Y1 >> MLIB_SHIFT) - 1; 504 505 srcPixelPtr = ((DTYPE **) lineAddr)[ySrc] + 4 * xSrc + k; 506 s0 = srcPixelPtr[0]; 507 s1 = srcPixelPtr[4]; 508 s2 = srcPixelPtr[8]; 509 s3 = srcPixelPtr[12]; 510 511 for (; dPtr <= (dstLineEnd - 1); dPtr += 4) { 512 X1 += dX; 513 Y1 += dY; 514 515 c0 = (s0 * xf0 + s1 * xf1 + s2 * xf2 + s3 * xf3 + ROUND_X) >> SHIFT_X; 516 srcPixelPtr = (DTYPE *) ((mlib_addr) srcPixelPtr + srcYStride); 517 c1 = (srcPixelPtr[0] * xf0 + srcPixelPtr[4] * xf1 + 518 srcPixelPtr[8] * xf2 + srcPixelPtr[12] * xf3 + ROUND_X) >> SHIFT_X; 519 srcPixelPtr = (DTYPE *) ((mlib_addr) srcPixelPtr + srcYStride); 520 c2 = (srcPixelPtr[0] * xf0 + srcPixelPtr[4] * xf1 + 521 srcPixelPtr[8] * xf2 + srcPixelPtr[12] * xf3 + ROUND_X) >> SHIFT_X; 522 srcPixelPtr = (DTYPE *) ((mlib_addr) srcPixelPtr + srcYStride); 523 c3 = (srcPixelPtr[0] * xf0 + srcPixelPtr[4] * xf1 + 524 srcPixelPtr[8] * xf2 + srcPixelPtr[12] * xf3 + ROUND_X) >> SHIFT_X; 525 526 filterpos = (X1 >> FILTER_SHIFT) & FILTER_MASK; 527 fptr = (mlib_s16 *) ((mlib_u8 *) mlib_filters_table + filterpos); 528 529 xf0 = fptr[0]; 530 xf1 = fptr[1]; 531 xf2 = fptr[2]; 532 xf3 = fptr[3]; 533 534 val0 = (c0 * yf0 + c1 * yf1 + c2 * yf2 + c3 * yf3 + ROUND_Y) >> SHIFT_Y; 535 536 filterpos = (Y1 >> FILTER_SHIFT) & FILTER_MASK; 537 fptr = (mlib_s16 *) ((mlib_u8 *) mlib_filters_table + filterpos); 538 539 yf0 = fptr[0]; 540 yf1 = fptr[1]; 541 yf2 = fptr[2]; 542 yf3 = fptr[3]; 543 544 S32_TO_U8_SAT(dPtr[0]); 545 546 xSrc = (X1 >> MLIB_SHIFT) - 1; 547 ySrc = (Y1 >> MLIB_SHIFT) - 1; 548 549 srcPixelPtr = ((DTYPE **) lineAddr)[ySrc] + 4 * xSrc + k; 550 s0 = srcPixelPtr[0]; 551 s1 = srcPixelPtr[4]; 552 s2 = srcPixelPtr[8]; 553 s3 = srcPixelPtr[12]; 554 } 555 556 c0 = (s0 * xf0 + s1 * xf1 + s2 * xf2 + s3 * xf3 + ROUND_X) >> SHIFT_X; 557 srcPixelPtr = (DTYPE *) ((mlib_addr) srcPixelPtr + srcYStride); 558 c1 = (srcPixelPtr[0] * xf0 + srcPixelPtr[4] * xf1 + 559 srcPixelPtr[8] * xf2 + srcPixelPtr[12] * xf3 + ROUND_X) >> SHIFT_X; 560 srcPixelPtr = (DTYPE *) ((mlib_addr) srcPixelPtr + srcYStride); 561 c2 = (srcPixelPtr[0] * xf0 + srcPixelPtr[4] * xf1 + 562 srcPixelPtr[8] * xf2 + srcPixelPtr[12] * xf3 + ROUND_X) >> SHIFT_X; 563 srcPixelPtr = (DTYPE *) ((mlib_addr) srcPixelPtr + srcYStride); 564 c3 = (srcPixelPtr[0] * xf0 + srcPixelPtr[4] * xf1 + 565 srcPixelPtr[8] * xf2 + srcPixelPtr[12] * xf3 + ROUND_X) >> SHIFT_X; 566 567 val0 = (c0 * yf0 + c1 * yf1 + c2 * yf2 + c3 * yf3 + ROUND_Y) >> SHIFT_Y; 568 569 S32_TO_U8_SAT(dPtr[0]); 570 } 571 } 572 573 return MLIB_SUCCESS; 574 } 575 576 /***************************************************************/