Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/img

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /externals/g4tools/include/tools/img (Version 11.3.0) and /externals/g4tools/include/tools/img (Version 8.0.p1)


  1 // Copyright (C) 2010, Guy Barrand. All rights    
  2 // See the file tools.license for terms.          
  3                                                   
  4 #ifndef tools_img                                 
  5 #define tools_img                                 
  6                                                   
  7 #ifdef TOOLS_MEM                                  
  8 #include "mem"                                    
  9 #endif                                            
 10                                                   
 11 #include <string> //memcpy                        
 12 #include <cstring> //memcpy                       
 13 #include "mnmx"                                   
 14 #include "S_STRING"                               
 15                                                   
 16 #include <vector> //concatenate                   
 17                                                   
 18 namespace tools {                                 
 19                                                   
 20 template <class T>                                
 21 class img {                                       
 22 public:                                           
 23   TOOLS_T_SCLASS(T,tools::img)                    
 24 public:                                           
 25   img()                                           
 26   :m_w(0),m_h(0),m_n(0)                           
 27   ,m_buffer(0)                                    
 28   ,m_owner(false)                                 
 29   {                                               
 30 #ifdef TOOLS_MEM                                  
 31     mem::increment(s_class().c_str());            
 32 #endif                                            
 33   }                                               
 34   img(unsigned int a_w,unsigned int a_h,unsign    
 35   :m_w(a_w),m_h(a_h),m_n(a_n)                     
 36   ,m_buffer(a_buffer)                             
 37   ,m_owner(a_owner)                               
 38   {                                               
 39 #ifdef TOOLS_MEM                                  
 40     mem::increment(s_class().c_str());            
 41 #endif                                            
 42   }                                               
 43   virtual ~img() {                                
 44     if(m_owner) delete [] m_buffer;               
 45 #ifdef TOOLS_MEM                                  
 46     mem::decrement(s_class().c_str());            
 47 #endif                                            
 48   }                                               
 49 public:                                           
 50   img(const img& a_from)                          
 51   :m_w(a_from.m_w),m_h(a_from.m_h),m_n(a_from.    
 52   ,m_buffer(0)                                    
 53   ,m_owner(a_from.m_owner)                        
 54   {                                               
 55 #ifdef TOOLS_MEM                                  
 56     mem::increment(s_class().c_str());            
 57 #endif                                            
 58     if(m_owner) {                                 
 59       unsigned int sz = m_w*m_h*m_n;              
 60       if(!sz) return;                             
 61       m_buffer = new T[sz];                       
 62       if(!m_buffer) {                             
 63         m_w = 0;m_h = 0;m_n = 0;m_owner = fals    
 64         return; //throw                           
 65       }                                           
 66       ::memcpy(m_buffer,a_from.m_buffer,sz*siz    
 67     } else {                                      
 68       m_buffer = a_from.m_buffer;                 
 69     }                                             
 70   }                                               
 71   img& operator=(const img& a_from){              
 72     if(&a_from==this) return *this;               
 73     if(m_owner) delete [] m_buffer;               
 74     m_buffer = 0;                                 
 75     m_w = a_from.m_w;                             
 76     m_h = a_from.m_h;                             
 77     m_n = a_from.m_n;                             
 78     m_owner = a_from.m_owner;                     
 79     if(m_owner) {                                 
 80       unsigned int sz = m_w*m_h*m_n;              
 81       if(!sz) return *this;                       
 82       m_buffer = new T[sz];                       
 83       if(!m_buffer) {                             
 84         m_w = 0;m_h = 0;m_n = 0;m_owner = fals    
 85         return *this;  //throw                    
 86       }                                           
 87       ::memcpy(m_buffer,a_from.m_buffer,sz*siz    
 88     } else {                                      
 89       m_buffer = a_from.m_buffer;                 
 90     }                                             
 91     return *this;                                 
 92   }                                               
 93 public:                                           
 94   bool operator==(const img& a_from) const {re    
 95   bool operator!=(const img& a_from) const {re    
 96 public:                                           
 97   void transfer(img& a_from) {                    
 98     if(m_owner) delete [] m_buffer;               
 99     m_w = a_from.m_w;                             
100     m_h = a_from.m_h;                             
101     m_n = a_from.m_n;                             
102     m_buffer = a_from.m_buffer;                   
103     m_owner = a_from.m_owner;                     
104     // empty a_from :                             
105     a_from.m_w = 0;                               
106     a_from.m_h = 0;                               
107     a_from.m_buffer = 0;                          
108     a_from.m_owner = false;                       
109   }                                               
110                                                   
111   void clear() {                                  
112     if(m_owner) delete [] m_buffer;               
113     m_w = 0;                                      
114     m_h = 0;                                      
115     m_n = 0;                                      
116     m_buffer = 0;                                 
117     m_owner = false;                              
118   }                                               
119   void set(unsigned int a_w,unsigned int a_h,u    
120     if(m_owner) delete [] m_buffer;               
121     m_w = a_w;                                    
122     m_h = a_h;                                    
123     m_n = a_n;                                    
124     m_buffer = a_buffer;                          
125     m_owner = a_owner;                            
126   }                                               
127   bool copy(unsigned int a_w,unsigned int a_h,    
128     if(m_owner) delete [] m_buffer;               
129     m_buffer = 0;                                 
130     m_w = a_w;                                    
131     m_h = a_h;                                    
132     m_n = a_n;                                    
133     unsigned int sz = m_w*m_h*m_n;                
134     if(!sz) {                                     
135       m_w = 0;m_h = 0;m_n = 0;m_owner = false;    
136       return false;                               
137     }                                             
138     m_buffer = new T[sz];                         
139     if(!m_buffer) {                               
140       m_w = 0;m_h = 0;m_n = 0;m_owner = false;    
141       return false;                               
142     }                                             
143     ::memcpy(m_buffer,a_buffer,sz*sizeof(T));     
144     m_owner = true;                               
145     return true;                                  
146   }                                               
147   bool copy(const img& a_from){                   
148     if(m_owner) delete [] m_buffer;               
149     m_buffer = 0;                                 
150     m_w = a_from.m_w;                             
151     m_h = a_from.m_h;                             
152     m_n = a_from.m_n;                             
153     unsigned int sz = m_w*m_h*m_n;                
154     if(!sz) {                                     
155       m_w = 0;m_h = 0;m_n = 0;m_owner = false;    
156       return false;                               
157     }                                             
158     m_buffer = new T[sz];                         
159     if(!m_buffer) {                               
160       m_w = 0;m_h = 0;m_n = 0;m_owner = false;    
161       return false;                               
162     }                                             
163     ::memcpy(m_buffer,a_from.m_buffer,sz*sizeo    
164     m_owner = true;                               
165     return true;                                  
166   }                                               
167   bool allocate(unsigned int a_w,unsigned int     
168     if(m_owner) delete [] m_buffer;               
169     m_buffer = 0;                                 
170     unsigned int sz = a_w*a_h*a_n;                
171     if(!sz) {                                     
172       m_w = 0;m_h = 0;m_n = 0;m_owner = false;    
173       return false;                               
174     }                                             
175     m_w = a_w;                                    
176     m_h = a_h;                                    
177     m_n = a_n;                                    
178     m_buffer = new T[sz];                         
179     if(!m_buffer) {                               
180       m_w = 0;m_h = 0;m_n = 0;m_owner = false;    
181       return false;                               
182     }                                             
183     m_owner = true;                               
184     return true;                                  
185   }                                               
186   void make_empty(bool a_delete = true) {         
187     if(m_owner && a_delete) delete [] m_buffer    
188     m_w = 0;                                      
189     m_h = 0;                                      
190     m_n = 0;                                      
191     m_buffer = 0;                                 
192     m_owner = false;                              
193   }                                               
194   bool is_empty() const {                         
195     if(!m_w) return true;                         
196     if(!m_h) return true;                         
197     if(!m_n) return true;                         
198     if(!m_buffer) return true;                    
199     return false;                                 
200   }                                               
201   bool equal(const img& a_from) const {           
202     if(m_w!=a_from.m_w) return false;             
203     if(m_h!=a_from.m_h) return false;             
204     if(m_n!=a_from.m_n) return false;             
205     //don't test ownership.                       
206     unsigned int sz = m_w*m_h*m_n;                
207     T* pos = m_buffer;                            
208     T* fpos = a_from.m_buffer;                    
209     for(unsigned int index=0;index<sz;index++,    
210       if((*pos)!=(*fpos)) return false;           
211     }                                             
212     return true;                                  
213   }                                               
214   unsigned int width() const {return m_w;}        
215   unsigned int height() const {return m_h;}       
216   unsigned int bytes_per_pixel() const {return    
217   unsigned int bpp() const {return m_n;}          
218   const T* buffer() const {return m_buffer;}      
219   T* buffer() {return m_buffer;}                  
220   bool owner() const {return m_owner;}            
221   unsigned int size() const {return m_w*m_h*m_    
222 public:                                           
223   bool pixel(unsigned int a_i,unsigned a_j,std    
224     if((!m_w)||(!m_h)||(a_i>=m_w)||(a_j>=m_h))    
225       a_pixel.clear();                            
226       return false;                               
227     }                                             
228     a_pixel.resize(m_n);                          
229     T* pos = m_buffer + a_j * (m_w * m_n) + a_    
230     for(unsigned int ipix=0;ipix<m_n;ipix++) {    
231       a_pixel[ipix] = *(pos+ipix);                
232     }                                             
233     return true;                                  
234   }                                               
235                                                   
236   bool expand(unsigned int a_factor,img<T>& a_    
237     if(a_factor==1) {                             
238       if(a_res_force_owner) {                     
239         a_res.copy(m_w,m_h,m_n,m_buffer);         
240       } else {                                    
241         a_res.set(m_w,m_h,m_n,m_buffer,false);    
242       }                                           
243       return true;                                
244     }                                             
245                                                   
246     unsigned int nw = m_w*a_factor;               
247     unsigned int nh = m_h*a_factor;               
248     unsigned int sz = nh*nw*m_n;                  
249     if(!sz) {                                     
250       a_res.make_empty();                         
251       return false;                               
252     }                                             
253                                                   
254     T* nb = new T[sz];                            
255     if(!nb) {                                     
256       a_res.make_empty();                         
257       return false;                               
258     }                                             
259                                                   
260     for(unsigned int j=0;j<m_h;j++) {             
261       for(unsigned int i=0;i<m_w;i++) {           
262         //position in the original image.         
263         T* pos = m_buffer + j * (m_w * m_n) +     
264                                                   
265         for(unsigned int fr=0;fr<a_factor;fr++    
266           for(unsigned int fc=0;fc<a_factor;fc    
267             //position in the new image.          
268             T* npos = nb + (j*a_factor+fr) * (    
269             for(unsigned int ipix=0;ipix<m_n;i    
270               *(npos+ipix) = *(pos+ipix);         
271             }                                     
272           }                                       
273         }                                         
274                                                   
275       }                                           
276     }                                             
277                                                   
278     a_res.set(nw,nh,m_n,nb,true);                 
279     return true;                                  
280   }                                               
281                                                   
282   bool contract_raw(unsigned int a_w,unsigned     
283     if((a_w==m_w)&&(a_h==m_h)) {                  
284       if(a_force_res_owner) {                     
285         a_res.copy(m_w,m_h,m_n,m_buffer);         
286       } else {                                    
287         a_res.set(m_w,m_h,m_n,m_buffer,false);    
288       }                                           
289       return true;                                
290     }                                             
291                                                   
292     unsigned int sz = a_h*a_w*m_n;                
293     if(!sz) {                                     
294       a_res.make_empty();                         
295       return false;                               
296     }                                             
297                                                   
298     T* rb = new T[sz];                            
299     if(!rb) {                                     
300       a_res.make_empty();                         
301       return false;                               
302     }                                             
303                                                   
304     double* pixels = new double[m_n]; //for me    
305     if(!pixels) {                                 
306       delete [] rb;                               
307       a_res.make_empty();                         
308       return false;                               
309     }                                             
310                                                   
311     unsigned int wfac = double(m_w)/double(a_w    
312     unsigned int hfac = double(m_h)/double(a_h    
313     if(!wfac) wfac = 1;                           
314     if(!hfac) hfac = 1;                           
315                                                   
316     unsigned int wfac_hfac = wfac*hfac;           
317                                                   
318     T* hpos;T* pos;                               
319     for(unsigned int j=0;j<a_h;j++) {             
320       for(unsigned int i=0;i<a_w;i++) {           
321                                                   
322         // take mean value of wfac*hfac pixels    
323        {for(unsigned int ipix=0;ipix<m_n;ipix+    
324                                                   
325         for(unsigned int fr=0;fr<hfac;fr++) {     
326           hpos = m_buffer + (j*hfac+fr)*(m_w*m    
327           for(unsigned int fc=0;fc<wfac;fc++)     
328             pos = hpos + (i*wfac+fc)*m_n;         
329             for(unsigned int ipix=0;ipix<m_n;i    
330               pixels[ipix] += double(*pos)/dou    
331             }                                     
332           }                                       
333         }                                         
334                                                   
335         //position in the result image.           
336         T* rpos = rb + j * (a_w * m_n) + i*m_n    
337        {for(unsigned int ipix=0;ipix<m_n;ipix+    
338       }                                           
339     }                                             
340                                                   
341     delete [] pixels;                             
342                                                   
343     a_res.set(a_w,a_h,m_n,rb,true);               
344     return true;                                  
345   }                                               
346                                                   
347   bool contract(unsigned int a_w,unsigned int     
348     //optimized version of contract_raw().        
349                                                   
350     if((a_w==m_w)&&(a_h==m_h)) {                  
351       if(a_force_res_owner) {                     
352         a_res.copy(m_w,m_h,m_n,m_buffer);         
353       } else {                                    
354         a_res.set(m_w,m_h,m_n,m_buffer,false);    
355       }                                           
356       return true;                                
357     }                                             
358                                                   
359     size_t sz = a_h*a_w*m_n;                      
360     if(!sz) {                                     
361       a_res.make_empty();                         
362       return false;                               
363     }                                             
364                                                   
365     T* rb = new T[sz];                            
366     if(!rb) {                                     
367       a_res.make_empty();                         
368       return false;                               
369     }                                             
370                                                   
371     double* pixels = new double[m_n]; //for me    
372     if(!pixels) {                                 
373       delete [] rb;                               
374       a_res.make_empty();                         
375       return false;                               
376     }                                             
377    {for(unsigned int ipix=0;ipix<m_n;ipix++) p    
378                                                   
379     unsigned int wfac = (unsigned int)(double(    
380     unsigned int hfac = (unsigned int)(double(    
381     if(!wfac) wfac = 1;                           
382     if(!hfac) hfac = 1;                           
383                                                   
384     double wfac_hfac = wfac*hfac;                 
385                                                   
386     //::printf("debug : %d %d, %d %d\n",a_h,a_    
387                                                   
388     T* hpos;T* pos;T* hrpos;T* rpos;T* hhpos;T    
389     unsigned int i,j,fr,fc,ipix,i0;               
390     unsigned int astride = a_w * m_n;             
391     unsigned int mstride = m_w * m_n;             
392     unsigned int wfacstride = wfac * m_n;         
393                                                   
394     for(j=0;j<a_h;j++) {                          
395       hrpos = rb + j * astride;                   
396       hhpos = m_buffer + j*hfac*mstride;          
397       for(i=0;i<a_w;i++) {                        
398                                                   
399         // take mean value of wfac*hfac pixels    
400                                                   
401         i0 = i*wfacstride;                        
402                                                   
403         hpos = hhpos;                             
404         for(fr=0;fr<hfac;fr++,hpos+=mstride) {    
405           _pos = hpos + i0;                       
406           for(fc=0;fc<wfac;fc++,_pos+=m_n) {      
407             pos = _pos;                           
408             ppos = pixels;                        
409             for(ipix=0;ipix<m_n;ipix++,pos++,p    
410               *ppos += double(*pos)/wfac_hfac;    
411 //              *ppos += double(*pos); //NOTE     
412             }                                     
413           }                                       
414         }                                         
415                                                   
416         //position in the result image.           
417         rpos = hrpos + i*m_n;                     
418         ppos = pixels;                            
419         for(ipix=0;ipix<m_n;ipix++,rpos++,ppos    
420           *rpos = T(*ppos);                       
421 //          *rpos = T((*ppos)/wfac_hfac); //sl    
422           *ppos = 0;                              
423         }                                         
424       }                                           
425     }                                             
426                                                   
427     delete [] pixels;                             
428                                                   
429     a_res.set(a_w,a_h,m_n,rb,true);               
430     return true;                                  
431   }                                               
432                                                   
433   bool contract(unsigned int a_factor,img<T>&     
434     // a_factor pixels are contracted in one.     
435     unsigned int nw = m_w/a_factor;               
436     unsigned int nh = m_h/a_factor;               
437     return contract(nw,nh,a_res,a_force_res_ow    
438   }                                               
439                                                   
440   template <class TTO>                            
441   bool convert(img<TTO>& a_res) const {           
442     a_res.make_empty();                           
443                                                   
444     unsigned int sz = m_w*m_h*m_n;                
445     if(!sz) return false;                         
446                                                   
447     TTO* _buffer = new TTO[sz];                   
448     if(!_buffer) return false;                    
449                                                   
450     unsigned int i,j,ipix,imn;                    
451     unsigned int mwn = m_w*m_n;                   
452     T* _pos;T* pos;                               
453     TTO* _rpos;TTO* rpos;                         
454                                                   
455     for(j=0;j<m_h;j++) {                          
456       _pos = m_buffer + j*mwn;                    
457       _rpos = _buffer + j*mwn;                    
458       for(i=0;i<m_w;i++) {                        
459         imn = i*m_n;                              
460         pos = _pos + imn;                         
461         rpos = _rpos + imn;                       
462         for(ipix=0;ipix<m_n;ipix++,pos++,rpos+    
463       }                                           
464     }                                             
465                                                   
466     a_res.set(m_w,m_h,m_n,_buffer,true);          
467     return true;                                  
468   }                                               
469                                                   
470   bool get_part(unsigned int a_sx,unsigned int    
471                                                   
472     if((a_sx>=m_w)||(a_sy>=m_h)){                 
473       a_res.make_empty();                         
474       return false;                               
475     }                                             
476                                                   
477     // 012345                                     
478     unsigned int rw = min_of<unsigned int>(m_w    
479     unsigned int rh = min_of<unsigned int>(m_h    
480     unsigned int sz = rh*rw*m_n;                  
481     if(!sz) {                                     
482       a_res.make_empty();                         
483       return false;                               
484     }                                             
485                                                   
486     T* rb = new T[sz];                            
487     if(!rb) {                                     
488       a_res.make_empty();                         
489       return false;                               
490     }                                             
491                                                   
492     unsigned int rstride = rw * m_n;              
493     T* rpos = rb;                                 
494                                                   
495     unsigned int stride = m_w * m_n;              
496     T* pos = m_buffer+a_sy*stride+a_sx*m_n;       
497                                                   
498     //T* mx = m_buffer+size();                    
499     //T* rmx = rb+sz*sizeof(T);                   
500                                                   
501     for(unsigned int j=0;j<rh;j++,rpos+=rstrid    
502 /*                                                
503       if((pos+rstride*sizeof(T))>mx) {            
504         ::printf("debug : get_part : buffer ov    
505         delete [] rb;                             
506         a_res.make_empty();                       
507         return false;                             
508       }                                           
509       if((rpos+rstride*sizeof(T))>rmx) {          
510         ::printf("debug : get_part : result bu    
511         delete [] rb;                             
512         a_res.make_empty();                       
513         return false;                             
514       }                                           
515 */                                                
516       ::memcpy(rpos,pos,rstride*sizeof(T));       
517     }                                             
518                                                   
519     a_res.set(rw,rh,m_n,rb,true);                 
520     return true;                                  
521   }                                               
522                                                   
523   bool to_texture(bool a_expand,                  
524                   const T a_pixel[], //size sh    
525                   img<T>& a_res,bool a_res_for    
526                                                   
527     //NOTE : pixels of the original image are     
528                                                   
529     if((!m_w)||(!m_h)) {                          
530       a_res.make_empty();                         
531       return false;                               
532     }                                             
533                                                   
534     // in case (m_w==1)||(m_h==1), expand the     
535     // up to the closest power of 2 ?             
536                                                   
537     if((m_w==1)||(m_h==1)||a_expand) {            
538       // find closest power of two upper than     
539       unsigned int rw = 2;                        
540       while(true) {if(rw>=m_w) break;rw *=2;}     
541       unsigned int rh = 2;                        
542       while(true) {if(rh>=m_h) break;rh *=2;}     
543                                                   
544       if((rw==m_w)&&(rh==m_h)) { //exact match    
545         if(a_res_force_owner) {                   
546           a_res.copy(m_w,m_h,m_n,m_buffer);       
547         } else {                                  
548           a_res.set(m_w,m_h,m_n,m_buffer,false    
549         }                                         
550         return true;                              
551       }                                           
552                                                   
553       // we expand the image and fill new spac    
554                                                   
555       T* rb = 0;                                  
556       bool res_set = true;                        
557       if(a_res.owner()&&(a_res.size()==(rh*rw*    
558         // a_res has already the right allocat    
559         rb = a_res.buffer();                      
560         res_set = false;                          
561       } else {                                    
562         rb = new T[rh*rw*m_n];                    
563         if(!rb) {                                 
564           a_res.make_empty();                     
565           return false;                           
566         }                                         
567       }                                           
568                                                   
569       unsigned int num = rw*m_n;                  
570                                                   
571       // initialize with given color :            
572      {T* pos = rb;                                
573       for(unsigned int i=0;i<rw;i++,pos+=m_n)     
574         ::memcpy(pos,a_pixel,m_n*sizeof(T));      
575       }                                           
576       unsigned int sz = num*sizeof(T);            
577       for(unsigned int j=1;j<rh;j++,pos+=num)     
578         ::memcpy(pos,rb,sz);                      
579       }}                                          
580                                                   
581       // center :                                 
582       unsigned int col = (rw-m_w)/2;              
583       unsigned int row = (rh-m_h)/2;              
584                                                   
585       unsigned int mnum = m_w*m_n;                
586                                                   
587       // copy original image in a centered par    
588      {T* pos = m_buffer;                          
589       T* rpos = rb+row*num+col*m_n;               
590       unsigned int sz = mnum*sizeof(T);           
591       for(unsigned int j=0;j<m_h;j++,pos+=mnum    
592         ::memcpy(rpos,pos,sz);                    
593       }}                                          
594                                                   
595       if(res_set) a_res.set(rw,rh,m_n,rb,true)    
596                                                   
597       return true;                                
598     } else {                                      
599       // then m_w>=2 and m_h>=2                   
600                                                   
601       // find closest power of two lower than     
602       unsigned int sw = 2;                        
603       while(true) {if((sw*2)>m_w) break;sw *=2    
604       unsigned int sh = 2;                        
605       while(true) {if((sh*2)>m_h) break;sh *=2    
606                                                   
607       if((sw==m_w)&&(sh==m_h)) { //exact match    
608         if(a_res_force_owner) {                   
609           a_res.copy(m_w,m_h,m_n,m_buffer);       
610         } else {                                  
611           a_res.set(m_w,m_h,m_n,m_buffer,false    
612         }                                         
613         return true;                              
614       }                                           
615                                                   
616       unsigned int sx = (m_w-sw)/2;               
617       unsigned int sy = (m_h-sh)/2;               
618                                                   
619       return get_part(sx,sy,sw,sh,a_res);         
620     }                                             
621                                                   
622   }                                               
623                                                   
624   bool check_gl_limit(unsigned int a_GL_MAX_TE    
625     // if ret true and a_res.is_empty(), "this    
626     // if ret true and !a_res.is_empty(), "thi    
627     // if ret false, "this" exceeds the limit     
628     unsigned int tw = m_w;                        
629     unsigned int th = m_h;                        
630     if((tw<=a_GL_MAX_TEXTURE_SIZE)&&(th<=a_GL_    
631       a_res.make_empty();                         
632       return true;                                
633     }                                             
634     unsigned int fac = 2;                         
635     while(true) {                                 
636       unsigned int pw = tw/fac;                   
637       unsigned int ph = th/fac;                   
638       if((pw<=a_GL_MAX_TEXTURE_SIZE)&&(ph<=a_G    
639         //unsigned int sx = (tw-pw)/2;            
640         //unsigned int sy = (th-ph)/2;            
641         //if(!get_part(sx,sy,pw,ph,a_res)) {      
642         if(!contract(fac,a_res)) {                
643           a_res.make_empty();                     
644           return false;                           
645         }                                         
646         return true;                              
647       }                                           
648       fac *= 2;                                   
649     }                                             
650     a_res.make_empty();                           
651     return false;                                 
652   }                                               
653                                                   
654   bool bw2x(unsigned int a_n,img<T>& a_res) co    
655     //expect a bw img.                            
656     if(m_n!=1) return false;                      
657                                                   
658     a_res.make_empty();                           
659     if(a_n<m_n) return false;                     
660     unsigned int sz = m_w*m_h*a_n;                
661     if(!sz) return false;                         
662                                                   
663     a_res.m_buffer = new T[sz];                   
664     if(!a_res.m_buffer) return false;             
665     a_res.m_owner = true;                         
666     a_res.m_w = m_w;                              
667     a_res.m_h = m_h;                              
668     a_res.m_n = a_n;                              
669                                                   
670     for(unsigned int j=0;j<m_h;j++) {             
671       for(unsigned int i=0;i<m_w;i++) {           
672         //position in the original image.         
673         T* pos = m_buffer + j * (m_w * m_n) +     
674                                                   
675         T* rpos = a_res.m_buffer + j * (m_w *     
676                                                   
677         for(unsigned int ipix=0;ipix<a_n;ipix+    
678           *(rpos+ipix) = *pos;                    
679         }                                         
680                                                   
681       }                                           
682     }                                             
683                                                   
684     return true;                                  
685   }                                               
686                                                   
687   bool yswap(img<T>& a_res) const {               
688     a_res.make_empty();                           
689                                                   
690     a_res.m_buffer = new T[size()];               
691     if(!a_res.m_buffer) return false;             
692     a_res.m_owner = true;                         
693     a_res.m_w = m_w;                              
694     a_res.m_h = m_h;                              
695     a_res.m_n = m_n;                              
696                                                   
697     unsigned int stride = m_w * m_n;              
698                                                   
699     for(unsigned int j=0;j<m_h;j++) {             
700       T* pos = m_buffer + j * stride;             
701       T* rpos = a_res.m_buffer + (m_h-j-1) * s    
702       ::memcpy(rpos,pos,stride*sizeof(T));        
703     }                                             
704                                                   
705     return true;                                  
706   }                                               
707                                                   
708   bool rgba2rgb(img<T>& a_res) const {            
709     if(m_n!=4) return false;                      
710                                                   
711     unsigned int a_n = 3;                         
712                                                   
713     a_res.make_empty();                           
714     unsigned int sz = m_w*m_h*a_n;                
715     if(!sz) return false;                         
716                                                   
717     a_res.m_buffer = new T[sz];                   
718     if(!a_res.m_buffer) return false;             
719     a_res.m_owner = true;                         
720     a_res.m_w = m_w;                              
721     a_res.m_h = m_h;                              
722     a_res.m_n = a_n;                              
723                                                   
724     for(unsigned int j=0;j<m_h;j++) {             
725       for(unsigned int i=0;i<m_w;i++) {           
726         //position in the original image.         
727         T* pos = m_buffer + j * (m_w * m_n) +     
728                                                   
729         T* rpos = a_res.m_buffer + j * (m_w *     
730                                                   
731         for(unsigned int ipix=0;ipix<a_n;ipix+    
732           *(rpos+ipix) = *(pos+ipix);             
733         }                                         
734                                                   
735       }                                           
736     }                                             
737                                                   
738     return true;                                  
739   }                                               
740                                                   
741   bool rgb2rgba(img<T>& a_res,const T& a_pixel    
742     if(m_n!=3) return false;                      
743                                                   
744     unsigned int n = 4;                           
745                                                   
746     a_res.make_empty();                           
747     unsigned int sz = m_w*m_h*n;                  
748     if(!sz) return false;                         
749                                                   
750     a_res.m_buffer = new T[sz];                   
751     if(!a_res.m_buffer) return false;             
752     a_res.m_owner = true;                         
753     a_res.m_w = m_w;                              
754     a_res.m_h = m_h;                              
755     a_res.m_n = n;                                
756                                                   
757     for(unsigned int j=0;j<m_h;j++) {             
758       for(unsigned int i=0;i<m_w;i++) {           
759         //position in the original image.         
760         T* pos = m_buffer + j * (m_w * m_n) +     
761                                                   
762         T* rpos = a_res.m_buffer + j * (m_w *     
763                                                   
764         *(rpos+0) = *(pos+0);                     
765         *(rpos+1) = *(pos+1);                     
766         *(rpos+2) = *(pos+2);                     
767         *(rpos+3) = a_pixel;                      
768                                                   
769       }                                           
770     }                                             
771                                                   
772     return true;                                  
773   }                                               
774                                                   
775   bool rgba2bgra() {                              
776     if(m_n!=4) return false;                      
777     for(unsigned int j=0;j<m_h;j++) {             
778       for(unsigned int i=0;i<m_w;i++) {           
779         T* pos = m_buffer + j * (m_w * m_n) +     
780         T r = *(pos+0);                           
781         T g = *(pos+1);                           
782         T b = *(pos+2);                           
783         T a = *(pos+3);                           
784         *(pos+0) = b;                             
785         *(pos+1) = g;                             
786         *(pos+2) = r;                             
787         *(pos+3) = a;                             
788       }                                           
789     }                                             
790     return true;                                  
791   }                                               
792                                                   
793 public:                                           
794   static bool concatenate(const std::vector< i    
795                           unsigned int a_cols,    
796                           unsigned int a_bw,un    
797                           T a_bc, //border gre    
798                           img<T>& a_res){         
799     // We assume that a_imgs.size() is a_cols*    
800                                                   
801     unsigned int num = a_cols*a_rows;             
802     if(!num) {a_res.make_empty();return false;    
803                                                   
804     unsigned int aw = a_imgs[0].m_w;              
805     unsigned int ah = a_imgs[0].m_h;              
806     unsigned int an = a_imgs[0].m_n;              
807                                                   
808     for(unsigned int index=1;index<num;index++    
809       if(a_imgs[index].m_n!=an) {                 
810         a_res.make_empty();                       
811         return false;                             
812       }                                           
813       if(a_imgs[index].m_w!=aw) {                 
814         a_res.make_empty();                       
815         return false;                             
816       }                                           
817       if(a_imgs[index].m_h!=ah) {                 
818         a_res.make_empty();                       
819         return false;                             
820       }                                           
821     }                                             
822                                                   
823     unsigned int wbw = aw + 2*a_bw;               
824     unsigned int hbh = ah + 2*a_bh;               
825                                                   
826     unsigned int rw = wbw * a_cols;               
827     unsigned int rh = hbh * a_rows;               
828     unsigned int rn = an;                         
829                                                   
830     //printf("debug : %d %d\n",rw,rh);            
831                                                   
832     // on big concatenated image the below may    
833     unsigned int rsz = rh*rw*rn;                  
834     T* rb = new T[rsz];                           
835     if(!rb) {                                     
836       a_res.make_empty();                         
837       return false;                               
838     }                                             
839                                                   
840     bool has_border = a_bw||a_bh?true:false;      
841     if(has_border) {                              
842       ::memset(rb,a_bc,rsz*sizeof(T));            
843     }                                             
844                                                   
845     //optimize :                                  
846     //unsigned int wbwn = wbw*an;                 
847     unsigned int awn = aw*an;                     
848     unsigned int rwn = rw*an;                     
849     unsigned int i,j,r;                           
850     //unsigned int c;                             
851     T* pos;T* ptile;T* _pos;                      
852                                                   
853     //copy tiles :                                
854     unsigned int index = 0;                       
855     for(j=0;j<a_rows;j++) {                       
856       for(i=0;i<a_cols;i++) {                     
857         // index = a_cols*j+i                     
858         const T* tile = a_imgs[index].buffer()    
859                                                   
860         //if(has_border) {                        
861         //  for(unsigned int r=0;r<hbh;r++) {     
862         //    T* pos = rb + (j*hbh+r)*rwn + i*    
863         //    ::memset(pos,a_bc,wbwn*sizeof(T)    
864         //  }                                     
865         //}                                       
866                                                   
867         _pos = rb + (j*hbh+a_bh)*rwn + (i*wbw+    
868        {for(r=0;r<ah;r++) {                       
869 //          pos = _pos + r*rwn;                   
870 //          ptile = tile + r*awn;                 
871 //          for(c=0;c<awn;c++,pos++,ptile++) *    
872           ::memcpy(_pos+r*rwn,tile+r*awn,awn*s    
873         }}                                        
874                                                   
875         index++;                                  
876       }                                           
877     }                                             
878                                                   
879     a_res.set(rw,rh,rn,rb,true);                  
880     return true;                                  
881   }                                               
882                                                   
883 protected:                                        
884   unsigned int m_w;                               
885   unsigned int m_h;                               
886   unsigned int m_n;                               
887   T* m_buffer;                                    
888   bool m_owner;                                   
889                                                   
890 private: static void check_instantiation() {im    
891 };                                                
892                                                   
893                                                   
894 typedef img<unsigned char> img_byte;              
895                                                   
896 // NOTE : img_byte is ready for OpenGL glTexIm    
897 //        For glTexImage2D, first row in m_buf    
898                                                   
899 inline void tex_expand_size(unsigned int a_w,u    
900                             unsigned int& a_ew    
901   // find closest power of two upper than a_w,    
902   a_ew = 2;                                       
903   while(true) {if(a_ew>=a_w) break;a_ew *=2;}     
904   a_eh = 2;                                       
905   while(true) {if(a_eh>=a_h) break;a_eh *=2;}     
906 }                                                 
907                                                   
908 }                                                 
909                                                   
910 #endif