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