ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

image_util.cpp

Go to the documentation of this file.
00001 /* ResidualVM - A 3D game interpreter
00002  *
00003  * ResidualVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the AUTHORS
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 /*
00024  * This file is based on, or a modified version of code from TinyGL (C) 1997-1998 Fabrice Bellard,
00025  * which is licensed under the zlib-license (see LICENSE).
00026  * It also has modifications by the ResidualVM-team, which are covered under the GPLv2 (or later).
00027  */
00028 
00029 #include "graphics/tinygl/zgl.h"
00030 
00031 namespace TinyGL {
00032 
00033 // linear interpolation with xf, yf normalized to 2^16
00034 
00035 #define INTERP_NORM_BITS  16
00036 #define INTERP_NORM       (1 << INTERP_NORM_BITS)
00037 
00038 static inline int interpolate(int v00, int v01, int v10, int xf, int yf) {
00039     return v00 + (((v01 - v00) * xf + (v10 - v00) * yf) >> INTERP_NORM_BITS);
00040 }
00041 
00042 // TODO: more accurate resampling
00043 
00044 void gl_resizeImage(unsigned char *dest, int xsize_dest, int ysize_dest,
00045                     unsigned char *src, int xsize_src, int ysize_src) {
00046     unsigned char *pix, *pix_src;
00047     int point1_offset = 0, point2_offset = 0, point3_offset = 0;
00048     float x1, y1, x1inc, y1inc;
00049     int xi, yi, xf, yf;
00050 
00051     pix = dest;
00052     pix_src = src;
00053 
00054     x1inc = (float)(xsize_src - 1) / (float)(xsize_dest - 1);
00055     y1inc = (float)(ysize_src - 1) / (float)(ysize_dest - 1);
00056 
00057     y1 = 0;
00058     for (int y = 0; y < ysize_dest; y++) {
00059         x1 = 0;
00060         for (int x = 0; x < xsize_dest; x++) {
00061             xi = (int)x1;
00062             yi = (int)y1;
00063             xf = (int)((x1 - floor(x1)) * INTERP_NORM);
00064             yf = (int)((y1 - floor(y1)) * INTERP_NORM);
00065 
00066             if ((xf + yf) <= INTERP_NORM) {
00067                 for (int j = 0; j < 3; j++) {
00068                     point1_offset = (yi * xsize_src + xi) * 4 + j;
00069                     if ((xi + 1) < xsize_src)
00070                         point2_offset = (yi * xsize_src + xi + 1) * 4 + j;
00071                     else
00072                         point2_offset = point1_offset;
00073                     if ((yi + 1) < ysize_src)
00074                         point3_offset = ((yi + 1) * xsize_src + xi) * 4 + j;
00075                     else
00076                         point3_offset = point1_offset;
00077                     pix[j] = interpolate(pix_src[point1_offset], pix_src[point2_offset], pix_src[point3_offset], xf, yf);
00078                 }
00079                 pix[3] = pix_src[(yi * xsize_src + xi) * 4 + 3];
00080             } else {
00081                 xf = INTERP_NORM - xf;
00082                 yf = INTERP_NORM - yf;
00083                 for (int j = 0; j < 3; j++) {
00084                     pix[j] = interpolate(pix_src[point1_offset], pix_src[point2_offset], pix_src[point3_offset], xf, yf);
00085                     if ((xi + 1) < xsize_src) {
00086                         if ((yi + 1) < ysize_src)
00087                             point1_offset = ((yi + 1) * xsize_src + xi + 1) * 4 + j;
00088                         else
00089                             point1_offset = (yi * xsize_src + xi + 1) * 4 + j;
00090                     } else {
00091                         if ((yi + 1) < ysize_src)
00092                             point1_offset = ((yi + 1) * xsize_src + xi) * 4 + j;
00093                         else
00094                             point1_offset = (yi * xsize_src + xi) * 4 + j;
00095                     }
00096                     if ((yi + 1) < ysize_src)
00097                         point2_offset = ((yi + 1) * xsize_src + xi) * 4 + j;
00098                     else
00099                         point2_offset = (yi * xsize_src + xi) * 4 + j;
00100                     if ((xi + 1) < xsize_src)
00101                         point3_offset = (yi * xsize_src + xi + 1) * 4 + j;
00102                     else
00103                         point3_offset = (yi * xsize_src + xi) * 4 + j;
00104                     pix[j] = interpolate(pix_src[point1_offset], pix_src[point2_offset], pix_src[point3_offset], xf, yf);
00105                 }
00106                 pix[3] = pix_src[(yi * xsize_src + xi) * 4 + 3];
00107             }
00108             pix += 4;
00109             x1 += x1inc;
00110         }
00111         y1 += y1inc;
00112     }
00113 }
00114 
00115 #define FRAC_BITS 16
00116 
00117 // resizing with no interlating nor nearest pixel
00118 void gl_resizeImageNoInterpolate(unsigned char *dest, int xsize_dest, int ysize_dest,
00119                                  unsigned char *src, int xsize_src, int ysize_src) {
00120     unsigned char *pix, *pix_src, *pix1;
00121     int x1, y1, x1inc, y1inc;
00122     int xi, yi;
00123 
00124     pix = dest;
00125     pix_src = src;
00126 
00127     x1inc = (int)((float)((xsize_src) << FRAC_BITS) / (float)(xsize_dest));
00128     y1inc = (int)((float)((ysize_src) << FRAC_BITS) / (float)(ysize_dest));
00129 
00130     y1 = 0;
00131     for (int y = 0; y < ysize_dest; y++) {
00132         x1 = 0;
00133         for (int x = 0; x < xsize_dest; x++) {
00134             xi = x1 >> FRAC_BITS;
00135             yi = y1 >> FRAC_BITS;
00136             pix1 = pix_src + (yi * xsize_src + xi) * 4;
00137 
00138             pix[0] = pix1[0];
00139             pix[1] = pix1[1];
00140             pix[2] = pix1[2];
00141             pix[3] = pix1[3];
00142 
00143             pix += 4;
00144             x1 += x1inc;
00145         }
00146         y1 += y1inc;
00147     }
00148 }
00149 
00150 } // end of namespace TinyGL


Generated on Sat May 18 2019 05:01:05 for ResidualVM by doxygen 1.7.1
curved edge   curved edge