/* * Pure Data Packet system file. - image resampling routines * Copyright (c) by Tom Schouten * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "pdp_resample.h" #include "pdp.h" /* efficient bilinear resampling ?? performance: how to eliminate divides? -> virtual coordinates 2^k x 2^k (conf. opengl) i.e. 16 bit virtual coordinates: easy modular addressing */ s32 pdp_resample_bilin(s16 *image, s32 width, s32 height, s32 virt_x, s32 virt_y) { s32 fp_x, fp_y, frac_x, frac_y, f, offset, r_1, r_2; virt_x &= 0xffff; virt_y &= 0xffff; fp_x = virt_x * (width - 1); fp_y = virt_y * (height - 1); frac_x = fp_x & (0xffff); frac_y = fp_y & (0xffff); offset = (fp_x >> 16) + (fp_y >> 16) * width; image += offset; f = 0x10000 - frac_x; r_1 = ((f * (s32)(image[0]) + frac_x * (s32)(image[1])))>>16; image += width; r_2 = ((f * (s32)(image[0]) + frac_x * (s32)(image[1])))>>16; f = 0x10000 - frac_y; return ((f * r_1 + frac_y * r_2)>>16); } void pdp_resample_scale_bilin(s16 *src_image, s16 *dst_image, s32 src_w, s32 src_h, s32 dst_w, s32 dst_h) { s32 i,j; s32 virt_x=0; s32 virt_y=0; /* virtual coordinates in 30 bit */ s32 scale_x = 0x40000000 / dst_w; s32 scale_y = 0x40000000 / dst_h; for (j=0; j>14, virt_y>>14); virt_x += scale_x; } virt_x = 0; virt_y += scale_y; } } void pdp_resample_scale_nn(s16 *src_image, s16 *dst_image, s32 src_w, s32 src_h, s32 dst_w, s32 dst_h) { s32 i,j; s32 x=0; s32 y=0; s32 frac_x=0; s32 frac_y=0; s32 scale_x = (src_w << 20 ) / dst_w; s32 scale_y = (src_h << 20 ) / dst_h; for (j=0; j> 20; } x = 0; frac_x = 0; frac_y += scale_y; y = (frac_y >> 20) * src_w; } } void pdp_resample_zoom_tiled_bilin(s16 *src_image, s16 *dst_image, s32 w, s32 h, float zoom_x, float zoom_y, float center_x_relative, float center_y_relative) { float izx = 1.0f / zoom_x; float izy = 1.0f / zoom_y; s32 scale_x = (s32)((float)0x100000 * izx / (float)w); s32 scale_y = (s32)((float)0x100000 * izy / (float)h); s32 top_virt_x = (s32)((1.0f - izx) * (float)0x100000 * center_x_relative); s32 top_virt_y = (s32)((1.0f - izy) * (float)0x100000 * center_y_relative); s32 virt_x = top_virt_x; s32 virt_y = top_virt_y; s32 i,j; for (j=0; j>4, virt_y>>4); virt_x += scale_x; } virt_x = top_virt_x; virt_y += scale_y; } }