blob: 5c1af0a335cc0b7a843ac6952d1767d02777d43a [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 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 * FUNCTION
29 * mlib_ImageZoom - image scaling with edge condition
30 *
31 * SYNOPSIS
32 * mlib_status mlib_ImageZoom(mlib_image *dst,
33 * const mlib_image *src,
34 * mlib_f32 zoomx,
35 * mlib_f32 zoomy,
36 * mlib_filter filter,
37 * mlib_edge edge)
38 *
39 * ARGUMENTS
40 * dst Pointer to destination image
41 * src Pointer to source image
42 * zoomx X zoom factor.
43 * zoomy Y zoom factor.
44 * filter Type of resampling filter.
45 * edge Type of edge condition.
46 *
47 * DESCRIPTION
48 * The center of the source image is mapped to the center of the
49 * destination image.
50 *
51 * The upper-left corner pixel of an image is located at (0.5, 0.5).
52 *
53 * The resampling filter can be one of the following:
54 * MLIB_NEAREST
55 * MLIB_BILINEAR
56 * MLIB_BICUBIC
57 * MLIB_BICUBIC2
58 *
59 * The edge condition can be one of the following:
60 * MLIB_EDGE_DST_NO_WRITE (default)
61 * MLIB_EDGE_DST_FILL_ZERO
62 * MLIB_EDGE_OP_NEAREST
63 * MLIB_EDGE_SRC_EXTEND
64 * MLIB_EDGE_SRC_PADDED
65 */
66
67#include <mlib_image.h>
68#include <vis_proto.h>
69
70/***************************************************************/
71
72#define _MLIB_VIS_VER_
73#include <mlib_ImageZoom.h>
74
75/***************************************************************/
76
77#define VARIABLE(FORMAT) \
78 mlib_s32 j, \
79 dx = GetElemStruct(DX), \
80 dy = GetElemStruct(DY), \
81 x = GetElemSubStruct(current, srcX), \
82 y = GetElemSubStruct(current, srcY), \
83 src_stride = GetElemStruct(src_stride), \
84 dst_stride = GetElemStruct(dst_stride), \
85 width = GetElemSubStruct(current, width), \
86 height = GetElemSubStruct(current, height); \
87 FORMAT *sp = GetElemSubStruct(current, sp), \
88 *dp = GetElemSubStruct(current, dp)
89
90/***************************************************************/
91
92mlib_status mlib_ImageZoom_U8_1_Nearest(mlib_work_image *param)
93{
94 VARIABLE(mlib_u8);
95 mlib_u8 *dl = dp, *tsp;
96 mlib_s32 y0 = -1, dx7 = 7*dx, dx15 = 8*dx + dx7;
97
98 tsp = sp;
99 y = GetElemSubStruct(current, srcY) & MLIB_MASK;
100
101 for (j = 0; j < height; j++) {
102
103 if ((y0 >> MLIB_SHIFT) == (y >> MLIB_SHIFT)) {
104 mlib_ImageCopy_na(dl - dst_stride, dl, width);
105 }
106 else {
107 mlib_u8 *dp = dl, *dend = dl + width;
108
109 vis_write_gsr(7);
110 x = GetElemSubStruct(current, srcX) & MLIB_MASK;
111
112 while (((mlib_addr)dp & 7) && (dp < dend)) {
113 *dp++ = tsp[x >> MLIB_SHIFT];
114 x += dx;
115 }
116
117 x += dx7;
118
119#pragma pipeloop(0)
120 for (; dp <= dend - 8; dp += 8) {
121 mlib_d64 s0;
122
123 s0 = vis_faligndata(vis_ld_u8_i(tsp, x >> MLIB_SHIFT), s0);
124 x -= dx;
125 s0 = vis_faligndata(vis_ld_u8_i(tsp, x >> MLIB_SHIFT), s0);
126 x -= dx;
127 s0 = vis_faligndata(vis_ld_u8_i(tsp, x >> MLIB_SHIFT), s0);
128 x -= dx;
129 s0 = vis_faligndata(vis_ld_u8_i(tsp, x >> MLIB_SHIFT), s0);
130 x -= dx;
131 s0 = vis_faligndata(vis_ld_u8_i(tsp, x >> MLIB_SHIFT), s0);
132 x -= dx;
133 s0 = vis_faligndata(vis_ld_u8_i(tsp, x >> MLIB_SHIFT), s0);
134 x -= dx;
135 s0 = vis_faligndata(vis_ld_u8_i(tsp, x >> MLIB_SHIFT), s0);
136 x -= dx;
137 s0 = vis_faligndata(vis_ld_u8_i(tsp, x >> MLIB_SHIFT), s0);
138 x += dx15;
139
140 *(mlib_d64*)dp = s0;
141 }
142
143 x -= dx7;
144
145 while (dp < dend) {
146 *dp++ = tsp[x >> MLIB_SHIFT];
147 x += dx;
148 }
149 }
150
151 y0 = y;
152 y += dy;
153 dl = (void*)((mlib_u8*)dl + dst_stride);
154 tsp = (void*)((mlib_u8*)sp + (y >> MLIB_SHIFT) * src_stride);
155 }
156
157 return MLIB_SUCCESS;
158}
159
160/***************************************************************/
161
162mlib_status mlib_ImageZoom_U8_3_Nearest(mlib_work_image *param)
163{
164 VARIABLE(mlib_u8);
165 mlib_u8 *dl = dp, *tsp, *tt;
166 mlib_s32 cx, y0 = -1, dx7 = 7*dx, dx15 = 8*dx + dx7;
167
168 tsp = sp;
169 y = GetElemSubStruct(current, srcY) & MLIB_MASK;
170
171 for (j = 0; j < height; j++) {
172
173 if ((y0 >> MLIB_SHIFT) == (y >> MLIB_SHIFT)) {
174 mlib_ImageCopy_na(dl - dst_stride, dl, 3*width);
175 }
176 else {
177 mlib_u8 *dp = dl, *dend = dl + 3*width;
178
179 vis_write_gsr(7);
180 x = GetElemSubStruct(current, srcX) & MLIB_MASK;
181
182 while (((mlib_addr)dp & 7) && (dp < dend)) {
183 cx = x >> MLIB_SHIFT;
184 tt = tsp + 2*cx + cx;
185 dp[0] = tt[0];
186 dp[1] = tt[1];
187 dp[2] = tt[2];
188 x += dx;
189 dp += 3;
190 }
191
192 x += dx7;
193
194#pragma pipeloop(0)
195 for (; dp <= dend - 24; dp += 24) {
196 mlib_d64 s0, s1, s2;
197
198 cx = x >> MLIB_SHIFT;
199 tt = tsp + 2*cx + cx;
200 x -= dx;
201 s2 = vis_faligndata(vis_ld_u8_i(tt, 2), s2);
202 s2 = vis_faligndata(vis_ld_u8_i(tt, 1), s2);
203 s2 = vis_faligndata(vis_ld_u8_i(tt, 0), s2);
204
205 cx = x >> MLIB_SHIFT;
206 tt = tsp + 2*cx + cx;
207 x -= dx;
208 s2 = vis_faligndata(vis_ld_u8_i(tt, 2), s2);
209 s2 = vis_faligndata(vis_ld_u8_i(tt, 1), s2);
210 s2 = vis_faligndata(vis_ld_u8_i(tt, 0), s2);
211
212 cx = x >> MLIB_SHIFT;
213 tt = tsp + 2*cx + cx;
214 x -= dx;
215 s2 = vis_faligndata(vis_ld_u8_i(tt, 2), s2);
216 s2 = vis_faligndata(vis_ld_u8_i(tt, 1), s2);
217 s1 = vis_faligndata(vis_ld_u8_i(tt, 0), s1);
218
219 cx = x >> MLIB_SHIFT;
220 tt = tsp + 2*cx + cx;
221 x -= dx;
222 s1 = vis_faligndata(vis_ld_u8_i(tt, 2), s1);
223 s1 = vis_faligndata(vis_ld_u8_i(tt, 1), s1);
224 s1 = vis_faligndata(vis_ld_u8_i(tt, 0), s1);
225
226 cx = x >> MLIB_SHIFT;
227 tt = tsp + 2*cx + cx;
228 x -= dx;
229 s1 = vis_faligndata(vis_ld_u8_i(tt, 2), s1);
230 s1 = vis_faligndata(vis_ld_u8_i(tt, 1), s1);
231 s1 = vis_faligndata(vis_ld_u8_i(tt, 0), s1);
232
233 cx = x >> MLIB_SHIFT;
234 tt = tsp + 2*cx + cx;
235 x -= dx;
236 s1 = vis_faligndata(vis_ld_u8_i(tt, 2), s1);
237 s0 = vis_faligndata(vis_ld_u8_i(tt, 1), s0);
238 s0 = vis_faligndata(vis_ld_u8_i(tt, 0), s0);
239
240 cx = x >> MLIB_SHIFT;
241 tt = tsp + 2*cx + cx;
242 x -= dx;
243 s0 = vis_faligndata(vis_ld_u8_i(tt, 2), s0);
244 s0 = vis_faligndata(vis_ld_u8_i(tt, 1), s0);
245 s0 = vis_faligndata(vis_ld_u8_i(tt, 0), s0);
246
247 cx = x >> MLIB_SHIFT;
248 tt = tsp + 2*cx + cx;
249 x += dx15;
250 s0 = vis_faligndata(vis_ld_u8_i(tt, 2), s0);
251 s0 = vis_faligndata(vis_ld_u8_i(tt, 1), s0);
252 s0 = vis_faligndata(vis_ld_u8_i(tt, 0), s0);
253
254 ((mlib_d64*)dp)[0] = s0;
255 ((mlib_d64*)dp)[1] = s1;
256 ((mlib_d64*)dp)[2] = s2;
257 }
258
259 x -= dx7;
260
261 while (dp < dend) {
262 cx = x >> MLIB_SHIFT;
263 tt = tsp + 2*cx + cx;
264 dp[0] = tt[0];
265 dp[1] = tt[1];
266 dp[2] = tt[2];
267 x += dx;
268 dp += 3;
269 }
270 }
271
272 y0 = y;
273 y += dy;
274 dl = (void*)((mlib_u8*)dl + dst_stride);
275 tsp = (void*)((mlib_u8*)sp + (y >> MLIB_SHIFT) * src_stride);
276 }
277
278 return MLIB_SUCCESS;
279}
280
281/***************************************************************/
282
283mlib_status mlib_ImageZoom_S16_3_Nearest(mlib_work_image *param)
284{
285 VARIABLE(mlib_s16);
286 mlib_s16 *dl = dp, *tsp, *tt;
287 mlib_s32 cx, y0 = -1, dx3 = 3*dx, dx7 = 4*dx + dx3;
288
289 tsp = sp;
290 y = GetElemSubStruct(current, srcY) & MLIB_MASK;
291
292 for (j = 0; j < height; j++) {
293
294 if ((y0 >> MLIB_SHIFT) == (y >> MLIB_SHIFT)) {
295 mlib_ImageCopy_na((void*)((mlib_u8*)dl - dst_stride), (void*)dl, 6*width);
296 }
297 else {
298 mlib_s16 *dp = dl, *dend = dl + 3*width;
299
300 vis_write_gsr(6);
301 x = GetElemSubStruct(current, srcX) & MLIB_MASK;
302
303 while (((mlib_addr)dp & 7) && (dp < dend)) {
304 cx = x >> MLIB_SHIFT;
305 tt = tsp + 2*cx + cx;
306 dp[0] = tt[0];
307 dp[1] = tt[1];
308 dp[2] = tt[2];
309 x += dx;
310 dp += 3;
311 }
312
313 x += dx3;
314
315#pragma pipeloop(0)
316 for (; dp <= dend - 12; dp += 12) {
317 mlib_d64 s0, s1, s2;
318
319 cx = x >> MLIB_SHIFT;
320 tt = tsp + 2*cx + cx;
321 x -= dx;
322 s2 = vis_faligndata(vis_ld_u16_i(tt, 4), s2);
323 s2 = vis_faligndata(vis_ld_u16_i(tt, 2), s2);
324 s2 = vis_faligndata(vis_ld_u16_i(tt, 0), s2);
325
326 cx = x >> MLIB_SHIFT;
327 tt = tsp + 2*cx + cx;
328 x -= dx;
329 s2 = vis_faligndata(vis_ld_u16_i(tt, 4), s2);
330 s1 = vis_faligndata(vis_ld_u16_i(tt, 2), s1);
331 s1 = vis_faligndata(vis_ld_u16_i(tt, 0), s1);
332
333 cx = x >> MLIB_SHIFT;
334 tt = tsp + 2*cx + cx;
335 x -= dx;
336 s1 = vis_faligndata(vis_ld_u16_i(tt, 4), s1);
337 s1 = vis_faligndata(vis_ld_u16_i(tt, 2), s1);
338 s0 = vis_faligndata(vis_ld_u16_i(tt, 0), s0);
339
340 cx = x >> MLIB_SHIFT;
341 tt = tsp + 2*cx + cx;
342 x += dx7;
343 s0 = vis_faligndata(vis_ld_u16_i(tt, 4), s0);
344 s0 = vis_faligndata(vis_ld_u16_i(tt, 2), s0);
345 s0 = vis_faligndata(vis_ld_u16_i(tt, 0), s0);
346
347 ((mlib_d64*)dp)[0] = s0;
348 ((mlib_d64*)dp)[1] = s1;
349 ((mlib_d64*)dp)[2] = s2;
350 }
351
352 x -= dx3;
353
354 while (dp < dend) {
355 cx = x >> MLIB_SHIFT;
356 tt = tsp + 2*cx + cx;
357 dp[0] = tt[0];
358 dp[1] = tt[1];
359 dp[2] = tt[2];
360 x += dx;
361 dp += 3;
362 }
363 }
364
365 y0 = y;
366 y += dy;
367 dl = (void*)((mlib_u8*)dl + dst_stride);
368 tsp = (void*)((mlib_u8*)sp + (y >> MLIB_SHIFT) * src_stride);
369 }
370
371 return MLIB_SUCCESS;
372}
373
374/***************************************************************/
375
376mlib_status mlib_ImageZoom_S16_1_Nearest(mlib_work_image *param)
377{
378 VARIABLE(mlib_u16);
379 mlib_u16 *dl = dp, *tsp;
380 mlib_s32 y0 = -1, dx3 = 3*dx, dx7 = 4*dx + dx3;
381
382 tsp = sp;
383 y = GetElemSubStruct(current, srcY) & MLIB_MASK;
384
385 for (j = 0; j < height; j++) {
386
387 if ((y0 >> MLIB_SHIFT) == (y >> MLIB_SHIFT)) {
388 mlib_ImageCopy_na((void*)((mlib_u8*)dl - dst_stride), (void*)dl, 2*width);
389 }
390 else {
391 mlib_u16 *dp = dl, *dend = dl + width;
392
393 vis_write_gsr(6);
394 x = GetElemSubStruct(current, srcX) & MLIB_MASK;
395
396 while (((mlib_addr)dp & 7) && (dp < dend)) {
397 *dp++ = tsp[x >> MLIB_SHIFT];
398 x += dx;
399 }
400
401 x += dx3;
402
403#pragma pipeloop(0)
404 for (; dp <= dend - 4; dp += 4) {
405 mlib_d64 s0;
406
407 s0 = vis_faligndata(vis_ld_u16_i(tsp, (x >> (MLIB_SHIFT - 1)) &~ 1), s0);
408 x -= dx;
409 s0 = vis_faligndata(vis_ld_u16_i(tsp, (x >> (MLIB_SHIFT - 1)) &~ 1), s0);
410 x -= dx;
411 s0 = vis_faligndata(vis_ld_u16_i(tsp, (x >> (MLIB_SHIFT - 1)) &~ 1), s0);
412 x -= dx;
413 s0 = vis_faligndata(vis_ld_u16_i(tsp, (x >> (MLIB_SHIFT - 1)) &~ 1), s0);
414 x += dx7;
415
416 *(mlib_d64*)dp = s0;
417 }
418
419 x -= dx3;
420
421 while (dp < dend) {
422 *dp++ = tsp[x >> MLIB_SHIFT];
423 x += dx;
424 }
425 }
426
427 y0 = y;
428 y += dy;
429 dl = (void*)((mlib_u8*)dl + dst_stride);
430 tsp = (void*)((mlib_u8*)sp + (y >> MLIB_SHIFT) * src_stride);
431 }
432
433 return MLIB_SUCCESS;
434}
435
436/***************************************************************/