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