Home | History | Annotate | Download | only in flann
      1 /***********************************************************************
      2  * Software License Agreement (BSD License)
      3  *
      4  * Copyright 2008-2009  Marius Muja (mariusm (at) cs.ubc.ca). All rights reserved.
      5  * Copyright 2008-2009  David G. Lowe (lowe (at) cs.ubc.ca). All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  *
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE NNIndexGOODS OR SERVICES; LOSS OF USE,
     23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  *************************************************************************/
     28 
     29 #ifndef OPENCV_FLANN_SAVING_H_
     30 #define OPENCV_FLANN_SAVING_H_
     31 
     32 #include <cstring>
     33 #include <vector>
     34 
     35 #include "general.h"
     36 #include "nn_index.h"
     37 
     38 #ifdef FLANN_SIGNATURE_
     39 #undef FLANN_SIGNATURE_
     40 #endif
     41 #define FLANN_SIGNATURE_ "FLANN_INDEX"
     42 
     43 namespace cvflann
     44 {
     45 
     46 template <typename T>
     47 struct Datatype {};
     48 template<>
     49 struct Datatype<char> { static flann_datatype_t type() { return FLANN_INT8; } };
     50 template<>
     51 struct Datatype<short> { static flann_datatype_t type() { return FLANN_INT16; } };
     52 template<>
     53 struct Datatype<int> { static flann_datatype_t type() { return FLANN_INT32; } };
     54 template<>
     55 struct Datatype<unsigned char> { static flann_datatype_t type() { return FLANN_UINT8; } };
     56 template<>
     57 struct Datatype<unsigned short> { static flann_datatype_t type() { return FLANN_UINT16; } };
     58 template<>
     59 struct Datatype<unsigned int> { static flann_datatype_t type() { return FLANN_UINT32; } };
     60 template<>
     61 struct Datatype<float> { static flann_datatype_t type() { return FLANN_FLOAT32; } };
     62 template<>
     63 struct Datatype<double> { static flann_datatype_t type() { return FLANN_FLOAT64; } };
     64 
     65 
     66 /**
     67  * Structure representing the index header.
     68  */
     69 struct IndexHeader
     70 {
     71     char signature[16];
     72     char version[16];
     73     flann_datatype_t data_type;
     74     flann_algorithm_t index_type;
     75     size_t rows;
     76     size_t cols;
     77 };
     78 
     79 /**
     80  * Saves index header to stream
     81  *
     82  * @param stream - Stream to save to
     83  * @param index - The index to save
     84  */
     85 template<typename Distance>
     86 void save_header(FILE* stream, const NNIndex<Distance>& index)
     87 {
     88     IndexHeader header;
     89     memset(header.signature, 0, sizeof(header.signature));
     90     strcpy(header.signature, FLANN_SIGNATURE_);
     91     memset(header.version, 0, sizeof(header.version));
     92     strcpy(header.version, FLANN_VERSION_);
     93     header.data_type = Datatype<typename Distance::ElementType>::type();
     94     header.index_type = index.getType();
     95     header.rows = index.size();
     96     header.cols = index.veclen();
     97 
     98     std::fwrite(&header, sizeof(header),1,stream);
     99 }
    100 
    101 
    102 /**
    103  *
    104  * @param stream - Stream to load from
    105  * @return Index header
    106  */
    107 inline IndexHeader load_header(FILE* stream)
    108 {
    109     IndexHeader header;
    110     size_t read_size = fread(&header,sizeof(header),1,stream);
    111 
    112     if (read_size!=(size_t)1) {
    113         throw FLANNException("Invalid index file, cannot read");
    114     }
    115 
    116     if (strcmp(header.signature,FLANN_SIGNATURE_)!=0) {
    117         throw FLANNException("Invalid index file, wrong signature");
    118     }
    119 
    120     return header;
    121 
    122 }
    123 
    124 
    125 template<typename T>
    126 void save_value(FILE* stream, const T& value, size_t count = 1)
    127 {
    128     fwrite(&value, sizeof(value),count, stream);
    129 }
    130 
    131 template<typename T>
    132 void save_value(FILE* stream, const cvflann::Matrix<T>& value)
    133 {
    134     fwrite(&value, sizeof(value),1, stream);
    135     fwrite(value.data, sizeof(T),value.rows*value.cols, stream);
    136 }
    137 
    138 template<typename T>
    139 void save_value(FILE* stream, const std::vector<T>& value)
    140 {
    141     size_t size = value.size();
    142     fwrite(&size, sizeof(size_t), 1, stream);
    143     fwrite(&value[0], sizeof(T), size, stream);
    144 }
    145 
    146 template<typename T>
    147 void load_value(FILE* stream, T& value, size_t count = 1)
    148 {
    149     size_t read_cnt = fread(&value, sizeof(value), count, stream);
    150     if (read_cnt != count) {
    151         throw FLANNException("Cannot read from file");
    152     }
    153 }
    154 
    155 template<typename T>
    156 void load_value(FILE* stream, cvflann::Matrix<T>& value)
    157 {
    158     size_t read_cnt = fread(&value, sizeof(value), 1, stream);
    159     if (read_cnt != 1) {
    160         throw FLANNException("Cannot read from file");
    161     }
    162     value.data = new T[value.rows*value.cols];
    163     read_cnt = fread(value.data, sizeof(T), value.rows*value.cols, stream);
    164     if (read_cnt != (size_t)(value.rows*value.cols)) {
    165         throw FLANNException("Cannot read from file");
    166     }
    167 }
    168 
    169 
    170 template<typename T>
    171 void load_value(FILE* stream, std::vector<T>& value)
    172 {
    173     size_t size;
    174     size_t read_cnt = fread(&size, sizeof(size_t), 1, stream);
    175     if (read_cnt!=1) {
    176         throw FLANNException("Cannot read from file");
    177     }
    178     value.resize(size);
    179     read_cnt = fread(&value[0], sizeof(T), size, stream);
    180     if (read_cnt != size) {
    181         throw FLANNException("Cannot read from file");
    182     }
    183 }
    184 
    185 }
    186 
    187 #endif /* OPENCV_FLANN_SAVING_H_ */
    188