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
mlib_ImageLookUp(mlib_image * dst,const mlib_image * src,const void ** table)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 /***************************************************************/
582