//#################### PRIVATE METHODS ####################
void Greyscale8ImageTexture::reload_image() const
{
	typedef itk::LinearInterpolateImageFunction<Image> Interpolator;
	typedef itk::ResampleImageFilter<Image,Image> Resampler;
	ImagePointer input = input_image<Resampler,Interpolator>(50);
	itk::Size<2> size = input->GetLargestPossibleRegion().GetSize();
	glTexImage2D(GL_TEXTURE_2D, 0, 1, size[0], size[1], 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, input->GetBufferPointer());
}
//#################### PRIVATE METHODS ####################
void RGBA32ImageTexture::reload_image() const
{
	typedef itk::VectorLinearInterpolateImageFunction<Image> Interpolator;
	typedef itk::VectorResampleImageFilter<Image,Image> Resampler;
	ImagePointer input = input_image<Resampler,Interpolator>(50);

	const RGBA32 *const pixels = input->GetBufferPointer();
	itk::Size<2> size = input->GetLargestPossibleRegion().GetSize();

	int pixelCount = size[0] * size[1];
	std::vector<unsigned char> data(pixelCount * 4);
	for(int i=0; i<pixelCount; ++i)
	{
		data[i*4]	= pixels[i][0];
		data[i*4+1]	= pixels[i][1];
		data[i*4+2]	= pixels[i][2];
		data[i*4+3]	= pixels[i][3];
	}
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size[0], size[1], 0, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
}
LabelImagePointer DeriveForegroundLabelImage(const ImagePointer I, const int threshold)
{   itk::ImageLinearConstIteratorWithIndex<ImageType> originitr(I, I->GetRequestedRegion());
    originitr.SetDirection(2);
    originitr.GoToBegin();
    ImageType::SizeType originsize = I->GetLargestPossibleRegion().GetSize();

    LabelImagePointer pBinaryImage = LabelImageType::New();
    LabelImageType::SizeType size;
    size[0] = originsize[0];
    size[1] = originsize[1];
    size[2] = originsize[2];
    LabelImageType::IndexType idx;
    idx.Fill(0);
    LabelImageType::RegionType region;
    region.SetSize(size);
    region.SetIndex(idx);
    pBinaryImage->SetRegions(region);
    pBinaryImage->Allocate();
    pBinaryImage->FillBuffer(0);
    itk::ImageLinearIteratorWithIndex<LabelImageType> 
                        binaryitr(pBinaryImage, pBinaryImage->GetRequestedRegion());
    binaryitr.SetDirection(2);
    binaryitr.GoToBegin();

    while( !originitr.IsAtEnd() && !binaryitr.IsAtEnd())
    {
        while(!originitr.IsAtEndOfLine()){
            if (originitr.Get() > threshold){
                binaryitr.Set(1);
            }
            ++originitr;
            ++binaryitr;
        }
        originitr.NextLine();
        binaryitr.NextLine();
    }
    
    return pBinaryImage;
}
void mitk::AutoCropImageFilter::ComputeNewImageBounds()
{
  mitk::Image::ConstPointer inputMitk = this->GetInput();

  if (m_OverrideCroppingRegion)
  {
    for (unsigned int i=0; i<3; ++i)
    {
      m_RegionIndex[i] = m_CroppingRegion.GetIndex()[i];
      m_RegionSize[i] = m_CroppingRegion.GetSize()[i];

      if (m_RegionIndex[i] >= inputMitk->GetDimension(i))
      {
        itkExceptionMacro("Cropping index is not inside the image. "
                       << std::endl << "Index:"
                       << std::endl << m_CroppingRegion.GetIndex()
                       << std::endl << "Size:"
                       << std::endl << m_CroppingRegion.GetSize());
      }

      if (m_RegionIndex[i] + m_RegionSize[i] >= inputMitk->GetDimension(i))
      {
        m_RegionSize[i] = inputMitk->GetDimension(i) - m_RegionIndex[i];
      }
    }

    for (unsigned int i=0; i<3; ++i)
    {
      m_RegionIndex[i] = m_CroppingRegion.GetIndex()[i];
      m_RegionSize[i] = m_CroppingRegion.GetSize()[i];
    }
  }
  else
  {
    // Check if a 3D or 4D image is present
    unsigned int timeSteps = 1;
    if (inputMitk->GetDimension() == 4 )
      timeSteps = inputMitk->GetDimension(3);

    ImageType::IndexType minima,maxima;

    if (inputMitk->GetDimension() == 4)
    {
      // initialize with time step 0
      m_TimeSelector = mitk::ImageTimeSelector::New();
      m_TimeSelector->SetInput( inputMitk );
      m_TimeSelector->SetTimeNr( 0 );
      m_TimeSelector->UpdateLargestPossibleRegion();
      inputMitk = m_TimeSelector->GetOutput();
    }

    ImagePointer inputItk = ImageType::New();
    mitk::CastToItkImage( inputMitk , inputItk );

    // it is assumed that all volumes in a time series have the same 3D dimensions
    ImageType::RegionType origRegion = inputItk->GetLargestPossibleRegion();

    // Initialize min and max on the first (or only) time step
    maxima = inputItk->GetLargestPossibleRegion().GetIndex();
    minima[0] = inputItk->GetLargestPossibleRegion().GetSize()[0];
    minima[1] = inputItk->GetLargestPossibleRegion().GetSize()[1];
    minima[2] = inputItk->GetLargestPossibleRegion().GetSize()[2];

    typedef itk::ImageRegionConstIterator< ImageType > ConstIteratorType;

    for(unsigned int idx = 0; idx < timeSteps; ++idx)
    {
       // if 4D image, update time step and itk image
      if( idx > 0)
      {
        m_TimeSelector->SetTimeNr( idx );
        m_TimeSelector->UpdateLargestPossibleRegion();
        inputMitk = m_TimeSelector->GetOutput();
        mitk::CastToItkImage( inputMitk , inputItk );
      }

      ConstIteratorType inIt( inputItk,  origRegion );

      for ( inIt.GoToBegin(); !inIt.IsAtEnd(); ++inIt)
      {
        float pix_val = inIt.Get();
        if ( fabs(pix_val - m_BackgroundValue) > mitk::eps )
        {
          for (int i=0; i < 3; i++)
          {
            minima[i] = vnl_math_min((int)minima[i],(int)(inIt.GetIndex()[i]));
            maxima[i] = vnl_math_max((int)maxima[i],(int)(inIt.GetIndex()[i]));
          }
        }
      }
    }

    typedef ImageType::RegionType::SizeType::SizeValueType  SizeValueType;

    m_RegionSize[0] = (SizeValueType)(m_MarginFactor * (maxima[0] - minima[0] + 1 ));
    m_RegionSize[1] = (SizeValueType)(m_MarginFactor * (maxima[1] - minima[1] + 1 ));
    m_RegionSize[2] = (SizeValueType)(m_MarginFactor * (maxima[2] - minima[2] + 1 ));
    m_RegionIndex = minima;

    m_RegionIndex[0] -= (m_RegionSize[0] - maxima[0] + minima[0] - 1 )/2;
    m_RegionIndex[1] -= (m_RegionSize[1] - maxima[1] + minima[1] - 1 )/2;
    m_RegionIndex[2] -= (m_RegionSize[2] - maxima[2] + minima[2] - 1 )/2;

    ImageType::RegionType cropRegion(m_RegionIndex,m_RegionSize);
    origRegion.Crop(cropRegion);

    m_RegionSize[0] = origRegion.GetSize()[0];
    m_RegionSize[1] = origRegion.GetSize()[1];
    m_RegionSize[2] = origRegion.GetSize()[2];

    m_RegionIndex[0] = origRegion.GetIndex()[0];
    m_RegionIndex[1] = origRegion.GetIndex()[1];
    m_RegionIndex[2] = origRegion.GetIndex()[2];

    m_CroppingRegion = origRegion;
  }
}