summaryrefslogtreecommitdiffabout
path: root/src/iii-extract-riff-chunk.cc
Unidiff
Diffstat (limited to 'src/iii-extract-riff-chunk.cc') (more/less context) (ignore whitespace changes)
-rw-r--r--src/iii-extract-riff-chunk.cc2
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 @@
1/* vim:set sw=8 nosi noai cin cino=:0,l1,g0: */ 1/* vim:set sw=8 nosi noai cin cino=:0,l1,g0: */
2#include <stdint.h> 2#include <stdint.h>
3#include <stdlib.h> 3#include <stdlib.h>
4#include <getopt.h> 4#include <getopt.h>
5#include <cstring> 5#include <cstring>
6#include <iostream> 6#include <iostream>
7#include <fstream> 7#include <fstream>
8#include <stdexcept> 8#include <stdexcept>
9#include <cassert> 9#include <cassert>
10#include <list> 10#include <list>
11#include <string> 11#include <string>
12#include <iterator> 12#include <iterator>
13 13
14#include "config.h" 14#include "config.h"
15 15
16#define PHEADER \ 16#define PHEADER \
17 PACKAGE " Version " VERSION "\n" \ 17 PACKAGE " Version " VERSION "\n" \
18 "Copyright (c) 2009-2010 Klever Group" 18 "Copyright (c) 2009-2011 Klever Group"
19 19
20typedef uint32_t fourcc_type; 20typedef uint32_t fourcc_type;
21enum fourcc_value { 21enum fourcc_value {
22 fourcc_RIFF = 0x46464952, fourcc_AVI = 0x20495641, fourcc_LIST = 0x5453494c, 22 fourcc_RIFF = 0x46464952, fourcc_AVI = 0x20495641, fourcc_LIST = 0x5453494c,
23 fourcc_hdrl = 0x6c726468, fourcc_strl = 0x6c727473, 23 fourcc_hdrl = 0x6c726468, fourcc_strl = 0x6c727473,
24 fourcc_ncdt = 0x7464636e, fourcc_ncvr = 0x7276636e, fourcc_nctg = 0x6774636e, fourcc_ncth = 0x6874636e 24 fourcc_ncdt = 0x7464636e, fourcc_ncvr = 0x7276636e, fourcc_nctg = 0x6774636e, fourcc_ncth = 0x6874636e
25}; 25};
26 26
27fourcc_type str2fourcc(const char *str) { 27fourcc_type str2fourcc(const char *str) {
28 fourcc_type rv = 0; 28 fourcc_type rv = 0;
29 return *(fourcc_type*)strncpy((char*)&rv,str,sizeof(rv)); 29 return *(fourcc_type*)strncpy((char*)&rv,str,sizeof(rv));
30} 30}
31const std::string fourcc2str(fourcc_type fcc) { 31const std::string fourcc2str(fourcc_type fcc) {
32 char rv[sizeof(fcc)+1]; 32 char rv[sizeof(fcc)+1];
33 *(fourcc_type*)rv = fcc; 33 *(fourcc_type*)rv = fcc;
34 rv[sizeof(fcc)]=0; 34 rv[sizeof(fcc)]=0;
35 return rv; 35 return rv;
36} 36}
37 37
38#pragma pack(1) 38#pragma pack(1)
39struct riff_sized_head { 39struct riff_sized_head {
40 fourcc_type fourcc; 40 fourcc_type fourcc;
41 uint32_t size; 41 uint32_t size;
42}; 42};
43#pragma pack() 43#pragma pack()
44 44
45class exceptional_success : public std::exception { }; 45class exceptional_success : public std::exception { };
46 46
47struct riff { 47struct riff {
48 struct chunk_type { 48 struct chunk_type {
49 riff_sized_head head; 49 riff_sized_head head;
50 uint32_t left; 50 uint32_t left;
51 51
52 chunk_type(riff& r) { 52 chunk_type(riff& r) {
53 r.read(&head); 53 r.read(&head);
54 left = head.size; 54 left = head.size;
55 } 55 }
56 }; 56 };
57 57
58 std::istream *in; 58 std::istream *in;
59 typedef std::list<chunk_type> chunks_type; 59 typedef std::list<chunk_type> chunks_type;
60 chunks_type chunks; 60 chunks_type chunks;
61 61
62 riff(std::istream& i) : in(&i) { } 62 riff(std::istream& i) : in(&i) { }
63 63
64 protected: 64 protected:
65 65
66 int begin_chunk() { 66 int begin_chunk() {
67 chunks.push_back( chunk_type(*this) ); 67 chunks.push_back( chunk_type(*this) );
68 return chunks.size(); 68 return chunks.size();
69 } 69 }
70 void end_chunk(int level) { 70 void end_chunk(int level) {
71 assert(in); assert(chunks.size()==level); 71 assert(in); assert(chunks.size()==level);
72 std::streamsize o = chunks.back().left; 72 std::streamsize o = chunks.back().left;
73 chunks.pop_back(); 73 chunks.pop_back();
74 if(!o) return; 74 if(!o) return;
75 in->seekg(o,std::ios::cur); 75 in->seekg(o,std::ios::cur);
76 for(chunks_type::iterator i=chunks.begin(),ie=chunks.end() ;i!=ie; (i++)->left -= o) ; 76 for(chunks_type::iterator i=chunks.begin(),ie=chunks.end() ;i!=ie; (i++)->left -= o) ;
77 } 77 }
78 78
79 void read(void *p,size_t n) { 79 void read(void *p,size_t n) {
80 assert(in); 80 assert(in);
81 if( (!chunks.empty()) && chunks.back().left < n) 81 if( (!chunks.empty()) && chunks.back().left < n)
82 throw std::runtime_error("attempt to read beyond the end of chunk"); 82 throw std::runtime_error("attempt to read beyond the end of chunk");
83 if(!in->read((char*)p,n)) 83 if(!in->read((char*)p,n))
84 throw std::runtime_error("failed to read()"); 84 throw std::runtime_error("failed to read()");
85 std::streamsize gc = in->gcount(); 85 std::streamsize gc = in->gcount();
86 for(chunks_type::iterator i=chunks.begin(),ie=chunks.end();i!=ie;++i) { 86 for(chunks_type::iterator i=chunks.begin(),ie=chunks.end();i!=ie;++i) {
87 i->left -= gc; assert(i->left >= 0); 87 i->left -= gc; assert(i->left >= 0);
88 } 88 }
89 if(gc!=n) throw std::runtime_error("incomplete read()"); 89 if(gc!=n) throw std::runtime_error("incomplete read()");
90 } 90 }
91 91
92 template<typename T> void read(T* v) { read(v,sizeof(*v)); } 92 template<typename T> void read(T* v) { read(v,sizeof(*v)); }
93 93
94 friend class scoped_chunk; 94 friend class scoped_chunk;
95 95
96}; 96};
97 97
98struct scoped_chunk { 98struct scoped_chunk {
99 riff& rs; 99 riff& rs;
100 int level; 100 int level;
101 riff::chunks_type::reverse_iterator chunk_iterator; 101 riff::chunks_type::reverse_iterator chunk_iterator;
102 102
103 scoped_chunk(riff& rs_) : rs(rs_), level(rs.begin_chunk()), chunk_iterator(rs.chunks.rbegin()) { } 103 scoped_chunk(riff& rs_) : rs(rs_), level(rs.begin_chunk()), chunk_iterator(rs.chunks.rbegin()) { }
104 ~scoped_chunk() { rs.end_chunk(level); } 104 ~scoped_chunk() { rs.end_chunk(level); }
105 105
106 riff::chunk_type& chunk() { return *chunk_iterator; } 106 riff::chunk_type& chunk() { return *chunk_iterator; }
107 107
108 fourcc_type get_chunk_id() { return chunk().head.fourcc; } 108 fourcc_type get_chunk_id() { return chunk().head.fourcc; }
109 bool has(uint32_t bytes=1) { return chunk().left >= bytes; } 109 bool has(uint32_t bytes=1) { return chunk().left >= bytes; }
110 110
111 template<typename T> T read() { T rv; rs.read(&rv); return rv; } 111 template<typename T> T read() { T rv; rs.read(&rv); return rv; }
112 template<typename T> void read(T& t) { rs.read(&t); } 112 template<typename T> void read(T& t) { rs.read(&t); }
113 void read(void *p,size_t n) { rs.read(p,n); } 113 void read(void *p,size_t n) { rs.read(p,n); }
114 114