Attached Files | StreamingFileWriter.diff [^] (15,066 bytes) 2008-12-22 11:56 [Show Content] [Hide Content]Index: itkImageFileWriter.h
===================================================================
RCS file: /cvsroot/Insight/Insight/Code/IO/itkImageFileWriter.h,v
retrieving revision 1.20
diff -r1.20 itkImageFileWriter.h
139,142d138
< /** Specify the region to write. If left NULL, then the whole image
< * is written. */
< void SetIORegion(const ImageIORegion & region);
< itkGetConstReferenceMacro( IORegion, ImageIORegion );
164a161,174
>
> /** Specify the region to write. If left NULL, then the whole image
> * is written.
> */
> void SetIORegion(const ImageIORegion & region);
> itkGetConstReferenceMacro( IORegion, ImageIORegion );
>
> /** Set streaming On or Off
> * The ImageIO class must support streaming
> */
> itkSetMacro(UseStreaming,bool);
> itkGetConstReferenceMacro(UseStreaming,bool);
> itkBooleanMacro(UseStreaming);
>
165a176,182
> /** Set the number of pieces to divide the input. The upstream pipeline
> * will try to be executed this many times. */
> itkSetMacro(NumberOfStreamDivisions,unsigned int);
>
> /** Get the number of pieces to divide the input. The upstream pipeline
> * will try to be executed this many times. */
> itkGetConstReferenceMacro(NumberOfStreamDivisions,unsigned int);
173a191
>
193a212,215
>
> bool m_UseStreaming;
> unsigned int m_NumberOfStreamDivisions;
>
Index: itkImageFileWriter.txx
===================================================================
RCS file: /cvsroot/Insight/Insight/Code/IO/itkImageFileWriter.txx,v
retrieving revision 1.56
diff -r1.56 itkImageFileWriter.txx
26a27,28
> #include "itkImageRegionConstIterator.h"
> #include "itkImageRegionIterator.h"
42d43
< }
43a45,47
> m_UseStreaming = false;
> m_NumberOfStreamDivisions = 10;
> }
178,187d181
< if ( ! m_UserSpecifiedIORegion )
< {
< // Make sure the data is up-to-date.
< if( nonConstImage->GetSource() )
< {
< nonConstImage->GetSource()->UpdateLargestPossibleRegion();
< }
< // Write the whole image
< ImageIORegion ioRegion(TInputImage::ImageDimension);
< RegionType region = input->GetLargestPossibleRegion();
189,199c183,184
< for(unsigned int i=0; i<TInputImage::ImageDimension; i++)
< {
< ioRegion.SetSize(i,region.GetSize(i));
< ioRegion.SetIndex(i,region.GetIndex(i));
< }
< m_IORegion = ioRegion; //used by GenerateData
< }
< else
< {
< nonConstImage->Update();
< }
---
> // Update the meta data
> nonConstImage->UpdateOutputInformation();
204c189
< RegionType region = input->GetLargestPossibleRegion();
---
> RegionType largestRegion = input->GetLargestPossibleRegion();
211,226c196,206
< m_ImageIO->SetDimensions(i,region.GetSize(i));
< m_ImageIO->SetSpacing(i,spacing[i]);
< m_ImageIO->SetOrigin(i,origin[i]);
< vnl_vector< double > axisDirection(TInputImage::ImageDimension);
< // Please note: direction cosines are stored as columns of the
< // direction matrix
< for(unsigned int j=0; j<TInputImage::ImageDimension; j++)
< {
< axisDirection[j] = direction[j][i];
< }
< m_ImageIO->SetDirection( i, axisDirection );
< }
<
< if(m_UserSpecifiedIORegion)
< {
< m_ImageIO->SetUseStreamedWriting(true);
---
> m_ImageIO->SetDimensions(i,largestRegion.GetSize(i));
> m_ImageIO->SetSpacing(i,spacing[i]);
> m_ImageIO->SetOrigin(i,origin[i]);
> vnl_vector< double > axisDirection(TInputImage::ImageDimension);
> // Please note: direction cosines are stored as columns of the
> // direction matrix
> for(unsigned int j=0; j<TInputImage::ImageDimension; j++)
> {
> axisDirection[j] = direction[j][i];
> }
> m_ImageIO->SetDirection( i, axisDirection );
227a208
>
230d210
< m_ImageIO->SetIORegion(m_IORegion);
233c213
< m_ImageIO->SetMetaDataDictionary(input->GetMetaDataDictionary());
---
> m_ImageIO->SetMetaDataDictionary(input->GetMetaDataDictionary());
238,239c218,340
< // Actually do something
< this->GenerateData();
---
> typedef ImageRegionSplitter< TInputImage::ImageDimension > SpliterType;
> typename SpliterType::Pointer regionSplitter =
> m_ImageIO->
> GenerateWriteRegionSplitter<TInputImage::ImageDimension>(m_NumberOfStreamDivisions,
> largestRegion);
>
> if ( m_UserSpecifiedIORegion )
> {
> // try user specified region
> // this is a legacy type of streaming that MUST be supported
> // or... deprecated
>
> m_ImageIO->SetUseStreamedWriting(true);
> m_ImageIO->SetIORegion( m_IORegion);
>
> RegionType requestRegion;
> ImageIORegionAdaptor<TInputImage::ImageDimension>::
> Convert( m_IORegion, requestRegion);
>
> // execute the the upstream pipeline with the requested
> // region
> nonConstImage->SetRequestedRegion(requestRegion);
> nonConstImage->PropagateRequestedRegion();
> nonConstImage->UpdateOutputData();
>
> // send info to image io
> this->GenerateData();
>
> }
> else if (m_UseStreaming && regionSplitter)
> {
> // try streaming
>
> m_ImageIO->SetUseStreamedWriting(true);
>
> /**
> * Determine of number of pieces to divide the input. This will be the
> * minimum of what the user specified via SetNumberOfStreamDivisions()
> * and what the Splitter thinks is a reasonable value.
> */
> unsigned int numDivisions, numDivisionsFromSplitter;
>
> numDivisions = m_NumberOfStreamDivisions;
> numDivisionsFromSplitter = regionSplitter
> ->GetNumberOfSplits(largestRegion, m_NumberOfStreamDivisions);
> if (numDivisionsFromSplitter < numDivisions)
> {
> numDivisions = numDivisionsFromSplitter;
> }
>
> /**
> * Loop over the number of pieces, execute the upstream pipeline on each
> * piece, and copy the results into the output image.
> */
> unsigned int piece;
> InputImageRegionType streamRegion;
> for (piece = 0;
> piece < numDivisions && !this->GetAbortGenerateData();
> piece++)
> {
> streamRegion = regionSplitter->GetSplit(piece, numDivisions,
> largestRegion);
>
> // execute the the upstream pipeline with the requested
> // region for streaming
> nonConstImage->SetRequestedRegion(streamRegion);
> nonConstImage->PropagateRequestedRegion();
> nonConstImage->UpdateOutputData();
>
> // check to see if we got the largest possible region
> bool didNotStream = false;
> if (piece == 0)
> {
> RegionType bufferedRegion = nonConstImage->GetBufferedRegion();
> didNotStream = true;
> for (unsigned long i = 0; i < TInputImage::ImageDimension; ++i)
> {
> if (bufferedRegion.GetIndex(i) != largestRegion.GetIndex(i) ||
> bufferedRegion.GetSize(i) != largestRegion.GetSize(i)) {
> didNotStream = false;
> break;
> }
> }
> }
> // if so, then bail and try not streaming
> if (didNotStream)
> {
> itkDebugMacro("Requested stream region matches largest region");
> itkDebugMacro("input filter may not support streaming well");
> itkDebugMacro("writer is not streaming now");
> regionSplitter = 0;
> break;
> }
>
> ImageIORegion ioRegion(TInputImage::ImageDimension);
> ImageIORegionAdaptor<TInputImage::ImageDimension>::
> Convert(streamRegion, ioRegion);
> m_ImageIO->SetIORegion(ioRegion);
>
> // write the data
> this->GenerateData();
>
> this->UpdateProgress((float) piece / numDivisions );
> }
> }
> if ( !m_UserSpecifiedIORegion && (!m_UseStreaming || !regionSplitter))
> {
>
> nonConstImage->SetRequestedRegionToLargestPossibleRegion();
> nonConstImage->PropagateRequestedRegion();
> nonConstImage->UpdateOutputData();
>
> // just incase we were lied to and it changed
> largestRegion = input->GetLargestPossibleRegion();
>
> ImageIORegion ioRegion(TInputImage::ImageDimension);
> ImageIORegionAdaptor<TInputImage::ImageDimension>::
> Convert(largestRegion, ioRegion);
> m_ImageIO->SetIORegion(ioRegion);
>
> // Actually do something
> this->GenerateData();
> }
245,248c346
< if ( input->ShouldIReleaseData() )
< {
< nonConstImage->ReleaseData();
< }
---
> this->ReleaseInputs();
258a357
> typename InputImageType::Pointer cache;
262,263c361
< // Make sure that the image is the right type and no more than
< // four components.
---
> // Make sure that the image is the right type
283a382,397
> // check that the image's buffered region is the same as
> // ImageIO is expecting and we requested
> ImageIORegion ioRegion = m_ImageIO->GetIORegion();
> typename InputImageType::RegionType bufferedRegion = input->GetBufferedRegion();
> bool sameRegions = true;
> if ( bufferedRegion.GetImageDimension() != ioRegion.GetImageDimension() )
> sameRegions = false;
> unsigned int i = 0;
> while (sameRegions && i < TInputImage::ImageDimension ) {
> if (ioRegion.GetSize(i) != long(bufferedRegion.GetSize(i)) ||
> ioRegion.GetIndex(i) != long(bufferedRegion.GetIndex(i)))
> sameRegions = false;
> ++i;
> }
>
>
285a400,444
>
> // before this test, bad stuff would happend when they don't match
> if (!sameRegions) {
> if (m_UseStreaming || m_UserSpecifiedIORegion) {
> itkDebugMacro("Requested stream region does not match generated output");
> itkDebugMacro("input filter may not support streaming well");
>
> cache = InputImageType::New();
> typename InputImageType::RegionType cacheRegion;
> ImageIORegionAdaptor<TInputImage::ImageDimension>::
> Convert(ioRegion, cacheRegion);
> cache->CopyInformation(input);
> cache->SetBufferedRegion(cacheRegion);
> cache->Allocate();
>
> typedef ImageRegionConstIterator<TInputImage> ConstIteratorType;
> typedef ImageRegionIterator<TInputImage> IteratorType;
>
> ConstIteratorType in(input, cacheRegion);
> IteratorType out(cache, cacheRegion);
>
> // copy the data into a buffer to match the ioregion
> for (in.GoToBegin(), out.GoToBegin(); !in.IsAtEnd(); ++in, ++out)
> {
> out.Set(in.Get());
> }
>
> dataPtr = (const void*) cache->GetBufferPointer();
>
> } else {
>
> ImageFileWriterException e(__FILE__, __LINE__);
> OStringStream msg;
> msg << "Did not get requested region!" << std::endl;
> msg << "Requested:" << std::endl;
> msg << ioRegion;
> msg << "Actual:" << std::endl;
> msg << bufferedRegion;
> e.SetDescription(msg.str().c_str());
> e.SetLocation(ITK_LOCATION);
> throw e;
> }
> }
>
>
Index: itkImageIOBase.h
===================================================================
RCS file: /cvsroot/Insight/Insight/Code/IO/itkImageIOBase.h,v
retrieving revision 1.49
diff -r1.49 itkImageIOBase.h
23a24
> #include "itkImageRegionSplitter.h"
321a323,359
> /** Method for supporting writing streams.
> * Returns a null pointer if streaming is not supported
> * Otherwise returns a region spliter that will appropriately splits the
> * largestPossibleRegion into numberOfStreamsDivisions regions suitable for
> * writing
> */
> template <unsigned int VImageDimension>
> typename ImageRegionSplitter<VImageDimension>::Pointer
> GenerateWriteRegionSplitter(unsigned int numberOfStreamDivisions,
> const ImageRegion<VImageDimension> &largestPossibleRegion)
> {
> // this non virtual method takes care of converting ImageRegion to ImageIORegion
> // and related nastyness caused by ImageRegionSplitter being templated yet
> // ImageIO is not
> ImageIORegion largestIORegion(VImageDimension);
> ImageIORegionAdaptor<VImageDimension>::Convert(largestPossibleRegion, largestIORegion);
> Object::Pointer bptr = this->GenerateWriteRegionSplitter(numberOfStreamDivisions, largestIORegion);
> typename ImageRegionSplitter<VImageDimension>::Pointer ret =
> dynamic_cast<ImageRegionSplitter<VImageDimension> *>(bptr.GetPointer());
> return ret;
> }
>
> /** Method for supporting writing streams.
> * Returns a null pointer if streaming is not supported
> * Otherwise returns an object rerived from ImageRegionSplitter<Dim>, where
> * Dim corresponds to the region dimension of largestPossibleRegion, which can
> * generate regions suitable for writing
> *
> *
> * This method should be overloaded by derived classes which support streaming
> */
> virtual Object::Pointer
> GenerateWriteRegionSplitter(unsigned int itkNotUsed(numberOfStreamDivisions),
> const ImageIORegion &itkNotUsed(largestPossibleRegion)) {
> return 0;
> }
>
Index: itkMetaImageIO.cxx
===================================================================
RCS file: /cvsroot/Insight/Insight/Code/IO/itkMetaImageIO.cxx,v
retrieving revision 1.87
diff -r1.87 itkMetaImageIO.cxx
1367a1368,1398
> Object::Pointer
> MetaImageIO
> ::GenerateWriteRegionSplitter(unsigned int numberOfStreamDivisions, const ImageIORegion &largestPossibleRegion)
> {
> Object::Pointer ret = 0;
> switch(largestPossibleRegion.GetImageDimension())
> {
> case 1:
> ret = ImageRegionSplitter<1>::New();
> break;
> case 2:
> ret = ImageRegionSplitter<2>::New();
> break;
> case 3:
> ret = ImageRegionSplitter<3>::New();
> break;
> case 4:
> ret = ImageRegionSplitter<4>::New();
> break;
> case 5:
> ret = ImageRegionSplitter<5>::New();
> break;
> case 6:
> ret = ImageRegionSplitter<6>::New();
> break;
> case 0:
> default:
> itkDebugMacro("Unsupported image dimension for streaming " << largestPossileRegion.GetImageDimension());
> }
> return ret;
> }
Index: itkMetaImageIO.h
===================================================================
RCS file: /cvsroot/Insight/Insight/Code/IO/itkMetaImageIO.h,v
retrieving revision 1.34
diff -r1.34 itkMetaImageIO.h
25a26
> #include "itkImageRegionSplitter.h"
28a30
>
107a110,114
>
> virtual Object::Pointer
> GenerateWriteRegionSplitter(unsigned int numberOfStreamDivisions, const ImageIORegion &largestPossibleRegion);
>
>
119c126
< return false;
---
> return true;
|