1 /* 2 * Copyright (c) 2000, 2013, 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 * Internal functions for mlib_ImageConv* on S32 type and 30 * MLIB_EDGE_DST_NO_WRITE mask 31 * 32 */ 33 34 #include "mlib_image.h" 35 #include "mlib_ImageConv.h" 36 37 /***************************************************************/ 38 #define CACHE_SIZE (64*1024) 39 40 /***************************************************************/ 41 #define CONV_FUNC(KERN) mlib_conv##KERN##nw_s32 42 43 /***************************************************************/ 44 #ifndef MLIB_USE_FTOI_CLAMPING 45 46 #define CLAMP_S32(dst, src) \ 47 if (src > (mlib_d64)MLIB_S32_MAX) src = (mlib_d64)MLIB_S32_MAX; \ 48 if (src < (mlib_d64)MLIB_S32_MIN) src = (mlib_d64)MLIB_S32_MIN; \ 49 dst = (mlib_s32)src 50 51 #else 52 53 #define CLAMP_S32(dst, src) dst = (mlib_s32)(src) 54 55 #endif /* MLIB_USE_FTOI_CLAMPING */ 56 57 /***************************************************************/ 58 #define GET_SRC_DST_PARAMETERS(type) \ 59 mlib_s32 hgt = mlib_ImageGetHeight(src); \ 60 mlib_s32 wid = mlib_ImageGetWidth(src); \ 61 mlib_s32 sll = mlib_ImageGetStride(src) / sizeof(type); \ 62 mlib_s32 dll = mlib_ImageGetStride(dst) / sizeof(type); \ 63 type* adr_src = mlib_ImageGetData(src); \ 64 type* adr_dst = mlib_ImageGetData(dst); \ 65 mlib_s32 chan1 = mlib_ImageGetChannels(src) 66 /* mlib_s32 chan2 = chan1 + chan1 */ 67 68 /***************************************************************/ 69 #define DEF_VARS(type) \ 70 GET_SRC_DST_PARAMETERS(type); \ 71 type *sl, *sp, *sl1, *dl, *dp; \ 72 mlib_d64 *pbuff = buff, *buff0, *buff1, *buff2, *buffT; \ 73 mlib_s32 i, j, c; \ 74 mlib_d64 scalef, d0, d1 75 76 /***************************************************************/ 77 #define DEF_VARS_MxN(type) \ 78 GET_SRC_DST_PARAMETERS(type); \ 79 type *sl, *sp = NULL, *dl, *dp = NULL; \ 80 mlib_d64 *pbuff = buff; \ 81 mlib_s32 i, j, c 82 83 /***************************************************************/ 84 #define FTYPE mlib_d64 85 #define DTYPE mlib_s32 86 87 #define BUFF_SIZE 1600 88 89 static mlib_status mlib_ImageConv1xN(mlib_image *dst, 90 const mlib_image *src, 91 const mlib_d64 *k, 92 mlib_s32 n, 93 mlib_s32 dn, 94 mlib_s32 cmask) 95 { 96 FTYPE buff[BUFF_SIZE]; 97 mlib_s32 off, kh; 98 const FTYPE *pk; 99 FTYPE k0, k1, k2, k3, d0, d1; 100 FTYPE p0, p1, p2, p3, p4; 101 DTYPE *sl_c, *dl_c, *sl0; 102 mlib_s32 l, hsize, max_hsize; 103 DEF_VARS_MxN(DTYPE); 104 105 hgt -= (n - 1); 106 adr_dst += dn*dll; 107 108 max_hsize = (CACHE_SIZE/sizeof(DTYPE))/sll; 109 110 if (!max_hsize) max_hsize = 1; 111 112 if (max_hsize > BUFF_SIZE) { 113 pbuff = mlib_malloc(sizeof(FTYPE)*max_hsize); 114 } 115 116 sl_c = adr_src; 117 dl_c = adr_dst; 118 119 for (l = 0; l < hgt; l += hsize) { 120 hsize = hgt - l; 121 122 if (hsize > max_hsize) hsize = max_hsize; 123 124 for (c = 0; c < chan1; c++) { 125 if (!(cmask & (1 << (chan1 - 1 - c)))) continue; 126 127 sl = sl_c + c; 128 dl = dl_c + c; 129 130 #ifdef __SUNPRO_C 131 #pragma pipeloop(0) 132 #endif /* __SUNPRO_C */ 133 for (j = 0; j < hsize; j++) pbuff[j] = 0.0; 134 135 for (i = 0; i < wid; i++) { 136 sl0 = sl; 137 138 for (off = 0; off < (n - 4); off += 4) { 139 pk = k + off; 140 sp = sl0; 141 142 k0 = pk[0]; k1 = pk[1]; k2 = pk[2]; k3 = pk[3]; 143 p2 = sp[0]; p3 = sp[sll]; p4 = sp[2*sll]; 144 sp += 3*sll; 145 146 #ifdef __SUNPRO_C 147 #pragma pipeloop(0) 148 #endif /* __SUNPRO_C */ 149 for (j = 0; j < hsize; j += 2) { 150 p0 = p2; p1 = p3; p2 = p4; 151 p3 = sp[0]; 152 p4 = sp[sll]; 153 154 pbuff[j ] += p0*k0 + p1*k1 + p2*k2 + p3*k3; 155 pbuff[j + 1] += p1*k0 + p2*k1 + p3*k2 + p4*k3; 156 157 sp += 2*sll; 158 } 159 160 sl0 += 4*sll; 161 } 162 163 pk = k + off; 164 sp = sl0; 165 166 k0 = pk[0]; k1 = pk[1]; k2 = pk[2]; k3 = pk[3]; 167 p2 = sp[0]; p3 = sp[sll]; p4 = sp[2*sll]; 168 169 dp = dl; 170 kh = n - off; 171 172 if (kh == 4) { 173 sp += 3*sll; 174 175 #ifdef __SUNPRO_C 176 #pragma pipeloop(0) 177 #endif /* __SUNPRO_C */ 178 for (j = 0; j <= (hsize - 2); j += 2) { 179 p0 = p2; p1 = p3; p2 = p4; 180 p3 = sp[0]; 181 p4 = sp[sll]; 182 183 d0 = p0*k0 + p1*k1 + p2*k2 + p3*k3 + pbuff[j]; 184 d1 = p1*k0 + p2*k1 + p3*k2 + p4*k3 + pbuff[j + 1]; 185 CLAMP_S32(dp[0 ], d0); 186 CLAMP_S32(dp[dll], d1); 187 188 pbuff[j] = 0; 189 pbuff[j + 1] = 0; 190 191 sp += 2*sll; 192 dp += 2*dll; 193 } 194 195 if (j < hsize) { 196 p0 = p2; p1 = p3; p2 = p4; 197 p3 = sp[0]; 198 199 d0 = p0*k0 + p1*k1 + p2*k2 + p3*k3 + pbuff[j]; 200 CLAMP_S32(dp[0], d0); 201 202 pbuff[j] = 0; 203 } 204 205 } else if (kh == 3) { 206 sp += 2*sll; 207 208 #ifdef __SUNPRO_C 209 #pragma pipeloop(0) 210 #endif /* __SUNPRO_C */ 211 for (j = 0; j <= (hsize - 2); j += 2) { 212 p0 = p2; p1 = p3; 213 p2 = sp[0]; 214 p3 = sp[sll]; 215 216 d0 = p0*k0 + p1*k1 + p2*k2 + pbuff[j]; 217 d1 = p1*k0 + p2*k1 + p3*k2 + pbuff[j + 1]; 218 CLAMP_S32(dp[0 ], d0); 219 CLAMP_S32(dp[dll], d1); 220 221 pbuff[j] = 0; 222 pbuff[j + 1] = 0; 223 224 sp += 2*sll; 225 dp += 2*dll; 226 } 227 228 if (j < hsize) { 229 p0 = p2; p1 = p3; 230 p2 = sp[0]; 231 232 d0 = p0*k0 + p1*k1 + p2*k2 + pbuff[j]; 233 CLAMP_S32(dp[0], d0); 234 235 pbuff[j] = 0; 236 } 237 238 } else if (kh == 2) { 239 sp += sll; 240 241 #ifdef __SUNPRO_C 242 #pragma pipeloop(0) 243 #endif /* __SUNPRO_C */ 244 for (j = 0; j <= (hsize - 2); j += 2) { 245 p0 = p2; 246 p1 = sp[0]; 247 p2 = sp[sll]; 248 249 d0 = p0*k0 + p1*k1 + pbuff[j]; 250 d1 = p1*k0 + p2*k1 + pbuff[j + 1]; 251 CLAMP_S32(dp[0 ], d0); 252 CLAMP_S32(dp[dll], d1); 253 254 pbuff[j] = 0; 255 pbuff[j + 1] = 0; 256 257 sp += 2*sll; 258 dp += 2*dll; 259 } 260 261 if (j < hsize) { 262 p0 = p2; 263 p1 = sp[0]; 264 265 d0 = p0*k0 + p1*k1 + pbuff[j]; 266 CLAMP_S32(dp[0], d0); 267 268 pbuff[j] = 0; 269 } 270 271 } else /* if (kh == 1) */ { 272 #ifdef __SUNPRO_C 273 #pragma pipeloop(0) 274 #endif /* __SUNPRO_C */ 275 for (j = 0; j < hsize; j++) { 276 p0 = sp[0]; 277 278 d0 = p0*k0 + pbuff[j]; 279 CLAMP_S32(dp[0], d0); 280 281 pbuff[j] = 0; 282 283 sp += sll; 284 dp += dll; 285 } 286 } 287 288 sl += chan1; 289 dl += chan1; 290 } 291 } 292 293 sl_c += max_hsize*sll; 294 dl_c += max_hsize*dll; 295 } 296 297 if (pbuff != buff) mlib_free(pbuff); 298 299 return MLIB_SUCCESS; 300 } 301 302 /***************************************************************/ 303 #define MAX_KER 7 304 305 #define MAX_N 15 306 307 #undef BUFF_SIZE 308 #define BUFF_SIZE 1500 309 310 mlib_status CONV_FUNC(MxN)(mlib_image *dst, 311 const mlib_image *src, 312 const mlib_s32 *kernel, 313 mlib_s32 m, 314 mlib_s32 n, 315 mlib_s32 dm, 316 mlib_s32 dn, 317 mlib_s32 scale, 318 mlib_s32 cmask) 319 { 320 mlib_d64 buff[BUFF_SIZE], *buffs_arr[2*(MAX_N + 1)]; 321 mlib_d64 **buffs = buffs_arr, *buffd; 322 mlib_d64 akernel[256], *k = akernel, fscale = 1.0; 323 mlib_s32 l, off, kw, bsize, buff_ind, mn; 324 mlib_d64 d0, d1; 325 mlib_d64 k0, k1, k2, k3, k4, k5, k6; 326 mlib_d64 p0, p1, p2, p3, p4, p5, p6, p7; 327 DEF_VARS_MxN(mlib_s32); 328 mlib_s32 chan2 = chan1 + chan1; 329 330 mlib_status status = MLIB_SUCCESS; 331 332 if (scale > 30) { 333 fscale *= 1.0/(1 << 30); 334 scale -= 30; 335 } 336 337 fscale /= (1 << scale); 338 339 mn = m*n; 340 341 if (mn > 256) { 342 k = mlib_malloc(mn*sizeof(mlib_d64)); 343 344 if (k == NULL) return MLIB_FAILURE; 345 } 346 347 for (i = 0; i < mn; i++) { 348 k[i] = kernel[i]*fscale; 349 } 350 351 if (m == 1) { 352 status = mlib_ImageConv1xN(dst, src, k, n, dn, cmask); 353 FREE_AND_RETURN_STATUS; 354 } 355 356 bsize = (n + 2)*wid; 357 358 if ((bsize > BUFF_SIZE) || (n > MAX_N)) { 359 pbuff = mlib_malloc(sizeof(mlib_d64)*bsize + sizeof(mlib_d64*)*2*(n + 1)); 360 361 if (pbuff == NULL) { 362 status = MLIB_FAILURE; 363 FREE_AND_RETURN_STATUS; 364 } 365 buffs = (mlib_d64**)(pbuff + bsize); 366 } 367 368 for (l = 0; l < (n + 1); l++) buffs[l] = pbuff + l*wid; 369 for (l = 0; l < (n + 1); l++) buffs[l + (n + 1)] = buffs[l]; 370 buffd = buffs[n] + wid; 371 372 wid -= (m - 1); 373 hgt -= (n - 1); 374 adr_dst += dn*dll + dm*chan1; 375 376 for (c = 0; c < chan1; c++) { 377 if (!(cmask & (1 << (chan1 - 1 - c)))) continue; 378 379 sl = adr_src + c; 380 dl = adr_dst + c; 381 382 for (l = 0; l < n; l++) { 383 mlib_d64 *buff = buffs[l]; 384 385 #ifdef __SUNPRO_C 386 #pragma pipeloop(0) 387 #endif /* __SUNPRO_C */ 388 for (i = 0; i < wid + (m - 1); i++) { 389 buff[i] = (mlib_d64)sl[i*chan1]; 390 } 391 392 sl += sll; 393 } 394 395 buff_ind = 0; 396 397 #ifdef __SUNPRO_C 398 #pragma pipeloop(0) 399 #endif /* __SUNPRO_C */ 400 for (i = 0; i < wid; i++) buffd[i] = 0.0; 401 402 for (j = 0; j < hgt; j++) { 403 mlib_d64 **buffc = buffs + buff_ind; 404 mlib_d64 *buffn = buffc[n]; 405 mlib_d64 *pk = k; 406 407 for (l = 0; l < n; l++) { 408 mlib_d64 *buff_l = buffc[l]; 409 410 for (off = 0; off < m;) { 411 mlib_d64 *buff = buff_l + off; 412 413 kw = m - off; 414 415 if (kw > 2*MAX_KER) kw = MAX_KER; else 416 if (kw > MAX_KER) kw = kw/2; 417 off += kw; 418 419 sp = sl; 420 dp = dl; 421 422 p2 = buff[0]; p3 = buff[1]; p4 = buff[2]; 423 p5 = buff[3]; p6 = buff[4]; p7 = buff[5]; 424 425 k0 = pk[0]; k1 = pk[1]; k2 = pk[2]; k3 = pk[3]; 426 k4 = pk[4]; k5 = pk[5]; k6 = pk[6]; 427 pk += kw; 428 429 if (kw == 7) { 430 431 if (l < (n - 1) || off < m) { 432 #ifdef __SUNPRO_C 433 #pragma pipeloop(0) 434 #endif /* __SUNPRO_C */ 435 for (i = 0; i <= (wid - 2); i += 2) { 436 p0 = p2; p1 = p3; p2 = p4; p3 = p5; p4 = p6; p5 = p7; 437 438 p6 = buff[i + 6]; p7 = buff[i + 7]; 439 440 buffd[i ] += p0*k0 + p1*k1 + p2*k2 + p3*k3 + p4*k4 + p5*k5 + p6*k6; 441 buffd[i + 1] += p1*k0 + p2*k1 + p3*k2 + p4*k3 + p5*k4 + p6*k5 + p7*k6; 442 } 443 444 } else { 445 #ifdef __SUNPRO_C 446 #pragma pipeloop(0) 447 #endif /* __SUNPRO_C */ 448 for (i = 0; i <= (wid - 2); i += 2) { 449 p0 = p2; p1 = p3; p2 = p4; p3 = p5; p4 = p6; p5 = p7; 450 451 p6 = buff[i + 6]; p7 = buff[i + 7]; 452 453 buffn[i ] = (mlib_d64)sp[0]; 454 buffn[i + 1] = (mlib_d64)sp[chan1]; 455 456 d0 = p0*k0 + p1*k1 + p2*k2 + p3*k3 + p4*k4 + p5*k5 + p6*k6 + buffd[i ]; 457 d1 = p1*k0 + p2*k1 + p3*k2 + p4*k3 + p5*k4 + p6*k5 + p7*k6 + buffd[i + 1]; 458 459 CLAMP_S32(dp[0], d0); 460 CLAMP_S32(dp[chan1], d1); 461 462 buffd[i ] = 0.0; 463 buffd[i + 1] = 0.0; 464 465 sp += chan2; 466 dp += chan2; 467 } 468 } 469 470 } else if (kw == 6) { 471 472 if (l < (n - 1) || off < m) { 473 #ifdef __SUNPRO_C 474 #pragma pipeloop(0) 475 #endif /* __SUNPRO_C */ 476 for (i = 0; i <= (wid - 2); i += 2) { 477 p0 = p2; p1 = p3; p2 = p4; p3 = p5; p4 = p6; 478 479 p5 = buff[i + 5]; p6 = buff[i + 6]; 480 481 buffd[i ] += p0*k0 + p1*k1 + p2*k2 + p3*k3 + p4*k4 + p5*k5; 482 buffd[i + 1] += p1*k0 + p2*k1 + p3*k2 + p4*k3 + p5*k4 + p6*k5; 483 } 484 485 } else { 486 #ifdef __SUNPRO_C 487 #pragma pipeloop(0) 488 #endif /* __SUNPRO_C */ 489 for (i = 0; i <= (wid - 2); i += 2) { 490 p0 = p2; p1 = p3; p2 = p4; p3 = p5; p4 = p6; 491 492 p5 = buff[i + 5]; p6 = buff[i + 6]; 493 494 buffn[i ] = (mlib_d64)sp[0]; 495 buffn[i + 1] = (mlib_d64)sp[chan1]; 496 497 d0 = p0*k0 + p1*k1 + p2*k2 + p3*k3 + p4*k4 + p5*k5 + buffd[i ]; 498 d1 = p1*k0 + p2*k1 + p3*k2 + p4*k3 + p5*k4 + p6*k5 + buffd[i + 1]; 499 500 CLAMP_S32(dp[0], d0); 501 CLAMP_S32(dp[chan1], d1); 502 503 buffd[i ] = 0.0; 504 buffd[i + 1] = 0.0; 505 506 sp += chan2; 507 dp += chan2; 508 } 509 } 510 511 } else if (kw == 5) { 512 513 if (l < (n - 1) || off < m) { 514 #ifdef __SUNPRO_C 515 #pragma pipeloop(0) 516 #endif /* __SUNPRO_C */ 517 for (i = 0; i <= (wid - 2); i += 2) { 518 p0 = p2; p1 = p3; p2 = p4; p3 = p5; 519 520 p4 = buff[i + 4]; p5 = buff[i + 5]; 521 522 buffd[i ] += p0*k0 + p1*k1 + p2*k2 + p3*k3 + p4*k4; 523 buffd[i + 1] += p1*k0 + p2*k1 + p3*k2 + p4*k3 + p5*k4; 524 } 525 526 } else { 527 #ifdef __SUNPRO_C 528 #pragma pipeloop(0) 529 #endif /* __SUNPRO_C */ 530 for (i = 0; i <= (wid - 2); i += 2) { 531 p0 = p2; p1 = p3; p2 = p4; p3 = p5; 532 533 p4 = buff[i + 4]; p5 = buff[i + 5]; 534 535 buffn[i ] = (mlib_d64)sp[0]; 536 buffn[i + 1] = (mlib_d64)sp[chan1]; 537 538 d0 = p0*k0 + p1*k1 + p2*k2 + p3*k3 + p4*k4 + buffd[i ]; 539 d1 = p1*k0 + p2*k1 + p3*k2 + p4*k3 + p5*k4 + buffd[i + 1]; 540 541 CLAMP_S32(dp[0], d0); 542 CLAMP_S32(dp[chan1], d1); 543 544 buffd[i ] = 0.0; 545 buffd[i + 1] = 0.0; 546 547 sp += chan2; 548 dp += chan2; 549 } 550 } 551 552 } else if (kw == 4) { 553 554 if (l < (n - 1) || off < m) { 555 #ifdef __SUNPRO_C 556 #pragma pipeloop(0) 557 #endif /* __SUNPRO_C */ 558 for (i = 0; i <= (wid - 2); i += 2) { 559 p0 = p2; p1 = p3; p2 = p4; 560 561 p3 = buff[i + 3]; p4 = buff[i + 4]; 562 563 buffd[i ] += p0*k0 + p1*k1 + p2*k2 + p3*k3; 564 buffd[i + 1] += p1*k0 + p2*k1 + p3*k2 + p4*k3; 565 } 566 567 } else { 568 #ifdef __SUNPRO_C 569 #pragma pipeloop(0) 570 #endif /* __SUNPRO_C */ 571 for (i = 0; i <= (wid - 2); i += 2) { 572 p0 = p2; p1 = p3; p2 = p4; 573 574 p3 = buff[i + 3]; p4 = buff[i + 4]; 575 576 buffn[i ] = (mlib_d64)sp[0]; 577 buffn[i + 1] = (mlib_d64)sp[chan1]; 578 579 d0 = p0*k0 + p1*k1 + p2*k2 + p3*k3 + buffd[i ]; 580 d1 = p1*k0 + p2*k1 + p3*k2 + p4*k3 + buffd[i + 1]; 581 582 CLAMP_S32(dp[0], d0); 583 CLAMP_S32(dp[chan1], d1); 584 585 buffd[i ] = 0.0; 586 buffd[i + 1] = 0.0; 587 588 sp += chan2; 589 dp += chan2; 590 } 591 } 592 593 } else if (kw == 3) { 594 595 if (l < (n - 1) || off < m) { 596 #ifdef __SUNPRO_C 597 #pragma pipeloop(0) 598 #endif /* __SUNPRO_C */ 599 for (i = 0; i <= (wid - 2); i += 2) { 600 p0 = p2; p1 = p3; 601 602 p2 = buff[i + 2]; p3 = buff[i + 3]; 603 604 buffd[i ] += p0*k0 + p1*k1 + p2*k2; 605 buffd[i + 1] += p1*k0 + p2*k1 + p3*k2; 606 } 607 608 } else { 609 #ifdef __SUNPRO_C 610 #pragma pipeloop(0) 611 #endif /* __SUNPRO_C */ 612 for (i = 0; i <= (wid - 2); i += 2) { 613 p0 = p2; p1 = p3; 614 615 p2 = buff[i + 2]; p3 = buff[i + 3]; 616 617 buffn[i ] = (mlib_d64)sp[0]; 618 buffn[i + 1] = (mlib_d64)sp[chan1]; 619 620 d0 = p0*k0 + p1*k1 + p2*k2 + buffd[i ]; 621 d1 = p1*k0 + p2*k1 + p3*k2 + buffd[i + 1]; 622 623 CLAMP_S32(dp[0], d0); 624 CLAMP_S32(dp[chan1], d1); 625 626 buffd[i ] = 0.0; 627 buffd[i + 1] = 0.0; 628 629 sp += chan2; 630 dp += chan2; 631 } 632 } 633 634 } else { /* kw == 2 */ 635 636 if (l < (n - 1) || off < m) { 637 #ifdef __SUNPRO_C 638 #pragma pipeloop(0) 639 #endif /* __SUNPRO_C */ 640 for (i = 0; i <= (wid - 2); i += 2) { 641 p0 = p2; 642 643 p1 = buff[i + 1]; p2 = buff[i + 2]; 644 645 buffd[i ] += p0*k0 + p1*k1; 646 buffd[i + 1] += p1*k0 + p2*k1; 647 } 648 649 } else { 650 #ifdef __SUNPRO_C 651 #pragma pipeloop(0) 652 #endif /* __SUNPRO_C */ 653 for (i = 0; i <= (wid - 2); i += 2) { 654 p0 = p2; 655 656 p1 = buff[i + 1]; p2 = buff[i + 2]; 657 658 buffn[i ] = (mlib_d64)sp[0]; 659 buffn[i + 1] = (mlib_d64)sp[chan1]; 660 661 d0 = p0*k0 + p1*k1 + buffd[i ]; 662 d1 = p1*k0 + p2*k1 + buffd[i + 1]; 663 664 CLAMP_S32(dp[0], d0); 665 CLAMP_S32(dp[chan1], d1); 666 667 buffd[i ] = 0.0; 668 buffd[i + 1] = 0.0; 669 670 sp += chan2; 671 dp += chan2; 672 } 673 } 674 } 675 } 676 } 677 678 /* last pixels */ 679 for (; i < wid; i++) { 680 mlib_d64 *pk = k, s = 0; 681 mlib_s32 x; 682 683 for (l = 0; l < n; l++) { 684 mlib_d64 *buff = buffc[l] + i; 685 686 for (x = 0; x < m; x++) s += buff[x] * (*pk++); 687 } 688 689 CLAMP_S32(dp[0], s); 690 691 buffn[i] = (mlib_d64)sp[0]; 692 693 sp += chan1; 694 dp += chan1; 695 } 696 697 for (l = 0; l < (m - 1); l++) buffn[wid + l] = sp[l*chan1]; 698 699 /* next line */ 700 sl += sll; 701 dl += dll; 702 703 buff_ind++; 704 705 if (buff_ind >= n + 1) buff_ind = 0; 706 } 707 } 708 709 FREE_AND_RETURN_STATUS; 710 } 711 712 /***************************************************************/