--- /dev/null
+
+///////////////////////////////////////////////////////////////////////////
+// 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];
+}