Commit e9a1b9742e9c2d44cf3c233d03a6fe945c1a62f0

Authored by Pavel Govyadinov
1 parent ae05c3e4

imlemented Dr. Mayeriches fix for the memory leak. Removed extranous comments

Showing 1 changed file with 35 additions and 31 deletions   Show diff stats
stim/image/image.h
@@ -24,6 +24,8 @@ class image{ @@ -24,6 +24,8 @@ class image{
24 size_t Y() const { return R[2]; } 24 size_t Y() const { return R[2]; }
25 size_t C() const { return R[0]; } 25 size_t C() const { return R[0]; }
26 26
  27 + size_t bytes(){ return size() * sizeof(T); }
  28 +
27 void init(){ //initializes all variables, assumes no memory is allocated 29 void init(){ //initializes all variables, assumes no memory is allocated
28 memset(R, 0, sizeof(size_t) * 3); //set the resolution and number of channels to zero 30 memset(R, 0, sizeof(size_t) * 3); //set the resolution and number of channels to zero
29 img = NULL; 31 img = NULL;
@@ -31,6 +33,8 @@ class image{ @@ -31,6 +33,8 @@ class image{
31 33
32 void unalloc(){ //frees any resources associated with the image 34 void unalloc(){ //frees any resources associated with the image
33 if(img) free(img); //if memory has been allocated, free it 35 if(img) free(img); //if memory has been allocated, free it
  36 + img=NULL;
  37 +
34 } 38 }
35 39
36 40
@@ -40,15 +44,17 @@ class image{ @@ -40,15 +44,17 @@ class image{
40 } 44 }
41 45
42 void allocate(){ 46 void allocate(){
43 - img = (T*) malloc( sizeof(T) * R[0] * R[1] * R[2] ); //allocate memory 47 + unalloc();
  48 + img = (T*) malloc( bytes() ); //allocate memory
  49 + memset(img, 0, bytes());
44 } 50 }
45 51
46 void allocate(size_t x, size_t y, size_t c){ //allocate memory based on the resolution 52 void allocate(size_t x, size_t y, size_t c){ //allocate memory based on the resolution
  53 + unalloc();
47 R[0] = c; R[1] = x; R[2] = y; //set the resolution 54 R[0] = c; R[1] = x; R[2] = y; //set the resolution
48 allocate(); //allocate memory 55 allocate(); //allocate memory
49 } 56 }
50 57
51 - size_t bytes(){ return size() * sizeof(T); }  
52 58
53 size_t idx(size_t x, size_t y, size_t c = 0){ 59 size_t idx(size_t x, size_t y, size_t c = 0){
54 return y * C() * X() + x * C() + c; 60 return y * C() * X() + x * C() + c;
@@ -89,36 +95,33 @@ public: @@ -89,36 +95,33 @@ public:
89 image(){ init(); } //initialize all variables to zero, don't allocate any memory 95 image(){ init(); } //initialize all variables to zero, don't allocate any memory
90 96
91 /// Constructor with a filename - loads the specified file 97 /// Constructor with a filename - loads the specified file
92 - image(std::string filename){ //constructor initialize the image with an image file 98 + image(std::string filename) : image(){ //constructor initialize the image with an image file
93 load(filename); 99 load(filename);
94 } 100 }
95 101
96 /// Create a new image from scratch given a number of samples and channels 102 /// Create a new image from scratch given a number of samples and channels
97 - image(size_t x, size_t y = 1, size_t c = 1){ 103 + image(size_t x, size_t y = 1, size_t c = 1) : image(){
  104 + init();
98 allocate(x, y, c); 105 allocate(x, y, c);
99 } 106 }
100 107
101 /// Create a new image with the data given in 'data' 108 /// Create a new image with the data given in 'data'
102 - image(T* data, size_t x, size_t y, size_t c = 1){ 109 + image(T* data, size_t x, size_t y, size_t c = 1) : image(){
  110 + init();
103 allocate(x, y, c); 111 allocate(x, y, c);
104 memcpy(img, data, bytes()); 112 memcpy(img, data, bytes());
105 } 113 }
106 114
107 /// Copy constructor - duplicates an image object 115 /// Copy constructor - duplicates an image object
108 - image(const stim::image<T>& I){ 116 + image(const stim::image<T>& I) : image(){
  117 + init();
109 allocate(I.X(), I.Y(), I.C()); 118 allocate(I.X(), I.Y(), I.C());
110 - //allocate(I.R[1], I.R[2], I.R[0]);  
111 memcpy(img, I.img, bytes()); 119 memcpy(img, I.img, bytes());
112 } 120 }
113 121
114 /// Destructor - clear memory 122 /// Destructor - clear memory
115 -// ~image(){  
116 -// free(img);  
117 -// }  
118 -  
119 - void clear_exp(){ //clears all image data  
120 - unalloc();  
121 - 123 + ~image(){
  124 + free(img);
122 } 125 }
123 126
124 stim::image<T> operator=(const stim::image<T>& I){ 127 stim::image<T> operator=(const stim::image<T>& I){
@@ -142,24 +145,14 @@ public: @@ -142,24 +145,14 @@ public:
142 if(C() == 1) 145 if(C() == 1)
143 { 146 {
144 //if this is a single-color image, just copy the data 147 //if this is a single-color image, just copy the data
145 -/*  
146 - THIS DOES NOT WORK PROPERLY.  
147 - YOU CANNOT DO MEMCPY LIKE THIS BECAUSE IT CORRUPTS THE POINTREF MECHANIC IN OPENCV AND NEVER ACTUALLY CREATES A DEEP COPY BUT TAKES UP THE MEMORY.  
148 - TO TEST run and compile pseudocode  
149 - stim::image<unsigned char> I;  
150 - for(int i = 0; i < file_list.size(); i++)  
151 - I.load(file_list[i].srt())  
152 -  
153 -  
154 - You will run out of memory.  
155 -*/  
156 memcpy(img, cv_ptr, bytes()); 148 memcpy(img, cv_ptr, bytes());
157 -// img = cvImage.data;  
158 } 149 }
159 - if(C() == 3) //if this is a 3-color image, OpenCV uses BGR interleaving 150 + if(C() == 3)
  151 + { //if this is a 3-color image, OpenCV uses BGR interleaving
160 set_interleaved_bgr(cv_ptr, X(), Y()); 152 set_interleaved_bgr(cv_ptr, X(), Y());
  153 + }
161 154
162 -// cvImage.deallocate(); 155 + cvImage.release();
163 } 156 }
164 157
165 //save a file 158 //save a file
@@ -352,6 +345,17 @@ public: @@ -352,6 +345,17 @@ public:
352 345
353 return r; //return the inverted image 346 return r; //return the inverted image
354 } 347 }
  348 +
  349 + /// Invert an image by calculating I1 = alpha - I0, where alpha is the maximum image value
  350 + image<T> invert(){
  351 + size_t N = size(); //calculate the total number of values in the image
  352 + image<T> r(X(), Y(), C()); //allocate space for the resulting image
  353 + T white_val = maxv();
  354 + for(size_t n = 0; n < N; n++)
  355 + r.img[n] = white_val - img[n]; //perform the inversion
  356 +
  357 + return r; //return the inverted image
  358 + }
355 359
356 ///crops the image from x1 to x0 and y1 to y0 and returns a new (smaller) image. 360 ///crops the image from x1 to x0 and y1 to y0 and returns a new (smaller) image.
357 ///Untested 361 ///Untested
@@ -361,12 +365,12 @@ public: @@ -361,12 +365,12 @@ public:
361 image<T> ret(x1-x0, y1-y0, C()); 365 image<T> ret(x1-x0, y1-y0, C());
362 int newWidth = x1-x0; 366 int newWidth = x1-x0;
363 int destidx, srcidx; 367 int destidx, srcidx;
364 -// for(int i = 0; i < (y1-y0); i++) 368 + for(int i = 0; i < (y1-y0); i++)
365 { 369 {
366 destidx = i*newWidth*C(); ///destination index one per each row 370 destidx = i*newWidth*C(); ///destination index one per each row
367 srcidx = ((i+(y0))*X()+x0)*C(); ///source index, one per each row. 371 srcidx = ((i+(y0))*X()+x0)*C(); ///source index, one per each row.
368 - ret.set_interleaved_rgb(img[srcidx], newWidth, y1-y0, C());  
369 - memcpy(&ret.img[destidx], &buffer[srcidx], sizeof(T)*newWidth*C()); 372 +// ret.set_interleaved_rgb(img[srcidx], newWidth, y1-y0, C());
  373 + memcpy(&ret.img[destidx], &img[srcidx], sizeof(T)*newWidth*C());
370 } 374 }
371 375
372 // for(int i = 0; i < (x1 -x0); i++) 376 // for(int i = 0; i < (x1 -x0); i++)