OgrePixelConversions.h

Go to the documentation of this file.
00001  /*
00002 -----------------------------------------------------------------------------
00003 This source file is part of OGRE
00004     (Object-oriented Graphics Rendering Engine)
00005 For the latest info, see http://www.ogre3d.org/
00006 
00007 Copyright (c) 2000-2006 Torus Knot Software Ltd
00008 Also see acknowledgements in Readme.html
00009 
00010 This program is free software; you can redistribute it and/or modify it under
00011 the terms of the GNU Lesser General Public License as published by the Free Software
00012 Foundation; either version 2 of the License, or (at your option) any later
00013 version.
00014 
00015 This program is distributed in the hope that it will be useful, but WITHOUT
00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
00018 
00019 You should have received a copy of the GNU Lesser General Public License along with
00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
00022 http://www.gnu.org/copyleft/lesser.txt.
00023 
00024 You may alternatively use this source under the terms of a specific version of
00025 the OGRE Unrestricted License provided you have obtained such a license from
00026 Torus Knot Software Ltd.
00027 -----------------------------------------------------------------------------
00028 */
00030 using namespace Ogre;
00031 
00032 // NB VC6 can't handle these templates
00033 #if OGRE_COMPILER != OGRE_COMPILER_MSVC || OGRE_COMP_VER >= 1300
00034 
00035 #define FMTCONVERTERID(from,to) (((from)<<8)|(to))
00036 
00047 template <class U> struct PixelBoxConverter 
00048 {
00049     static const int ID = U::ID;
00050     static void conversion(const PixelBox &src, const PixelBox &dst)
00051     {
00052         typename U::SrcType *srcptr = static_cast<typename U::SrcType*>(src.data)
00053             + (src.left + src.top * src.rowPitch + src.front * src.slicePitch);
00054         typename U::DstType *dstptr = static_cast<typename U::DstType*>(dst.data)
00055             + (dst.left + dst.top * dst.rowPitch + dst.front * dst.slicePitch);
00056         const size_t srcSliceSkip = src.getSliceSkip();
00057         const size_t dstSliceSkip = dst.getSliceSkip();
00058         const size_t k = src.right - src.left;
00059         for(size_t z=src.front; z<src.back; z++) 
00060         {
00061             for(size_t y=src.top; y<src.bottom; y++)
00062             {
00063                 for(size_t x=0; x<k; x++)
00064                 {
00065                     dstptr[x] = U::pixelConvert(srcptr[x]);
00066                 }
00067                 srcptr += src.rowPitch;
00068                 dstptr += dst.rowPitch;
00069             }
00070             srcptr += srcSliceSkip;
00071             dstptr += dstSliceSkip;
00072         }    
00073     }
00074 };
00075 
00076 template <typename T, typename U, int id> struct PixelConverter {
00077     static const int ID = id;
00078     typedef T SrcType;
00079     typedef U DstType;    
00080     
00081     //inline static DstType pixelConvert(const SrcType &inp);
00082 };
00083 
00084 
00086 struct Col3b {
00087     Col3b(unsigned int a, unsigned int b, unsigned int c): 
00088         x((Ogre::uint8)a), y((Ogre::uint8)b), z((Ogre::uint8)c) { }
00089     Ogre::uint8 x,y,z;
00090 };
00092 struct Col3f {
00093     Col3f(float r, float g, float b):
00094         r(r), g(g), b(b) { }
00095     float r,g,b;
00096 };
00098 struct Col4f {
00099     Col4f(float r, float g, float b, float a):
00100         r(r), g(g), b(b), a(a) { }
00101     float r,g,b,a;
00102 };
00103 
00104 struct A8R8G8B8toA8B8G8R8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_A8R8G8B8, PF_A8B8G8R8)>
00105 {
00106     inline static DstType pixelConvert(SrcType inp)
00107     {
00108         return ((inp&0x000000FF)<<16)|(inp&0xFF00FF00)|((inp&0x00FF0000)>>16);
00109     }
00110 };
00111 
00112 struct A8R8G8B8toB8G8R8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_A8R8G8B8, PF_B8G8R8A8)>
00113 {
00114     inline static DstType pixelConvert(SrcType inp)
00115     {
00116         return ((inp&0x000000FF)<<24)|((inp&0x0000FF00)<<8)|((inp&0x00FF0000)>>8)|((inp&0xFF000000)>>24);
00117     }
00118 };
00119 
00120 struct A8R8G8B8toR8G8B8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_A8R8G8B8, PF_R8G8B8A8)>
00121 {
00122     inline static DstType pixelConvert(SrcType inp)
00123     {
00124         return ((inp&0x00FFFFFF)<<8)|((inp&0xFF000000)>>24);
00125     }
00126 };
00127 
00128 struct A8B8G8R8toA8R8G8B8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_A8B8G8R8, PF_A8R8G8B8)>
00129 {
00130     inline static DstType pixelConvert(SrcType inp)
00131     {
00132         return ((inp&0x000000FF)<<16)|(inp&0xFF00FF00)|((inp&0x00FF0000)>>16);
00133     }
00134 };
00135 
00136 struct A8B8G8R8toB8G8R8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_A8B8G8R8, PF_B8G8R8A8)>
00137 {
00138     inline static DstType pixelConvert(SrcType inp)
00139     {
00140         return ((inp&0x00FFFFFF)<<8)|((inp&0xFF000000)>>24);
00141     }
00142 };
00143 
00144 struct A8B8G8R8toR8G8B8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_A8B8G8R8, PF_R8G8B8A8)>
00145 {
00146     inline static DstType pixelConvert(SrcType inp)
00147     {
00148         return ((inp&0x000000FF)<<24)|((inp&0x0000FF00)<<8)|((inp&0x00FF0000)>>8)|((inp&0xFF000000)>>24);
00149     }
00150 };
00151 
00152 struct B8G8R8A8toA8R8G8B8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_B8G8R8A8, PF_A8R8G8B8)>
00153 {
00154     inline static DstType pixelConvert(SrcType inp)
00155     {
00156         return ((inp&0x000000FF)<<24)|((inp&0x0000FF00)<<8)|((inp&0x00FF0000)>>8)|((inp&0xFF000000)>>24);
00157     }
00158 };
00159 
00160 struct B8G8R8A8toA8B8G8R8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_B8G8R8A8, PF_A8B8G8R8)>
00161 {
00162     inline static DstType pixelConvert(SrcType inp)
00163     {
00164         return ((inp&0x000000FF)<<24)|((inp&0xFFFFFF00)>>8);
00165     }
00166 };
00167 
00168 struct B8G8R8A8toR8G8B8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_B8G8R8A8, PF_R8G8B8A8)>
00169 {
00170     inline static DstType pixelConvert(SrcType inp)
00171     {
00172         return ((inp&0x0000FF00)<<16)|(inp&0x00FF00FF)|((inp&0xFF000000)>>16);
00173     }
00174 };
00175 
00176 struct R8G8B8A8toA8R8G8B8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_R8G8B8A8, PF_A8R8G8B8)>
00177 {
00178     inline static DstType pixelConvert(SrcType inp)
00179     {
00180         return ((inp&0x000000FF)<<24)|((inp&0xFFFFFF00)>>8);
00181     }
00182 };
00183 
00184 struct R8G8B8A8toA8B8G8R8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_R8G8B8A8, PF_A8B8G8R8)>
00185 {
00186     inline static DstType pixelConvert(SrcType inp)
00187     {
00188         return ((inp&0x000000FF)<<24)|((inp&0x0000FF00)<<8)|((inp&0x00FF0000)>>8)|((inp&0xFF000000)>>24);
00189     }
00190 };
00191 
00192 struct R8G8B8A8toB8G8R8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_R8G8B8A8, PF_B8G8R8A8)>
00193 {
00194     inline static DstType pixelConvert(SrcType inp)
00195     {
00196         return ((inp&0x0000FF00)<<16)|(inp&0x00FF00FF)|((inp&0xFF000000)>>16);
00197     }
00198 };
00199 
00200 struct A8B8G8R8toL8: public PixelConverter <Ogre::uint32, Ogre::uint8, FMTCONVERTERID(PF_A8B8G8R8, PF_L8)>
00201 {
00202     inline static DstType pixelConvert(SrcType inp)
00203     {
00204         return (Ogre::uint8)(inp&0x000000FF);
00205     }
00206 };
00207 
00208 struct L8toA8B8G8R8: public PixelConverter <Ogre::uint8, Ogre::uint32, FMTCONVERTERID(PF_L8, PF_A8B8G8R8)>
00209 {
00210     inline static DstType pixelConvert(SrcType inp)
00211     {
00212         return 0xFF000000|(((unsigned int)inp)<<0)|(((unsigned int)inp)<<8)|(((unsigned int)inp)<<16);
00213     }
00214 };
00215 
00216 struct A8R8G8B8toL8: public PixelConverter <Ogre::uint32, Ogre::uint8, FMTCONVERTERID(PF_A8R8G8B8, PF_L8)>
00217 {
00218     inline static DstType pixelConvert(SrcType inp)
00219     {
00220         return (Ogre::uint8)((inp&0x00FF0000)>>16);
00221     }
00222 };
00223 
00224 struct L8toA8R8G8B8: public PixelConverter <Ogre::uint8, Ogre::uint32, FMTCONVERTERID(PF_L8, PF_A8R8G8B8)>
00225 {
00226     inline static DstType pixelConvert(SrcType inp)
00227     {
00228         return 0xFF000000|(((unsigned int)inp)<<0)|(((unsigned int)inp)<<8)|(((unsigned int)inp)<<16);
00229     }
00230 };
00231 
00232 struct B8G8R8A8toL8: public PixelConverter <Ogre::uint32, Ogre::uint8, FMTCONVERTERID(PF_B8G8R8A8, PF_L8)>
00233 {
00234     inline static DstType pixelConvert(SrcType inp)
00235     {
00236         return (Ogre::uint8)((inp&0x0000FF00)>>8);
00237     }
00238 };
00239 
00240 struct L8toB8G8R8A8: public PixelConverter <Ogre::uint8, Ogre::uint32, FMTCONVERTERID(PF_L8, PF_B8G8R8A8)>
00241 {
00242     inline static DstType pixelConvert(SrcType inp)
00243     {
00244         return 0x000000FF|(((unsigned int)inp)<<8)|(((unsigned int)inp)<<16)|(((unsigned int)inp)<<24);
00245     }
00246 };
00247 
00248 struct L8toL16: public PixelConverter <Ogre::uint8, Ogre::uint16, FMTCONVERTERID(PF_L8, PF_L16)>
00249 {
00250     inline static DstType pixelConvert(SrcType inp)
00251     {
00252         return (Ogre::uint16)((((unsigned int)inp)<<8)|(((unsigned int)inp)));
00253     }
00254 };
00255 
00256 struct L16toL8: public PixelConverter <Ogre::uint16, Ogre::uint8, FMTCONVERTERID(PF_L16, PF_L8)>
00257 {
00258     inline static DstType pixelConvert(SrcType inp)
00259     {
00260         return (Ogre::uint8)(inp>>8);
00261     }
00262 };
00263 
00264 struct R8G8B8toB8G8R8: public PixelConverter <Col3b, Col3b, FMTCONVERTERID(PF_R8G8B8, PF_B8G8R8)>
00265 {
00266     inline static DstType pixelConvert(const SrcType &inp)
00267     {
00268         return Col3b(inp.z, inp.y, inp.x);
00269     }  
00270 };
00271 
00272 struct B8G8R8toR8G8B8: public PixelConverter <Col3b, Col3b, FMTCONVERTERID(PF_B8G8R8, PF_R8G8B8)>
00273 {
00274     inline static DstType pixelConvert(const SrcType &inp)
00275     {
00276         return Col3b(inp.z, inp.y, inp.x);
00277     }  
00278 };
00279 
00280 // X8Y8Z8 ->  X8<<xshift Y8<<yshift Z8<<zshift A8<<ashift
00281 template <int id, unsigned int xshift, unsigned int yshift, unsigned int zshift, unsigned int ashift> struct Col3btoUint32swizzler:
00282     public PixelConverter <Col3b, Ogre::uint32, id>
00283 {
00284     inline static Ogre::uint32 pixelConvert(const Col3b &inp)
00285     {
00286 #if OGRE_ENDIAN == OGRE_ENDIAN_BIG
00287         return (0xFF<<ashift) | (((unsigned int)inp.x)<<xshift) | (((unsigned int)inp.y)<<yshift) | (((unsigned int)inp.z)<<zshift);
00288 #else
00289         return (0xFF<<ashift) | (((unsigned int)inp.x)<<zshift) | (((unsigned int)inp.y)<<yshift) | (((unsigned int)inp.z)<<xshift);
00290 #endif
00291     }
00292 };
00293 
00294 struct R8G8B8toA8R8G8B8: public Col3btoUint32swizzler<FMTCONVERTERID(PF_R8G8B8, PF_A8R8G8B8), 16, 8, 0, 24> { };
00295 struct B8G8R8toA8R8G8B8: public Col3btoUint32swizzler<FMTCONVERTERID(PF_B8G8R8, PF_A8R8G8B8), 0, 8, 16, 24> { };
00296 struct R8G8B8toA8B8G8R8: public Col3btoUint32swizzler<FMTCONVERTERID(PF_R8G8B8, PF_A8B8G8R8), 0, 8, 16, 24> { };
00297 struct B8G8R8toA8B8G8R8: public Col3btoUint32swizzler<FMTCONVERTERID(PF_B8G8R8, PF_A8B8G8R8), 16, 8, 0, 24> { };
00298 struct R8G8B8toB8G8R8A8: public Col3btoUint32swizzler<FMTCONVERTERID(PF_R8G8B8, PF_B8G8R8A8), 8, 16, 24, 0> { };
00299 struct B8G8R8toB8G8R8A8: public Col3btoUint32swizzler<FMTCONVERTERID(PF_B8G8R8, PF_B8G8R8A8), 24, 16, 8, 0> { };
00300 
00301 struct A8R8G8B8toR8G8B8: public PixelConverter <Ogre::uint32, Col3b, FMTCONVERTERID(PF_A8R8G8B8, PF_BYTE_RGB)>
00302 {
00303     inline static DstType pixelConvert(Ogre::uint32 inp)
00304     {
00305         return Col3b((Ogre::uint8)((inp>>16)&0xFF), (Ogre::uint8)((inp>>8)&0xFF), (Ogre::uint8)((inp>>0)&0xFF));
00306     }
00307 };
00308 struct A8R8G8B8toB8G8R8: public PixelConverter <Ogre::uint32, Col3b, FMTCONVERTERID(PF_A8R8G8B8, PF_BYTE_BGR)>
00309 {
00310     inline static DstType pixelConvert(Ogre::uint32 inp)
00311     {
00312         return Col3b((Ogre::uint8)((inp>>0)&0xFF), (Ogre::uint8)((inp>>8)&0xFF), (Ogre::uint8)((inp>>16)&0xFF));
00313     }
00314 };
00315 
00316 // Only conversions from X8R8G8B8 to formats with alpha need to be defined, the rest is implicitly the same
00317 // as A8R8G8B8
00318 struct X8R8G8B8toA8R8G8B8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_X8R8G8B8, PF_A8R8G8B8)>
00319 {
00320     inline static DstType pixelConvert(SrcType inp)
00321     {
00322         return inp | 0xFF000000;
00323     }
00324 };
00325 struct X8R8G8B8toA8B8G8R8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_X8R8G8B8, PF_A8B8G8R8)>
00326 {
00327     inline static DstType pixelConvert(SrcType inp)
00328     {
00329         return ((inp&0x0000FF)<<16)|((inp&0xFF0000)>>16)|(inp&0x00FF00)|0xFF000000;
00330     }
00331 };
00332 struct X8R8G8B8toB8G8R8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_X8R8G8B8, PF_B8G8R8A8)>
00333 {
00334     inline static DstType pixelConvert(SrcType inp)
00335     {
00336         return ((inp&0x0000FF)<<24)|((inp&0xFF0000)>>8)|((inp&0x00FF00)<<8)|0x000000FF;
00337     }
00338 };
00339 struct X8R8G8B8toR8G8B8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_X8R8G8B8, PF_R8G8B8A8)>
00340 {
00341     inline static DstType pixelConvert(SrcType inp)
00342     {
00343         return ((inp&0xFFFFFF)<<8)|0x000000FF;
00344     }
00345 };
00346 
00347 // X8B8G8R8
00348 struct X8B8G8R8toA8R8G8B8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_X8B8G8R8, PF_A8R8G8B8)>
00349 {
00350     inline static DstType pixelConvert(SrcType inp)
00351     {
00352         return ((inp&0x0000FF)<<16)|((inp&0xFF0000)>>16)|(inp&0x00FF00)|0xFF000000;
00353     }
00354 };
00355 struct X8B8G8R8toA8B8G8R8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_X8B8G8R8, PF_A8B8G8R8)>
00356 {
00357     inline static DstType pixelConvert(SrcType inp)
00358     {
00359         return inp | 0xFF000000;
00360     }
00361 };
00362 struct X8B8G8R8toB8G8R8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_X8B8G8R8, PF_B8G8R8A8)>
00363 {
00364     inline static DstType pixelConvert(SrcType inp)
00365     {
00366         return ((inp&0xFFFFFF)<<8)|0x000000FF;
00367     }
00368 };
00369 struct X8B8G8R8toR8G8B8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_X8B8G8R8, PF_R8G8B8A8)>
00370 {
00371     inline static DstType pixelConvert(SrcType inp)
00372     {
00373         return ((inp&0x0000FF)<<24)|((inp&0xFF0000)>>8)|((inp&0x00FF00)<<8)|0x000000FF;
00374     }
00375 };
00376 
00377 
00378 #define CASECONVERTER(type) case type::ID : PixelBoxConverter<type>::conversion(src, dst); return 1;
00379 
00380 inline int doOptimizedConversion(const PixelBox &src, const PixelBox &dst)
00381 {;
00382     switch(FMTCONVERTERID(src.format, dst.format))
00383     {
00384         // Register converters here
00385         CASECONVERTER(A8R8G8B8toA8B8G8R8);
00386         CASECONVERTER(A8R8G8B8toB8G8R8A8);
00387         CASECONVERTER(A8R8G8B8toR8G8B8A8);
00388         CASECONVERTER(A8B8G8R8toA8R8G8B8);
00389         CASECONVERTER(A8B8G8R8toB8G8R8A8);
00390         CASECONVERTER(A8B8G8R8toR8G8B8A8);
00391         CASECONVERTER(B8G8R8A8toA8R8G8B8);
00392         CASECONVERTER(B8G8R8A8toA8B8G8R8);
00393         CASECONVERTER(B8G8R8A8toR8G8B8A8);
00394         CASECONVERTER(R8G8B8A8toA8R8G8B8);
00395         CASECONVERTER(R8G8B8A8toA8B8G8R8);
00396         CASECONVERTER(R8G8B8A8toB8G8R8A8);
00397         CASECONVERTER(A8B8G8R8toL8);
00398         CASECONVERTER(L8toA8B8G8R8);
00399         CASECONVERTER(A8R8G8B8toL8);
00400         CASECONVERTER(L8toA8R8G8B8);
00401         CASECONVERTER(B8G8R8A8toL8);
00402         CASECONVERTER(L8toB8G8R8A8);
00403         CASECONVERTER(L8toL16);
00404         CASECONVERTER(L16toL8);
00405         CASECONVERTER(B8G8R8toR8G8B8);
00406         CASECONVERTER(R8G8B8toB8G8R8);
00407         CASECONVERTER(R8G8B8toA8R8G8B8);
00408         CASECONVERTER(B8G8R8toA8R8G8B8);
00409         CASECONVERTER(R8G8B8toA8B8G8R8);
00410         CASECONVERTER(B8G8R8toA8B8G8R8);
00411         CASECONVERTER(R8G8B8toB8G8R8A8);
00412         CASECONVERTER(B8G8R8toB8G8R8A8);
00413         CASECONVERTER(A8R8G8B8toR8G8B8);
00414         CASECONVERTER(A8R8G8B8toB8G8R8);
00415         CASECONVERTER(X8R8G8B8toA8R8G8B8);
00416         CASECONVERTER(X8R8G8B8toA8B8G8R8);
00417         CASECONVERTER(X8R8G8B8toB8G8R8A8);
00418         CASECONVERTER(X8R8G8B8toR8G8B8A8);
00419         CASECONVERTER(X8B8G8R8toA8R8G8B8);
00420         CASECONVERTER(X8B8G8R8toA8B8G8R8);
00421         CASECONVERTER(X8B8G8R8toB8G8R8A8);
00422         CASECONVERTER(X8B8G8R8toR8G8B8A8);
00423 
00424         default:
00425             return 0;
00426     }
00427 }
00428 #undef CASECONVERTER
00429 
00430 #endif // VC6 protection

Copyright © 2008 Torus Knot Software Ltd
Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sun Sep 27 22:02:24 2009