cmfile.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
00037
00038
00039
00040
00041
00042
00043
00044 ColormapFile::ColormapBlockVector::~ColormapBlockVector()
00045 {
00046 for (iterator i = begin(); i != end(); ++i) {
00047 delete *i;
00048 }
00049 }
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 ColormapFile::ColormapFile(uint16_t depth, uint16_t width, uint16_t height)
00065 : FireVisionDataFile(CMFILE_MAGIC_TOKEN, CMFILE_CUR_VERSION)
00066 {
00067 _spec_header = calloc(1, sizeof(cmfile_header_t));
00068 _spec_header_size = sizeof(cmfile_header_t);
00069 __header = (cmfile_header_t *)_spec_header;
00070 __header->depth = depth;
00071 __header->width = width;
00072 __header->height = height;
00073 }
00074
00075
00076
00077
00078 ColormapFile::ColormapFile()
00079 : FireVisionDataFile(CMFILE_MAGIC_TOKEN, CMFILE_CUR_VERSION)
00080 {
00081 __header = NULL;
00082 }
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 void
00093 ColormapFile::add_colormap(Colormap *colormap)
00094 {
00095 if (! __header) {
00096 if ( _spec_header) {
00097 __header = (cmfile_header_t *)_spec_header;
00098 } else {
00099 _spec_header = calloc(1, sizeof(cmfile_header_t));
00100 _spec_header_size = sizeof(cmfile_header_t);
00101 __header = (cmfile_header_t *)_spec_header;
00102 __header->depth = colormap->depth();
00103 __header->width = colormap->width();
00104 __header->height = colormap->height();
00105 }
00106 }
00107
00108 if ( (colormap->depth() != __header->depth) ||
00109 (colormap->width() != __header->width) ||
00110 (colormap->height() != __header->height) ) {
00111 throw fawkes::Exception("Colormap dimensions %dx%dx%d do not match expected dimensions %dx%dx%d",
00112 colormap->depth(), colormap->width(), colormap->height(),
00113 __header->depth, __header->width, __header->height);
00114 }
00115
00116 printf("Adding colormap with dimensions %dx%dx%d\n", colormap->width(), colormap->height(), colormap->depth());
00117
00118 std::list<ColormapFileBlock *> blocks = colormap->get_blocks();
00119 for (std::list<ColormapFileBlock *>::iterator i = blocks.begin(); i != blocks.end(); ++i) {
00120 add_block(*i);
00121 }
00122 }
00123
00124
00125
00126
00127
00128 ColormapFile::ColormapBlockVector *
00129 ColormapFile::colormap_blocks()
00130 {
00131 FireVisionDataFile::BlockList &b = blocks();
00132 ColormapBlockVector *rv = new ColormapBlockVector();
00133 for (std::list<FireVisionDataFileBlock *>::iterator i = b.begin(); i != b.end(); ++i) {
00134 if ((*i)->type() == CMFILE_TYPE_YUV ) {
00135 ColormapFileYuvBlock *yuvb = new ColormapFileYuvBlock(*i);
00136 rv->push_back(yuvb);
00137 }
00138 }
00139
00140 return rv;
00141 }
00142
00143
00144 void
00145 ColormapFile::assert_header()
00146 {
00147 if ( ! __header ) {
00148 if (! _spec_header) {
00149 throw fawkes::Exception("Cannot get header information, invalid ctor used or file not read?");
00150 }
00151 __header = (cmfile_header_t *)_spec_header;
00152 }
00153
00154 }
00155
00156
00157
00158
00159
00160
00161
00162
00163 Colormap *
00164 ColormapFile::get_colormap()
00165 {
00166
00167 BlockList &bl = blocks();
00168 YuvColormap *cm = NULL;
00169
00170 for (BlockList::iterator b = bl.begin(); b != bl.end(); ++b) {
00171 if ( (*b)->type() != CMFILE_TYPE_YUV ) {
00172 throw fawkes::Exception("Colormap file contains block of unknown type");
00173 }
00174 }
00175
00176 assert_header();
00177
00178
00179 printf("File header dimensions: %dx%dx%d\n", __header->depth, __header->width, __header->height);
00180 cm = new YuvColormap(__header->depth, __header->width, __header->height);
00181
00182 unsigned int level = 0;
00183 for (BlockList::iterator b = bl.begin(); b != bl.end(); ++b) {
00184 if ( (*b)->data_size() != cm->plane_size() ) {
00185
00186 delete cm;
00187 throw fawkes::Exception("Invalid data size for a YUV block");
00188 }
00189
00190 cm->copy_uvplane((unsigned char *)(*b)->data_ptr(), level++);
00191 }
00192
00193 return cm;
00194 }
00195
00196
00197
00198
00199
00200 bool
00201 ColormapFile::is_colormap_file(const char *filename)
00202 {
00203 return FireVisionDataFile::has_magic_token(filename, CMFILE_MAGIC_TOKEN);
00204 }
00205
00206
00207
00208
00209
00210
00211 std::string
00212 ColormapFile::compose_filename(const std::string format)
00213 {
00214 std::string rv = format;
00215
00216 struct utsname uname_info;
00217 uname( &uname_info );
00218
00219 size_t loc = rv.find( "%h" );
00220 while (loc != std::string::npos) {
00221 rv.replace( loc, 2, uname_info.nodename );
00222 loc = rv.find( "%h" );
00223 }
00224
00225 return rv;
00226 }
00227
00228
00229 void
00230 ColormapFile::clear()
00231 {
00232 FireVisionDataFile::clear();
00233 __header = NULL;
00234 }
00235
00236
00237
00238
00239
00240 uint16_t
00241 ColormapFile::get_depth()
00242 {
00243 assert_header();
00244 return __header->depth;
00245 }
00246
00247
00248
00249
00250 uint16_t
00251 ColormapFile::get_width()
00252 {
00253 assert_header();
00254 return __header->width;
00255 }
00256
00257
00258
00259
00260 uint16_t
00261 ColormapFile::get_height()
00262 {
00263 assert_header();
00264 return __header->height;
00265 }