2
* Pure Data Packet system file. - image resampling routines
3
* Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org>
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
#include "pdp_resample.h"
28
efficient bilinear resampling ??
29
performance: how to eliminate divides? -> virtual coordinates 2^k x 2^k (conf. opengl)
31
i.e. 16 bit virtual coordinates: easy modular addressing
36
/* code in this file should go out to be replaced by code in pdp_imageproc */
38
static s32 pdp_resample_bilin(s16 *image, s32 width, s32 height, s32 virt_x, s32 virt_y)
41
s32 fp_x, fp_y, frac_x, frac_y, f, offset, r_1, r_2;
46
fp_x = virt_x * (width - 1);
47
fp_y = virt_y * (height - 1);
49
frac_x = fp_x & (0xffff);
50
frac_y = fp_y & (0xffff);
52
offset = (fp_x >> 16) + (fp_y >> 16) * width;
57
r_1 = ((f * (s32)(image[0]) + frac_x * (s32)(image[1])))>>16;
61
r_2 = ((f * (s32)(image[0]) + frac_x * (s32)(image[1])))>>16;
65
return ((f * r_1 + frac_y * r_2)>>16);
70
void pdp_resample_scale_bilin(s16 *src_image, s16 *dst_image, s32 src_w, s32 src_h, s32 dst_w, s32 dst_h)
74
s32 virt_y=0; /* virtual coordinates in 30 bit */
75
s32 scale_x = 0x40000000 / dst_w;
76
s32 scale_y = 0x40000000 / dst_h;
78
for (j=0; j<dst_h; j++){
79
for (i=0; i<dst_w; i++){
80
*dst_image++ = pdp_resample_bilin(src_image, src_w, src_h, virt_x>>14, virt_y>>14);
89
void pdp_resample_scale_nn(s16 *src_image, s16 *dst_image, s32 src_w, s32 src_h, s32 dst_w, s32 dst_h)
96
s32 scale_x = (src_w << 20 ) / dst_w;
97
s32 scale_y = (src_h << 20 ) / dst_h;
99
for (j=0; j<dst_h; j++){
100
for (i=0; i<dst_w; i++){
101
*dst_image++ = src_image[x+y];
108
y = (frac_y >> 20) * src_w;
113
/* USE pdp_resample_affinemap
114
void pdp_resample_zoom_tiled_bilin(s16 *src_image, s16 *dst_image, s32 w, s32 h,
115
float zoom_x, float zoom_y, float center_x_relative, float center_y_relative)
117
float izx = 1.0f / zoom_x;
118
float izy = 1.0f / zoom_y;
119
s32 scale_x = (s32)((float)0x100000 * izx / (float)w);
120
s32 scale_y = (s32)((float)0x100000 * izy / (float)h);
122
s32 top_virt_x = (s32)((1.0f - izx) * (float)0x100000 * center_x_relative);
123
s32 top_virt_y = (s32)((1.0f - izy) * (float)0x100000 * center_y_relative);
125
s32 virt_x = top_virt_x;
126
s32 virt_y = top_virt_y;
132
*dst_image++ = pdp_resample_bilin(src_image, w, h, virt_x>>4, virt_y>>4);
142
void pdp_resample_halve(s16 *src_image, s16 *dst_image, s32 src_w, s32 src_h)
148
int dst_w = src_w >> 1;
149
int dst_h = src_h >> 1;
150
s32 tmp1,tmp2,tmp3,tmp4;
152
//post("%x %x %d %d\n", src_image, dst_image, src_w, src_h);
154
for(dst_y = 0; dst_y < dst_h * dst_w; dst_y += dst_w){
155
for (dst_x = 0; dst_x < dst_w; dst_x++){
157
tmp1 = (s32)src_image[src_y + src_x];
158
tmp2 = (s32)src_image[src_y + src_x + 1];
159
tmp3 = (s32)src_image[src_y + src_x + src_w];
160
tmp4 = (s32)src_image[src_y + src_x + src_w + 1];
167
dst_image[dst_x+dst_y] = (s16)((tmp1 + tmp3)>>2);
174
void pdp_resample_double(s16 *src_image, s16 *dst_image, s32 src_w, s32 src_h)
179
int dst_w = src_w << 1;
183
for(src_y = 0; src_y < src_h * src_w; src_y += src_w){
184
for (src_x = 0; src_x < src_w; src_x++){
187
dst = (src_y << 2) + (src_x << 1);
188
dst_image[dst] = tmp;
189
dst_image[dst+1] = tmp;
191
dst_image[dst] = tmp;
192
dst_image[dst+1] = tmp;
197
/* $$$TODO: finish this */
198
void pdp_resample_padcrop(s16 *src_image, s16 *dst_image, s32 src_w, s32 src_h, s32 dst_w, s32 dst_h)
201
int shift_x = (dst_w - src_w) / 2;
202
int shift_y = (dst_h - src_h) / 2;