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 
33 namespace 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  */
62 ColormapFile::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  */
76 ColormapFile::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  */
88 void
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 
145 void
146 ColormapFile::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  */
163 Colormap *
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  */
201 bool
202 ColormapFile::is_colormap_file(const char *filename)
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  */
212 std::string
213 ColormapFile::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 
229 void
231 {
233  header_ = NULL;
234 }
235 
236 /** Get depth of colormap.
237  * @return depth
238  */
239 uint16_t
241 {
242  assert_header();
243  return header_->depth;
244 }
245 
246 /** Get width of colormap.
247  * @return width
248  */
249 uint16_t
251 {
252  assert_header();
253  return header_->width;
254 }
255 
256 /** Get height of colormap.
257  * @return height
258  */
259 uint16_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