Skip to content
Snippets Groups Projects
Commit c6d9ca1c authored by Guillaume Pasero's avatar Guillaume Pasero
Browse files

BUG: fix for the ImageFileWriter that request the largest region first

parent 81f78fda
No related branches found
No related tags found
No related merge requests found
......@@ -20,7 +20,7 @@
#include "otbMacro.h"
#include "itkImageIOBase.h"
#include "itkImageToImageFilter.h"
#include "itkProcessObject.h"
#include "otbStreamingManager.h"
#include "otbExtendedFilenameToWriterOptions.h"
......@@ -55,12 +55,12 @@ namespace otb
* \sa ExtendedFilenameToReaderOptions
*/
template <class TInputImage>
class ITK_EXPORT ImageFileWriter : public itk::ImageToImageFilter<TInputImage, TInputImage>
class ITK_EXPORT ImageFileWriter : public itk::ProcessObject
{
public:
/** Standard class typedefs. */
typedef ImageFileWriter Self;
typedef itk::ImageToImageFilter<TInputImage, TInputImage> Superclass;
typedef ImageFileWriter Self;
typedef itk::ProcessObject Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
......@@ -68,7 +68,7 @@ public:
itkNewMacro(Self);
/** Run-time type information (and related methods). */
itkTypeMacro(ImageFileWriter, itk::ImageToImageFilter);
itkTypeMacro(ImageFileWriter, itk::ProcessObject);
/** Some typedefs for the input and output. */
typedef TInputImage InputImageType;
......@@ -181,12 +181,21 @@ public:
/** Get the number of pieces to divide the input. The upstream pipeline
* will be executed this many times. */
itkLegacyMacro( unsigned long GetNumberOfStreamDivisions(void) );
/** Override UpdateOutputData() from ProcessObject to divide upstream
* updates into pieces. This filter does not have a GenerateData()
* or ThreadedGenerateData() method. Instead, all the work is done
* in UpdateOutputData() since it must update a little, execute a little,
* update some more, execute some more, etc. */
/** Set the only input of the writer */
virtual void SetInput(const InputImageType *input);
/** Get writer only input */
const InputImageType* GetInput();
/** Override Update() from ProcessObject because this filter
* has no output. */
virtual void Update();
/** Override UpdateOutputData() from ProcessObject to divide the
* largest possible region into pieces. Each piece is processed
* by GenerateData(). The setting and propagation of the requested
* regions are done in UpdateOutputData(). */
virtual void UpdateOutputData(itk::DataObject * itkNotUsed(output));
/** ImageFileWriter Methods */
......@@ -233,9 +242,6 @@ protected:
/** Does the real work. */
virtual void GenerateData(void);
virtual void GenerateOutputRequestedRegion(itk::DataObject *output);
private:
ImageFileWriter(const ImageFileWriter &); //purposely not implemented
void operator =(const ImageFileWriter&); //purposely not implemented
......
......@@ -352,6 +352,44 @@ ImageFileWriter<TInputImage>
}
}
template<class TInputImage>
void
ImageFileWriter<TInputImage>
::SetInput(const InputImageType* input)
{
this->ProcessObject::SetNthInput(0,const_cast<InputImageType*>(input));
}
template<class TInputImage>
const TInputImage*
ImageFileWriter<TInputImage>
::GetInput()
{
if (this->GetNumberOfInputs() < 1)
{
return 0;
}
return static_cast<const InputImageType*>(this->ProcessObject::GetInput(0));
}
/**
* Update method : update output information of input and write to file
*/
template<class TInputImage>
void
ImageFileWriter<TInputImage>
::Update()
{
// Update output information on input image
InputImagePointer inputPtr =
const_cast<InputImageType *>(this->GetInput());
inputPtr->UpdateOutputInformation();
itk::DataObject *dummyObject;
this->UpdateOutputData(dummyObject);
}
/**
*
*/
......@@ -476,12 +514,6 @@ ImageFileWriter<TInputImage>
}
}
/**
* Prepare all the outputs. This may deallocate previous bulk data.
*/
this->PrepareOutputs();
/**
* Make sure we have the necessary inputs
*/
......@@ -501,12 +533,6 @@ ImageFileWriter<TInputImage>
*/
this->InvokeEvent(itk::StartEvent());
/**
* Allocate the output buffer.
*/
OutputImagePointer outputPtr = this->GetOutput(0);
OutputImageRegionType outputRegion = outputPtr->GetLargestPossibleRegion();
/** Prepare ImageIO : create ImageFactory */
if (m_FileName == "")
......@@ -586,9 +612,9 @@ ImageFileWriter<TInputImage>
/**
* Grab the input
*/
InputImagePointer inputPtr =
const_cast<InputImageType *>(this->GetInput(0));
InputImagePointer inputPtr = const_cast<InputImageType *>(this->GetInput());
InputImageRegionType inputRegion = inputPtr->GetLargestPossibleRegion();
/**
* Determine of number of pieces to divide the input. This will be the
* minimum of what the user specified via SetNumberOfDivisionsStrippedStreaming()
......@@ -608,7 +634,7 @@ ImageFileWriter<TInputImage>
otbMsgDevMacro(<< "Buffered region is the largest possible region, there is no need for streaming.");
this->SetNumberOfDivisionsStrippedStreaming(1);
}
m_StreamingManager->PrepareStreaming(inputPtr, outputRegion);
m_StreamingManager->PrepareStreaming(inputPtr, inputRegion);
m_NumberOfDivisions = m_StreamingManager->GetNumberOfSplits();
otbMsgDebugMacro(<< "Number Of Stream Divisions : " << m_NumberOfDivisions);
......@@ -619,17 +645,17 @@ ImageFileWriter<TInputImage>
InputImageRegionType streamRegion;
//
// Setup the ImageIO with information from outputPtr
// Setup the ImageIO with information from inputPtr
//
m_ImageIO->SetNumberOfDimensions(TInputImage::ImageDimension);
const typename TInputImage::SpacingType& spacing = outputPtr->GetSpacing();
const typename TInputImage::PointType& origin = outputPtr->GetOrigin();
const typename TInputImage::DirectionType& direction = outputPtr->GetDirection();
const typename TInputImage::SpacingType& spacing = inputPtr->GetSpacing();
const typename TInputImage::PointType& origin = inputPtr->GetOrigin();
const typename TInputImage::DirectionType& direction = inputPtr->GetDirection();
for (unsigned int i = 0; i < TInputImage::ImageDimension; ++i)
{
// Final image size
m_ImageIO->SetDimensions(i, outputRegion.GetSize(i));
m_ImageIO->SetDimensions(i, inputRegion.GetSize(i));
m_ImageIO->SetSpacing(i, spacing[i]);
m_ImageIO->SetOrigin(i, origin[i]);
......@@ -721,17 +747,6 @@ ImageFileWriter<TInputImage>
source->RemoveObserver(m_ObserverID);
}
/**
* Now we have to mark the data as up to data.
*/
for (idx = 0; idx < this->GetNumberOfOutputs(); ++idx)
{
if (this->GetOutput(idx))
{
this->GetOutput(idx)->DataHasBeenGenerated();
}
}
// Write the image keyword list if any
// ossimKeywordlist geom_kwl;
// ImageKeywordlist otb_kwl;
......@@ -764,7 +779,6 @@ ImageFileWriter<TInputImage>
{
const InputImageType * input = this->GetInput();
InputImagePointer cacheImage;
InputImageRegionType largestRegion = input->GetLargestPossibleRegion();
// Make sure that the image is the right type and no more than
// four components.
......@@ -881,20 +895,6 @@ ImageFileWriter<TInputImage>
return this->m_FilenameHelper->GetSimpleFileName();
}
template <class TInputImage>
void
ImageFileWriter<TInputImage>
::GenerateOutputRequestedRegion(itk::DataObject *output)
{
Superclass::GenerateOutputRequestedRegion(output);
// Here we set the output requested region to the largest possible region
// This is a default behaviour that should work with most upstream filters
// This requested region will be modified anyway and repropagated during UpdateOutputData.
OutputImageType* imgOutput = dynamic_cast<OutputImageType*>(output);
imgOutput->SetRequestedRegionToLargestPossibleRegion();
}
} // end namespace otb
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment