# 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
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Last modified Wed Nov 3 2010 19:24:52