Changeset 12912

Show
Ignore:
Timestamp:
01/24/12 15:34:02 (16 months ago)
Author:
robert
Message:

Added support for using GL_UNPACK_ROW_LENGTH in conjunction with texture's + osg::Image via new RowLength?
parameter in osg::Image. To support this Image::setData(..) now has a new optional rowLength parameter which
defaults to 0, which provides the original behaviour, Image::setRowLength(int) and int Image::getRowLength() are also provided.

With the introduction of RowLength? support in osg::Image it is now possible to create a sub image where
the t size of the image are smaller than the row length, useful for when you have a large image on the CPU
and which to use a small portion of it on the GPU. However, when these sub images are created the data
within the image is no longer contiguous so data access can no longer assume that all the data is in
one block. The new method Image::isDataContiguous() enables the user to check whether the data is contiguous,
and if not one can either access the data row by row using Image::data(column,row,image) accessor, or use the
new Image::DataIterator? for stepping through each block on memory assocatied with the image.

To support the possibility of non contiguous osg::Image usage of image objects has had to be updated to
check DataContiguous? and handle the case or use access via the DataIerator? or by row by row. To achieve
this a relatively large number of files has had to be modified, in particular the texture classes and
image plugins that doing writing.

Location:
OpenSceneGraph/trunk
Files:
34 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/examples/osgphotoalbum/PhotoArchive.cpp

    r12577 r12912  
    223223            osg::PixelStorageModes psm; 
    224224            psm.pack_alignment = image->getPacking(); 
     225            psm.pack_row_length = image->getRowLength(); 
    225226            psm.unpack_alignment = image->getPacking(); 
    226227 
     
    290291            osg::PixelStorageModes psm; 
    291292            psm.pack_alignment = image->getPacking(); 
     293            psm.pack_row_length = image->getRowLength(); 
    292294            psm.unpack_alignment = image->getPacking(); 
    293295 
  • OpenSceneGraph/trunk/examples/osgscreencapture/osgscreencapture.cpp

    r12292 r12912  
    385385    { 
    386386        memcpy(image->data(), src, image->getTotalSizeInBytes()); 
     387         
    387388        ext->glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB); 
    388389    } 
  • OpenSceneGraph/trunk/examples/osgtexture2D/osgtexture2D.cpp

    r9636 r12912  
    537537    { 
    538538 
    539          
     539#if 1         
     540        osg::ref_ptr<osg::Image> originalImage = osgDB::readImageFile("Images/dog_left_eye.jpg"); 
     541 
     542        osg::ref_ptr<osg::Image> subImage = new osg::Image; 
     543        subImage->setUserData(originalImage.get()); // attach the originalImage as user data to prevent it being deleted. 
     544 
     545        // now assign the appropriate portion data from the originalImage 
     546        subImage->setImage(originalImage->s()/2, originalImage->t()/2, originalImage->r(), // half the width and height 
     547                           originalImage->getInternalTextureFormat(), // same internal texture format 
     548                           originalImage->getPixelFormat(),originalImage->getDataType(), // same pixel foramt and data type 
     549                           originalImage->data(originalImage->s()/4,originalImage->t()/4), // offset teh start point to 1/4 into the image 
     550                           osg::Image::NO_DELETE, // don't attempt to delete the image data, leave this to the originalImage 
     551                           originalImage->getPacking(), // use the the same packing 
     552                           originalImage->s()); // use the width of the original image as the row width 
     553 
     554 
     555        subImage->setPixelBufferObject(new osg::PixelBufferObject(subImage.get())); 
     556 
     557#if 0 
     558        OSG_NOTICE<<"orignalImage iterator"<<std::endl; 
     559        for(osg::Image::DataIterator itr(originalImage.get()); itr.valid(); ++itr) 
     560        { 
     561            OSG_NOTICE<<"  "<<(void*)itr.data()<<", "<<itr.size()<<std::endl; 
     562        } 
     563 
     564        OSG_NOTICE<<"subImage iterator, size "<<subImage->s()<<", "<<subImage->t()<<std::endl; 
     565        unsigned int i=0; 
     566        for(osg::Image::DataIterator itr(subImage.get()); itr.valid(); ++itr, ++i) 
     567        { 
     568            OSG_NOTICE<<"  "<<i<<", "<<(void*)itr.data()<<", "<<itr.size()<<std::endl; 
     569 
     570            for(unsigned char* d=const_cast<unsigned char*>(itr.data()); d<(itr.data()+itr.size()); ++d) 
     571            { 
     572                *d = 255-*d; 
     573            } 
     574        } 
     575#endif    
     576 
     577         
     578        _imageList.push_back(subImage.get()); 
     579 
     580#else 
    540581        _imageList.push_back(osgDB::readImageFile("Images/dog_left_eye.jpg")); 
     582#endif 
    541583        _textList.push_back("Subloaded Image 1 - dog_left_eye.jpg"); 
    542584         
     
    585627protected: 
    586628 
     629     
    587630    typedef std::vector< osg::ref_ptr<osg::Image> > ImageList; 
    588631    typedef std::vector<std::string>                TextList; 
  • OpenSceneGraph/trunk/include/osg/Array

    r12608 r12912  
    105105        GLint                   getDataSize() const { return _dataSize; } 
    106106        GLenum                  getDataType() const { return _dataType; } 
     107 
     108        virtual osg::Array* asArray() { return this; } 
     109        virtual const osg::Array* asArray() const { return this; } 
     110 
    107111        virtual const GLvoid*   getDataPointer() const = 0; 
    108112        virtual unsigned int    getTotalDataSize() const = 0; 
  • OpenSceneGraph/trunk/include/osg/BufferObject

    r12797 r12912  
    621621        virtual unsigned int    getTotalDataSize() const = 0; 
    622622 
     623        virtual osg::Array* asArray() { return 0; } 
     624        virtual const osg::Array* asArray() const { return 0; } 
     625 
     626        virtual osg::PrimitiveSet* asPrimitiveSet() { return 0; } 
     627        virtual const osg::PrimitiveSet* asPrimitiveSet() const { return 0; } 
     628 
     629        virtual osg::Image* asImage() { return 0; } 
     630        virtual const osg::Image* asImage() const { return 0; } 
     631 
    623632        void setBufferObject(BufferObject* bufferObject); 
    624633        BufferObject* getBufferObject() { return _bufferObject.get(); } 
  • OpenSceneGraph/trunk/include/osg/Image

    r12842 r12912  
    115115        virtual const char* className() const { return "Image"; } 
    116116 
     117        virtual osg::Image* asImage() { return this; } 
     118        virtual const osg::Image* asImage() const { return this; } 
     119 
    117120        virtual const GLvoid*   getDataPointer() const { return data(); } 
    118121        virtual unsigned int    getTotalDataSize() const { return getTotalSizeInBytesIncludingMipmaps(); } 
     
    158161                      unsigned char* data, 
    159162                      AllocationMode mode, 
    160                       int packing=1); 
     163                      int packing=1, int rowLength=0); 
    161164             
    162165        /** Read pixels from current frame buffer at specified position and size, using glReadPixels. 
     
    214217        /** Depth of image. */ 
    215218        inline int r() const { return _r; } 
     219 
     220        void setRowLength(int length) { _rowLength = length; } 
     221        inline int getRowLength() const { return _rowLength; } 
    216222         
    217223        void setInternalTextureFormat(GLint internalFormat); 
     
    242248        inline unsigned int getRowSizeInBytes() const { return computeRowWidthInBytes(_s,_pixelFormat,_dataType,_packing); } 
    243249 
     250        /** Return the number of bytes between each successive row. 
     251          * Note, getRowSizeInBytes() will only equal getRowStepInBytes() when isDataContiguous() return true. */ 
     252        inline unsigned int getRowStepInBytes() const { return computeRowWidthInBytes(_rowLength==0?_s:_rowLength,_pixelFormat,_dataType,_packing); } 
     253 
    244254        /** Return the number of bytes each image (_s*_t) of pixels occupies. */ 
    245255        inline unsigned int getImageSizeInBytes() const { return getRowSizeInBytes()*_t; } 
    246256         
     257        /** Return the number of bytes between each successive image.  
     258          * Note, getImageSizeInBytes() will only equal getImageStepInBytes() when isDataContiguous() return true. */ 
     259        inline unsigned int getImageStepInBytes() const { return getRowStepInBytes()*_t; } 
     260 
    247261        /** Return the number of bytes the whole row/image/volume of pixels occupies. */ 
    248262        inline unsigned int getTotalSizeInBytes() const { return getImageSizeInBytes()*_r; } 
     
    254268        bool valid() const { return _s!=0 && _t!=0 && _r!=0 && _data!=0 && _dataType!=0; } 
    255269 
    256         /** Raw image data. */ 
     270        /** Raw image data. 
     271          * Note, data in successive rows may not be contiguous, isDataContiguous() return false then you should 
     272          * take care to access the data per row rather than treating the whole data as a single block. */ 
    257273        inline unsigned char* data() { return _data; } 
    258274         
    259         /** Raw const image data. */ 
     275        /** Raw const image data. 
     276          * Note, data in successive rows may not be contiguous, isDataContiguous() return false then you should 
     277          * take care to access the data per row rather than treating the whole data as a single block. */ 
    260278        inline const unsigned char* data() const { return _data; } 
    261279 
    262  
    263280        inline unsigned char* data(int column, int row=0,int image=0) 
    264281        { 
    265282            if (!_data) return NULL; 
    266             return _data+(column*getPixelSizeInBits())/8+row*getRowSizeInBytes()+image*getImageSizeInBytes(); 
     283            return _data+(column*getPixelSizeInBits())/8+row*getRowStepInBytes()+image*getImageSizeInBytes(); 
    267284        } 
    268285         
     
    270287        { 
    271288            if (!_data) return NULL; 
    272             return _data+(column*getPixelSizeInBits())/8+row*getRowSizeInBytes()+image*getImageSizeInBytes(); 
     289            return _data+(column*getPixelSizeInBits())/8+row*getRowStepInBytes()+image*getImageSizeInBytes(); 
    273290        } 
     291 
     292        /** return true if the data stored in the image is a contiguous block of data.*/ 
     293        bool isDataContiguous() const { return _rowLength==0 || _rowLength==_s; } 
     294 
     295        /** Convenience class for assisting the copying of image data when the image data isn't contiguous.*/ 
     296        class OSG_EXPORT DataIterator 
     297        { 
     298        public: 
     299            DataIterator(const Image* image); 
     300            DataIterator(const DataIterator& ri); 
     301            ~DataIterator() {} 
     302 
     303            /** advance iterator to next block of data.*/ 
     304            void operator ++ (); 
     305 
     306            /** is iterator valid.*/ 
     307            bool valid() const { return _currentPtr!=0; } 
     308 
     309            /** data pointer of current block to copy.*/ 
     310            const unsigned char* data() const { return _currentPtr; } 
     311 
     312            /** Size of current block to copy.*/ 
     313            unsigned int size() const { return _currentSize; } 
     314 
     315        protected: 
     316 
     317             
     318            void assign(); 
     319             
     320            const osg::Image*                   _image; 
     321            int                                 _rowNum; 
     322            int                                 _imageNum; 
     323            unsigned int                        _mipmapNum; 
     324            const unsigned char*                _currentPtr; 
     325            unsigned int                        _currentSize; 
     326        }; 
    274327 
    275328        /** Get the color value for specified texcoord.*/ 
     
    302355        static GLenum computePixelFormat(GLenum pixelFormat); 
    303356        static GLenum computeFormatDataType(GLenum pixelFormat); 
     357        static unsigned int computeBlockSize(GLenum pixelFormat, GLenum packing); 
    304358        static unsigned int computeNumComponents(GLenum pixelFormat); 
    305359        static unsigned int computePixelSizeInBits(GLenum pixelFormat,GLenum type); 
    306360        static unsigned int computeRowWidthInBytes(int width,GLenum pixelFormat,GLenum type,int packing); 
     361        static unsigned int computeImageSizeInBytes(int width,int height, int depth, GLenum pixelFormat,GLenum type,int packing); 
    307362        static int computeNearestPowerOfTwo(int s,float bias=0.5f); 
    308363        static int computeNumberOfMipmapLevels(int s,int t = 1, int r = 1); 
     
    342397        } 
    343398 
    344         /*inline const unsigned char* getMipmapData(unsigned int row, unsigned int column, unsigned int mipmapLevel) const 
    345         { 
    346            if (!_data) return NULL; 
    347            return getMipmapData(mipmapLevel) + (column*getPixelSizeInBits())/8+row*getRowSizeInBytes(); 
    348         }*/ 
    349  
    350399        /** Return true if this image is translucent - i.e. it has alpha values that are less 1.0 (when normalized). */ 
    351400        virtual bool isImageTranslucent() const; 
     
    400449 
    401450        int _s, _t, _r; 
     451        int _rowLength; 
    402452        GLint _internalTextureFormat; 
    403453        GLenum _pixelFormat; 
  • OpenSceneGraph/trunk/include/osg/PrimitiveSet

    r12360 r12912  
    198198         
    199199        Type                    getType() const { return _primitiveType; } 
     200 
     201        virtual osg::PrimitiveSet* asPrimitiveSet() { return this; } 
     202        virtual const osg::PrimitiveSet* asPrimitiveSet() const { return this; } 
     203 
    200204        virtual const GLvoid*   getDataPointer() const { return 0; } 
    201205        virtual unsigned int    getTotalDataSize() const { return 0; } 
  • OpenSceneGraph/trunk/src/osg/BufferObject.cpp

    r12522 r12912  
    205205            entry.modifiedCount = entry.dataSource->getModifiedCount(); 
    206206 
    207             _extensions->glBufferSubData(_profile._target, (GLintptrARB)entry.offset, (GLsizeiptrARB)entry.dataSize, entry.dataSource->getDataPointer()); 
     207            const osg::Image* image = entry.dataSource->asImage(); 
     208            if (image && !(image->isDataContiguous())) 
     209            {                 
     210                unsigned int offset = entry.offset; 
     211                for(osg::Image::DataIterator img_itr(image); img_itr.valid(); ++img_itr) 
     212                { 
     213                    //OSG_NOTICE<<"Copying to buffer object using DataIterator, offset="<<offset<<", size="<<img_itr.size()<<", data="<<(void*)img_itr.data()<<std::endl; 
     214                    _extensions->glBufferSubData(_profile._target, (GLintptrARB)offset, (GLsizeiptrARB)img_itr.size(), img_itr.data()); 
     215                    offset += img_itr.size(); 
     216                } 
     217            } 
     218            else 
     219            {             
     220                _extensions->glBufferSubData(_profile._target, (GLintptrARB)entry.offset, (GLsizeiptrARB)entry.dataSize, entry.dataSource->getDataPointer()); 
     221            } 
    208222 
    209223        } 
  • OpenSceneGraph/trunk/src/osg/DrawPixels.cpp

    r11472 r12912  
    9797    { 
    9898        const GLvoid* pixels = _image->data(_offsetX,_offsetY); 
     99        glPixelStorei(GL_UNPACK_ALIGNMENT,_image->getPacking()); 
    99100        glPixelStorei(GL_UNPACK_ROW_LENGTH,_image->s()); 
    100101        glDrawPixels(_width,_height, 
     
    106107    else 
    107108    { 
     109        glPixelStorei(GL_UNPACK_ALIGNMENT,_image->getPacking()); 
     110        glPixelStorei(GL_UNPACK_ROW_LENGTH,0); 
    108111        glDrawPixels(_image->s(), _image->t(), 
    109112                     (GLenum)_image->getPixelFormat(), 
  • OpenSceneGraph/trunk/src/osg/Image.cpp

    r12842 r12912  
    4949} 
    5050 
     51Image::DataIterator::DataIterator(const Image* image): 
     52    _image(image), 
     53    _rowNum(0), 
     54    _imageNum(0), 
     55    _mipmapNum(0), 
     56    _currentPtr(0), 
     57    _currentSize(0) 
     58{ 
     59    assign(); 
     60} 
     61 
     62Image::DataIterator::DataIterator(const DataIterator& ri): 
     63    _image(ri._image), 
     64    _rowNum(ri._rowNum), 
     65    _imageNum(ri._imageNum), 
     66    _mipmapNum(ri._mipmapNum), 
     67    _currentPtr(0), 
     68    _currentSize(0) 
     69{ 
     70    assign(); 
     71} 
     72 
     73void Image::DataIterator::operator ++ () 
     74{ 
     75    if (!_image || _image->isDataContiguous()) 
     76    { 
     77        // for contiguous image data we never need more than one block of data 
     78        _currentPtr = 0; 
     79        _currentSize = 0; 
     80        return; 
     81    } 
     82 
     83    if (_image->isMipmap()) 
     84    { 
     85        // advance to next row 
     86        ++_rowNum; 
     87 
     88        if (_rowNum>=_image->t()) 
     89        { 
     90            // moved over end of current image so move to next 
     91            _rowNum = 0; 
     92            ++_imageNum; 
     93 
     94            if (_imageNum>=_image->r()) 
     95            { 
     96                // move to next mipmap 
     97                _imageNum = 0; 
     98                ++_mipmapNum; 
     99 
     100                if (_mipmapNum>=_image->getNumMipmapLevels()) 
     101                { 
     102                    _currentPtr = 0; 
     103                    _currentSize = 0; 
     104                    return; 
     105                } 
     106            } 
     107        } 
     108    } 
     109    else 
     110    { 
     111        // advance to next row 
     112        ++_rowNum; 
     113         
     114        if (_rowNum>=_image->t()) 
     115        { 
     116            // moved over end of current image so move to next 
     117            _rowNum = 0; 
     118            ++_imageNum; 
     119 
     120            if (_imageNum>=_image->r()) 
     121            { 
     122                // we've moved off the end of the osg::Image so reset to null 
     123                _currentPtr = 0; 
     124                _currentSize = 0; 
     125                return; 
     126            } 
     127        } 
     128    } 
     129    
     130    assign(); 
     131} 
     132 
     133void Image::DataIterator::assign() 
     134{ 
     135    //OSG_NOTICE<<"DataIterator::assign A"<<std::endl; 
     136    if (!_image) 
     137    { 
     138        _currentPtr = 0; 
     139        _currentSize = 0; 
     140        return; 
     141    } 
     142     
     143    //OSG_NOTICE<<"DataIterator::assign B"<<std::endl; 
     144 
     145    if (_image->isDataContiguous()) 
     146    { 
     147        _currentPtr = _image->data(); 
     148        _currentSize = _image->getTotalSizeInBytesIncludingMipmaps(); 
     149 
     150        //OSG_NOTICE<<"   _currentPtr="<<(void*)_currentPtr<<std::endl; 
     151        //OSG_NOTICE<<"   _currentSize="<<_currentSize<<std::endl; 
     152 
     153        return; 
     154    } 
     155     
     156    //OSG_NOTICE<<"DataIterator::assign C"<<std::endl; 
     157 
     158    if (_image->isMipmap()) 
     159    { 
     160        //OSG_NOTICE<<"DataIterator::assign D"<<std::endl; 
     161 
     162        if (_mipmapNum>=_image->getNumMipmapLevels()) 
     163        { 
     164            _currentPtr = 0; 
     165            _currentSize = 0; 
     166            return; 
     167        } 
     168        const unsigned char* ptr = _image->getMipmapData(_mipmapNum); 
     169         
     170        int rowLength = _image->getRowLength()>>_mipmapNum; 
     171        if (rowLength==0) rowLength = 1; 
     172         
     173        int imageHeight = _image->t()>>_mipmapNum; 
     174        if (imageHeight==0) imageHeight = 1; 
     175         
     176        unsigned int rowWidthInBytes = Image::computeRowWidthInBytes(rowLength,_image->getPixelFormat(),_image->getDataType(),_image->getPacking()); 
     177        unsigned int imageSizeInBytes = rowWidthInBytes*imageHeight; 
     178         
     179        _currentPtr = ptr + rowWidthInBytes*_rowNum + imageSizeInBytes*_imageNum; 
     180        _currentSize = rowWidthInBytes; 
     181    } 
     182    else 
     183    { 
     184        //OSG_NOTICE<<"DataIterator::assign E"<<std::endl; 
     185 
     186        if (_imageNum>=_image->r() || _rowNum>=_image->t()) 
     187        { 
     188            _currentPtr = 0; 
     189            _currentSize = 0; 
     190            return; 
     191        } 
     192 
     193        //OSG_NOTICE<<"DataIterator::assign F"<<std::endl; 
     194 
     195        _currentPtr = _image->data(0, _rowNum, _imageNum); 
     196        _currentSize = _image->getRowSizeInBytes(); 
     197        return; 
     198    } 
     199} 
     200 
     201 
    51202Image::Image() 
    52203    :BufferData(), 
     
    55206    _origin(BOTTOM_LEFT), 
    56207    _s(0), _t(0), _r(0), 
     208    _rowLength(0), 
    57209    _internalTextureFormat(0), 
    58210    _pixelFormat(0), 
     
    72224    _origin(image._origin), 
    73225    _s(image._s), _t(image._t), _r(image._r), 
     226    _rowLength(0), 
    74227    _internalTextureFormat(image._internalTextureFormat), 
    75228    _pixelFormat(image._pixelFormat), 
     
    85238        int size = image.getTotalSizeInBytesIncludingMipmaps(); 
    86239        setData(new unsigned char [size],USE_NEW_DELETE); 
    87         memcpy(_data,image._data,size); 
     240        unsigned char* dest_ptr = _data; 
     241        for(DataIterator itr(&image); itr.valid(); ++itr) 
     242        { 
     243            memcpy(dest_ptr, itr.data(), itr.size()); 
     244            dest_ptr += itr.size(); 
     245        } 
    88246    } 
    89247} 
     
    511669} 
    512670 
     671unsigned int Image::computeBlockSize(GLenum pixelFormat, GLenum packing) 
     672{ 
     673    switch(pixelFormat) 
     674    { 
     675        case(GL_COMPRESSED_RGB_S3TC_DXT1_EXT): 
     676        case(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT): 
     677            return osg::maximum(8u,packing); // block size of 8 
     678        case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT): 
     679        case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT): 
     680        case(GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG): 
     681        case(GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG): 
     682        case(GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG): 
     683        case(GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG): 
     684        case(GL_ETC1_RGB8_OES): 
     685            return osg::maximum(16u,packing); // block size of 16 
     686        case(GL_COMPRESSED_SIGNED_RED_RGTC1_EXT): 
     687        case(GL_COMPRESSED_RED_RGTC1_EXT): 
     688            return osg::maximum(8u,packing); // block size of 8 
     689            break; 
     690        case(GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT): 
     691        case(GL_COMPRESSED_RED_GREEN_RGTC2_EXT): 
     692            return osg::maximum(16u,packing); // block size of 16 
     693        default: 
     694            break; 
     695    } 
     696    return packing; 
     697} 
     698 
    513699unsigned int Image::computeRowWidthInBytes(int width,GLenum pixelFormat,GLenum type,int packing) 
    514700{ 
     
    518704    //OSG_INFO << "width="<<width<<" pixelSize="<<pixelSize<<"  width in bit="<<widthInBits<<" packingInBits="<<packingInBits<<" widthInBits%packingInBits="<<widthInBits%packingInBits<<std::endl; 
    519705    return (widthInBits/packingInBits + ((widthInBits%packingInBits)?1:0))*packing; 
     706} 
     707 
     708unsigned int Image::computeImageSizeInBytes(int width,int height, int depth, GLenum pixelFormat,GLenum type,int packing) 
     709{ 
     710    if (width==0 || height==0 || depth==0) return 0; 
     711     
     712    return osg::maximum( 
     713            Image::computeRowWidthInBytes(width,pixelFormat,type,packing)*height*depth, 
     714            computeBlockSize(pixelFormat, packing) 
     715        ); 
    520716} 
    521717 
     
    582778    int t = _t; 
    583779    int r = _r; 
    584      
    585     unsigned int maxValue = 0; 
    586     for(unsigned int i=0;i<_mipmapData.size() && _mipmapData[i];++i) 
    587     { 
     780    unsigned int totalSize = 0; 
     781    for(unsigned int i=0;i<_mipmapData.size()+1;++i) 
     782    { 
     783        totalSize += computeImageSizeInBytes(s, t, r, _pixelFormat, _dataType, _packing); 
     784         
    588785        s >>= 1; 
    589786        t >>= 1; 
    590787        r >>= 1; 
    591         maxValue = maximum(maxValue,_mipmapData[i]); 
     788 
     789        if (s<1) s=1; 
     790        if (t<1) t=1; 
     791        if (r<1) r=1; 
    592792   } 
    593     
    594    if (s==0) s=1; 
    595    if (t==0) t=1; 
    596    if (r==0) r=1; 
    597     
    598    unsigned int sizeOfLastMipMap = computeRowWidthInBytes(s,_pixelFormat,_dataType,_packing)* r*t; 
    599    switch(_pixelFormat) 
    600    { 
    601         case(GL_COMPRESSED_RGB_S3TC_DXT1_EXT): 
    602         case(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT): 
    603            sizeOfLastMipMap = maximum(sizeOfLastMipMap, 8u); // block size of 8 
    604            break; 
    605         case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT): 
    606         case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT): 
    607         case(GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG): 
    608         case(GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG): 
    609         case(GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG): 
    610         case(GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG): 
    611         case(GL_ETC1_RGB8_OES): 
    612            sizeOfLastMipMap = maximum(sizeOfLastMipMap, 16u); // block size of 16 
    613            break; 
    614         case(GL_COMPRESSED_SIGNED_RED_RGTC1_EXT): 
    615         case(GL_COMPRESSED_RED_RGTC1_EXT): 
    616             sizeOfLastMipMap = maximum(sizeOfLastMipMap, 8u); // block size of 8 
    617             break; 
    618         case(GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT): 
    619         case(GL_COMPRESSED_RED_GREEN_RGTC2_EXT): 
    620             sizeOfLastMipMap = maximum(sizeOfLastMipMap, 16u); // block size of 8 
    621             break; 
    622         default: break; 
    623    } 
    624  
    625    // OSG_INFO<<"sizeOfLastMipMap="<<sizeOfLastMipMap<<"\ts="<<s<<"\tt="<<t<<"\tr"<<r<<std::endl;                   
    626  
    627    return maxValue+sizeOfLastMipMap; 
    628  
     793 
     794   return totalSize; 
    629795} 
    630796 
     
    686852        _dataType = type; 
    687853        _packing = packing; 
     854        _rowLength = 0; 
    688855         
    689856        // preserve internalTextureFormat if already set, otherwise 
     
    701868        _dataType = 0; 
    702869        _packing = 0; 
     870        _rowLength = 0; 
    703871         
    704872        // commenting out reset of _internalTextureFormat as we are changing 
     
    715883                     unsigned char *data, 
    716884                     AllocationMode mode, 
    717                      int packing) 
     885                     int packing, 
     886                     int rowLength) 
    718887{ 
    719888    _mipmapData.clear(); 
     
    730899 
    731900    _packing = packing; 
     901    _rowLength = rowLength; 
    732902         
    733903    dirty(); 
     
    741911 
    742912    glPixelStorei(GL_PACK_ALIGNMENT,_packing); 
     913    glPixelStorei(GL_PACK_ROW_LENGTH,_rowLength); 
    743914 
    744915    glReadPixels(x,y,width,height,format,type,_data); 
     
    776947    GLint depth; 
    777948    GLint packing; 
     949    GLint rowLength; 
    778950 
    779951    GLint numMipMaps = 0; 
     
    8571029        glGetIntegerv(GL_UNPACK_ALIGNMENT, &packing); 
    8581030        glPixelStorei(GL_PACK_ALIGNMENT, packing); 
     1031        glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowLength); 
     1032        glPixelStorei(GL_PACK_ROW_LENGTH, rowLength); 
    8591033 
    8601034        _data = data; 
     
    8691043        _allocationMode=USE_NEW_DELETE; 
    8701044        _packing = packing; 
    871          
     1045        _rowLength = rowLength; 
     1046 
    8721047        for(i=0;i<numMipMaps;++i) 
    8731048        { 
     
    8871062        glGetIntegerv(GL_UNPACK_ALIGNMENT, &packing); 
    8881063        glPixelStorei(GL_PACK_ALIGNMENT, packing); 
     1064        glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowLength); 
     1065        glPixelStorei(GL_PACK_ROW_LENGTH, rowLength); 
    8891066 
    8901067        unsigned int total_size = 0; 
     
    9281105        _allocationMode=USE_NEW_DELETE; 
    9291106        _packing = packing; 
     1107        _rowLength = rowLength; 
    9301108         
    9311109        for(i=0;i<numMipMaps;++i) 
     
    9701148    PixelStorageModes psm; 
    9711149    psm.pack_alignment = _packing; 
     1150    psm.pack_row_length = _rowLength; 
    9721151    psm.unpack_alignment = _packing; 
    9731152 
     
    9881167        _s = s; 
    9891168        _t = t; 
     1169        _rowLength = 0; 
    9901170        _dataType = newDataType; 
    9911171        setData(newData,USE_NEW_DELETE); 
     
    10351215    PixelStorageModes psm; 
    10361216    psm.pack_alignment = _packing; 
    1037     psm.pack_row_length = _s; 
    1038     psm.unpack_alignment = _packing; 
     1217    psm.pack_row_length = _rowLength!=0 ? _rowLength : _s; 
     1218    psm.unpack_alignment = source->getPacking(); 
     1219    psm.unpack_row_length = source->getRowLength(); 
    10391220 
    10401221    GLint status = gluScaleImage(&psm, _pixelFormat, 
     
    10481229        data_destination); 
    10491230 
    1050     glPixelStorei(GL_PACK_ROW_LENGTH,0); 
    1051  
    10521231    if (status!=0) 
    10531232    { 
     
    10681247    if (_mipmapData.empty()) 
    10691248    { 
    1070  
     1249        unsigned int rowStepInBytes = getRowStepInBytes(); 
     1250        unsigned int imageStepInBytes = getImageStepInBytes(); 
     1251         
    10711252        for(int r=0;r<_r;++r) 
    10721253        { 
    10731254            for (int t=0; t<_t; ++t) 
    10741255            { 
    1075                 unsigned char* rowData = _data+t*getRowSizeInBytes()+r*getImageSizeInBytes(); 
     1256                unsigned char* rowData = _data + t*rowStepInBytes + r*imageStepInBytes; 
    10761257                unsigned char* left  = rowData ; 
    10771258                unsigned char* right = rowData + ((_s-1)*getPixelSizeInBits())/8; 
     
    10981279} 
    10991280 
    1100 void flipImageVertical(unsigned char* top, unsigned char* bottom, unsigned int rowSize) 
     1281void flipImageVertical(unsigned char* top, unsigned char* bottom, unsigned int rowSize, unsigned int rowStep) 
    11011282{ 
    11021283    while(top<bottom) 
    11031284    { 
    1104         for(unsigned int i=0;i<rowSize;++i, ++top,++bottom) 
    1105         { 
    1106             unsigned char temp=*top; 
    1107             *top = *bottom; 
    1108             *bottom = temp; 
    1109         } 
    1110         bottom -= 2*rowSize; 
     1285        unsigned char* t = top; 
     1286        unsigned char* b = bottom; 
     1287        for(unsigned int i=0;i<rowSize;++i, ++t,++b) 
     1288        { 
     1289            unsigned char temp=*t; 
     1290            *t = *b; 
     1291            *b = temp; 
     1292        } 
     1293        top += rowStep; 
     1294        bottom -= rowStep; 
    11111295    } 
    11121296} 
     
    11261310        return; 
    11271311    } 
     1312 
     1313    unsigned int rowSize = getRowSizeInBytes(); 
     1314    unsigned int rowStep = getRowStepInBytes(); 
    11281315 
    11291316    if (_mipmapData.empty()) 
     
    11361323            { 
    11371324                // its not a compressed image, so implement flip oursleves. 
    1138                  
    1139                 unsigned int rowSize = computeRowWidthInBytes(_s,_pixelFormat,_dataType,_packing); 
    11401325                unsigned char* top = data(0,0,r); 
    1141                 unsigned char* bottom = top + (_t-1)*rowSize; 
     1326                unsigned char* bottom = top + (_t-1)*rowStep; 
    11421327                     
    1143                 flipImageVertical(top, bottom, rowSize); 
     1328                flipImageVertical(top, bottom, rowSize, rowStep); 
    11441329            } 
    11451330        } 
     
    11501335        { 
    11511336            // its not a compressed image, so implement flip oursleves. 
    1152             unsigned int rowSize = computeRowWidthInBytes(_s,_pixelFormat,_dataType,_packing); 
    11531337            unsigned char* top = data(0,0,0); 
    1154             unsigned char* bottom = top + (_t-1)*rowSize; 
    1155  
    1156             flipImageVertical(top, bottom, rowSize); 
     1338            unsigned char* bottom = top + (_t-1)*rowStep; 
     1339 
     1340            flipImageVertical(top, bottom, rowSize, rowStep); 
    11571341        } 
    11581342 
     
    11701354            { 
    11711355                // its not a compressed image, so implement flip oursleves. 
    1172                 unsigned int rowSize = computeRowWidthInBytes(s,_pixelFormat,_dataType,_packing); 
    11731356                unsigned char* top = _data+_mipmapData[i]; 
    1174                 unsigned char* bottom = top + (t-1)*rowSize; 
    1175  
    1176                 flipImageVertical(top, bottom, rowSize); 
     1357                unsigned char* bottom = top + (t-1)*rowStep; 
     1358 
     1359                flipImageVertical(top, bottom, rowSize, rowStep); 
    11771360            } 
    11781361       } 
     
    12011384    } 
    12021385 
    1203     unsigned int sizeOfSlice = getImageSizeInBytes(); 
    1204  
    1205     int r_top = 0; 
    1206     int r_bottom = _r-1; 
    1207     for(; r_top<r_bottom; ++r_top,--r_bottom) 
    1208     { 
    1209         unsigned char* top_slice = data(0,0,r_top); 
    1210         unsigned char* bottom_slice = data(0,0,r_bottom); 
    1211         for(unsigned int i=0; i<sizeOfSlice; ++i, ++top_slice, ++bottom_slice) 
    1212         { 
    1213             std::swap(*top_slice, *bottom_slice); 
     1386    unsigned int sizeOfRow = getRowSizeInBytes(); 
     1387 
     1388    int r_front = 0; 
     1389    int r_back = _r-1; 
     1390    for(; r_front<r_back; ++r_front,--r_back) 
     1391    { 
     1392        for(int row=0; row<_t; ++row) 
     1393        {         
     1394            unsigned char* front = data(0, row, r_front); 
     1395            unsigned char* back = data(0, row, r_back); 
     1396            for(unsigned int i=0; i<sizeOfRow; ++i, ++front, ++back) 
     1397            { 
     1398                std::swap(*front, *back); 
     1399            } 
    12141400        } 
    12151401    } 
     
    14261612            dstate->setTextureAttributeAndModes(0, texture,osg::StateAttribute::ON); 
    14271613 
    1428             // set up the geoset. 
     1614            // set up the geoset.                unsigned int rowSize = computeRowWidthInBytes(s,_pixelFormat,_dataType,_packing); 
     1615 
    14291616            Geometry* geom = new Geometry; 
    14301617            geom->setStateSet(dstate); 
  • OpenSceneGraph/trunk/src/osg/Texture.cpp

    r12727 r12912  
    18431843 
    18441844    glPixelStorei(GL_UNPACK_ALIGNMENT,image->getPacking()); 
     1845    unsigned int rowLength = image->getRowLength(); 
    18451846 
    18461847    bool useClientStorage = extensions->isClientStorageSupported() && getClientStorageHint(); 
     
    18921893        PixelStorageModes psm; 
    18931894        psm.pack_alignment = image->getPacking(); 
     1895        psm.pack_row_length = image->getRowLength(); 
    18941896        psm.unpack_alignment = image->getPacking(); 
    18951897 
     
    19001902                        dataPtr); 
    19011903 
     1904        rowLength = 0; 
    19021905    } 
    19031906 
     
    19111914        state.bindPixelBufferObject(pbo); 
    19121915        dataPtr = reinterpret_cast<unsigned char*>(pbo->getOffset(image->getBufferIndex())); 
     1916        rowLength = 0; 
    19131917#ifdef DO_TIMING 
    19141918        OSG_NOTICE<<"after PBO "<<osg::Timer::instance()->delta_m(start_tick,osg::Timer::instance()->tick())<<"ms"<<std::endl; 
     
    19191923        pbo = 0; 
    19201924    } 
     1925 
     1926    glPixelStorei(GL_UNPACK_ROW_LENGTH,rowLength); 
    19211927 
    19221928    if( !mipmappingRequired || useHardwareMipMapGeneration) 
     
    21092115     
    21102116    glPixelStorei(GL_UNPACK_ALIGNMENT,image->getPacking()); 
     2117    unsigned int rowLength = image->getRowLength(); 
    21112118     
    21122119    unsigned char* dataPtr = (unsigned char*)image->data(); 
     
    21482155                      inwidth,inheight,image->getDataType(), 
    21492156                      dataPtr); 
     2157 
     2158        rowLength = 0; 
    21502159    } 
    21512160 
     
    21602169        state.bindPixelBufferObject(pbo); 
    21612170        dataPtr = reinterpret_cast<unsigned char*>(pbo->getOffset(image->getBufferIndex())); 
     2171        rowLength = 0; 
    21622172#ifdef DO_TIMING 
    21632173        OSG_NOTICE<<"after PBO "<<osg::Timer::instance()->delta_m(start_tick,osg::Timer::instance()->tick())<<"ms"<<std::endl; 
     
    21682178        pbo = 0; 
    21692179    } 
     2180 
     2181    glPixelStorei(GL_UNPACK_ROW_LENGTH,rowLength); 
    21702182 
    21712183    if( !mipmappingRequired || useHardwareMipMapGeneration) 
  • OpenSceneGraph/trunk/src/osg/Texture1D.cpp

    r11817 r12912  
    287287 
    288288    glPixelStorei(GL_UNPACK_ALIGNMENT,image->getPacking()); 
     289    glPixelStorei(GL_UNPACK_ROW_LENGTH,image->getRowLength()); 
    289290 
    290291    static MyCompressedTexImage1DArbProc glCompressedTexImage1D_ptr =  
  • OpenSceneGraph/trunk/src/osg/Texture2DArray.cpp

    r12292 r12912  
    456456     
    457457    glPixelStorei(GL_UNPACK_ALIGNMENT,image->getPacking()); 
     458    glPixelStorei(GL_UNPACK_ROW_LENGTH,image->getRowLength()); 
    458459 
    459460    bool useHardwareMipmapGeneration =  
  • OpenSceneGraph/trunk/src/osg/Texture3D.cpp

    r11881 r12912  
    381381 
    382382    glPixelStorei(GL_UNPACK_ALIGNMENT,image->getPacking()); 
     383    glPixelStorei(GL_UNPACK_ROW_LENGTH,image->getRowLength()); 
    383384 
    384385    bool useHardwareMipMapGeneration = !image->isMipmap() && _useHardwareMipMapGeneration && texExtensions->isGenerateMipMapSupported(); 
  • OpenSceneGraph/trunk/src/osg/TextureRectangle.cpp

    r11808 r12912  
    313313 
    314314    glPixelStorei(GL_UNPACK_ALIGNMENT, image->getPacking()); 
     315    glPixelStorei(GL_UNPACK_ROW_LENGTH,image->getRowLength()); 
    315316 
    316317    bool useClientStorage = extensions->isClientStorageSupported() && getClientStorageHint(); 
     
    393394 
    394395    glPixelStorei(GL_UNPACK_ALIGNMENT, image->getPacking()); 
     396    unsigned int rowLength = image->getRowLength(); 
     397     
    395398 
    396399#ifdef DO_TIMING 
     
    404407        state.bindPixelBufferObject(pbo); 
    405408        dataPtr = reinterpret_cast<unsigned char*>(pbo->getOffset(image->getBufferIndex())); 
     409        rowLength = 0; 
    406410#ifdef DO_TIMING 
    407411        OSG_NOTICE<<"after PBO "<<osg::Timer::instance()->delta_m(start_tick,osg::Timer::instance()->tick())<<"ms"<<std::endl; 
    408412#endif 
    409413    } 
    410      
     414 
     415    glPixelStorei(GL_UNPACK_ROW_LENGTH,rowLength); 
    411416 
    412417    if(isCompressedInternalFormat(_internalFormat) && extensions->isCompressedTexSubImage2DSupported()) 
  • OpenSceneGraph/trunk/src/osgDB/OutputStream.cpp

    r12896 r12912  
    370370                // _data 
    371371                unsigned int size = img->getTotalSizeInBytesIncludingMipmaps(); 
    372                 writeSize(size); writeCharArray( (char*)img->data(), size ); 
     372                writeSize(size); 
     373 
     374                for(osg::Image::DataIterator img_itr(img); img_itr.valid(); ++img_itr) 
     375                { 
     376                    writeCharArray( (char*)img_itr.data(), img_itr.size() ); 
     377                } 
    373378 
    374379                // _mipmapData 
    375                 const osg::Image::MipmapDataType& levels = img->getMipmapLevels(); 
    376                 writeSize(levels.size()); 
    377                 for ( osg::Image::MipmapDataType::const_iterator itr=levels.begin(); 
    378                     itr!=levels.end(); ++itr ) 
     380                unsigned int numMipmaps = img->getNumMipmapLevels()-1; 
     381                writeSize(numMipmaps); 
     382                int s = img->s(); 
     383                int t = img->t(); 
     384                int r = img->r(); 
     385                unsigned int offset = 0; 
     386                for (unsigned int i=0; i<numMipmaps; ++i) 
    379387                { 
    380                     *this << *itr; 
     388                    unsigned int size = osg::Image::computeImageSizeInBytes(s,t,r,img->getPixelFormat(),img->getDataType(),img->getPacking()); 
     389                    offset += size; 
     390                     
     391                    *this << offset; 
     392 
     393                    s >>= 1; 
     394                    t >>= 1; 
     395                    r >>= 1; 
     396                    if (s<1) s=1; 
     397                    if (t<1) t=1; 
     398                    if (r<1) r=1;                     
    381399                } 
    382400            } 
  • OpenSceneGraph/trunk/src/osgPlugins/Inventor/ConvertFromInventor.cpp

    r12625 r12912  
    10941094static osg::Image* loadImage(const char *fileName, osgDB::ReaderWriter::Options *options) 
    10951095{ 
    1096     osg::Image *osgImage = osgDB::readImageFile(fileName, options); 
     1096    osg::ref_ptr<osg::Image> osgImage = osgDB::readImageFile(fileName, options); 
    10971097 
    10981098    if (!osgImage) 
     1099    { 
    10991100        OSG_WARN << NOTIFY_HEADER << "Could not read texture file '" << fileName << "'."; 
    1100  
    1101     return osgImage; 
     1101        return 0; 
     1102    } 
     1103 
     1104    if (!osgImage->isDataContiguous()) 
     1105    { 
     1106        OSG_WARN << NOTIFY_HEADER << "Inventor cannot handle non contiguous image data found in texture file '" << fileName << "'."; 
     1107        return 0; 
     1108    } 
     1109 
     1110    return osgImage.release(); 
    11021111} 
    11031112 
  • OpenSceneGraph/trunk/src/osgPlugins/Inventor/ReaderWriterIV.cpp

    r12577 r12912  
    143143        { 
    144144            OSG_NOTICE << "osgDB::ReaderWriterIV::readNode() " 
    145                       << "File " << fileName.data() 
     145                      << "File " << fileName 
    146146                      << " loaded successfully." << std::endl; 
    147147        } 
     
    155155        { 
    156156            OSG_WARN << "osgDB::ReaderWriterIV::readNode() " 
    157                       << "Failed to load file " << fileName.data() 
     157                      << "Failed to load file " << fileName 
    158158                      << "." << std::endl; 
    159159        } 
  • OpenSceneGraph/trunk/src/osgPlugins/bmp/ReaderWriterBMP.cpp

    r12574 r12912  
    528528    for (int y = 0; y < img.t(); ++y) 
    529529    { 
    530         const unsigned char* imgp = img.data() + img.s() * y * channelsPerPixel; 
     530        const unsigned char* imgp = img.data(0, y); 
    531531        for (int x = 0; x < img.s(); ++x) 
    532532        { 
  • OpenSceneGraph/trunk/src/osgPlugins/dds/ReaderWriterDDS.cpp

    r12597 r12912  
    879879    } 
    880880 
    881     int size = img->getTotalSizeInBytes(); 
    882  
    883881    // set even more flags 
    884882    if( !img->isMipmap() ) { 
     
    896894         
    897895        ddsd.dwMipMapCount = img->getNumMipmapLevels(); 
    898  
    899         size = img->getTotalSizeInBytesIncludingMipmaps(); 
    900896 
    901897        OSG_INFO<<"writing out with mipmaps ddsd.dwMipMapCount"<<ddsd.dwMipMapCount<<std::endl; 
     
    914910    fout.write("DDS ", 4); /* write FOURCC */ 
    915911    fout.write(reinterpret_cast<char*>(&ddsd), sizeof(ddsd)); /* write file header */ 
    916     fout.write(reinterpret_cast<const char*>(img->data()), size ); 
     912 
     913    for(osg::Image::DataIterator itr(img); itr.valid(); ++itr) 
     914    { 
     915        fout.write(reinterpret_cast<const char*>(itr.data()), itr.size() ); 
     916    } 
    917917 
    918918    // Check for correct saving 
  • OpenSceneGraph/trunk/src/osgPlugins/exr/ReaderWriterEXR.cpp

    r12292 r12912  
    277277         if (dataType == GL_HALF_FLOAT_ARB) 
    278278         {     
    279              half* pOut = (half*) img.data(); 
    280279             for (long i = height-1; i >= 0; i--) 
    281280             { 
     281                half* pOut = (half*) img.data(0,i); 
    282282                 for (long j = 0 ; j < width; j++) 
    283283                 { 
  • OpenSceneGraph/trunk/src/osgPlugins/hdr/hdrwriter.cpp

    r12292 r12912  
    3737 
    3838 
    39 bool HDRWriter::writeRLE(const osg::Image *img, std::ostream& fout) 
    40 { 
    41     return writePixelsRLE(fout,(float*) img->data(), img->s(), img->t()); 
    42 } 
    43  
    4439bool HDRWriter::writeRAW(const osg::Image *img, std::ostream& fout) 
    4540{ 
    46     return writePixelsRAW(fout,(unsigned char*) img->data(), img->s() * img->t()); 
    47 } 
    48  
    49  
    50  
    51  
     41    bool result = true; 
     42    for(int row=0; result && row<img->t(); ++row) 
     43    { 
     44        result = writePixelsRAW(fout,(unsigned char*) img->data(0, row), img->s()); 
     45    } 
     46    return result; 
     47} 
    5248 
    5349/* number of floats per pixel */ 
     
    8783/* These routines can be made faster by allocating a larger buffer and 
    8884   fread-ing and fwrite-ing the data in larger chunks */ 
    89 bool HDRWriter::writePixelsNoRLE( std::ostream& fout, float* data, int numpixels) 
     85bool HDRWriter::writeNoRLE( std::ostream& fout, const osg::Image* img) 
    9086{ 
    9187  unsigned char rgbe[4]; 
    9288 
    93   while (numpixels-- > 0) 
     89  for(int row=0; row<img->t(); ++row) 
    9490  { 
    95     float2rgbe( 
     91    float* data = (float*)img->data(0,row); 
     92    for(int column=0; column<img->s(); ++column) 
     93    { 
     94      float2rgbe( 
    9695        rgbe, 
    9796        data[R], 
     
    9998        data[B] 
    10099        ); 
    101     data += RGBE_DATA_SIZE; 
    102     fout.write(reinterpret_cast<const char*>(rgbe), sizeof(rgbe)); //img->getTotalSizeInBytesIncludingMipmaps() 
     100      data += RGBE_DATA_SIZE; 
     101      fout.write(reinterpret_cast<const char*>(rgbe), sizeof(rgbe)); 
     102    } 
    103103  } 
     104 
    104105  return true; 
    105106} 
     
    184185} 
    185186 
    186 bool HDRWriter::writePixelsRLE( std::ostream& fout, float* data, int scanline_width, int num_scanlines ) 
    187  
    188 { 
     187bool HDRWriter::writeRLE( const osg::Image* img, std::ostream& fout) 
     188{ 
     189    int scanline_width = img->s(); 
     190    int num_scanlines = img->t(); 
     191 
    189192    unsigned char rgbe[4]; 
    190193    unsigned char *buffer; 
     
    192195    if ((scanline_width < MINELEN)||(scanline_width > MAXELEN)) 
    193196        // run length encoding is not allowed so write flat 
    194         return writePixelsNoRLE(fout,data,scanline_width*num_scanlines); 
     197        return writeNoRLE(fout,img); 
    195198 
    196199    buffer = (unsigned char *)malloc(sizeof(unsigned char)*4*scanline_width); 
    197200    if (buffer == NULL)  
    198201        // no buffer space so write flat 
    199         return writePixelsNoRLE(fout,data,scanline_width*num_scanlines); 
    200  
    201     while(num_scanlines-- > 0) 
    202     { 
     202        return writeNoRLE(fout,img); 
     203 
     204    for(int row = 0; row<num_scanlines; ++row) 
     205    { 
     206        float* data = (float*) img->data(0, row); 
     207         
    203208        rgbe[0] = 2; 
    204209        rgbe[1] = 2; 
  • OpenSceneGraph/trunk/src/osgPlugins/hdr/hdrwriter.h

    r12292 r12912  
    4040 
    4141// can read or write pixels in chunks of any size including single pixels 
    42     static bool writePixelsNoRLE( std::ostream& fout, float* data, int numpixels); 
     42    static bool writeNoRLE( std::ostream& fout, const osg::Image* image); 
    4343    static bool writePixelsRAW(  std::ostream& fout, unsigned char* data, int numpixels); 
    4444 
     
    4646// must be called to read or write whole scanlines 
    4747    static bool writeBytesRLE(std::ostream& fout, unsigned char *data, int numbytes); 
    48     static bool writePixelsRLE( std::ostream& fout, float* data, int scanline_width, int num_scanlines ); 
    4948 
    5049// inline conversions 
  • OpenSceneGraph/trunk/src/osgPlugins/imageio/ReaderWriterImageIO.cpp

    r12789 r12912  
    12001200    WriteResult writeImageStream(const osg::Image& osg_image, std::ostream& fout, const osgDB::ReaderWriter::Options* the_options) const 
    12011201    { 
     1202        if (!osg_image.isDataContiguous()) 
     1203        { 
     1204            return WriteResult::FILE_NOT_HANDLED; 
     1205        } 
     1206 
    12021207        WriteResult ret_val = WriteResult::ERROR_IN_WRITING_FILE; 
    12031208 
     
    12361241    WriteResult writeImageFile(const osg::Image& osg_image, const std::string& full_file_name, const osgDB::ReaderWriter::Options* the_options) const 
    12371242    { 
     1243        if (!osg_image.isDataContiguous()) 
     1244        { 
     1245            return WriteResult::FILE_NOT_HANDLED; 
     1246        } 
     1247 
     1248        WriteResult ret_val = WriteResult::ERROR_IN_WRITING_FILE; 
    12381249        WriteResult ret_val = WriteResult::ERROR_IN_WRITING_FILE; 
    12391250        // Call ImageIO to load the image. 
     
    12691280        if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED; 
    12701281 
     1282        if (!osg_image.isDataContiguous()) 
     1283        { 
     1284            return WriteResult::FILE_NOT_HANDLED; 
     1285        } 
     1286 
     1287        WriteResult ret_val = WriteResult::ERROR_IN_WRITING_FILE; 
    12711288#if 1 
    12721289        // FIXME: Something may need to provide a proper writable location for the files. 
  • OpenSceneGraph/trunk/src/osgPlugins/ive/Image.cpp

    r11807 r12912  
    7373        out->writeInt(size); 
    7474        // Write the data 
    75         out->writeCharArray((char*)data(), size); 
     75        for(osg::Image::DataIterator itr(this); itr.valid(); ++itr) 
     76        { 
     77            out->writeCharArray((char*)itr.data(), itr.size()); 
     78        } 
    7679    } 
    7780 
  • OpenSceneGraph/trunk/src/osgPlugins/jp2/ReaderWriterJP2.cpp

    r12597 r12912  
    354354            if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED; 
    355355 
     356            if (!img.isDataContiguous()) 
     357            { 
     358                OSG_WARN<<"Warning: Writing of image data, that is non contiguous, is not supported by JPEG2000 plugin."<<std::endl; 
     359                return WriteResult::ERROR_IN_WRITING_FILE; 
     360            } 
     361 
    356362            jas_image_cmptparm_t cmptparms[4]; 
    357363            jas_image_cmptparm_t *cmptparm; 
     
    430436        WriteResult writeImage(const osg::Image& img, std::ostream& fout, const Options* options) const 
    431437        { 
     438            if (!img.isDataContiguous()) 
     439            { 
     440                OSG_WARN<<"Warning: Writing of image data, that is non contiguous, is not supported by JPEG2000 plugin."<<std::endl; 
     441                return WriteResult::ERROR_IN_WRITING_FILE; 
     442            } 
     443 
    432444            jas_image_cmptparm_t cmptparms[4]; 
    433445            jas_image_cmptparm_t *cmptparm; 
  • OpenSceneGraph/trunk/src/osgPlugins/jpeg/ReaderWriterJPEG.cpp

    r12545 r12912  
    648648        WriteResult::WriteStatus write_JPEG_file (std::ostream &fout, const osg::Image &img, int quality = 100) const 
    649649        { 
     650            if (!img.isDataContiguous()) 
     651            { 
     652                OSG_WARN<<"Warning: Writing of image data, that is non contiguous, is not supported by JPEG plugin."<<std::endl; 
     653                return WriteResult::ERROR_IN_WRITING_FILE; 
     654            } 
     655 
    650656            int image_width = img.s(); 
    651657            int image_height = img.t(); 
  • OpenSceneGraph/trunk/src/osgPlugins/logo/ReaderWriterLOGO.cpp

    r11516 r12912  
    153153                    { 
    154154                        osg::Image *img = (*p).get(); 
     155                        glPixelStorei(GL_UNPACK_ALIGNMENT, img->getPacking()); 
     156                        glPixelStorei(GL_UNPACK_ROW_LENGTH, img->getRowLength()); 
    155157                        x = place[i][0] + xi * img->s(); 
    156158                        if( i == Center || i == UpperLeft || i == UpperRight || i == UpperCenter) 
  • OpenSceneGraph/trunk/src/osgPlugins/nvtt/NVTTImageProcessor.cpp

    r12292 r12912  
    4747 
    4848    // Convert RGBA to BGRA : nvtt only accepts BGRA pixel format 
    49     void convertRGBAToBGRA( std::vector<unsigned char>& outputData, const unsigned char* inputData ); 
     49    void convertRGBAToBGRA( std::vector<unsigned char>& outputData, const osg::Image& image ); 
    5050 
    5151    // Convert RGB to BGRA : nvtt only accepts BGRA pixel format 
    52     void convertRGBToBGRA( std::vector<unsigned char>& outputData, const unsigned char* inputData ); 
     52    void convertRGBToBGRA( std::vector<unsigned char>& outputData, const osg::Image& image ); 
    5353 
    5454}; 
     
    176176 
    177177// Convert RGBA to BGRA : nvtt only accepts BGRA pixel format 
    178 void NVTTProcessor::convertRGBAToBGRA( std::vector<unsigned char>& outputData, const unsigned char* inputData ) 
    179 { 
    180     for (unsigned n=0; n<outputData.size(); n += 4) 
    181     { 
    182         outputData[n] = inputData[n+2]; 
    183         outputData[n+1] = inputData[n+1]; 
    184         outputData[n+2] = inputData[n]; 
    185         outputData[n+3] = inputData[n+3]; 
     178void NVTTProcessor::convertRGBAToBGRA( std::vector<unsigned char>& outputData, const osg::Image& image ) 
     179{ 
     180    unsigned int n=0; 
     181    for(int row=0; row<image.t(); ++row) 
     182    { 
     183        const unsigned char* data = image.data(0,row); 
     184        for(int column=0; column<image.s(); ++column) 
     185        { 
     186            outputData[n] = data[column*4+2]; 
     187            outputData[n+1] = data[column*4+1]; 
     188            outputData[n+2] = data[column*4+n]; 
     189            outputData[n+3] = data[column*4+3]; 
     190            n+=4; 
     191        } 
    186192    } 
    187193} 
    188194 
    189195// Convert RGB to BGRA : nvtt only accepts BGRA pixel format 
    190 void NVTTProcessor::convertRGBToBGRA( std::vector<unsigned char>& outputData, const unsigned char* inputData ) 
    191 { 
    192     unsigned int numberOfPixels = outputData.size()/4; 
    193     for (unsigned n=0; n<numberOfPixels; n++) 
    194     { 
    195         outputData[4*n] = inputData[3*n+2]; 
    196         outputData[4*n+1] = inputData[3*n+1]; 
    197         outputData[4*n+2] = inputData[3*n]; 
    198         outputData[4*n+3] = 255; 
     196void NVTTProcessor::convertRGBToBGRA( std::vector<unsigned char>& outputData, const osg::Image& image ) 
     197{ 
     198    unsigned int n=0; 
     199    for(int row=0; row<image.t(); ++row) 
     200    { 
     201        const unsigned char* data = image.data(0,row); 
     202        for(int column=0; column<image.s(); ++column) 
     203        { 
     204            outputData[n] = data[column*3+2]; 
     205            outputData[n+1] = data[column*3+1]; 
     206            outputData[n+2] = data[column*3+n]; 
     207            outputData[n+3] = 255; 
     208            n+=4; 
     209        } 
    199210    } 
    200211} 
     
    228239    if (image.getPixelFormat() == GL_RGB) 
    229240    { 
    230         convertRGBToBGRA( imageData, image.data() ); 
     241        convertRGBToBGRA( imageData, image ); 
    231242    } 
    232243    else 
    233244    { 
    234         convertRGBAToBGRA( imageData, image.data() ); 
     245        convertRGBAToBGRA( imageData, image ); 
    235246    } 
    236247    inputOptions.setMipmapData(&imageData[0],image.s(),image.t()); 
  • OpenSceneGraph/trunk/src/osgPlugins/pov/ReaderWriterPOV.cpp

    r12292 r12912  
    102102   if( !acceptsExtension( ext ) )  return WriteResult::FILE_NOT_HANDLED; 
    103103 
    104    notify( NOTICE ) << "ReaderWriterPOV::writeNode() Writing file " 
    105                     << fileName.data() << endl; 
     104   notify( NOTICE ) << "ReaderWriterPOV::writeNode() Writing file " << fileName << endl; 
    106105 
    107106   osgDB::ofstream fout( fileName.c_str(), ios::out | ios::trunc ); 
  • OpenSceneGraph/trunk/src/osgPlugins/rgb/ReaderWriterRGB.cpp

    r11563 r12912  
    661661        virtual WriteResult writeImage(const osg::Image& img,std::ostream& fout,const osgDB::ReaderWriter::Options*) const 
    662662        { 
     663            if (img.isCompressed()) 
     664            { 
     665                OSG_NOTICE<<"Warning: RGB plugin does not supporting writing compressed imagery."<<std::endl; 
     666                return WriteResult::ERROR_IN_WRITING_FILE; 
     667            } 
     668            if (!img.isDataContiguous()) 
     669            { 
     670                OSG_NOTICE<<"Warning: RGB plugin does not supporting writing non contiguous imagery."<<std::endl; 
     671                return WriteResult::ERROR_IN_WRITING_FILE; 
     672            } 
     673             
    663674            return writeRGBStream(img,fout,""); 
    664675        } 
     
    666677        virtual WriteResult writeImage(const osg::Image &img,const std::string& fileName, const osgDB::ReaderWriter::Options*) const 
    667678        { 
     679            if (img.isCompressed()) 
     680            { 
     681                OSG_NOTICE<<"Warning: RGB plugin does not supporting writing compressed imagery."<<std::endl; 
     682                return WriteResult::ERROR_IN_WRITING_FILE; 
     683            } 
     684            if (!img.isDataContiguous()) 
     685            { 
     686                OSG_NOTICE<<"Warning: RGB plugin does not supporting writing non contiguous imagery."<<std::endl; 
     687                return WriteResult::ERROR_IN_WRITING_FILE; 
     688            } 
     689 
    668690            std::string ext = osgDB::getFileExtension(fileName); 
    669691            if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED; 
  • OpenSceneGraph/trunk/src/osgPlugins/tga/ReaderWriterTGA.cpp

    r12574 r12912  
    546546        bool saveTGAStream(const osg::Image& image, std::ostream& fout) const 
    547547        { 
     548            if (!image.data()) return false; 
     549 
    548550            // At present, I will only save the image to unmapped RGB format 
    549551            // Other data types can be added soon with different options 
     
    554556            int numPerPixel = image.computeNumComponents(pixelFormat); 
    555557            int pixelMultiplier = (image.getDataType()==GL_FLOAT ? 255 : 1); 
    556             const unsigned char* data = image.data(); 
    557             if ( !data ) return false; 
    558558             
    559559            // Headers 
     
    582582            for (int y=0; y<height; ++y) 
    583583            { 
    584                 const unsigned char* ptr = data + y * width * numPerPixel; 
     584                const unsigned char* ptr = image.data(0,y); 
    585585                for (int x=0; x<width; ++x) 
    586586                { 
  • OpenSceneGraph/trunk/src/osgPlugins/xine/ReaderWriterXine.cpp

    r12262 r12912  
    193193            GLenum pixelFormat = GL_BGRA; 
    194194 
    195         #if 0    
    196             if (!imageStream->_ready) 
    197             { 
    198                 imageStream->allocateImage(width,height,1,pixelFormat,GL_UNSIGNED_BYTE,1); 
    199                 imageStream->setInternalTextureFormat(GL_RGBA); 
    200             } 
    201  
    202             osg::Timer_t start_tick = osg::Timer::instance()->tick(); 
    203  
    204             memcpy(imageStream->data(),data,imageStream->getTotalSizeInBytes()); 
    205  
    206             OSG_INFO<<"image memcpy size="<<imageStream->getTotalSizeInBytes()<<" time="<<osg::Timer::instance()->delta_m(start_tick,osg::Timer::instance()->tick())<<"ms"<<std::endl; 
    207  
    208  
    209             imageStream->dirty(); 
    210         #else 
    211              imageStream->setImage(width,height,1, 
     195            imageStream->setImage(width,height,1, 
    212196                              GL_RGB, 
    213197                              pixelFormat,GL_UNSIGNED_BYTE, 
     
    215199                              osg::Image::NO_DELETE, 
    216200                              1); 
    217         #endif 
     201 
    218202            imageStream->_ready = true; 
    219203        } 
  • OpenSceneGraph/trunk/src/osgText/Glyph.cpp

    r12407 r12912  
    475475 
    476476    glPixelStorei(GL_UNPACK_ALIGNMENT,getPacking()); 
     477    glPixelStorei(GL_UNPACK_ROW_LENGTH,getRowLength()); 
    477478 
    478479    glTexSubImage2D(GL_TEXTURE_2D,0,