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 /***************************************************************/