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