Diffstat (limited to 'src/iii-extract-riff-chunk.cc') (more/less context) (ignore whitespace changes)
-rw-r--r-- | src/iii-extract-riff-chunk.cc | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/src/iii-extract-riff-chunk.cc b/src/iii-extract-riff-chunk.cc index 3a06db2..d53170d 100644 --- a/src/iii-extract-riff-chunk.cc +++ b/src/iii-extract-riff-chunk.cc @@ -1,114 +1,114 @@ /* vim:set sw=8 nosi noai cin cino=:0,l1,g0: */ #include <stdint.h> #include <stdlib.h> #include <getopt.h> #include <cstring> #include <iostream> #include <fstream> #include <stdexcept> #include <cassert> #include <list> #include <string> #include <iterator> #include "config.h" #define PHEADER \ PACKAGE " Version " VERSION "\n" \ - "Copyright (c) 2009-2010 Klever Group" + "Copyright (c) 2009-2011 Klever Group" typedef uint32_t fourcc_type; enum fourcc_value { fourcc_RIFF = 0x46464952, fourcc_AVI = 0x20495641, fourcc_LIST = 0x5453494c, fourcc_hdrl = 0x6c726468, fourcc_strl = 0x6c727473, fourcc_ncdt = 0x7464636e, fourcc_ncvr = 0x7276636e, fourcc_nctg = 0x6774636e, fourcc_ncth = 0x6874636e }; fourcc_type str2fourcc(const char *str) { fourcc_type rv = 0; return *(fourcc_type*)strncpy((char*)&rv,str,sizeof(rv)); } const std::string fourcc2str(fourcc_type fcc) { char rv[sizeof(fcc)+1]; *(fourcc_type*)rv = fcc; rv[sizeof(fcc)]=0; return rv; } #pragma pack(1) struct riff_sized_head { fourcc_type fourcc; uint32_t size; }; #pragma pack() class exceptional_success : public std::exception { }; struct riff { struct chunk_type { riff_sized_head head; uint32_t left; chunk_type(riff& r) { r.read(&head); left = head.size; } }; std::istream *in; typedef std::list<chunk_type> chunks_type; chunks_type chunks; riff(std::istream& i) : in(&i) { } protected: int begin_chunk() { chunks.push_back( chunk_type(*this) ); return chunks.size(); } void end_chunk(int level) { assert(in); assert(chunks.size()==level); std::streamsize o = chunks.back().left; chunks.pop_back(); if(!o) return; in->seekg(o,std::ios::cur); for(chunks_type::iterator i=chunks.begin(),ie=chunks.end() ;i!=ie; (i++)->left -= o) ; } void read(void *p,size_t n) { assert(in); if( (!chunks.empty()) && chunks.back().left < n) throw std::runtime_error("attempt to read beyond the end of chunk"); if(!in->read((char*)p,n)) throw std::runtime_error("failed to read()"); std::streamsize gc = in->gcount(); for(chunks_type::iterator i=chunks.begin(),ie=chunks.end();i!=ie;++i) { i->left -= gc; assert(i->left >= 0); } if(gc!=n) throw std::runtime_error("incomplete read()"); } template<typename T> void read(T* v) { read(v,sizeof(*v)); } friend class scoped_chunk; }; struct scoped_chunk { riff& rs; int level; riff::chunks_type::reverse_iterator chunk_iterator; scoped_chunk(riff& rs_) : rs(rs_), level(rs.begin_chunk()), chunk_iterator(rs.chunks.rbegin()) { } ~scoped_chunk() { rs.end_chunk(level); } riff::chunk_type& chunk() { return *chunk_iterator; } fourcc_type get_chunk_id() { return chunk().head.fourcc; } bool has(uint32_t bytes=1) { return chunk().left >= bytes; } template<typename T> T read() { T rv; rs.read(&rv); return rv; } template<typename T> void read(T& t) { rs.read(&t); } void read(void *p,size_t n) { rs.read(p,n); } |