cgv
Loading...
Searching...
No Matches
riff.cxx
1#include "riff.h"
2
3#pragma warning (disable:4996)
4
5namespace cgv {
6 namespace media {
7
8
9unsigned fourcc::make_id(const std::string& ascii)
10{
11 std::string s = ascii;
12 while (s.size() < 4)
13 s += ' ';
14 unsigned id = (unsigned&)(s[0]);
15 return id;
16}
17
18std::string fourcc::to_string() const
19{
20 return std::string((char*)&id, 4);
21}
22
23bool fourcc::operator == (const std::string& s) const
24{
25 return id == make_id(s);
26}
27
28bool fourcc::operator != (const std::string& s) const
29{
30 return id != make_id(s);
31}
32
33std::ostream& operator << (std::ostream& os, const fourcc& f)
34{
35 return os << f.to_string();
36}
37
38bool riff_handler::begin_list_chunk(fourcc id, unsigned size, fourcc hdr) { return true; }
39bool riff_handler::process_chunk_header(fourcc id, unsigned size, void*& data_ptr) { return true; }
40void riff_handler::process_chunk_data(fourcc id, unsigned size, void* data_ptr) { }
41void riff_handler::end_list_chunk(fourcc id, unsigned size, fourcc hdr) { }
42
44{
45}
46
47bool riff_reader::read_chunk_info(fourcc& id, unsigned& size)
48{
49 if (fread(&id, 1, 4, fp) != 4) {
50 fclose(fp);
51 return false;
52 }
53 if (fread(&size, 1, 4, fp) != 4) {
54 fclose(fp);
55 return false;
56 }
57 return true;
58}
59
60bool riff_reader::read_chunk_list(unsigned list_size)
61{
62 while (list_size > 0) {
63
64 fourcc id;
65 unsigned size;
66 if (!read_chunk_info(id, size))
67 return false;
68 unsigned size_correct = size;
69 if ((size & 1) == 1)
70 size_correct += 1;
71
72 list_size -= 8+size_correct;
73
74 if (id == "LIST") {
75 fourcc hdr;
76 if (fread(&hdr, 1, 4, fp) != 4) {
77 close();
78 return false;
79 }
80 if (rh->begin_list_chunk(id, size, hdr)) {
81 if (!read_chunk_list(size-4))
82 return false;
83 rh->end_list_chunk(id, size, hdr);
84 }
85 else {
86 if (fseek(fp, size-4, SEEK_CUR) != 0) {
87 close();
88 return false;
89 }
90 }
91 }
92 else {
93 void* data_ptr = 0;
94 unsigned char* data;
95 if (id != "JUNK" && rh->process_chunk_header(id, size, data_ptr)) {
96 if (data_ptr == 0)
97 data = new unsigned char [size];
98 else
99 data = (unsigned char*) data_ptr;
100
101 if (fread(data, 1, size, fp) != size) {
102 close();
103 return false;
104 }
105
106 if (size_correct > size)
107 fseek(fp, 1, SEEK_CUR);
108
109 rh->process_chunk_data(id, size, data);
110
111 if (data_ptr == 0)
112 delete [] data;
113 }
114 else {
115 if (fseek(fp, size, SEEK_CUR) != 0) {
116 close();
117 return false;
118 }
119 }
120 }
121 }
122 return true;
123}
124
125void riff_reader::close()
126{
127 fclose(fp);
128 fp = 0;
129}
130
131bool riff_reader::read(const std::string& file_name)
132{
133 if (!rh)
134 return false;
135
136 fp = fopen(file_name.c_str(), "rb");
137 if (fp == 0)
138 return false;
139
140 fourcc id;
141 unsigned size;
142 if (!read_chunk_info(id, size))
143 return false;
144
145 if (id != "RIFF") {
146 close();
147 return false;
148 }
149
150 fourcc hdr;
151 if (fread(&hdr, 1, 4, fp) != 4) {
152 close();
153 return false;
154 }
155
156 if (!rh->begin_list_chunk(id, size, hdr)) {
157 close();
158 return false;
159 }
160
161 if (read_chunk_list(size-4))
162 close();
163
164 rh->end_list_chunk(id, size, hdr);
165 return true;
166}
167
168 }
169}
bool read(const std::string &file_name)
read given file and generate callbacks to the riff_handler, return whether read was successful
Definition riff.cxx:131
riff_reader(riff_handler *_rh)
construct from riff_handler
Definition riff.cxx:43
the cgv namespace
Definition print.h:11
represents fourcc ids as used in the riff format to identify chunks
Definition riff.h:14
unsigned id
store fourcc as 32 bit integer
Definition riff.h:17
bool operator!=(const std::string &s) const
compare with string
Definition riff.cxx:28
bool operator==(const std::string &s) const
compare with string
Definition riff.cxx:23
std::string to_string() const
convert to string
Definition riff.cxx:18
callback handler passed to riff reader
Definition riff.h:35
virtual bool begin_list_chunk(fourcc id, unsigned size, fourcc hdr)
this is called when riff or list chunk is started, return whether to process list elements (default r...
Definition riff.cxx:38
virtual void process_chunk_data(fourcc id, unsigned size, void *data_ptr)
if process_chunk_header returned true, this callback is called to process chunk data
Definition riff.cxx:40
virtual void end_list_chunk(fourcc id, unsigned size, fourcc hdr)
called to mark the end of a list chunk
Definition riff.cxx:41
virtual bool process_chunk_header(fourcc id, unsigned size, void *&data_ptr)
this is called before data of chunk is read, return whether to process chunk data (default return is ...
Definition riff.cxx:39