Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/Tests/OgreMain/src/PixelFormatTests.cpp @ 1

Last change on this file since 1 was 1, checked in by landauf, 17 years ago
File size: 7.6 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 "PixelFormatTests.h"
30#include <cstdlib>
31
32// Register the suite
33CPPUNIT_TEST_SUITE_REGISTRATION( PixelFormatTests );
34
35void PixelFormatTests::setUp()
36{
37    size = 4096;
38    randomData = new uint8[size];
39    temp = new uint8[size];
40    temp2 = new uint8[size];
41    // Generate reproducable random data
42    srand(0);
43    for(unsigned int x=0; x<size; x++)
44        randomData[x] = (uint8)rand();
45}
46
47void PixelFormatTests::tearDown()
48{
49    delete [] randomData;
50    delete [] temp;
51    delete [] temp2;
52}
53
54
55void PixelFormatTests::testIntegerPackUnpack()
56{
57
58}
59
60void PixelFormatTests::testFloatPackUnpack()
61{
62    // Float32
63    float data[4] = {1.0f, 2.0f, 3.0f, 4.0f};
64    float r,g,b,a;
65    PixelUtil::unpackColour(&r, &g, &b, &a, PF_FLOAT32_RGBA, data);
66    CPPUNIT_ASSERT_EQUAL(r, 1.0f);
67    CPPUNIT_ASSERT_EQUAL(g, 2.0f);
68    CPPUNIT_ASSERT_EQUAL(b, 3.0f);
69    CPPUNIT_ASSERT_EQUAL(a, 4.0f);
70
71    // Float16
72    setupBoxes(PF_A8B8G8R8, PF_FLOAT16_RGBA);
73    dst2.format = PF_A8B8G8R8;
74    unsigned int eob = src.getWidth()*4;
75
76    PixelUtil::bulkPixelConversion(src, dst1);
77    PixelUtil::bulkPixelConversion(dst1, dst2);
78
79    // Locate errors
80    std::stringstream s;
81    int x;
82    for(x=0; x<eob; x++) {
83        if(temp2[x] != randomData[x])
84            s << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) randomData[x]
85              << "!= " << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) temp2[x] << " ";
86    }
87
88    // src and dst2 should match
89    CPPUNIT_ASSERT_MESSAGE("PF_FLOAT16_RGBA<->PF_A8B8G8R8 conversion was not lossless "+s.str(),
90        memcmp(src.data, dst2.data, eob) == 0);
91}
92
93// Pure 32 bit float precision brute force pixel conversion; for comparision
94void naiveBulkPixelConversion(const PixelBox &src, const PixelBox &dst)
95{
96    uint8 *srcptr = static_cast<uint8*>(src.data);
97    uint8 *dstptr = static_cast<uint8*>(dst.data);
98    unsigned int srcPixelSize = PixelUtil::getNumElemBytes(src.format);
99    unsigned int dstPixelSize = PixelUtil::getNumElemBytes(dst.format);
100
101    // Calculate pitches+skips in bytes
102    int srcRowSkipBytes = src.getRowSkip()*srcPixelSize;
103    int srcSliceSkipBytes = src.getSliceSkip()*srcPixelSize;
104
105    int dstRowSkipBytes = dst.getRowSkip()*dstPixelSize;
106    int dstSliceSkipBytes = dst.getSliceSkip()*dstPixelSize;
107
108        // The brute force fallback
109        float r,g,b,a;
110        for(size_t z=src.front; z<src.back; z++)
111        {
112                for(size_t y=src.top; y<src.bottom; y++)
113                {
114                        for(size_t x=src.left; x<src.right; x++)
115                        {
116                                PixelUtil::unpackColour(&r, &g, &b, &a, src.format, srcptr);
117                                PixelUtil::packColour(r, g, b, a, dst.format, dstptr);
118                                srcptr += srcPixelSize;
119                                dstptr += dstPixelSize;
120                        }
121                        srcptr += srcRowSkipBytes;
122                        dstptr += dstRowSkipBytes;
123                }
124                srcptr += srcSliceSkipBytes;
125                dstptr += dstSliceSkipBytes;
126        }
127
128}
129
130void PixelFormatTests::setupBoxes(PixelFormat srcFormat, PixelFormat dstFormat)
131{
132    unsigned int width = (size-4) / PixelUtil::getNumElemBytes(srcFormat);
133    unsigned int width2 = (size-4) / PixelUtil::getNumElemBytes(dstFormat);
134    if(width > width2)
135        width = width2;
136
137    src = PixelBox(width, 1, 1, srcFormat, randomData);
138        dst1 = PixelBox(width, 1, 1, dstFormat, temp);
139        dst2 = PixelBox(width, 1, 1, dstFormat, temp2);
140
141}
142
143void PixelFormatTests::testCase(PixelFormat srcFormat, PixelFormat dstFormat)
144{
145    setupBoxes(srcFormat, dstFormat);
146    // Check end of buffer
147    unsigned int eob = dst1.getWidth()*PixelUtil::getNumElemBytes(dstFormat);
148    temp[eob] = (unsigned char)0x56;
149    temp[eob+1] = (unsigned char)0x23;
150
151    //std::cerr << "["+PixelUtil::getFormatName(srcFormat)+"->"+PixelUtil::getFormatName(dstFormat)+"]" << " " << eob << std::endl;
152
153    // Do pack/unpacking with both naive and optimized version
154    PixelUtil::bulkPixelConversion(src, dst1);
155    naiveBulkPixelConversion(src, dst2);
156
157    CPPUNIT_ASSERT_EQUAL(temp[eob], (unsigned char)0x56);
158    CPPUNIT_ASSERT_EQUAL(temp[eob+1], (unsigned char)0x23);
159
160    std::stringstream s;
161    int x;
162    s << "src=";
163    for(x=0; x<16; x++)
164        s << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) randomData[x];
165    s << " dst=";
166    for(x=0; x<16; x++)
167        s << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) temp[x];
168    s << " dstRef=";
169    for(x=0; x<16; x++)
170        s << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) temp2[x];
171    s << " ";
172
173    // Compare result
174    CPPUNIT_ASSERT_MESSAGE("Conversion mismatch ["+PixelUtil::getFormatName(srcFormat)+"->"+PixelUtil::getFormatName(dstFormat)+"] "+s.str(),
175        memcmp(dst1.data, dst2.data, eob) == 0);
176}
177
178void PixelFormatTests::testBulkConversion()
179{
180    // Self match
181    testCase(PF_A8R8G8B8, PF_A8R8G8B8);
182    // Optimized
183        testCase(PF_A8R8G8B8,PF_A8B8G8R8);
184        testCase(PF_A8R8G8B8,PF_B8G8R8A8);
185        testCase(PF_A8R8G8B8,PF_R8G8B8A8);
186        testCase(PF_A8B8G8R8,PF_A8R8G8B8);
187        testCase(PF_A8B8G8R8,PF_B8G8R8A8);
188        testCase(PF_A8B8G8R8,PF_R8G8B8A8);
189        testCase(PF_B8G8R8A8,PF_A8R8G8B8);
190        testCase(PF_B8G8R8A8,PF_A8B8G8R8);
191        testCase(PF_B8G8R8A8,PF_R8G8B8A8);
192        testCase(PF_R8G8B8A8,PF_A8R8G8B8);
193        testCase(PF_R8G8B8A8,PF_A8B8G8R8);
194        testCase(PF_R8G8B8A8,PF_B8G8R8A8);
195
196    testCase(PF_A8B8G8R8, PF_L8);
197    testCase(PF_L8, PF_A8B8G8R8);
198    testCase(PF_A8R8G8B8, PF_L8);
199    testCase(PF_L8, PF_A8R8G8B8);
200    testCase(PF_B8G8R8A8, PF_L8);
201    testCase(PF_L8, PF_B8G8R8A8);
202    testCase(PF_L8, PF_L16);
203    testCase(PF_L16, PF_L8);
204    testCase(PF_R8G8B8, PF_B8G8R8);
205    testCase(PF_B8G8R8, PF_R8G8B8);
206    testCase(PF_B8G8R8, PF_R8G8B8);
207    testCase(PF_R8G8B8, PF_B8G8R8);
208    testCase(PF_R8G8B8, PF_A8R8G8B8);
209    testCase(PF_B8G8R8, PF_A8R8G8B8);
210    testCase(PF_R8G8B8, PF_A8B8G8R8);
211    testCase(PF_B8G8R8, PF_A8B8G8R8);
212    testCase(PF_R8G8B8, PF_B8G8R8A8);
213    testCase(PF_B8G8R8, PF_B8G8R8A8);
214        testCase(PF_A8R8G8B8, PF_R8G8B8);
215        testCase(PF_A8R8G8B8, PF_B8G8R8);
216        testCase(PF_X8R8G8B8, PF_A8R8G8B8);
217        testCase(PF_X8R8G8B8, PF_A8B8G8R8);
218        testCase(PF_X8R8G8B8, PF_B8G8R8A8);
219        testCase(PF_X8R8G8B8, PF_R8G8B8A8);
220        testCase(PF_X8B8G8R8, PF_A8R8G8B8);
221        testCase(PF_X8B8G8R8, PF_A8B8G8R8);
222        testCase(PF_X8B8G8R8, PF_B8G8R8A8);
223        testCase(PF_X8B8G8R8, PF_R8G8B8A8);
224
225    //CPPUNIT_ASSERT_MESSAGE("Conversion mismatch", false);
226}
227
Note: See TracBrowser for help on using the repository browser.