# 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
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sat Apr 11 14:26:44 2009