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-2012 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 
00051 template <class U> struct PixelBoxConverter 
00052 {
00053     static const int ID = U::ID;
00054     static void conversion(const Ogre::PixelBox &src, const Ogre::PixelBox &dst)
00055     {
00056         typename U::SrcType *srcptr = static_cast<typename U::SrcType*>(src.data)
00057             + (src.left + src.top * src.rowPitch + src.front * src.slicePitch);
00058         typename U::DstType *dstptr = static_cast<typename U::DstType*>(dst.data)
00059             + (dst.left + dst.top * dst.rowPitch + dst.front * dst.slicePitch);
00060         const size_t srcSliceSkip = src.getSliceSkip();
00061         const size_t dstSliceSkip = dst.getSliceSkip();
00062         const size_t k = src.right - src.left;
00063         for(size_t z=src.front; z<src.back; z++) 
00064         {
00065             for(size_t y=src.top; y<src.bottom; y++)
00066             {
00067                 for(size_t x=0; x<k; x++)
00068                 {
00069                     dstptr[x] = U::pixelConvert(srcptr[x]);
00070                 }
00071                 srcptr += src.rowPitch;
00072                 dstptr += dst.rowPitch;
00073             }
00074             srcptr += srcSliceSkip;
00075             dstptr += dstSliceSkip;
00076         }    
00077     }
00078 };
00079 
00080 template <typename T, typename U, int id> struct PixelConverter {
00081     static const int ID = id;
00082     typedef T SrcType;
00083     typedef U DstType;    
00084     
00085     //inline static DstType pixelConvert(const SrcType &inp);
00086 };
00087 
00088 
00090 struct Col3b {
00091     Col3b(unsigned int a, unsigned int b, unsigned int c): 
00092         x((Ogre::uint8)a), y((Ogre::uint8)b), z((Ogre::uint8)c) { }
00093     Ogre::uint8 x,y,z;
00094 };
00096 struct Col3f {
00097     Col3f(float inR, float inG, float inB):
00098         r(inR), g(inG), b(inB) { }
00099     float r,g,b;
00100 };
00102 struct Col4f {
00103     Col4f(float inR, float inG, float inB, float inA):
00104         r(inR), g(inG), b(inB), a(inA) { }
00105     float r,g,b,a;
00106 };
00107 
00108 struct A8R8G8B8toA8B8G8R8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(Ogre::PF_A8R8G8B8, Ogre::PF_A8B8G8R8)>
00109 {
00110     inline static DstType pixelConvert(SrcType inp)
00111     {
00112         return ((inp&0x000000FF)<<16)|(inp&0xFF00FF00)|((inp&0x00FF0000)>>16);
00113     }
00114 };
00115 
00116 struct A8R8G8B8toB8G8R8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(Ogre::PF_A8R8G8B8, Ogre::PF_B8G8R8A8)>
00117 {
00118     inline static DstType pixelConvert(SrcType inp)
00119     {
00120         return ((inp&0x000000FF)<<24)|((inp&0x0000FF00)<<8)|((inp&0x00FF0000)>>8)|((inp&0xFF000000)>>24);
00121     }
00122 };
00123 
00124 struct A8R8G8B8toR8G8B8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(Ogre::PF_A8R8G8B8, Ogre::PF_R8G8B8A8)>
00125 {
00126     inline static DstType pixelConvert(SrcType inp)
00127     {
00128         return ((inp&0x00FFFFFF)<<8)|((inp&0xFF000000)>>24);
00129     }
00130 };
00131 
00132 struct A8B8G8R8toA8R8G8B8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(Ogre::PF_A8B8G8R8, Ogre::PF_A8R8G8B8)>
00133 {
00134     inline static DstType pixelConvert(SrcType inp)
00135     {
00136         return ((inp&0x000000FF)<<16)|(inp&0xFF00FF00)|((inp&0x00FF0000)>>16);
00137     }
00138 };
00139 
00140 struct A8B8G8R8toB8G8R8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(Ogre::PF_A8B8G8R8, Ogre::PF_B8G8R8A8)>
00141 {
00142     inline static DstType pixelConvert(SrcType inp)
00143     {
00144         return ((inp&0x00FFFFFF)<<8)|((inp&0xFF000000)>>24);
00145     }
00146 };
00147 
00148 struct A8B8G8R8toR8G8B8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(Ogre::PF_A8B8G8R8, Ogre::PF_R8G8B8A8)>
00149 {
00150     inline static DstType pixelConvert(SrcType inp)
00151     {
00152         return ((inp&0x000000FF)<<24)|((inp&0x0000FF00)<<8)|((inp&0x00FF0000)>>8)|((inp&0xFF000000)>>24);
00153     }
00154 };
00155 
00156 struct B8G8R8A8toA8R8G8B8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(Ogre::PF_B8G8R8A8, Ogre::PF_A8R8G8B8)>
00157 {
00158     inline static DstType pixelConvert(SrcType inp)
00159     {
00160         return ((inp&0x000000FF)<<24)|((inp&0x0000FF00)<<8)|((inp&0x00FF0000)>>8)|((inp&0xFF000000)>>24);
00161     }
00162 };
00163 
00164 struct B8G8R8A8toA8B8G8R8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(Ogre::PF_B8G8R8A8, Ogre::PF_A8B8G8R8)>
00165 {
00166     inline static DstType pixelConvert(SrcType inp)
00167     {
00168         return ((inp&0x000000FF)<<24)|((inp&0xFFFFFF00)>>8);
00169     }
00170 };
00171 
00172 struct B8G8R8A8toR8G8B8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(Ogre::PF_B8G8R8A8, Ogre::PF_R8G8B8A8)>
00173 {
00174     inline static DstType pixelConvert(SrcType inp)
00175     {
00176         return ((inp&0x0000FF00)<<16)|(inp&0x00FF00FF)|((inp&0xFF000000)>>16);
00177     }
00178 };
00179 
00180 struct R8G8B8A8toA8R8G8B8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(Ogre::PF_R8G8B8A8, Ogre::PF_A8R8G8B8)>
00181 {
00182     inline static DstType pixelConvert(SrcType inp)
00183     {
00184         return ((inp&0x000000FF)<<24)|((inp&0xFFFFFF00)>>8);
00185     }
00186 };
00187 
00188 struct R8G8B8A8toA8B8G8R8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(Ogre::PF_R8G8B8A8, Ogre::PF_A8B8G8R8)>
00189 {
00190     inline static DstType pixelConvert(SrcType inp)
00191     {
00192         return ((inp&0x000000FF)<<24)|((inp&0x0000FF00)<<8)|((inp&0x00FF0000)>>8)|((inp&0xFF000000)>>24);
00193     }
00194 };
00195 
00196 struct R8G8B8A8toB8G8R8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(Ogre::PF_R8G8B8A8, Ogre::PF_B8G8R8A8)>
00197 {
00198     inline static DstType pixelConvert(SrcType inp)
00199     {
00200         return ((inp&0x0000FF00)<<16)|(inp&0x00FF00FF)|((inp&0xFF000000)>>16);
00201     }
00202 };
00203 
00204 struct A8B8G8R8toL8: public PixelConverter <Ogre::uint32, Ogre::uint8, FMTCONVERTERID(Ogre::PF_A8B8G8R8, Ogre::PF_L8)>
00205 {
00206     inline static DstType pixelConvert(SrcType inp)
00207     {
00208         return (Ogre::uint8)(inp&0x000000FF);
00209     }
00210 };
00211 
00212 struct L8toA8B8G8R8: public PixelConverter <Ogre::uint8, Ogre::uint32, FMTCONVERTERID(Ogre::PF_L8, Ogre::PF_A8B8G8R8)>
00213 {
00214     inline static DstType pixelConvert(SrcType inp)
00215     {
00216         return 0xFF000000|(((unsigned int)inp)<<0)|(((unsigned int)inp)<<8)|(((unsigned int)inp)<<16);
00217     }
00218 };
00219 
00220 struct A8R8G8B8toL8: public PixelConverter <Ogre::uint32, Ogre::uint8, FMTCONVERTERID(Ogre::PF_A8R8G8B8, Ogre::PF_L8)>
00221 {
00222     inline static DstType pixelConvert(SrcType inp)
00223     {
00224         return (Ogre::uint8)((inp&0x00FF0000)>>16);
00225     }
00226 };
00227 
00228 struct L8toA8R8G8B8: public PixelConverter <Ogre::uint8, Ogre::uint32, FMTCONVERTERID(Ogre::PF_L8, Ogre::PF_A8R8G8B8)>
00229 {
00230     inline static DstType pixelConvert(SrcType inp)
00231     {
00232         return 0xFF000000|(((unsigned int)inp)<<0)|(((unsigned int)inp)<<8)|(((unsigned int)inp)<<16);
00233     }
00234 };
00235 
00236 struct B8G8R8A8toL8: public PixelConverter <Ogre::uint32, Ogre::uint8, FMTCONVERTERID(Ogre::PF_B8G8R8A8, Ogre::PF_L8)>
00237 {
00238     inline static DstType pixelConvert(SrcType inp)
00239     {
00240         return (Ogre::uint8)((inp&0x0000FF00)>>8);
00241     }
00242 };
00243 
00244 struct L8toB8G8R8A8: public PixelConverter <Ogre::uint8, Ogre::uint32, FMTCONVERTERID(Ogre::PF_L8, Ogre::PF_B8G8R8A8)>
00245 {
00246     inline static DstType pixelConvert(SrcType inp)
00247     {
00248         return 0x000000FF|(((unsigned int)inp)<<8)|(((unsigned int)inp)<<16)|(((unsigned int)inp)<<24);
00249     }
00250 };
00251 
00252 struct L8toL16: public PixelConverter <Ogre::uint8, Ogre::uint16, FMTCONVERTERID(Ogre::PF_L8, Ogre::PF_L16)>
00253 {
00254     inline static DstType pixelConvert(SrcType inp)
00255     {
00256         return (Ogre::uint16)((((unsigned int)inp)<<8)|(((unsigned int)inp)));
00257     }
00258 };
00259 
00260 struct L16toL8: public PixelConverter <Ogre::uint16, Ogre::uint8, FMTCONVERTERID(Ogre::PF_L16, Ogre::PF_L8)>
00261 {
00262     inline static DstType pixelConvert(SrcType inp)
00263     {
00264         return (Ogre::uint8)(inp>>8);
00265     }
00266 };
00267 
00268 struct R8G8B8toB8G8R8: public PixelConverter <Col3b, Col3b, FMTCONVERTERID(Ogre::PF_R8G8B8, Ogre::PF_B8G8R8)>
00269 {
00270     inline static DstType pixelConvert(const SrcType &inp)
00271     {
00272         return Col3b(inp.z, inp.y, inp.x);
00273     }  
00274 };
00275 
00276 struct B8G8R8toR8G8B8: public PixelConverter <Col3b, Col3b, FMTCONVERTERID(Ogre::PF_B8G8R8, Ogre::PF_R8G8B8)>
00277 {
00278     inline static DstType pixelConvert(const SrcType &inp)
00279     {
00280         return Col3b(inp.z, inp.y, inp.x);
00281     }  
00282 };
00283 
00284 // X8Y8Z8 ->  X8<<xshift Y8<<yshift Z8<<zshift A8<<ashift
00285 template <int id, unsigned int xshift, unsigned int yshift, unsigned int zshift, unsigned int ashift> struct Col3btoUint32swizzler:
00286     public PixelConverter <Col3b, Ogre::uint32, id>
00287 {
00288     inline static Ogre::uint32 pixelConvert(const Col3b &inp)
00289     {
00290 #if OGRE_ENDIAN == OGRE_ENDIAN_BIG
00291         return (0xFF<<ashift) | (((unsigned int)inp.x)<<xshift) | (((unsigned int)inp.y)<<yshift) | (((unsigned int)inp.z)<<zshift);
00292 #else
00293         return (0xFF<<ashift) | (((unsigned int)inp.x)<<zshift) | (((unsigned int)inp.y)<<yshift) | (((unsigned int)inp.z)<<xshift);
00294 #endif
00295     }
00296 };
00297 
00298 struct R8G8B8toA8R8G8B8: public Col3btoUint32swizzler<FMTCONVERTERID(Ogre::PF_R8G8B8, Ogre::PF_A8R8G8B8), 16, 8, 0, 24> { };
00299 struct B8G8R8toA8R8G8B8: public Col3btoUint32swizzler<FMTCONVERTERID(Ogre::PF_B8G8R8, Ogre::PF_A8R8G8B8), 0, 8, 16, 24> { };
00300 struct R8G8B8toA8B8G8R8: public Col3btoUint32swizzler<FMTCONVERTERID(Ogre::PF_R8G8B8, Ogre::PF_A8B8G8R8), 0, 8, 16, 24> { };
00301 struct B8G8R8toA8B8G8R8: public Col3btoUint32swizzler<FMTCONVERTERID(Ogre::PF_B8G8R8, Ogre::PF_A8B8G8R8), 16, 8, 0, 24> { };
00302 struct R8G8B8toB8G8R8A8: public Col3btoUint32swizzler<FMTCONVERTERID(Ogre::PF_R8G8B8, Ogre::PF_B8G8R8A8), 8, 16, 24, 0> { };
00303 struct B8G8R8toB8G8R8A8: public Col3btoUint32swizzler<FMTCONVERTERID(Ogre::PF_B8G8R8, Ogre::PF_B8G8R8A8), 24, 16, 8, 0> { };
00304 
00305 struct A8R8G8B8toR8G8B8: public PixelConverter <Ogre::uint32, Col3b, FMTCONVERTERID(Ogre::PF_A8R8G8B8, Ogre::PF_BYTE_RGB)>
00306 {
00307     inline static DstType pixelConvert(Ogre::uint32 inp)
00308     {
00309         return Col3b((Ogre::uint8)((inp>>16)&0xFF), (Ogre::uint8)((inp>>8)&0xFF), (Ogre::uint8)((inp>>0)&0xFF));
00310     }
00311 };
00312 struct A8R8G8B8toB8G8R8: public PixelConverter <Ogre::uint32, Col3b, FMTCONVERTERID(Ogre::PF_A8R8G8B8, Ogre::PF_BYTE_BGR)>
00313 {
00314     inline static DstType pixelConvert(Ogre::uint32 inp)
00315     {
00316         return Col3b((Ogre::uint8)((inp>>0)&0xFF), (Ogre::uint8)((inp>>8)&0xFF), (Ogre::uint8)((inp>>16)&0xFF));
00317     }
00318 };
00319 
00320 // Only conversions from X8R8G8B8 to formats with alpha need to be defined, the rest is implicitly the same
00321 // as A8R8G8B8
00322 struct X8R8G8B8toA8R8G8B8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(Ogre::PF_X8R8G8B8, Ogre::PF_A8R8G8B8)>
00323 {
00324     inline static DstType pixelConvert(SrcType inp)
00325     {
00326         return inp | 0xFF000000;
00327     }
00328 };
00329 struct X8R8G8B8toA8B8G8R8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(Ogre::PF_X8R8G8B8, Ogre::PF_A8B8G8R8)>
00330 {
00331     inline static DstType pixelConvert(SrcType inp)
00332     {
00333         return ((inp&0x0000FF)<<16)|((inp&0xFF0000)>>16)|(inp&0x00FF00)|0xFF000000;
00334     }
00335 };
00336 struct X8R8G8B8toB8G8R8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(Ogre::PF_X8R8G8B8, Ogre::PF_B8G8R8A8)>
00337 {
00338     inline static DstType pixelConvert(SrcType inp)
00339     {
00340         return ((inp&0x0000FF)<<24)|((inp&0xFF0000)>>8)|((inp&0x00FF00)<<8)|0x000000FF;
00341     }
00342 };
00343 struct X8R8G8B8toR8G8B8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(Ogre::PF_X8R8G8B8, Ogre::PF_R8G8B8A8)>
00344 {
00345     inline static DstType pixelConvert(SrcType inp)
00346     {
00347         return ((inp&0xFFFFFF)<<8)|0x000000FF;
00348     }
00349 };
00350 
00351 // X8B8G8R8
00352 struct X8B8G8R8toA8R8G8B8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(Ogre::PF_X8B8G8R8, Ogre::PF_A8R8G8B8)>
00353 {
00354     inline static DstType pixelConvert(SrcType inp)
00355     {
00356         return ((inp&0x0000FF)<<16)|((inp&0xFF0000)>>16)|(inp&0x00FF00)|0xFF000000;
00357     }
00358 };
00359 struct X8B8G8R8toA8B8G8R8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(Ogre::PF_X8B8G8R8, Ogre::PF_A8B8G8R8)>
00360 {
00361     inline static DstType pixelConvert(SrcType inp)
00362     {
00363         return inp | 0xFF000000;
00364     }
00365 };
00366 struct X8B8G8R8toB8G8R8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(Ogre::PF_X8B8G8R8, Ogre::PF_B8G8R8A8)>
00367 {
00368     inline static DstType pixelConvert(SrcType inp)
00369     {
00370         return ((inp&0xFFFFFF)<<8)|0x000000FF;
00371     }
00372 };
00373 struct X8B8G8R8toR8G8B8A8: public PixelConverter <Ogre::uint32, Ogre::uint32, FMTCONVERTERID(Ogre::PF_X8B8G8R8, Ogre::PF_R8G8B8A8)>
00374 {
00375     inline static DstType pixelConvert(SrcType inp)
00376     {
00377         return ((inp&0x0000FF)<<24)|((inp&0xFF0000)>>8)|((inp&0x00FF00)<<8)|0x000000FF;
00378     }
00379 };
00380 
00381 
00382 #define CASECONVERTER(type) case type::ID : PixelBoxConverter<type>::conversion(src, dst); return 1;
00383 
00384 inline int doOptimizedConversion(const Ogre::PixelBox &src, const Ogre::PixelBox &dst)
00385 {;
00386     switch(FMTCONVERTERID(src.format, dst.format))
00387     {
00388         // Register converters here
00389         CASECONVERTER(A8R8G8B8toA8B8G8R8);
00390         CASECONVERTER(A8R8G8B8toB8G8R8A8);
00391         CASECONVERTER(A8R8G8B8toR8G8B8A8);
00392         CASECONVERTER(A8B8G8R8toA8R8G8B8);
00393         CASECONVERTER(A8B8G8R8toB8G8R8A8);
00394         CASECONVERTER(A8B8G8R8toR8G8B8A8);
00395         CASECONVERTER(B8G8R8A8toA8R8G8B8);
00396         CASECONVERTER(B8G8R8A8toA8B8G8R8);
00397         CASECONVERTER(B8G8R8A8toR8G8B8A8);
00398         CASECONVERTER(R8G8B8A8toA8R8G8B8);
00399         CASECONVERTER(R8G8B8A8toA8B8G8R8);
00400         CASECONVERTER(R8G8B8A8toB8G8R8A8);
00401         CASECONVERTER(A8B8G8R8toL8);
00402         CASECONVERTER(L8toA8B8G8R8);
00403         CASECONVERTER(A8R8G8B8toL8);
00404         CASECONVERTER(L8toA8R8G8B8);
00405         CASECONVERTER(B8G8R8A8toL8);
00406         CASECONVERTER(L8toB8G8R8A8);
00407         CASECONVERTER(L8toL16);
00408         CASECONVERTER(L16toL8);
00409         CASECONVERTER(B8G8R8toR8G8B8);
00410         CASECONVERTER(R8G8B8toB8G8R8);
00411         CASECONVERTER(R8G8B8toA8R8G8B8);
00412         CASECONVERTER(B8G8R8toA8R8G8B8);
00413         CASECONVERTER(R8G8B8toA8B8G8R8);
00414         CASECONVERTER(B8G8R8toA8B8G8R8);
00415         CASECONVERTER(R8G8B8toB8G8R8A8);
00416         CASECONVERTER(B8G8R8toB8G8R8A8);
00417         CASECONVERTER(A8R8G8B8toR8G8B8);
00418         CASECONVERTER(A8R8G8B8toB8G8R8);
00419         CASECONVERTER(X8R8G8B8toA8R8G8B8);
00420         CASECONVERTER(X8R8G8B8toA8B8G8R8);
00421         CASECONVERTER(X8R8G8B8toB8G8R8A8);
00422         CASECONVERTER(X8R8G8B8toR8G8B8A8);
00423         CASECONVERTER(X8B8G8R8toA8R8G8B8);
00424         CASECONVERTER(X8B8G8R8toA8B8G8R8);
00425         CASECONVERTER(X8B8G8R8toB8G8R8A8);
00426         CASECONVERTER(X8B8G8R8toR8G8B8A8);
00427 
00428         default:
00429             return 0;
00430     }
00431 }
00432 #undef CASECONVERTER
00433 
00436 #endif // VC6 protection

Copyright © 2012 Torus Knot Software Ltd
Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Last modified Fri May 25 23:36:25 2012