1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkImageQuantizeRGBToIndex.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14 =========================================================================*/
15 #include "vtkImageQuantizeRGBToIndex.h"
16
17 #include "vtkImageData.h"
18 #include "vtkLookupTable.h"
19 #include "vtkInformation.h"
20 #include "vtkInformationVector.h"
21 #include "vtkObjectFactory.h"
22 #include "vtkStreamingDemandDrivenPipeline.h"
23 #include "vtkTimerLog.h"
24
25 #include <math.h>
26
27 vtkStandardNewMacro(vtkImageQuantizeRGBToIndex);
28
29 class vtkColorQuantizeNode
30 {
31 public:
vtkColorQuantizeNode()32 vtkColorQuantizeNode()
33 { this->Axis = -1; this->SplitPoint = -1; this->Index = -1;
34 this->Child1 = NULL; this->Child2 = NULL;
35 this->StdDev[0] = this->StdDev[1] = this->StdDev[2] = 0.0;
36 this->Histogram[0] = this->Histogram[1] = this->Histogram[2] = NULL;
37 this->Image = NULL;
38 this->Bounds[0] = 0; this->Bounds[1] = 256;
39 this->Bounds[2] = 0; this->Bounds[3] = 256;
40 this->Bounds[4] = 0; this->Bounds[5] = 256; };
41
~vtkColorQuantizeNode()42 ~vtkColorQuantizeNode()
43 { delete []this->Histogram[0];
44 delete []this->Histogram[1];
45 delete []this->Histogram[2];
46 delete this->Child1;
47 delete this->Child2; };
48
SetImageExtent(int v[6])49 void SetImageExtent( int v[6] )
50 { memcpy( this->ImageExtent, v, 6*sizeof(int) ); };
51
SetImageIncrement(vtkIdType v[3])52 void SetImageIncrement( vtkIdType v[3] )
53 { memcpy( this->ImageIncrement, v, 3*sizeof(vtkIdType) ); };
54
SetImageType(double type)55 void SetImageType(double type)
56 {
57 this->ImageType = static_cast<int>(type);
58 }
59
SetImage(void * image)60 void SetImage( void *image ) { this->Image = image; };
61
GetAxis()62 int GetAxis( ) { return this->Axis; };
SetAxis(int v)63 void SetAxis( int v ) { this->Axis = v; };
64
GetSplitPoint()65 int GetSplitPoint( ) { return this->SplitPoint; };
SetSplitPoint(int v)66 void SetSplitPoint( int v ) { this->SplitPoint = v; };
67
GetBounds()68 int *GetBounds( ) { return this->Bounds; };
SetBounds(int v[6])69 void SetBounds( int v[6] ) { memcpy( this->Bounds, v, 6*sizeof(int) ); };
70
GetIndex()71 int GetIndex( ) { return this->Index; };
SetIndex(int v)72 void SetIndex( int v ) { this->Index = v; };
73
GetStdDev(int axis)74 double GetStdDev( int axis ) { return this->StdDev[axis]; };
75 void ComputeStdDev();
76
GetCount()77 int GetCount() { return this->Count; };
78
GetMean(int axis)79 double GetMean( int axis ) { return this->Mean[axis]; };
80
81 void Divide( int axis, int nextIndex );
82
GetChild1()83 vtkColorQuantizeNode *GetChild1() { return this->Child1; };
SetChild1(vtkColorQuantizeNode * n)84 void SetChild1( vtkColorQuantizeNode *n ) { this->Child1 = n; };
85
GetChild2()86 vtkColorQuantizeNode *GetChild2() { return this->Child2; };
SetChild2(vtkColorQuantizeNode * n)87 void SetChild2( vtkColorQuantizeNode *n ) { this->Child2 = n; };
88
GetIndex(int c[3])89 int GetIndex( int c[3] )
90 { if ( this->Index>=0 ) {return this->Index;}
91 if ( c[this->Axis]>this->SplitPoint )
92 {return this->Child2->GetIndex(c);}
93 return this->Child1->GetIndex(c); };
94
95
GetAverageColor(int c[3])96 void GetAverageColor(int c[3])
97 {
98 if(this->AverageCount)
99 {
100 c[0] = static_cast<int>(this->AverageColor[0] / this->AverageCount);
101 c[1] = static_cast<int>(this->AverageColor[1] / this->AverageCount);
102 c[2] = static_cast<int>(this->AverageColor[2] / this->AverageCount);
103 }
104 }
105
StartColorAveraging()106 void StartColorAveraging()
107 {if (this->Child1)
108 {
109 this->Child1->StartColorAveraging(); this->Child2->StartColorAveraging();
110 }
111 else
112 {
113 this->AverageCount = 0;
114 this->AverageColor[0] =
115 this->AverageColor[1] = this->AverageColor[2] = 0.0;
116 }
117 };
118
AddColor(int c[3])119 void AddColor( int c[3] )
120 { this->AverageCount++; this->AverageColor[0] += c[0];
121 this->AverageColor[1] += c[1]; this->AverageColor[2] += c[2]; };
122
123 protected:
124 int Axis;
125 int SplitPoint;
126 int Bounds[6];
127 int Index;
128 double StdDev[3];
129 double Median[3];
130 double Mean[3];
131 int Count;
132 int AverageCount;
133 double AverageColor[3];
134 vtkIdType ImageIncrement[3];
135 int ImageExtent[6];
136 int ImageType;
137 void *Image;
138 int *Histogram[3];
139 vtkColorQuantizeNode *Child1, *Child2;
140 };
141
142 template <class T>
vtkImageQuantizeRGBToIndexHistogram(T * inPtr,int extent[6],vtkIdType inIncrement[3],int type,int bounds[6],int * histogram[3])143 void vtkImageQuantizeRGBToIndexHistogram( T *inPtr, int extent[6],
144 vtkIdType inIncrement[3], int type,
145 int bounds[6], int *histogram[3] )
146 {
147 T *rgbPtr, v[3];
148 int x, y, z, c;
149 int value[3];
150 int max[3];
151
152 max[0] = bounds[1] - bounds[0] + 1;
153 max[1] = bounds[3] - bounds[2] + 1;
154 max[2] = bounds[5] - bounds[4] + 1;
155
156 for ( c = 0; c < 3; c++ )
157 {
158 for ( x = 0; x < max[c]; x++ )
159 {
160 histogram[c][x] = 0;
161 }
162 }
163
164 // Generate the histogram
165 rgbPtr = inPtr;
166 for (z = extent[4]; z <= extent[5]; z++)
167 {
168 for (y = extent[2]; y <= extent[3]; y++)
169 {
170 for (x = extent[0]; x <= extent[1]; x++)
171 {
172 if ( type == VTK_UNSIGNED_CHAR )
173 {
174 v[0] = *(rgbPtr++) - bounds[0];
175 v[1] = *(rgbPtr++) - bounds[2];
176 v[2] = *(rgbPtr++) - bounds[4];
177 if ( static_cast<int>(v[0]) < max[0] &&
178 static_cast<int>(v[1]) < max[1] &&
179 static_cast<int>(v[2]) < max[2] )
180 {
181 histogram[0][static_cast<unsigned char>(v[0])]++;
182 histogram[1][static_cast<unsigned char>(v[1])]++;
183 histogram[2][static_cast<unsigned char>(v[2])]++;
184 }
185 }
186 else if ( type == VTK_UNSIGNED_SHORT )
187 {
188 v[0] = ((static_cast<unsigned short>(*(rgbPtr++)))>>8) - bounds[0];
189 v[1] = ((static_cast<unsigned short>(*(rgbPtr++)))>>8) - bounds[2];
190 v[2] = ((static_cast<unsigned short>(*(rgbPtr++)))>>8) - bounds[4];
191 if (static_cast<int>(v[0]) < max[0] &&
192 static_cast<int>(v[1]) < max[1] &&
193 static_cast<int>(v[2]) < max[2] )
194 {
195 histogram[0][static_cast<unsigned short>(v[0])]++;
196 histogram[1][static_cast<unsigned short>(v[1])]++;
197 histogram[2][static_cast<unsigned short>(v[2])]++;
198 }
199 }
200 else
201 {
202 value[0] = static_cast<int>( *(rgbPtr++) * 255.5 ) - bounds[0];
203 value[1] = static_cast<int>( *(rgbPtr++) * 255.5 ) - bounds[2];
204 value[2] = static_cast<int>( *(rgbPtr++) * 255.5 ) - bounds[4];
205 if ( static_cast<int>(value[0]) < max[0] &&
206 static_cast<int>(value[1]) < max[1] &&
207 static_cast<int>(value[2]) < max[2] )
208 {
209 histogram[0][value[0]]++;
210 histogram[1][value[1]]++;
211 histogram[2][value[2]]++;
212 }
213 }
214 rgbPtr += inIncrement[0];
215 }
216 rgbPtr += inIncrement[1];
217 }
218 rgbPtr += inIncrement[2];
219 }
220 }
221
222 // This templated function executes the filter for supported types of data.
223 template <class T>
vtkImageQuantizeRGBToIndexExecute(vtkImageQuantizeRGBToIndex * self,vtkImageData * inData,T * inPtr,vtkImageData * outData,unsigned short * outPtr)224 void vtkImageQuantizeRGBToIndexExecute(vtkImageQuantizeRGBToIndex *self,
225 vtkImageData *inData, T *inPtr,
226 vtkImageData *outData,
227 unsigned short *outPtr)
228 {
229 int extent[6];
230 vtkIdType inIncrement[3], outIncrement[3];
231 T *rgbPtr;
232 unsigned short *indexPtr;
233 int x, y, z, c;
234 int type;
235 vtkColorQuantizeNode *root, *tmp;
236 vtkColorQuantizeNode *leafNodes[65536];
237 int numLeafNodes;
238 int maxdevAxis = 0, maxdevLeafNode = 0;
239 double maxdev, dev;
240 int leaf, axis;
241 int cannotDivideFurther;
242 vtkLookupTable *lut;
243 double color[4];
244 int rgb[3];
245 vtkTimerLog *timer;
246 int totalCount;
247 double weight;
248 int done=0;
249
250 timer = vtkTimerLog::New();
251 timer->StartTimer();
252 type = self->GetInputType();
253
254 // need extent to get increments.
255 // in and out extents are the same
256 inData->GetExtent( extent );
257
258 inData->GetContinuousIncrements(extent, inIncrement[0],
259 inIncrement[1], inIncrement[2]);
260 outData->GetContinuousIncrements(extent, outIncrement[0],
261 outIncrement[1], outIncrement[2]);
262
263 timer->StopTimer();
264
265 self->SetInitializeExecuteTime( timer->GetElapsedTime() );
266 timer->StartTimer();
267
268 // Build the tree
269 // Create the root node - it is our only leaf node
270 root = new vtkColorQuantizeNode;
271 root->SetIndex( 0 );
272 root->SetImageExtent( extent );
273 root->SetImageIncrement( inIncrement );
274 root->SetImageType( type );
275 root->SetImage( inPtr );
276 root->ComputeStdDev();
277 leafNodes[0] = root;
278 numLeafNodes = 1;
279
280 cannotDivideFurther = 0;
281
282 totalCount =
283 (extent[1] - extent[0] + 1) *
284 (extent[3] - extent[2] + 1) *
285 (extent[5] - extent[4] + 1);
286
287 // Loop until we've added enough leaf nodes or we can't add any more
288 while ( numLeafNodes < self->GetNumberOfColors() && !cannotDivideFurther )
289 {
290 // Find leaf node / axis with maximum deviation
291 maxdev = 0.0;
292 for ( leaf = 0; leaf < numLeafNodes; leaf++ )
293 {
294 for ( axis = 0; axis < 3; axis++ )
295 {
296 dev = leafNodes[leaf]->GetStdDev( axis );
297 weight = static_cast<double>(leafNodes[leaf]->GetCount())
298 /static_cast<double>(totalCount);
299 dev *= weight;
300 if ( dev > maxdev )
301 {
302 maxdevAxis = axis;
303 maxdevLeafNode = leaf;
304 maxdev = dev;
305 }
306 }
307 }
308 if ( maxdev == 0.0 )
309 {
310 cannotDivideFurther = 1;
311 }
312 else
313 {
314 leafNodes[maxdevLeafNode]->Divide( maxdevAxis, numLeafNodes );
315 leafNodes[numLeafNodes] = leafNodes[maxdevLeafNode]->GetChild1();
316 leafNodes[maxdevLeafNode] = leafNodes[maxdevLeafNode]->GetChild2();
317 numLeafNodes++;
318 }
319
320 self->UpdateProgress(0.6667*numLeafNodes/self->GetNumberOfColors());
321 }
322
323 timer->StopTimer();
324 self->SetBuildTreeExecuteTime( timer->GetElapsedTime() );
325 timer->StartTimer();
326
327 root->StartColorAveraging();
328
329 // Fill in the indices in the output image
330 indexPtr = outPtr;
331 rgbPtr = inPtr;
332 for (z = extent[4]; z <= extent[5]; z++)
333 {
334 for (y = extent[2]; !self->AbortExecute && y <= extent[3]; y++)
335 {
336 for (x = extent[0]; x <= extent[1]; x++)
337 {
338 for (c = 0; c < 3; c++)
339 {
340 if ( type == VTK_UNSIGNED_CHAR )
341 {
342 rgb[c] = static_cast<int>(*rgbPtr);
343 }
344 else if ( type == VTK_UNSIGNED_SHORT )
345 {
346 rgb[c] = (static_cast<unsigned short>(*rgbPtr))>>8;
347 }
348 else
349 {
350 rgb[c] = static_cast<int>(*rgbPtr * 255.5);
351 }
352 rgbPtr++;
353 }
354 tmp = root;
355 while( !done )
356 {
357 if ( tmp->GetIndex() != -1 )
358 {
359 *indexPtr = tmp->GetIndex();
360 break;
361 }
362 if ( rgb[tmp->GetAxis()] > tmp->GetSplitPoint() )
363 {
364 tmp = tmp->GetChild2();
365 }
366 else
367 {
368 tmp = tmp->GetChild1();
369 }
370 }
371 tmp->AddColor( rgb );
372 indexPtr++;
373
374 rgbPtr += inIncrement[0];
375 indexPtr += outIncrement[0];
376 }
377 rgbPtr += inIncrement[1];
378 indexPtr += outIncrement[1];
379 }
380 rgbPtr += inIncrement[2];
381 indexPtr += outIncrement[2];
382 }
383
384 self->UpdateProgress(0.90);
385
386 // Fill in the lookup table
387 lut = self->GetLookupTable();
388 lut->SetNumberOfTableValues( numLeafNodes );
389 lut->SetNumberOfColors( numLeafNodes );
390 lut->SetTableRange( 0, numLeafNodes-1 );
391 color[3] = 1.0;
392 for ( leaf = 0; leaf < numLeafNodes; leaf++ )
393 {
394 leafNodes[leaf]->GetAverageColor( rgb );
395 color[0] = rgb[0] / 255.0;
396 color[1] = rgb[1] / 255.0;
397 color[2] = rgb[2] / 255.0;
398 lut->SetTableValue( leafNodes[leaf]->GetIndex(), color );
399 }
400
401
402 timer->StopTimer();
403 self->SetLookupIndexExecuteTime( timer->GetElapsedTime() );
404 timer->Delete();
405
406 delete root;
407 }
408
ComputeStdDev()409 void vtkColorQuantizeNode::ComputeStdDev()
410 {
411 int i, j;
412 double mean;
413 int count=0;
414 int medianCount;
415
416 // Create space for histogram
417 this->Histogram[0] = new int[this->Bounds[1] - this->Bounds[0] + 1];
418 this->Histogram[1] = new int[this->Bounds[3] - this->Bounds[2] + 1];
419 this->Histogram[2] = new int[this->Bounds[5] - this->Bounds[4] + 1];
420
421 // Create histogram
422 switch (this->ImageType)
423 {
424 vtkTemplateMacro(
425 vtkImageQuantizeRGBToIndexHistogram(
426 static_cast<VTK_TT *>(this->Image), this->ImageExtent,
427 this->ImageIncrement, this->ImageType,
428 this->Bounds, this->Histogram ));
429 }
430
431
432 // Compute for r, g, and b
433 for ( i = 0; i < 3; i++ )
434 {
435 // Compute the mean
436 mean = 0;
437 count = 0;
438 for ( j = 0; j <= (this->Bounds[i*2 + 1] - this->Bounds[i*2]); j++ )
439 {
440 count += this->Histogram[i][j];
441 mean += this->Histogram[i][j] * (j + this->Bounds[i*2]);
442 }
443 if (count>0)
444 {
445 mean /= static_cast<double>(count);
446 }
447 else
448 {
449 mean = 0;
450 }
451 this->Mean[i] = mean;
452
453 // Must have some minimum distance to subdivide - if we
454 // are below this distance limit, don't compute a
455 // standard deviation since we don't want to subdivide this
456 // node along this axis. Set the deviation to 0.0 and continue.
457 if ( this->Bounds[i*2 + 1] == this->Bounds[i*2] )
458 {
459 this->StdDev[i] = 0.0;
460 continue;
461 }
462
463
464 // Where is the median?
465 medianCount = count / 2;
466
467 // Initialize the median to unset
468 this->Median[i] = -1;
469
470 // Compute the standard deviation and the location of the median
471 this->StdDev[i] = 0;
472 count = 0;
473 for ( j = 0; j <= (this->Bounds[i*2 + 1] - this->Bounds[i*2]); j++ )
474 {
475 count += this->Histogram[i][j];
476 this->StdDev[i] += static_cast<double>(this->Histogram[i][j]) *
477 (static_cast<double>(j)+this->Bounds[i*2]-mean) *
478 (static_cast<double>(j)+this->Bounds[i*2]-mean);
479 if ( this->Median[i] == -1 && count > medianCount )
480 {
481 this->Median[i] = j + this->Bounds[i*2];
482 }
483 }
484
485 // If our median is at the upper bound, bump down by one. This will
486 // help in the cases where we have a distance of 2 in this dimension,
487 // and just over half the entries are in the second bucket. We
488 // still want to divide - the division needs to be at the first
489 // bucket.
490 if ( this->Median[i] == this->Bounds[i*2 + 1] )
491 {
492 this->Median[i]--;
493 }
494
495 // Do the final division and square root to get the standard deviation
496 if (count>0)
497 {
498 this->StdDev[i] /= static_cast<double>(count);
499 }
500 else
501 {
502 this->StdDev[i] = 0;
503 }
504
505 this->StdDev[i] = sqrt( this->StdDev[i] );
506 }
507
508 // Should all be the same - just take the last one
509 this->Count = count;
510 }
511
Divide(int axis,int nextIndex)512 void vtkColorQuantizeNode::Divide( int axis, int nextIndex )
513 {
514 int newBounds[6];
515
516 this->Child1 = new vtkColorQuantizeNode;
517 this->Child2 = new vtkColorQuantizeNode;
518
519 memcpy( newBounds, this->Bounds, 6*sizeof(int) );
520
521 newBounds[axis*2 + 1] = static_cast<int>(this->Median[axis]);
522 this->Child1->SetBounds( newBounds );
523
524 newBounds[axis*2] = static_cast<int>(this->Median[axis] + 1);
525 newBounds[axis*2 + 1] = static_cast<int>(this->Bounds[axis*2 + 1]);
526 this->Child2->SetBounds( newBounds );
527
528 this->SplitPoint = static_cast<int>(this->Median[axis]);
529 this->Axis = axis;
530
531 this->Child1->SetIndex( this->Index );
532 this->Child2->SetIndex( nextIndex );
533 this->Index = -1;
534
535 delete [] this->Histogram[0];
536 delete [] this->Histogram[1];
537 delete [] this->Histogram[2];
538
539 this->Histogram[0] = NULL;
540 this->Histogram[1] = NULL;
541 this->Histogram[2] = NULL;
542
543 this->Child1->SetImageExtent( this->ImageExtent );
544 this->Child1->SetImageIncrement( this->ImageIncrement );
545 this->Child1->SetImageType( this->ImageType );
546 this->Child1->SetImage( this->Image );
547
548 this->Child2->SetImageExtent( this->ImageExtent );
549 this->Child2->SetImageIncrement( this->ImageIncrement );
550 this->Child2->SetImageType( this->ImageType );
551 this->Child2->SetImage( this->Image );
552
553 this->Child1->ComputeStdDev();
554 this->Child2->ComputeStdDev();
555 }
556
557 // Constructor sets default values
vtkImageQuantizeRGBToIndex()558 vtkImageQuantizeRGBToIndex::vtkImageQuantizeRGBToIndex()
559 {
560 this->LookupTable = vtkLookupTable::New();
561 this->NumberOfColors = 256;
562 this->InputType = VTK_UNSIGNED_SHORT;
563
564 this->InitializeExecuteTime = 0.0;
565 this->BuildTreeExecuteTime = 0.0;
566 this->LookupIndexExecuteTime = 0.0;
567 }
568
569 // Destructor deletes used resources
~vtkImageQuantizeRGBToIndex()570 vtkImageQuantizeRGBToIndex::~vtkImageQuantizeRGBToIndex()
571 {
572 if ( this->LookupTable )
573 {
574 this->LookupTable->Delete();
575 }
576 }
577
578 // This method is passed an input and output Data, and executes the filter
579 // algorithm to fill the output from the input.
580 // It just executes a switch statement to call the correct function for
581 // the Datas data types.
RequestData(vtkInformation * vtkNotUsed (request),vtkInformationVector ** inputVector,vtkInformationVector * outputVector)582 int vtkImageQuantizeRGBToIndex::RequestData(
583 vtkInformation *vtkNotUsed(request),
584 vtkInformationVector **inputVector,
585 vtkInformationVector *outputVector)
586 {
587 void *inPtr;
588 void *outPtr;
589
590 vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
591 vtkInformation *outInfo = outputVector->GetInformationObject(0);
592
593 vtkImageData *inData = vtkImageData::SafeDownCast(
594 inInfo->Get(vtkDataObject::DATA_OBJECT()));
595 vtkImageData *outData = vtkImageData::SafeDownCast(
596 outInfo->Get(vtkDataObject::DATA_OBJECT()));
597
598 outData->SetExtent(
599 outInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT()));
600 outData->AllocateScalars(outInfo);
601
602 int inExt[6];
603 inData->GetExtent(inExt);
604 // if the input extent is empty then exit
605 if (inExt[1] < inExt[0] ||
606 inExt[3] < inExt[2] ||
607 inExt[5] < inExt[4])
608 {
609 return 1;
610 }
611
612 inPtr = inData->GetScalarPointer();
613 outPtr = outData->GetScalarPointer();
614
615 // Input must be 3 components (rgb)
616 if (inData->GetNumberOfScalarComponents() != 3)
617 {
618 vtkErrorMacro("This filter can handles only 3 components");
619 return 1;
620 }
621
622 // this filter expects that output is type unsigned short.
623 if (outData->GetScalarType() != VTK_UNSIGNED_SHORT)
624 {
625 vtkErrorMacro(<< "Execute: out ScalarType " << outData->GetScalarType()
626 << " must be unsigned short\n");
627 return 1;
628 }
629
630 this->InputType = inData->GetScalarType();
631
632 switch ( this->InputType )
633 {
634 vtkTemplateMacro(
635 vtkImageQuantizeRGBToIndexExecute(this,
636 inData, static_cast<VTK_TT *>(inPtr),
637 outData,
638 static_cast<unsigned short *>(outPtr)));
639 default:
640 vtkErrorMacro(<< "Execute: This ScalarType is not handled");
641 return 1;
642 }
643
644 return 1;
645 }
646
647 // Change the output type and number of components
RequestInformation(vtkInformation * vtkNotUsed (request),vtkInformationVector ** vtkNotUsed (inputVector),vtkInformationVector * outputVector)648 int vtkImageQuantizeRGBToIndex::RequestInformation (
649 vtkInformation * vtkNotUsed(request),
650 vtkInformationVector **vtkNotUsed(inputVector),
651 vtkInformationVector *outputVector)
652 {
653 // get the info objects
654 vtkInformation* outInfo = outputVector->GetInformationObject(0);
655
656 vtkDataObject::SetPointDataActiveScalarInfo(outInfo, VTK_UNSIGNED_SHORT, 1);
657 return 1;
658 }
659
660 // Get ALL of the input.
RequestUpdateExtent(vtkInformation * vtkNotUsed (request),vtkInformationVector ** inputVector,vtkInformationVector * vtkNotUsed (outputVector))661 int vtkImageQuantizeRGBToIndex::RequestUpdateExtent(
662 vtkInformation * vtkNotUsed(request),
663 vtkInformationVector **inputVector,
664 vtkInformationVector *vtkNotUsed(outputVector))
665 {
666 // get the info objects
667 vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
668
669 int inExt[6];
670 inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), inExt);
671 inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), inExt, 6);
672
673 return 1;
674 }
675
PrintSelf(ostream & os,vtkIndent indent)676 void vtkImageQuantizeRGBToIndex::PrintSelf(ostream& os, vtkIndent indent)
677 {
678 this->Superclass::PrintSelf(os,indent);
679
680 // Input Type is internal so we dont prit it
681 //os << indent << "InputType: " << this->InputType << endl;
682
683 os << indent << "Number Of Colors: " << this->NumberOfColors << endl;
684 os << indent << "Lookup Table: " << endl << *this->LookupTable;
685 os << indent << "Execute Time (in initialize stage): " <<
686 this->InitializeExecuteTime << endl;
687 os << indent << "Execute Time (in build tree stage): " <<
688 this->BuildTreeExecuteTime << endl;
689 os << indent << "Execute Time (in lookup index stage): " <<
690 this->LookupIndexExecuteTime << endl;
691 }
692