1 /* 2 * Copyright (c) 1997, 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 * mlib_ImageAffine_u8_1ch_nn 30 * mlib_ImageAffine_u8_2ch_nn 31 * mlib_ImageAffine_u8_3ch_nn 32 * mlib_ImageAffine_u8_4ch_nn 33 * mlib_ImageAffine_s16_1ch_nn 34 * mlib_ImageAffine_s16_2ch_nn 35 * mlib_ImageAffine_s16_3ch_nn 36 * mlib_ImageAffine_s16_4ch_nn 37 * - image affine transformation with Nearest Neighbor filtering 38 * SYNOPSIS 39 * mlib_status mlib_ImageAffine_[u8|s16]_?ch_nn(mlib_s32 *leftEdges, 40 * mlib_s32 *rightEdges, 41 * mlib_s32 *xStarts, 42 * mlib_s32 *yStarts, 43 * mlib_s32 *sides, 44 * mlib_u8 *dstData, 45 * mlib_u8 **lineAddr, 46 * mlib_s32 dstYStride, 47 * mlib_s32 is_affine) 48 * 49 * ARGUMENTS 50 * leftEdges array[dstHeight] of xLeft coordinates 51 * RightEdges array[dstHeight] of xRight coordinates 52 * xStarts array[dstHeight] of xStart * 65536 coordinates 53 * yStarts array[dstHeight] of yStart * 65536 coordinates 54 * sides output array[4]. sides[0] is yStart, sides[1] is yFinish, 55 * sides[2] is dx * 65536, sides[3] is dy * 65536 56 * dstData pointer to the first pixel on (yStart - 1) line 57 * lineAddr array[srcHeight] of pointers to the first pixel on 58 * the corresponding lines 59 * dstYStride stride of destination image 60 * is_affine indicator (Affine - GridWarp) 61 * 62 * DESCRIPTION 63 * The functions step along the lines from xLeft to xRight and get the 64 * nearest pixel values as being with the following coordinates 65 * ((xStart - (i - xLeft) * dx) >> 16, (yStart - (i - xLeft) * dy) >> 16) 66 * 67 */ 68 69 #include "mlib_ImageAffine.h" 70 71 /***************************************************************/ 72 #undef DTYPE 73 #define DTYPE mlib_u8 74 75 mlib_status mlib_ImageAffine_u8_1ch_nn(mlib_affine_param *param) 76 { 77 DECLAREVAR_NN(); 78 DTYPE *dstLineEnd; 79 80 for (j = yStart; j <= yFinish; j++) { 81 DTYPE pix0; 82 83 CLIP(1); 84 dstLineEnd = (DTYPE *) dstData + xRight; 85 86 for (; dstPixelPtr <= dstLineEnd; dstPixelPtr++) { 87 ySrc = MLIB_POINTER_SHIFT(Y); 88 Y += dY; 89 srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc); 90 xSrc = X >> MLIB_SHIFT; 91 X += dX; 92 pix0 = srcPixelPtr[xSrc]; 93 dstPixelPtr[0] = pix0; 94 } 95 } 96 97 return MLIB_SUCCESS; 98 } 99 100 /***************************************************************/ 101 mlib_status mlib_ImageAffine_u8_2ch_nn(mlib_affine_param *param) 102 { 103 DECLAREVAR_NN(); 104 DTYPE *dstLineEnd; 105 106 for (j = yStart; j <= yFinish; j++) { 107 DTYPE pix0, pix1; 108 109 CLIP(2); 110 dstLineEnd = (DTYPE *) dstData + 2 * xRight; 111 112 ySrc = MLIB_POINTER_SHIFT(Y); 113 Y += dY; 114 xSrc = X >> MLIB_SHIFT; 115 X += dX; 116 srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 2 * xSrc; 117 pix0 = srcPixelPtr[0]; 118 pix1 = srcPixelPtr[1]; 119 ySrc = MLIB_POINTER_SHIFT(Y); 120 Y += dY; 121 xSrc = X >> MLIB_SHIFT; 122 X += dX; 123 for (; dstPixelPtr < dstLineEnd; dstPixelPtr += 2) { 124 srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 2 * xSrc; 125 ySrc = MLIB_POINTER_SHIFT(Y); 126 Y += dY; 127 xSrc = X >> MLIB_SHIFT; 128 X += dX; 129 dstPixelPtr[0] = pix0; 130 dstPixelPtr[1] = pix1; 131 pix0 = srcPixelPtr[0]; 132 pix1 = srcPixelPtr[1]; 133 } 134 135 dstPixelPtr[0] = pix0; 136 dstPixelPtr[1] = pix1; 137 } 138 139 return MLIB_SUCCESS; 140 } 141 142 /***************************************************************/ 143 mlib_status mlib_ImageAffine_u8_3ch_nn(mlib_affine_param *param) 144 { 145 DECLAREVAR_NN(); 146 DTYPE *dstLineEnd; 147 148 for (j = yStart; j <= yFinish; j++) { 149 DTYPE pix0, pix1, pix2; 150 151 CLIP(3); 152 dstLineEnd = (DTYPE *) dstData + 3 * xRight; 153 154 ySrc = MLIB_POINTER_SHIFT(Y); 155 Y += dY; 156 xSrc = X >> MLIB_SHIFT; 157 X += dX; 158 srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 3 * xSrc; 159 pix0 = srcPixelPtr[0]; 160 pix1 = srcPixelPtr[1]; 161 pix2 = srcPixelPtr[2]; 162 ySrc = MLIB_POINTER_SHIFT(Y); 163 Y += dY; 164 xSrc = X >> MLIB_SHIFT; 165 X += dX; 166 for (; dstPixelPtr < dstLineEnd; dstPixelPtr += 3) { 167 srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 3 * xSrc; 168 ySrc = MLIB_POINTER_SHIFT(Y); 169 Y += dY; 170 xSrc = X >> MLIB_SHIFT; 171 X += dX; 172 dstPixelPtr[0] = pix0; 173 dstPixelPtr[1] = pix1; 174 dstPixelPtr[2] = pix2; 175 pix0 = srcPixelPtr[0]; 176 pix1 = srcPixelPtr[1]; 177 pix2 = srcPixelPtr[2]; 178 } 179 180 dstPixelPtr[0] = pix0; 181 dstPixelPtr[1] = pix1; 182 dstPixelPtr[2] = pix2; 183 } 184 185 return MLIB_SUCCESS; 186 } 187 188 /***************************************************************/ 189 mlib_status mlib_ImageAffine_u8_4ch_nn(mlib_affine_param *param) 190 { 191 DECLAREVAR_NN(); 192 DTYPE *dstLineEnd; 193 194 for (j = yStart; j <= yFinish; j++) { 195 DTYPE pix0, pix1, pix2, pix3; 196 CLIP(4); 197 dstLineEnd = (DTYPE *) dstData + 4 * xRight; 198 199 ySrc = MLIB_POINTER_SHIFT(Y); 200 Y += dY; 201 xSrc = X >> MLIB_SHIFT; 202 X += dX; 203 srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 4 * xSrc; 204 pix0 = srcPixelPtr[0]; 205 pix1 = srcPixelPtr[1]; 206 pix2 = srcPixelPtr[2]; 207 pix3 = srcPixelPtr[3]; 208 ySrc = MLIB_POINTER_SHIFT(Y); 209 Y += dY; 210 xSrc = X >> MLIB_SHIFT; 211 X += dX; 212 for (; dstPixelPtr < dstLineEnd; dstPixelPtr += 4) { 213 srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 4 * xSrc; 214 ySrc = MLIB_POINTER_SHIFT(Y); 215 Y += dY; 216 xSrc = X >> MLIB_SHIFT; 217 X += dX; 218 dstPixelPtr[0] = pix0; 219 dstPixelPtr[1] = pix1; 220 dstPixelPtr[2] = pix2; 221 dstPixelPtr[3] = pix3; 222 pix0 = srcPixelPtr[0]; 223 pix1 = srcPixelPtr[1]; 224 pix2 = srcPixelPtr[2]; 225 pix3 = srcPixelPtr[3]; 226 } 227 228 dstPixelPtr[0] = pix0; 229 dstPixelPtr[1] = pix1; 230 dstPixelPtr[2] = pix2; 231 dstPixelPtr[3] = pix3; 232 } 233 234 return MLIB_SUCCESS; 235 } 236 237 /***************************************************************/ 238 #undef DTYPE 239 #define DTYPE mlib_u16 240 241 mlib_status mlib_ImageAffine_s16_1ch_nn(mlib_affine_param *param) 242 { 243 DECLAREVAR_NN(); 244 DTYPE *dstLineEnd; 245 246 for (j = yStart; j <= yFinish; j++) { 247 mlib_s32 pix0; 248 249 CLIP(1); 250 dstLineEnd = (DTYPE *) dstData + xRight; 251 252 ySrc = MLIB_POINTER_SHIFT(Y); 253 Y += dY; 254 xSrc = X >> MLIB_SHIFT; 255 X += dX; 256 srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc); 257 pix0 = srcPixelPtr[xSrc]; 258 ySrc = MLIB_POINTER_SHIFT(Y); 259 Y += dY; 260 for (; dstPixelPtr < dstLineEnd; dstPixelPtr++) { 261 xSrc = X >> MLIB_SHIFT; 262 X += dX; 263 srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc); 264 dstPixelPtr[0] = pix0; 265 ySrc = MLIB_POINTER_SHIFT(Y); 266 Y += dY; 267 pix0 = srcPixelPtr[xSrc]; 268 } 269 270 dstPixelPtr[0] = pix0; 271 } 272 273 return MLIB_SUCCESS; 274 } 275 276 /***************************************************************/ 277 mlib_status mlib_ImageAffine_s16_2ch_nn(mlib_affine_param *param) 278 { 279 DECLAREVAR_NN(); 280 DTYPE *dstLineEnd; 281 282 for (j = yStart; j <= yFinish; j++) { 283 mlib_s32 pix0, pix1; 284 285 CLIP(2); 286 dstLineEnd = (DTYPE *) dstData + 2 * xRight; 287 288 ySrc = MLIB_POINTER_SHIFT(Y); 289 Y += dY; 290 xSrc = X >> MLIB_SHIFT; 291 X += dX; 292 srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 2 * xSrc; 293 pix0 = srcPixelPtr[0]; 294 pix1 = srcPixelPtr[1]; 295 ySrc = MLIB_POINTER_SHIFT(Y); 296 Y += dY; 297 xSrc = X >> MLIB_SHIFT; 298 X += dX; 299 300 for (; dstPixelPtr < dstLineEnd; dstPixelPtr += 2) { 301 srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 2 * xSrc; 302 ySrc = MLIB_POINTER_SHIFT(Y); 303 Y += dY; 304 xSrc = X >> MLIB_SHIFT; 305 X += dX; 306 dstPixelPtr[0] = pix0; 307 dstPixelPtr[1] = pix1; 308 pix0 = srcPixelPtr[0]; 309 pix1 = srcPixelPtr[1]; 310 } 311 312 dstPixelPtr[0] = pix0; 313 dstPixelPtr[1] = pix1; 314 } 315 316 return MLIB_SUCCESS; 317 } 318 319 /***************************************************************/ 320 mlib_status mlib_ImageAffine_s16_3ch_nn(mlib_affine_param *param) 321 { 322 DECLAREVAR_NN(); 323 DTYPE *dstLineEnd; 324 325 for (j = yStart; j <= yFinish; j++) { 326 mlib_s32 pix0, pix1, pix2; 327 328 CLIP(3); 329 dstLineEnd = (DTYPE *) dstData + 3 * xRight; 330 331 ySrc = MLIB_POINTER_SHIFT(Y); 332 Y += dY; 333 xSrc = X >> MLIB_SHIFT; 334 X += dX; 335 srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 3 * xSrc; 336 pix0 = srcPixelPtr[0]; 337 pix1 = srcPixelPtr[1]; 338 pix2 = srcPixelPtr[2]; 339 ySrc = MLIB_POINTER_SHIFT(Y); 340 Y += dY; 341 xSrc = X >> MLIB_SHIFT; 342 X += dX; 343 for (; dstPixelPtr < dstLineEnd; dstPixelPtr += 3) { 344 srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 3 * xSrc; 345 ySrc = MLIB_POINTER_SHIFT(Y); 346 Y += dY; 347 xSrc = X >> MLIB_SHIFT; 348 X += dX; 349 dstPixelPtr[0] = pix0; 350 dstPixelPtr[1] = pix1; 351 dstPixelPtr[2] = pix2; 352 pix0 = srcPixelPtr[0]; 353 pix1 = srcPixelPtr[1]; 354 pix2 = srcPixelPtr[2]; 355 } 356 357 dstPixelPtr[0] = pix0; 358 dstPixelPtr[1] = pix1; 359 dstPixelPtr[2] = pix2; 360 } 361 362 return MLIB_SUCCESS; 363 } 364 365 /***************************************************************/ 366 mlib_status mlib_ImageAffine_s16_4ch_nn(mlib_affine_param *param) 367 { 368 DECLAREVAR_NN(); 369 DTYPE *dstLineEnd; 370 371 for (j = yStart; j <= yFinish; j++) { 372 mlib_s32 pix0, pix1, pix2, pix3; 373 CLIP(4); 374 dstLineEnd = (DTYPE *) dstData + 4 * xRight; 375 376 ySrc = MLIB_POINTER_SHIFT(Y); 377 Y += dY; 378 xSrc = X >> MLIB_SHIFT; 379 X += dX; 380 srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 4 * xSrc; 381 pix0 = srcPixelPtr[0]; 382 pix1 = srcPixelPtr[1]; 383 pix2 = srcPixelPtr[2]; 384 pix3 = srcPixelPtr[3]; 385 ySrc = MLIB_POINTER_SHIFT(Y); 386 Y += dY; 387 xSrc = X >> MLIB_SHIFT; 388 X += dX; 389 for (; dstPixelPtr < dstLineEnd; dstPixelPtr += 4) { 390 srcPixelPtr = MLIB_POINTER_GET(lineAddr, ySrc) + 4 * xSrc; 391 ySrc = MLIB_POINTER_SHIFT(Y); 392 Y += dY; 393 xSrc = X >> MLIB_SHIFT; 394 X += dX; 395 dstPixelPtr[0] = pix0; 396 dstPixelPtr[1] = pix1; 397 dstPixelPtr[2] = pix2; 398 dstPixelPtr[3] = pix3; 399 pix0 = srcPixelPtr[0]; 400 pix1 = srcPixelPtr[1]; 401 pix2 = srcPixelPtr[2]; 402 pix3 = srcPixelPtr[3]; 403 } 404 405 dstPixelPtr[0] = pix0; 406 dstPixelPtr[1] = pix1; 407 dstPixelPtr[2] = pix2; 408 dstPixelPtr[3] = pix3; 409 } 410 411 return MLIB_SUCCESS; 412 } 413 414 /***************************************************************/