Blender V2.61 - r43446
|
00001 /* 00002 ----------------------------------------------------------------------------- 00003 This source file is part of blendTex library 00004 00005 Copyright (c) 2007 The Zdeno Ash Miklas 00006 00007 This program is free software; you can redistribute it and/or modify it under 00008 the terms of the GNU Lesser General Public License as published by the Free Software 00009 Foundation; either version 2 of the License, or (at your option) any later 00010 version. 00011 00012 This program is distributed in the hope that it will be useful, but WITHOUT 00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00014 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 00015 00016 You should have received a copy of the GNU Lesser General Public License along with 00017 this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00018 Place - Suite 330, Boston, MA 02111-1307, USA, or go to 00019 http://www.gnu.org/copyleft/lesser.txt. 00020 ----------------------------------------------------------------------------- 00021 */ 00022 00027 #if !defined FILTERSOURCE_H 00028 #define FILTERSOURCE_H 00029 00030 #include "Common.h" 00031 00032 #include "FilterBase.h" 00033 00034 00036 class FilterRGB24 : public FilterBase 00037 { 00038 public: 00040 FilterRGB24 (void) {} 00042 virtual ~FilterRGB24 (void) {} 00043 00045 virtual unsigned int getPixelSize (void) { return 3; } 00046 00047 protected: 00049 virtual unsigned int filter (unsigned char * src, short x, short y, 00050 short * size, unsigned int pixSize, unsigned int val) 00051 { VT_RGBA(val,src[0],src[1],src[2],0xFF); return val; } 00052 }; 00053 00055 class FilterRGBA32 : public FilterBase 00056 { 00057 public: 00059 FilterRGBA32 (void) {} 00061 virtual ~FilterRGBA32 (void) {} 00062 00064 virtual unsigned int getPixelSize (void) { return 4; } 00065 00066 protected: 00068 virtual unsigned int filter (unsigned char * src, short x, short y, 00069 short * size, unsigned int pixSize, unsigned int val) 00070 { 00071 if ((intptr_t(src)&0x3) == 0) 00072 return *(unsigned int*)src; 00073 else 00074 { 00075 VT_RGBA(val,src[0],src[1],src[2],src[3]); 00076 return val; 00077 } 00078 } 00079 }; 00080 00082 class FilterBGR24 : public FilterBase 00083 { 00084 public: 00086 FilterBGR24 (void) {} 00088 virtual ~FilterBGR24 (void) {} 00089 00091 virtual unsigned int getPixelSize (void) { return 3; } 00092 00093 protected: 00095 virtual unsigned int filter (unsigned char * src, short x, short y, 00096 short * size, unsigned int pixSize, unsigned int val) 00097 { VT_RGBA(val,src[2],src[1],src[0],0xFF); return val; } 00098 }; 00099 00101 class FilterYV12 : public FilterBase 00102 { 00103 public: 00105 FilterYV12 (void) {} 00107 virtual ~FilterYV12 (void) {} 00108 00110 virtual unsigned int getPixelSize (void) { return 1; } 00111 00113 void setBuffs (unsigned char * buff, short * size) 00114 { 00115 unsigned int buffSize = size[0] * size[1]; 00116 m_buffV = buff + buffSize; 00117 m_buffU = m_buffV + (buffSize >> 2); 00118 m_pitchUV = size[0] >> 1; 00119 } 00120 00121 protected: 00123 unsigned char * m_buffV; 00125 unsigned char * m_buffU; 00127 short m_pitchUV; 00128 00130 int interpol (int a, int b, int c, int d) 00131 { return (9 * (b + c) - a - d + 8) >> 4; } 00132 00134 int interpolH (unsigned char * src) 00135 { return interpol(*(src-1), *src, *(src+1), *(src+2)); } 00136 00138 int interpolV (unsigned char * src) 00139 { return interpol(*(src-m_pitchUV), *src, *(src+m_pitchUV), *(src+2*m_pitchUV)); } 00140 00142 int interpolVH (unsigned char * src) 00143 { 00144 return interpol(interpolV(src-1), interpolV(src), interpolV(src+1), 00145 interpolV(src+2)); 00146 } 00147 00149 bool isEdge (short x, short y, short * size) 00150 { return x <= 1 || x >= size[0] - 4 || y <= 1 || y >= size[1] - 4; } 00151 00153 unsigned char * interParA (unsigned char * src, short x, short size, short shift) 00154 { return x > 1 ? src - shift : src; } 00156 unsigned char * interParC (unsigned char * src, short x, short size, short shift) 00157 { return x < size - 2 ? src + shift : src; } 00159 unsigned char * interParD (unsigned char * src, short x, short size, short shift) 00160 { return x < size - 4 ? src + 2 * shift : x < size - 2 ? src + shift : src; } 00161 00163 int interpolEH (unsigned char * src, short x, short size) 00164 { 00165 return interpol(*interParA(src, x, size, 1), *src, 00166 *interParC(src, x, size, 1), *interParD(src, x, size, 1)); 00167 } 00168 00170 int interpolEV (unsigned char * src, short y, short size) 00171 { 00172 return interpol(*interParA(src, y, size, m_pitchUV), *src, 00173 *interParC(src, y, size, m_pitchUV), *interParD(src, y, size, m_pitchUV)); 00174 } 00175 00177 int interpolEVH (unsigned char * src, short x, short y, short * size) 00178 { 00179 return interpol(interpolEV(interParA(src, x, size[0], 1), y, size[1]), 00180 interpolEV(src, y, size[1]), interpolEV(interParC(src, x, size[0], 1), y, size[1]), 00181 interpolEV(interParD(src, x, size[0], 1), y, size[1])); 00182 } 00183 00184 00186 virtual unsigned int filter (unsigned char * src, short x, short y, 00187 short * size, unsigned int pixSize, unsigned int val) 00188 { 00189 // V & U offset 00190 long offset = (x >> 1) + m_pitchUV * (y >> 1); 00191 // get modified YUV -> CDE: C = Y - 16; D = U - 128; E = V - 128 00192 int c = *src - 16; 00193 int d = m_buffU[offset] - 128; 00194 int e = m_buffV[offset] - 128; 00195 // if horizontal interpolation is needed 00196 if ((x & 1) == 1) { 00197 // if vertical interpolation is needed too 00198 if ((y & 1) == 1) 00199 { 00200 // if this pixel is on the edge 00201 if (isEdge(x, y, size)) 00202 { 00203 // get U & V from edge 00204 d = interpolEVH(m_buffU + offset, x, y, size) - 128; 00205 e = interpolEVH(m_buffV + offset, x, y, size) - 128; 00206 } 00207 // otherwise get U & V from inner range 00208 else 00209 { 00210 d = interpolVH(m_buffU + offset) - 128; 00211 e = interpolVH(m_buffV + offset) - 128; 00212 } 00213 // otherwise use horizontal interpolation only 00214 } 00215 else { 00216 // if this pixel is on the edge 00217 if (isEdge(x, y, size)) 00218 { 00219 // get U & V from edge 00220 d = interpolEH(m_buffU + offset, x, size[0]) - 128; 00221 e = interpolEH(m_buffV + offset, x, size[0]) - 128; 00222 } 00223 // otherwise get U & V from inner range 00224 else 00225 { 00226 d = interpolH(m_buffU + offset) - 128; 00227 e = interpolH(m_buffV + offset) - 128; 00228 } 00229 // otherwise if only vertical interpolation is needed 00230 } 00231 } 00232 else if ((y & 1) == 1) { 00233 // if this pixel is on the edge 00234 if (isEdge(x, y, size)) 00235 { 00236 // get U & V from edge 00237 d = interpolEV(m_buffU + offset, y, size[1]) - 128; 00238 e = interpolEV(m_buffV + offset, y, size[1]) - 128; 00239 } 00240 // otherwise get U & V from inner range 00241 else 00242 { 00243 d = interpolV(m_buffU + offset) - 128; 00244 e = interpolV(m_buffV + offset) - 128; 00245 } 00246 } 00247 // convert to RGB 00248 // R = clip(( 298 * C + 409 * E + 128) >> 8) 00249 // G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8) 00250 // B = clip(( 298 * C + 516 * D + 128) >> 8) 00251 int red = (298 * c + 409 * e + 128) >> 8; 00252 if (red >= 0x100) red = 0xFF; 00253 else if (red < 0) red = 0; 00254 int green = (298 * c - 100 * d - 208 * e) >> 8; 00255 if (green >= 0x100) green = 0xFF; 00256 else if (green < 0) green = 0; 00257 int blue = (298 * c + 516 * d + 128) >> 8; 00258 if (blue >= 0x100) blue = 0xFF; 00259 else if (blue < 0) blue = 0; 00260 // return result 00261 VT_RGBA(val, red, green, blue, 0xFF); 00262 return val; 00263 } 00264 }; 00265 00266 00267 #endif