1/* 2 * Copyright (c) 1998, 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/* 29 * FUNCTION 30 * mlib_ImageLookUp - table lookup 31 * 32 * SYNOPSIS 33 * mlib_status mlib_ImageLookUp(mlib_image *dst, 34 * const mlib_image *src, 35 * void **table) 36 * 37 * ARGUMENT 38 * dst Pointer to destination image. 39 * src Pointer to source image. 40 * table Lookup table. 41 * 42 * DESCRIPTION 43 * The mlib_ImageLookUp function performs general table lookup on an 44 * image. The destination image is obtained by passing a source image 45 * through a lookup table. 46 * 47 * The source image may be 1-, 2-, 3-, or 4-channeled of data types 48 * MLIB_BIT, MLIB_BYTE, MLIB_SHORT, or MLIB_INT. The lookup table may be 49 * 1-, 2-, 3-, or 4-channeled of data types MLIB_BYTE, MLIB_SHORT, MLIB_INT, 50 * MLIB_FLOAT, or MLIB_DOUBLE. 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_v_ImageLookUpFunc.h" 79 80/***************************************************************/ 81#define CALL_SIFUNC(STYPE, DTYPE, TYPE) \ 82 switch (nchan) { \ 83 case 2: \ 84 mlib_v_ImageLookUpSI_##STYPE##_##DTYPE##_2(sa, slb, da, dlb, \ 85 xsize, ysize, (const TYPE **) table); \ 86 break; \ 87 case 3: \ 88 mlib_v_ImageLookUpSI_##STYPE##_##DTYPE##_3(sa, slb, da, dlb, \ 89 xsize, ysize, (const TYPE **) table); \ 90 break; \ 91 case 4: \ 92 mlib_v_ImageLookUpSI_##STYPE##_##DTYPE##_4(sa, slb, da, dlb, \ 93 xsize, ysize, (const TYPE **) table); \ 94 break; \ 95 default: \ 96 return MLIB_FAILURE; \ 97 } \ 98 return MLIB_SUCCESS 99 100/***************************************************************/ 101#define CALL_FUNC(STYPE, DTYPE, TYPE) \ 102 switch (nchan) { \ 103 case 1: \ 104 mlib_v_ImageLookUp_##STYPE##_##DTYPE##_1(sa, slb, da, dlb, \ 105 xsize, ysize, (const TYPE **) table); \ 106 break; \ 107 case 2: \ 108 mlib_v_ImageLookUp_##STYPE##_##DTYPE##_2(sa, slb, da, dlb, \ 109 xsize, ysize, (const TYPE **) table); \ 110 break; \ 111 case 3: \ 112 mlib_v_ImageLookUp_##STYPE##_##DTYPE##_3(sa, slb, da, dlb, \ 113 xsize, ysize, (const TYPE **) table); \ 114 break; \ 115 case 4: \ 116 mlib_v_ImageLookUp_##STYPE##_##DTYPE##_4(sa, slb, da, dlb, \ 117 xsize, ysize, (const TYPE **) table); \ 118 break; \ 119 default: \ 120 return MLIB_FAILURE; \ 121 } \ 122 return MLIB_SUCCESS 123 124/***************************************************************/ 125mlib_status mlib_ImageLookUp(mlib_image *dst, 126 const mlib_image *src, 127 const void **table) 128{ 129 mlib_s32 slb, dlb, xsize, ysize, nchan, ichan, bitoff_src; 130 mlib_type stype, dtype; 131 void *sa, *da; 132 133 MLIB_IMAGE_CHECK(src); 134 MLIB_IMAGE_CHECK(dst); 135 MLIB_IMAGE_SIZE_EQUAL(src, dst); 136 MLIB_IMAGE_CHAN_SRC1_OR_EQ(src, dst); 137 138 stype = mlib_ImageGetType(src); 139 dtype = mlib_ImageGetType(dst); 140 ichan = mlib_ImageGetChannels(src); 141 nchan = mlib_ImageGetChannels(dst); 142 xsize = mlib_ImageGetWidth(src); 143 ysize = mlib_ImageGetHeight(src); 144 slb = mlib_ImageGetStride(src); 145 dlb = mlib_ImageGetStride(dst); 146 sa = mlib_ImageGetData(src); 147 da = mlib_ImageGetData(dst); 148 149 if (ichan == nchan) { 150 if (dtype == MLIB_BYTE) { 151 if (stype == MLIB_BYTE) { 152 CALL_FUNC(U8, U8, mlib_u8); 153 } 154 else if (stype == MLIB_SHORT) { 155 CALL_FUNC(S16, U8, mlib_u8); 156 } 157 else if (stype == MLIB_USHORT) { 158 CALL_FUNC(U16, U8, mlib_u8); 159 } 160 else if (stype == MLIB_INT) { 161 CALL_FUNC(S32, U8, mlib_u8); 162 } 163 else if (stype == MLIB_BIT) { 164 if (nchan != 1) 165 return MLIB_FAILURE; 166 167 bitoff_src = mlib_ImageGetBitOffset(src); /* bits to first byte */ 168 return mlib_ImageLookUp_Bit_U8_1(sa, slb, da, dlb, xsize, ysize, nchan, 169 bitoff_src, (const mlib_u8 **) table); 170 } 171 } 172 else if (dtype == MLIB_SHORT) { 173 if (stype == MLIB_BYTE) { 174 CALL_FUNC(U8, S16, mlib_s16); 175 } 176 else if (stype == MLIB_SHORT) { 177 CALL_FUNC(S16, S16, mlib_s16); 178 } 179 else if (stype == MLIB_USHORT) { 180 CALL_FUNC(U16, S16, mlib_s16); 181 } 182 else if (stype == MLIB_INT) { 183 CALL_FUNC(S32, S16, mlib_s16); 184 } 185 } 186 else if (dtype == MLIB_USHORT) { 187 if (stype == MLIB_BYTE) { 188 CALL_FUNC(U8, U16, mlib_u16); 189 } 190 else if (stype == MLIB_SHORT) { 191 CALL_FUNC(S16, U16, mlib_u16); 192 } 193 else if (stype == MLIB_USHORT) { 194 CALL_FUNC(U16, U16, mlib_u16); 195 } 196 else if (stype == MLIB_INT) { 197 CALL_FUNC(S32, U16, mlib_u16); 198 } 199 } 200 else if (dtype == MLIB_INT) { 201 if (stype == MLIB_BYTE) { 202 CALL_FUNC(U8, S32, mlib_s32); 203 } 204 else if (stype == MLIB_SHORT) { 205 CALL_FUNC(S16, S32, mlib_s32); 206 } 207 else if (stype == MLIB_USHORT) { 208 CALL_FUNC(U16, S32, mlib_s32); 209 } 210 else if (stype == MLIB_INT) { 211 if ((nchan >= 1) && (nchan <= 4)) { 212 mlib_v_ImageLookUp_S32_S32(sa, slb, da, dlb, xsize, ysize, (const mlib_s32 **) table, 213 nchan); 214 return MLIB_SUCCESS; 215 } 216 else { 217 return MLIB_FAILURE; 218 } 219 } 220 } 221 else if (dtype == MLIB_FLOAT) { 222 if (stype == MLIB_BYTE) { 223 CALL_FUNC(U8, S32, mlib_s32); 224 } 225 else if (stype == MLIB_SHORT) { 226 CALL_FUNC(S16, S32, mlib_s32); 227 } 228 else if (stype == MLIB_USHORT) { 229 CALL_FUNC(U16, S32, mlib_s32); 230 } 231 else if (stype == MLIB_INT) { 232 if ((nchan >= 1) && (nchan <= 4)) { 233 mlib_v_ImageLookUp_S32_S32(sa, slb, da, dlb, xsize, ysize, (const mlib_s32 **) table, 234 nchan); 235 return MLIB_SUCCESS; 236 } 237 else { 238 return MLIB_FAILURE; 239 } 240 } 241 } 242 else if (dtype == MLIB_DOUBLE) { 243 if (stype == MLIB_BYTE) { 244 mlib_ImageLookUp_U8_D64(sa, slb, da, dlb / 8, xsize, ysize, nchan, 245 (const mlib_d64 **) table); 246 return MLIB_SUCCESS; 247 } 248 else if (stype == MLIB_SHORT) { 249 mlib_ImageLookUp_S16_D64(sa, slb / 2, da, dlb / 8, xsize, ysize, nchan, 250 (const mlib_d64 **) table); 251 return MLIB_SUCCESS; 252 } 253 else if (stype == MLIB_USHORT) { 254 mlib_ImageLookUp_U16_D64(sa, slb / 2, da, dlb / 8, xsize, ysize, nchan, 255 (const mlib_d64 **) table); 256 return MLIB_SUCCESS; 257 } 258 else if (stype == MLIB_INT) { 259 mlib_ImageLookUp_S32_D64(sa, slb / 4, da, dlb / 8, xsize, ysize, nchan, 260 (const mlib_d64 **) table); 261 return MLIB_SUCCESS; 262 } 263 } 264 } 265 else if (ichan == 1) { 266 if (dtype == MLIB_BYTE) { 267 if (stype == MLIB_BYTE) { 268 CALL_SIFUNC(U8, U8, mlib_u8); 269 } 270 else if (stype == MLIB_SHORT) { 271 CALL_SIFUNC(S16, U8, mlib_u8); 272 } 273 else if (stype == MLIB_USHORT) { 274 CALL_SIFUNC(U16, U8, mlib_u8); 275 } 276 else if (stype == MLIB_INT) { 277 CALL_SIFUNC(S32, U8, mlib_u8); 278 } 279 else if (stype == MLIB_BIT) { 280 bitoff_src = mlib_ImageGetBitOffset(src); /* bits to first byte */ 281 282 if (nchan == 2) { 283 return mlib_ImageLookUp_Bit_U8_2(sa, slb, da, dlb, xsize, ysize, nchan, 284 bitoff_src, (const mlib_u8 **) table); 285 } 286 else if (nchan == 3) { 287 return mlib_ImageLookUp_Bit_U8_3(sa, slb, da, dlb, xsize, ysize, nchan, 288 bitoff_src, (const mlib_u8 **) table); 289 } 290 else { /* (nchan == 4) */ 291 return mlib_ImageLookUp_Bit_U8_4(sa, slb, da, dlb, xsize, ysize, nchan, 292 bitoff_src, (const mlib_u8 **) table); 293 } 294 } 295 } 296 else if (dtype == MLIB_SHORT) { 297 if (stype == MLIB_BYTE) { 298 CALL_SIFUNC(U8, S16, mlib_s16); 299 } 300 else if (stype == MLIB_SHORT) { 301 CALL_SIFUNC(S16, S16, mlib_s16); 302 } 303 else if (stype == MLIB_USHORT) { 304 CALL_SIFUNC(U16, S16, mlib_s16); 305 } 306 else if (stype == MLIB_INT) { 307 CALL_SIFUNC(S32, S16, mlib_s16); 308 } 309 } 310 else if (dtype == MLIB_USHORT) { 311 if (stype == MLIB_BYTE) { 312 CALL_SIFUNC(U8, U16, mlib_u16); 313 } 314 else if (stype == MLIB_SHORT) { 315 CALL_SIFUNC(S16, U16, mlib_u16); 316 } 317 else if (stype == MLIB_USHORT) { 318 CALL_SIFUNC(U16, U16, mlib_u16); 319 } 320 else if (stype == MLIB_INT) { 321 CALL_SIFUNC(S32, U16, mlib_u16); 322 } 323 } 324 else if (dtype == MLIB_INT) { 325 326 if (stype == MLIB_BYTE) { 327 CALL_SIFUNC(U8, S32, mlib_s32); 328 } 329 else if (stype == MLIB_SHORT) { 330 CALL_SIFUNC(S16, S32, mlib_s32); 331 } 332 else if (stype == MLIB_USHORT) { 333 CALL_SIFUNC(U16, S32, mlib_s32); 334 } 335 else if (stype == MLIB_INT) { 336 if ((nchan >= 1) && (nchan <= 4)) { 337 mlib_v_ImageLookUpSI_S32_S32(sa, slb, da, dlb, xsize, ysize, 338 (const mlib_s32 **) table, nchan); 339 return MLIB_SUCCESS; 340 } 341 else { 342 return MLIB_FAILURE; 343 } 344 } 345 } 346 else if (dtype == MLIB_FLOAT) { 347 348 if (stype == MLIB_BYTE) { 349 CALL_SIFUNC(U8, S32, mlib_s32); 350 } 351 else if (stype == MLIB_SHORT) { 352 CALL_SIFUNC(S16, S32, mlib_s32); 353 } 354 else if (stype == MLIB_USHORT) { 355 CALL_SIFUNC(U16, S32, mlib_s32); 356 } 357 else if (stype == MLIB_INT) { 358 if ((nchan >= 1) && (nchan <= 4)) { 359 mlib_v_ImageLookUpSI_S32_S32(sa, slb, da, dlb, xsize, ysize, 360 (const mlib_s32 **) table, nchan); 361 return MLIB_SUCCESS; 362 } 363 else { 364 return MLIB_FAILURE; 365 } 366 } 367 } 368 else if (dtype == MLIB_DOUBLE) { 369 if (stype == MLIB_BYTE) { 370 mlib_ImageLookUpSI_U8_D64(sa, slb, da, dlb / 8, xsize, ysize, nchan, 371 (const mlib_d64 **) table); 372 return MLIB_SUCCESS; 373 } 374 else if (stype == MLIB_SHORT) { 375 mlib_ImageLookUpSI_S16_D64(sa, slb / 2, da, dlb / 8, xsize, ysize, nchan, 376 (const mlib_d64 **) table); 377 return MLIB_SUCCESS; 378 } 379 else if (stype == MLIB_USHORT) { 380 mlib_ImageLookUpSI_U16_D64(sa, slb / 2, da, dlb / 8, xsize, ysize, nchan, 381 (const mlib_d64 **) table); 382 return MLIB_SUCCESS; 383 } 384 else if (stype == MLIB_INT) { 385 mlib_ImageLookUpSI_S32_D64(sa, slb / 4, da, dlb / 8, xsize, ysize, nchan, 386 (const mlib_d64 **) table); 387 return MLIB_SUCCESS; 388 } 389 } 390 } 391 392 return MLIB_FAILURE; 393} 394 395/***************************************************************/ 396