blob: af7943f616a1670f6da78e74f6d59d55325a9543 [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#include "mlib_image.h"
28#include "mlib_ImageAffine.h"
29#include "mlib_ImageColormap.h"
30
31/***************************************************************/
32#define MLIB_LIMIT 512
33#define MLIB_SHIFT 16
34#define MLIB_PREC (1 << MLIB_SHIFT)
35#define MLIB_MASK (MLIB_PREC - 1)
36
37/***************************************************************/
38#define DTYPE MLIB_TYPE
39
40/***************************************************************/
41#define DECLAREVAR_IND() \
42 DECLAREVAR0(); \
43 mlib_s32 *warp_tbl = param -> warp_tbl; \
44 mlib_s32 xSrc, ySrc; \
45 mlib_s32 srcYStride = param -> srcYStride; \
46 mlib_s32 max_xsize = param -> max_xsize; \
47 mlib_filter filter = param -> filter; \
48 MLIB_TYPE *sp, *dl; \
49 mlib_d64 xf0, xf1, xf2, xf3; \
50 mlib_d64 yf0, yf1, yf2, yf3; \
51 mlib_d64 c0, c1, c2, c3, val0; \
52 mlib_s32 filterpos; \
53 mlib_f32 *fptr; \
54 mlib_d64 s0, s1, s2, s3; \
55 mlib_s32 i, size
56
57/***************************************************************/
58#define GET_FILTERS_KOEF() \
59 filterpos = (X >> FILTER_SHIFT) & FILTER_MASK; \
60 fptr = (mlib_f32 *) ((mlib_u8 *)mlib_filters_table + filterpos); \
61 \
62 xf0 = fptr[0]; \
63 xf1 = fptr[1]; \
64 xf2 = fptr[2]; \
65 xf3 = fptr[3]; \
66 \
67 filterpos = (Y >> FILTER_SHIFT) & FILTER_MASK; \
68 fptr = (mlib_f32 *) ((mlib_u8 *)mlib_filters_table + filterpos); \
69 \
70 yf0 = fptr[0]; \
71 yf1 = fptr[1]; \
72 yf2 = fptr[2]; \
73 yf3 = fptr[3]
74
75/***************************************************************/
76#define GET_POINTER() \
77 xSrc = (X >> MLIB_SHIFT)-1; \
78 ySrc = (Y >> MLIB_SHIFT)-1; \
79 sp = ((MLIB_TYPE **)lineAddr)[ySrc] + xSrc
80
81/***************************************************************/
82#define LOAD_FIRST_ROW(nchan, chan) \
83 s0 = *(lut + sp[0]*nchan + chan); \
84 s1 = *(lut + sp[1]*nchan + chan); \
85 s2 = *(lut + sp[2]*nchan + chan); \
86 s3 = *(lut + sp[3]*nchan + chan)
87
88/***************************************************************/
89#define COUNT_NEXT_ROW(dst, nchan, chan) \
90 sp = (MLIB_TYPE*)((mlib_addr)sp + srcYStride); \
91 dst = ((*(lut + sp[0]*nchan + chan))*xf0 + \
92 (*(lut + sp[1]*nchan + chan))*xf1 + \
93 (*(lut + sp[2]*nchan + chan))*xf2 + \
94 (*(lut + sp[3]*nchan + chan))*xf3)
95
96/***************************************************************/
97#ifdef MLIB_USE_FTOI_CLAMPING
98
99/***********/
100#define STORE_SAT_VALUE_U8(ind) \
101 dp[ind] = ((mlib_s32)(val0 - (mlib_d64)0x7F800000) >> 24) ^ 0x80
102
103/***********/
104#define STORE_SAT_VALUE_S16(ind) \
105 dp[ind] = ((mlib_s32)(val0)) >> 16
106
107#else
108
109/***********/
110#define STORE_SAT_VALUE_U8(ind) \
111 val0 -= (mlib_d64)0x7F800000; \
112 if (val0 >= MLIB_S32_MAX) \
113 dp[ind] = MLIB_U8_MAX; \
114 else if (val0 <= MLIB_S32_MIN) \
115 dp[ind] = MLIB_U8_MIN; \
116 else \
117 dp[ind] = ((mlib_s32)val0 >> 24) ^ 0x80
118
119/***********/
120#define STORE_SAT_VALUE_S16(ind) \
121 if (val0 >= MLIB_S32_MAX) \
122 dp[ind] = MLIB_S16_MAX; \
123 else if (val0 <= MLIB_S32_MIN) \
124 dp[ind] = MLIB_S16_MIN; \
125 else \
126 dp[ind] = (mlib_s32)val0 >> 16
127
128#endif /* MLIB_USE_FTOI_CLAMPING */
129
130/***************************************************************/
131#define MAKE_BC_3CH(lut_format) \
132 X += dX; \
133 Y += dY; \
134 c0 = (s0*xf0 + s1*xf1 + s2*xf2 + s3*xf3); \
135 COUNT_NEXT_ROW(c1, 3, 0); \
136 COUNT_NEXT_ROW(c2, 3, 0); \
137 COUNT_NEXT_ROW(c3, 3, 0); \
138 val0 = (c0*yf0 + c1*yf1 + c2*yf2 + c3*yf3); \
139 sp = (MLIB_TYPE*)((mlib_addr)sp - 3*srcYStride); \
140 LOAD_FIRST_ROW(3, 1); \
141 STORE_SAT_VALUE_##lut_format(0); \
142 c0 = (s0*xf0 + s1*xf1 + s2*xf2 + s3*xf3); \
143 COUNT_NEXT_ROW(c1, 3, 1); \
144 COUNT_NEXT_ROW(c2, 3, 1); \
145 COUNT_NEXT_ROW(c3, 3, 1); \
146 val0 = (c0*yf0 + c1*yf1 + c2*yf2 + c3*yf3); \
147 sp = (MLIB_TYPE*)((mlib_addr)sp - 3*srcYStride); \
148 LOAD_FIRST_ROW(3, 2); \
149 STORE_SAT_VALUE_##lut_format(1); \
150 c0 = (s0*xf0 + s1*xf1 + s2*xf2 + s3*xf3); \
151 COUNT_NEXT_ROW(c1, 3, 2); \
152 COUNT_NEXT_ROW(c2, 3, 2); \
153 COUNT_NEXT_ROW(c3, 3, 2); \
154 val0 = (c0*yf0 + c1*yf1 + c2*yf2 + c3*yf3); \
155 GET_FILTERS_KOEF(); \
156 GET_POINTER(); \
157 LOAD_FIRST_ROW(3, 0); \
158 STORE_SAT_VALUE_##lut_format(2);
159
160/***************************************************************/
161#define MAKE_LAST_PIXEL_BC_3CH(lut_format) \
162 c0 = (s0*xf0 + s1*xf1 + s2*xf2 + s3*xf3); \
163 COUNT_NEXT_ROW(c1, 3, 0); \
164 COUNT_NEXT_ROW(c2, 3, 0); \
165 COUNT_NEXT_ROW(c3, 3, 0); \
166 val0 = (c0*yf0 + c1*yf1 + c2*yf2 + c3*yf3); \
167 sp = (MLIB_TYPE*)((mlib_addr)sp - 3*srcYStride); \
168 LOAD_FIRST_ROW(3, 1); \
169 STORE_SAT_VALUE_##lut_format(0); \
170 c0 = (s0*xf0 + s1*xf1 + s2*xf2 + s3*xf3); \
171 COUNT_NEXT_ROW(c1, 3, 1); \
172 COUNT_NEXT_ROW(c2, 3, 1); \
173 COUNT_NEXT_ROW(c3, 3, 1); \
174 val0 = (c0*yf0 + c1*yf1 + c2*yf2 + c3*yf3); \
175 sp = (MLIB_TYPE*)((mlib_addr)sp - 3*srcYStride); \
176 LOAD_FIRST_ROW(3, 2); \
177 STORE_SAT_VALUE_##lut_format(1); \
178 c0 = (s0*xf0 + s1*xf1 + s2*xf2 + s3*xf3); \
179 COUNT_NEXT_ROW(c1, 3, 2); \
180 COUNT_NEXT_ROW(c2, 3, 2); \
181 COUNT_NEXT_ROW(c3, 3, 2); \
182 val0 = (c0*yf0 + c1*yf1 + c2*yf2 + c3*yf3); \
183 STORE_SAT_VALUE_##lut_format(2);
184
185/***************************************************************/
186#define MAKE_BC_4CH(lut_format) \
187 X += dX; \
188 Y += dY; \
189 c0 = (s0*xf0 + s1*xf1 + s2*xf2 + s3*xf3); \
190 COUNT_NEXT_ROW(c1, 4, 0); \
191 COUNT_NEXT_ROW(c2, 4, 0); \
192 COUNT_NEXT_ROW(c3, 4, 0); \
193 val0 = (c0*yf0 + c1*yf1 + c2*yf2 + c3*yf3); \
194 sp = (MLIB_TYPE*)((mlib_addr)sp - 3*srcYStride); \
195 LOAD_FIRST_ROW(4, 1); \
196 STORE_SAT_VALUE_##lut_format(0); \
197 c0 = (s0*xf0 + s1*xf1 + s2*xf2 + s3*xf3); \
198 COUNT_NEXT_ROW(c1, 4, 1); \
199 COUNT_NEXT_ROW(c2, 4, 1); \
200 COUNT_NEXT_ROW(c3, 4, 1); \
201 val0 = (c0*yf0 + c1*yf1 + c2*yf2 + c3*yf3); \
202 sp = (MLIB_TYPE*)((mlib_addr)sp - 3*srcYStride); \
203 LOAD_FIRST_ROW(4, 2); \
204 STORE_SAT_VALUE_##lut_format(1); \
205 c0 = (s0*xf0 + s1*xf1 + s2*xf2 + s3*xf3); \
206 COUNT_NEXT_ROW(c1, 4, 2); \
207 COUNT_NEXT_ROW(c2, 4, 2); \
208 COUNT_NEXT_ROW(c3, 4, 2); \
209 val0 = (c0*yf0 + c1*yf1 + c2*yf2 + c3*yf3); \
210 sp = (MLIB_TYPE*)((mlib_addr)sp - 3*srcYStride); \
211 LOAD_FIRST_ROW(4, 3); \
212 STORE_SAT_VALUE_##lut_format(2); \
213 c0 = (s0*xf0 + s1*xf1 + s2*xf2 + s3*xf3); \
214 COUNT_NEXT_ROW(c1, 4, 3); \
215 COUNT_NEXT_ROW(c2, 4, 3); \
216 COUNT_NEXT_ROW(c3, 4, 3); \
217 val0 = (c0*yf0 + c1*yf1 + c2*yf2 + c3*yf3); \
218 GET_FILTERS_KOEF(); \
219 GET_POINTER(); \
220 LOAD_FIRST_ROW(4, 0); \
221 STORE_SAT_VALUE_##lut_format(3);
222
223/***************************************************************/
224#define MAKE_LAST_PIXEL_BC_4CH(lut_format) \
225 c0 = (s0*xf0 + s1*xf1 + s2*xf2 + s3*xf3); \
226 COUNT_NEXT_ROW(c1, 4, 0); \
227 COUNT_NEXT_ROW(c2, 4, 0); \
228 COUNT_NEXT_ROW(c3, 4, 0); \
229 val0 = (c0*yf0 + c1*yf1 + c2*yf2 + c3*yf3); \
230 sp = (MLIB_TYPE*)((mlib_addr)sp - 3*srcYStride); \
231 LOAD_FIRST_ROW(4, 1); \
232 STORE_SAT_VALUE_##lut_format(0); \
233 c0 = (s0*xf0 + s1*xf1 + s2*xf2 + s3*xf3); \
234 COUNT_NEXT_ROW(c1, 4, 1); \
235 COUNT_NEXT_ROW(c2, 4, 1); \
236 COUNT_NEXT_ROW(c3, 4, 1); \
237 val0 = (c0*yf0 + c1*yf1 + c2*yf2 + c3*yf3); \
238 sp = (MLIB_TYPE*)((mlib_addr)sp - 3*srcYStride); \
239 LOAD_FIRST_ROW(4, 2); \
240 STORE_SAT_VALUE_##lut_format(1); \
241 c0 = (s0*xf0 + s1*xf1 + s2*xf2 + s3*xf3); \
242 COUNT_NEXT_ROW(c1, 4, 2); \
243 COUNT_NEXT_ROW(c2, 4, 2); \
244 COUNT_NEXT_ROW(c3, 4, 2); \
245 val0 = (c0*yf0 + c1*yf1 + c2*yf2 + c3*yf3); \
246 sp = (MLIB_TYPE*)((mlib_addr)sp - 3*srcYStride); \
247 LOAD_FIRST_ROW(4, 3); \
248 STORE_SAT_VALUE_##lut_format(2); \
249 c0 = (s0*xf0 + s1*xf1 + s2*xf2 + s3*xf3); \
250 COUNT_NEXT_ROW(c1, 4, 3); \
251 COUNT_NEXT_ROW(c2, 4, 3); \
252 COUNT_NEXT_ROW(c3, 4, 3); \
253 val0 = (c0*yf0 + c1*yf1 + c2*yf2 + c3*yf3); \
254 STORE_SAT_VALUE_##lut_format(3);
255
256/***************************************************************/
257#define FILTER_U8 ((filter == MLIB_BICUBIC) ? mlib_filters_u8f_bc : mlib_filters_u8f_bc2)
258#define FILTER_S16 ((filter == MLIB_BICUBIC) ? mlib_filters_s16f_bc : mlib_filters_s16f_bc2)
259
260/***************************************************************/
261#define mlib_U8 mlib_u8
262#define mlib_S16 mlib_s16
263
264/***************************************************************/
265#define FUNC_AFFINEINDEX_BC_0(ITYPE, LTYPE, NCHAN) \
266 mlib_status mlib_ImageAffineIndex_##ITYPE##_##LTYPE##_##NCHAN##CH_BC(mlib_affine_param *param, \
267 const void *colormap) \
268 { \
269 DECLAREVAR_IND(); \
270 mlib_##LTYPE buff_lcl[NCHAN * MLIB_LIMIT], *pbuff = buff_lcl, *dp; \
271 mlib_d64 *lut = ((mlib_d64*)mlib_ImageGetLutDoubleData(colormap) - \
272 NCHAN * mlib_ImageGetLutOffset(colormap)); \
273 const mlib_f32 *mlib_filters_table = FILTER_##LTYPE; \
274 \
275 if (max_xsize > MLIB_LIMIT) { \
276 pbuff = mlib_malloc(NCHAN * sizeof(mlib_##LTYPE) * max_xsize); \
277 if (pbuff == NULL) return MLIB_FAILURE; \
278 } \
279 \
280 for (j = yStart; j <= yFinish; j++) { \
281 \
282 NEW_LINE(1); \
283 dp = pbuff; \
284 \
285 GET_FILTERS_KOEF(); \
286 GET_POINTER(); \
287 LOAD_FIRST_ROW(NCHAN, 0);
288
289 /* pragma pipeloop(0) must be here */
290
291/***************************************************************/
292#define FUNC_AFFINEINDEX_BC_1(ITYPE, LTYPE, NCHAN) \
293 \
294 for (i = 0; i < (xRight - xLeft); i++, dp += NCHAN) { \
295 MAKE_BC_##NCHAN##CH(LTYPE); \
296 } \
297 \
298 MAKE_LAST_PIXEL_BC_##NCHAN##CH(LTYPE); \
299 \
300 mlib_ImageColorTrue2IndexLine_##LTYPE##_##ITYPE##_##NCHAN \
301 (pbuff, dl, xRight - xLeft + 1, colormap); \
302 } \
303 \
304 if (pbuff != buff_lcl) mlib_free(pbuff); \
305 \
306 return MLIB_SUCCESS; \
307 }
308
309/***************************************************************/
310#undef MLIB_TYPE
311#define MLIB_TYPE mlib_u8
312
313/***************************************************************/
314#undef FILTER_SHIFT
315#define FILTER_SHIFT 4
316#undef FILTER_MASK
317#define FILTER_MASK (((1 << 8) - 1) << 4)
318
319FUNC_AFFINEINDEX_BC_0(U8, U8, 3)
320#ifdef __SUNPRO_C
321#pragma pipeloop(0)
322#endif /* __SUNPRO_C */
323FUNC_AFFINEINDEX_BC_1(U8, U8, 3)
324
325/***************************************************************/
326#undef FILTER_SHIFT
327#define FILTER_SHIFT 3
328#undef FILTER_MASK
329#define FILTER_MASK (((1 << 9) - 1) << 4)
330
331FUNC_AFFINEINDEX_BC_0(U8, S16, 3)
332#ifdef __SUNPRO_C
333#pragma pipeloop(0)
334#endif /* __SUNPRO_C */
335FUNC_AFFINEINDEX_BC_1(U8, S16, 3)
336
337/***************************************************************/
338#undef FILTER_SHIFT
339#define FILTER_SHIFT 4
340#undef FILTER_MASK
341#define FILTER_MASK (((1 << 8) - 1) << 4)
342
343FUNC_AFFINEINDEX_BC_0(U8, U8, 4)
344#ifdef __SUNPRO_C
345#pragma pipeloop(0)
346#endif /* __SUNPRO_C */
347FUNC_AFFINEINDEX_BC_1(U8, U8, 4)
348
349/***************************************************************/
350#undef FILTER_SHIFT
351#define FILTER_SHIFT 3
352#undef FILTER_MASK
353#define FILTER_MASK (((1 << 9) - 1) << 4)
354
355FUNC_AFFINEINDEX_BC_0(U8, S16, 4)
356#ifdef __SUNPRO_C
357#pragma pipeloop(0)
358#endif /* __SUNPRO_C */
359FUNC_AFFINEINDEX_BC_1(U8, S16, 4)
360
361/***************************************************************/
362#undef MLIB_TYPE
363#define MLIB_TYPE mlib_s16
364
365/***************************************************************/
366#undef FILTER_SHIFT
367#define FILTER_SHIFT 4
368#undef FILTER_MASK
369#define FILTER_MASK (((1 << 8) - 1) << 4)
370
371FUNC_AFFINEINDEX_BC_0(S16, U8, 3)
372#ifdef __SUNPRO_C
373#pragma pipeloop(0)
374#endif /* __SUNPRO_C */
375FUNC_AFFINEINDEX_BC_1(S16, U8, 3)
376
377/***************************************************************/
378#undef FILTER_SHIFT
379#define FILTER_SHIFT 3
380#undef FILTER_MASK
381#define FILTER_MASK (((1 << 9) - 1) << 4)
382
383FUNC_AFFINEINDEX_BC_0(S16, S16, 3)
384#ifdef __SUNPRO_C
385#pragma pipeloop(0)
386#endif /* __SUNPRO_C */
387FUNC_AFFINEINDEX_BC_1(S16, S16, 3)
388
389/***************************************************************/
390#undef FILTER_SHIFT
391#define FILTER_SHIFT 4
392#undef FILTER_MASK
393#define FILTER_MASK (((1 << 8) - 1) << 4)
394
395FUNC_AFFINEINDEX_BC_0(S16, U8, 4)
396#ifdef __SUNPRO_C
397#pragma pipeloop(0)
398#endif /* __SUNPRO_C */
399FUNC_AFFINEINDEX_BC_1(S16, U8, 4)
400
401/***************************************************************/
402#undef FILTER_SHIFT
403#define FILTER_SHIFT 3
404#undef FILTER_MASK
405#define FILTER_MASK (((1 << 9) - 1) << 4)
406
407FUNC_AFFINEINDEX_BC_0(S16, S16, 4)
408#ifdef __SUNPRO_C
409#pragma pipeloop(0)
410#endif /* __SUNPRO_C */
411FUNC_AFFINEINDEX_BC_1(S16, S16, 4)
412
413/***************************************************************/