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-2009 Torus Knot Software Ltd
00008 
00009 Permission is hereby granted, free of charge, to any person obtaining a copy
00010 of this software and associated documentation files (the "Software"), to deal
00011 in the Software without restriction, including without limitation the rights
00012 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00013 copies of the Software, and to permit persons to whom the Software is
00014 furnished to do so, subject to the following conditions:
00015 
00016 The above copyright notice and this permission notice shall be included in
00017 all copies or substantial portions of the Software.
00018 
00019 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00020 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00021 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00022 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00023 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00024 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00025 THE SOFTWARE.
00026 -----------------------------------------------------------------------------
00027 */
00029 using namespace Ogre;
00030 
00031 // NB VC6 can't handle these templates
00032 #if OGRE_COMPILER != OGRE_COMPILER_MSVC || OGRE_COMP_VER >= 1300
00033 
00034 #define FMTCONVERTERID(from,to) (((from)<<8)|(to))
00035 
00052 template <class U> struct PixelBoxConverter 
00053 {
00054     static const int ID = U::ID;
00055     static void conversion(const PixelBox &src, const PixelBox &dst)
00056     {
00057         typename U::SrcType *srcptr = static_cast<typename U::SrcType*>(src.data)
00058             + (src.left + src.top * src.rowPitch + src.front * src.slicePitch);
00059         typename U::DstType *dstptr = static_cast<typename U::DstType*>(dst.data)
00060             + (dst.left + dst.top * dst.rowPitch + dst.front * dst.slicePitch);
00061         const size_t srcSliceSkip = src.getSliceSkip();
00062         const size_t dstSliceSkip = dst.getSliceSkip();
00063         const size_t k = src.right - src.left;
00064         for(size_t z=src.front; z<src.back; z++) 
00065         {
00066             for(size_t y=src.top; y<src.bottom; y++)
00067             {
00068                 for(size_t x=0; x<k; x++)
00069                 {
00070                     dstptr[x] = U::pixelConvert(srcptr[x]);
00071                 }
00072                 srcptr += src.rowPitch;
00073                 dstptr += dst.rowPitch;
00074             }
00075             srcptr += srcSliceSkip;
00076             dstptr += dstSliceSkip;
00077         }    
00078     }
00079 };
00080 
00081 template <typename T, typename U, int id> struct PixelConverter {
00082     static const int ID = id;
00083     typedef T SrcType;
00084     typedef U DstType;    
00085     
00086     //inline static DstType pixelConvert(const SrcType &inp);
00087 };
00088 
00089 
00091 struct Col3b {
00092     Col3b(unsigned int a, unsigned int b, unsigned int c): 
00093         x((Ogre::uint8)a), y((Ogre::uint8)b), z((Ogre::uint8)c) { }
00094     Ogre::uint8 x,y,z;
00095 };
00097 struct Col3f {
00098     Col3f(float inR, float inG, float inB):
00099         r(inR), g(inG), b(inB) { }
00100     float r,g,b;
00101 };
00103 struct Col4f {
00104     Col4f(float inR, float inG, float inB, float inA):
00105         r(inR), g(inG), b(inB), a(inA) { }
00106     float r,g,b,a;
00107 };
00108 
00109 struct A8R8G8B8toA8B8G8R8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_A8R8G8B8, PF_A8B8G8R8)>
00110 {
00111     inline static DstType pixelConvert(SrcType inp)
00112     {
00113         return ((inp&0x000000FF)<<16)|(inp&0xFF00FF00)|((inp&0x00FF0000)>>16);
00114     }
00115 };
00116 
00117 struct A8R8G8B8toB8G8R8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_A8R8G8B8, PF_B8G8R8A8)>
00118 {
00119     inline static DstType pixelConvert(SrcType inp)
00120     {
00121         return ((inp&0x000000FF)<<24)|((inp&0x0000FF00)<<8)|((inp&0x00FF0000)>>8)|((inp&0xFF000000)>>24);
00122     }
00123 };
00124 
00125 struct A8R8G8B8toR8G8B8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_A8R8G8B8, PF_R8G8B8A8)>
00126 {
00127     inline static DstType pixelConvert(SrcType inp)
00128     {
00129         return ((inp&0x00FFFFFF)<<8)|((inp&0xFF000000)>>24);
00130     }
00131 };
00132 
00133 struct A8B8G8R8toA8R8G8B8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_A8B8G8R8, PF_A8R8G8B8)>
00134 {
00135     inline static DstType pixelConvert(SrcType inp)
00136     {
00137         return ((inp&0x000000FF)<<16)|(inp&0xFF00FF00)|((inp&0x00FF0000)>>16);
00138     }
00139 };
00140 
00141 struct A8B8G8R8toB8G8R8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_A8B8G8R8, PF_B8G8R8A8)>
00142 {
00143     inline static DstType pixelConvert(SrcType inp)
00144     {
00145         return ((inp&0x00FFFFFF)<<8)|((inp&0xFF000000)>>24);
00146     }
00147 };
00148 
00149 struct A8B8G8R8toR8G8B8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_A8B8G8R8, PF_R8G8B8A8)>
00150 {
00151     inline static DstType pixelConvert(SrcType inp)
00152     {
00153         return ((inp&0x000000FF)<<24)|((inp&0x0000FF00)<<8)|((inp&0x00FF0000)>>8)|((inp&0xFF000000)>>24);
00154     }
00155 };
00156 
00157 struct B8G8R8A8toA8R8G8B8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_B8G8R8A8, PF_A8R8G8B8)>
00158 {
00159     inline static DstType pixelConvert(SrcType inp)
00160     {
00161         return ((inp&0x000000FF)<<24)|((inp&0x0000FF00)<<8)|((inp&0x00FF0000)>>8)|((inp&0xFF000000)>>24);
00162     }
00163 };
00164 
00165 struct B8G8R8A8toA8B8G8R8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_B8G8R8A8, PF_A8B8G8R8)>
00166 {
00167     inline static DstType pixelConvert(SrcType inp)
00168     {
00169         return ((inp&0x000000FF)<<24)|((inp&0xFFFFFF00)>>8);
00170     }
00171 };
00172 
00173 struct B8G8R8A8toR8G8B8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_B8G8R8A8, PF_R8G8B8A8)>
00174 {
00175     inline static DstType pixelConvert(SrcType inp)
00176     {
00177         return ((inp&0x0000FF00)<<16)|(inp&0x00FF00FF)|((inp&0xFF000000)>>16);
00178     }
00179 };
00180 
00181 struct R8G8B8A8toA8R8G8B8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_R8G8B8A8, PF_A8R8G8B8)>
00182 {
00183     inline static DstType pixelConvert(SrcType inp)
00184     {
00185         return ((inp&0x000000FF)<<24)|((inp&0xFFFFFF00)>>8);
00186     }
00187 };
00188 
00189 struct R8G8B8A8toA8B8G8R8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_R8G8B8A8, PF_A8B8G8R8)>
00190 {
00191     inline static DstType pixelConvert(SrcType inp)
00192     {
00193         return ((inp&0x000000FF)<<24)|((inp&0x0000FF00)<<8)|((inp&0x00FF0000)>>8)|((inp&0xFF000000)>>24);
00194     }
00195 };
00196 
00197 struct R8G8B8A8toB8G8R8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_R8G8B8A8, PF_B8G8R8A8)>
00198 {
00199     inline static DstType pixelConvert(SrcType inp)
00200     {
00201         return ((inp&0x0000FF00)<<16)|(inp&0x00FF00FF)|((inp&0xFF000000)>>16);
00202     }
00203 };
00204 
00205 struct A8B8G8R8toL8: public PixelConverter <Ogre::uint32, Ogre::uint8, FMTCONVERTERID(PF_A8B8G8R8, PF_L8)>
00206 {
00207     inline static DstType pixelConvert(SrcType inp)
00208     {
00209         return (Ogre::uint8)(inp&0x000000FF);
00210     }
00211 };
00212 
00213 struct L8toA8B8G8R8: public PixelConverter <Ogre::uint8, Ogre::uint32, FMTCONVERTERID(PF_L8, PF_A8B8G8R8)>
00214 {
00215     inline static DstType pixelConvert(SrcType inp)
00216     {
00217         return 0xFF000000|(((unsigned int)inp)<<0)|(((unsigned int)inp)<<8)|(((unsigned int)inp)<<16);
00218     }
00219 };
00220 
00221 struct A8R8G8B8toL8: public PixelConverter <Ogre::uint32, Ogre::uint8, FMTCONVERTERID(PF_A8R8G8B8, PF_L8)>
00222 {
00223     inline static DstType pixelConvert(SrcType inp)
00224     {
00225         return (Ogre::uint8)((inp&0x00FF0000)>>16);
00226     }
00227 };
00228 
00229 struct L8toA8R8G8B8: public PixelConverter <Ogre::uint8, Ogre::uint32, FMTCONVERTERID(PF_L8, PF_A8R8G8B8)>
00230 {
00231     inline static DstType pixelConvert(SrcType inp)
00232     {
00233         return 0xFF000000|(((unsigned int)inp)<<0)|(((unsigned int)inp)<<8)|(((unsigned int)inp)<<16);
00234     }
00235 };
00236 
00237 struct B8G8R8A8toL8: public PixelConverter <Ogre::uint32, Ogre::uint8, FMTCONVERTERID(PF_B8G8R8A8, PF_L8)>
00238 {
00239     inline static DstType pixelConvert(SrcType inp)
00240     {
00241         return (Ogre::uint8)((inp&0x0000FF00)>>8);
00242     }
00243 };
00244 
00245 struct L8toB8G8R8A8: public PixelConverter <Ogre::uint8, Ogre::uint32, FMTCONVERTERID(PF_L8, PF_B8G8R8A8)>
00246 {
00247     inline static DstType pixelConvert(SrcType inp)
00248     {
00249         return 0x000000FF|(((unsigned int)inp)<<8)|(((unsigned int)inp)<<16)|(((unsigned int)inp)<<24);
00250     }
00251 };
00252 
00253 struct L8toL16: public PixelConverter <Ogre::uint8, Ogre::uint16, FMTCONVERTERID(PF_L8, PF_L16)>
00254 {
00255     inline static DstType pixelConvert(SrcType inp)
00256     {
00257         return (Ogre::uint16)((((unsigned int)inp)<<8)|(((unsigned int)inp)));
00258     }
00259 };
00260 
00261 struct L16toL8: public PixelConverter <Ogre::uint16, Ogre::uint8, FMTCONVERTERID(PF_L16, PF_L8)>
00262 {
00263     inline static DstType pixelConvert(SrcType inp)
00264     {
00265         return (Ogre::uint8)(inp>>8);
00266     }
00267 };
00268 
00269 struct R8G8B8toB8G8R8: public PixelConverter <Col3b, Col3b, FMTCONVERTERID(PF_R8G8B8, PF_B8G8R8)>
00270 {
00271     inline static DstType pixelConvert(const SrcType &inp)
00272     {
00273         return Col3b(inp.z, inp.y, inp.x);
00274     }  
00275 };
00276 
00277 struct B8G8R8toR8G8B8: public PixelConverter <Col3b, Col3b, FMTCONVERTERID(PF_B8G8R8, PF_R8G8B8)>
00278 {
00279     inline static DstType pixelConvert(const SrcType &inp)
00280     {
00281         return Col3b(inp.z, inp.y, inp.x);
00282     }  
00283 };
00284 
00285 // X8Y8Z8 ->  X8<<xshift Y8<<yshift Z8<<zshift A8<<ashift
00286 template <int id, unsigned int xshift, unsigned int yshift, unsigned int zshift, unsigned int ashift> struct Col3btoUint32swizzler:
00287     public PixelConverter <Col3b, Ogre::uint32, id>
00288 {
00289     inline static Ogre::uint32 pixelConvert(const Col3b &inp)
00290     {
00291 #if OGRE_ENDIAN == OGRE_ENDIAN_BIG
00292         return (0xFF<<ashift) | (((unsigned int)inp.x)<<xshift) | (((unsigned int)inp.y)<<yshift) | (((unsigned int)inp.z)<<zshift);
00293 #else
00294         return (0xFF<<ashift) | (((unsigned int)inp.x)<<zshift) | (((unsigned int)inp.y)<<yshift) | (((unsigned int)inp.z)<<xshift);
00295 #endif
00296     }
00297 };
00298 
00299 struct R8G8B8toA8R8G8B8: public Col3btoUint32swizzler<FMTCONVERTERID(PF_R8G8B8, PF_A8R8G8B8), 16, 8, 0, 24> { };
00300 struct B8G8R8toA8R8G8B8: public Col3btoUint32swizzler<FMTCONVERTERID(PF_B8G8R8, PF_A8R8G8B8), 0, 8, 16, 24> { };
00301 struct R8G8B8toA8B8G8R8: public Col3btoUint32swizzler<FMTCONVERTERID(PF_R8G8B8, PF_A8B8G8R8), 0, 8, 16, 24> { };
00302 struct B8G8R8toA8B8G8R8: public Col3btoUint32swizzler<FMTCONVERTERID(PF_B8G8R8, PF_A8B8G8R8), 16, 8, 0, 24> { };
00303 struct R8G8B8toB8G8R8A8: public Col3btoUint32swizzler<FMTCONVERTERID(PF_R8G8B8, PF_B8G8R8A8), 8, 16, 24, 0> { };
00304 struct B8G8R8toB8G8R8A8: public Col3btoUint32swizzler<FMTCONVERTERID(PF_B8G8R8, PF_B8G8R8A8), 24, 16, 8, 0> { };
00305 
00306 struct A8R8G8B8toR8G8B8: public PixelConverter <Ogre::uint32, Col3b, FMTCONVERTERID(PF_A8R8G8B8, PF_BYTE_RGB)>
00307 {
00308     inline static DstType pixelConvert(Ogre::uint32 inp)
00309     {
00310         return Col3b((Ogre::uint8)((inp>>16)&0xFF), (Ogre::uint8)((inp>>8)&0xFF), (Ogre::uint8)((inp>>0)&0xFF));
00311     }
00312 };
00313 struct A8R8G8B8toB8G8R8: public PixelConverter <Ogre::uint32, Col3b, FMTCONVERTERID(PF_A8R8G8B8, PF_BYTE_BGR)>
00314 {
00315     inline static DstType pixelConvert(Ogre::uint32 inp)
00316     {
00317         return Col3b((Ogre::uint8)((inp>>0)&0xFF), (Ogre::uint8)((inp>>8)&0xFF), (Ogre::uint8)((inp>>16)&0xFF));
00318     }
00319 };
00320 
00321 // Only conversions from X8R8G8B8 to formats with alpha need to be defined, the rest is implicitly the same
00322 // as A8R8G8B8
00323 struct X8R8G8B8toA8R8G8B8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_X8R8G8B8, PF_A8R8G8B8)>
00324 {
00325     inline static DstType pixelConvert(SrcType inp)
00326     {
00327         return inp | 0xFF000000;
00328     }
00329 };
00330 struct X8R8G8B8toA8B8G8R8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_X8R8G8B8, PF_A8B8G8R8)>
00331 {
00332     inline static DstType pixelConvert(SrcType inp)
00333     {
00334         return ((inp&0x0000FF)<<16)|((inp&0xFF0000)>>16)|(inp&0x00FF00)|0xFF000000;
00335     }
00336 };
00337 struct X8R8G8B8toB8G8R8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_X8R8G8B8, PF_B8G8R8A8)>
00338 {
00339     inline static DstType pixelConvert(SrcType inp)
00340     {
00341         return ((inp&0x0000FF)<<24)|((inp&0xFF0000)>>8)|((inp&0x00FF00)<<8)|0x000000FF;
00342     }
00343 };
00344 struct X8R8G8B8toR8G8B8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_X8R8G8B8, PF_R8G8B8A8)>
00345 {
00346     inline static DstType pixelConvert(SrcType inp)
00347     {
00348         return ((inp&0xFFFFFF)<<8)|0x000000FF;
00349     }
00350 };
00351 
00352 // X8B8G8R8
00353 struct X8B8G8R8toA8R8G8B8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_X8B8G8R8, PF_A8R8G8B8)>
00354 {
00355     inline static DstType pixelConvert(SrcType inp)
00356     {
00357         return ((inp&0x0000FF)<<16)|((inp&0xFF0000)>>16)|(inp&0x00FF00)|0xFF000000;
00358     }
00359 };
00360 struct X8B8G8R8toA8B8G8R8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_X8B8G8R8, PF_A8B8G8R8)>
00361 {
00362     inline static DstType pixelConvert(SrcType inp)
00363     {
00364         return inp | 0xFF000000;
00365     }
00366 };
00367 struct X8B8G8R8toB8G8R8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_X8B8G8R8, PF_B8G8R8A8)>
00368 {
00369     inline static DstType pixelConvert(SrcType inp)
00370     {
00371         return ((inp&0xFFFFFF)<<8)|0x000000FF;
00372     }
00373 };
00374 struct X8B8G8R8toR8G8B8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(PF_X8B8G8R8, PF_R8G8B8A8)>
00375 {
00376     inline static DstType pixelConvert(SrcType inp)
00377     {
00378         return ((inp&0x0000FF)<<24)|((inp&0xFF0000)>>8)|((inp&0x00FF00)<<8)|0x000000FF;
00379     }
00380 };
00381 
00382 
00383 #define CASECONVERTER(type) case type::ID : PixelBoxConverter<type>::conversion(src, dst); return 1;
00384 
00385 inline int doOptimizedConversion(const PixelBox &src, const PixelBox &dst)
00386 {;
00387     switch(FMTCONVERTERID(src.format, dst.format))
00388     {
00389         // Register converters here
00390         CASECONVERTER(A8R8G8B8toA8B8G8R8);
00391         CASECONVERTER(A8R8G8B8toB8G8R8A8);
00392         CASECONVERTER(A8R8G8B8toR8G8B8A8);
00393         CASECONVERTER(A8B8G8R8toA8R8G8B8);
00394         CASECONVERTER(A8B8G8R8toB8G8R8A8);
00395         CASECONVERTER(A8B8G8R8toR8G8B8A8);
00396         CASECONVERTER(B8G8R8A8toA8R8G8B8);
00397         CASECONVERTER(B8G8R8A8toA8B8G8R8);
00398         CASECONVERTER(B8G8R8A8toR8G8B8A8);
00399         CASECONVERTER(R8G8B8A8toA8R8G8B8);
00400         CASECONVERTER(R8G8B8A8toA8B8G8R8);
00401         CASECONVERTER(R8G8B8A8toB8G8R8A8);
00402         CASECONVERTER(A8B8G8R8toL8);
00403         CASECONVERTER(L8toA8B8G8R8);
00404         CASECONVERTER(A8R8G8B8toL8);
00405         CASECONVERTER(L8toA8R8G8B8);
00406         CASECONVERTER(B8G8R8A8toL8);
00407         CASECONVERTER(L8toB8G8R8A8);
00408         CASECONVERTER(L8toL16);
00409         CASECONVERTER(L16toL8);
00410         CASECONVERTER(B8G8R8toR8G8B8);
00411         CASECONVERTER(R8G8B8toB8G8R8);
00412         CASECONVERTER(R8G8B8toA8R8G8B8);
00413         CASECONVERTER(B8G8R8toA8R8G8B8);
00414         CASECONVERTER(R8G8B8toA8B8G8R8);
00415         CASECONVERTER(B8G8R8toA8B8G8R8);
00416         CASECONVERTER(R8G8B8toB8G8R8A8);
00417         CASECONVERTER(B8G8R8toB8G8R8A8);
00418         CASECONVERTER(A8R8G8B8toR8G8B8);
00419         CASECONVERTER(A8R8G8B8toB8G8R8);
00420         CASECONVERTER(X8R8G8B8toA8R8G8B8);
00421         CASECONVERTER(X8R8G8B8toA8B8G8R8);
00422         CASECONVERTER(X8R8G8B8toB8G8R8A8);
00423         CASECONVERTER(X8R8G8B8toR8G8B8A8);
00424         CASECONVERTER(X8B8G8R8toA8R8G8B8);
00425         CASECONVERTER(X8B8G8R8toA8B8G8R8);
00426         CASECONVERTER(X8B8G8R8toB8G8R8A8);
00427         CASECONVERTER(X8B8G8R8toR8G8B8A8);
00428 
00429         default:
00430             return 0;
00431     }
00432 }
00433 #undef CASECONVERTER
00434 
00437 #endif // VC6 protection

Copyright © 2008 Torus Knot Software Ltd
Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Last modified Wed Nov 3 2010 19:24:52