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