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

Revision 3329, 7.6 kB (checked in by robert, 10 years ago)

Added .tif extension to handled extension list

  • 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,"tif") ||               
47                osgDB::equalCaseInsensitive(extension,"tiff") ||               
48                osgDB::equalCaseInsensitive(extension,"pict") ||
49                osgDB::equalCaseInsensitive(extension,"gif") ||
50                osgDB::equalCaseInsensitive(extension,"png") ||
51                osgDB::equalCaseInsensitive(extension,"pict") ||
52                osgDB::equalCaseInsensitive(extension,"pct") ||
53                osgDB::equalCaseInsensitive(extension,"tga") ||
54                acceptsMovieExtension(extension);
55        }
56
57        virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options*)
58        {                   
59            std::string ext = osgDB::getLowerCaseFileExtension(file);
60            if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
61
62            std::string fileName = osgDB::findDataFile( file );
63            if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
64               
65            // if the file is a movie file then load as an ImageStream.
66            if (acceptsMovieExtension(ext))
67            {
68                // note from Robert Osfield when integrating, we should probably have so
69                // error handling mechanism here.  Possibly move the load from
70                // the constructor to a seperate load method, and have a valid
71                // state on the ImageStream... will integrated as is right now
72                // to get things off the ground.
73                osg::QuicktimeImageStream* moov = new osg::QuicktimeImageStream(fileName);
74                moov->play();
75                return moov;
76            }
77
78            long origWidth, origHeight,buffWidth,buffHeight,buffDepth,origDepth;
79       
80            // NOTE - implememntation means that this will always return 32 bits, so it is hard to work out if
81            // an image was monochrome. So it will waste texture memory unless it gets a monochrome hint.
82           
83            unsigned char *pixels = LoadBufferFromDarwinPath ( fileName.c_str(), &origWidth,&origHeight,&origDepth,
84                                &buffWidth,&buffHeight,
85                                &buffDepth);
86       
87            // IMPORTANT -
88            // origDepth in BYTES, buffDepth in BITS
89           
90            if (pixels == 0) {
91                    osg::notify(osg::WARN) << "LoadBufferFromDarwinPath failed " << fileName.c_str() << QTfailureMessage() << std::endl;
92                    return 0;
93            }                     
94           
95            unsigned int pixelFormat;
96           
97            switch(origDepth) {
98                case 1 :
99                    pixelFormat = GL_RGB;
100                    break;
101                case 2 :
102                    pixelFormat = GL_LUMINANCE_ALPHA;
103                    break;
104                case 3 :
105                    pixelFormat = GL_RGB;
106                    break;
107                case 4 :
108                    pixelFormat = GL_RGBA;
109                    break;
110                default :
111                    osg::notify(osg::WARN) << "Unknown file type in " << fileName.c_str() << " with " << origDepth << std::endl;
112                    pixelFormat = (GLenum)-1;
113                    return 0;
114                    break;
115            }
116                   
117            {
118                unsigned char *srcp=pixels, *dstp=pixels;
119         
120                int i, j;
121         
122                // swizzle entire image in-place
123                for (i=0; i<buffHeight; i++ ) {
124                    unsigned char r, g, b, a;
125                    switch (origDepth) {
126                    /*
127                        since 8-bit tgas will get expanded into colour, have to use RGB code for 8-bit images
128                   
129                        case 1 :
130                            for (j=0; j<buffWidth; j++ ) {
131                                dstp[0]=srcp[2];
132                                srcp+=4;
133                                dstp++;
134                            }
135                            break;
136                        */
137                        case 2 :
138                            for (j=0; j<buffWidth; j++ ) {
139                                dstp[1]=srcp[0];
140                                dstp[0]=srcp[2];
141                                srcp+=4;
142                                dstp+=2;
143                            }
144                            break;
145                        case 1 :
146                        case 3 :
147                            for (j=0; j<buffWidth; j++ ) {
148                                dstp[0]=srcp[1];
149                                dstp[1]=srcp[2];
150                                dstp[2]=srcp[3];
151                                srcp+=4;
152                                dstp+=3;
153                            }
154                            break;
155                        case 4 :
156                            for (j=0; j<buffWidth; j++ ) {
157                                r=srcp[1];
158                                g=srcp[2];
159                                b=srcp[3];
160                                a=srcp[0];
161                               
162                                dstp[0]=r;
163                                dstp[1]=g;
164                                dstp[2]=b;
165                                dstp[3]=a;
166                               
167                                srcp+=4;
168                                dstp+=4;
169                            }
170                            break;
171                        default :
172                            // osg::notify(osg::WARN) << "ERROR IN RETURNED PIXEL DEPTH, CANNOT COPE" << std::endl;
173                            return 0;
174                            break;
175                    }
176                }
177            }
178
179            Image* image = new Image();
180            image->setFileName(fileName.c_str());
181            image->setImage(buffWidth,buffHeight,1,
182                buffDepth >> 3,
183                pixelFormat,
184                GL_UNSIGNED_BYTE,
185                pixels,
186                osg::Image::USE_NEW_DELETE );
187               
188            notify(INFO) << "image read ok "<<buffWidth<<"  "<<buffHeight<<std::endl;
189            return image;
190        }
191
192};
193
194// now register with Registry to instantiate the above
195// reader/writer.
196osgDB::RegisterReaderWriterProxy<ReaderWriterQT> g_readerWriter_QT_Proxy;
Note: See TracBrowser for help on using the browser.