cgv
Loading...
Searching...
No Matches
image_reader.cxx
1#include "image_reader.h"
2#include <cgv/base/register.h>
3#include <cgv/utils/scan.h>
4#include <vector>
5
6using namespace cgv::base;
7using namespace cgv::data;
8using namespace cgv::utils;
9
10namespace cgv {
11 namespace media {
12 namespace image {
13
14
17{
18 return false;
19}
20
23{
24 return 1;
25}
26
27
30{
31 return 0;
32}
33
36{
37 return 0;
38}
39
42{
43 return idx == 0;
44}
45
48{
49 return false;
50}
51
54{
55 static std::vector<base_ptr>& ref_readers()
56 {
57 static std::vector<base_ptr> readers;
58 return readers;
59 }
60 std::string get_type_name() const { return "image_reader_listener"; }
61
62 void register_object(base_ptr object, const std::string&)
63 {
64 if (object->get_interface<abst_image_reader>())
65 ref_readers().push_back(object);
66 }
67 void unregister_object(base_ptr object, const std::string&)
68 {
69 for (unsigned int i=0; i<ref_readers().size(); ++i) {
70 if (object == ref_readers()[i]) {
71 ref_readers().erase(ref_readers().begin()+i);
72 ++i;
73 }
74 }
75 }
76};
77
79image_reader::image_reader(data_format& file_format, std::vector<data_format>* _palette_formats)
80 : file_format_ptr(&file_format), palette_formats(_palette_formats), rd(0)
81{
82}
83
85const std::string& image_reader::get_supported_extensions(char sep)
86{
87 static std::string exts;
88 exts.clear();
89 std::vector<base_ptr>& readers = reader_listener::ref_readers();
90 for (unsigned int i=0; i<readers.size(); ++i) {
91 if (!exts.empty())
92 exts += ';';
93 exts += readers[i]->get_interface<abst_image_reader>()->get_supported_extensions();
94 }
95 if (sep != ';')
96 cgv::utils::replace(exts,';',sep);
97 return exts;
98}
99
102{
103 std::string text = "Image Files (";
104 std::string exts = "*.";
105 text += get_supported_extensions(',');
106 text += "):";
107 exts += get_supported_extensions(',');
108 replace(exts,",",";*.");
109 return text+exts;
110}
111
113const std::string& image_reader::get_last_error() const
114{
115 if (!rd)
116 return last_error;
117 return rd->get_last_error();
118}
119
121bool image_reader::read_image(const std::string& file_name, data_view& dv, std::vector<data_view> *palettes)
122{
123 if (!open(file_name) || file_format_ptr->empty())
124 return false;
125 if (!read_image(dv, palettes) || !close())
126 return false;
127 return true;
128}
129
131bool image_reader::read_image(const std::string& file_name, const data_view& dv, const std::vector<data_view> *palettes)
132{
133 if (dv.empty() || !open(file_name) || file_format_ptr->empty())
134 return false;
135 if (!read_image(dv, palettes) || !close())
136 return false;
137 return true;
138}
139
141bool image_reader::open(const std::string& file_name)
142{
143 if (!file_format_ptr)
144 return false;
145 std::string::size_type pos = file_name.find_last_of('.');
146 if (pos == std::string::npos)
147 return false;
148 std::string ext = to_lower(file_name.substr(pos+1));
149 std::vector<base_ptr>& readers = reader_listener::ref_readers();
150 std::stringstream all_supported_extensions("");
151 for (unsigned int i=0; i<readers.size(); ++i) {
152 if (i != readers.size() - 1) {
153 all_supported_extensions << ":";
154 }
155 const std::string &supported_extensions = readers[i]->get_interface<abst_image_reader>()->get_supported_extensions();
156 all_supported_extensions << supported_extensions;
157 if (cgv::utils::is_element(ext, supported_extensions)) {
158 rd = readers[i]->get_interface<abst_image_reader>()->clone();
159 return rd->open(file_name, *file_format_ptr, palette_formats);
160 }
161 }
162 last_error = "could not find a suitable reader for " + file_name + " (supported formats are " +
163 all_supported_extensions.str() + ")";
164 return false;
165}
166
172
175{
176 return false;
177}
178
181{
182 if (!rd)
183 return 1;
184 return rd->get_nr_images();
185}
186
189{
190 if (!rd)
191 return 0;
192 return rd->get_image_duration();
193}
194
197{
198 if (!rd)
199 return 0;
200 return rd->get_current_image();
201}
202
204bool image_reader::seek_image(unsigned idx)
205{
206 if (!rd)
207 return idx == 0;
208 return rd->seek_image(idx);
209}
210
212bool image_reader::read_palette(unsigned int i, data_view& dv)
213{
214 if (!rd || !palette_formats || i > palette_formats->size())
215 return false;
216 if (dv.empty())
217 new(&dv) data_view(&palette_formats->at(i));
218 return rd->read_palette(i,dv);
219}
220
222bool image_reader::read_palette(unsigned int i, const data_view& dv)
223{
224 if (!rd || !palette_formats || i > palette_formats->size() || dv.empty())
225 return false;
226 return rd->read_palette(i,dv);
227}
228
231{
232 if (!rd)
233 return false;
234 return rd->supports_per_line_read();
235}
236
239{
240 if (!rd)
241 return false;
242 if (dv.empty()) {
243 data_view dv_all(file_format_ptr,0);
244 dv = dv_all(0);
245 dv.set_ptr(new unsigned char[file_format_ptr->get_width()*
246 file_format_ptr->get_entry_size()], true);
247 }
248 return rd->read_line(*file_format_ptr, dv);
249}
250
252{
253 if (!rd || dv.empty())
254 return false;
255 return rd->read_line(*file_format_ptr, dv);
256}
257
259bool image_reader::read_image(data_view& dv, std::vector<data_view> *palettes)
260{
261 if (!rd)
262 return false;
263 if (dv.empty())
264 new(&dv) data_view(file_format_ptr);
265
266 if (palette_formats && palettes) {
267 for (unsigned i=0; i<palette_formats->size(); ++i) {
268 palettes->push_back(data_view());
269 if (!read_palette(i, palettes->back()))
270 return false;
271 }
272 }
273 return rd->read_image(*file_format_ptr, dv);
274}
275
277bool image_reader::read_image(const data_view& dv, const std::vector<data_view> *palettes)
278{
279 if (!rd || dv.empty())
280 return false;
281
282 if (palette_formats) {
283 if (!palettes)
284 return false;
285 if (palettes->size() != palette_formats->size())
286 return false;
287 for (unsigned i=0; i<palette_formats->size(); ++i) {
288 if (!read_palette(i, palettes->at(i)))
289 return false;
290 }
291 }
292 return rd->read_image(*file_format_ptr, dv);
293}
294
297{
298 if (!rd)
299 return false;
300 return rd->close();
301}
302
305{
306 if (rd)
307 return rd->get_type_name();
308 return "cmi::image_reader";
309}
310
312{
313 if (rd)
314 return rd->get_property_declarations();
316}
317
319bool image_reader::set_void(const std::string& property, const std::string& type, const void* value)
320{
321 if (rd)
322 return rd->set_void(property, type, value);
323 return cgv::base::base::set_void(property, type, value);
324}
325
326bool image_reader::get_void(const std::string& property, const std::string& type, void* value)
327{
328 if (rd)
329 return rd->get_void(property, type, value);
330 return cgv::base::base::get_void(property, type, value);
331}
332
333object_registration<reader_listener> rlr("register image reader registry");
334
335 }
336 }
337}
base class for all classes that can be registered with support for dynamic properties (see also secti...
Definition base.h:75
virtual std::string get_property_declarations()
return a semicolon separated list of property declarations
Definition base.cxx:264
T * get_interface()
use dynamic type cast to check for the given interface
Definition base.h:128
virtual bool set_void(const std::string &property, const std::string &value_type, const void *value_ptr)
abstract interface for the setter of a dynamic property.
Definition base.cxx:181
virtual bool get_void(const std::string &property, const std::string &value_type, void *value_ptr)
abstract interface for the getter of a dynamic property.
Definition base.cxx:215
A data_format describes a multidimensional data block of data entries.
Definition data_format.h:17
bool empty() const
return whether the data pointer is a null pointer
the data view gives access to a data array of one, two, three or four dimensions.
Definition data_view.h:153
void set_ptr(unsigned char *ptr, bool manage_ptr)
set a different data pointer that will be deleted with the delete [] operator of type (unsigned char*...
abstract interface for image readers
virtual float get_image_duration() const
return the duration of the current image in seconds, if returned value is 0, no duration is available
virtual bool read_palette(unsigned int i, const cgv::data::data_view &dv)
read the i-th palette in case of a paletted file format, the standard implementation returns false
virtual bool supports_multiple_images() const
whether the file can contain several images
virtual unsigned get_current_image() const
return the index of the current image
virtual bool seek_image(unsigned idx)
jump to a specific image and return whether this was successful
virtual unsigned get_nr_images() const
return the number of images in the file, what can cause the whole file to be scanned
std::string last_error
last error message in case no reader is available
std::vector< cgv::data::data_format > * palette_formats
store a pointer to the palette format vector
unsigned get_current_image() const
return the index of the current image
cgv::data::data_format * file_format_ptr
store the data format
bool supports_multiple_images() const
whether the file can contain several images
unsigned get_nr_images() const
return the number of images in the file, what can cause the whole file to be scanned
const std::string & get_last_error() const
return a reference to the last error message
bool read_image(const std::string &file_name, cgv::data::data_view &dv, std::vector< cgv::data::data_view > *palettes=0)
read the whole image into the given data view.
static std::string construct_filter_string()
use this to generate a file_open_dialog or file_save_dialog
float get_image_duration() const
return the duration of the current image in seconds, if returned value is 0, no duration is available
bool read_line(cgv::data::data_view &dv)
read the next line into the given data view.
bool close()
close the image file
image_reader(cgv::data::data_format &file_format, std::vector< cgv::data::data_format > *palette_formats=0)
construct an image reader from a reference to a data format instance in which the format of the image...
bool read_palette(unsigned int i, cgv::data::data_view &dv)
read the i-th palette in case of a paletted file format, and handle the data view as in the read_imag...
cgv::data::data_format * get_file_format() const
return the data format of the image file
static const std::string & get_supported_extensions(char sep=';')
return a string with a list of supported extensions, where the list entries are separated with the pa...
bool set_void(const std::string &property, const std::string &type, const void *value)
abstract interface for the setter, by default it simply returns false
bool open(const std::string &file_name)
open the file and read the image header in order to determine the data format of the file,...
bool get_void(const std::string &property, const std::string &type, void *value)
abstract interface for the getter, by default it simply returns false
abst_image_reader * rd
store a pointer to the chosen reader
std::string get_type_name() const
overload to return the type name of this object
bool seek_image(unsigned idx)
jump to a specific image and return whether this was successful
std::string get_property_declarations()
return a semicolon separated list of property declarations of the form "name:type",...
bool supports_per_line_read() const
return whether the reader supports per line reading (only valid after successfully opening an image f...
the base namespace holds the base hierarchy, support for plugin registration and signals
Definition action.cxx:4
data::ref_ptr< base, true > base_ptr
ref counted pointer to base
Definition base.h:37
namespace for data management components
namespace for image processing
namespace for compile time type information
Definition bool32_t.h:7
namespace that holds tools that dont fit any other namespace
unsigned int replace(std::string &s, char c1, char c2)
replace char c1 with c2 in the given string _s and return number of replacements
Definition scan.cxx:241
char to_lower(char c)
convert char to lower case
Definition scan.cxx:39
bool is_element(char c, const std::string &s)
check if char c arises in string s
Definition scan.cxx:373
this header is dependency free
Definition print.h:11
Helper functions to process strings.
convenience class to register an object of the given class type
Definition register.h:159
interfaces that allows to listen to registration events.
Definition register.h:218
interfaces that add provides very basic functionality.
Definition register.h:203
interfaces that allows to listen to registration events
std::string get_type_name() const
overload to return the type name of this object. By default the type interface is queried over get_ty...
void unregister_object(base_ptr object, const std::string &)
overload to handle unregistration events
void register_object(base_ptr object, const std::string &)
overload to handle registration events