Blender  V2.59
FilterSource.h
Go to the documentation of this file.
00001 /* $Id: FilterSource.h 35082 2011-02-22 19:30:37Z jesterking $
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