root/OpenSceneGraph/trunk/src/osgPlugins/quicktime/ReaderWriterQT.cpp @ 3191

Revision 3191, 7.5 kB (checked in by robert, 10 years ago)

Changes to fix multiple thread start.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#include "osg/Image"
2#include "osg/Notify"
3
4#include <osg/Geode>
5
6#include "osg/GL"
7
8#include "osgDB/FileNameUtils"
9#include "osgDB/Registry"
10#include "osgDB/FileUtils"
11
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15
16#ifndef SEEK_SET
17define SEEK_SET 0
18#endif
19
20#include "QTtexture.h"
21#include "QuicktimeImageStream.h"
22
23using namespace osg;
24
25class ReaderWriterQT : public osgDB::ReaderWriter
26{
27    public:
28        virtual const char* className() { return "Default Quicktime Image Reader/Writer"; }
29       
30        virtual bool acceptsMovieExtension(const std::string& extension)
31        {
32            return osgDB::equalCaseInsensitive(extension,"mov") ||
33                   osgDB::equalCaseInsensitive(extension,"mpg") ||
34                   osgDB::equalCaseInsensitive(extension,"mpv") ||
35                   osgDB::equalCaseInsensitive(extension,"dv");
36        }
37       
38        virtual bool acceptsExtension(const std::string& extension)
39        {
40            // this should be the only image importer required on the Mac
41            // dont know what else it supports, but these will do
42            return osgDB::equalCaseInsensitive(extension,"rgb") ||
43                osgDB::equalCaseInsensitive(extension,"rgba") ||
44                osgDB::equalCaseInsensitive(extension,"jpg") ||
45                osgDB::equalCaseInsensitive(extension,"jpeg") ||
46                osgDB::equalCaseInsensitive(extension,"tiff") ||               
47                osgDB::equalCaseInsensitive(extension,"pict") ||
48                osgDB::equalCaseInsensitive(extension,"gif") ||
49                osgDB::equalCaseInsensitive(extension,"png") ||
50                osgDB::equalCaseInsensitive(extension,"pict") ||
51                osgDB::equalCaseInsensitive(extension,"pct") ||
52                osgDB::equalCaseInsensitive(extension,"tga") ||
53                acceptsMovieExtension(extension);
54        }
55
56        virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options*)
57        {                   
58            std::string ext = osgDB::getLowerCaseFileExtension(file);
59            if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
60
61            std::string fileName = osgDB::findDataFile( file );
62            if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
63               
64            // if the file is a movie file then load as an ImageStream.
65            if (acceptsMovieExtension(ext))
66            {
67                // note from Robert Osfield when integrating, we should probably have so
68                // error handling mechanism here.  Possibly move the load from
69                // the constructor to a seperate load method, and have a valid
70                // state on the ImageStream... will integrated as is right now
71                // to get things off the ground.
72                osg::QuicktimeImageStream* moov = new osg::QuicktimeImageStream(fileName);
73                moov->play();
74                return moov;
75            }
76
77            long origWidth, origHeight,buffWidth,buffHeight,buffDepth,origDepth;
78       
79            // NOTE - implememntation means that this will always return 32 bits, so it is hard to work out if
80            // an image was monochrome. So it will waste texture memory unless it gets a monochrome hint.
81           
82            unsigned char *pixels = LoadBufferFromDarwinPath ( fileName.c_str(), &origWidth,&origHeight,&origDepth,
83                                &buffWidth,&buffHeight,
84                                &buffDepth);
85       
86            // IMPORTANT -
87            // origDepth in BYTES, buffDepth in BITS
88           
89            if (pixels == 0) {
90                    osg::notify(osg::WARN) << "LoadBufferFromDarwinPath failed " << fileName.c_str() << QTfailureMessage() << std::endl;
91                    return 0;
92            }                     
93           
94            unsigned int pixelFormat;
95           
96            switch(origDepth) {
97                case 1 :
98                    pixelFormat = GL_RGB;
99                    break;
100                case 2 :
101                    pixelFormat = GL_LUMINANCE_ALPHA;
102                    break;
103                case 3 :
104                    pixelFormat = GL_RGB;
105                    break;
106                case 4 :
107                    pixelFormat = GL_RGBA;
108                    break;
109                default :
110                    osg::notify(osg::WARN) << "Unknown file type in " << fileName.c_str() << " with " << origDepth << std::endl;
111                    pixelFormat = (GLenum)-1;
112                    return 0;
113                    break;
114            }
115                   
116            {
117                unsigned char *srcp=pixels, *dstp=pixels;
118         
119                int i, j;
120         
121                // swizzle entire image in-place
122                for (i=0; i<buffHeight; i++ ) {
123                    unsigned char r, g, b, a;
124                    switch (origDepth) {
125                    /*
126                        since 8-bit tgas will get expanded into colour, have to use RGB code for 8-bit images
127                   
128                        case 1 :
129                            for (j=0; j<buffWidth; j++ ) {
130                                dstp[0]=srcp[2];
131                                srcp+=4;
132                                dstp++;
133                            }
134                            break;
135                        */
136                        case 2 :
137                            for (j=0; j<buffWidth; j++ ) {
138                                dstp[1]=srcp[0];
139                                dstp[0]=srcp[2];
140                                srcp+=4;
141                                dstp+=2;
142                            }
143                            break;
144                        case 1 :
145                        case 3 :
146                            for (j=0; j<buffWidth; j++ ) {
147                                dstp[0]=srcp[1];
148                                dstp[1]=srcp[2];
149                                dstp[2]=srcp[3];
150                                srcp+=4;
151                                dstp+=3;
152                            }
153                            break;
154                        case 4 :
155                            for (j=0; j<buffWidth; j++ ) {
156                                r=srcp[1];
157                                g=srcp[2];
158                                b=srcp[3];
159                                a=srcp[0];
160                               
161                                dstp[0]=r;
162                                dstp[1]=g;
163                                dstp[2]=b;
164                                dstp[3]=a;
165                               
166                                srcp+=4;
167                                dstp+=4;
168                            }
169                            break;
170                        default :
171                            // osg::notify(osg::WARN) << "ERROR IN RETURNED PIXEL DEPTH, CANNOT COPE" << std::endl;
172                            return 0;
173                            break;
174                    }
175                }
176            }
177
178            Image* image = new Image();
179            image->setFileName(fileName.c_str());
180            image->setImage(buffWidth,buffHeight,1,
181                buffDepth >> 3,
182                pixelFormat,
183                GL_UNSIGNED_BYTE,
184                pixels,
185                osg::Image::USE_NEW_DELETE );
186               
187            notify(INFO) << "image read ok "<<buffWidth<<"  "<<buffHeight<<std::endl;
188            return image;
189        }
190
191};
192
193// now register with Registry to instantiate the above
194// reader/writer.
195osgDB::RegisterReaderWriterProxy<ReaderWriterQT> g_readerWriter_QT_Proxy;
Note: See TracBrowser for help on using the browser.