source: OGRE/trunk/ogrenew/OgreMain/src/OgrePixelConversions.h @ 692

Revision 692, 14.6 KB checked in by mattausch, 18 years ago (diff)

adding ogre 1.2 and dependencies

Line 
1 /*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23-----------------------------------------------------------------------------
24*/
25/** Internal include file -- do not use externally */
26using namespace Ogre;
27
28// NB VC6 can't handle these templates
29#if OGRE_COMPILER != OGRE_COMPILER_MSVC || OGRE_COMP_VER >= 1300
30
31#define FMTCONVERTERID(from,to) (((from)<<8)|(to))
32
33/**
34 * Convert a box of pixel from one type to another. Who needs automatic code
35 * generation when we have C++ templates and the policy design pattern.
36 *
37 * @param   U       Policy class to facilitate pixel-to-pixel conversion. This class
38 *    has at least two typedefs: SrcType and DstType. SrcType is the source element type,
39 *    dstType is the destination element type. It also has a static method, pixelConvert, that
40 *    converts a srcType into a dstType.
41 */
42
43template <class U> struct PixelBoxConverter
44{
45    static const int ID = U::ID;
46    static void conversion(const PixelBox &src, const PixelBox &dst)
47    {
48        typename U::SrcType *srcptr = static_cast<typename U::SrcType*>(src.data);
49        typename U::DstType *dstptr = static_cast<typename U::DstType*>(dst.data);
50        const size_t srcSliceSkip = src.getSliceSkip();
51        const size_t dstSliceSkip = dst.getSliceSkip();
52        const size_t k = src.right - src.left;
53        for(size_t z=src.front; z<src.back; z++)
54        {
55            for(size_t y=src.top; y<src.bottom; y++)
56            {
57                for(size_t x=0; x<k; x++)
58                {
59                    dstptr[x] = U::pixelConvert(srcptr[x]);
60                }
61                srcptr += src.rowPitch;
62                dstptr += dst.rowPitch;
63            }
64            srcptr += srcSliceSkip;
65            dstptr += dstSliceSkip;
66        }   
67    }
68};
69
70template <typename T, typename U, int id> struct PixelConverter {
71    static const int ID = id;
72    typedef T SrcType;
73    typedef U DstType;   
74   
75    //inline static DstType pixelConvert(const SrcType &inp);
76};
77
78
79/** Type for PF_R8G8B8/PF_B8G8R8 */
80struct Col3b {
81    Col3b(unsigned int a, unsigned int b, unsigned int c):
82        x((uint8)a), y((uint8)b), z((uint8)c) { }
83    uint8 x,y,z;
84};
85/** Type for PF_FLOAT32_RGB */
86struct Col3f {
87        Col3f(float r, float g, float b):
88                r(r), g(g), b(b) { }
89        float r,g,b;
90};
91/** Type for PF_FLOAT32_RGBA */
92struct Col4f {
93        Col4f(float r, float g, float b, float a):
94                r(r), g(g), b(b), a(a) { }
95        float r,g,b,a;
96};
97
98struct A8R8G8B8toA8B8G8R8: public PixelConverter <uint32, uint32, FMTCONVERTERID(PF_A8R8G8B8, PF_A8B8G8R8)>
99{
100    inline static DstType pixelConvert(SrcType inp)
101    {
102        return ((inp&0x000000FF)<<16)|(inp&0xFF00FF00)|((inp&0x00FF0000)>>16);
103    }
104};
105
106struct A8R8G8B8toB8G8R8A8: public PixelConverter <uint32, uint32, FMTCONVERTERID(PF_A8R8G8B8, PF_B8G8R8A8)>
107{
108    inline static DstType pixelConvert(SrcType inp)
109    {
110        return ((inp&0x000000FF)<<24)|((inp&0x0000FF00)<<8)|((inp&0x00FF0000)>>8)|((inp&0xFF000000)>>24);
111    }
112};
113
114struct A8R8G8B8toR8G8B8A8: public PixelConverter <uint32, uint32, FMTCONVERTERID(PF_A8R8G8B8, PF_R8G8B8A8)>
115{
116    inline static DstType pixelConvert(SrcType inp)
117    {
118        return ((inp&0x00FFFFFF)<<8)|((inp&0xFF000000)>>24);
119    }
120};
121
122struct A8B8G8R8toA8R8G8B8: public PixelConverter <uint32, uint32, FMTCONVERTERID(PF_A8B8G8R8, PF_A8R8G8B8)>
123{
124    inline static DstType pixelConvert(SrcType inp)
125    {
126        return ((inp&0x000000FF)<<16)|(inp&0xFF00FF00)|((inp&0x00FF0000)>>16);
127    }
128};
129
130struct A8B8G8R8toB8G8R8A8: public PixelConverter <uint32, uint32, FMTCONVERTERID(PF_A8B8G8R8, PF_B8G8R8A8)>
131{
132    inline static DstType pixelConvert(SrcType inp)
133    {
134        return ((inp&0x00FFFFFF)<<8)|((inp&0xFF000000)>>24);
135    }
136};
137
138struct A8B8G8R8toR8G8B8A8: public PixelConverter <uint32, uint32, FMTCONVERTERID(PF_A8B8G8R8, PF_R8G8B8A8)>
139{
140    inline static DstType pixelConvert(SrcType inp)
141    {
142        return ((inp&0x000000FF)<<24)|((inp&0x0000FF00)<<8)|((inp&0x00FF0000)>>8)|((inp&0xFF000000)>>24);
143    }
144};
145
146struct B8G8R8A8toA8R8G8B8: public PixelConverter <uint32, uint32, FMTCONVERTERID(PF_B8G8R8A8, PF_A8R8G8B8)>
147{
148    inline static DstType pixelConvert(SrcType inp)
149    {
150        return ((inp&0x000000FF)<<24)|((inp&0x0000FF00)<<8)|((inp&0x00FF0000)>>8)|((inp&0xFF000000)>>24);
151    }
152};
153
154struct B8G8R8A8toA8B8G8R8: public PixelConverter <uint32, uint32, FMTCONVERTERID(PF_B8G8R8A8, PF_A8B8G8R8)>
155{
156    inline static DstType pixelConvert(SrcType inp)
157    {
158        return ((inp&0x000000FF)<<24)|((inp&0xFFFFFF00)>>8);
159    }
160};
161
162struct B8G8R8A8toR8G8B8A8: public PixelConverter <uint32, uint32, FMTCONVERTERID(PF_B8G8R8A8, PF_R8G8B8A8)>
163{
164    inline static DstType pixelConvert(SrcType inp)
165    {
166        return ((inp&0x0000FF00)<<16)|(inp&0x00FF00FF)|((inp&0xFF000000)>>16);
167    }
168};
169
170struct R8G8B8A8toA8R8G8B8: public PixelConverter <uint32, uint32, FMTCONVERTERID(PF_R8G8B8A8, PF_A8R8G8B8)>
171{
172    inline static DstType pixelConvert(SrcType inp)
173    {
174        return ((inp&0x000000FF)<<24)|((inp&0xFFFFFF00)>>8);
175    }
176};
177
178struct R8G8B8A8toA8B8G8R8: public PixelConverter <uint32, uint32, FMTCONVERTERID(PF_R8G8B8A8, PF_A8B8G8R8)>
179{
180    inline static DstType pixelConvert(SrcType inp)
181    {
182        return ((inp&0x000000FF)<<24)|((inp&0x0000FF00)<<8)|((inp&0x00FF0000)>>8)|((inp&0xFF000000)>>24);
183    }
184};
185
186struct R8G8B8A8toB8G8R8A8: public PixelConverter <uint32, uint32, FMTCONVERTERID(PF_R8G8B8A8, PF_B8G8R8A8)>
187{
188    inline static DstType pixelConvert(SrcType inp)
189    {
190        return ((inp&0x0000FF00)<<16)|(inp&0x00FF00FF)|((inp&0xFF000000)>>16);
191    }
192};
193
194struct A8B8G8R8toL8: public PixelConverter <uint32, uint8, FMTCONVERTERID(PF_A8B8G8R8, PF_L8)>
195{
196    inline static DstType pixelConvert(SrcType inp)
197    {
198        return (uint8)(inp&0x000000FF);
199    }
200};
201
202struct L8toA8B8G8R8: public PixelConverter <uint8, uint32, FMTCONVERTERID(PF_L8, PF_A8B8G8R8)>
203{
204    inline static DstType pixelConvert(SrcType inp)
205    {
206        return 0xFF000000|(((unsigned int)inp)<<0)|(((unsigned int)inp)<<8)|(((unsigned int)inp)<<16);
207    }
208};
209
210struct A8R8G8B8toL8: public PixelConverter <uint32, uint8, FMTCONVERTERID(PF_A8R8G8B8, PF_L8)>
211{
212    inline static DstType pixelConvert(SrcType inp)
213    {
214        return (uint8)((inp&0x00FF0000)>>16);
215    }
216};
217
218struct L8toA8R8G8B8: public PixelConverter <uint8, uint32, FMTCONVERTERID(PF_L8, PF_A8R8G8B8)>
219{
220    inline static DstType pixelConvert(SrcType inp)
221    {
222        return 0xFF000000|(((unsigned int)inp)<<0)|(((unsigned int)inp)<<8)|(((unsigned int)inp)<<16);
223    }
224};
225
226struct B8G8R8A8toL8: public PixelConverter <uint32, uint8, FMTCONVERTERID(PF_B8G8R8A8, PF_L8)>
227{
228    inline static DstType pixelConvert(SrcType inp)
229    {
230        return (uint8)((inp&0x0000FF00)>>8);
231    }
232};
233
234struct L8toB8G8R8A8: public PixelConverter <uint8, uint32, FMTCONVERTERID(PF_L8, PF_B8G8R8A8)>
235{
236    inline static DstType pixelConvert(SrcType inp)
237    {
238        return 0x000000FF|(((unsigned int)inp)<<8)|(((unsigned int)inp)<<16)|(((unsigned int)inp)<<24);
239    }
240};
241
242struct L8toL16: public PixelConverter <uint8, uint16, FMTCONVERTERID(PF_L8, PF_L16)>
243{
244    inline static DstType pixelConvert(SrcType inp)
245    {
246        return (uint16)((((unsigned int)inp)<<8)|(((unsigned int)inp)));
247    }
248};
249
250struct L16toL8: public PixelConverter <uint16, uint8, FMTCONVERTERID(PF_L16, PF_L8)>
251{
252    inline static DstType pixelConvert(SrcType inp)
253    {
254        return (uint8)(inp>>8);
255    }
256};
257
258struct R8G8B8toB8G8R8: public PixelConverter <Col3b, Col3b, FMTCONVERTERID(PF_R8G8B8, PF_B8G8R8)>
259{
260    inline static DstType pixelConvert(const SrcType &inp)
261    {
262        return Col3b(inp.z, inp.y, inp.x);
263    } 
264};
265
266struct B8G8R8toR8G8B8: public PixelConverter <Col3b, Col3b, FMTCONVERTERID(PF_B8G8R8, PF_R8G8B8)>
267{
268    inline static DstType pixelConvert(const SrcType &inp)
269    {
270        return Col3b(inp.z, inp.y, inp.x);
271    } 
272};
273
274// X8Y8Z8 ->  X8<<xshift Y8<<yshift Z8<<zshift A8<<ashift
275template <int id, unsigned int xshift, unsigned int yshift, unsigned int zshift, unsigned int ashift> struct Col3btoUint32swizzler:
276    public PixelConverter <Col3b, uint32, id>
277{
278    inline static uint32 pixelConvert(const Col3b &inp)
279    {
280#if OGRE_ENDIAN == OGRE_ENDIAN_BIG
281        return (0xFF<<ashift) | (((unsigned int)inp.x)<<xshift) | (((unsigned int)inp.y)<<yshift) | (((unsigned int)inp.z)<<zshift);
282#else
283        return (0xFF<<ashift) | (((unsigned int)inp.x)<<zshift) | (((unsigned int)inp.y)<<yshift) | (((unsigned int)inp.z)<<xshift);
284#endif
285    }
286};
287
288struct R8G8B8toA8R8G8B8: public Col3btoUint32swizzler<FMTCONVERTERID(PF_R8G8B8, PF_A8R8G8B8), 16, 8, 0, 24> { };
289struct B8G8R8toA8R8G8B8: public Col3btoUint32swizzler<FMTCONVERTERID(PF_B8G8R8, PF_A8R8G8B8), 0, 8, 16, 24> { };
290struct R8G8B8toA8B8G8R8: public Col3btoUint32swizzler<FMTCONVERTERID(PF_R8G8B8, PF_A8B8G8R8), 0, 8, 16, 24> { };
291struct B8G8R8toA8B8G8R8: public Col3btoUint32swizzler<FMTCONVERTERID(PF_B8G8R8, PF_A8B8G8R8), 16, 8, 0, 24> { };
292struct R8G8B8toB8G8R8A8: public Col3btoUint32swizzler<FMTCONVERTERID(PF_R8G8B8, PF_B8G8R8A8), 8, 16, 24, 0> { };
293struct B8G8R8toB8G8R8A8: public Col3btoUint32swizzler<FMTCONVERTERID(PF_B8G8R8, PF_B8G8R8A8), 24, 16, 8, 0> { };
294
295struct A8R8G8B8toR8G8B8: public PixelConverter <uint32, Col3b, FMTCONVERTERID(PF_A8R8G8B8, PF_BYTE_RGB)>
296{
297    inline static DstType pixelConvert(uint32 inp)
298    {
299        return Col3b((uint8)((inp>>16)&0xFF), (uint8)((inp>>8)&0xFF), (uint8)((inp>>0)&0xFF));
300    }
301};
302struct A8R8G8B8toB8G8R8: public PixelConverter <uint32, Col3b, FMTCONVERTERID(PF_A8R8G8B8, PF_BYTE_BGR)>
303{
304    inline static DstType pixelConvert(uint32 inp)
305    {
306        return Col3b((uint8)((inp>>0)&0xFF), (uint8)((inp>>8)&0xFF), (uint8)((inp>>16)&0xFF));
307    }
308};
309
310// Only conversions from X8R8G8B8 to formats with alpha need to be defined, the rest is implicitly the same
311// as A8R8G8B8
312struct X8R8G8B8toA8R8G8B8: public PixelConverter <uint32, uint32, FMTCONVERTERID(PF_X8R8G8B8, PF_A8R8G8B8)>
313{
314    inline static DstType pixelConvert(SrcType inp)
315    {
316        return inp | 0xFF000000;
317    }
318};
319struct X8R8G8B8toA8B8G8R8: public PixelConverter <uint32, uint32, FMTCONVERTERID(PF_X8R8G8B8, PF_A8B8G8R8)>
320{
321    inline static DstType pixelConvert(SrcType inp)
322    {
323        return ((inp&0x0000FF)<<16)|((inp&0xFF0000)>>16)|(inp&0x00FF00)|0xFF000000;
324    }
325};
326struct X8R8G8B8toB8G8R8A8: public PixelConverter <uint32, uint32, FMTCONVERTERID(PF_X8R8G8B8, PF_B8G8R8A8)>
327{
328    inline static DstType pixelConvert(SrcType inp)
329    {
330        return ((inp&0x0000FF)<<24)|((inp&0xFF0000)>>8)|((inp&0x00FF00)<<8)|0x000000FF;
331    }
332};
333struct X8R8G8B8toR8G8B8A8: public PixelConverter <uint32, uint32, FMTCONVERTERID(PF_X8R8G8B8, PF_R8G8B8A8)>
334{
335    inline static DstType pixelConvert(SrcType inp)
336    {
337        return ((inp&0xFFFFFF)<<8)|0x000000FF;
338    }
339};
340
341// X8B8G8R8
342struct X8B8G8R8toA8R8G8B8: public PixelConverter <uint32, uint32, FMTCONVERTERID(PF_X8B8G8R8, PF_A8R8G8B8)>
343{
344    inline static DstType pixelConvert(SrcType inp)
345    {
346        return ((inp&0x0000FF)<<16)|((inp&0xFF0000)>>16)|(inp&0x00FF00)|0xFF000000;
347    }
348};
349struct X8B8G8R8toA8B8G8R8: public PixelConverter <uint32, uint32, FMTCONVERTERID(PF_X8B8G8R8, PF_A8B8G8R8)>
350{
351        inline static DstType pixelConvert(SrcType inp)
352    {
353        return inp | 0xFF000000;
354    }
355};
356struct X8B8G8R8toB8G8R8A8: public PixelConverter <uint32, uint32, FMTCONVERTERID(PF_X8B8G8R8, PF_B8G8R8A8)>
357{
358    inline static DstType pixelConvert(SrcType inp)
359    {
360        return ((inp&0xFFFFFF)<<8)|0x000000FF;
361    }
362};
363struct X8B8G8R8toR8G8B8A8: public PixelConverter <uint32, uint32, FMTCONVERTERID(PF_X8B8G8R8, PF_R8G8B8A8)>
364{
365    inline static DstType pixelConvert(SrcType inp)
366    {
367        return ((inp&0x0000FF)<<24)|((inp&0xFF0000)>>8)|((inp&0x00FF00)<<8)|0x000000FF;
368    }
369};
370
371
372#define CASECONVERTER(type) case type::ID : PixelBoxConverter<type>::conversion(src, dst); return 1;
373
374inline int doOptimizedConversion(const PixelBox &src, const PixelBox &dst)
375{;
376    switch(FMTCONVERTERID(src.format, dst.format))
377    {
378        // Register converters here
379                CASECONVERTER(A8R8G8B8toA8B8G8R8);
380                CASECONVERTER(A8R8G8B8toB8G8R8A8);
381                CASECONVERTER(A8R8G8B8toR8G8B8A8);
382                CASECONVERTER(A8B8G8R8toA8R8G8B8);
383                CASECONVERTER(A8B8G8R8toB8G8R8A8);
384                CASECONVERTER(A8B8G8R8toR8G8B8A8);
385                CASECONVERTER(B8G8R8A8toA8R8G8B8);
386                CASECONVERTER(B8G8R8A8toA8B8G8R8);
387                CASECONVERTER(B8G8R8A8toR8G8B8A8);
388                CASECONVERTER(R8G8B8A8toA8R8G8B8);
389                CASECONVERTER(R8G8B8A8toA8B8G8R8);
390                CASECONVERTER(R8G8B8A8toB8G8R8A8);
391        CASECONVERTER(A8B8G8R8toL8);
392        CASECONVERTER(L8toA8B8G8R8);
393        CASECONVERTER(A8R8G8B8toL8);
394        CASECONVERTER(L8toA8R8G8B8);
395        CASECONVERTER(B8G8R8A8toL8);
396        CASECONVERTER(L8toB8G8R8A8);
397        CASECONVERTER(L8toL16);
398        CASECONVERTER(L16toL8);
399        CASECONVERTER(B8G8R8toR8G8B8);
400        CASECONVERTER(R8G8B8toB8G8R8);
401        CASECONVERTER(R8G8B8toA8R8G8B8);
402        CASECONVERTER(B8G8R8toA8R8G8B8);
403        CASECONVERTER(R8G8B8toA8B8G8R8);
404        CASECONVERTER(B8G8R8toA8B8G8R8);
405        CASECONVERTER(R8G8B8toB8G8R8A8);
406        CASECONVERTER(B8G8R8toB8G8R8A8);
407                CASECONVERTER(A8R8G8B8toR8G8B8);
408                CASECONVERTER(A8R8G8B8toB8G8R8);
409                CASECONVERTER(X8R8G8B8toA8R8G8B8);
410                CASECONVERTER(X8R8G8B8toA8B8G8R8);
411                CASECONVERTER(X8R8G8B8toB8G8R8A8);
412                CASECONVERTER(X8R8G8B8toR8G8B8A8);
413                CASECONVERTER(X8B8G8R8toA8R8G8B8);
414                CASECONVERTER(X8B8G8R8toA8B8G8R8);
415                CASECONVERTER(X8B8G8R8toB8G8R8A8);
416                CASECONVERTER(X8B8G8R8toR8G8B8A8);
417
418        default:
419            return 0;
420    }
421}
422#undef CASECONVERTER
423
424#endif // VC6 protection
Note: See TracBrowser for help on using the repository browser.