Fawkes API
Fawkes Development Version
|
00001 00002 /************************************************************************** 00003 * cmfile.cpp - FVFF Colormap File Format 00004 * 00005 * Created: Mon Mar 31 14:11:01 2008 00006 * Copyright 2005-2008 Tim Niemueller [www.niemueller.de] 00007 * 00008 ***************************************************************************/ 00009 00010 /* This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. A runtime exception applies to 00014 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Library General Public License for more details. 00020 * 00021 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00022 */ 00023 00024 #include <fvutils/colormap/cmfile.h> 00025 00026 #include <fvutils/colormap/colormap.h> 00027 #include <fvutils/colormap/cmfile_yuvblock.h> 00028 00029 #include <fvutils/colormap/yuvcm.h> 00030 #include <core/exception.h> 00031 00032 #include <sys/utsname.h> 00033 00034 #include <cstdio> 00035 00036 namespace firevision { 00037 #if 0 /* just to make Emacs auto-indent happy */ 00038 } 00039 #endif 00040 00041 /** @class ColormapFile::ColormapBlockVector <fvutils/colormap/cmfile.h> 00042 * Vector of colormap blocks. 00043 * @author Tim Niemueller 00044 */ 00045 00046 /** Destructor. 00047 * Deletes all hold colormap blocks. 00048 */ 00049 ColormapFile::ColormapBlockVector::~ColormapBlockVector() 00050 { 00051 for (iterator i = begin(); i != end(); ++i) { 00052 delete *i; 00053 } 00054 } 00055 00056 00057 /** @class ColormapFile <fvutils/colormap/cmfile.h> 00058 * Colormap file. 00059 * This class implements a FireVision data file format for colormaps. 00060 * @author Tim Niemueller 00061 */ 00062 00063 /** Constructor. 00064 * Creates a plain empty colormap file with given dimensions. 00065 * @param depth depth of colormap 00066 * @param width width of colormap 00067 * @param height height of colormap 00068 */ 00069 ColormapFile::ColormapFile(uint16_t depth, uint16_t width, uint16_t height) 00070 : FireVisionDataFile(CMFILE_MAGIC_TOKEN, CMFILE_CUR_VERSION) 00071 { 00072 _spec_header = calloc(1, sizeof(cmfile_header_t)); 00073 _spec_header_size = sizeof(cmfile_header_t); 00074 __header = (cmfile_header_t *)_spec_header; 00075 __header->depth = depth; 00076 __header->width = width; 00077 __header->height = height; 00078 } 00079 00080 /** Constructor. 00081 * Creates a plain empty colormap file. 00082 */ 00083 ColormapFile::ColormapFile() 00084 : FireVisionDataFile(CMFILE_MAGIC_TOKEN, CMFILE_CUR_VERSION) 00085 { 00086 __header = NULL; 00087 } 00088 00089 00090 /** Add colormap. 00091 * This will add the given colormap to this file. It will query the colormap for 00092 * a number of blocks that shall be added to the file. 00093 * Note that for now only a single colormap per file is supported, though not 00094 * enforced. 00095 * @param colormap colormap to add 00096 */ 00097 void 00098 ColormapFile::add_colormap(Colormap *colormap) 00099 { 00100 if (! __header) { 00101 if ( _spec_header) { 00102 __header = (cmfile_header_t *)_spec_header; 00103 } else { 00104 _spec_header = calloc(1, sizeof(cmfile_header_t)); 00105 _spec_header_size = sizeof(cmfile_header_t); 00106 __header = (cmfile_header_t *)_spec_header; 00107 __header->depth = colormap->depth(); 00108 __header->width = colormap->width(); 00109 __header->height = colormap->height(); 00110 } 00111 } 00112 00113 if ( (colormap->depth() != __header->depth) || 00114 (colormap->width() != __header->width) || 00115 (colormap->height() != __header->height) ) { 00116 throw fawkes::Exception("Colormap dimensions %dx%dx%d do not match expected dimensions %dx%dx%d", 00117 colormap->depth(), colormap->width(), colormap->height(), 00118 __header->depth, __header->width, __header->height); 00119 } 00120 00121 printf("Adding colormap with dimensions %dx%dx%d\n", colormap->width(), colormap->height(), colormap->depth()); 00122 00123 std::list<ColormapFileBlock *> blocks = colormap->get_blocks(); 00124 for (std::list<ColormapFileBlock *>::iterator i = blocks.begin(); i != blocks.end(); ++i) { 00125 add_block(*i); 00126 } 00127 } 00128 00129 00130 /** Get colormap blocks. 00131 * @return vector of colormap blocks 00132 */ 00133 ColormapFile::ColormapBlockVector * 00134 ColormapFile::colormap_blocks() 00135 { 00136 FireVisionDataFile::BlockList &b = blocks(); 00137 ColormapBlockVector *rv = new ColormapBlockVector(); 00138 for (std::list<FireVisionDataFileBlock *>::iterator i = b.begin(); i != b.end(); ++i) { 00139 if ((*i)->type() == CMFILE_TYPE_YUV ) { 00140 ColormapFileYuvBlock *yuvb = new ColormapFileYuvBlock(*i); 00141 rv->push_back(yuvb); 00142 } 00143 } 00144 00145 return rv; 00146 } 00147 00148 00149 void 00150 ColormapFile::assert_header() 00151 { 00152 if ( ! __header ) { 00153 if (! _spec_header) { 00154 throw fawkes::Exception("Cannot get header information, invalid ctor used or file not read?"); 00155 } 00156 __header = (cmfile_header_t *)_spec_header; 00157 } 00158 00159 } 00160 00161 /** Get a freshly generated colormap based on current file content. 00162 * This returns an instance of a colormap that uses all current blocks of this instance. 00163 * Currently it only supports file which contain a valid YuvColormap. This means that it 00164 * has d blocks of YUV type. d is the depth and must fulfill d=2^n with n from [1,8]. 00165 * It can throw any exception that the YuvColormap ctor can throw. 00166 * @return instance of colormap. You must delete it after you are done with it. 00167 */ 00168 Colormap * 00169 ColormapFile::get_colormap() 00170 { 00171 // Make sure we only have YUV blocks 00172 BlockList &bl = blocks(); 00173 YuvColormap *cm = NULL; 00174 00175 for (BlockList::iterator b = bl.begin(); b != bl.end(); ++b) { 00176 if ( (*b)->type() != CMFILE_TYPE_YUV ) { 00177 throw fawkes::Exception("Colormap file contains block of unknown type"); 00178 } 00179 } 00180 00181 assert_header(); 00182 00183 // create colormap, throws an exception is depth/num_blocks is invalid 00184 //printf("File header dimensions: %dx%dx%d\n", 00185 // __header->depth, __header->width, __header->height); 00186 cm = new YuvColormap(__header->depth, __header->width, __header->height); 00187 00188 unsigned int level = 0; 00189 for (BlockList::iterator b = bl.begin(); b != bl.end(); ++b) { 00190 if ( (*b)->data_size() != cm->plane_size() ) { 00191 // invalid size, for a YUV colormap we must have this for one plane! 00192 delete cm; 00193 throw fawkes::Exception("Invalid data size for a YUV block"); 00194 } 00195 00196 cm->copy_uvplane((unsigned char *)(*b)->data_ptr(), level++); 00197 } 00198 00199 return cm; 00200 } 00201 00202 00203 /** Check if given file is a colormap file. 00204 * @param filename name of file to check 00205 * @return true if file is a colormap file, false otherwise 00206 */ 00207 bool 00208 ColormapFile::is_colormap_file(const char *filename) 00209 { 00210 return FireVisionDataFile::has_magic_token(filename, CMFILE_MAGIC_TOKEN); 00211 } 00212 00213 00214 /** Compose filename. 00215 * In the format %g is replaced with the hostname. 00216 * @param format format for the filename 00217 * @return filename 00218 */ 00219 std::string 00220 ColormapFile::compose_filename(const std::string format) 00221 { 00222 std::string rv = format; 00223 00224 struct utsname uname_info; 00225 uname( &uname_info ); 00226 00227 size_t loc = rv.find( "%h" ); 00228 while (loc != std::string::npos) { 00229 rv.replace( loc, 2, uname_info.nodename ); 00230 loc = rv.find( "%h" ); 00231 } 00232 00233 return rv; 00234 } 00235 00236 00237 void 00238 ColormapFile::clear() 00239 { 00240 FireVisionDataFile::clear(); 00241 __header = NULL; 00242 } 00243 00244 00245 /** Get depth of colormap. 00246 * @return depth 00247 */ 00248 uint16_t 00249 ColormapFile::get_depth() 00250 { 00251 assert_header(); 00252 return __header->depth; 00253 } 00254 00255 /** Get width of colormap. 00256 * @return width 00257 */ 00258 uint16_t 00259 ColormapFile::get_width() 00260 { 00261 assert_header(); 00262 return __header->width; 00263 } 00264 00265 /** Get height of colormap. 00266 * @return height 00267 */ 00268 uint16_t 00269 ColormapFile::get_height() 00270 { 00271 assert_header(); 00272 return __header->height; 00273 } 00274 00275 } // end namespace firevision