root/OpenSceneGraph/trunk/src/osgDB/Compressors.cpp @ 13041

Revision 13041, 4.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-2010 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// Written by Wang Rui, (C) 2010
14
15#include <osg/Notify>
16#include <osgDB/Registry>
17#include <osgDB/Registry>
18#include <osgDB/ObjectWrapper>
19#include <sstream>
20
21using namespace osgDB;
22
23// Example compressor copying data to/from stream directly
24class NullCompressor : public BaseCompressor
25{
26public:
27    NullCompressor() {}
28
29    virtual bool compress( std::ostream& fout, const std::string& src )
30    {
31        int size = src.size();
32        fout.write( (char*)&size, INT_SIZE );
33        fout.write( src.c_str(), src.size() );
34        return true;
35    }
36
37    virtual bool decompress( std::istream& fin, std::string& target )
38    {
39        int size = 0; fin.read( (char*)&size, INT_SIZE );
40        if ( size )
41        {
42            target.resize( size );
43            fin.read( (char*)target.c_str(), size );
44        }
45        return true;
46    }
47};
48
49REGISTER_COMPRESSOR( "null", NullCompressor )
50
51#ifdef USE_ZLIB
52
53#include <zlib.h>
54
55#define CHUNK 32768
56
57// ZLib compressor
58class ZLibCompressor : public BaseCompressor
59{
60public:
61    ZLibCompressor() {}
62
63    virtual bool compress( std::ostream& fout, const std::string& src )
64    {
65        int ret, flush = Z_FINISH;
66        unsigned have;
67        z_stream strm;
68        unsigned char out[CHUNK];
69
70        int level = 6;
71        int stategy = Z_DEFAULT_STRATEGY;
72
73        /* allocate deflate state */
74        strm.zalloc = Z_NULL;
75        strm.zfree = Z_NULL;
76        strm.opaque = Z_NULL;
77        ret = deflateInit2( &strm, level, Z_DEFLATED,
78                           15+16, // +16 to use gzip encoding
79                           8, // default
80                           stategy );
81        if ( ret != Z_OK ) return false;
82
83        strm.avail_in = src.size();
84        strm.next_in = (Bytef*)( &(*src.begin()) );
85
86        /* run deflate() on input until output buffer not full, finish
87           compression if all of source has been read in */
88        do
89        {
90            strm.avail_out = CHUNK;
91            strm.next_out = out;
92            ret = deflate(&strm, flush);    /* no bad return value */
93
94            if ( ret == Z_STREAM_ERROR )
95            {
96                OSG_NOTICE << "Z_STREAM_ERROR" << std::endl;
97                return false;
98            }
99
100            have = CHUNK - strm.avail_out;
101            if ( have>0 ) fout.write( (const char*)out, have );
102
103            if ( fout.fail() )
104            {
105                (void)deflateEnd( &strm );
106                return false;
107            }
108        } while ( strm.avail_out==0 );
109
110        /* clean up and return */
111        (void)deflateEnd( &strm );
112        return true;
113    }
114
115    virtual bool decompress( std::istream& fin, std::string& target )
116    {
117        int ret;
118        unsigned have;
119        z_stream strm;
120        unsigned char in[CHUNK];
121        unsigned char out[CHUNK];
122
123        /* allocate inflate state */
124        strm.zalloc = Z_NULL;
125        strm.zfree = Z_NULL;
126        strm.opaque = Z_NULL;
127        strm.avail_in = 0;
128        strm.next_in = Z_NULL;
129        ret = inflateInit2( &strm,
130                            15 + 32 ); // autodected zlib or gzip header
131
132        if ( ret!=Z_OK )
133        {
134            OSG_INFO << "failed to init" << std::endl;
135            return ret!=0;
136        }
137
138        /* decompress until deflate stream ends or end of file */
139        do
140        {
141            fin.read( (char *)in, CHUNK );
142            strm.avail_in = fin.gcount();
143            if (strm.avail_in==0 ) break;
144
145            /* run inflate() on input until output buffer not full */
146            strm.next_in = in;
147            do
148            {
149                strm.avail_out = CHUNK;
150                strm.next_out = out;
151                ret = inflate( &strm, Z_NO_FLUSH );
152
153                switch (ret)
154                {
155                case Z_NEED_DICT:
156                case Z_DATA_ERROR:
157                case Z_MEM_ERROR:
158                    (void)inflateEnd( &strm );
159                    return false;
160                }
161                have = CHUNK - strm.avail_out;
162                target.append( (char*)out, have );
163            } while ( strm.avail_out==0 );
164
165            /* done when inflate() says it's done */
166        } while ( ret!=Z_STREAM_END );
167
168        /* clean up and return */
169        (void)inflateEnd( &strm );
170        return ret==Z_STREAM_END ? true : false;
171    }
172};
173
174REGISTER_COMPRESSOR( "zlib", ZLibCompressor )
175
176#endif
Note: See TracBrowser for help on using the browser.