Fawkes API Fawkes Development Version
cmfile.cpp
1
2/**************************************************************************
3 * cmfile.cpp - FVFF Colormap File Format
4 *
5 * Created: Mon Mar 31 14:11:01 2008
6 * Copyright 2005-2008 Tim Niemueller [www.niemueller.de]
7 *
8 ***************************************************************************/
9
10/* This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version. A runtime exception applies to
14 * this software (see LICENSE.GPL_WRE file mentioned below for details).
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Library General Public License for more details.
20 *
21 * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22 */
23
24#include <core/exception.h>
25#include <fvutils/colormap/cmfile.h>
26#include <fvutils/colormap/cmfile_yuvblock.h>
27#include <fvutils/colormap/colormap.h>
28#include <fvutils/colormap/yuvcm.h>
29#include <sys/utsname.h>
30
31#include <cstdio>
32
33namespace firevision {
34
35/** @class ColormapFile::ColormapBlockVector <fvutils/colormap/cmfile.h>
36 * Vector of colormap blocks.
37 * @author Tim Niemueller
38 */
39
40/** Destructor.
41 * Deletes all hold colormap blocks.
42 */
44{
45 for (iterator i = begin(); i != end(); ++i) {
46 delete *i;
47 }
48}
49
50/** @class ColormapFile <fvutils/colormap/cmfile.h>
51 * Colormap file.
52 * This class implements a FireVision data file format for colormaps.
53 * @author Tim Niemueller
54 */
55
56/** Constructor.
57 * Creates a plain empty colormap file with given dimensions.
58 * @param depth depth of colormap
59 * @param width width of colormap
60 * @param height height of colormap
61 */
62ColormapFile::ColormapFile(uint16_t depth, uint16_t width, uint16_t height)
63: FireVisionDataFile(CMFILE_MAGIC_TOKEN, CMFILE_CUR_VERSION)
64{
65 _spec_header = calloc(1, sizeof(cmfile_header_t));
67 header_ = (cmfile_header_t *)_spec_header;
68 header_->depth = depth;
69 header_->width = width;
70 header_->height = height;
71}
72
73/** Constructor.
74 * Creates a plain empty colormap file.
75 */
76ColormapFile::ColormapFile() : FireVisionDataFile(CMFILE_MAGIC_TOKEN, CMFILE_CUR_VERSION)
77{
78 header_ = NULL;
79}
80
81/** Add colormap.
82 * This will add the given colormap to this file. It will query the colormap for
83 * a number of blocks that shall be added to the file.
84 * Note that for now only a single colormap per file is supported, though not
85 * enforced.
86 * @param colormap colormap to add
87 */
88void
90{
91 if (!header_) {
92 if (_spec_header) {
93 header_ = (cmfile_header_t *)_spec_header;
94 } else {
95 _spec_header = calloc(1, sizeof(cmfile_header_t));
97 header_ = (cmfile_header_t *)_spec_header;
98 header_->depth = colormap->depth();
99 header_->width = colormap->width();
100 header_->height = colormap->height();
101 }
102 }
103
104 if ((colormap->depth() != header_->depth) || (colormap->width() != header_->width)
105 || (colormap->height() != header_->height)) {
106 throw fawkes::Exception(
107 "Colormap dimensions %dx%dx%d do not match expected dimensions %dx%dx%d",
108 colormap->depth(),
109 colormap->width(),
110 colormap->height(),
111 header_->depth,
112 header_->width,
113 header_->height);
114 }
115
116 printf("Adding colormap with dimensions %dx%dx%d\n",
117 colormap->width(),
118 colormap->height(),
119 colormap->depth());
120
121 std::list<ColormapFileBlock *> blocks = colormap->get_blocks();
122 for (std::list<ColormapFileBlock *>::iterator i = blocks.begin(); i != blocks.end(); ++i) {
123 add_block(*i);
124 }
125}
126
127/** Get colormap blocks.
128 * @return vector of colormap blocks
129 */
132{
135 for (std::list<FireVisionDataFileBlock *>::iterator i = b.begin(); i != b.end(); ++i) {
136 if ((*i)->type() == CMFILE_TYPE_YUV) {
138 rv->push_back(yuvb);
139 }
140 }
141
142 return rv;
143}
144
145void
146ColormapFile::assert_header()
147{
148 if (!header_) {
149 if (!_spec_header) {
150 throw fawkes::Exception("Cannot get header information, invalid ctor used or file not read?");
151 }
152 header_ = (cmfile_header_t *)_spec_header;
153 }
154}
155
156/** Get a freshly generated colormap based on current file content.
157 * This returns an instance of a colormap that uses all current blocks of this instance.
158 * Currently it only supports file which contain a valid YuvColormap. This means that it
159 * has d blocks of YUV type. d is the depth and must fulfill d=2^n with n from [1,8].
160 * It can throw any exception that the YuvColormap ctor can throw.
161 * @return instance of colormap. You must delete it after you are done with it.
162 */
163Colormap *
165{
166 // Make sure we only have YUV blocks
167 BlockList & bl = blocks();
168 YuvColormap *cm = NULL;
169
170 for (BlockList::iterator b = bl.begin(); b != bl.end(); ++b) {
171 if ((*b)->type() != CMFILE_TYPE_YUV) {
172 throw fawkes::Exception("Colormap file contains block of unknown type");
173 }
174 }
175
176 assert_header();
177
178 // create colormap, throws an exception is depth/num_blocks is invalid
179 //printf("File header dimensions: %dx%dx%d\n",
180 // header_->depth, header_->width, header_->height);
181 cm = new YuvColormap(header_->depth, header_->width, header_->height);
182
183 unsigned int level = 0;
184 for (BlockList::iterator b = bl.begin(); b != bl.end(); ++b) {
185 if ((*b)->data_size() != cm->plane_size()) {
186 // invalid size, for a YUV colormap we must have this for one plane!
187 delete cm;
188 throw fawkes::Exception("Invalid data size for a YUV block");
189 }
190
191 cm->copy_uvplane((unsigned char *)(*b)->data_ptr(), level++);
192 }
193
194 return cm;
195}
196
197/** Check if given file is a colormap file.
198 * @param filename name of file to check
199 * @return true if file is a colormap file, false otherwise
200 */
201bool
203{
204 return FireVisionDataFile::has_magic_token(filename, CMFILE_MAGIC_TOKEN);
205}
206
207/** Compose filename.
208 * In the format %g is replaced with the hostname.
209 * @param format format for the filename
210 * @return filename
211 */
212std::string
213ColormapFile::compose_filename(const std::string format)
214{
215 std::string rv = format;
216
217 struct utsname uname_info;
218 uname(&uname_info);
219
220 size_t loc = rv.find("%h");
221 while (loc != std::string::npos) {
222 rv.replace(loc, 2, uname_info.nodename);
223 loc = rv.find("%h");
224 }
225
226 return rv;
227}
228
229void
231{
233 header_ = NULL;
234}
235
236/** Get depth of colormap.
237 * @return depth
238 */
239uint16_t
241{
242 assert_header();
243 return header_->depth;
244}
245
246/** Get width of colormap.
247 * @return width
248 */
249uint16_t
251{
252 assert_header();
253 return header_->width;
254}
255
256/** Get height of colormap.
257 * @return height
258 */
259uint16_t
261{
262 assert_header();
263 return header_->height;
264}
265
266} // end namespace firevision
Base class for exceptions in Fawkes.
Definition: exception.h:36
YUV block for colormap file.
Vector of colormap blocks.
Definition: cmfile.h:61
static std::string compose_filename(const std::string format)
Compose filename.
Definition: cmfile.cpp:213
uint16_t get_height()
Get height of colormap.
Definition: cmfile.cpp:260
virtual void clear()
Clear internal storage.
Definition: cmfile.cpp:230
uint16_t get_width()
Get width of colormap.
Definition: cmfile.cpp:250
ColormapBlockVector * colormap_blocks()
Get colormap blocks.
Definition: cmfile.cpp:131
Colormap * get_colormap()
Get a freshly generated colormap based on current file content.
Definition: cmfile.cpp:164
void add_colormap(Colormap *colormap)
Add colormap.
Definition: cmfile.cpp:89
static bool is_colormap_file(const char *filename)
Check if given file is a colormap file.
Definition: cmfile.cpp:202
ColormapFile()
Constructor.
Definition: cmfile.cpp:76
uint16_t get_depth()
Get depth of colormap.
Definition: cmfile.cpp:240
Colormap interface.
Definition: colormap.h:37
virtual unsigned int depth() const =0
Get depth of colormap.
virtual unsigned int height() const =0
Get height of colormap.
virtual std::list< ColormapFileBlock * > get_blocks()=0
Get file blocks for this colormap.
virtual unsigned int width() const =0
Get width of colormap.
FireVision File Format for data files.
Definition: fvfile.h:36
void * _spec_header
Content specific header.
Definition: fvfile.h:66
virtual void clear()
Clear internal storage.
Definition: fvfile.cpp:122
size_t _spec_header_size
Size in bytes of _spec_header.
Definition: fvfile.h:67
virtual void add_block(FireVisionDataFileBlock *block)
Add a block.
Definition: fvfile.cpp:225
std::list< FireVisionDataFileBlock * > BlockList
List of FireVision data file blocks.
Definition: fvfile.h:62
static bool has_magic_token(const char *filename, unsigned short int magic_token)
Check if file has a certain magic token.
Definition: fvfile.cpp:428
BlockList & blocks()
Get blocks.
Definition: fvfile.cpp:234
YUV Colormap.
Definition: yuvcm.h:36
void copy_uvplane(unsigned char *uvplane, unsigned int level)
Copy single U/V plane.
Definition: yuvcm.cpp:243
unsigned int plane_size() const
Get U/V plane size.
Definition: yuvcm.cpp:351
Block header for a Colormap header block in a ColormapFile.
Definition: cmfile.h:46
uint16_t width
U resolution.
Definition: cmfile.h:48
uint16_t depth
Y resolution.
Definition: cmfile.h:47
uint16_t height
V resolution.
Definition: cmfile.h:49