automatic commit
[folded-ctf.git] / labelled_image_pool_file.cc
1
2 ///////////////////////////////////////////////////////////////////////////
3 // This program is free software: you can redistribute it and/or modify  //
4 // it under the terms of the version 3 of the GNU General Public License //
5 // as published by the Free Software Foundation.                         //
6 //                                                                       //
7 // This program is distributed in the hope that it will be useful, but   //
8 // WITHOUT ANY WARRANTY; without even the implied warranty of            //
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      //
10 // General Public License for more details.                              //
11 //                                                                       //
12 // You should have received a copy of the GNU General Public License     //
13 // along with this program. If not, see <http://www.gnu.org/licenses/>.  //
14 //                                                                       //
15 // Written by Francois Fleuret                                           //
16 // (C) Idiap Research Institute                                          //
17 //                                                                       //
18 // Contact <francois.fleuret@idiap.ch> for comments & bug reports        //
19 ///////////////////////////////////////////////////////////////////////////
20
21 #include "labelled_image_pool_file.h"
22
23 LabelledImagePoolFile::LabelledImagePoolFile(char *file_name) {
24   _stream = new ifstream(file_name);
25
26   if(_stream->fail()) {
27     cerr << "Can not open image pool " << file_name << " for reading." << endl;
28     exit(1);
29   }
30
31   cout << "Opening image pool " << file_name << " ... ";
32   cout.flush();
33
34   LabelledImage dummy;
35
36   int nb_image_max = 1024;
37   int nb_targets = 0;
38
39   _nb_images = 0;
40   streampos *tmp_positions = new streampos[nb_image_max];
41
42   // This looks slightly ugly to me
43
44   _stream->seekg(0, ios::end);
45   streampos end = _stream->tellg();
46   _stream->seekg(0, ios::beg);
47
48   while(_stream->tellg() < end) {
49     grow(&nb_image_max, _nb_images, &tmp_positions, 2);
50     tmp_positions[_nb_images] = _stream->tellg();
51     dummy.read(_stream);
52     nb_targets += dummy.nb_targets();
53     _nb_images++;
54   }
55
56   _images = new LabelledImage *[_nb_images];
57   _image_stream_positions = new streampos[_nb_images];
58   _image_nb_refs = new int[_nb_images];
59
60   for(int i = 0; i < _nb_images; i++) {
61     _images[i] = 0;
62     _image_stream_positions[i] = tmp_positions[i];
63     _image_nb_refs[i] = 0;
64   }
65
66   delete[] tmp_positions;
67
68   cout << "done." << endl;
69   cout << "It contains " << _nb_images << " images and " << nb_targets << " targets." << endl;
70 }
71
72 LabelledImagePoolFile::~LabelledImagePoolFile() {
73 #ifdef DEBUG
74   for(int i = 0; i < _nb_images; i++) if(_image_nb_refs[i] > 0) {
75     cerr << "Destroying a pool while images are grabbed." << endl;
76     abort();
77   }
78 #endif
79   delete[] _images;
80   delete[] _image_stream_positions;
81   delete[] _image_nb_refs;
82   delete _stream;
83 }
84
85 int LabelledImagePoolFile::nb_images() {
86   return _nb_images;
87 }
88
89 LabelledImage *LabelledImagePoolFile::grab_image(int n_image) {
90   if(_image_nb_refs[n_image] == 0) {
91     _stream->seekg(_image_stream_positions[n_image]);
92     _images[n_image] = new LabelledImage();
93     _images[n_image]->read(_stream);
94   }
95   _image_nb_refs[n_image]++;
96   return _images[n_image];
97 }
98
99 void LabelledImagePoolFile::release_image(int n_image) {
100   ASSERT(_image_nb_refs[n_image] > 0);
101   _image_nb_refs[n_image]--;
102   if(_image_nb_refs[n_image] <= 0) delete _images[n_image];
103 }