Blender V2.61 - r43446

FilterSource.h

Go to the documentation of this file.
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