RIFF.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *                                                                         *
00003  *   libgig - C++ cross-platform Gigasampler format file access library    *
00004  *                                                                         *
00005  *   Copyright (C) 2003-2011 by Christian Schoenebeck                      *
00006  *                              <cuse@users.sourceforge.net>               *
00007  *                                                                         *
00008  *   This library is free software; you can redistribute it and/or modify  *
00009  *   it under the terms of the GNU General Public License as published by  *
00010  *   the Free Software Foundation; either version 2 of the License, or     *
00011  *   (at your option) any later version.                                   *
00012  *                                                                         *
00013  *   This library is distributed in the hope that it will be useful,       *
00014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00016  *   GNU General Public License for more details.                          *
00017  *                                                                         *
00018  *   You should have received a copy of the GNU General Public License     *
00019  *   along with this library; if not, write to the Free Software           *
00020  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
00021  *   MA  02111-1307  USA                                                   *
00022  ***************************************************************************/
00023 
00024 #ifndef __RIFF_H__
00025 #define __RIFF_H__
00026 
00027 #ifdef WIN32
00028 # define POSIX 0
00029 #endif
00030 
00031 #ifndef POSIX
00032 # define POSIX 1
00033 #endif
00034 
00035 #ifndef DEBUG
00036 # define DEBUG 0
00037 #endif
00038 
00039 #include <string>
00040 #include <list>
00041 #include <map>
00042 #include <iostream>
00043 
00044 #ifdef HAVE_CONFIG_H
00045 # include <config.h>
00046 #endif
00047 
00048 #if POSIX
00049 # include <sys/types.h>
00050 # include <sys/stat.h>
00051 # include <fcntl.h>
00052 # include <unistd.h>
00053 #endif // POSIX
00054 
00055 #ifdef _MSC_VER
00056 // Visual C++ 2008 doesn't have stdint.h
00057 typedef __int8 int8_t;
00058 typedef __int16 int16_t;
00059 typedef __int32 int32_t;
00060 typedef __int64 int64_t;
00061 typedef unsigned __int8 uint8_t;
00062 typedef unsigned __int16 uint16_t;
00063 typedef unsigned __int32 uint32_t;
00064 typedef unsigned __int64 uint64_t;
00065 #else
00066 #include <stdint.h>
00067 #endif
00068 
00069 #ifdef WIN32
00070 # include <windows.h>
00071   typedef unsigned int   uint;
00072 #endif // WIN32
00073 
00074 #include <stdio.h>
00075 
00076 #if WORDS_BIGENDIAN
00077 # define CHUNK_ID_RIFF  0x52494646
00078 # define CHUNK_ID_RIFX  0x52494658
00079 # define CHUNK_ID_LIST  0x4C495354
00080 
00081 # define LIST_TYPE_INFO 0x494E464F
00082 # define CHUNK_ID_ICMT  0x49434D54
00083 # define CHUNK_ID_ICOP  0x49434F50
00084 # define CHUNK_ID_ICRD  0x49435244
00085 # define CHUNK_ID_IENG  0x49454E47
00086 # define CHUNK_ID_INAM  0x494E414D
00087 # define CHUNK_ID_IPRD  0x49505244
00088 # define CHUNK_ID_ISFT  0x49534654
00089 
00090 # define CHUNK_ID_SMPL  0x736D706C
00091 
00092 #else  // little endian
00093 # define CHUNK_ID_RIFF  0x46464952
00094 # define CHUNK_ID_RIFX  0x58464952
00095 # define CHUNK_ID_LIST  0x5453494C
00096 
00097 # define LIST_TYPE_INFO 0x4F464E49
00098 # define CHUNK_ID_ICMT  0x544D4349
00099 # define CHUNK_ID_ICOP  0x504F4349
00100 # define CHUNK_ID_ICRD  0x44524349
00101 # define CHUNK_ID_IENG  0x474E4549
00102 # define CHUNK_ID_INAM  0x4D414E49
00103 # define CHUNK_ID_IPRD  0x44525049
00104 # define CHUNK_ID_ISFT  0x54465349
00105 
00106 # define CHUNK_ID_SMPL  0x6C706D73
00107 
00108 #endif // WORDS_BIGENDIAN
00109 
00110 #define CHUNK_HEADER_SIZE       8
00111 #define LIST_HEADER_SIZE        12
00112 #define RIFF_HEADER_SIZE        12
00113 
00114 
00134 namespace RIFF {
00135 
00136     /* just symbol prototyping */
00137     class Chunk;
00138     class List;
00139     class File;
00140 
00141     typedef std::string String;
00142 
00144     typedef enum {
00145         stream_mode_read       = 0,
00146         stream_mode_read_write = 1,
00147         stream_mode_closed     = 2
00148     } stream_mode_t;
00149 
00151     typedef enum {
00152         stream_ready       = 0,
00153         stream_end_reached = 1,
00154         stream_closed      = 2
00155     } stream_state_t;
00156 
00158     typedef enum {
00159         stream_start    = 0,
00160         stream_curpos   = 1,
00161         stream_backward = 2,
00162         stream_end      = 3
00163     } stream_whence_t;
00164 
00166     typedef enum {
00167         endian_little = 0,
00168         endian_big    = 1,
00169         endian_native = 2
00170     } endian_t;
00171 
00177     class Chunk {
00178         public:
00179             Chunk(File* pFile, unsigned long StartPos, List* Parent);
00180             String         GetChunkIDString();
00181             uint32_t       GetChunkID() { return ChunkID; }             
00182             List*          GetParent()  { return pParent; }             
00183             unsigned long  GetSize()    { return CurrentChunkSize; }    
00184             unsigned long  GetNewSize() { return NewChunkSize;     }    
00185             unsigned long  GetPos()     { return ulPos; }               
00186             unsigned long  GetFilePos() { return ulStartPos + ulPos; }  
00187             unsigned long  SetPos(unsigned long Where, stream_whence_t Whence = stream_start);
00188             unsigned long  RemainingBytes();
00189             stream_state_t GetState();
00190             unsigned long  Read(void* pData, unsigned long WordCount, unsigned long WordSize);
00191             unsigned long  ReadInt8(int8_t* pData,     unsigned long WordCount = 1);
00192             unsigned long  ReadUint8(uint8_t* pData,   unsigned long WordCount = 1);
00193             unsigned long  ReadInt16(int16_t* pData,   unsigned long WordCount = 1);
00194             unsigned long  ReadUint16(uint16_t* pData, unsigned long WordCount = 1);
00195             unsigned long  ReadInt32(int32_t* pData,   unsigned long WordCount = 1);
00196             unsigned long  ReadUint32(uint32_t* pData, unsigned long WordCount = 1);
00197             int8_t         ReadInt8();
00198             uint8_t        ReadUint8();
00199             int16_t        ReadInt16();
00200             uint16_t       ReadUint16();
00201             int32_t        ReadInt32();
00202             uint32_t       ReadUint32();
00203             unsigned long  Write(void* pData, unsigned long WordCount, unsigned long WordSize);
00204             unsigned long  WriteInt8(int8_t* pData,     unsigned long WordCount = 1);
00205             unsigned long  WriteUint8(uint8_t* pData,   unsigned long WordCount = 1);
00206             unsigned long  WriteInt16(int16_t* pData,   unsigned long WordCount = 1);
00207             unsigned long  WriteUint16(uint16_t* pData, unsigned long WordCount = 1);
00208             unsigned long  WriteInt32(int32_t* pData,   unsigned long WordCount = 1);
00209             unsigned long  WriteUint32(uint32_t* pData, unsigned long WordCount = 1);
00210             void*          LoadChunkData();
00211             void           ReleaseChunkData();
00212             void           Resize(int iNewSize);
00213             virtual ~Chunk();
00214         protected:
00215             uint32_t      ChunkID;
00216             uint32_t      CurrentChunkSize;             /* in bytes */
00217             uint32_t      NewChunkSize;                 /* in bytes (if chunk was scheduled to be resized) */
00218             List*         pParent;
00219             File*         pFile;
00220             unsigned long ulStartPos;           /* actual position in file where chunk (without header) starts */
00221             unsigned long ulPos;                /* # of bytes from ulStartPos */
00222             uint8_t*      pChunkData;
00223             unsigned long ulChunkDataSize;
00224 
00225             Chunk(File* pFile);
00226             Chunk(File* pFile, List* pParent, uint32_t uiChunkID, uint uiBodySize);
00227             void          ReadHeader(unsigned long fPos);
00228             void          WriteHeader(unsigned long fPos);
00229             unsigned long ReadSceptical(void* pData, unsigned long WordCount, unsigned long WordSize);
00230             inline void   swapBytes_16(void* Word) {
00231                 uint8_t byteCache = *((uint8_t*) Word);
00232                 *((uint8_t*) Word)     = *((uint8_t*) Word + 1);
00233                 *((uint8_t*) Word + 1) = byteCache;
00234             }
00235             inline void   swapBytes_32(void* Word) {
00236                 uint8_t byteCache = *((uint8_t*) Word);
00237                 *((uint8_t*) Word)     = *((uint8_t*) Word + 3);
00238                 *((uint8_t*) Word + 3) = byteCache;
00239                 byteCache = *((uint8_t*) Word + 1);
00240                 *((uint8_t*) Word + 1) = *((uint8_t*) Word + 2);
00241                 *((uint8_t*) Word + 2) = byteCache;
00242             }
00243             inline void   swapBytes(void* Word, unsigned long WordSize) {
00244                 uint8_t byteCache;
00245                 unsigned long lo = 0, hi = WordSize - 1;
00246                 for (; lo < hi; hi--, lo++) {
00247                     byteCache = *((uint8_t*) Word + lo);
00248                     *((uint8_t*) Word + lo) = *((uint8_t*) Word + hi);
00249                     *((uint8_t*) Word + hi) = byteCache;
00250                 }
00251             }
00252             inline String convertToString(uint32_t word) {
00253                 String result;
00254                 for (int i = 0; i < 4; i++) {
00255                     uint8_t byte = *((uint8_t*)(&word) + i);
00256                     char c = byte;
00257                     result += c;
00258                 }
00259                 return result;
00260             }
00261             virtual unsigned long WriteChunk(unsigned long ulWritePos, unsigned long ulCurrentDataOffset);
00262             virtual void __resetPos(); 
00263 
00264             friend class List;
00265     };
00266 
00272     class List : public Chunk {
00273         public:
00274             List(File* pFile, unsigned long StartPos, List* Parent);
00275             String       GetListTypeString();
00276             uint32_t     GetListType() { return ListType; }   
00277             Chunk*       GetSubChunk(uint32_t ChunkID);
00278             List*        GetSubList(uint32_t ListType);
00279             Chunk*       GetFirstSubChunk();
00280             Chunk*       GetNextSubChunk();
00281             List*        GetFirstSubList();
00282             List*        GetNextSubList();
00283             unsigned int CountSubChunks();
00284             unsigned int CountSubChunks(uint32_t ChunkID);
00285             unsigned int CountSubLists();
00286             unsigned int CountSubLists(uint32_t ListType);
00287             Chunk*       AddSubChunk(uint32_t uiChunkID, uint uiBodySize);
00288             List*        AddSubList(uint32_t uiListType);
00289             void         DeleteSubChunk(Chunk* pSubChunk);
00290             void         MoveSubChunk(Chunk* pSrc, Chunk* pDst);
00291             virtual ~List();
00292         protected:
00293             typedef std::map<uint32_t, RIFF::Chunk*>  ChunkMap;
00294             typedef std::list<Chunk*>                 ChunkList;
00295 
00296             uint32_t   ListType;
00297             ChunkList* pSubChunks;
00298             ChunkMap*  pSubChunksMap;
00299             ChunkList::iterator ChunksIterator;
00300             ChunkList::iterator ListIterator;
00301 
00302             List(File* pFile);
00303             List(File* pFile, List* pParent, uint32_t uiListID);
00304             void ReadHeader(unsigned long fPos);
00305             void WriteHeader(unsigned long fPos);
00306             void LoadSubChunks();
00307             void LoadSubChunksRecursively();
00308             virtual unsigned long WriteChunk(unsigned long ulWritePos, unsigned long ulCurrentDataOffset);
00309             virtual void __resetPos(); 
00310             void DeleteChunkList();
00311     };
00312 
00319     class File : public List {
00320         public:
00321             File(uint32_t FileType);
00322             File(const String& path);
00323             stream_mode_t GetMode();
00324             bool          SetMode(stream_mode_t NewMode);
00325             void SetByteOrder(endian_t Endian);
00326             String GetFileName();
00327             virtual void Save();
00328             virtual void Save(const String& path);
00329             virtual ~File();
00330         protected:
00331             #if POSIX
00332             int    hFileRead;  
00333             int    hFileWrite; 
00334             #elif defined(WIN32)
00335             HANDLE hFileRead;  
00336             HANDLE hFileWrite; 
00337             #else
00338             FILE*  hFileRead;  
00339             FILE*  hFileWrite; 
00340             #endif // POSIX
00341             String Filename;
00342             bool   bEndianNative;
00343 
00344             void LogAsResized(Chunk* pResizedChunk);
00345             void UnlogResized(Chunk* pResizedChunk);
00346             friend class Chunk;
00347             friend class List;
00348         private:
00349             stream_mode_t  Mode;
00350             ChunkList ResizedChunks; 
00351 
00352             unsigned long GetFileSize();
00353             void ResizeFile(unsigned long ulNewSize);
00354             #if POSIX
00355             unsigned long __GetFileSize(int hFile);
00356             #elif defined(WIN32)
00357             unsigned long __GetFileSize(HANDLE hFile);
00358             #else
00359             unsigned long __GetFileSize(FILE* hFile);
00360             #endif
00361             void Cleanup();
00362     };
00363 
00367     class Exception {
00368         public:
00369             String Message;
00370 
00371             Exception(String Message) { Exception::Message = Message; }
00372             void PrintMessage();
00373             virtual ~Exception() {}
00374     };
00375 
00376     String libraryName();
00377     String libraryVersion();
00378 
00379 } // namespace RIFF
00380 #endif // __RIFF_H__

Generated on Sun May 1 03:22:46 2011 for libgig by  doxygen 1.5.2