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