automatic commit
[folded-ctf.git] / labelled_image_pool_file.cc
diff --git a/labelled_image_pool_file.cc b/labelled_image_pool_file.cc
new file mode 100644 (file)
index 0000000..cb099ee
--- /dev/null
@@ -0,0 +1,101 @@
+
+///////////////////////////////////////////////////////////////////////////
+// This program is free software: you can redistribute it and/or modify  //
+// it under the terms of the version 3 of the GNU General Public License //
+// as published by the Free Software Foundation.                         //
+//                                                                       //
+// This program is distributed in the hope that it will be useful, but   //
+// WITHOUT ANY WARRANTY; without even the implied warranty of            //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      //
+// General Public License for more details.                              //
+//                                                                       //
+// You should have received a copy of the GNU General Public License     //
+// along with this program. If not, see <http://www.gnu.org/licenses/>.  //
+//                                                                       //
+// Written by Francois Fleuret, (C) IDIAP                                //
+// Contact <francois.fleuret@idiap.ch> for comments & bug reports        //
+///////////////////////////////////////////////////////////////////////////
+
+#include "labelled_image_pool_file.h"
+
+LabelledImagePoolFile::LabelledImagePoolFile(char *file_name) {
+  _stream = new ifstream(file_name);
+
+  if(_stream->fail()) {
+    cerr << "Can not open image pool " << file_name << " for reading." << endl;
+    exit(1);
+  }
+
+  cout << "Opening image pool " << file_name << " ... ";
+  cout.flush();
+
+  LabelledImage dummy;
+
+  int nb_image_max = 1024;
+  int nb_targets = 0;
+
+  _nb_images = 0;
+  streampos *tmp_positions = new streampos[nb_image_max];
+
+  // This looks slightly ugly to me
+
+  _stream->seekg(0, ios::end);
+  streampos end = _stream->tellg();
+  _stream->seekg(0, ios::beg);
+
+  while(_stream->tellg() < end) {
+    grow(&nb_image_max, _nb_images, &tmp_positions, 2);
+    tmp_positions[_nb_images] = _stream->tellg();
+    dummy.read(_stream);
+    nb_targets += dummy.nb_targets();
+    _nb_images++;
+  }
+
+  _images = new LabelledImage *[_nb_images];
+  _image_stream_positions = new streampos[_nb_images];
+  _image_nb_refs = new int[_nb_images];
+
+  for(int i = 0; i < _nb_images; i++) {
+    _images[i] = 0;
+    _image_stream_positions[i] = tmp_positions[i];
+    _image_nb_refs[i] = 0;
+  }
+
+  delete[] tmp_positions;
+
+  cout << "done." << endl;
+  cout << "It contains " << _nb_images << " images and " << nb_targets << " targets." << endl;
+}
+
+LabelledImagePoolFile::~LabelledImagePoolFile() {
+#ifdef DEBUG
+  for(int i = 0; i < _nb_images; i++) if(_image_nb_refs[i] > 0) {
+    cerr << "Destroying a pool while images are grabbed." << endl;
+    abort();
+  }
+#endif
+  delete[] _images;
+  delete[] _image_stream_positions;
+  delete[] _image_nb_refs;
+  delete _stream;
+}
+
+int LabelledImagePoolFile::nb_images() {
+  return _nb_images;
+}
+
+LabelledImage *LabelledImagePoolFile::grab_image(int n_image) {
+  if(_image_nb_refs[n_image] == 0) {
+    _stream->seekg(_image_stream_positions[n_image]);
+    _images[n_image] = new LabelledImage();
+    _images[n_image]->read(_stream);
+  }
+  _image_nb_refs[n_image]++;
+  return _images[n_image];
+}
+
+void LabelledImagePoolFile::release_image(int n_image) {
+  ASSERT(_image_nb_refs[n_image] > 0);
+  _image_nb_refs[n_image]--;
+  if(_image_nb_refs[n_image] <= 0) delete _images[n_image];
+}