ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

iff_container.cpp

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "common/iff_container.h"
00024 #include "common/substream.h"
00025 #include "common/util.h"
00026 
00027 namespace Common {
00028 
00029 IFFParser::IFFParser(ReadStream *stream, bool disposeStream) : _stream(stream), _disposeStream(disposeStream) {
00030     setInputStream(stream);
00031 }
00032 
00033 IFFParser::~IFFParser() {
00034     if (_disposeStream) {
00035         delete _stream;
00036     }
00037     _stream = nullptr;
00038 }
00039 
00040 void IFFParser::setInputStream(ReadStream *stream) {
00041     assert(stream);
00042     _formChunk.setInputStream(stream);
00043     _chunk.setInputStream(stream);
00044 
00045     _formChunk.readHeader();
00046     if (_formChunk.id != ID_FORM) {
00047         error("IFFParser input is not a FORM type IFF file");
00048     }
00049     _formSize = _formChunk.size;
00050     _formType = _formChunk.readUint32BE();
00051 }
00052 
00053 void IFFParser::parse(IFFCallback &callback) {
00054     bool stop;
00055     do {
00056         _chunk.feed();
00057         _formChunk.incBytesRead(_chunk.size);
00058 
00059         if (_formChunk.hasReadAll()) {
00060             break;
00061         }
00062 
00063         _formChunk.incBytesRead(8);
00064         _chunk.readHeader();
00065 
00066         // invoke the callback
00067         SubReadStream stream(&_chunk, _chunk.size);
00068         IFFChunk chunk(_chunk.id, _chunk.size, &stream);
00069         stop = callback(chunk);
00070 
00071         // eats up all the remaining data in the chunk
00072         while (!stream.eos()) {
00073             stream.readByte();
00074         }
00075 
00076     } while (!stop);
00077 }
00078 
00079 
00080 PackBitsReadStream::PackBitsReadStream(Common::ReadStream &input) : _input(&input) {
00081 }
00082 
00083 PackBitsReadStream::~PackBitsReadStream() {
00084 }
00085 
00086 bool PackBitsReadStream::eos() const {
00087     return _input->eos();
00088 }
00089 
00090 uint32 PackBitsReadStream::read(void *dataPtr, uint32 dataSize) {
00091     byte *out = (byte *)dataPtr;
00092     uint32 left = dataSize;
00093 
00094     uint32 lenR = 0, lenW = 0;
00095     while (left > 0 && !_input->eos()) {
00096         lenR = _input->readByte();
00097 
00098         if (lenR == 128) {
00099             // no-op
00100             lenW = 0;
00101         } else if (lenR <= 127) {
00102             // literal run
00103             lenR++;
00104             lenW = MIN(lenR, left);
00105             for (uint32 j = 0; j < lenW; j++) {
00106                 *out++ = _input->readByte();
00107             }
00108             for (; lenR > lenW; lenR--) {
00109                 _input->readByte();
00110             }
00111         } else {  // len > 128
00112             // expand run
00113             lenW = MIN((256 - lenR) + 1, left);
00114             byte val = _input->readByte();
00115             memset(out, val, lenW);
00116             out += lenW;
00117         }
00118 
00119         left -= lenW;
00120     }
00121 
00122     return dataSize - left;
00123 }
00124 
00125 } // End of namespace Common


Generated on Sat May 18 2019 05:01:04 for ResidualVM by doxygen 1.7.1
curved edge   curved edge