Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/PlugIns/EXRCodec/src/OgreEXRCodec.cpp @ 3

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

=update

File size: 6.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
31#include "OgreRoot.h"
32#include "OgreLogManager.h"
33#include "OgreImage.h"
34#include "OgreException.h"
35
36#include "OgreEXRCodec.h"
37
38#include "O_IStream.h"
39
40#include <cmath>
41#include <ImfOutputFile.h>
42#include <ImfInputFile.h>
43#include <ImfChannelList.h>
44#include <ImfStringAttribute.h>
45#include <ImfMatrixAttribute.h>
46#include <ImfArray.h>
47
48using namespace Imath;
49using namespace Imf;
50
51namespace Ogre {
52
53void writeEXRHalf(OStream *ost, const float *pixels,
54              int width, int height, int components) 
55{
56        //assert(components==3 || components==4);
57        // TODO: throw std::exception if invalid number of components
58
59        Header header (width, height);
60        header.channels().insert ("R", Channel (HALF));
61        header.channels().insert ("G", Channel (HALF));
62        header.channels().insert ("B", Channel (HALF));
63        if(components==4)
64                header.channels().insert ("A", Channel (HALF));
65
66        // Convert data to half
67        half *data = new half [width*height*components];
68       
69        std::copy(pixels, pixels+(width*height*components), data);
70       
71        // And save it
72        OutputFile file (*ost, header);
73        FrameBuffer frameBuffer;
74
75        frameBuffer.insert("R",                         // name
76                            Slice (HALF,                // type
77                                   ((char *) data)+0,   // base
78                                   2 * components,              // xStride
79                                   2 * components * width));    // yStride
80        frameBuffer.insert("G",                         // name
81                            Slice (HALF,                // type
82                                   ((char *) data)+2,   // base
83                                   2 * components,              // xStride
84                                   2 * components * width));    // yStride
85        frameBuffer.insert("B",                         // name
86                            Slice (HALF,                // type
87                                   ((char *) data)+4,   // base
88                                   2 * components,              // xStride
89                                   2 * components * width));    // yStride
90        if(components==4) {
91                frameBuffer.insert("A",                                 // name
92                                    Slice (HALF,                        // type
93                                           ((char *) data)+6,           // base
94                                           2 * components,              // xStride
95                                           2 * components * width));    // yStride
96        }
97
98        file.setFrameBuffer(frameBuffer);
99        file.writePixels(height);
100        delete data;
101}
102
103
104EXRCodec::EXRCodec() 
105{
106    LogManager::getSingleton().logMessage("EXRCodec initialised");
107}
108EXRCodec::~EXRCodec() 
109{
110    LogManager::getSingleton().logMessage("EXRCodec deinitialised");
111}
112
113DataStreamPtr EXRCodec::code(MemoryDataStreamPtr& input, CodecDataPtr& pData) const
114{
115
116}
117
118Codec::DecodeResult EXRCodec::decode(DataStreamPtr& input) const
119{
120    ImageData * imgData = new ImageData;
121    MemoryDataStreamPtr output;
122
123    try {
124        // Make a mutable clone of input to be able to change file pointer
125        MemoryDataStream myIn(input);
126   
127        // Now we can simulate an OpenEXR file with that
128        O_IStream str(myIn, "SomeChunk.exr");
129        InputFile file(str);
130   
131        Box2i dw = file.header().dataWindow();
132        int width  = dw.max.x - dw.min.x + 1;
133        int height = dw.max.y - dw.min.y + 1;
134        int components = 3;
135   
136        // Alpha channel present?
137        const ChannelList &channels = file.header().channels();
138        if(channels.findChannel("A"))
139            components = 4;
140       
141        // Allocate memory
142        output.bind(new MemoryDataStream(width*height*components*4));
143   
144        // Construct frame buffer
145        uchar *pixels = output->getPtr();
146        FrameBuffer frameBuffer;
147        frameBuffer.insert("R",             // name
148                    Slice (FLOAT,       // type
149                       ((char *) pixels)+0, // base
150                       4 * components,      // xStride
151                    4 * components * width));    // yStride
152        frameBuffer.insert("G",             // name
153                    Slice (FLOAT,       // type
154                       ((char *) pixels)+4, // base
155                       4 * components,      // xStride
156                    4 * components * width));    // yStride
157        frameBuffer.insert("B",             // name
158                    Slice (FLOAT,       // type
159                       ((char *) pixels)+8, // base
160                       4 * components,      // xStride
161                    4 * components * width));    // yStride
162        if(components==4) {
163            frameBuffer.insert("A",                 // name
164                        Slice (FLOAT,           // type
165                           ((char *) pixels)+12,        // base
166                           4 * components,      // xStride
167                        4 * components * width));    // yStride
168        }
169     
170        file.setFrameBuffer (frameBuffer);
171        file.readPixels (dw.min.y, dw.max.y);
172   
173        imgData->format = components==3 ? PF_FLOAT32_RGB : PF_FLOAT32_RGBA;
174        imgData->width = width;
175        imgData->height = height;
176        imgData->depth = 1;
177        imgData->size = width*height*components*4;
178        imgData->num_mipmaps = 0;
179        imgData->flags = 0;
180    } catch (const std::exception &exc) {
181        delete imgData;
182        throw(Exception(Exception::ERR_INTERNAL_ERROR,
183            "OpenEXR Error",
184            exc.what()));
185    }
186   
187    DecodeResult ret;
188    ret.first = output; 
189    ret.second = CodecDataPtr(imgData);
190    return ret;
191}
192
193void EXRCodec::codeToFile(MemoryDataStreamPtr& input, const String& outFileName, CodecDataPtr& pData) const
194{
195
196}
197
198
199String EXRCodec::getType() const 
200{
201    return "exr";
202}
203
204
205
206}
Note: See TracBrowser for help on using the repository browser.