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-2011 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 Sat Jan 14 2012 18:40:43