⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 readerwritergif.cpp

📁 最新osg包
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <osg/Image>#include <osg/ImageStream>#include <osg/Notify>#include <osg/Geode>#include <osg/GL>#include <osgDB/FileNameUtils>#include <osgDB/FileUtils>#include <osgDB/Registry>#include <OpenThreads/Thread>/**************************************************************************** * * Follows is code extracted from the simage library.  Original Authors: * *      Systems in Motion, *      <URL:http://www.sim.no> * *      Peder Blekken <pederb@sim.no> *      Morten Eriksen <mortene@sim.no> *      Marius Bugge Monsen <mariusbu@sim.no> * * The original COPYING notice * *      All files in this library are public domain, except simage_rgb.cpp which is *      Copyright (c) Mark J Kilgard <mjk@nvidia.com>. I will contact Mark *      very soon to hear if this source also can become public domain. * *      Please send patches for bugs and new features to: <pederb@sim.no>. * *      Peder Blekken * * * Ported into the OSG as a plugin, Robert Osfield Decemeber 2000. * Note, reference above to license of simage_rgb is not relevent to the OSG * as the OSG does not use it.  Also for patches, bugs and new features * please send them direct to the OSG dev team rather than address above. * **********************************************************************//*!  GIF loader, using libungif  Based, in part, on source code found in libungif, gif2rgb.c*/#include <stdlib.h>#include <string.h>#include <stdio.h>extern  "C"{    #include <gif_lib.h>}#define ERR_NO_ERROR     0#define ERR_OPEN         1#define ERR_READ         2#define ERR_MEM          3#define MY_GIF_DEBUG 1// GifImageStream class class GifImageStream : public osg::ImageStream, public OpenThreads::Thread{public:    GifImageStream()         : _length(0), _dataNum(0), _frameNum(0),         _done(false), _currentLength(0), _multiplier(1.0),        osg::ImageStream()    {        _status=PAUSED;    }    virtual Object* clone() const { return new GifImageStream; }    virtual bool isSameKindAs( const Object* obj ) const     { return dynamic_cast<const GifImageStream*>(obj) != NULL; }    virtual const char* className() const { return "GifImageStream"; }    virtual void play()     {         if (!isRunning())             start();        _status=PLAYING;     }    virtual void pause() { _status=PAUSED; }    virtual void rewind() { setReferenceTime( 0.0 ); }    virtual void quit( bool waitForThreadToExit=true )     {        _done = true;        if ( waitForThreadToExit )        {            while( isRunning() )                OpenThreads::Thread::YieldCurrentThread();            osg::notify(osg::DEBUG_INFO)<<"GifImageStream thread quitted"<<std::endl;        }    }    StreamStatus getStatus() { return _status; }    virtual double getLength() const { return _length*0.01*_multiplier; }    // Go to a specific position of stream    virtual void setReferenceTime( double time )     {        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);        int i=1;        int framePos = static_cast<int>(time*100.0/_multiplier);        if ( framePos>=(int)_length )            framePos = _length;        std::vector<FrameData*>::iterator it;        for ( it=_dataList.begin(); it!=_dataList.end(); it++,i++ )        {            framePos -= (*it)->delay;            if ( framePos<0 )                break;        }        _dataNum = i-1;        _frameNum = (*it)->delay+framePos;        setNewImage();    }    virtual double getReferenceTime() const { return _currentLength*0.01*_multiplier; }    // Speed up, slow down or back to normal (1.0)    virtual void setTimeMultiplier( double m )     {        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);        if ( m>0 )            _multiplier = m;    }    virtual double getTimeMultiplier() const { return _multiplier; }        // Not used in GIF animation    virtual void setVolume(float) {}    virtual float getVolume() const { return 0.0f; }    virtual void run()    {        _dataIter = _dataList.begin();        while ( !_done )        {            if ( _status==PLAYING && (*_dataIter) )            {                if ( _frameNum>=(*_dataIter)->delay )                {                    _frameNum = 0;                    if ( _dataNum>=_dataList.size()-1 )                    {                        if ( getLoopingMode()==LOOPING )                        {                            _dataNum = 0;                            _currentLength = 0;                        }                    }                    else                        _dataNum++;                    setNewImage();                }                else                {                    _frameNum++;                    _currentLength++;                }                OpenThreads::Thread::microSleep(static_cast<int>(10000.0f*_multiplier));            }            else                OpenThreads::Thread::microSleep(150000L);        }    }    void addToImageStream( int ss, int tt, int rr, int numComponents, int delayTime, unsigned char* imgData )    {        if ( isRunning() )        {            osg::notify(osg::WARN)<<"GifImageStream::addToImageStream: thread is running!"<<std::endl;            return;        }        _s = ss;        _t = tt;        _r = rr;        _internalFormat = numComponents;        _dataType = GL_UNSIGNED_BYTE;        _pixelFormat =            numComponents == 1 ? GL_LUMINANCE :            numComponents == 2 ? GL_LUMINANCE_ALPHA :            numComponents == 3 ? GL_RGB :            numComponents == 4 ? GL_RGBA : (GLenum)-1;        if ( _dataList.empty() )        {            // Set image texture for the first time            setImage(_s,_t,_r,_internalFormat,_pixelFormat,_dataType,                imgData,osg::Image::NO_DELETE,1);        }        FrameData* newData = new FrameData;        newData->delay = delayTime;        newData->data = imgData;        _dataList.push_back( newData );        _length += delayTime;    }protected:    typedef struct    {        unsigned int delay;        unsigned char* data;    } FrameData;    void setNewImage()    {        _dataIter = _dataList.begin()+_dataNum;        if ( *_dataIter )        {            unsigned char* image = (*_dataIter)->data;            setImage(_s,_t,_r,_internalFormat,_pixelFormat,_dataType,                image,osg::Image::NO_DELETE,1);            dirty();        }    }    virtual ~GifImageStream()     {        if( isRunning() )            quit( true );        std::vector<FrameData*>::iterator it;        for ( it=_dataList.begin(); it!=_dataList.end(); it++ )        {            delete (*it)->data;            delete (*it);        }    }    double _multiplier;    unsigned int _currentLength;    unsigned int _length;    unsigned int _frameNum;    unsigned int _dataNum;    std::vector<FrameData*> _dataList;    std::vector<FrameData*>::iterator _dataIter;    int _s;    int _t;    int _r;    int _internalFormat;    unsigned int _pixelFormat;    unsigned int _dataType;    bool _done;    OpenThreads::Mutex _mutex;};static int giferror = ERR_NO_ERROR;intsimage_gif_error(char * buffer, int buflen){    switch (giferror)    {        case ERR_OPEN:            strncpy(buffer, "GIF loader: Error opening file", buflen);            break;        case ERR_READ:            strncpy(buffer, "GIF loader: Error reading file", buflen);            break;        case ERR_MEM:            strncpy(buffer, "GIF loader: Out of memory error", buflen);            break;    }    return giferror;}intsimage_gif_identify(const char *,const unsigned char *header,int headerlen){    static unsigned char gifcmp[] = {'G', 'I', 'F'};    if (headerlen < 3) return 0;    if (memcmp((const void*)header,        (const void*)gifcmp, 3) == 0) return 1;    return 0;}static voiddecode_row(GifFileType * giffile,unsigned char * buffer,unsigned char * rowdata,int x, int y, int len,int transparent){    GifColorType * cmentry;    ColorMapObject * colormap;    int colormapsize;    unsigned char col;    unsigned char * ptr;    y = giffile->SHeight - (y+1);    ptr = buffer + (giffile->SWidth * y + x) * 4;    colormap = (giffile->Image.ColorMap        ? giffile->Image.ColorMap        : giffile->SColorMap);    colormapsize = colormap ? colormap->ColorCount : 255;    while (len--)    {        col = *rowdata++;                                 /* just in case */        if (col >= colormapsize) col = 0;                if ( col == transparent )        {            // keep pixels of last image if transparent mode is on            // this is necessary for GIF animating             ptr += 3;        }        else        {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -