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/***************************************************************/
81mlib_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/***************************************************************/
581