source: OGRE/trunk/ogrenew/PlugIns/EXRCodec/src/OgreEXRCodec.cpp @ 690

Revision 690, 6.3 KB checked in by mattausch, 18 years ago (diff)

added ogre 1.07 main

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