Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/ogre/OgreMain/src/OgrePixelFormat.cpp @ 11

Last change on this file since 11 was 5, checked in by anonymous, 17 years ago

=hoffentlich gehts jetzt

File size: 43.3 KB
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-2006 Torus Knot Software Ltd
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
24You may alternatively use this source under the terms of a specific version of
25the OGRE Unrestricted License provided you have obtained such a license from
26Torus Knot Software Ltd.
27-----------------------------------------------------------------------------
28*/
29#include "OgreStableHeaders.h"
30#include "OgrePixelFormat.h"
31#include "OgreBitwise.h"
32#include "OgreColourValue.h"
33#include "OgreException.h"
34
35
36namespace {
37#include "OgrePixelConversions.h"
38};
39
40namespace Ogre {
41
42    //-----------------------------------------------------------------------
43    /**
44    * A record that describes a pixel format in detail.
45    */
46    struct PixelFormatDescription {
47        /* Name of the format, as in the enum */
48        char *name;
49        /* Number of bytes one element (colour value) takes. */
50        unsigned char elemBytes;
51        /* Pixel format flags, see enum PixelFormatFlags for the bit field
52        * definitions
53        */
54        uint32 flags;
55        /** Component type
56         */
57        PixelComponentType componentType;
58        /** Component count
59         */
60        unsigned char componentCount;
61        /* Number of bits for red(or luminance), green, blue, alpha
62        */
63        unsigned char rbits,gbits,bbits,abits; /*, ibits, dbits, ... */
64
65        /* Masks and shifts as used by packers/unpackers */
66        uint32 rmask, gmask, bmask, amask;
67        unsigned char rshift, gshift, bshift, ashift;
68    };
69    //-----------------------------------------------------------------------
70    /** Pixel format database */
71    PixelFormatDescription _pixelFormats[PF_COUNT] = {
72        //-----------------------------------------------------------------------
73        {"PF_UNKNOWN",
74            /* Bytes per element */
75            0,
76            /* Flags */
77            0,
78            /* Component type and count */
79            PCT_BYTE, 0,
80            /* rbits, gbits, bbits, abits */
81            0, 0, 0, 0,
82            /* Masks and shifts */
83            0, 0, 0, 0, 0, 0, 0, 0
84        },
85        //-----------------------------------------------------------------------
86        {"PF_L8",
87        /* Bytes per element */
88        1,
89        /* Flags */
90        PFF_LUMINANCE | PFF_NATIVEENDIAN,
91        /* Component type and count */
92        PCT_BYTE, 1,
93        /* rbits, gbits, bbits, abits */
94        8, 0, 0, 0,
95        /* Masks and shifts */
96        0xFF, 0, 0, 0, 0, 0, 0, 0
97        },
98        //-----------------------------------------------------------------------
99        {"PF_L16",
100        /* Bytes per element */
101        2,
102        /* Flags */
103        PFF_LUMINANCE | PFF_NATIVEENDIAN,
104        /* Component type and count */
105        PCT_SHORT, 1,
106        /* rbits, gbits, bbits, abits */
107        16, 0, 0, 0,
108        /* Masks and shifts */
109        0xFFFF, 0, 0, 0, 0, 0, 0, 0
110        },
111        //-----------------------------------------------------------------------
112        {"PF_A8",
113        /* Bytes per element */
114        1,
115        /* Flags */
116        PFF_HASALPHA | PFF_NATIVEENDIAN,
117        /* Component type and count */
118        PCT_BYTE, 1,
119        /* rbits, gbits, bbits, abits */
120        0, 0, 0, 8,
121        /* Masks and shifts */
122        0, 0, 0, 0xFF, 0, 0, 0, 0
123        },
124        //-----------------------------------------------------------------------
125        {"PF_A4L4",
126        /* Bytes per element */
127        1,
128        /* Flags */
129        PFF_HASALPHA | PFF_LUMINANCE | PFF_NATIVEENDIAN,
130        /* Component type and count */
131        PCT_BYTE, 2,
132        /* rbits, gbits, bbits, abits */
133        4, 0, 0, 4,
134        /* Masks and shifts */
135        0x0F, 0, 0, 0xF0, 0, 0, 0, 4
136        },
137        //-----------------------------------------------------------------------
138        {"PF_BYTE_LA",
139        /* Bytes per element */
140        2,
141        /* Flags */
142        PFF_HASALPHA | PFF_LUMINANCE,
143        /* Component type and count */
144        PCT_BYTE, 2,
145        /* rbits, gbits, bbits, abits */
146        8, 0, 0, 8,
147        /* Masks and shifts */
148        0,0,0,0,0,0,0,0
149        },
150        //-----------------------------------------------------------------------
151        {"PF_R5G6B5",
152        /* Bytes per element */
153        2,
154        /* Flags */
155        PFF_NATIVEENDIAN,
156        /* Component type and count */
157        PCT_BYTE, 3,
158        /* rbits, gbits, bbits, abits */
159        5, 6, 5, 0,
160        /* Masks and shifts */
161        0xF800, 0x07E0, 0x001F, 0,
162        11, 5, 0, 0
163        },
164        //-----------------------------------------------------------------------
165                {"PF_B5G6R5",
166        /* Bytes per element */
167        2,
168        /* Flags */
169        PFF_NATIVEENDIAN,
170        /* Component type and count */
171        PCT_BYTE, 3,
172        /* rbits, gbits, bbits, abits */
173        5, 6, 5, 0,
174        /* Masks and shifts */
175        0x001F, 0x07E0, 0xF800, 0,
176        0, 5, 11, 0
177        },
178        //-----------------------------------------------------------------------
179        {"PF_A4R4G4B4",
180        /* Bytes per element */
181        2,
182        /* Flags */
183        PFF_HASALPHA | PFF_NATIVEENDIAN,
184        /* Component type and count */
185        PCT_BYTE, 4,
186        /* rbits, gbits, bbits, abits */
187        4, 4, 4, 4,
188        /* Masks and shifts */
189        0x0F00, 0x00F0, 0x000F, 0xF000,
190        8, 4, 0, 12
191        },
192        //-----------------------------------------------------------------------
193        {"PF_A1R5G5B5",
194        /* Bytes per element */
195        2,
196        /* Flags */
197        PFF_HASALPHA | PFF_NATIVEENDIAN,
198        /* Component type and count */
199        PCT_BYTE, 4,
200        /* rbits, gbits, bbits, abits */
201        5, 5, 5, 1,
202        /* Masks and shifts */
203        0x7C00, 0x03E0, 0x001F, 0x8000,
204        10, 5, 0, 15,
205        },
206        //-----------------------------------------------------------------------
207        {"PF_R8G8B8",
208        /* Bytes per element */
209        3,  // 24 bit integer -- special
210        /* Flags */
211        PFF_NATIVEENDIAN,
212        /* Component type and count */
213        PCT_BYTE, 3,
214        /* rbits, gbits, bbits, abits */
215        8, 8, 8, 0,
216        /* Masks and shifts */
217        0xFF0000, 0x00FF00, 0x0000FF, 0,
218        16, 8, 0, 0
219        },
220        //-----------------------------------------------------------------------
221        {"PF_B8G8R8",
222        /* Bytes per element */
223        3,  // 24 bit integer -- special
224        /* Flags */
225        PFF_NATIVEENDIAN,
226        /* Component type and count */
227        PCT_BYTE, 3,
228        /* rbits, gbits, bbits, abits */
229        8, 8, 8, 0,
230        /* Masks and shifts */
231        0x0000FF, 0x00FF00, 0xFF0000, 0,
232        0, 8, 16, 0
233        },
234        //-----------------------------------------------------------------------
235        {"PF_A8R8G8B8",
236        /* Bytes per element */
237        4,
238        /* Flags */
239        PFF_HASALPHA | PFF_NATIVEENDIAN,
240        /* Component type and count */
241        PCT_BYTE, 4,
242        /* rbits, gbits, bbits, abits */
243        8, 8, 8, 8,
244        /* Masks and shifts */
245        0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000,
246        16, 8, 0, 24
247        },
248        //-----------------------------------------------------------------------
249        {"PF_A8B8G8R8",
250        /* Bytes per element */
251        4,
252        /* Flags */
253        PFF_HASALPHA | PFF_NATIVEENDIAN,
254        /* Component type and count */
255        PCT_BYTE, 4,
256        /* rbits, gbits, bbits, abits */
257        8, 8, 8, 8,
258        /* Masks and shifts */
259        0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000,
260        0, 8, 16, 24,
261        },
262        //-----------------------------------------------------------------------
263        {"PF_B8G8R8A8",
264        /* Bytes per element */
265        4,
266        /* Flags */
267        PFF_HASALPHA | PFF_NATIVEENDIAN,
268        /* Component type and count */
269        PCT_BYTE, 4,
270        /* rbits, gbits, bbits, abits */
271        8, 8, 8, 8,
272        /* Masks and shifts */
273        0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF,
274        8, 16, 24, 0
275        },
276        //-----------------------------------------------------------------------
277        {"PF_A2R10G10B10",
278        /* Bytes per element */
279        4,
280        /* Flags */
281        PFF_HASALPHA | PFF_NATIVEENDIAN,
282        /* Component type and count */
283        PCT_BYTE, 4,
284        /* rbits, gbits, bbits, abits */
285        10, 10, 10, 2,
286        /* Masks and shifts */
287        0x3FF00000, 0x000FFC00, 0x000003FF, 0xC0000000,
288        20, 10, 0, 30
289        },
290        //-----------------------------------------------------------------------
291        {"PF_A2B10G10R10",
292        /* Bytes per element */
293        4,
294        /* Flags */
295        PFF_HASALPHA | PFF_NATIVEENDIAN,
296        /* Component type and count */
297        PCT_BYTE, 4,
298        /* rbits, gbits, bbits, abits */
299        10, 10, 10, 2,
300        /* Masks and shifts */
301        0x000003FF, 0x000FFC00, 0x3FF00000, 0xC0000000,
302        0, 10, 20, 30
303        },
304        //-----------------------------------------------------------------------
305        {"PF_DXT1",
306        /* Bytes per element */
307        0,
308        /* Flags */
309        PFF_COMPRESSED | PFF_HASALPHA,
310        /* Component type and count */
311        PCT_BYTE, 3, // No alpha
312        /* rbits, gbits, bbits, abits */
313        0, 0, 0, 0,
314        /* Masks and shifts */
315        0, 0, 0, 0, 0, 0, 0, 0
316        },
317        //-----------------------------------------------------------------------
318        {"PF_DXT2",
319        /* Bytes per element */
320        0,
321        /* Flags */
322        PFF_COMPRESSED | PFF_HASALPHA,
323        /* Component type and count */
324        PCT_BYTE, 4,
325        /* rbits, gbits, bbits, abits */
326        0, 0, 0, 0,
327        /* Masks and shifts */
328        0, 0, 0, 0, 0, 0, 0, 0
329        },
330        //-----------------------------------------------------------------------
331        {"PF_DXT3",
332        /* Bytes per element */
333        0,
334        /* Flags */
335        PFF_COMPRESSED | PFF_HASALPHA,
336        /* Component type and count */
337        PCT_BYTE, 4,
338        /* rbits, gbits, bbits, abits */
339        0, 0, 0, 0,
340        /* Masks and shifts */
341        0, 0, 0, 0, 0, 0, 0, 0
342        },
343        //-----------------------------------------------------------------------
344        {"PF_DXT4",
345        /* Bytes per element */
346        0,
347        /* Flags */
348        PFF_COMPRESSED | PFF_HASALPHA,
349        /* Component type and count */
350        PCT_BYTE, 4,
351        /* rbits, gbits, bbits, abits */
352        0, 0, 0, 0,
353        /* Masks and shifts */
354        0, 0, 0, 0, 0, 0, 0, 0
355        },
356        //-----------------------------------------------------------------------
357        {"PF_DXT5",
358        /* Bytes per element */
359        0,
360        /* Flags */
361        PFF_COMPRESSED | PFF_HASALPHA,
362        /* Component type and count */
363        PCT_BYTE, 4,
364        /* rbits, gbits, bbits, abits */
365        0, 0, 0, 0,
366        /* Masks and shifts */
367        0, 0, 0, 0, 0, 0, 0, 0
368        },
369        //-----------------------------------------------------------------------
370        {"PF_FLOAT16_RGB",
371        /* Bytes per element */
372        6,
373        /* Flags */
374        PFF_FLOAT,
375        /* Component type and count */
376        PCT_FLOAT16, 3,
377        /* rbits, gbits, bbits, abits */
378        16, 16, 16, 0,
379        /* Masks and shifts */
380        0, 0, 0, 0, 0, 0, 0, 0
381        },
382        //-----------------------------------------------------------------------
383        {"PF_FLOAT16_RGBA",
384        /* Bytes per element */
385        8,
386        /* Flags */
387        PFF_FLOAT,
388        /* Component type and count */
389        PCT_FLOAT16, 4,
390        /* rbits, gbits, bbits, abits */
391        16, 16, 16, 16,
392        /* Masks and shifts */
393        0, 0, 0, 0, 0, 0, 0, 0
394        },
395        //-----------------------------------------------------------------------
396        {"PF_FLOAT32_RGB",
397        /* Bytes per element */
398        12,
399        /* Flags */
400        PFF_FLOAT,
401        /* Component type and count */
402        PCT_FLOAT32, 3,
403        /* rbits, gbits, bbits, abits */
404        32, 32, 32, 0,
405        /* Masks and shifts */
406        0, 0, 0, 0, 0, 0, 0, 0
407        },
408        //-----------------------------------------------------------------------
409        {"PF_FLOAT32_RGBA",
410        /* Bytes per element */
411        16,
412        /* Flags */
413        PFF_FLOAT,
414        /* Component type and count */
415        PCT_FLOAT32, 4,
416        /* rbits, gbits, bbits, abits */
417        32, 32, 32, 32,
418        /* Masks and shifts */
419        0, 0, 0, 0, 0, 0, 0, 0
420        },
421        //-----------------------------------------------------------------------
422        {"PF_X8R8G8B8",
423        /* Bytes per element */
424        4,
425        /* Flags */
426        PFF_NATIVEENDIAN,
427        /* Component type and count */
428        PCT_BYTE, 3,
429        /* rbits, gbits, bbits, abits */
430        8, 8, 8, 0,
431        /* Masks and shifts */
432        0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000,
433        16, 8, 0, 24
434        },
435        //-----------------------------------------------------------------------
436        {"PF_X8B8G8R8",
437        /* Bytes per element */
438        4,
439        /* Flags */
440        PFF_NATIVEENDIAN,
441        /* Component type and count */
442        PCT_BYTE, 3,
443        /* rbits, gbits, bbits, abits */
444        8, 8, 8, 0,
445        /* Masks and shifts */
446        0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000,
447        0, 8, 16, 24
448        },
449        //-----------------------------------------------------------------------
450        {"PF_R8G8B8A8",
451        /* Bytes per element */
452        4,
453        /* Flags */
454        PFF_HASALPHA | PFF_NATIVEENDIAN,
455        /* Component type and count */
456        PCT_BYTE, 4,
457        /* rbits, gbits, bbits, abits */
458        8, 8, 8, 8,
459        /* Masks and shifts */
460        0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF,
461        24, 16, 8, 0
462        },
463        //-----------------------------------------------------------------------
464                {"PF_DEPTH",
465        /* Bytes per element */
466        4,
467        /* Flags */
468        PFF_DEPTH,
469        /* Component type and count */
470        PCT_FLOAT32, 1, // ?
471        /* rbits, gbits, bbits, abits */
472        0, 0, 0, 0,
473        /* Masks and shifts */
474                0, 0, 0, 0, 0, 0, 0, 0
475        },
476        //-----------------------------------------------------------------------
477                {"PF_SHORT_RGBA",
478                /* Bytes per element */
479        8,
480        /* Flags */
481        PFF_HASALPHA,
482        /* Component type and count */
483        PCT_SHORT, 4,
484        /* rbits, gbits, bbits, abits */
485        16, 16, 16, 16,
486        /* Masks and shifts */
487                0, 0, 0, 0, 0, 0, 0, 0
488        },
489        //-----------------------------------------------------------------------
490        {"PF_R3G3B2",
491        /* Bytes per element */
492        1,
493        /* Flags */
494        PFF_NATIVEENDIAN,
495        /* Component type and count */
496        PCT_BYTE, 3,
497        /* rbits, gbits, bbits, abits */
498        3, 3, 2, 0,
499        /* Masks and shifts */
500        0xE0, 0x1C, 0x03, 0,
501        5, 2, 0, 0
502        },
503        //-----------------------------------------------------------------------
504        {"PF_FLOAT16_R",
505        /* Bytes per element */
506        2,
507        /* Flags */
508        PFF_FLOAT,
509        /* Component type and count */
510        PCT_FLOAT16, 1,
511        /* rbits, gbits, bbits, abits */
512        16, 0, 0, 0,
513        /* Masks and shifts */
514        0, 0, 0, 0, 0, 0, 0, 0
515        },
516        //-----------------------------------------------------------------------
517        {"PF_FLOAT32_R",
518        /* Bytes per element */
519        4,
520        /* Flags */
521        PFF_FLOAT,
522        /* Component type and count */
523        PCT_FLOAT32, 1,
524        /* rbits, gbits, bbits, abits */
525        32, 0, 0, 0,
526        /* Masks and shifts */
527        0, 0, 0, 0, 0, 0, 0, 0
528        },
529        //-----------------------------------------------------------------------
530        {"PF_SHORT_GR",
531        /* Bytes per element */
532        4,
533        /* Flags */
534        PFF_NATIVEENDIAN,
535        /* Component type and count */
536        PCT_SHORT, 2,
537        /* rbits, gbits, bbits, abits */
538        16, 16, 0, 0,
539        /* Masks and shifts */
540        0x0000FFFF, 0xFFFF0000, 0, 0, 
541                0, 16, 0, 0
542        },
543        //-----------------------------------------------------------------------
544        {"PF_FLOAT16_GR",
545        /* Bytes per element */
546        4,
547        /* Flags */
548        PFF_FLOAT,
549        /* Component type and count */
550        PCT_FLOAT16, 2,
551        /* rbits, gbits, bbits, abits */
552        16, 16, 0, 0,
553        /* Masks and shifts */
554        0, 0, 0, 0, 0, 0, 0, 0
555        },
556        //-----------------------------------------------------------------------
557        {"PF_FLOAT32_GR",
558        /* Bytes per element */
559        8,
560        /* Flags */
561        PFF_FLOAT,
562        /* Component type and count */
563        PCT_FLOAT32, 2,
564        /* rbits, gbits, bbits, abits */
565        32, 32, 0, 0,
566        /* Masks and shifts */
567        0, 0, 0, 0, 0, 0, 0, 0
568        },
569        //-----------------------------------------------------------------------
570                {"PF_SHORT_RGB",
571                /* Bytes per element */
572        6,
573        /* Flags */
574        0,
575        /* Component type and count */
576        PCT_SHORT, 3,
577        /* rbits, gbits, bbits, abits */
578        16, 16, 16, 0,
579        /* Masks and shifts */
580                0, 0, 0, 0, 0, 0, 0, 0
581        },
582    };
583    //-----------------------------------------------------------------------
584        size_t PixelBox::getConsecutiveSize() const
585        {
586                return PixelUtil::getMemorySize(getWidth(), getHeight(), getDepth(), format);
587        }
588        PixelBox PixelBox::getSubVolume(const Box &def) const
589        {
590                if(PixelUtil::isCompressed(format))
591                {
592                        if(def.left == left && def.top == top && def.front == front &&
593                           def.right == right && def.bottom == bottom && def.back == back)
594                        {
595                                // Entire buffer is being queried
596                                return *this;
597                        }
598                        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot return subvolume of compressed PixelBuffer", "PixelBox::getSubVolume");
599                }
600                if(!contains(def))
601                        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Bounds out of range", "PixelBox::getSubVolume");
602
603                const size_t elemSize = PixelUtil::getNumElemBytes(format);
604                // Calculate new data origin
605                PixelBox rval(def, format, ((uint8*)data)
606                        + ((def.left-left)*elemSize)
607                        + ((def.top-top)*rowPitch*elemSize)
608                        + ((def.front-front)*slicePitch*elemSize)
609                );
610
611                rval.rowPitch = rowPitch;
612                rval.slicePitch = slicePitch;
613                rval.format = format;
614
615                return rval;
616        }
617    //-----------------------------------------------------------------------
618    /**
619    * Directly get the description record for provided pixel format. For debug builds,
620    * this checks the bounds of fmt with an assertion.
621    */
622    static inline const PixelFormatDescription &getDescriptionFor(const PixelFormat fmt)
623    {
624        const int ord = (int)fmt;
625        assert(ord>=0 && ord<PF_COUNT);
626
627        return _pixelFormats[ord];
628    }
629    //-----------------------------------------------------------------------
630    size_t PixelUtil::getNumElemBytes( PixelFormat format )
631    {
632        return getDescriptionFor(format).elemBytes;
633    }
634        //-----------------------------------------------------------------------
635        size_t PixelUtil::getMemorySize(size_t width, size_t height, size_t depth, PixelFormat format)
636        {
637                if(isCompressed(format))
638                {
639                        switch(format)
640                        {
641                                // DXT formats work by dividing the image into 4x4 blocks, then encoding each
642                                // 4x4 block with a certain number of bytes. DXT can only be used on 2D images.
643                                case PF_DXT1:
644                                        assert(depth == 1);
645                                        return ((width+3)/4)*((height+3)/4)*8;
646                                case PF_DXT2:
647                                case PF_DXT3:
648                                case PF_DXT4:
649                                case PF_DXT5:
650                                        assert(depth == 1);
651                                        return ((width+3)/4)*((height+3)/4)*16;
652                                default:
653                                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid compressed pixel format",
654                                        "PixelUtil::getMemorySize");
655                        }
656                }
657                else
658                {
659                        return width*height*depth*getNumElemBytes(format);
660                }
661        }
662    //-----------------------------------------------------------------------
663    size_t PixelUtil::getNumElemBits( PixelFormat format )
664    {
665        return getDescriptionFor(format).elemBytes * 8;
666    }
667    //-----------------------------------------------------------------------
668    unsigned int PixelUtil::getFlags( PixelFormat format )
669    {
670        return getDescriptionFor(format).flags;
671    }
672    //-----------------------------------------------------------------------
673    bool PixelUtil::hasAlpha(PixelFormat format)
674    {
675        return (PixelUtil::getFlags(format) & PFF_HASALPHA) > 0;
676    }
677    //-----------------------------------------------------------------------
678    bool PixelUtil::isFloatingPoint(PixelFormat format)
679    {
680        return (PixelUtil::getFlags(format) & PFF_FLOAT) > 0;
681    }
682    //-----------------------------------------------------------------------
683    bool PixelUtil::isCompressed(PixelFormat format)
684    {
685        return (PixelUtil::getFlags(format) & PFF_COMPRESSED) > 0;
686    }
687    //-----------------------------------------------------------------------
688    bool PixelUtil::isDepth(PixelFormat format)
689    {
690        return (PixelUtil::getFlags(format) & PFF_DEPTH) > 0;
691    }
692    //-----------------------------------------------------------------------
693    bool PixelUtil::isNativeEndian(PixelFormat format)
694    {
695        return (PixelUtil::getFlags(format) & PFF_NATIVEENDIAN) > 0;
696    }
697    //-----------------------------------------------------------------------
698    bool PixelUtil::isLuminance(PixelFormat format)
699    {
700        return (PixelUtil::getFlags(format) & PFF_LUMINANCE) > 0;
701    }
702    //-----------------------------------------------------------------------
703        bool PixelUtil::isValidExtent(size_t width, size_t height, size_t depth, PixelFormat format)
704        {
705                if(isCompressed(format))
706                {
707                        switch(format)
708                        {
709                                case PF_DXT1:
710                                case PF_DXT2:
711                                case PF_DXT3:
712                                case PF_DXT4:
713                                case PF_DXT5:
714                                        return ((width&3)==0 && (height&3)==0 && depth==1);
715                                default:
716                                        return true;
717                        }
718                }
719                else
720                {
721                        return true;
722                }
723        }
724        //-----------------------------------------------------------------------
725    void PixelUtil::getBitDepths(PixelFormat format, int rgba[4])
726    {
727        const PixelFormatDescription &des = getDescriptionFor(format);
728        rgba[0] = des.rbits;
729        rgba[1] = des.gbits;
730        rgba[2] = des.bbits;
731        rgba[3] = des.abits;
732    }
733        //-----------------------------------------------------------------------
734        void PixelUtil::getBitMasks(PixelFormat format, uint32 rgba[4])
735    {
736        const PixelFormatDescription &des = getDescriptionFor(format);
737        rgba[0] = des.rmask;
738        rgba[1] = des.gmask;
739        rgba[2] = des.bmask;
740        rgba[3] = des.amask;
741    }
742    //-----------------------------------------------------------------------
743    String PixelUtil::getFormatName(PixelFormat srcformat)
744    {
745        return getDescriptionFor(srcformat).name;
746    }
747    //-----------------------------------------------------------------------
748    bool PixelUtil::isAccessible(PixelFormat srcformat)
749    {
750        if (srcformat == PF_UNKNOWN)
751            return false;
752        unsigned int flags = getFlags(srcformat);
753        return !((flags & PFF_COMPRESSED) || (flags & PFF_DEPTH));
754    }
755    //-----------------------------------------------------------------------
756    PixelComponentType PixelUtil::getComponentType(PixelFormat fmt)
757    {
758        const PixelFormatDescription &des = getDescriptionFor(fmt);
759        return des.componentType;
760    }
761    //-----------------------------------------------------------------------
762    size_t PixelUtil::getComponentCount(PixelFormat fmt)
763    {
764        const PixelFormatDescription &des = getDescriptionFor(fmt);
765        return des.componentCount;
766    }
767    //-----------------------------------------------------------------------
768    PixelFormat PixelUtil::getFormatFromName(const String& name, bool accessibleOnly, bool caseSensitive)
769    {
770        String tmp = name;
771        if (!caseSensitive)
772        {
773            // We are stored upper-case format names.
774            StringUtil::toUpperCase(tmp);
775        }
776
777        for (int i = 0; i < PF_COUNT; ++i)
778        {
779            PixelFormat pf = static_cast<PixelFormat>(i);
780            if (!accessibleOnly || isAccessible(pf))
781            {
782                if (tmp == getFormatName(pf))
783                    return pf;
784            }
785        }
786        return PF_UNKNOWN;
787    }
788    //-----------------------------------------------------------------------
789    String PixelUtil::getBNFExpressionOfPixelFormats(bool accessibleOnly)
790    {
791        // Collect format names sorted by length, it's required by BNF compiler
792        // that similar tokens need longer ones comes first.
793        typedef std::multimap<String::size_type, String> FormatNameMap;
794        FormatNameMap formatNames;
795        for (size_t i = 0; i < PF_COUNT; ++i)
796        {
797            PixelFormat pf = static_cast<PixelFormat>(i);
798            if (!accessibleOnly || isAccessible(pf))
799            {
800                String formatName = getFormatName(pf);
801                formatNames.insert(std::make_pair(formatName.length(), formatName));
802            }
803        }
804
805        // Populate the BNF expression in reverse order
806        String result;
807        // Note: Stupid M$ VC7.1 can't dealing operator!= with FormatNameMap::const_reverse_iterator.
808        for (FormatNameMap::reverse_iterator j = formatNames.rbegin(); j != formatNames.rend(); ++j)
809        {
810            if (!result.empty())
811                result += " | ";
812            result += "'" + j->second + "'";
813        }
814
815        return result;
816    }
817    //-----------------------------------------------------------------------
818    PixelFormat PixelUtil::getFormatForBitDepths(PixelFormat fmt, ushort integerBits, ushort floatBits)
819    {
820        switch (integerBits)
821        {
822        case 16:
823            switch (fmt)
824            {
825            case PF_R8G8B8:
826            case PF_X8R8G8B8:
827                return PF_R5G6B5;
828
829            case PF_B8G8R8:
830            case PF_X8B8G8R8:
831                return PF_B5G6R5;
832
833            case PF_A8R8G8B8:
834            case PF_R8G8B8A8:
835            case PF_A8B8G8R8:
836            case PF_B8G8R8A8:
837                return PF_A4R4G4B4;
838
839            case PF_A2R10G10B10:
840            case PF_A2B10G10R10:
841                return PF_A1R5G5B5;
842
843            default:
844                // use original image format
845                break;
846            }
847            break;
848
849        case 32:
850            switch (fmt)
851            {
852            case PF_R5G6B5:
853                return PF_X8R8G8B8;
854
855            case PF_B5G6R5:
856                return PF_X8B8G8R8;
857
858            case PF_A4R4G4B4:
859                return PF_A8R8G8B8;
860
861            case PF_A1R5G5B5:
862                return PF_A2R10G10B10;
863
864            default:
865                // use original image format
866                break;
867            }
868            break;
869
870        default:
871            // use original image format
872            break;
873        }
874
875        switch (floatBits)
876        {
877        case 16:
878            switch (fmt)
879            {
880            case PF_FLOAT32_R:
881                return PF_FLOAT16_R;
882
883            case PF_FLOAT32_RGB:
884                return PF_FLOAT16_RGB;
885
886            case PF_FLOAT32_RGBA:
887                return PF_FLOAT16_RGBA;
888
889            default:
890                // use original image format
891                break;
892            }
893            break;
894
895        case 32:
896            switch (fmt)
897            {
898            case PF_FLOAT16_R:
899                return PF_FLOAT32_R;
900
901            case PF_FLOAT16_RGB:
902                return PF_FLOAT32_RGB;
903
904            case PF_FLOAT16_RGBA:
905                return PF_FLOAT32_RGBA;
906
907            default:
908                // use original image format
909                break;
910            }
911            break;
912
913        default:
914            // use original image format
915            break;
916        }
917
918        return fmt;
919    }
920    //-----------------------------------------------------------------------
921    /*************************************************************************
922    * Pixel packing/unpacking utilities
923    */
924    void PixelUtil::packColour(const ColourValue &colour, const PixelFormat pf,  void* dest)
925    {
926        packColour(colour.r, colour.g, colour.b, colour.a, pf, dest);
927    }
928    //-----------------------------------------------------------------------
929    void PixelUtil::packColour(const uint8 r, const uint8 g, const uint8 b, const uint8 a, const PixelFormat pf,  void* dest)
930    {
931        const PixelFormatDescription &des = getDescriptionFor(pf);
932        if(des.flags & PFF_NATIVEENDIAN) {
933            // Shortcut for integer formats packing
934            unsigned int value = ((Bitwise::fixedToFixed(r, 8, des.rbits)<<des.rshift) & des.rmask) |
935                ((Bitwise::fixedToFixed(g, 8, des.gbits)<<des.gshift) & des.gmask) |
936                ((Bitwise::fixedToFixed(b, 8, des.bbits)<<des.bshift) & des.bmask) |
937                ((Bitwise::fixedToFixed(a, 8, des.abits)<<des.ashift) & des.amask);
938            // And write to memory
939            Bitwise::intWrite(dest, des.elemBytes, value);
940        } else {
941            // Convert to float
942            packColour((float)r/255.0f,(float)g/255.0f,(float)b/255.0f,(float)a/255.0f, pf, dest);
943        }
944    }
945    //-----------------------------------------------------------------------
946    void PixelUtil::packColour(const float r, const float g, const float b, const float a, const PixelFormat pf,  void* dest)
947    {
948        // Catch-it-all here
949        const PixelFormatDescription &des = getDescriptionFor(pf);
950        if(des.flags & PFF_NATIVEENDIAN) {
951            // Do the packing
952            //std::cerr << dest << " " << r << " " << g <<  " " << b << " " << a << std::endl;
953            const unsigned int value = ((Bitwise::floatToFixed(r, des.rbits)<<des.rshift) & des.rmask) |
954                ((Bitwise::floatToFixed(g, des.gbits)<<des.gshift) & des.gmask) |
955                ((Bitwise::floatToFixed(b, des.bbits)<<des.bshift) & des.bmask) |
956                ((Bitwise::floatToFixed(a, des.abits)<<des.ashift) & des.amask);
957            // And write to memory
958            Bitwise::intWrite(dest, des.elemBytes, value);
959        } else {
960            switch(pf)
961            {
962            case PF_FLOAT32_R:
963                ((float*)dest)[0] = r;
964                break;
965                        case PF_FLOAT32_GR:
966                                ((float*)dest)[0] = g;
967                                ((float*)dest)[1] = r;
968                                break;
969            case PF_FLOAT32_RGB:
970                ((float*)dest)[0] = r;
971                ((float*)dest)[1] = g;
972                ((float*)dest)[2] = b;
973                break;
974            case PF_FLOAT32_RGBA:
975                ((float*)dest)[0] = r;
976                ((float*)dest)[1] = g;
977                ((float*)dest)[2] = b;
978                ((float*)dest)[3] = a;
979                break;
980            case PF_FLOAT16_R:
981                ((uint16*)dest)[0] = Bitwise::floatToHalf(r);
982                break;
983                        case PF_FLOAT16_GR:
984                                ((uint16*)dest)[0] = Bitwise::floatToHalf(g);
985                                ((uint16*)dest)[1] = Bitwise::floatToHalf(r);
986                                break;
987            case PF_FLOAT16_RGB:
988                ((uint16*)dest)[0] = Bitwise::floatToHalf(r);
989                ((uint16*)dest)[1] = Bitwise::floatToHalf(g);
990                ((uint16*)dest)[2] = Bitwise::floatToHalf(b);
991                break;
992            case PF_FLOAT16_RGBA:
993                ((uint16*)dest)[0] = Bitwise::floatToHalf(r);
994                ((uint16*)dest)[1] = Bitwise::floatToHalf(g);
995                ((uint16*)dest)[2] = Bitwise::floatToHalf(b);
996                ((uint16*)dest)[3] = Bitwise::floatToHalf(a);
997                break;
998            case PF_SHORT_RGB:
999                                ((uint16*)dest)[0] = Bitwise::floatToFixed(r, 16);
1000                ((uint16*)dest)[1] = Bitwise::floatToFixed(g, 16);
1001                ((uint16*)dest)[2] = Bitwise::floatToFixed(b, 16);
1002                break;
1003                        case PF_SHORT_RGBA:
1004                                ((uint16*)dest)[0] = Bitwise::floatToFixed(r, 16);
1005                ((uint16*)dest)[1] = Bitwise::floatToFixed(g, 16);
1006                ((uint16*)dest)[2] = Bitwise::floatToFixed(b, 16);
1007                ((uint16*)dest)[3] = Bitwise::floatToFixed(a, 16);
1008                                break;
1009                        case PF_BYTE_LA:
1010                                ((uint8*)dest)[0] = Bitwise::floatToFixed(r, 8);
1011                ((uint8*)dest)[1] = Bitwise::floatToFixed(a, 8);
1012                                break;
1013            default:
1014                // Not yet supported
1015                OGRE_EXCEPT(
1016                    Exception::ERR_NOT_IMPLEMENTED,
1017                    "pack to "+getFormatName(pf)+" not implemented",
1018                    "PixelUtil::packColour");
1019                break;
1020            }
1021        }
1022    }
1023    //-----------------------------------------------------------------------
1024    void PixelUtil::unpackColour(ColourValue *colour, PixelFormat pf,  const void* src)
1025    {
1026        unpackColour(&colour->r, &colour->g, &colour->b, &colour->a, pf, src);
1027    }
1028    //-----------------------------------------------------------------------
1029    void PixelUtil::unpackColour(uint8 *r, uint8 *g, uint8 *b, uint8 *a, PixelFormat pf,  const void* src)
1030    {
1031        const PixelFormatDescription &des = getDescriptionFor(pf);
1032        if(des.flags & PFF_NATIVEENDIAN) {
1033            // Shortcut for integer formats unpacking
1034            const unsigned int value = Bitwise::intRead(src, des.elemBytes);
1035            if(des.flags & PFF_LUMINANCE)
1036            {
1037                // Luminance format -- only rbits used
1038                *r = *g = *b = Bitwise::fixedToFixed(
1039                    (value & des.rmask)>>des.rshift, des.rbits, 8);
1040            }
1041            else
1042            {
1043                *r = Bitwise::fixedToFixed((value & des.rmask)>>des.rshift, des.rbits, 8);
1044                *g = Bitwise::fixedToFixed((value & des.gmask)>>des.gshift, des.gbits, 8);
1045                *b = Bitwise::fixedToFixed((value & des.bmask)>>des.bshift, des.bbits, 8);
1046            }
1047            if(des.flags & PFF_HASALPHA)
1048            {
1049                *a = Bitwise::fixedToFixed((value & des.amask)>>des.ashift, des.abits, 8);
1050            }
1051            else
1052            {
1053                *a = 255; // No alpha, default a component to full
1054            }
1055        } else {
1056            // Do the operation with the more generic floating point
1057            float rr, gg, bb, aa;
1058            unpackColour(&rr,&gg,&bb,&aa, pf, src);
1059            *r = Bitwise::floatToFixed(rr, 8);
1060            *g = Bitwise::floatToFixed(gg, 8);
1061            *b = Bitwise::floatToFixed(bb, 8);
1062            *a = Bitwise::floatToFixed(aa, 8);
1063        }
1064    }
1065    //-----------------------------------------------------------------------
1066    void PixelUtil::unpackColour(float *r, float *g, float *b, float *a,
1067        PixelFormat pf,  const void* src)
1068    {
1069        const PixelFormatDescription &des = getDescriptionFor(pf);
1070        if(des.flags & PFF_NATIVEENDIAN) {
1071            // Shortcut for integer formats unpacking
1072            const unsigned int value = Bitwise::intRead(src, des.elemBytes);
1073            if(des.flags & PFF_LUMINANCE)
1074            {
1075                // Luminance format -- only rbits used
1076                *r = *g = *b = Bitwise::fixedToFloat(
1077                    (value & des.rmask)>>des.rshift, des.rbits);
1078            }
1079            else
1080            {
1081                *r = Bitwise::fixedToFloat((value & des.rmask)>>des.rshift, des.rbits);
1082                *g = Bitwise::fixedToFloat((value & des.gmask)>>des.gshift, des.gbits);
1083                *b = Bitwise::fixedToFloat((value & des.bmask)>>des.bshift, des.bbits);
1084            }
1085            if(des.flags & PFF_HASALPHA)
1086            {
1087                *a = Bitwise::fixedToFloat((value & des.amask)>>des.ashift, des.abits);
1088            }
1089            else
1090            {
1091                *a = 1.0f; // No alpha, default a component to full
1092            }
1093        } else {
1094            switch(pf)
1095            {
1096            case PF_FLOAT32_R:
1097                *r = *g = *b = ((float*)src)[0];
1098                *a = 1.0f;
1099                break;
1100                        case PF_FLOAT32_GR:
1101                                *g = ((float*)src)[0];
1102                                *r = *b = ((float*)src)[1];
1103                                *a = 1.0f;
1104                                break;
1105            case PF_FLOAT32_RGB:
1106                *r = ((float*)src)[0];
1107                *g = ((float*)src)[1];
1108                *b = ((float*)src)[2];
1109                *a = 1.0f;
1110                break;
1111            case PF_FLOAT32_RGBA:
1112                *r = ((float*)src)[0];
1113                *g = ((float*)src)[1];
1114                *b = ((float*)src)[2];
1115                *a = ((float*)src)[3];
1116                break;
1117            case PF_FLOAT16_R:
1118                *r = *g = *b = Bitwise::halfToFloat(((uint16*)src)[0]);
1119                *a = 1.0f;
1120                break;
1121                        case PF_FLOAT16_GR:
1122                                *g = Bitwise::halfToFloat(((uint16*)src)[0]);
1123                                *r = *b = Bitwise::halfToFloat(((uint16*)src)[1]);
1124                                *a = 1.0f;
1125                                break;
1126            case PF_FLOAT16_RGB:
1127                *r = Bitwise::halfToFloat(((uint16*)src)[0]);
1128                *g = Bitwise::halfToFloat(((uint16*)src)[1]);
1129                *b = Bitwise::halfToFloat(((uint16*)src)[2]);
1130                *a = 1.0f;
1131                break;
1132            case PF_FLOAT16_RGBA:
1133                *r = Bitwise::halfToFloat(((uint16*)src)[0]);
1134                *g = Bitwise::halfToFloat(((uint16*)src)[1]);
1135                *b = Bitwise::halfToFloat(((uint16*)src)[2]);
1136                *a = Bitwise::halfToFloat(((uint16*)src)[3]);
1137                break;
1138                        case PF_SHORT_RGB:
1139                                *r = Bitwise::fixedToFloat(((uint16*)src)[0], 16);
1140                *g = Bitwise::fixedToFloat(((uint16*)src)[1], 16);
1141                                *b = Bitwise::fixedToFloat(((uint16*)src)[2], 16);
1142                                *a = 1.0f;
1143                                break;
1144                        case PF_SHORT_RGBA:
1145                                *r = Bitwise::fixedToFloat(((uint16*)src)[0], 16);
1146                *g = Bitwise::fixedToFloat(((uint16*)src)[1], 16);
1147                                *b = Bitwise::fixedToFloat(((uint16*)src)[2], 16);
1148                                *a = Bitwise::fixedToFloat(((uint16*)src)[3], 16);
1149                                break;
1150                        case PF_BYTE_LA:
1151                                *r = *g = *b = Bitwise::fixedToFloat(((uint8*)src)[0], 8);
1152                                *a = Bitwise::fixedToFloat(((uint8*)src)[1], 8);
1153                                break;
1154            default:
1155                // Not yet supported
1156                OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,
1157                    "unpack from "+getFormatName(pf)+" not implemented",
1158                    "PixelUtil::unpackColour");
1159                break;
1160            }
1161        }
1162    }
1163    //-----------------------------------------------------------------------
1164    /* Convert pixels from one format to another */
1165    void PixelUtil::bulkPixelConversion(void *srcp, PixelFormat srcFormat,
1166        void *destp, PixelFormat dstFormat, unsigned int count)
1167    {
1168        PixelBox src(count, 1, 1, srcFormat, srcp),
1169                                 dst(count, 1, 1, dstFormat, destp);
1170
1171        bulkPixelConversion(src, dst);
1172    }
1173    //-----------------------------------------------------------------------
1174    void PixelUtil::bulkPixelConversion(const PixelBox &src, const PixelBox &dst)
1175    {
1176        assert(src.getWidth() == dst.getWidth() &&
1177                           src.getHeight() == dst.getHeight() &&
1178                           src.getDepth() == dst.getDepth());
1179
1180                // Check for compressed formats, we don't support decompression, compression or recoding
1181                if(PixelUtil::isCompressed(src.format) || PixelUtil::isCompressed(dst.format))
1182                {
1183                        if(src.format == dst.format)
1184                        {
1185                                memcpy(dst.data, src.data, src.getConsecutiveSize());
1186                                return;
1187                        }
1188                        else
1189                        {
1190                                OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,
1191                                        "This method can not be used to compress or decompress images",
1192                                        "PixelUtil::bulkPixelConversion");
1193                        }
1194                }
1195
1196        // The easy case
1197        if(src.format == dst.format) {
1198            // Everything consecutive?
1199            if(src.isConsecutive() && dst.isConsecutive())
1200            {
1201                                memcpy(dst.data, src.data, src.getConsecutiveSize());
1202                return;
1203            }
1204
1205            uint8 *srcptr = static_cast<uint8*>(src.data);
1206            uint8 *dstptr = static_cast<uint8*>(dst.data);
1207            const size_t srcPixelSize = PixelUtil::getNumElemBytes(src.format);
1208            const size_t dstPixelSize = PixelUtil::getNumElemBytes(dst.format);
1209
1210            // Calculate pitches+skips in bytes
1211            const size_t srcRowPitchBytes = src.rowPitch*srcPixelSize;
1212            //const size_t srcRowSkipBytes = src.getRowSkip()*srcPixelSize;
1213            const size_t srcSliceSkipBytes = src.getSliceSkip()*srcPixelSize;
1214
1215            const size_t dstRowPitchBytes = dst.rowPitch*dstPixelSize;
1216            //const size_t dstRowSkipBytes = dst.getRowSkip()*dstPixelSize;
1217            const size_t dstSliceSkipBytes = dst.getSliceSkip()*dstPixelSize;
1218
1219            // Otherwise, copy per row
1220            const size_t rowSize = src.getWidth()*srcPixelSize;
1221            for(size_t z=src.front; z<src.back; z++)
1222            {
1223                for(size_t y=src.top; y<src.bottom; y++)
1224                {
1225                                        memcpy(dstptr, srcptr, rowSize);
1226                    srcptr += srcRowPitchBytes;
1227                    dstptr += dstRowPitchBytes;
1228                }
1229                srcptr += srcSliceSkipBytes;
1230                dstptr += dstSliceSkipBytes;
1231            }
1232            return;
1233        }
1234                // Converting to PF_X8R8G8B8 is exactly the same as converting to
1235                // PF_A8R8G8B8. (same with PF_X8B8G8R8 and PF_A8B8G8R8)
1236                if(dst.format == PF_X8R8G8B8 || dst.format == PF_X8B8G8R8)
1237                {
1238                        // Do the same conversion, with PF_A8R8G8B8, which has a lot of
1239                        // optimized conversions
1240                        PixelBox tempdst = dst;
1241                        tempdst.format = dst.format==PF_X8R8G8B8?PF_A8R8G8B8:PF_A8B8G8R8;
1242                        bulkPixelConversion(src, tempdst);
1243                        return;
1244                }
1245                // Converting from PF_X8R8G8B8 is exactly the same as converting from
1246                // PF_A8R8G8B8, given that the destination format does not have alpha.
1247                if((src.format == PF_X8R8G8B8||src.format == PF_X8B8G8R8) && !hasAlpha(dst.format))
1248                {
1249                        // Do the same conversion, with PF_A8R8G8B8, which has a lot of
1250                        // optimized conversions
1251                        PixelBox tempsrc = src;
1252                        tempsrc.format = src.format==PF_X8R8G8B8?PF_A8R8G8B8:PF_A8B8G8R8;
1253                        bulkPixelConversion(tempsrc, dst);
1254                        return;
1255                }
1256
1257// NB VC6 can't handle the templates required for optimised conversion, tough
1258#if OGRE_COMPILER != OGRE_COMPILER_MSVC || OGRE_COMP_VER >= 1300
1259        // Is there a specialized, inlined, conversion?
1260        if(doOptimizedConversion(src, dst))
1261        {
1262            // If so, good
1263            return;
1264        }
1265#endif
1266
1267        uint8 *srcptr = static_cast<uint8*>(src.data);
1268        uint8 *dstptr = static_cast<uint8*>(dst.data);
1269        const size_t srcPixelSize = PixelUtil::getNumElemBytes(src.format);
1270        const size_t dstPixelSize = PixelUtil::getNumElemBytes(dst.format);
1271
1272        // Calculate pitches+skips in bytes
1273        const size_t srcRowSkipBytes = src.getRowSkip()*srcPixelSize;
1274        const size_t srcSliceSkipBytes = src.getSliceSkip()*srcPixelSize;
1275        const size_t dstRowSkipBytes = dst.getRowSkip()*dstPixelSize;
1276        const size_t dstSliceSkipBytes = dst.getSliceSkip()*dstPixelSize;
1277
1278        // The brute force fallback
1279        float r,g,b,a;
1280        for(size_t z=src.front; z<src.back; z++)
1281        {
1282            for(size_t y=src.top; y<src.bottom; y++)
1283            {
1284                for(size_t x=src.left; x<src.right; x++)
1285                {
1286                    unpackColour(&r, &g, &b, &a, src.format, srcptr);
1287                    packColour(r, g, b, a, dst.format, dstptr);
1288                    srcptr += srcPixelSize;
1289                    dstptr += dstPixelSize;
1290                }
1291                srcptr += srcRowSkipBytes;
1292                dstptr += dstRowSkipBytes;
1293            }
1294            srcptr += srcSliceSkipBytes;
1295            dstptr += dstSliceSkipBytes;
1296        }
1297    }
1298
1299}
Note: See TracBrowser for help on using the repository browser.