1 /*
   2  * Copyright (c) 1997, 2018, 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_ImageLookUp - table lookup
  30  *
  31  * SYNOPSIS
  32  *      mlib_status mlib_ImageLookUp(mlib_image       *dst,
  33  *                                   const mlib_image *src,
  34  *                                   const void       **table)
  35  *
  36  * ARGUMENT
  37  *      dst      Pointer to destination image.
  38  *      src      Pointer to source image.
  39  *      table    Lookup table.
  40  *
  41  * DESCRIPTION
  42  *      The mlib_ImageLookUp function performs general table lookup on an
  43  *      image. The destination image is obtained by passing a source image
  44  *      through a lookup table.
  45  *
  46  *      The source image may be 1-, 2-, 3-, or 4-channeled of data types
  47  *      MLIB_BIT, MLIB_BYTE, MLIB_SHORT, MLIB_USHORT, or MLIB_INT. The lookup
  48  *      table may be 1-, 2-, 3-, or 4-channeled of data types MLIB_BYTE,
  49  *      MLIB_SHORT, MLIB_USHORT, MLIB_INT, MLIB_FLOAT, or MLIB_DOUBLE.
  50  *      The destination image must have the same
  51  *      number of channels as either source image or the lookup table,
  52  *      whichever is greater, and the same data type as the lookup table.
  53  *
  54  *      It is the user's responsibility to make sure that the lookup table
  55  *      supplied is suitable for the source image. Specifically, the table
  56  *      entries cover the entire range of source data. Otherwise, the result
  57  *      of this function is undefined.
  58  *
  59  *      The pixel values of the destination image are defined as the following:
  60  *
  61  *      If the source image is single-channeled and the destination image is
  62  *      multi-channeled, then the lookup table has the same number of channels
  63  *      as the destination image:
  64  *
  65  *          dst[x][y][c] = table[c][src[x][y][0]]
  66  *
  67  *      If the source image is multi-channeled and the destination image is
  68  *      multi-channeled, with the same number of channels as the source image,
  69  *      then the lookup table will have the same number of channels as
  70  *      the source image:
  71  *
  72  *          dst[x][y][c] = table[c][src[x][y][c]]
  73  */
  74 
  75 #include "mlib_image.h"
  76 #include "mlib_ImageCheck.h"
  77 #include "mlib_ImageLookUp.h"
  78 #include "mlib_c_ImageLookUp.h"
  79 
  80 /***************************************************************/
  81 JNIEXPORT
  82 mlib_status mlib_ImageLookUp(mlib_image       *dst,
  83                              const mlib_image *src,
  84                              const void       **table)
  85 {
  86   mlib_s32   slb, dlb, xsize, ysize, nchan, ichan, bitoff_src;
  87   mlib_type  stype, dtype;
  88   void       *sa, *da;
  89 
  90   MLIB_IMAGE_CHECK(src);
  91   MLIB_IMAGE_CHECK(dst);
  92   MLIB_IMAGE_SIZE_EQUAL(src, dst);
  93   MLIB_IMAGE_CHAN_SRC1_OR_EQ(src, dst);
  94 
  95   stype = mlib_ImageGetType(src);
  96   dtype = mlib_ImageGetType(dst);
  97   ichan = mlib_ImageGetChannels(src);
  98   nchan = mlib_ImageGetChannels(dst);
  99   xsize = mlib_ImageGetWidth(src);
 100   ysize = mlib_ImageGetHeight(src);
 101   slb   = mlib_ImageGetStride(src);
 102   dlb   = mlib_ImageGetStride(dst);
 103   sa    = mlib_ImageGetData(src);
 104   da    = mlib_ImageGetData(dst);
 105 
 106   if (ichan == nchan) {
 107     if (dtype == MLIB_BYTE) {
 108       if (stype == MLIB_BYTE) {
 109 
 110         mlib_c_ImageLookUp_U8_U8(sa, slb,
 111                                  da, dlb,
 112                                  xsize, ysize, nchan,
 113                                  (const mlib_u8 **) table);
 114 
 115         return MLIB_SUCCESS;
 116 
 117       } else if (stype == MLIB_SHORT) {
 118 
 119         mlib_c_ImageLookUp_S16_U8(sa, slb/2,
 120                                   da, dlb,
 121                                   xsize, ysize, nchan,
 122                                   (const mlib_u8 **) table);
 123         return MLIB_SUCCESS;
 124 
 125       } else if (stype == MLIB_USHORT) {
 126 
 127         mlib_c_ImageLookUp_U16_U8(sa, slb/2,
 128                                   da, dlb,
 129                                   xsize, ysize, nchan,
 130                                   (const mlib_u8 **) table);
 131         return MLIB_SUCCESS;
 132 
 133       } else if (stype == MLIB_INT) {
 134 
 135         mlib_c_ImageLookUp_S32_U8(sa, slb/4,
 136                                   da, dlb,
 137                                   xsize, ysize, nchan,
 138                                   (const mlib_u8 **) table);
 139         return MLIB_SUCCESS;
 140 
 141       } else if (stype == MLIB_BIT) {
 142 
 143         if (nchan != 1) return MLIB_FAILURE;
 144 
 145         bitoff_src = mlib_ImageGetBitOffset(src);   /* bits to first byte */
 146         return mlib_ImageLookUp_Bit_U8_1(sa, slb,
 147                                 da, dlb,
 148                                 xsize, ysize, nchan, bitoff_src,
 149                                 (const mlib_u8 **) table);
 150       }
 151 
 152     } else if (dtype == MLIB_SHORT) {
 153 
 154       if (stype == MLIB_BYTE) {
 155 
 156         mlib_c_ImageLookUp_U8_S16(sa, slb,
 157                                   da, dlb/2,
 158                                   xsize, ysize, nchan,
 159                                   (const mlib_s16 **) table);
 160 
 161         return MLIB_SUCCESS;
 162 
 163       } else if (stype == MLIB_SHORT) {
 164 
 165         mlib_c_ImageLookUp_S16_S16(sa, slb/2,
 166                                    da, dlb/2,
 167                                    xsize, ysize, nchan,
 168                                    (const mlib_s16 **) table);
 169         return MLIB_SUCCESS;
 170 
 171       } else if (stype == MLIB_USHORT) {
 172 
 173         mlib_c_ImageLookUp_U16_S16(sa, slb/2,
 174                                    da, dlb/2,
 175                                    xsize, ysize, nchan,
 176                                    (const mlib_s16 **) table);
 177         return MLIB_SUCCESS;
 178 
 179       } else if (stype == MLIB_INT) {
 180 
 181         mlib_c_ImageLookUp_S32_S16(sa, slb/4,
 182                                    da, dlb/2,
 183                                    xsize, ysize, nchan,
 184                                    (const mlib_s16 **) table);
 185         return MLIB_SUCCESS;
 186       }
 187 
 188     } else if (dtype == MLIB_USHORT) {
 189 
 190       if (stype == MLIB_BYTE) {
 191 
 192         mlib_c_ImageLookUp_U8_U16(sa, slb,
 193                                   da, dlb/2,
 194                                   xsize, ysize, nchan,
 195                                   (const mlib_s16 **) table);
 196 
 197         return MLIB_SUCCESS;
 198 
 199       } else if (stype == MLIB_SHORT) {
 200 
 201         mlib_c_ImageLookUp_S16_U16(sa, slb/2,
 202                                    da, dlb/2,
 203                                    xsize, ysize, nchan,
 204                                    (const mlib_s16 **) table);
 205         return MLIB_SUCCESS;
 206 
 207       } else if (stype == MLIB_USHORT) {
 208 
 209         mlib_c_ImageLookUp_U16_U16(sa, slb/2,
 210                                    da, dlb/2,
 211                                    xsize, ysize, nchan,
 212                                    (const mlib_s16 **) table);
 213         return MLIB_SUCCESS;
 214 
 215       } else if (stype == MLIB_INT) {
 216 
 217         mlib_c_ImageLookUp_S32_U16(sa, slb/4,
 218                                    da, dlb/2,
 219                                    xsize, ysize, nchan,
 220                                    (const mlib_s16 **) table);
 221         return MLIB_SUCCESS;
 222       }
 223 
 224     } else if (dtype == MLIB_INT) {
 225 
 226       if (stype == MLIB_BYTE) {
 227 
 228         mlib_c_ImageLookUp_U8_S32(sa, slb,
 229                                   da, dlb/4,
 230                                   xsize, ysize, nchan,
 231                                   (const mlib_s32 **) table);
 232 
 233         return MLIB_SUCCESS;
 234 
 235       } else if (stype == MLIB_SHORT) {
 236 
 237         mlib_c_ImageLookUp_S16_S32(sa, slb/2,
 238                                    da, dlb/4,
 239                                    xsize, ysize, nchan,
 240                                    (const mlib_s32 **) table);
 241         return MLIB_SUCCESS;
 242 
 243       } else if (stype == MLIB_USHORT) {
 244 
 245         mlib_c_ImageLookUp_U16_S32(sa, slb/2,
 246                                    da, dlb/4,
 247                                    xsize, ysize, nchan,
 248                                    (const mlib_s32 **) table);
 249         return MLIB_SUCCESS;
 250 
 251       } else if (stype == MLIB_INT) {
 252 
 253         mlib_c_ImageLookUp_S32_S32(sa, slb/4,
 254                                    da, dlb/4,
 255                                    xsize, ysize, nchan,
 256                                    (const mlib_s32 **) table);
 257         return MLIB_SUCCESS;
 258       }
 259 
 260     } else if (dtype == MLIB_FLOAT) {
 261 
 262       if (stype == MLIB_BYTE) {
 263 
 264         mlib_c_ImageLookUp_U8_S32(sa, slb,
 265                                   da, dlb/4,
 266                                   xsize, ysize, nchan,
 267                                   (const mlib_s32 **) table);
 268 
 269         return MLIB_SUCCESS;
 270 
 271       } else if (stype == MLIB_SHORT) {
 272 
 273         mlib_c_ImageLookUp_S16_S32(sa, slb/2,
 274                                    da, dlb/4,
 275                                    xsize, ysize, nchan,
 276                                    (const mlib_s32 **) table);
 277         return MLIB_SUCCESS;
 278 
 279       } else if (stype == MLIB_USHORT) {
 280 
 281         mlib_c_ImageLookUp_U16_S32(sa, slb/2,
 282                                    da, dlb/4,
 283                                    xsize, ysize, nchan,
 284                                    (const mlib_s32 **) table);
 285         return MLIB_SUCCESS;
 286 
 287       } else if (stype == MLIB_INT) {
 288 
 289         mlib_c_ImageLookUp_S32_S32(sa, slb/4,
 290                                    da, dlb/4,
 291                                    xsize, ysize, nchan,
 292                                    (const mlib_s32 **) table);
 293         return MLIB_SUCCESS;
 294       }
 295 
 296     } else if (dtype == MLIB_DOUBLE) {
 297 
 298       if (stype == MLIB_BYTE) {
 299 
 300         mlib_ImageLookUp_U8_D64(sa, slb,
 301                                 da, dlb/8,
 302                                 xsize, ysize, nchan,
 303                                 (const mlib_d64 **) table);
 304 
 305         return MLIB_SUCCESS;
 306 
 307       } else if (stype == MLIB_SHORT) {
 308 
 309         mlib_ImageLookUp_S16_D64(sa, slb/2,
 310                                  da, dlb/8,
 311                                  xsize, ysize, nchan,
 312                                  (const mlib_d64 **) table);
 313         return MLIB_SUCCESS;
 314 
 315       } else if (stype == MLIB_USHORT) {
 316 
 317         mlib_ImageLookUp_U16_D64(sa, slb/2,
 318                                  da, dlb/8,
 319                                  xsize, ysize, nchan,
 320                                  (const mlib_d64 **) table);
 321         return MLIB_SUCCESS;
 322 
 323       } else if (stype == MLIB_INT) {
 324 
 325         mlib_ImageLookUp_S32_D64(sa, slb/4,
 326                                  da, dlb/8,
 327                                  xsize, ysize, nchan,
 328                                  (const mlib_d64 **) table);
 329         return MLIB_SUCCESS;
 330       }
 331     }
 332 
 333   } else if (ichan == 1) {
 334 
 335     if (dtype == MLIB_BYTE) {
 336 
 337       if (stype == MLIB_BYTE) {
 338 
 339         mlib_c_ImageLookUpSI_U8_U8(sa, slb,
 340                                    da, dlb,
 341                                    xsize, ysize, nchan,
 342                                    (const mlib_u8 **) table);
 343 
 344         return MLIB_SUCCESS;
 345 
 346       } else if (stype == MLIB_SHORT) {
 347 
 348         mlib_c_ImageLookUpSI_S16_U8(sa, slb/2,
 349                                     da, dlb,
 350                                     xsize, ysize, nchan,
 351                                     (const mlib_u8 **) table);
 352         return MLIB_SUCCESS;
 353 
 354       } else if (stype == MLIB_USHORT) {
 355 
 356         mlib_c_ImageLookUpSI_U16_U8(sa, slb/2,
 357                                     da, dlb,
 358                                     xsize, ysize, nchan,
 359                                     (const mlib_u8 **) table);
 360         return MLIB_SUCCESS;
 361 
 362       } else if (stype == MLIB_INT) {
 363 
 364         mlib_c_ImageLookUpSI_S32_U8(sa, slb/4,
 365                                     da, dlb,
 366                                     xsize, ysize, nchan,
 367                                     (const mlib_u8 **) table);
 368         return MLIB_SUCCESS;
 369 
 370       } else if (stype == MLIB_BIT) {
 371 
 372         bitoff_src = mlib_ImageGetBitOffset(src);
 373 
 374         if (nchan == 2) {
 375 
 376         return mlib_ImageLookUp_Bit_U8_2(sa, slb,
 377                                 da, dlb,
 378                                 xsize, ysize, nchan, bitoff_src,
 379                                 (const mlib_u8 **) table);
 380         } else  if (nchan == 3) {
 381 
 382         return mlib_ImageLookUp_Bit_U8_3(sa, slb,
 383                                 da, dlb,
 384                                 xsize, ysize, nchan, bitoff_src,
 385                                 (const mlib_u8 **) table);
 386 
 387         } else /* (nchan == 4) */ {
 388 
 389         return mlib_ImageLookUp_Bit_U8_4(sa, slb,
 390                                 da, dlb,
 391                                 xsize, ysize, nchan, bitoff_src,
 392                                 (const mlib_u8 **) table);
 393         }
 394       }
 395 
 396     } else if (dtype == MLIB_SHORT) {
 397 
 398       if (stype == MLIB_BYTE) {
 399 
 400         mlib_c_ImageLookUpSI_U8_S16(sa, slb,
 401                                     da, dlb/2,
 402                                     xsize, ysize, nchan,
 403                                     (const mlib_s16 **) table);
 404 
 405         return MLIB_SUCCESS;
 406 
 407       } else if (stype == MLIB_SHORT) {
 408 
 409         mlib_c_ImageLookUpSI_S16_S16(sa, slb/2,
 410                                      da, dlb/2,
 411                                      xsize, ysize, nchan,
 412                                      (const mlib_s16 **) table);
 413         return MLIB_SUCCESS;
 414 
 415       } else if (stype == MLIB_USHORT) {
 416 
 417         mlib_c_ImageLookUpSI_U16_S16(sa, slb/2,
 418                                      da, dlb/2,
 419                                      xsize, ysize, nchan,
 420                                      (const mlib_s16 **) table);
 421         return MLIB_SUCCESS;
 422 
 423       } else if (stype == MLIB_INT) {
 424 
 425         mlib_c_ImageLookUpSI_S32_S16(sa, slb/4,
 426                                      da, dlb/2,
 427                                      xsize, ysize, nchan,
 428                                      (const mlib_s16 **) table);
 429         return MLIB_SUCCESS;
 430       }
 431 
 432     } else if (dtype == MLIB_USHORT) {
 433 
 434       if (stype == MLIB_BYTE) {
 435 
 436         mlib_c_ImageLookUpSI_U8_U16(sa, slb,
 437                                     da, dlb/2,
 438                                     xsize, ysize, nchan,
 439                                     (const mlib_s16 **) table);
 440 
 441         return MLIB_SUCCESS;
 442 
 443       } else if (stype == MLIB_SHORT) {
 444 
 445         mlib_c_ImageLookUpSI_S16_U16(sa, slb/2,
 446                                      da, dlb/2,
 447                                      xsize, ysize, nchan,
 448                                      (const mlib_u16 **) table);
 449         return MLIB_SUCCESS;
 450 
 451       } else if (stype == MLIB_USHORT) {
 452 
 453         mlib_c_ImageLookUpSI_U16_U16(sa, slb/2,
 454                                      da, dlb/2,
 455                                      xsize, ysize, nchan,
 456                                      (const mlib_u16 **) table);
 457         return MLIB_SUCCESS;
 458 
 459       } else if (stype == MLIB_INT) {
 460 
 461         mlib_c_ImageLookUpSI_S32_U16(sa, slb/4,
 462                                      da, dlb/2,
 463                                      xsize, ysize, nchan,
 464                                      (const mlib_u16 **) table);
 465         return MLIB_SUCCESS;
 466       }
 467 
 468     } else if (dtype == MLIB_INT) {
 469 
 470       if (stype == MLIB_BYTE) {
 471 
 472         mlib_c_ImageLookUpSI_U8_S32(sa, slb,
 473                                     da, dlb/4,
 474                                     xsize, ysize, nchan,
 475                                     (const mlib_s32 **) table);
 476 
 477         return MLIB_SUCCESS;
 478 
 479       } else if (stype == MLIB_SHORT) {
 480 
 481         mlib_c_ImageLookUpSI_S16_S32(sa, slb/2,
 482                                      da, dlb/4,
 483                                      xsize, ysize, nchan,
 484                                      (const mlib_s32 **) table);
 485         return MLIB_SUCCESS;
 486 
 487       } else if (stype == MLIB_USHORT) {
 488 
 489         mlib_c_ImageLookUpSI_U16_S32(sa, slb/2,
 490                                      da, dlb/4,
 491                                      xsize, ysize, nchan,
 492                                      (const mlib_s32 **) table);
 493         return MLIB_SUCCESS;
 494 
 495       } else if (stype == MLIB_INT) {
 496 
 497         mlib_c_ImageLookUpSI_S32_S32(sa, slb/4,
 498                                      da, dlb/4,
 499                                      xsize, ysize, nchan,
 500                                      (const mlib_s32 **) table);
 501         return MLIB_SUCCESS;
 502       }
 503 
 504     } else if (dtype == MLIB_FLOAT) {
 505 
 506       if (stype == MLIB_BYTE) {
 507 
 508         mlib_c_ImageLookUpSI_U8_S32(sa, slb,
 509                                     da, dlb/4,
 510                                     xsize, ysize, nchan,
 511                                     (const mlib_s32 **) table);
 512 
 513         return MLIB_SUCCESS;
 514 
 515       } else if (stype == MLIB_SHORT) {
 516 
 517         mlib_c_ImageLookUpSI_S16_S32(sa, slb/2,
 518                                      da, dlb/4,
 519                                      xsize, ysize, nchan,
 520                                      (const mlib_s32 **) table);
 521         return MLIB_SUCCESS;
 522 
 523       } else if (stype == MLIB_USHORT) {
 524 
 525         mlib_c_ImageLookUpSI_U16_S32(sa, slb/2,
 526                                      da, dlb/4,
 527                                      xsize, ysize, nchan,
 528                                      (const mlib_s32 **) table);
 529         return MLIB_SUCCESS;
 530 
 531       } else if (stype == MLIB_INT) {
 532 
 533         mlib_c_ImageLookUpSI_S32_S32(sa, slb/4,
 534                                      da, dlb/4,
 535                                      xsize, ysize, nchan,
 536                                      (const mlib_s32 **) table);
 537         return MLIB_SUCCESS;
 538       }
 539 
 540     } else if (dtype == MLIB_DOUBLE) {
 541 
 542       if (stype == MLIB_BYTE) {
 543 
 544         mlib_ImageLookUpSI_U8_D64(sa, slb,
 545                                   da, dlb/8,
 546                                   xsize, ysize, nchan,
 547                                   (const mlib_d64 **) table);
 548 
 549         return MLIB_SUCCESS;
 550 
 551       } else if (stype == MLIB_SHORT) {
 552 
 553         mlib_ImageLookUpSI_S16_D64(sa, slb/2,
 554                                    da, dlb/8,
 555                                    xsize, ysize, nchan,
 556                                    (const mlib_d64 **) table);
 557         return MLIB_SUCCESS;
 558 
 559       } else if (stype == MLIB_USHORT) {
 560 
 561         mlib_ImageLookUpSI_U16_D64(sa, slb/2,
 562                                    da, dlb/8,
 563                                    xsize, ysize, nchan,
 564                                    (const mlib_d64 **) table);
 565         return MLIB_SUCCESS;
 566 
 567       } else if (stype == MLIB_INT) {
 568 
 569         mlib_ImageLookUpSI_S32_D64(sa, slb/4,
 570                                    da, dlb/8,
 571                                    xsize, ysize, nchan,
 572                                    (const mlib_d64 **) table);
 573         return MLIB_SUCCESS;
 574       }
 575     }
 576   }
 577 
 578   return MLIB_FAILURE;
 579 }
 580 
 581 /***************************************************************/