00001 #ifndef Impala_Core_Geometry_InterestPointListIO_h
00002 #define Impala_Core_Geometry_InterestPointListIO_h
00003
00004 #include "Core/Geometry/InterestPointList.h"
00005 #include "Core/Geometry/InterestCircle.h"
00006 #include "Core/Geometry/InterestRectangleZ.h"
00007 #include "Core/Vector/VectorTem.h"
00008
00009 #include <iostream>
00010 #include <fstream>
00011
00012 namespace Impala
00013 {
00014 namespace Sandbox
00015 {
00016 namespace Koen
00017 {
00018
00019 using namespace Impala::Core::Geometry;
00020
00021
00022 void
00023 WriteRegionsToStreamFormatKoen(std::ostream& fs, InterestPointList& outputPointList, bool writeDescriptors, int borderOffset)
00024 {
00025 ILOG_VAR(Sandbox.koen.WriteRegionsToStreamFormatKoen);
00026
00027
00028
00029
00030
00031
00032 int dimensionCount = -1;
00033 fs << "KOEN1\n";
00034 if(writeDescriptors)
00035 {
00036 if(outputPointList.size() == 0)
00037 {
00038 dimensionCount = 0;
00039 }
00040 else
00041 {
00042 dimensionCount = (*(outputPointList.begin()))->mDescriptor.size();
00043 }
00044 fs << dimensionCount << "\n";
00045 }
00046 else
00047 {
00048 fs << "0\n";
00049 }
00050 fs << outputPointList.size() << "\n";
00051 for(InterestPointList::iterator iter = outputPointList.begin(); iter != outputPointList.end(); iter++)
00052 {
00053 InterestPoint* point = *iter;
00054
00055
00056 fs << point->Serialize(borderOffset+1, borderOffset+1);
00057 if(writeDescriptors)
00058 {
00059 if(point->mDescriptor.size() != dimensionCount)
00060 {
00061 ILOG_ERROR("Your code has created descriptors with variable length!");
00062 throw "Dimension mismatch!";
00063 }
00064 for(int i = 0; i < dimensionCount; i++)
00065 {
00066 fs << " " << point->mDescriptor[i];
00067 }
00068 }
00069 fs << ";\n";
00070 }
00071 }
00072
00073
00074 void
00075 WriteRegionsToBuffer(Util::IOBuffer* buffer, InterestPointList& outputPointList, bool writeDescriptors, int borderOffset)
00076 {
00077 ILOG_VAR(Sandbox.koen.WriteRegionsToBuffer);
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 int elementsPerPoint = 0;
00089 int dimensionCount = 0;
00090 int pointCount = outputPointList.size();
00091 int bytesPerElement = 8;
00092
00093 String magic = "BINDESC1";
00094 String dataType = "UNKNOWN ";
00095 String geometry = "";
00096 if(outputPointList.size() > 0)
00097 {
00098 Core::Vector::VectorTem<Real64>* p = (*(outputPointList.begin()))->PointAsVector(borderOffset+1, borderOffset+1);
00099 elementsPerPoint = p->Size();
00100 delete p;
00101
00102 dimensionCount = (*(outputPointList.begin()))->mDescriptor.size();
00103 geometry = (*(outputPointList.begin()))->geometryType();
00104 if(geometry == "CircleZ")
00105 {
00106 dataType = "CIRCLE ";
00107 }
00108 else if(geometry == "RectangleZ")
00109 {
00110 dataType = "RECT ";
00111 }
00112 }
00113 if(!writeDescriptors) dimensionCount = 0;
00114
00115 ILOG_DEBUG("Writing header...");
00116 buffer->Write(magic.c_str(), 8);
00117 buffer->Write(dataType.c_str(), 8);
00118 buffer->Write(&elementsPerPoint, 4);
00119 buffer->Write(&dimensionCount, 4);
00120 buffer->Write(&pointCount, 4);
00121 buffer->Write(&bytesPerElement, 4);
00122 ILOG_DEBUG("Wrote full header");
00123
00124 for(InterestPointList::iterator iter = outputPointList.begin(); iter != outputPointList.end(); iter++)
00125 {
00126 InterestPoint* point = *iter;
00127
00128
00129 Core::Vector::VectorTem<Real64>* p = point->PointAsVector(borderOffset+1, borderOffset+1);
00130 if(p->Size() != elementsPerPoint)
00131 {
00132 ILOG_ERROR("Point representations do not have equal length!");
00133 return;
00134 }
00135 buffer->Write(p->GetData(), sizeof(Real64) * elementsPerPoint);
00136 delete p;
00137 }
00138
00139 if(dimensionCount == 0) return;
00140
00141 Core::Vector::VectorTem<Real64> v = Core::Vector::VectorTem<Real64>(dimensionCount);
00142 for(InterestPointList::iterator iter = outputPointList.begin(); iter != outputPointList.end(); iter++)
00143 {
00144 InterestPoint* point = *iter;
00145 if(point->mDescriptor.size() != dimensionCount)
00146 {
00147 ILOG_ERROR("Your code has created descriptors with variable length!");
00148 }
00149 for(int i = 0; i < dimensionCount; i++)
00150 {
00151 v[i] = point->mDescriptor[i];
00152 }
00153 buffer->Write(v.GetData(), sizeof(Real64) * dimensionCount);
00154 }
00155 }
00156
00157
00158 void
00159 WritePointListToFile(String filename, InterestPointList& outputPointList, bool writeDescriptors, int borderOffset, String format, bool appendToExisting=false)
00160 {
00161 if((format == "bindesc1") || (format == "binary"))
00162 {
00163 Util::IOBuffer* buffer = new Util::IOBufferFile(filename, false, false);
00164 WriteRegionsToBuffer(buffer, outputPointList, writeDescriptors, borderOffset);
00165 delete buffer;
00166 }
00167 else
00168 {
00169 std::ios::openmode flags = std::ios::ate | std::ios::out | std::ios::in;
00170 if(!appendToExisting)
00171 {
00172 flags = std::ios::out;
00173 }
00174 std::ofstream fs(filename.c_str(), flags);
00175 WriteRegionsToStreamFormatKoen(fs, outputPointList, writeDescriptors, borderOffset);
00176 fs.close();
00177 }
00178 }
00179
00180
00181 void
00182 ReadRegionsFromStreamFormatKoen(CString content, InterestPointList& outputPointList, bool readDescriptors, int borderOffset)
00183 {
00184 ILOG_VAR(Sandbox.koen.ReadRegionsFromStreamFormatKoen);
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194 Util::StringParser sp(content);
00195
00196
00197
00198 String header = sp.GetString('\n');
00199 if(header != String("KOEN1"))
00200 {
00201 ILOG_ERROR("Unsupported region format: " << header);
00202 return;
00203 }
00204
00205
00206 int dimensionCount = sp.GetInt('\n');
00207 int regionCount = sp.GetInt('\n');
00208 ILOG_DEBUG("Reading file; dimensionCount = " << dimensionCount << "; regionCount = " << regionCount);
00209 for(int i = 0; i < regionCount; i++)
00210 {
00211 InterestPoint* point = 0;
00212
00213 String line = sp.GetString('\n');
00214 Util::StringParser sp2(line);
00215 String region = sp2.GetString(';');
00216 if(region.substr(0, 8) == "<CIRCLE ")
00217 {
00218
00219
00220 point = new InterestCircle(region, borderOffset+1, borderOffset+1);
00221 }
00222 else
00223 {
00224 ILOG_ERROR("Unsupported region: " << region);
00225 throw "Unsupported serialization type!";
00226 }
00227
00228 if(readDescriptors)
00229 {
00230 String descriptor = sp2.GetString(';');
00231 Util::StringParser sp3(descriptor);
00232 if(dimensionCount > 0)
00233 {
00234 point->mDescriptor.reserve(dimensionCount);
00235 for(int j = 0; j < dimensionCount; j++)
00236 {
00237 point->mDescriptor.push_back(sp3.GetDouble());
00238 }
00239 }
00240 }
00241 if(point)
00242 {
00243 outputPointList.push_back(point);
00244 }
00245 }
00246 }
00247
00248
00249 void
00250 ReadRegionsFromStreamFormatKoen(std::istream& fs, InterestPointList& outputPointList, bool readDescriptors, int borderOffset)
00251 {
00252 ILOG_VAR(Sandbox.koen.ReadRegionsFromStreamFormatKoen);
00253
00254
00255 fs.seekg(0, std::ios_base::end);
00256 int fileSize = fs.tellg();
00257 fs.seekg(0, std::ios_base::beg);
00258 char* buffer = new char[fileSize];
00259
00260 fs.get(buffer, fileSize, '\0');
00261
00262 String content(buffer);
00263 ReadRegionsFromStreamFormatKoen(content, outputPointList, readDescriptors, borderOffset);
00264 }
00265
00266
00267 void
00268 ReadPointListFromBuffer(Util::IOBuffer* buffer,
00269 InterestPointList& pointList,
00270 bool readDescriptors, int borderOffset)
00271 {
00272 ILOG_VAR(Sandbox.koen.ReadRegionsFromBuffer);
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283 int elementsPerPoint = 0;
00284 int dimensionCount = 0;
00285 int pointCount = 0;
00286 int bytesPerElement = 8;
00287
00288 String magic = "BINDESC1";
00289 String dataType = "UNKNOWN ";
00290 String geometry = "";
00291
00292 char buf[9];
00293 for (int i=0 ; i<9 ; i++)
00294 buf[i] = 0;
00295
00296 ILOG_DEBUG("Reading header...");
00297
00298 buffer->Read(buf, 8);
00299 if(String(buf) != magic)
00300 {
00301 ILOG_ERROR("ReadPointListFromBuffer invalid magic");
00302 return;
00303 }
00304
00305
00306 buffer->Read(buf, 8);
00307 dataType = String(buf);
00308 if(dataType == "CIRCLE ")
00309 {
00310 geometry = "CircleZ";
00311 }
00312 else if(dataType == "RECT ")
00313 {
00314 geometry = "RectangleZ";
00315 }
00316
00317 buffer->Read(&elementsPerPoint, 4);
00318 buffer->Read(&dimensionCount, 4);
00319 buffer->Read(&pointCount, 4);
00320 buffer->Read(&bytesPerElement, 4);
00321 ILOG_DEBUG("Read full header");
00322 if(bytesPerElement != 8)
00323 {
00324 ILOG_ERROR("Can only read BINDESC1 with 8 bytes per element (double)");
00325 return;
00326 }
00327
00328
00329 Core::Vector::VectorTem<Real64> pointVector =
00330 Core::Vector::VectorTem<Real64>(elementsPerPoint);
00331 for(int i = 0; i < pointCount; i++)
00332 {
00333 buffer->Read(pointVector.GetData(), sizeof(Real64) * elementsPerPoint);
00334 if(geometry == "CircleZ")
00335 {
00336 InterestCircle* point =
00337 new InterestCircle(pointVector, borderOffset+1, borderOffset+1);
00338 pointList.push_back(point);
00339 }
00340 else if(geometry == "RectangleZ")
00341 {
00342 ILOG_ERROR("Cannot deserialize rectangles: code not written");
00343
00344
00345
00346
00347 }
00348 }
00349
00350 if(dimensionCount == 0) return;
00351 if(!readDescriptors) return;
00352
00353 Core::Vector::VectorTem<Real64> v =
00354 Core::Vector::VectorTem<Real64>(dimensionCount);
00355 for(InterestPointList::iterator iter = pointList.begin(); iter != pointList.end(); iter++)
00356 {
00357 InterestPoint* point = *iter;
00358 buffer->Read(v.GetData(), sizeof(Real64) * dimensionCount);
00359 point->mDescriptor.reserve(dimensionCount);
00360 for(int i = 0; i < dimensionCount; i++)
00361 {
00362 point->mDescriptor.push_back(v[i]);
00363 }
00364 }
00365 }
00366
00367
00368 void
00369 ReadPointListFromFile(String filename, InterestPointList& outputPointList,
00370 bool readDescriptors, int borderOffset)
00371 {
00372 Util::IOBuffer* buffer = new Util::IOBufferFile(filename, true, false);
00373 char buf[9];
00374 for (int i=0 ; i<9 ; i++)
00375 buf[i] = 0;
00376 buffer->Read(buf, 8);
00377
00378 if(String(buf) == "BINDESC1")
00379 {
00380
00381 buffer->Seek(0, SEEK_SET);
00382 ReadPointListFromBuffer(buffer, outputPointList, readDescriptors,
00383 borderOffset);
00384 delete buffer;
00385 }
00386 else
00387 {
00388 delete buffer;
00389
00390
00391 std::ifstream fs(filename.c_str());
00392 ReadRegionsFromStreamFormatKoen
00393 (fs, outputPointList, false, borderOffset);
00394 fs.close();
00395 }
00396 }
00397
00398
00399 }
00400 }
00401 }
00402
00403 #endif