blob: 8c3f042b41869ee7546c5c0ee7890337d2520f9a [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1998-2003 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any 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/***************************************************************/