MultiChannelImage3DT.tcc 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764
  1. #include <iostream>
  2. #include <assert.h>
  3. #include <stdio.h>
  4. namespace NICE {
  5. template<class P>
  6. MultiChannelImage3DT<P>::MultiChannelImage3DT( int _xsize, int _ysize, int _zsize, uint _numChannels)
  7. {
  8. data = NULL;
  9. numChannels = 0;
  10. xsize = 0;
  11. ysize = 0;
  12. zsize = 0;
  13. reInit( _xsize, _ysize, _zsize, _numChannels);
  14. }
  15. template<class P>
  16. MultiChannelImage3DT<P>::MultiChannelImage3DT()
  17. {
  18. xsize = 0;
  19. ysize = 0;
  20. zsize = 0;
  21. numChannels = 0;
  22. data = NULL;
  23. }
  24. template<class P>
  25. P & MultiChannelImage3DT<P>::operator() (int x, int y, int z, uint channel)
  26. {
  27. assert( channel < numChannels );
  28. assert(( x < xsize ) && ( x >= 0 ) );
  29. assert(( y < ysize ) && ( y >= 0 ) );
  30. assert(( z < zsize ) && ( z >= 0 ) );
  31. assert( data[channel] != NULL );
  32. return data[channel][x + y*xsize + z*xsize*ysize];
  33. }
  34. template<class P>
  35. MultiChannelImageT<P> MultiChannelImage3DT<P>::operator[] (uint c)
  36. {
  37. // This was our first idea ... but it creates a real copy
  38. // ImageT<P> tmp ( data[c], xsize, ysize, xsize*sizeof(P), GrayColorImageCommonImplementation::noAlignment );
  39. // This is the correct version. The funny thing about this is that shallowCopy
  40. // is not an enum parameter, but an instance of ShallowCopyMode, which is a class.
  41. // This fancy trick was done in older to prevent automatic conversion between enum types
  42. // as done implicitly by C++.
  43. MultiChannelImageT<P> img;
  44. for( int z = 0; z < zsize; z++ )
  45. {
  46. P * datatmp = data[c];
  47. ImageT<P> tmp ( &datatmp[z*(xsize*ysize)], xsize, ysize, xsize*sizeof(P), GrayColorImageCommonImplementation::shallowCopy );
  48. img.addChannel(tmp);
  49. }
  50. return img;
  51. }
  52. template<class P>
  53. MultiChannelImage3DT<P>& MultiChannelImage3DT<P>::operator=(const MultiChannelImage3DT<P>& orig)
  54. {
  55. if(!(xsize == orig.xsize && ysize == orig.ysize && zsize == orig.zsize && numChannels == orig.numChannels))
  56. {
  57. freeData();
  58. xsize = orig.xsize;
  59. ysize = orig.ysize;
  60. zsize = orig.zsize;
  61. numChannels = orig.numChannels;
  62. if(orig.data != NULL)
  63. {
  64. data = new P *[numChannels];
  65. for ( int c = 0; c < ( int )numChannels; c++ )
  66. {
  67. if ( orig.data[c] == NULL )
  68. {
  69. data[c] = NULL;
  70. }
  71. else
  72. {
  73. data[c] = new P [xsize*ysize*zsize];
  74. }
  75. }
  76. }
  77. else
  78. data = NULL;
  79. }
  80. for ( int c = 0; c < ( int )numChannels; c++ )
  81. {
  82. if ( orig.data[c] != NULL )
  83. {
  84. for ( int x = 0; x < xsize*ysize*zsize; x++ )
  85. {
  86. data[c][x] = orig.data[c][x];
  87. }
  88. }
  89. }
  90. return *this;
  91. }
  92. template<class P>
  93. MultiChannelImage3DT<P>::MultiChannelImage3DT( const MultiChannelImage3DT<P>& p )
  94. {
  95. data = NULL;
  96. xsize = p.xsize;
  97. ysize = p.ysize;
  98. zsize = p.zsize;
  99. numChannels = p.numChannels;
  100. if(p.data != NULL)
  101. data = new P *[numChannels];
  102. else
  103. data = NULL;
  104. for ( int c = 0; c < ( int )numChannels; c++ )
  105. {
  106. if ( p.data[c] == NULL )
  107. {
  108. data[c] = NULL;
  109. }
  110. else
  111. {
  112. data[c] = new P [xsize*ysize*zsize];
  113. for ( int x = 0; x < xsize*ysize*zsize; x++ )
  114. {
  115. data[c][x] = p.data[c][x];
  116. }
  117. }
  118. }
  119. }
  120. template<class P>
  121. void MultiChannelImage3DT<P>::addChannel( int newChans )
  122. {
  123. P **tmpData = new P *[numChannels+newChans];
  124. bool allocMem = false;
  125. int i = 0;
  126. for ( ; i < (int)numChannels; i++ )
  127. {
  128. tmpData[i] = data[i];
  129. if ( data[i] != NULL )
  130. allocMem = true;
  131. }
  132. if ( allocMem )
  133. {
  134. for ( ; i < newChans + (int)numChannels; i++ )
  135. {
  136. tmpData[i] = new P [xsize*ysize*zsize];
  137. }
  138. }
  139. numChannels += newChans;
  140. delete [] data;
  141. data = new P *[numChannels];
  142. for ( i = 0; i < (int)numChannels; i++ )
  143. {
  144. data[i] = tmpData[i];
  145. }
  146. delete [] tmpData;
  147. }
  148. template<class P>
  149. template<class SrcP>
  150. void MultiChannelImage3DT<P>::addChannel(NICE::MultiChannelImageT<SrcP> &newMCImg)
  151. {
  152. int oldchan = numChannels;
  153. if(this->xsize > 0)
  154. {
  155. assert(newMCImg.width() == this->width() && newMCImg.height() == this->height());
  156. assert(newMCImg.channels() == this->zsize);
  157. addChannel(1);
  158. }
  159. else
  160. {
  161. reInit( newMCImg.width(), newMCImg.height(), newMCImg.channels(), 1 );
  162. }
  163. for(int z = 0; z < this->zsize; z++)
  164. {
  165. NICE::ImageT<SrcP> newImg = newMCImg[z];
  166. for(int y = 0; y < this->ysize; y++)
  167. {
  168. for(int x = 0; x < this->xsize; x++)
  169. {
  170. data[oldchan][x + y*xsize + z*xsize*ysize] = (P)newImg(x,y);
  171. }
  172. }
  173. }
  174. }
  175. template<class P>
  176. template<class SrcP>
  177. void MultiChannelImage3DT<P>::addChannel(const NICE::MultiChannelImage3DT<SrcP> &newImg)
  178. {
  179. int oldchan = numChannels;
  180. if(numChannels > 0)
  181. {
  182. assert(newImg.width() == this->width() && newImg.height() == this->height() && newImg.depth() == this->depth());
  183. addChannel(newImg.channels());
  184. }
  185. else
  186. {
  187. reInit( newImg.width(), newImg.height(), newImg.depth(), newImg.channels() );
  188. }
  189. int chanNI = 0;
  190. for(int c = oldchan; c < (int)numChannels; c++, chanNI++)
  191. {
  192. int val = 0;
  193. for(int z = 0; z < this->zsize; z++)
  194. {
  195. for(int y = 0; y < this->ysize; y++)
  196. {
  197. for(int x = 0; x < this->xsize; x++, val++)
  198. {
  199. data[c][val] = newImg.get(x,y,z,chanNI);
  200. }
  201. }
  202. }
  203. }
  204. }
  205. template<class P>
  206. MultiChannelImage3DT<P>::~MultiChannelImage3DT()
  207. {
  208. freeData();
  209. }
  210. template<class P>
  211. void MultiChannelImage3DT<P>::freeData()
  212. {
  213. if ( data != NULL )
  214. {
  215. for ( uint i = 0 ; i < numChannels ; i++ )
  216. if ( data[i] != NULL )
  217. delete [] data[i];
  218. delete [] data;
  219. data = NULL;
  220. }
  221. }
  222. template<class P>
  223. void MultiChannelImage3DT<P>::reInit( int _xsize, int _ysize, int _zsize, int _numChannels )
  224. {
  225. freeData();
  226. xsize = _xsize;
  227. ysize = _ysize;
  228. zsize = _zsize;
  229. numChannels = _numChannels;
  230. data = new P *[numChannels];
  231. for ( uint i = 0 ; i < numChannels; i++ )
  232. data[i] = new P [xsize*ysize*zsize];
  233. }
  234. template<class P>
  235. template<class SrcP>
  236. void MultiChannelImage3DT<P>::reInitFrom( const MultiChannelImage3DT<SrcP> & src )
  237. {
  238. freeData();
  239. xsize = src.width();
  240. ysize = src.height();
  241. zsize = src.depth();
  242. numChannels = src.channels();
  243. data = new P *[numChannels];
  244. for ( uint i = 0 ; i < numChannels; i++ )
  245. data[i] = new P [xsize*ysize*zsize];
  246. }
  247. template<class P>
  248. P MultiChannelImage3DT<P>::get( int x, int y, int z, uint channel ) const
  249. {
  250. assert( channel < numChannels );
  251. assert(( x < xsize ) && ( x >= 0 ) );
  252. assert(( y < ysize ) && ( y >= 0 ) );
  253. assert(( z < zsize ) && ( z >= 0 ) );
  254. assert( data[channel] != NULL );
  255. return data[channel][x + y*xsize + z*xsize*ysize];
  256. }
  257. template<class P>
  258. P ** MultiChannelImage3DT<P>::getDataPointer()
  259. {
  260. return data;
  261. }
  262. template<class P>
  263. void MultiChannelImage3DT<P>::set( int x, int y, int z, P val, uint channel )
  264. {
  265. assert( channel < numChannels );
  266. assert(( x < xsize ) && ( x >= 0 ) );
  267. assert(( y < ysize ) && ( y >= 0 ) );
  268. assert(( z < zsize ) && ( z >= 0 ) );
  269. assert( data[channel] != NULL );
  270. data[channel][x + y*xsize + z*xsize*ysize] = val;
  271. }
  272. template<class P>
  273. void MultiChannelImage3DT<P>::set( P val, uint channel )
  274. {
  275. assert( channel < numChannels );
  276. assert( data[channel] != NULL );
  277. for ( int k = 0 ; k < xsize*ysize*zsize ; k++ )
  278. data[channel][k] = val;
  279. }
  280. template<class P>
  281. void MultiChannelImage3DT<P>::setAll( P val )
  282. {
  283. for ( uint channel = 0 ; channel < numChannels ; channel++ )
  284. if ( data[channel] != NULL )
  285. set( val, channel );
  286. }
  287. template<class P>
  288. void MultiChannelImage3DT<P>::statistics( P & min, P & max, uint channel ) const
  289. {
  290. assert( channel < numChannels );
  291. for ( long k = 0 ; k < xsize*ysize*zsize ; k++ )
  292. {
  293. P val = data [channel][k];
  294. if (( k == 0 ) || ( val > max ) ) max = val;
  295. if (( k == 0 ) || ( val < min ) ) min = val;
  296. }
  297. assert(finite(max));
  298. assert(finite(min));
  299. }
  300. template<class P>
  301. Image MultiChannelImage3DT<P>::getChannel( int z, uint channel ) const
  302. {
  303. assert( channel < numChannels );
  304. NICE::Image img;
  305. convertToGrey( img, z, channel, true );
  306. return img;
  307. }
  308. template<class P>
  309. ImageT<P> MultiChannelImage3DT<P>::getChannelT( int z, uint channel ) const
  310. {
  311. assert( channel < numChannels );
  312. NICE::ImageT<P> img;
  313. convertToGrey( img, z, channel, false );
  314. P min, max;
  315. statistics ( min, max, channel );
  316. fprintf (stderr, "MultiChannelImage3DT<>::showChannel: max %f min %f\n", (double)max, (double)min );
  317. return img;
  318. }
  319. /** convert to ice image */
  320. template<class P>
  321. void MultiChannelImage3DT<P>::convertToGrey( NICE::Image & img, int z, uint channel, bool normalize ) const
  322. {
  323. assert( channel < numChannels );
  324. P min, max;
  325. if ( normalize ) {
  326. statistics( min, max, channel );
  327. fprintf( stderr, "MultiChannelImage3DT<>::showChannel: max %f min %f\n", ( double )max, ( double )min );
  328. }
  329. bool skip_assignment = false;
  330. img.resize( xsize, ysize );
  331. if ( normalize )
  332. if ( max - min < std::numeric_limits<double>::min() )
  333. {
  334. img.set( max );
  335. skip_assignment = true;
  336. fprintf( stderr, "MultiChannelImage3DT::showChannel: image is uniform! (%f)\n", ( double )max );
  337. }
  338. if ( ! skip_assignment )
  339. {
  340. long k = 0;
  341. for ( int y = 0 ; y < ysize; y++ )
  342. {
  343. for ( int x = 0 ; x < xsize ; x++, k++ )
  344. {
  345. if ( normalize )
  346. {
  347. img.setPixel( x, y, ( int )(( data[channel][z*xsize*ysize + k] - min ) * 255 / ( max - min ) ) );
  348. }
  349. else
  350. {
  351. img.setPixel( x, y, ( int )( data[channel][z*xsize*ysize + k] ) );
  352. }
  353. }
  354. }
  355. }
  356. }
  357. /** convert to ice image template */
  358. template<class P>
  359. void MultiChannelImage3DT<P>::convertToGrey( NICE::ImageT<P> & img, int z, uint channel, bool normalize ) const
  360. {
  361. assert( channel < numChannels );
  362. P min, max;
  363. if ( normalize ) {
  364. statistics( min, max, channel );
  365. fprintf( stderr, "MultiChannelImage3DT<>::showChannel: max %f min %f\n", ( double )max, ( double )min );
  366. }
  367. bool skip_assignment = false;
  368. img.resize( xsize, ysize );
  369. if ( normalize )
  370. if ( max - min < std::numeric_limits<double>::min() )
  371. {
  372. img.set( max );
  373. skip_assignment = true;
  374. fprintf( stderr, "MultiChannelImage3DT::showChannel: image is uniform! (%f)\n", ( double )max );
  375. }
  376. if ( ! skip_assignment )
  377. {
  378. long k = 0;
  379. for ( int y = 0 ; y < ysize; y++ )
  380. {
  381. for ( int x = 0 ; x < xsize ; x++, k++ )
  382. {
  383. if ( normalize )
  384. {
  385. img.setPixel( x, y, ( int )(( data[channel][z*xsize*ysize + k] - min ) * 255 / ( max - min ) ) );
  386. }
  387. else
  388. {
  389. img.setPixel( x, y, ( int )( data[channel][z*xsize*ysize + k] ) );
  390. }
  391. }
  392. }
  393. }
  394. }
  395. template<class P>
  396. void MultiChannelImage3DT<P>::convertToColor( NICE::ColorImage & img, int z, const int chan1, const int chan2, const int chan3) const
  397. {
  398. assert( chan1 < numChannels && chan2 < numChannels && chan3 < numChannels);
  399. img.resize( xsize, ysize );
  400. long k = 0;
  401. for ( int y = 0 ; y < ysize; y++ )
  402. {
  403. for ( int x = 0 ; x < xsize ; x++, k++ )
  404. {
  405. img.setPixel( x, y, 0, ( int )( data[chan1][z*xsize*ysize + k] ) );
  406. img.setPixel( x, y, 1, ( int )( data[chan2][z*xsize*ysize + k] ) );
  407. img.setPixel( x, y, 2, ( int )( data[chan3][z*xsize*ysize + k] ) );
  408. }
  409. }
  410. }
  411. template<class P>
  412. ColorImage MultiChannelImage3DT<P>::getColor(int z) const
  413. {
  414. assert( z < zsize );
  415. assert( numChannels >= 3 );
  416. NICE::ColorImage img( xsize, ysize );
  417. long k = 0;
  418. for ( int y = 0 ; y < ysize; y++ )
  419. {
  420. for ( int x = 0 ; x < xsize ; x++, k++ )
  421. {
  422. img.setPixel( x, y, 0, ( int )( data[0][z*xsize*ysize + k] ) );
  423. img.setPixel( x, y, 1, ( int )( data[1][z*xsize*ysize + k] ) );
  424. img.setPixel( x, y, 2, ( int )( data[2][z*xsize*ysize + k] ) );
  425. }
  426. }
  427. //showImage(img);
  428. //getchar();
  429. return img;
  430. }
  431. template<class P>
  432. void MultiChannelImage3DT<P>::calcIntegral( uint channel )
  433. {
  434. assert( channel < numChannels );
  435. assert( data[channel] != NULL );
  436. P *integralImage = data[channel];
  437. /** first column **/
  438. int k = xsize;
  439. for ( int y = 1 ; y < ysize; y++, k += xsize )
  440. integralImage[k] += integralImage[k-xsize];
  441. /** first row **/
  442. k = 1;
  443. for ( int x = 1 ; x < xsize; x++, k++ )
  444. integralImage[k] += integralImage[k-1];
  445. /** first stack (depth) **/
  446. k = xsize * ysize;
  447. for ( int z = 1 ; z < zsize; z++, k += (xsize*ysize) )
  448. integralImage[k] += integralImage[k-(xsize*ysize)];
  449. /** x-y plane **/
  450. k = xsize + 1;
  451. for ( int y = 1 ; y < ysize ; y++, k++ )
  452. for ( int x = 1 ; x < xsize ; x++, k++ )
  453. {
  454. integralImage[k] += integralImage[k-1];
  455. integralImage[k] += integralImage[k - xsize];
  456. integralImage[k] -= integralImage[k - xsize - 1];
  457. }
  458. /** y-z plane **/
  459. k = xsize*ysize + xsize;
  460. for ( int z = 1 ; z < zsize ; z++, k+=xsize )
  461. for ( int y = 1 ; y < zsize ; y++, k+=xsize )
  462. {
  463. integralImage[k] += integralImage[k-(xsize*ysize)];
  464. integralImage[k] += integralImage[k - xsize];
  465. integralImage[k] -= integralImage[k - xsize - (xsize*ysize)];
  466. }
  467. /** x-z plane **/
  468. k = xsize*ysize + 1;
  469. for ( int z = 1 ; z < zsize ; z++, k+=((xsize*ysize)-(xsize-1)) )
  470. for ( int x = 1 ; x < xsize ; x++, k++ )
  471. {
  472. integralImage[k] += integralImage[k-1];
  473. integralImage[k] += integralImage[k - (xsize*ysize)];
  474. integralImage[k] -= integralImage[k - (xsize*ysize) - 1];
  475. }
  476. /** all other pixels **/
  477. k = xsize*ysize + xsize + 1;
  478. for ( int z = 1 ; z < zsize ; z++, k+= xsize )
  479. {
  480. for ( int y = 1 ; y < ysize ; y++, k++ )
  481. {
  482. for ( int x = 1 ; x < xsize ; x++, k++ )
  483. {
  484. integralImage[k] += integralImage[k - (xsize*ysize)];
  485. integralImage[k] += integralImage[k - xsize];
  486. integralImage[k] += integralImage[k - 1];
  487. integralImage[k] += integralImage[k - (xsize*ysize) - xsize - 1];
  488. integralImage[k] -= integralImage[k - (xsize*ysize) - xsize];
  489. integralImage[k] -= integralImage[k - (xsize*ysize) - 1];
  490. integralImage[k] -= integralImage[k - xsize - 1];
  491. }
  492. }
  493. }
  494. }
  495. template<class P>
  496. P MultiChannelImage3DT<P>::getIntegralValue(int ulfx, int ulfy, int ulfz, int lrbx, int lrby, int lrbz, int channel)
  497. {
  498. ulfx = std::max(ulfx-1, -1);
  499. ulfx = std::min(ulfx, xsize-1);
  500. ulfy = std::max(ulfy-1, -1);
  501. ulfy = std::min(ulfy, ysize-1);
  502. ulfz = std::max(ulfz-1, -1);
  503. ulfz = std::min(ulfz, zsize-1);
  504. lrbx = std::max(lrbx, 0);
  505. lrbx = std::min(lrbx, xsize-1);
  506. lrby = std::max(lrby, 0);
  507. lrby = std::min(lrby, ysize-1);
  508. lrbz = std::max(lrbz, 0);
  509. lrbz = std::min(lrbz, zsize-1);
  510. P val1, val2, val3, val4, val5, val6, val7, val8;
  511. val1 = get(lrbx, lrby, lrbz, channel);
  512. if( ulfz > -1 )
  513. val2 = get(lrbx, lrby, ulfz, channel);
  514. else
  515. val2 = 0;
  516. if( ulfx > -1 )
  517. val3 = get(ulfx, lrby, lrbz, channel);
  518. else
  519. val3 = 0;
  520. if( ulfx > -1 && ulfz > -1 )
  521. val4 = get(ulfx, lrby, ulfz, channel);
  522. else
  523. val4 = 0;
  524. if( ulfy > -1 )
  525. val5 = get(lrbx, ulfy, lrbz, channel);
  526. else
  527. val5 = 0;
  528. if( ulfy > -1 && ulfz > -1 )
  529. val6 = get(lrbx, ulfy, ulfz, channel);
  530. else
  531. val6 = 0;
  532. if( ulfx > -1 && ulfy > -1 )
  533. val7 = get(ulfx, ulfy, lrbz, channel);
  534. else
  535. val7 = 0;
  536. if(ulfx > -1 && ulfy > -1 && ulfz > -1)
  537. val8 = get(ulfx, ulfy, ulfz, channel);
  538. else
  539. val8 = 0;
  540. P volume = abs((P)(lrbx-ulfx)*(lrby-ulfy)*(lrbz-ulfz));
  541. P val = val1 - val2 - val3 + val4 - ( val5 - val6 - val7 + val8 );
  542. return val/volume;
  543. }
  544. template<class P>
  545. void MultiChannelImage3DT<P>::store( std::string filename ) const
  546. {
  547. // simple raw format
  548. FILE *f = fopen( filename.c_str(), "w" );
  549. if ( f == NULL ) {
  550. fprintf( stderr, "MultiChannelImage3DT::store: error writing to %s\n", filename.c_str() );
  551. exit( -1 );
  552. }
  553. fwrite( &xsize, sizeof( int ), 1, f );
  554. fwrite( &ysize, sizeof( int ), 1, f );
  555. fwrite( &zsize, sizeof( int ), 1, f );
  556. fwrite( &numChannels, sizeof( uint ), 1, f );
  557. for ( uint channel = 0 ; channel < numChannels ; channel++ )
  558. {
  559. assert( data[channel] != NULL );
  560. fwrite( data[channel], sizeof( P ), xsize*ysize*zsize, f );
  561. }
  562. fclose( f );
  563. }
  564. template<class P>
  565. void MultiChannelImage3DT<P>::restore( std::string filename )
  566. {
  567. // simple raw format
  568. FILE *f = fopen( filename.c_str(), "r" );
  569. if ( f == NULL ) {
  570. fprintf( stderr, "MultiChannelImage3DT::store: error reading from %s\n", filename.c_str() );
  571. exit( -1 );
  572. }
  573. fread( &xsize, sizeof( int ), 1, f );
  574. fread( &ysize, sizeof( int ), 1, f );
  575. fread( &zsize, sizeof( int ), 1, f );
  576. fread( &numChannels, sizeof( uint ), 1, f );
  577. if ( numChannels > 0 ) {
  578. reInit( xsize, ysize, zsize, numChannels );
  579. for ( uint channel = 0 ; channel < numChannels ; channel++ )
  580. {
  581. assert( data[channel] != NULL );
  582. fread( data[channel], sizeof( P ), xsize*ysize*zsize, f );
  583. }
  584. } else {
  585. freeData();
  586. data = NULL;
  587. }
  588. fclose( f );
  589. }
  590. template<class P>
  591. int MultiChannelImage3DT<P>::width() const
  592. {
  593. return xsize;
  594. }
  595. template<class P>
  596. int MultiChannelImage3DT<P>::height() const
  597. {
  598. return ysize;
  599. }
  600. template<class P>
  601. int MultiChannelImage3DT<P>::depth() const
  602. {
  603. return zsize;
  604. }
  605. template<class P>
  606. int MultiChannelImage3DT<P>::channels() const
  607. {
  608. return ( int )numChannels;
  609. }
  610. template<class P>
  611. int MultiChannelImage3DT<P>::getPixelInt( int x, int y, int z, int channel ) const
  612. {
  613. throw( "this type is not implemented\n" );
  614. return -1;
  615. }
  616. template<class P>
  617. double MultiChannelImage3DT<P>::getPixelFloat( int x, int y, int z, int channel ) const
  618. {
  619. throw( "this type is not implemented\n" );
  620. return -1.0;
  621. }
  622. template<class P>
  623. void MultiChannelImage3DT<P>::setPixelInt( int x, int y, int z, int channel, int pixel )
  624. {
  625. throw( "this type is not implemented\n" );
  626. }
  627. template<class P>
  628. void MultiChannelImage3DT<P>::setPixelFloat( int x, int y, int z, int channel, double pixel )
  629. {
  630. throw( "this type is not implemented\n" );
  631. }
  632. /*
  633. #define SET_FUNCS_PROTO_MACRO(MYTYPE) \
  634. template<>\
  635. int MultiChannelImage3DT<MYTYPE>::getPixelInt(int x, int y, int channel) const;\
  636. template<>\
  637. double MultiChannelImage3DT<MYTYPE>::getPixelFloat(int x, int y, int channel) const;\
  638. template<>\
  639. void MultiChannelImage3DT<MYTYPE>::setPixelInt(int x, int y, int channel, int pixel);\
  640. template<>\
  641. void MultiChannelImage3DT<MYTYPE>::setPixelFloat(int x, int y, int channel, double pixel);
  642. SET_FUNCS_PROTO_MACRO( double )
  643. SET_FUNCS_PROTO_MACRO( int )
  644. SET_FUNCS_PROTO_MACRO( long int )
  645. SET_FUNCS_PROTO_MACRO( float )
  646. SET_FUNCS_PROTO_MACRO( unsigned int )
  647. */
  648. } // namespace