You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							615 lines
						
					
					
						
							17 KiB
						
					
					
				
			
		
		
	
	
							615 lines
						
					
					
						
							17 KiB
						
					
					
				| /*=========================================================================
 | |
| 
 | |
|   Program:   Visualization Toolkit
 | |
|   Module:    $RCSfile: vtkImageShrink3D.cxx,v $
 | |
| 
 | |
|   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
 | |
|   All rights reserved.
 | |
|   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
 | |
| 
 | |
|      This software is distributed WITHOUT ANY WARRANTY; without even
 | |
|      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 | |
|      PURPOSE.  See the above copyright notice for more information.
 | |
| 
 | |
| =========================================================================*/
 | |
| #include "vtkImageShrink3D.h"
 | |
| 
 | |
| #include "vtkImageData.h"
 | |
| #include "vtkInformation.h"
 | |
| #include "vtkInformationVector.h"
 | |
| #include "vtkObjectFactory.h"
 | |
| #include "vtkStreamingDemandDrivenPipeline.h"
 | |
| 
 | |
| #include <math.h>
 | |
| 
 | |
| vtkCxxRevisionMacro(vtkImageShrink3D, "$Revision: 1.69 $");
 | |
| vtkStandardNewMacro(vtkImageShrink3D);
 | |
| 
 | |
| //----------------------------------------------------------------------------
 | |
| // Constructor: Sets default filter to be identity.
 | |
| vtkImageShrink3D::vtkImageShrink3D()
 | |
| {
 | |
|   this->ShrinkFactors[0] = this->ShrinkFactors[1] = this->ShrinkFactors[2] = 1;
 | |
|   this->Shift[0] = this->Shift[1] = this->Shift[2] = 0;
 | |
|   this->Mean = 1;
 | |
|   this->Median = 0;
 | |
|   this->Maximum = 0;
 | |
|   this->Minimum = 0;
 | |
| }
 | |
| 
 | |
| void vtkImageShrink3D::SetMean (int value)
 | |
| {
 | |
|   if (value != this->Mean)
 | |
|     {
 | |
|     this->Mean = value;
 | |
|     if (value == 1)
 | |
|       {
 | |
|       this->Minimum = 0;
 | |
|       this->Maximum = 0;
 | |
|       this->Median = 0;
 | |
|       }      
 | |
|     this->Modified();
 | |
|     }
 | |
| }
 | |
| 
 | |
| void vtkImageShrink3D::SetMinimum (int value)
 | |
| {
 | |
|   if (value != this->Minimum)
 | |
|     {
 | |
|     this->Minimum = value;
 | |
|     if (value == 1)
 | |
|       {
 | |
|       this->Mean = 0;
 | |
|       this->Maximum = 0;
 | |
|       this->Median = 0;
 | |
|       }      
 | |
|     this->Modified();
 | |
|     }
 | |
| }
 | |
| 
 | |
| void vtkImageShrink3D::SetMaximum (int value)
 | |
| {
 | |
|   if (value != this->Maximum)
 | |
|     {
 | |
|     this->Maximum = value;
 | |
|     if (value == 1)
 | |
|       {
 | |
|       this->Minimum = 0;
 | |
|       this->Mean = 0;
 | |
|       this->Median = 0;
 | |
|       }      
 | |
|     this->Modified();
 | |
|     }
 | |
| }
 | |
| 
 | |
| void vtkImageShrink3D::SetMedian (int value)
 | |
| {
 | |
|   if (value != this->Median)
 | |
|     {
 | |
|     this->Median = value;
 | |
|     if (value == 1)
 | |
|       {
 | |
|       this->Minimum = 0;
 | |
|       this->Maximum = 0;
 | |
|       this->Mean = 0;
 | |
|       }      
 | |
|     this->Modified();
 | |
|     }
 | |
| }
 | |
| 
 | |
| void vtkImageShrink3D::SetAveraging (int value)
 | |
| {
 | |
|   this->SetMean(value);
 | |
| }
 | |
| 
 | |
| //----------------------------------------------------------------------------
 | |
| void vtkImageShrink3D::PrintSelf(ostream& os, vtkIndent indent)
 | |
| {
 | |
|   this->Superclass::PrintSelf(os,indent);
 | |
| 
 | |
|   os << indent << "ShrinkFactors: (" << this->ShrinkFactors[0] << ", "
 | |
|      << this->ShrinkFactors[1] << ", " << this->ShrinkFactors[2] << ")\n";
 | |
|   os << indent << "Shift: (" << this->Shift[0] << ", "
 | |
|      << this->Shift[1] << ", " << this->Shift[2] << ")\n";
 | |
| 
 | |
|   os << indent << "Averaging: " << (this->Mean ? "On\n" : "Off\n");
 | |
|   os << indent << "Mean: " << (this->Mean ? "On\n" : "Off\n");
 | |
|   os << indent << "Minimum: " << (this->Minimum ? "On\n" : "Off\n");
 | |
|   os << indent << "Maximum: " << (this->Maximum ? "On\n" : "Off\n");
 | |
|   os << indent << "Median: " << (this->Median ? "On\n" : "Off\n");
 | |
| }
 | |
| 
 | |
| void vtkImageShrink3D::InternalRequestUpdateExtent(int *inExt, int *outExt)
 | |
| {
 | |
|   int idx;
 | |
|   
 | |
|   for (idx = 0; idx < 3; ++idx)
 | |
|     {
 | |
|     // For Min.
 | |
|     inExt[idx*2] = outExt[idx*2] * this->ShrinkFactors[idx] 
 | |
|       + this->Shift[idx];
 | |
|     // For Max.
 | |
|     inExt[idx*2+1] = outExt[idx*2+1] * this->ShrinkFactors[idx]
 | |
|       + this->Shift[idx];
 | |
|     // If we are not sub sampling, we need a little more
 | |
|     if (this->Mean || this->Minimum || this->Maximum || this->Median)
 | |
|       {
 | |
|       inExt[idx*2+1] += this->ShrinkFactors[idx] - 1;
 | |
|       }
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| //----------------------------------------------------------------------------
 | |
| // This method computes the Region of input necessary to generate outRegion.
 | |
| int vtkImageShrink3D::RequestUpdateExtent (
 | |
|   vtkInformation * vtkNotUsed(request),
 | |
|   vtkInformationVector **inputVector,
 | |
|   vtkInformationVector *outputVector)
 | |
| {
 | |
|   // get the info objects
 | |
|   vtkInformation* outInfo = outputVector->GetInformationObject(0);
 | |
|   vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
 | |
| 
 | |
|   int outExt[6], inExt[6];
 | |
|   outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), outExt);
 | |
| 
 | |
|   this->InternalRequestUpdateExtent(inExt, outExt);
 | |
| 
 | |
|   inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), inExt, 6);
 | |
| 
 | |
|   return 1;
 | |
| }
 | |
| 
 | |
| //----------------------------------------------------------------------------
 | |
| // Computes any global image information associated with regions.
 | |
| // Any problems with roundoff or negative numbers ???
 | |
| int vtkImageShrink3D::RequestInformation (
 | |
|   vtkInformation * vtkNotUsed(request),
 | |
|   vtkInformationVector **inputVector,
 | |
|   vtkInformationVector *outputVector)
 | |
| {
 | |
|   // get the info objects
 | |
|   vtkInformation* outInfo = outputVector->GetInformationObject(0);
 | |
|   vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
 | |
| 
 | |
|   int idx;
 | |
|   int wholeExtent[6];
 | |
|   double spacing[3];
 | |
| 
 | |
|   inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),wholeExtent);
 | |
|   inInfo->Get(vtkDataObject::SPACING(), spacing);
 | |
| 
 | |
|   for (idx = 0; idx < 3; ++idx)
 | |
|     {
 | |
|     // Avoid dividing by 0.
 | |
|       if (this->ShrinkFactors[idx] == 0)
 | |
|       {
 | |
|       this->ShrinkFactors[idx] = 1;
 | |
|       }
 | |
|     // Scale the output extent
 | |
|     wholeExtent[2*idx] = 
 | |
|       (int)(ceil((double)(wholeExtent[2*idx] - this->Shift[idx]) 
 | |
|                  / (double)(this->ShrinkFactors[idx])));
 | |
|     wholeExtent[2*idx+1] = (int)(floor(
 | |
|      (double)(wholeExtent[2*idx+1]-this->Shift[idx]-this->ShrinkFactors[idx]+1)
 | |
|          / (double)(this->ShrinkFactors[idx])));
 | |
|      // make sure WholeExtent is valid when the ShrinkFactors are set on an
 | |
|      // axis with no Extent beforehand
 | |
|      if (wholeExtent[2*idx+1]<wholeExtent[2*idx])
 | |
|        {
 | |
|        wholeExtent[2*idx+1] = wholeExtent[2*idx];
 | |
|        }
 | |
|     // Change the data spacing
 | |
|     spacing[idx] *= (double)(this->ShrinkFactors[idx]);
 | |
|     }
 | |
| 
 | |
|   outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),wholeExtent,6);
 | |
|   outInfo->Set(vtkDataObject::SPACING(),spacing,3);
 | |
| 
 | |
|   return 1;
 | |
| }
 | |
| 
 | |
| template <class T>
 | |
| #ifdef _WIN32_WCE
 | |
| int __cdecl vtkiscompare(const T *y1,const T *y2)
 | |
| #else
 | |
| int vtkiscompare(const T *y1,const T *y2)
 | |
| #endif
 | |
| {
 | |
|   if ( *y1 <  *y2) 
 | |
|     {
 | |
|     return -1; 
 | |
|     }
 | |
|   
 | |
|   if ( *y1 == *y2) 
 | |
|     {
 | |
|     return  0;
 | |
|     }
 | |
|   
 | |
|   return  1;
 | |
| }
 | |
| 
 | |
| extern "C" 
 | |
| {
 | |
|   typedef int (*vtkCompareFunction)(const void*, const void*);
 | |
| }
 | |
| 
 | |
| //----------------------------------------------------------------------------
 | |
| // The templated execute function handles all the data types.
 | |
| template <class T>
 | |
| void vtkImageShrink3DExecute(vtkImageShrink3D *self,
 | |
|                              vtkImageData *inData, T *inPtr,
 | |
|                              vtkImageData *outData, T *outPtr,
 | |
|                              int outExt[6], int id,
 | |
|                              vtkInformation *inInfo)
 | |
| {
 | |
|   int outIdx0, outIdx1, outIdx2, inIdx0, inIdx1, inIdx2;
 | |
|   vtkIdType inInc0, inInc1, inInc2;
 | |
|   T *inPtr0, *inPtr1, *inPtr2;
 | |
|   vtkIdType outInc0, outInc1, outInc2;
 | |
|   vtkIdType tmpInc0, tmpInc1, tmpInc2;
 | |
|   T *tmpPtr0, *tmpPtr1, *tmpPtr2;
 | |
|   int factor0, factor1, factor2;
 | |
|   double sum, norm;
 | |
|   unsigned long count = 0;
 | |
|   unsigned long target;
 | |
|   int idxC, maxC, maxX;
 | |
|   T *outPtr2;
 | |
| 
 | |
|   // black magic to force the correct version of the comparison function
 | |
|   // to be instantiated AND used.
 | |
| #ifdef _WIN32_WCE
 | |
|   int (__cdecl *compareF1)(const T*, const T*) = vtkiscompare;
 | |
|   int (__cdecl *compareFn)(const void*, const void*)
 | |
|     = (int (__cdecl *)(const void*, const void*)) compareF1;
 | |
| #else
 | |
|   int (*compareF1)(const T*, const T*) = vtkiscompare;
 | |
| //  int (*compareFn)(const void*, const void*)
 | |
| //    = (int (*)(const void*, const void*)) compareF1;
 | |
|   vtkCompareFunction compareFn = 
 | |
|     reinterpret_cast<vtkCompareFunction>(compareF1);
 | |
| #endif
 | |
| 
 | |
|   self->GetShrinkFactors(factor0, factor1, factor2);
 | |
| 
 | |
|   // make sure we don't have a 3D shrinkfactor for a 2D image
 | |
|   if (factor2>1 && inData && inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT())[5]==0)
 | |
|     {
 | |
|     factor2=1;
 | |
|     }
 | |
| 
 | |
|   // Get information to march through data
 | |
|   inData->GetIncrements(inInc0, inInc1, inInc2);
 | |
|   tmpInc0 = inInc0 * factor0;
 | |
|   tmpInc1 = inInc1 * factor1;
 | |
|   tmpInc2 = inInc2 * factor2;
 | |
|   outData->GetContinuousIncrements(outExt,outInc0, outInc1, outInc2);
 | |
| 
 | |
|   maxX = outExt[1] - outExt[0];
 | |
|   maxC = inData->GetNumberOfScalarComponents();
 | |
|   target = (unsigned long)(maxC*(outExt[5] - outExt[4] + 1)*
 | |
|                            (outExt[3] - outExt[2] + 1)/50.0);
 | |
|   target++;
 | |
|   
 | |
|   if (self->GetMean())
 | |
|     {
 | |
|     norm = 1.0 / (double)(factor0 * factor1 * factor2);
 | |
|     // Loop through output pixels
 | |
|     for (idxC = 0; idxC < maxC; idxC++)
 | |
|       {
 | |
|       tmpPtr2 = inPtr + idxC;
 | |
|       outPtr2 = outPtr + idxC;
 | |
|       for (outIdx2 = outExt[4]; outIdx2 <= outExt[5]; ++outIdx2)
 | |
|         {
 | |
|         tmpPtr1 = tmpPtr2;
 | |
|         for (outIdx1 = outExt[2]; 
 | |
|              !self->AbortExecute && outIdx1 <= outExt[3]; ++outIdx1)
 | |
|           {
 | |
|           if (!id) 
 | |
|             {
 | |
|             if (!(count%target))
 | |
|               {
 | |
|               self->UpdateProgress(count/(50.0*target));
 | |
|               }
 | |
|             count++;
 | |
|             }
 | |
|           tmpPtr0 = tmpPtr1;
 | |
|           for (outIdx0 = 0; outIdx0 <= maxX; ++outIdx0)
 | |
|             {
 | |
|             sum = 0.0;
 | |
|             // Loop through neighborhood pixels
 | |
|             inPtr2 = tmpPtr0;
 | |
|             for (inIdx2 = 0; inIdx2 < factor2; ++inIdx2)
 | |
|               {
 | |
|               inPtr1 = inPtr2;
 | |
|               for (inIdx1 = 0; inIdx1 < factor1; ++inIdx1)
 | |
|                 {
 | |
|                 inPtr0 = inPtr1;
 | |
|                 for (inIdx0 = 0; inIdx0 < factor0; ++inIdx0)
 | |
|                   {
 | |
|                   sum += (double)(*inPtr0);
 | |
|                   inPtr0 += inInc0;
 | |
|                   }
 | |
|                 inPtr1 += inInc1;
 | |
|                 }
 | |
|               inPtr2 += inInc2;
 | |
|               }
 | |
|             *outPtr2 = (T)(sum * norm);
 | |
|             tmpPtr0 += tmpInc0;
 | |
|             outPtr2 += maxC;
 | |
|             }
 | |
|           tmpPtr1 += tmpInc1;
 | |
|           outPtr2 += outInc1;
 | |
|           }
 | |
|         tmpPtr2 += tmpInc2;
 | |
|         outPtr2 += outInc2;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   else if (self->GetMinimum())
 | |
|     {
 | |
|     T minValue;
 | |
|     // Loop through output pixels
 | |
|     for (idxC = 0; idxC < maxC; idxC++)
 | |
|       {
 | |
|       tmpPtr2 = inPtr + idxC;
 | |
|       outPtr2 = outPtr + idxC;
 | |
|       for (outIdx2 = outExt[4]; outIdx2 <= outExt[5]; ++outIdx2)
 | |
|         {
 | |
|         tmpPtr1 = tmpPtr2;
 | |
|         for (outIdx1 = outExt[2]; 
 | |
|              !self->AbortExecute && outIdx1 <= outExt[3]; ++outIdx1)
 | |
|           {
 | |
|           if (!id) 
 | |
|             {
 | |
|             if (!(count%target))
 | |
|               {
 | |
|               self->UpdateProgress(count/(50.0*target));
 | |
|               }
 | |
|             count++;
 | |
|             }
 | |
|           tmpPtr0 = tmpPtr1;
 | |
|           for (outIdx0 = 0; outIdx0 <= maxX; ++outIdx0)
 | |
|             {
 | |
|             minValue = (T) self->GetOutput()->GetScalarTypeMax();
 | |
|             // Loop through neighborhood pixels
 | |
|             inPtr2 = tmpPtr0;
 | |
|             for (inIdx2 = 0; inIdx2 < factor2; ++inIdx2)
 | |
|               {
 | |
|               inPtr1 = inPtr2;
 | |
|               for (inIdx1 = 0; inIdx1 < factor1; ++inIdx1)
 | |
|                 {
 | |
|                 inPtr0 = inPtr1;
 | |
|                 for (inIdx0 = 0; inIdx0 < factor0; ++inIdx0)
 | |
|                   {
 | |
|                   if (*inPtr0 < minValue)
 | |
|                     {
 | |
|                     minValue = *inPtr0;
 | |
|                     }
 | |
|                   inPtr0 += inInc0;
 | |
|                   }
 | |
|                 inPtr1 += inInc1;
 | |
|                 }
 | |
|               inPtr2 += inInc2;
 | |
|               }
 | |
|             *outPtr2 = minValue;
 | |
|             tmpPtr0 += tmpInc0;
 | |
|             outPtr2 += maxC;
 | |
|             }
 | |
|           tmpPtr1 += tmpInc1;
 | |
|           outPtr2 += outInc1;
 | |
|           }
 | |
|         tmpPtr2 += tmpInc2;
 | |
|         outPtr2 += outInc2;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   else if (self->GetMaximum())
 | |
|     {
 | |
|     T maxValue;
 | |
|     // Loop through output pixels
 | |
|     for (idxC = 0; idxC < maxC; idxC++)
 | |
|       {
 | |
|       tmpPtr2 = inPtr + idxC;
 | |
|       outPtr2 = outPtr + idxC;
 | |
|       for (outIdx2 = outExt[4]; outIdx2 <= outExt[5]; ++outIdx2)
 | |
|         {
 | |
|         tmpPtr1 = tmpPtr2;
 | |
|         for (outIdx1 = outExt[2]; 
 | |
|              !self->AbortExecute && outIdx1 <= outExt[3]; ++outIdx1)
 | |
|           {
 | |
|           if (!id) 
 | |
|             {
 | |
|             if (!(count%target))
 | |
|               {
 | |
|               self->UpdateProgress(count/(50.0*target));
 | |
|               }
 | |
|             count++;
 | |
|             }
 | |
|           tmpPtr0 = tmpPtr1;
 | |
|           for (outIdx0 = 0; outIdx0 <= maxX; ++outIdx0)
 | |
|             {
 | |
|             maxValue = (T) self->GetOutput()->GetScalarTypeMin();
 | |
|             // Loop through neighborhood pixels
 | |
|             inPtr2 = tmpPtr0;
 | |
|             for (inIdx2 = 0; inIdx2 < factor2; ++inIdx2)
 | |
|               {
 | |
|               inPtr1 = inPtr2;
 | |
|               for (inIdx1 = 0; inIdx1 < factor1; ++inIdx1)
 | |
|                 {
 | |
|                 inPtr0 = inPtr1;
 | |
|                 for (inIdx0 = 0; inIdx0 < factor0; ++inIdx0)
 | |
|                   {
 | |
|                   if (*inPtr0 > maxValue)
 | |
|                     {
 | |
|                     maxValue = *inPtr0;
 | |
|                     }
 | |
|                   inPtr0 += inInc0;
 | |
|                   }
 | |
|                 inPtr1 += inInc1;
 | |
|                 }
 | |
|               inPtr2 += inInc2;
 | |
|               }
 | |
|             *outPtr2 = maxValue;
 | |
|             tmpPtr0 += tmpInc0;
 | |
|             outPtr2 += maxC;
 | |
|             }
 | |
|           tmpPtr1 += tmpInc1;
 | |
|           outPtr2 += outInc1;
 | |
|           }
 | |
|         tmpPtr2 += tmpInc2;
 | |
|         outPtr2 += outInc2;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   else if (self->GetMedian())
 | |
|     {
 | |
|     T* kernel = new T [factor0 * factor1 * factor2];
 | |
|     int index;
 | |
|     
 | |
|     // Loop through output pixels
 | |
|     for (idxC = 0; idxC < maxC; idxC++)
 | |
|       {
 | |
|       tmpPtr2 = inPtr + idxC;
 | |
|       outPtr2 = outPtr + idxC;
 | |
|       for (outIdx2 = outExt[4]; outIdx2 <= outExt[5]; ++outIdx2)
 | |
|         {
 | |
|         tmpPtr1 = tmpPtr2;
 | |
|         for (outIdx1 = outExt[2]; 
 | |
|              !self->AbortExecute && outIdx1 <= outExt[3]; ++outIdx1)
 | |
|           {
 | |
|           if (!id) 
 | |
|             {
 | |
|             if (!(count%target))
 | |
|               {
 | |
|               self->UpdateProgress(count/(50.0*target));
 | |
|               }
 | |
|             count++;
 | |
|             }
 | |
|           tmpPtr0 = tmpPtr1;
 | |
|           for (outIdx0 = 0; outIdx0 <= maxX; ++outIdx0)
 | |
|             {
 | |
|             // Loop through neighborhood pixels
 | |
|             inPtr2 = tmpPtr0;
 | |
|             index = 0;
 | |
|             for (inIdx2 = 0; inIdx2 < factor2; ++inIdx2)
 | |
|               {
 | |
|               inPtr1 = inPtr2;
 | |
|               for (inIdx1 = 0; inIdx1 < factor1; ++inIdx1)
 | |
|                 {
 | |
|                 inPtr0 = inPtr1;
 | |
|                 for (inIdx0 = 0; inIdx0 < factor0; ++inIdx0)
 | |
|                   {
 | |
|                   kernel[index++] = *inPtr0;
 | |
| 
 | |
|                   inPtr0 += inInc0;
 | |
|                   }
 | |
|                 inPtr1 += inInc1;
 | |
|                 }
 | |
|               inPtr2 += inInc2;
 | |
|               }
 | |
|             qsort(kernel,index,sizeof(T),compareFn);
 | |
|             *outPtr2 = *(kernel + index/2);
 | |
| 
 | |
|             tmpPtr0 += tmpInc0;
 | |
|             outPtr2 += maxC;
 | |
|             }
 | |
|           tmpPtr1 += tmpInc1;
 | |
|           outPtr2 += outInc1;
 | |
|           }
 | |
|         tmpPtr2 += tmpInc2;
 | |
|         outPtr2 += outInc2;
 | |
|         }
 | |
|       }
 | |
|     delete [] kernel;
 | |
|     }
 | |
|   else // Just SubSample
 | |
|     {
 | |
|     // Loop through output pixels
 | |
|     for (idxC = 0; idxC < maxC; idxC++)
 | |
|       {
 | |
|       tmpPtr2 = inPtr + idxC;
 | |
|       outPtr2 = outPtr + idxC;
 | |
|       for (outIdx2 = outExt[4]; outIdx2 <= outExt[5]; ++outIdx2)
 | |
|         {
 | |
|         tmpPtr1 = tmpPtr2;
 | |
|         for (outIdx1 = outExt[2]; 
 | |
|              !self->AbortExecute && outIdx1 <= outExt[3]; ++outIdx1)
 | |
|           {
 | |
|           if (!id) 
 | |
|             {
 | |
|             if (!(count%target))
 | |
|               {
 | |
|               self->UpdateProgress(count/(50.0*target));
 | |
|               }
 | |
|             count++;
 | |
|             }
 | |
|           tmpPtr0 = tmpPtr1;
 | |
|           for (outIdx0 = 0; outIdx0 <= maxX; ++outIdx0)
 | |
|             {
 | |
|             *outPtr2 = *tmpPtr0;
 | |
| 
 | |
|             tmpPtr0 += tmpInc0;
 | |
|             outPtr2 += maxC;
 | |
|             }
 | |
|           tmpPtr1 += tmpInc1;
 | |
|           outPtr2 += outInc1;
 | |
|           }
 | |
|         tmpPtr2 += tmpInc2;
 | |
|         outPtr2 += outInc2;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
| }
 | |
|     
 | |
| //----------------------------------------------------------------------------
 | |
| // This method uses the input data to fill the output data.
 | |
| // It can handle any type data, but the two datas must have the same 
 | |
| // data type.
 | |
| void vtkImageShrink3D::ThreadedRequestData(
 | |
|   vtkInformation * vtkNotUsed( request ),
 | |
|   vtkInformationVector **inputVector,
 | |
|   vtkInformationVector * vtkNotUsed( outputVector ),
 | |
|   vtkImageData ***inData,
 | |
|   vtkImageData **outData,
 | |
|   int outExt[6], int id)
 | |
| {
 | |
|   int inExt[6];
 | |
|   void *outPtr = outData[0]->GetScalarPointerForExtent(outExt);
 | |
| 
 | |
|   vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
 | |
| 
 | |
|   this->InternalRequestUpdateExtent(inExt, outExt);
 | |
|   void *inPtr = inData[0][0]->GetScalarPointerForExtent(inExt);
 | |
|   if (!inPtr)
 | |
|     {
 | |
|     return;
 | |
|     }
 | |
| 
 | |
|   // this filter expects that input is the same type as output.
 | |
|   if (inData[0][0]->GetScalarType() != outData[0]->GetScalarType())
 | |
|     {
 | |
|     vtkErrorMacro("Execute: input ScalarType, "
 | |
|                   << inData[0][0]->GetScalarType()
 | |
|                   << ", must match out ScalarType "
 | |
|                   << outData[0]->GetScalarType());
 | |
|     return;
 | |
|     }
 | |
|   
 | |
|   switch (inData[0][0]->GetScalarType())
 | |
|     {
 | |
|     vtkTemplateMacro(
 | |
|       vtkImageShrink3DExecute( this, 
 | |
|                                inData[0][0],
 | |
|                                (VTK_TT *)(inPtr), 
 | |
|                                outData[0], 
 | |
|                                (VTK_TT *)(outPtr),
 | |
|                                outExt, 
 | |
|                                id, 
 | |
|                                inInfo) );
 | |
|     default:
 | |
|       vtkErrorMacro(<< "Execute: Unknown ScalarType");
 | |
|       return;
 | |
|     }
 | |
| }
 | |
| 
 |