Changeset 9021

Show
Ignore:
Timestamp:
10/10/08 14:01:54
Author:
robert
Message:

Moved compress/uncompress code across to using gzip compatible methods

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • OpenSceneGraph/trunk/src/osgPlugins/gz/ReaderWriterGZ.cpp

    r9020 r9021  
    104104        WriteResult writeFile(ObjectType objectType, const osg::Object* object, const std::string& fullFileName, const osgDB::ReaderWriter::Options* options) const; 
    105105 
     106 
     107        bool read(std::istream& fin, std::string& destination) const; 
     108        bool write(std::ostream& fout, const std::string& source) const; 
     109         
     110 
    106111}; 
    107112 
     
    170175    if (!fin) return ReadResult::ERROR_IN_READING_FILE; 
    171176     
    172     std::streampos start = fin.tellg(); 
    173     fin.seekg(0, std::ios::end); 
    174     std::streampos end = fin.tellg(); 
    175     fin.seekg(start, std::ios::beg); 
    176     std::streampos sourceLen = end - start; 
    177  
    178     /* empty stream into memory, open that, and keep the pointer in a FreeTypeFont for cleanup */ 
    179     char* buffer = new char[sourceLen]; 
    180     fin.read(reinterpret_cast<char*>(buffer), sourceLen); 
    181     if (!fin || (static_cast<std::streampos>(fin.gcount()) != sourceLen)) 
    182     { 
    183         osg::notify(osg::WARN)<<" .... the compressed file could not be read from its stream"<<std::endl; 
    184         return 0; 
    185     } 
    186      
    187     uLongf destLen = 1000000; 
    188      
     177 
    189178    std::string dest; 
    190     dest.resize(destLen); 
    191          
    192     int result = uncompress ((Bytef *)(&(*dest.begin())), &destLen, 
    193                              (const Bytef *)buffer, sourceLen); 
    194                                     
    195     delete [] buffer; 
     179    read(fin, dest); 
    196180 
    197181    std::stringstream strstream(dest); 
     
    242226    osgDB::ReaderWriter::WriteResult writeResult = writeFile(objectType, object, rw, strstream, options); 
    243227     
    244      
    245     std::string str(strstream.str()); 
    246      
    247     uLong destLen = compressBound(str.size()); 
    248      
    249     osg::notify(osg::NOTICE)<<"compressBound("<<str.size()<<") = "<<destLen<<std::endl; 
    250      
    251     std::string output; 
    252     output.resize(destLen); 
     228    std::ofstream fout(fullFileName.c_str()); 
     229     
     230    write(fout,strstream.str()); 
     231     
     232    return writeResult; 
     233
     234 
     235#define CHUNK 16384 
     236 
     237bool ReaderWriterGZ::read(std::istream& fin, std::string& destination) const 
     238
     239    int ret; 
     240    unsigned have; 
     241    z_stream strm; 
     242    unsigned char in[CHUNK]; 
     243    unsigned char out[CHUNK]; 
     244 
     245    /* allocate inflate state */ 
     246    strm.zalloc = Z_NULL; 
     247    strm.zfree = Z_NULL; 
     248    strm.opaque = Z_NULL; 
     249    strm.avail_in = 0; 
     250    strm.next_in = Z_NULL; 
     251    ret = inflateInit2(&strm, 
     252                       15 + 32 // autodected zlib or gzip header 
     253                       ); 
     254    if (ret != Z_OK) 
     255        return ret; 
     256 
     257    /* decompress until deflate stream ends or end of file */ 
     258    do { 
     259 
     260        osg::notify(osg::NOTICE)<<"Doing readsome"<<std::endl; 
     261 
     262        strm.avail_in = fin.readsome((char*)in, CHUNK); 
     263 
     264        if (fin.fail()) 
     265        { 
     266            (void)inflateEnd(&strm); 
     267            return false; 
     268        } 
     269        if (strm.avail_in == 0) 
     270            break; 
     271        strm.next_in = in; 
     272 
     273        /* run inflate() on input until output buffer not full */ 
     274        do { 
     275            strm.avail_out = CHUNK; 
     276            strm.next_out = out; 
     277            ret = inflate(&strm, Z_NO_FLUSH); 
     278 
     279            switch (ret) { 
     280            case Z_NEED_DICT: 
     281            case Z_DATA_ERROR: 
     282            case Z_MEM_ERROR: 
     283                (void)inflateEnd(&strm); 
     284                return false; 
     285            } 
     286            have = CHUNK - strm.avail_out; 
     287 
     288            destination.append((char*)out, have); 
     289             
     290        } while (strm.avail_out == 0); 
     291 
     292        /* done when inflate() says it's done */ 
     293    } while (ret != Z_STREAM_END); 
     294 
     295    /* clean up and return */ 
     296    (void)inflateEnd(&strm); 
     297    return ret == Z_STREAM_END ? true : false; 
     298
     299 
     300bool ReaderWriterGZ::write(std::ostream& fout, const std::string& source) const 
     301
     302    int ret, flush = Z_FINISH; 
     303    unsigned have; 
     304    z_stream strm; 
     305    unsigned char out[CHUNK]; 
    253306     
    254307    int level = 6; 
    255      
    256     char* source = new char[str.size()]; 
    257     char* dest = new char[destLen]; 
    258  
    259     int result = compress2( (Bytef *)(&(*output.begin())), &destLen, 
    260                             (const Bytef *)(&(*str.begin())), str.size(), 
    261                              level); 
    262  
    263     osg::notify(osg::NOTICE)<<"compress2()"<<result<<", destLen="<<destLen<<std::endl; 
    264      
    265     output.resize(destLen); 
    266      
    267     std::ofstream fout(fullFileName.c_str());     
    268     fout<<output; 
    269  
    270     return writeResult; 
    271 
     308    int stategy = Z_DEFAULT_STRATEGY; // looks to be the best for .osg/.ive files 
     309    //int stategy = Z_FILTERED; 
     310    //int stategy = Z_HUFFMAN_ONLY; 
     311    //int stategy = Z_RLE; 
     312 
     313    /* allocate deflate state */ 
     314    strm.zalloc = Z_NULL; 
     315    strm.zfree = Z_NULL; 
     316    strm.opaque = Z_NULL; 
     317    ret = deflateInit2(&strm,  
     318                       level, 
     319                       Z_DEFLATED, 
     320                       15+16, // +16 to use gzip encoding 
     321                       8, // default 
     322                       stategy); 
     323    if (ret != Z_OK) 
     324    return false; 
     325 
     326    strm.avail_in = source.size(); 
     327    strm.next_in = (Bytef*)(&(*source.begin())); 
     328 
     329    /* run deflate() on input until output buffer not full, finish 
     330       compression if all of source has been read in */ 
     331    do { 
     332        strm.avail_out = CHUNK; 
     333        strm.next_out = out; 
     334        ret = deflate(&strm, flush);    /* no bad return value */ 
     335 
     336        if (ret == Z_STREAM_ERROR) 
     337        { 
     338            osg::notify(osg::NOTICE)<<"Z_STREAM_ERROR"<<std::endl; 
     339            return false; 
     340        } 
     341 
     342        have = CHUNK - strm.avail_out; 
     343 
     344        if (have>0) fout.write((const char*)out, have); 
     345         
     346        if (fout.fail()) 
     347        { 
     348            (void)deflateEnd(&strm); 
     349            return false; 
     350        } 
     351    } while (strm.avail_out == 0); 
     352 
     353    /* clean up and return */ 
     354    (void)deflateEnd(&strm); 
     355    return true; 
     356
     357 
    272358 
    273359// now register with Registry to instantiate the above