root/OpenSceneGraph/trunk/src/osgPlugins/gdal/ReaderWriterGDAL.cpp @ 13041

Revision 13041, 35.9 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2007 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14
15
16#include <osg/Image>
17#include <osg/Notify>
18#include <osg/Geode>
19#include <osg/GL>
20
21#include <osgDB/Registry>
22#include <osgDB/FileNameUtils>
23#include <osgDB/FileUtils>
24#include <osgDB/ImageOptions>
25
26#include <OpenThreads/ScopedLock>
27#include <OpenThreads/ReentrantMutex>
28
29#include <memory>
30
31#include <gdal_priv.h>
32
33#include "DataSetLayer.h"
34
35#define SERIALIZER() OpenThreads::ScopedLock<OpenThreads::ReentrantMutex> lock(_serializerMutex)
36
37// From easyrgb.com
38float Hue_2_RGB( float v1, float v2, float vH )
39{
40   if ( vH < 0 ) vH += 1;
41   if ( vH > 1 ) vH -= 1;
42   if ( ( 6 * vH ) < 1 ) return ( v1 + ( v2 - v1 ) * 6 * vH );
43   if ( ( 2 * vH ) < 1 ) return ( v2 );
44   if ( ( 3 * vH ) < 2 ) return ( v1 + ( v2 - v1 ) * ( ( 2 / 3 ) - vH ) * 6 );
45   return ( v1 );
46}
47
48class ReaderWriterGDAL : public osgDB::ReaderWriter
49{
50    public:
51
52        ReaderWriterGDAL()
53        {
54            supportsExtension("gdal","GDAL Image reader");
55        }
56
57        virtual const char* className() const { return "GDAL Image Reader"; }
58
59        virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options) const
60        {
61            if (file.empty()) return ReadResult::FILE_NOT_FOUND;
62
63            if (osgDB::equalCaseInsensitive(osgDB::getFileExtension(file),"gdal"))
64            {
65                return readObject(osgDB::getNameLessExtension(file),options);
66            }
67
68            OpenThreads::ScopedLock<OpenThreads::ReentrantMutex> lock(_serializerMutex);
69
70            std::string fileName = osgDB::findDataFile( file, options );
71            if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
72
73            initGDAL();
74
75            // open a DataSetLayer.
76            osg::ref_ptr<GDALPlugin::DataSetLayer> dataset = new GDALPlugin::DataSetLayer(fileName);
77            dataset->setGdalReader(this);
78
79            if (dataset->isOpen()) return dataset.release();
80
81            return ReadResult::FILE_NOT_HANDLED;
82        }
83
84        virtual ReadResult readImage(const std::string& fileName, const osgDB::ReaderWriter::Options* options) const
85        {
86            if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
87
88            if (osgDB::equalCaseInsensitive(osgDB::getFileExtension(fileName),"gdal"))
89            {
90                return readImage(osgDB::getNameLessExtension(fileName),options);
91            }
92
93            OpenThreads::ScopedLock<OpenThreads::ReentrantMutex> lock(_serializerMutex);
94            return const_cast<ReaderWriterGDAL*>(this)->local_readImage(fileName, options);
95        }
96
97        virtual ReadResult readHeightField(const std::string& fileName, const osgDB::ReaderWriter::Options* options) const
98        {
99            if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
100
101            if (osgDB::equalCaseInsensitive(osgDB::getFileExtension(fileName),"gdal"))
102            {
103                return readHeightField(osgDB::getNameLessExtension(fileName),options);
104            }
105
106            OpenThreads::ScopedLock<OpenThreads::ReentrantMutex> lock(_serializerMutex);
107            return const_cast<ReaderWriterGDAL*>(this)->local_readHeightField(fileName, options);
108        }
109
110        virtual ReadResult local_readImage(const std::string& file, const osgDB::ReaderWriter::Options* options)
111        {
112            // Looks like gdal's GDALRasterBand::GetColorInterpretation()
113            // is not giving proper values for ecw images. There is small
114            // hack to get around
115            bool ecwLoad = osgDB::equalCaseInsensitive(osgDB::getFileExtension(file),"ecw");
116
117            //if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
118
119            OSG_INFO << "GDAL : " << file << std::endl;
120
121            std::string fileName = osgDB::findDataFile( file, options );
122            if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
123
124            initGDAL();
125
126            std::auto_ptr<GDALDataset> dataset((GDALDataset*)GDALOpen(fileName.c_str(),GA_ReadOnly));
127            if (!dataset.get()) return ReadResult::FILE_NOT_HANDLED;
128
129            int dataWidth = dataset->GetRasterXSize();
130            int dataHeight = dataset->GetRasterYSize();
131
132            int windowX = 0;
133            int windowY = 0;
134            int windowWidth = dataWidth;
135            int windowHeight = dataHeight;
136
137            int destX = 0;
138            int destY = 0;
139            int destWidth = osg::minimum(dataWidth,4096);
140            int destHeight = osg::minimum(dataHeight,4096);
141//             int destWidth = osg::minimum(dataWidth,4096);
142//             int destHeight = osg::minimum(dataHeight,4096);
143
144
145            osgDB::ImageOptions::TexCoordRange* texCoordRange = 0;
146
147            osgDB::ImageOptions* imageOptions = dynamic_cast<osgDB::ImageOptions*>(const_cast<osgDB::ReaderWriter::Options*>(options));
148            if (imageOptions)
149            {
150                OSG_INFO<<"Got ImageOptions"<<std::endl;
151
152                int margin = 0;
153                switch(imageOptions->_sourceImageWindowMode)
154                {
155                case(osgDB::ImageOptions::RATIO_WINDOW):
156                    {
157                        double desiredX = (double)dataWidth * imageOptions->_sourceRatioWindow.windowX;
158                        double desiredY = (double)dataHeight * imageOptions->_sourceRatioWindow.windowY;
159                        double desiredWidth = (double)dataWidth * imageOptions->_sourceRatioWindow.windowWidth;
160                        double desiredHeight = (double)dataHeight * imageOptions->_sourceRatioWindow.windowHeight;
161
162                        windowX = osg::maximum((int)(floor(desiredX))-margin,0);
163                        windowY = osg::maximum((int)(floor(desiredY))-margin,0);
164                        windowWidth = osg::minimum((int)(ceil(desiredX + desiredWidth))+margin,dataWidth)-windowX;
165                        windowHeight = osg::minimum((int)(ceil(desiredY + desiredHeight))+margin,dataHeight)-windowY;
166
167                        texCoordRange = new osgDB::ImageOptions::TexCoordRange;
168                        texCoordRange->set((desiredX-(double)windowX)/(double)windowWidth,
169                                           ((double)(windowY+windowHeight) -(desiredY+desiredHeight))/(double)windowHeight,
170                                           (desiredWidth)/(double)windowWidth,
171                                           (desiredHeight)/(double)windowHeight);
172                        OSG_INFO<<"tex coord range "<<texCoordRange->_x<<" "<<texCoordRange->_y<<" "<<texCoordRange->_w<<" "<<texCoordRange->_h<<std::endl;
173                    }
174                    break;
175                case(osgDB::ImageOptions::PIXEL_WINDOW):
176                    windowX = imageOptions->_sourcePixelWindow.windowX;
177                    windowY = imageOptions->_sourcePixelWindow.windowY;
178                    windowWidth = imageOptions->_sourcePixelWindow.windowWidth;
179                    windowHeight = imageOptions->_sourcePixelWindow.windowHeight;
180                    break;
181                default:
182                    // leave source window dimensions as whole image.
183                    break;
184                }
185
186                // reapply the window coords to the pixel window so that calling code
187                // knows the original pixel size
188                imageOptions->_sourcePixelWindow.windowX = windowX;
189                imageOptions->_sourcePixelWindow.windowY = windowY;
190                imageOptions->_sourcePixelWindow.windowWidth = windowWidth;
191                imageOptions->_sourcePixelWindow.windowHeight = windowHeight;
192
193                switch(imageOptions->_destinationImageWindowMode)
194                {
195                case(osgDB::ImageOptions::RATIO_WINDOW):
196                    destX = (unsigned int)(floor((double)dataWidth * imageOptions->_destinationRatioWindow.windowX));
197                    destY = (unsigned int)(floor((double)dataHeight * imageOptions->_destinationRatioWindow.windowY));
198                    destWidth = (unsigned int)(ceil((double)dataWidth * (imageOptions->_destinationRatioWindow.windowX + imageOptions->_destinationRatioWindow.windowWidth)))-windowX;
199                    destHeight = (unsigned int)(ceil((double)dataHeight * (imageOptions->_destinationRatioWindow.windowY + imageOptions->_destinationRatioWindow.windowHeight)))-windowY;
200                    break;
201                case(osgDB::ImageOptions::PIXEL_WINDOW):
202                    destX = imageOptions->_destinationPixelWindow.windowX;
203                    destY = imageOptions->_destinationPixelWindow.windowY;
204                    destWidth = imageOptions->_destinationPixelWindow.windowWidth;
205                    destHeight = imageOptions->_destinationPixelWindow.windowHeight;
206                    break;
207                default:
208                    // leave source window dimensions as whole image.
209                    break;
210                }
211
212            }
213
214//             windowX =     0;
215//             windowY =     0;
216//            windowWidth = destWidth;
217//            windowHeight = destHeight;
218
219            OSG_INFO << "    windowX = "<<windowX<<std::endl;
220            OSG_INFO << "    windowY = "<<windowY<<std::endl;
221            OSG_INFO << "    windowWidth = "<<windowWidth<<std::endl;
222            OSG_INFO << "    windowHeight = "<<windowHeight<<std::endl;
223
224            OSG_INFO << std::endl;
225
226            OSG_INFO << "    destX = "<<destX<<std::endl;
227            OSG_INFO << "    destY = "<<destY<<std::endl;
228            OSG_INFO << "    destWidth = "<<destWidth<<std::endl;
229            OSG_INFO << "    destHeight = "<<destHeight<<std::endl;
230
231            OSG_INFO << std::endl;
232
233            OSG_INFO << "    GetRaterCount() "<< dataset->GetRasterCount()<<std::endl;
234            OSG_INFO << "    GetProjectionRef() "<< dataset->GetProjectionRef()<<std::endl;
235
236
237            double geoTransform[6];
238            if (dataset->GetGeoTransform(geoTransform)==CE_None)
239            {
240                OSG_INFO << "    GetGeoTransform "<< std::endl;
241                OSG_INFO << "        Origin = "<<geoTransform[0]<<" "<<geoTransform[3]<<std::endl;
242                OSG_INFO << "        Pixel X = "<<geoTransform[1]<<" "<<geoTransform[4]<<std::endl;
243                OSG_INFO << "        Pixel Y = "<<geoTransform[2]<<" "<<geoTransform[5]<<std::endl;
244            }
245
246            int numBands = dataset->GetRasterCount();
247
248
249            GDALRasterBand* bandGray = 0;
250            GDALRasterBand* bandRed = 0;
251            GDALRasterBand* bandGreen = 0;
252            GDALRasterBand* bandBlue = 0;
253            GDALRasterBand* bandAlpha = 0;
254            GDALRasterBand* bandPalette = 0;
255
256            int internalFormat = GL_LUMINANCE;
257            unsigned int pixelFormat = GL_LUMINANCE;
258            unsigned int dataType = 0;
259            unsigned int numBytesPerPixel = 0;
260
261            GDALDataType targetGDALType = GDT_Byte;
262
263            for(int b=1;b<=numBands;++b)
264            {
265
266                GDALRasterBand* band = dataset->GetRasterBand(b);
267
268                OSG_INFO << "    Band "<<b<<std::endl;
269
270                OSG_INFO << "        GetOverviewCount() = "<< band->GetOverviewCount()<<std::endl;
271                OSG_INFO << "        GetColorTable() = "<< band->GetColorTable()<<std::endl;
272                OSG_INFO << "        DataTypeName() = "<< GDALGetDataTypeName(band->GetRasterDataType())<<std::endl;
273                OSG_INFO << "        ColorIntepretationName() = "<< GDALGetColorInterpretationName(band->GetColorInterpretation())<<std::endl;
274
275                bool bandNotHandled = true;
276                if (ecwLoad)
277                {
278                    bandNotHandled = false;
279                    switch (b)
280                    {
281                    case 1:
282                        bandRed = band;
283                        break;
284                    case 2:
285                        bandGreen = band;
286                        break;
287                    case 3:
288                        bandBlue = band;
289                        break;
290                    default:
291                        bandNotHandled = true;
292                    }
293                }
294
295                if (bandNotHandled)
296                {
297                    if (band->GetColorInterpretation()==GCI_GrayIndex) bandGray = band;
298                    else if (band->GetColorInterpretation()==GCI_RedBand) bandRed = band;
299                    else if (band->GetColorInterpretation()==GCI_GreenBand) bandGreen = band;
300                    else if (band->GetColorInterpretation()==GCI_BlueBand) bandBlue = band;
301                    else if (band->GetColorInterpretation()==GCI_AlphaBand) bandAlpha = band;
302                    else if (band->GetColorInterpretation()==GCI_PaletteIndex) bandPalette = band;
303                    else bandGray = band;
304                }
305
306                if (bandPalette)
307                {
308                    OSG_INFO << "        Palette Interpretation: " << GDALGetPaletteInterpretationName(band->GetColorTable()->GetPaletteInterpretation()) << std::endl;
309                }
310
311//                 int gotMin,gotMax;
312//                 double minmax[2];
313//
314//                 minmax[0] = band->GetMinimum(&gotMin);
315//                 minmax[1] = band->GetMaximum(&gotMax);
316//                 if (!(gotMin && gotMax))
317//                 {
318//                     OSG_INFO<<" computing min max"<<std::endl;
319//                     GDALComputeRasterMinMax(band,TRUE,minmax);
320//                 }
321//
322//                 OSG_INFO << "        min "<<minmax[0]<<std::endl;
323//                 OSG_INFO << "        max "<<minmax[1]<<std::endl;
324
325                if (dataType==0)
326                {
327                    targetGDALType = band->GetRasterDataType();
328                    switch(band->GetRasterDataType())
329                    {
330                      case(GDT_Byte): dataType = GL_UNSIGNED_BYTE; numBytesPerPixel = 1; break;
331                      case(GDT_UInt16): dataType = GL_UNSIGNED_SHORT; numBytesPerPixel = 2; break;
332                      case(GDT_Int16): dataType = GL_SHORT; numBytesPerPixel = 2; break;
333                      case(GDT_UInt32): dataType = GL_UNSIGNED_INT; numBytesPerPixel = 4; break;
334                      case(GDT_Int32): dataType = GL_INT; numBytesPerPixel = 4; break;
335                      case(GDT_Float32): dataType = GL_FLOAT; numBytesPerPixel = 4; break;
336                      case(GDT_Float64): dataType = GL_DOUBLE; numBytesPerPixel = 8; break// not handled
337                      default: dataType = 0; numBytesPerPixel = 0; break; // not handled
338                    }
339                }
340            }
341
342
343            int s = destWidth;
344            int t = destHeight;
345            int r = 1;
346
347
348            if (dataType==0)
349            {
350                dataType = GL_UNSIGNED_BYTE;
351                numBytesPerPixel = 1;
352                targetGDALType = GDT_Byte;
353            }
354
355            unsigned char* imageData = 0;
356
357            if (bandRed && bandGreen && bandBlue)
358            {
359                if (bandAlpha)
360                {
361                    // RGBA
362
363                    int pixelSpace=4*numBytesPerPixel;
364                    int lineSpace=destWidth * pixelSpace;
365
366                    imageData = new unsigned char[destWidth * destHeight * pixelSpace];
367                    pixelFormat = GL_RGBA;
368                    internalFormat = GL_RGBA;
369
370                    OSG_INFO << "reading RGBA"<<std::endl;
371
372                    bandRed->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+0),destWidth,destHeight,targetGDALType,pixelSpace,lineSpace);
373                    bandGreen->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+1),destWidth,destHeight,targetGDALType,pixelSpace,lineSpace);
374                    bandBlue->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+2),destWidth,destHeight,targetGDALType,pixelSpace,lineSpace);
375                    bandAlpha->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+3),destWidth,destHeight,targetGDALType,pixelSpace,lineSpace);
376
377                }
378                else
379                {
380                    // RGB
381
382                    int pixelSpace=3*numBytesPerPixel;
383                    int lineSpace=destWidth * pixelSpace;
384
385                    imageData = new unsigned char[destWidth * destHeight * pixelSpace];
386                    pixelFormat = GL_RGB;
387                    internalFormat = GL_RGB;
388
389                    OSG_INFO << "reading RGB"<<std::endl;
390
391                    bandRed->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+0),destWidth,destHeight,targetGDALType,pixelSpace,lineSpace);
392                    bandGreen->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+1),destWidth,destHeight,targetGDALType,pixelSpace,lineSpace);
393                    bandBlue->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+2),destWidth,destHeight,targetGDALType,pixelSpace,lineSpace);
394
395                }
396            }
397            else if (bandGray)
398            {
399                if (bandAlpha)
400                {
401                    // Luminance alpha
402                    int pixelSpace=2*numBytesPerPixel;
403                    int lineSpace=destWidth * pixelSpace;
404
405                    imageData = new unsigned char[destWidth * destHeight * pixelSpace];
406                    pixelFormat = GL_LUMINANCE_ALPHA;
407                    internalFormat = GL_LUMINANCE_ALPHA;
408
409                    OSG_INFO << "reading grey + alpha"<<std::endl;
410
411                    bandGray->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+0),destWidth,destHeight,targetGDALType,pixelSpace,lineSpace);
412                    bandAlpha->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+1),destWidth,destHeight,targetGDALType,pixelSpace,lineSpace);
413                }
414                else
415                {
416                    // Luminance map
417                    int pixelSpace=1*numBytesPerPixel;
418                    int lineSpace=destWidth * pixelSpace;
419
420                    imageData = new unsigned char[destWidth * destHeight * pixelSpace];
421                    pixelFormat = GL_LUMINANCE;
422                    internalFormat = GL_LUMINANCE;
423
424                    OSG_INFO << "reading grey"<<std::endl;
425
426                    bandGray->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+0),destWidth,destHeight,targetGDALType,pixelSpace,lineSpace);
427                }
428            }
429            else if (bandAlpha)
430            {
431                // alpha map
432                int pixelSpace=1*numBytesPerPixel;
433                int lineSpace=destWidth * pixelSpace;
434
435                imageData = new unsigned char[destWidth * destHeight * pixelSpace];
436                pixelFormat = GL_ALPHA;
437                internalFormat = GL_ALPHA;
438
439                OSG_INFO << "reading alpha"<<std::endl;
440
441                bandAlpha->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(imageData+0),destWidth,destHeight,targetGDALType,pixelSpace,lineSpace);
442
443            }
444            else if (bandPalette)
445            {
446                // Paletted map
447                int pixelSpace=1*numBytesPerPixel;
448                int lineSpace=destWidth * pixelSpace;
449
450                unsigned char *rawImageData;
451                rawImageData = new unsigned char[destWidth * destHeight * pixelSpace];
452                imageData = new unsigned char[destWidth * destHeight * 4/*RGBA*/];
453                pixelFormat = GL_RGBA;
454                internalFormat = GL_RGBA;
455
456                OSG_INFO << "reading palette"<<std::endl;
457                OSG_INFO << "numBytesPerPixel: " << numBytesPerPixel << std::endl;
458
459                bandPalette->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(rawImageData),destWidth,destHeight,targetGDALType,pixelSpace,lineSpace);
460
461                // Map the indexes to an actual RGBA Value.
462                for (int i = 0; i < destWidth * destHeight; i++)
463                {
464                    const GDALColorEntry *colorEntry = bandPalette->GetColorTable()->GetColorEntry(rawImageData[i]);
465                    GDALPaletteInterp interp = bandPalette->GetColorTable()->GetPaletteInterpretation();
466                    if (!colorEntry)
467                    {
468                        //FIXME: What to do here?
469
470                        //OSG_INFO << "NO COLOR ENTRY FOR COLOR " << rawImageData[i] << std::endl;
471                        imageData[4*i+0] = 255;
472                        imageData[4*i+1] = 0;
473                        imageData[4*i+2] = 0;
474                        imageData[4*i+3] = 1;
475
476                    }
477                    else
478                    {
479                        if (interp == GPI_RGB)
480                        {
481                            imageData[4*i+0] = colorEntry->c1;
482                            imageData[4*i+1] = colorEntry->c2;
483                            imageData[4*i+2] = colorEntry->c3;
484                            imageData[4*i+3] = colorEntry->c4;
485                        }
486                        else if (interp == GPI_CMYK)
487                        {
488                            // from wikipedia.org
489                            short C = colorEntry->c1;
490                            short M = colorEntry->c2;
491                            short Y = colorEntry->c3;
492                            short K = colorEntry->c4;
493                            imageData[4*i+0] = 255 - C*(255 - K) - K;
494                            imageData[4*i+1] = 255 - M*(255 - K) - K;
495                            imageData[4*i+2] = 255 - Y*(255 - K) - K;
496                            imageData[4*i+3] = 255;
497                        }
498                        else if (interp == GPI_HLS)
499                        {
500                            // from easyrgb.com
501                            float H = colorEntry->c1;
502                            float S = colorEntry->c3;
503                            float L = colorEntry->c2;
504                            float R, G, B;
505                            if ( S == 0 )                       //HSL values = 0 - 1
506                            {
507                                R = L;                      //RGB results = 0 - 1
508                                G = L;
509                                B = L;
510                            }
511                            else
512                            {
513                                float var_2, var_1;
514                                if ( L < 0.5 )
515                                    var_2 = L * ( 1 + S );
516                                else
517                                    var_2 = ( L + S ) - ( S * L );
518
519                                var_1 = 2 * L - var_2;
520
521                                R = Hue_2_RGB( var_1, var_2, H + ( 1 / 3 ) );
522                                G = Hue_2_RGB( var_1, var_2, H );
523                                B = Hue_2_RGB( var_1, var_2, H - ( 1 / 3 ) );
524                            }
525                            imageData[4*i+0] = static_cast<unsigned char>(R*255.0f);
526                            imageData[4*i+1] = static_cast<unsigned char>(G*255.0f);
527                            imageData[4*i+2] = static_cast<unsigned char>(B*255.0f);
528                            imageData[4*i+3] = static_cast<unsigned char>(255.0f);
529                        }
530                        else if (interp == GPI_Gray)
531                        {
532                            imageData[4*i+0] = static_cast<unsigned char>(colorEntry->c1*255.0f);
533                            imageData[4*i+1] = static_cast<unsigned char>(colorEntry->c1*255.0f);
534                            imageData[4*i+2] = static_cast<unsigned char>(colorEntry->c1*255.0f);
535                            imageData[4*i+3] = static_cast<unsigned char>(255.0f);
536                        }
537                    }
538                }
539                delete [] rawImageData;
540            }
541            else
542            {
543                OSG_INFO << "not found any usable bands in file."<<std::endl;
544            }
545
546
547            //GDALOpen(dataset);
548
549            if (imageData)
550            {
551                osg::Image* image = new osg::Image;
552                image->setFileName(fileName.c_str());
553                image->setImage(s,t,r,
554                    internalFormat,
555                    pixelFormat,
556                    dataType,
557                    (unsigned char *)imageData,
558                    osg::Image::USE_NEW_DELETE);
559
560                if (texCoordRange) image->setUserData(texCoordRange);
561
562                image->flipVertical();
563
564                return image;
565
566            }
567
568            return 0;
569
570        }
571
572
573        ReadResult local_readHeightField(const std::string& fileName, const osgDB::ReaderWriter::Options* options)
574        {
575            //std::string ext = osgDB::getFileExtension(fileName);
576            //if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
577
578            initGDAL();
579
580            std::auto_ptr<GDALDataset> dataset((GDALDataset*)GDALOpen(fileName.c_str(),GA_ReadOnly));
581            if (!dataset.get()) return ReadResult::FILE_NOT_HANDLED;
582
583            int dataWidth = dataset->GetRasterXSize();
584            int dataHeight = dataset->GetRasterYSize();
585
586            int windowX = 0;
587            int windowY = 0;
588            int windowWidth = dataWidth;
589            int windowHeight = dataHeight;
590
591            int destX = 0;
592            int destY = 0;
593            int destWidth = osg::minimum(dataWidth,4096);
594            int destHeight = osg::minimum(dataHeight,4096);
595
596            osgDB::ImageOptions::TexCoordRange* texCoordRange = 0;
597
598            const osgDB::ImageOptions* imageOptions = dynamic_cast<const osgDB::ImageOptions*>(options);
599            if (imageOptions)
600            {
601                OSG_INFO<<"Got ImageOptions"<<std::endl;
602
603                int margin = 0;
604                switch(imageOptions->_sourceImageWindowMode)
605                {
606                case(osgDB::ImageOptions::RATIO_WINDOW):
607                    {
608                        double desiredX = (double)dataWidth * imageOptions->_sourceRatioWindow.windowX;
609                        double desiredY = (double)dataHeight * imageOptions->_sourceRatioWindow.windowY;
610                        double desiredWidth = (double)dataWidth * imageOptions->_sourceRatioWindow.windowWidth;
611                        double desiredHeight = (double)dataHeight * imageOptions->_sourceRatioWindow.windowHeight;
612
613                        windowX = osg::maximum((int)(floor(desiredX))-margin,0);
614                        windowY = osg::maximum((int)(floor(desiredY))-margin,0);
615                        windowWidth = osg::minimum((int)(ceil(desiredX + desiredWidth))+margin,dataWidth)-windowX;
616                        windowHeight = osg::minimum((int)(ceil(desiredY + desiredHeight))+margin,dataHeight)-windowY;
617
618                        texCoordRange = new osgDB::ImageOptions::TexCoordRange;
619                        texCoordRange->set((desiredX-(double)windowX)/(double)windowWidth,
620                                           ((double)(windowY+windowHeight) -(desiredY+desiredHeight))/(double)windowHeight,
621                                           (desiredWidth)/(double)windowWidth,
622                                           (desiredHeight)/(double)windowHeight);
623                        OSG_INFO<<"tex coord range "<<texCoordRange->_x<<" "<<texCoordRange->_y<<" "<<texCoordRange->_w<<" "<<texCoordRange->_h<<std::endl;
624                    }
625                    break;
626                case(osgDB::ImageOptions::PIXEL_WINDOW):
627                    windowX = imageOptions->_sourcePixelWindow.windowX;
628                    windowY = imageOptions->_sourcePixelWindow.windowY;
629                    windowWidth = imageOptions->_sourcePixelWindow.windowWidth;
630                    windowHeight = imageOptions->_sourcePixelWindow.windowHeight;
631                    break;
632                default:
633                    // leave source window dimensions as whole image.
634                    break;
635                }
636
637                switch(imageOptions->_destinationImageWindowMode)
638                {
639                case(osgDB::ImageOptions::RATIO_WINDOW):
640                    destX = (unsigned int)(floor((double)dataWidth * imageOptions->_destinationRatioWindow.windowX));
641                    destY = (unsigned int)(floor((double)dataHeight * imageOptions->_destinationRatioWindow.windowY));
642                    destWidth = (unsigned int)(ceil((double)dataWidth * (imageOptions->_destinationRatioWindow.windowX + imageOptions->_destinationRatioWindow.windowWidth)))-windowX;
643                    destHeight = (unsigned int)(ceil((double)dataHeight * (imageOptions->_destinationRatioWindow.windowY + imageOptions->_destinationRatioWindow.windowHeight)))-windowY;
644                    break;
645                case(osgDB::ImageOptions::PIXEL_WINDOW):
646                    destX = imageOptions->_destinationPixelWindow.windowX;
647                    destY = imageOptions->_destinationPixelWindow.windowY;
648                    destWidth = imageOptions->_destinationPixelWindow.windowWidth;
649                    destHeight = imageOptions->_destinationPixelWindow.windowHeight;
650                    break;
651                default:
652                    // leave source window dimensions as whole image.
653                    break;
654                }
655
656            }
657
658//             windowX =     0;
659//             windowY =     0;
660//            windowWidth = destWidth;
661//            windowHeight = destHeight;
662
663            OSG_INFO << "    windowX = "<<windowX<<std::endl;
664            OSG_INFO << "    windowY = "<<windowY<<std::endl;
665            OSG_INFO << "    windowWidth = "<<windowWidth<<std::endl;
666            OSG_INFO << "    windowHeight = "<<windowHeight<<std::endl;
667
668            OSG_INFO << std::endl;
669
670            OSG_INFO << "    destX = "<<destX<<std::endl;
671            OSG_INFO << "    destY = "<<destY<<std::endl;
672            OSG_INFO << "    destWidth = "<<destWidth<<std::endl;
673            OSG_INFO << "    destHeight = "<<destHeight<<std::endl;
674
675            OSG_INFO << std::endl;
676
677            OSG_INFO << "    GetRaterCount() "<< dataset->GetRasterCount()<<std::endl;
678            OSG_INFO << "    GetProjectionRef() "<< dataset->GetProjectionRef()<<std::endl;
679
680
681            double geoTransform[6];
682            CPLErr err = dataset->GetGeoTransform(geoTransform);
683            OSG_INFO << "   GetGeoTransform == "<< err <<" == CE_None"<<std::endl;
684            OSG_INFO << "    GetGeoTransform "<< std::endl;
685            OSG_INFO << "        Origin = "<<geoTransform[0]<<" "<<geoTransform[3]<<std::endl;
686            OSG_INFO << "        Pixel X = "<<geoTransform[1]<<" "<<geoTransform[4]<<std::endl;
687            OSG_INFO << "        Pixel Y = "<<geoTransform[2]<<" "<<geoTransform[5]<<std::endl;
688
689
690            double TopLeft[2],BottomLeft[2],BottomRight[2],TopRight[2];
691            TopLeft[0] = geoTransform[0];
692            TopLeft[1] = geoTransform[3];
693            BottomLeft[0] = TopLeft[0]+geoTransform[2]*(dataHeight-1);
694            BottomLeft[1] = TopLeft[1]+geoTransform[5]*(dataHeight-1);
695            BottomRight[0] = BottomLeft[0]+geoTransform[1]*(dataWidth-1);
696            BottomRight[1] = BottomLeft[1]+geoTransform[4]*(dataWidth-1);
697            TopRight[0] = TopLeft[0]+geoTransform[1]*(dataWidth-1);
698            TopRight[1] = TopLeft[1]+geoTransform[4]*(dataWidth-1);
699
700
701            double rotation = atan2(geoTransform[2], geoTransform[1]);
702            OSG_INFO<<"GDAL rotation = "<<rotation<<std::endl;
703
704            OSG_INFO << "TopLeft     "<<TopLeft[0]<<"\t"<<TopLeft[1]<<std::endl;
705            OSG_INFO << "BottomLeft  "<<BottomLeft[0]<<"\t"<<BottomLeft[1]<<std::endl;
706            OSG_INFO << "BottomRight "<<BottomRight[0]<<"\t"<<BottomRight[1]<<std::endl;
707            OSG_INFO << "TopRight    "<<TopRight[0]<<"\t"<<TopRight[1]<<std::endl;
708
709            OSG_INFO<<"    GDALGetGCPCount "<<dataset->GetGCPCount()<<std::endl;
710
711            int numBands = dataset->GetRasterCount();
712
713
714            GDALRasterBand* bandGray = 0;
715            GDALRasterBand* bandRed = 0;
716            GDALRasterBand* bandGreen = 0;
717            GDALRasterBand* bandBlue = 0;
718            GDALRasterBand* bandAlpha = 0;
719
720            for(int b=1;b<=numBands;++b)
721            {
722
723                GDALRasterBand* band = dataset->GetRasterBand(b);
724
725                OSG_INFO << "    Band "<<b<<std::endl;
726
727                OSG_INFO << "        GetOverviewCount() = "<< band->GetOverviewCount()<<std::endl;
728                OSG_INFO << "        GetColorTable() = "<< band->GetColorTable()<<std::endl;
729                OSG_INFO << "        DataTypeName() = "<< GDALGetDataTypeName(band->GetRasterDataType())<<std::endl;
730                OSG_INFO << "        ColorIntepretationName() = "<< GDALGetColorInterpretationName(band->GetColorInterpretation())<<std::endl;
731
732
733                OSG_INFO << std::endl;
734                OSG_INFO << "        GetNoDataValue() = "<< band->GetNoDataValue()<<std::endl;
735                OSG_INFO << "        GetMinimum() = "<< band->GetMinimum()<<std::endl;
736                OSG_INFO << "        GetMaximum() = "<< band->GetMaximum()<<std::endl;
737                OSG_INFO << "        GetOffset() = "<< band->GetOffset()<<std::endl;
738                OSG_INFO << "        GetScale() = "<< band->GetScale()<<std::endl;
739                OSG_INFO << "        GetUnitType() = '"<< band->GetUnitType()<<"'"<<std::endl;
740
741
742                if (band->GetColorInterpretation()==GCI_GrayIndex) bandGray = band;
743                else if (band->GetColorInterpretation()==GCI_RedBand) bandRed = band;
744                else if (band->GetColorInterpretation()==GCI_GreenBand) bandGreen = band;
745                else if (band->GetColorInterpretation()==GCI_BlueBand) bandBlue = band;
746                else if (band->GetColorInterpretation()==GCI_AlphaBand) bandAlpha = band;
747                else bandGray = band;
748
749            }
750
751
752            GDALRasterBand* bandSelected = 0;
753            if (!bandSelected && bandGray) bandSelected = bandGray;
754            else if (!bandSelected && bandAlpha) bandSelected = bandAlpha;
755            else if (!bandSelected && bandRed) bandSelected = bandRed;
756            else if (!bandSelected && bandGreen) bandSelected = bandGreen;
757            else if (!bandSelected && bandBlue) bandSelected = bandBlue;
758
759            if (bandSelected)
760            {
761                osg::HeightField* hf = new osg::HeightField;
762                hf->allocate(destWidth,destHeight);
763
764                bandSelected->RasterIO(GF_Read,windowX,windowY,windowWidth,windowHeight,(void*)(&(hf->getHeightList().front())),destWidth,destHeight,GDT_Float32,0,0);
765
766                // now need to flip since the OSG's origin is in lower left corner.
767                OSG_INFO<<"flipping"<<std::endl;
768                unsigned int copy_r = hf->getNumRows()-1;
769                for(unsigned int r=0;r<copy_r;++r,--copy_r)
770                {
771                    for(unsigned int c=0;c<hf->getNumColumns();++c)
772                    {
773                        float temp = hf->getHeight(c,r);
774                        hf->setHeight(c,r,hf->getHeight(c,copy_r));
775                        hf->setHeight(c,copy_r,temp);
776                    }
777                }
778                hf->setOrigin(osg::Vec3(BottomLeft[0],BottomLeft[1],0));
779
780                hf->setXInterval(sqrt(geoTransform[1]*geoTransform[1] + geoTransform[2]*geoTransform[2]));
781                hf->setYInterval(sqrt(geoTransform[4]*geoTransform[4] + geoTransform[5]*geoTransform[5]));
782
783                hf->setRotation(osg::Quat(rotation, osg::Vec3d(0.0, 0.0, 1.0)));
784
785                return hf;
786            }
787
788            return ReadResult::FILE_NOT_HANDLED;
789
790        }
791
792        void initGDAL() const
793        {
794            static bool s_initialized = false;
795            if (!s_initialized)
796            {
797                s_initialized = true;
798                GDALAllRegister();
799            }
800        }
801
802        mutable OpenThreads::ReentrantMutex _serializerMutex;
803
804};
805
806// now register with Registry to instantiate the above
807// reader/writer.
808REGISTER_OSGPLUGIN(gdal, ReaderWriterGDAL)
Note: See TracBrowser for help on using the browser.