Logo Search packages:      
Sourcecode: scummvm version File versions  Download package

iff_container.h

/* ScummVM - Graphic Adventure Engine
 *
 * ScummVM is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/tags/release-1-0-0/common/iff_container.h $
 * $Id: iff_container.h 41474 2009-06-12 10:26:58Z peres001 $
 */

#ifndef COMMON_IFF_CONTAINER_H
#define COMMON_IFF_CONTAINER_H

#include "common/scummsys.h"
#include "common/endian.h"
#include "common/func.h"
#include "common/stream.h"
#include "common/util.h"

namespace Common {

typedef uint32 IFF_ID;

#define ID_FORM     MKID_BE('FORM')
/* EA IFF 85 group identifier */
#define ID_CAT      MKID_BE('CAT ')
/* EA IFF 85 group identifier */
#define ID_LIST     MKID_BE('LIST')
/* EA IFF 85 group identifier */
#define ID_PROP     MKID_BE('PROP')
/* EA IFF 85 group identifier */
#define ID_END      MKID_BE('END ')
/* unofficial END-of-FORM identifier (see Amiga RKM Devices Ed.3
page 376) */
#define ID_ILBM     MKID_BE('ILBM')
/* EA IFF 85 raster bitmap form */
#define ID_DEEP     MKID_BE('DEEP')
/* Chunky pixel image files (Used in TV Paint) */
#define ID_RGB8     MKID_BE('RGB8')
/* RGB image forms, Turbo Silver (Impulse) */
#define ID_RGBN     MKID_BE('RGBN')
/* RGB image forms, Turbo Silver (Impulse) */
#define ID_PBM      MKID_BE('PBM ')
/* 256-color chunky format (DPaint 2 ?) */
#define ID_ACBM     MKID_BE('ACBM')
/* Amiga Contiguous Bitmap (AmigaBasic) */
#define ID_8SVX     MKID_BE('8SVX')
/* Amiga 8 bits voice */

/* generic */

#define ID_FVER     MKID_BE('FVER')
/* AmigaOS version string */
#define ID_JUNK     MKID_BE('JUNK')
/* always ignore this chunk */
#define ID_ANNO     MKID_BE('ANNO')
/* EA IFF 85 Generic Annotation chunk */
#define ID_AUTH     MKID_BE('AUTH')
/* EA IFF 85 Generic Author chunk */
#define ID_CHRS     MKID_BE('CHRS')
/* EA IFF 85 Generic character string chunk */
#define ID_NAME     MKID_BE('NAME')
/* EA IFF 85 Generic Name of art, music, etc. chunk */
#define ID_TEXT     MKID_BE('TEXT')
/* EA IFF 85 Generic unformatted ASCII text chunk */
#define ID_copy     MKID_BE('(c) ')
/* EA IFF 85 Generic Copyright text chunk */

/* ILBM chunks */

#define ID_BMHD     MKID_BE('BMHD')
/* ILBM BitmapHeader */
#define ID_CMAP     MKID_BE('CMAP')
/* ILBM 8bit RGB colormap */
#define ID_GRAB     MKID_BE('GRAB')
/* ILBM "hotspot" coordiantes */
#define ID_DEST     MKID_BE('DEST')
/* ILBM destination image info */
#define ID_SPRT     MKID_BE('SPRT')
/* ILBM sprite identifier */
#define ID_CAMG     MKID_BE('CAMG')
/* Amiga viewportmodes */
#define ID_BODY     MKID_BE('BODY')
/* ILBM image data */
#define ID_CRNG     MKID_BE('CRNG')
/* color cycling */
#define ID_CCRT     MKID_BE('CCRT')
/* color cycling */
#define ID_CLUT     MKID_BE('CLUT')
/* Color Lookup Table chunk */
#define ID_DPI      MKID_BE('DPI ')
/* Dots per inch chunk */
#define ID_DPPV     MKID_BE('DPPV')
/* DPaint perspective chunk (EA) */
#define ID_DRNG     MKID_BE('DRNG')
/* DPaint IV enhanced color cycle chunk (EA) */
#define ID_EPSF     MKID_BE('EPSF')
/* Encapsulated Postscript chunk */
#define ID_CMYK     MKID_BE('CMYK')
/* Cyan, Magenta, Yellow, & Black color map (Soft-Logik) */
#define ID_CNAM     MKID_BE('CNAM')
/* Color naming chunk (Soft-Logik) */
#define ID_PCHG     MKID_BE('PCHG')
/* Line by line palette control information (Sebastiano Vigna) */
#define ID_PRVW     MKID_BE('PRVW')
/* A mini duplicate ILBM used for preview (Gary Bonham) */
#define ID_XBMI     MKID_BE('XBMI')
/* eXtended BitMap Information (Soft-Logik) */
#define ID_CTBL     MKID_BE('CTBL')
/* Newtek Dynamic Ham color chunk */
#define ID_DYCP     MKID_BE('DYCP')
/* Newtek Dynamic Ham chunk */
#define ID_SHAM     MKID_BE('SHAM')
/* Sliced HAM color chunk */
#define ID_ABIT     MKID_BE('ABIT')
/* ACBM body chunk */
#define ID_DCOL     MKID_BE('DCOL')
/* unofficial direct color */
#define ID_DPPS     MKID_BE('DPPS')
/* ? */
#define ID_TINY     MKID_BE('TINY')
/* ? */
#define ID_DPPV     MKID_BE('DPPV')
/* ? */

/* 8SVX chunks */

#define ID_VHDR     MKID_BE('VHDR')
/* 8SVX Voice8Header */


char * ID2string(Common::IFF_ID id);


/**
 *  Represents a IFF chunk available to client code.
 *
 *  Client code must *not* deallocate _stream when done.
 */
00154 struct IFFChunk {
      Common::IFF_ID                _type;
      uint32                              _size;
      Common::ReadStream            *_stream;

      IFFChunk(Common::IFF_ID type, uint32 size, Common::ReadStream *stream) : _type(type), _size(size), _stream(stream) {
            assert(_stream);
      }
};

/**
 *  Parser for IFF containers.
 */
00167 class IFFParser {

      /**
       *  This private class implements IFF chunk navigation.
       */
00172       class IFFChunkNav : public Common::ReadStream {
      protected:
            Common::ReadStream *_input;
            uint32 _bytesRead;
      public:
            Common::IFF_ID id;
            uint32 size;

            IFFChunkNav() : _input(0) {
            }
            void setInputStream(Common::ReadStream *input) {
                  _input = input;
                  size = _bytesRead = 0;
            }
            void incBytesRead(uint32 inc) {
                  _bytesRead += inc;
                  if (_bytesRead > size) {
                        error("Chunk overread");
                  }
            }
            void readHeader() {
                  id = _input->readUint32BE();
                  size = _input->readUint32BE();
                  _bytesRead = 0;
            }
            bool hasReadAll() const {
                  return (size - _bytesRead) == 0;
            }
            void feed() {
                  if (size % 2) {
                        size++;
                  }
                  while (!hasReadAll()) {
                        readByte();
                  }
            }
            // Common::ReadStream implementation
00209             bool eos() const { return _input->eos(); }
00210             bool err() const { return _input->err(); }
00211             void clearErr() { _input->clearErr(); }

00213             uint32 read(void *dataPtr, uint32 dataSize) {
                  incBytesRead(dataSize);
                  return _input->read(dataPtr, dataSize);
            }
      };

protected:
00220       IFFChunkNav _formChunk; //!< The root chunk of the file.
00221       IFFChunkNav _chunk;     //!< The current chunk.

      uint32 _formSize;
      Common::IFF_ID _formType;

      Common::ReadStream *_stream;
      bool _disposeStream;

      void setInputStream(Common::ReadStream *stream) {
            assert(stream);
            _formChunk.setInputStream(stream);
            _chunk.setInputStream(stream);

            _formChunk.readHeader();
            if (_formChunk.id != ID_FORM) {
                  error("IFFParser input is not a FORM type IFF file");
            }
            _formSize = _formChunk.size;
            _formType = _formChunk.readUint32BE();
      }

public:
      IFFParser(Common::ReadStream *stream, bool disposeStream = false) : _stream(stream), _disposeStream(disposeStream) {
            setInputStream(stream);
      }
      ~IFFParser() {
            if (_disposeStream) {
                  delete _stream;
            }
            _stream = 0;
      }

      /**
       * Returns the IFF FORM type.
       * @return the IFF FORM type of the stream, or 0 if FORM header is not found.
       */
      Common::IFF_ID getFORMType() const;

      /**
       * Returns the size of the data.
       * @return the size of the data in file, or -1 if FORM header is not found.
       */
      uint32 getFORMSize() const;

      /**
       * Callback type for the parser.
       */
00268       typedef Common::Functor1< IFFChunk&, bool > IFFCallback;

      /**
       * Parse the IFF container, invoking the callback on each chunk encountered.
       * The callback can interrupt the parsing by returning 'true'.
       */
00274       void parse(IFFCallback &callback) {
            bool stop;
            do {
                  _chunk.feed();
                  _formChunk.incBytesRead(_chunk.size);

                  if (_formChunk.hasReadAll()) {
                        break;
                  }

                  _formChunk.incBytesRead(8);
                  _chunk.readHeader();

                  // invoke the callback
                  Common::SubReadStream stream(&_chunk, _chunk.size);
                  IFFChunk chunk(_chunk.id, _chunk.size, &stream);
                  stop = callback(chunk);

                  // eats up all the remaining data in the chunk
                  while (!stream.eos()) {
                        stream.readByte();
                  }

            } while (!stop);
      }
};


} // namespace Common

#endif

Generated by  Doxygen 1.6.0   Back to index