| 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 | |
|---|
| 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 | |
|---|
| | 237 | bool 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 | |
|---|
| | 300 | bool 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]; |
|---|
| 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 | |
|---|