Fawkes API Fawkes Development Version
fileloader.cpp
1
2/***************************************************************************
3 * fileloader.cpp - A camera which obtains its images from a single image
4 * file or from several image files in a directory
5 *
6 * Generated: Tue Feb 22 13:28:08 2005
7 * Copyright 2005-2007 Tim Niemueller [www.niemueller.de]
8 * 2008 Daniel Beck
9 *
10 ****************************************************************************/
11
12/* This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version. A runtime exception applies to
16 * this software (see LICENSE.GPL_WRE file mentioned below for details).
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Library General Public License for more details.
22 *
23 * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
24 */
25
26#include <core/exception.h>
27#include <core/exceptions/software.h>
28#include <core/exceptions/system.h>
29#include <fvcams/fileloader.h>
30#include <fvutils/colormap/cmfile.h>
31#include <fvutils/colormap/colormap.h>
32#include <fvutils/readers/fvraw.h>
33#include <fvutils/system/camargp.h>
34#include <fvutils/system/filetype.h>
35#include <fvutils/writers/fvraw.h>
36#ifdef HAVE_LIBJPEG
37# include <fvutils/readers/jpeg.h>
38#endif
39#ifdef HAVE_LIBPNG
40# include <fvutils/readers/png.h>
41#endif
42
43#include <sys/types.h>
44
45#include <cstdio>
46#include <cstdlib>
47#include <cstring>
48
49using namespace fawkes;
50
51namespace firevision {
52
53/** @class FileLoader <fvcams/fileloader.h>
54 * Load images from files.
55 * The file loader tries to determine the image format of the given image using
56 * the the file type utility. Currently it recognizes JPEG and FvRaw image files.
57 *
58 * @author Tim Niemueller
59 * @author Daniel Beck
60 */
61
62char *FileLoader::extension = NULL;
63
64#if defined(__GLIBC__) || defined(__FreeBSD__)
65int
66file_select(const struct dirent *ent)
67#else
68int
69file_select(struct dirent *ent)
70#endif
71{
72 if (!FileLoader::extension) {
73 return 1;
74 }
75
76 // NOTE: this only checks whether the filename contains the
77 // extension and not whether it ends with it.
78 if (NULL != strstr(ent->d_name, FileLoader::extension)) {
79 return 1;
80 }
81
82 return 0;
83}
84
85/** Constructor.
86 * @param filename name of file to open, full path or relative to working directory
87 */
88FileLoader::FileLoader(const char *filename)
89{
90 this->filename = strdup(filename);
91 this->dirname = NULL;
92 this->extension = NULL;
93 this->file_list = NULL;
94 num_files = 0;
95 cur_file = 0;
96 opened = started = false;
97 width = height = 0;
98 file_buffer = NULL;
99 this->cspace = CS_UNKNOWN;
100}
101
102/** Constructor.
103 * Initialize with the parameters from the given camera argument parser. The following
104 * parameters are supported:
105 * - file=FILENAME: open the given file
106 * - dir=DIRECTORY: sequentially open files in this directory
107 * - ext=EXTENSION: only open files with this extension
108 * - width=W: width in pixels of image
109 * - height=H: height in pixels of image
110 * - colorspace=C: colorspace of image
111 *
112 * Width, height, and colorspace are used for raw images without an header, e.g if
113 * captured by v4l2-ctl.
114 *
115 * @param cap camera argument parser
116 */
118{
119 filename = NULL;
120 dirname = NULL;
121
122 file_list = NULL;
123 num_files = 0;
124 cur_file = 0;
125 width = height = 0;
126 file_buffer = NULL;
127 this->cspace = CS_UNKNOWN;
128 opened = started = false;
129
130 if (cap->has("file")) {
131 this->filename = strdup(cap->get("file").c_str());
132 if (cap->has("width")) {
133 width = cap->get_int("width");
134 }
135 if (cap->has("height")) {
136 height = cap->get_int("height");
137 }
138 if (cap->has("colorspace")) {
139 cspace = colorspace_by_name(cap->get("colorspace").c_str());
140 }
141 } else if (cap->has("dir")) {
142 this->dirname = strdup(cap->get("dir").c_str());
143 if (cap->has("ext")) {
144 this->extension = strdup(cap->get("ext").c_str());
145 }
146 } else {
147 throw MissingParameterException("Neither parameter file nor parameter directory are present");
148 }
149}
150
151/** Legacy constructor.
152 * Before FvRaw FireVision had the ability to store the pure buffer of an image
153 * without any header. Because of this additional information like colorspace,
154 * width and height of the image had to be supplied. The number of bytes that
155 * has to be read for the image is calculated from the given parameters.
156 * @param cspace color space of image
157 * @param filename filename to open
158 * @param width width of image
159 * @param height height of image
160 */
161FileLoader::FileLoader(colorspace_t cspace,
162 const char * filename,
163 unsigned int width,
164 unsigned int height)
165{
166 started = opened = false;
167 this->cspace = cspace;
168 this->width = width;
169 this->height = height;
170 this->filename = strdup(filename);
171 this->dirname = NULL;
172 this->extension = NULL;
173 this->file_list = NULL;
174 num_files = 0;
175 cur_file = 0;
176 file_buffer = NULL;
177}
178
179/** Destructor. */
181{
182 for (int i = 0; i < num_files; ++i) {
183 free(file_list[i]);
184 }
185 free(file_list);
186 free(dirname);
187 free(extension);
188 free(filename);
189}
190
191void
193{
194 if (opened)
195 return;
196
197 if (dirname) {
198 num_files = scandir(dirname, &file_list, file_select, alphasort);
199
200 if (-1 == num_files) {
201 throw Exception("Error while scanning directory %s", dirname);
202 }
203 }
204
205 read_file();
206 opened = true;
207}
208
209void
211{
212 if (started)
213 return;
214
215 if (!opened) {
216 throw Exception("Trying to start closed file");
217 }
218
219 started = true;
220}
221
222void
224{
225 started = false;
226}
227
228void
230{
231}
232
233void
235{
236 if (0 != num_files) {
237 if (file_buffer) {
238 free(file_buffer);
239 }
240
241 read_file();
242
243 if (++cur_file == num_files) {
244 cur_file = 0;
245 }
246 }
247}
248
249unsigned char *
251{
252 return file_buffer;
253}
254
255unsigned int
257{
258 return _buffer_size;
259}
260
261void
263{
264 if (file_buffer != NULL) {
265 free(file_buffer);
266 file_buffer = NULL;
267 }
268 opened = false;
269}
270
271void
273{
274}
275
276void
278{
279}
280
281bool
283{
284 return started;
285}
286
287void
289{
290}
291
292unsigned int
294{
295 return width;
296}
297
298unsigned int
300{
301 return height;
302}
303
304colorspace_t
306{
307 return cspace;
308}
309
310/** Set the colorspace of the image.
311 * @param c colorspace
312 */
313void
315{
316 cspace = c;
317}
318
319/** Set width.
320 * @param w image width in pixels
321 */
322void
324{
325 width = w;
326}
327
328/** Set height.
329 * @param h image height in pixels
330 */
331void
333{
334 height = h;
335}
336
337void
338FileLoader::read_file()
339{
340 char *fn;
341 if (0 != num_files) {
342 if (asprintf(&fn, "%s/%s", dirname, file_list[cur_file]->d_name) == -1) {
343 throw OutOfMemoryException("FileLoader::read_file(): asprintf() failed (2)");
344 }
345 } else {
346 fn = strdup(filename);
347 }
348
349 std::string ft = fv_filetype_file(fn);
350
351 if (ft == "FvRaw") {
352 FvRawReader *fvrr = new FvRawReader(fn);
353 cspace = fvrr->colorspace();
354 width = fvrr->pixel_width();
355 height = fvrr->pixel_height();
356 _buffer_size = colorspace_buffer_size(cspace, width, height);
357 file_buffer = (unsigned char *)malloc(_buffer_size);
358 fvrr->set_buffer(file_buffer);
359 try {
360 fvrr->read();
361 } catch (Exception &e) {
362 delete fvrr;
363 e.append("FileLoader::open() failed");
364 throw;
365 }
366 delete fvrr;
367
368#ifdef HAVE_LIBJPEG
369 } else if (ft.find("JPEG") != std::string::npos) {
370 JpegReader *jr = new JpegReader(fn);
371 cspace = jr->colorspace();
372 width = jr->pixel_width();
373 height = jr->pixel_height();
374 _buffer_size = colorspace_buffer_size(cspace, width, height);
375 file_buffer = (unsigned char *)malloc(_buffer_size);
376 jr->set_buffer(file_buffer);
377 try {
378 jr->read();
379 } catch (Exception &e) {
380 delete jr;
381 e.append("FileLoader::open() failed");
382 throw;
383 }
384 delete jr;
385#endif
386
387#ifdef HAVE_LIBPNG
388 } else if (ft.find("PNG") != std::string::npos) {
389 PNGReader *pr = new PNGReader(fn);
390 cspace = pr->colorspace();
391 width = pr->pixel_width();
392 height = pr->pixel_height();
393 _buffer_size = colorspace_buffer_size(cspace, width, height);
394 file_buffer = (unsigned char *)malloc(_buffer_size);
395 pr->set_buffer(file_buffer);
396 try {
397 pr->read();
398 } catch (Exception &e) {
399 delete pr;
400 e.append("FileLoader::open() failed for PNG");
401 throw;
402 }
403 delete pr;
404#endif
405
406 } else if (ft == "FvColormap") {
407 ColormapFile cmf;
408 cmf.read(fn);
409
410 Colormap *colormap = cmf.get_colormap();
411 cspace = YUV422_PLANAR;
412 width = colormap->width() * 2;
413 height = colormap->height() * 2;
414 _buffer_size = colorspace_buffer_size(cspace, width, height);
415 file_buffer = (unsigned char *)malloc(_buffer_size);
416 colormap->to_image(file_buffer);
417
418 delete colormap;
419
420 } else {
421 _buffer_size = colorspace_buffer_size(cspace, width, height);
422
423 if (_buffer_size > 0) {
424 FILE *f;
425 f = fopen(fn, "rb");
426 file_buffer = (unsigned char *)malloc(_buffer_size);
427 if (fread(file_buffer, _buffer_size, 1, f) != 1) {
428 // cout << "FileLoader: Could not read data." << endl;
429 fclose(f);
430 throw Exception("Could not read data");
431 }
432 fclose(f);
433 } else {
434 throw Exception("Invalid color space (buffer size is 0)");
435 }
436 }
437
438 free(fn);
439}
440
441} // end namespace firevision
Base class for exceptions in Fawkes.
Definition: exception.h:36
void append(const char *format,...) noexcept
Append messages to the message list.
Definition: exception.cpp:333
Expected parameter is missing.
Definition: software.h:74
System ran out of memory and desired operation could not be fulfilled.
Definition: system.h:32
Camera argument parser.
Definition: camargp.h:36
long int get_int(std::string s) const
Get the value of the given parameter as integer.
Definition: camargp.cpp:175
bool has(std::string s) const
Check if an parameter was given.
Definition: camargp.cpp:145
std::string get(std::string s) const
Get the value of the given parameter.
Definition: camargp.cpp:156
virtual void capture()
Capture an image.
Definition: fileloader.cpp:234
virtual void flush()
Flush image queue.
Definition: fileloader.cpp:277
void set_colorspace(colorspace_t c)
Set the colorspace of the image.
Definition: fileloader.cpp:314
virtual void dispose_buffer()
Dispose current buffer.
Definition: fileloader.cpp:272
~FileLoader()
Destructor.
Definition: fileloader.cpp:180
FileLoader(const char *filename)
Constructor.
Definition: fileloader.cpp:88
virtual bool ready()
Camera is ready for taking pictures.
Definition: fileloader.cpp:282
void set_pixel_width(unsigned int w)
Set width.
Definition: fileloader.cpp:323
void set_pixel_height(unsigned int h)
Set height.
Definition: fileloader.cpp:332
virtual colorspace_t colorspace()
Colorspace of returned image.
Definition: fileloader.cpp:305
virtual unsigned int buffer_size()
Size of buffer.
Definition: fileloader.cpp:256
virtual void start()
Start image transfer from the camera.
Definition: fileloader.cpp:210
virtual void set_image_number(unsigned int n)
Set image number to retrieve.
Definition: fileloader.cpp:288
virtual void close()
Close camera.
Definition: fileloader.cpp:262
virtual unsigned char * buffer()
Get access to current image buffer.
Definition: fileloader.cpp:250
virtual void open()
Open the camera.
Definition: fileloader.cpp:192
virtual unsigned int pixel_height()
Height of image in pixels.
Definition: fileloader.cpp:299
virtual unsigned int pixel_width()
Width of image in pixels.
Definition: fileloader.cpp:293
virtual void print_info()
Print out camera information.
Definition: fileloader.cpp:229
virtual void stop()
Stop image transfer from the camera.
Definition: fileloader.cpp:223
Fawkes library namespace.