vtkCompressCompositer.cxx 20.3 KB
Newer Older
1
2
3
4
5
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkCompressCompositer.cxx

6
  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7
8
9
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

10
11
     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

// This software and ancillary information known as vtk_ext (and
// herein called "SOFTWARE") is made available under the terms
// described below.  The SOFTWARE has been approved for release with
// associated LA_CC Number 99-44, granted by Los Alamos National
// Laboratory in July 1999.
//
// Unless otherwise indicated, this SOFTWARE has been authored by an
// employee or employees of the University of California, operator of
// the Los Alamos National Laboratory under Contract No. W-7405-ENG-36
// with the United States Department of Energy.
//
// The United States Government has rights to use, reproduce, and
// distribute this SOFTWARE.  The public may copy, distribute, prepare
// derivative works and publicly display this SOFTWARE without charge,
// provided that this Notice and any statement of authorship are
// reproduced on all copies.
//
// Neither the U. S. Government, the University of California, nor the
// Advanced Computing Laboratory makes any warranty, either express or
// implied, nor assumes any liability or responsibility for the use of
// this SOFTWARE.
//
// If SOFTWARE is modified to produce derivative works, such modified
// SOFTWARE should be clearly marked, so as not to confuse it with the
// version available from Los Alamos National Laboratory.

#include "vtkCompressCompositer.h"
#include "vtkObjectFactory.h"
#include "vtkToolkits.h"
#include "vtkFloatArray.h"
#include "vtkUnsignedCharArray.h"
47
#include "vtkMultiProcessController.h"
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

#include "vtkTimerLog.h"

vtkStandardNewMacro(vtkCompressCompositer);


// Different pixel types to template.
typedef struct {
  unsigned char r;
  unsigned char g;
  unsigned char b;
} vtkCharRGBType;

typedef struct {
  unsigned char r;
  unsigned char g;
  unsigned char b;
  unsigned char a;
} vtkCharRGBAType;

typedef struct {
  float r;
  float g;
  float b;
  float a;
} vtkFloatRGBAType;



//-------------------------------------------------------------------------
vtkCompressCompositer::vtkCompressCompositer()
{
  this->InternalPData = NULL;
  this->InternalZData = NULL;
  this->Timer = vtkTimerLog::New();
}

85

86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
//-------------------------------------------------------------------------
vtkCompressCompositer::~vtkCompressCompositer()
{
  if (this->InternalPData)
    {
    this->InternalPData->Delete();
    this->InternalPData = NULL;
    }
  if (this->InternalZData)
    {
    this->InternalZData->Delete();
    this->InternalZData = NULL;
    }

  this->Timer->Delete();
  this->Timer = NULL;
}



//-------------------------------------------------------------------------
// Compress background pixels with runlength encoding.
// z values above 1.0 mean: Repeat background for that many pixels.
109
// We could easily compress inplace, but it works out better for buffer
Kyle Lutz's avatar
Kyle Lutz committed
110
// management if we do not.  zIn == zOut is allowed....
111
template <class P>
Ken Martin's avatar
Ken Martin committed
112
113
int vtkCompressCompositerCompress(float *zIn, P *pIn, float *zOut, P *pOut,
                                  int numPixels)
114
115
116
117
118
{
  float* endZ;
  int length = 0;
  int compressCount;

119
120
  // Do not go past the last pixel (zbuf check/correct)
  endZ = zIn+numPixels-1;
121
122
123
  if (*zIn < 0.0 || *zIn > 1.0)
    {
    *zIn = 1.0;
124
    }
125
126
127
128
129
130
131
132
133
134
135
  while (zIn < endZ)
    {
    ++length;
    // Always copy the first pixel value.
    *pOut++ = *pIn++;
    // Find the length of any compressed run.
    compressCount = 0;
    while (*zIn == 1.0 && zIn < endZ)
      {
      ++compressCount;
      ++zIn;
136
137
138
      if (*zIn < 0.0 || *zIn > 1.0)
        {
        *zIn = 1.0;
139
        }
140
      }
141

142
143
144
145
146
147
148
149
    if (compressCount > 0)
      { // Only compress runs of 2 or more.
      // Move the pixel pointer past compressed region.
      pIn += (compressCount-1);
      // Set the special z value.
      *zOut++ = (float)(compressCount);
      }
    else
150
      {
151
      *zOut++ = *zIn++;
152
153
154
      if (*zIn < 0.0 || *zIn > 1.0)
        {
        *zIn = 1.0;
155
        }
156
157
      }
    }
158
159
160
161
  // Put the last pixel in.
  *pOut = *pIn;
  *zOut = *zIn;

162
163
164
165
166
167
  return length;
}

//-------------------------------------------------------------------------
// Compress background pixels with runlength encoding.
// z values above 1.0 mean: Repeat background for that many pixels.
168
// We could easily compress inplace, but it works out better for buffer
Kyle Lutz's avatar
Kyle Lutz committed
169
// management if we do not.  zIn == zOut is allowed....
170
171
172
173
174
175
176
177
178
void vtkCompressCompositer::Compress(vtkFloatArray *zIn, vtkDataArray *pIn,
                                     vtkFloatArray *zOut, vtkDataArray *pOut)
{
  float* pzf1 = zIn->GetPointer(0);
  float* pzf2 = zOut->GetPointer(0);
  void*  ppv1 = pIn->GetVoidPointer(0);
  void*  ppv2 = pOut->GetVoidPointer(0);
  int totalPixels = zIn->GetNumberOfTuples();
  int length;
179

180
181
  vtkTimerLog::MarkStartEvent("Compress");

182
  // This is just a complex switch statement
183
  // to call the correct templated function.
184
  if (pIn->GetDataType() == VTK_UNSIGNED_CHAR)
185
    {
186
    if (pIn->GetNumberOfComponents() == 3)
187
      {
Andy Cedilnik's avatar
Andy Cedilnik committed
188
189
190
191
      length = vtkCompressCompositerCompress(
        pzf1, reinterpret_cast<vtkCharRGBType*>(ppv1),
        pzf2, reinterpret_cast<vtkCharRGBType*>(ppv2),
        totalPixels);
192
      }
193
    else if (pIn->GetNumberOfComponents() == 4)
194
      {
Andy Cedilnik's avatar
Andy Cedilnik committed
195
196
197
198
      length = vtkCompressCompositerCompress(
        pzf1, reinterpret_cast<vtkCharRGBAType*>(ppv1),
        pzf2, reinterpret_cast<vtkCharRGBAType*>(ppv2),
        totalPixels);
199
      }
200
    else
201
      {
202
      vtkGenericWarningMacro("Pixels have unexpected number of components.");
203
204
205
      return;
      }
    }
206
207
  else if (pIn->GetDataType() == VTK_FLOAT &&
           pIn->GetNumberOfComponents() == 4)
208
    {
Andy Cedilnik's avatar
Andy Cedilnik committed
209
210
211
212
    length = vtkCompressCompositerCompress(
      pzf1, reinterpret_cast<vtkFloatRGBAType*>(ppv1),
      pzf2, reinterpret_cast<vtkFloatRGBAType*>(ppv2),
      totalPixels);
213
214
215
    }
  else
    {
216
    vtkGenericWarningMacro("Unexpected pixel type.");
217
218
219
220
221
222
223
224
225
226
227
228
229
230
    return;
    }

  zOut->SetNumberOfTuples(length);
  pOut->SetNumberOfTuples(length);

  vtkTimerLog::MarkEndEvent("Compress");
}

//-------------------------------------------------------------------------
//  z values above 1.0 mean: Repeat background for that many pixels.
// Assume that the array has enough allocated space for the uncompressed.
// In place/reverse order.
template <class P>
231
232
void vtkCompressCompositerUncompress(float *zIn, P *pIn, float *zOut, P *pOut,
                                     int lengthIn)
233
234
235
236
{
  float* endZ;
  int count;
  P background;
237

238
239
240
241
242
243
244
245
246
247
248
249
  endZ = zIn + lengthIn;

  while (zIn < endZ)
    {
    // Expand any compressed data.
    if (*zIn > 1.0)
      {
      background = *pIn++;
      count = (int)(*zIn++);
      while (count-- > 0)
        {
        *pOut++ = background;
250
        *zOut++ = 1.0;
251
252
253
254
255
        }
      }
    else
      {
      *pOut++ = *pIn++;
256
      *zOut++ = *zIn++;
257
258
259
260
261
262
263
      }
    }
}

//-------------------------------------------------------------------------
// Compress background pixels with runlength encoding.
// z values above 1.0 mean: Repeat background for that many pixels.
264
// We could easily compress inplace, but it works out better for buffer
Kyle Lutz's avatar
Kyle Lutz committed
265
// management if we do not.  zIn == zOut is allowed....
266
void vtkCompressCompositer::Uncompress(vtkFloatArray *zIn, vtkDataArray *pIn,
267
268
                                       vtkFloatArray *zOut, vtkDataArray *pOut,
                                       int lengthOut)
269
270
{
  float* pzf1 = zIn->GetPointer(0);
271
  float* pzf2 = zOut->GetPointer(0);
272
273
274
  void*  ppv1 = pIn->GetVoidPointer(0);
  void*  ppv2 = pOut->GetVoidPointer(0);
  int lengthIn = zIn->GetNumberOfTuples();
275

276
277
  vtkTimerLog::MarkStartEvent("Uncompress");

278
  // This is just a complex switch statement
279
  // to call the correct templated function.
280
  if (pIn->GetDataType() == VTK_UNSIGNED_CHAR)
281
    {
282
    if (pIn->GetNumberOfComponents() == 3)
283
      {
284
      vtkCompressCompositerUncompress(pzf1,
Andy Cedilnik's avatar
Andy Cedilnik committed
285
                                      reinterpret_cast<vtkCharRGBType*>(ppv1),
286
                                      pzf2,
287
288
289
                                      reinterpret_cast<vtkCharRGBType*>(ppv2),
                                      lengthIn);
      }
290
    else if (pIn->GetNumberOfComponents() == 4)
291
      {
292
      vtkCompressCompositerUncompress(pzf1,
Andy Cedilnik's avatar
Andy Cedilnik committed
293
                                      reinterpret_cast<vtkCharRGBAType*>(ppv1),
294
                                      pzf2,
295
296
297
                                      reinterpret_cast<vtkCharRGBAType*>(ppv2),
                                      lengthIn);
      }
298
    else
299
      {
300
      vtkGenericWarningMacro("Pixels have unexpected number of components.");
301
302
303
      return;
      }
    }
304
305
  else if (pIn->GetDataType() == VTK_FLOAT &&
           pIn->GetNumberOfComponents() == 4)
306
    {
307
    vtkCompressCompositerUncompress(pzf1,
Andy Cedilnik's avatar
Andy Cedilnik committed
308
                                    reinterpret_cast<vtkFloatRGBAType*>(ppv1),
309
                                    pzf2,
310
311
312
313
314
                                    reinterpret_cast<vtkFloatRGBAType*>(ppv2),
                                    lengthIn);
    }
  else
    {
315
    vtkGenericWarningMacro("Unexpected pixel type.");
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
    return;
    }

  //zOut->SetNumberOfTuples(lengthOut);
  pOut->SetNumberOfTuples(lengthOut);

  vtkTimerLog::MarkEndEvent("Uncompress");
}




//-------------------------------------------------------------------------
// Can handle compositing compressed buffers.
// z values above 1.0 mean: Repeat background for that many pixels.
template <class P>
Ken Martin's avatar
Ken Martin committed
332
333
int vtkCompressCompositerCompositePair(float *z1, P *p1, float *z2, P *p2,
                                       float *zOut, P *pOut, int length1)
334
335
336
337
338
339
340
341
342
343
{
  float* startZOut = zOut;
  float* endZ1;
  // These counts keep track of the length of compressed runs.
  // Value -1 means pointer is not on a compression run.
  // Value 0 means pointer is on a used up compression run.
  int cCount1 = 0;
  int cCount2 = 0;
  int cCount3;
  int length3;
344

345
  // This is for the end test.
346
  // We are assuming that the uncompressed buffer length of 1 and 2
Andy Cedilnik's avatar
Andy Cedilnik committed
347
  // are the same.
348
349
  endZ1 = z1 + length1;

350
  while(z1 != endZ1)
351
352
353
354
355
356
357
358
359
360
    {
    // Initialize a new state if necessary.
    if (cCount1 == 0 && *z1 > 1.0)
      { // Detect a new run in buffer 1.
      cCount1 = (int)(*z1);
      }
    if (cCount2 == 0 && *z2 > 1.0)
      { // Detect a new run in buffer 2.
      cCount2 = (int)(*z2);
      }
361

362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
    // Case 1: Neither buffer is compressed.
    // We could keep the length of uncompressed runs ...
    if (cCount1 == 0 && cCount2 == 0)
      {
      // Loop through buffers doing standard compositing.
      while (*z1 <= 1.0 && *z2 <= 1.0 && z1 != endZ1)
        {
        if (*z1 < *z2)
          {
          *zOut++ = *z1++;
          ++z2;
          *pOut++ = *p1++;
          ++p2;
          }
        else
377
          {
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
          *zOut++ = *z2++;
          ++z1;
          *pOut++ = *p2++;
          ++p1;
          }
        }
      // Let the next iteration determine the new state (counts).
      }
    else if (cCount1 > 0 && cCount2 > 0)
      { // segment where both are compressed
      // Pick the smaller compressed run an duplicate in output.
      cCount3 = (cCount1 < cCount2) ? cCount1 : cCount2;
      cCount2 -= cCount3;
      cCount1 -= cCount3;
      // Set the output pixel.
      *zOut++ = (float)(cCount3);
      // either pixel will do.
      *pOut++ = *p1;
      if (cCount1 == 0)
        {
        ++z1;
        ++p1;
        }
      if (cCount2 == 0)
        {
        ++z2;
        ++p2;
        }
      }
    else if (cCount1 > 0 && cCount2 == 0)
      { //1 is in a compressed run but 2 is not.
409
      // Copy from 2 until we hit a compressed region,
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
      // or we run out of the 1 compressed run.
      while (cCount1 && *z2 <= 1.0)
        {
        *zOut++ = *z2++;
        *pOut++ = *p2++;
        --cCount1;
        }
      if (cCount1 == 0)
        {
        ++z1;
        ++p1;
        }
      }
    else if (cCount1 == 0 && cCount2 > 0)
      { //2 is in a compressed run but 1 is not.
425
      // Copy from 1 until we hit a compressed region,
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
      // or we run out of the 2 compressed run.
      while (cCount2 && *z1 <= 1.0)
        {
        *zOut++ = *z1++;
        *pOut++ = *p1++;
        --cCount2;
        }
      if (cCount2 == 0)
        {
        ++z2;
        ++p2;
        }
      } // end case if.
    } // while not finished (process cases).
  // Here is a scary way to determine the length of the new buffer.
  length3 = zOut - startZOut;

  return length3;
}
445

446
447
448
//-------------------------------------------------------------------------
// Can handle compositing compressed buffers.
// z values above 1.0 mean: Repeat background for that many pixels.
Andy Cedilnik's avatar
Andy Cedilnik committed
449
450
451
void vtkCompressCompositer::CompositeImagePair(
  vtkFloatArray *localZ, vtkDataArray *localP,
  vtkFloatArray *remoteZ, vtkDataArray *remoteP,
452
  vtkFloatArray *outZ, vtkDataArray *outP)
453
454
455
456
457
458
459
460
461
{
  float* z1 = localZ->GetPointer(0);
  float* z2 = remoteZ->GetPointer(0);
  float* z3 = outZ->GetPointer(0);
  void*  p1 = localP->GetVoidPointer(0);
  void*  p2 = remoteP->GetVoidPointer(0);
  void*  p3 = outP->GetVoidPointer(0);
  int length1 = localZ->GetNumberOfTuples();
  int l3;
462

463
464
  //vtkTimerLog::MarkStartEvent("Coomposite Image Pair");

465
  // This is just a complex switch statement
466
  // to call the correct templated function.
467
  if (localP->GetDataType() == VTK_UNSIGNED_CHAR)
468
    {
469
    if (localP->GetNumberOfComponents() == 3)
470
      {
Andy Cedilnik's avatar
Andy Cedilnik committed
471
472
473
474
      l3 = vtkCompressCompositerCompositePair(
        z1, reinterpret_cast<vtkCharRGBType*>(p1),
        z2, reinterpret_cast<vtkCharRGBType*>(p2),
        z3, reinterpret_cast<vtkCharRGBType*>(p3),
475
476
                                              length1);
      }
477
    else if (localP->GetNumberOfComponents() == 4)
478
      {
Andy Cedilnik's avatar
Andy Cedilnik committed
479
480
481
482
483
      l3 = vtkCompressCompositerCompositePair(
        z1, reinterpret_cast<vtkCharRGBAType*>(p1),
        z2, reinterpret_cast<vtkCharRGBAType*>(p2),
        z3, reinterpret_cast<vtkCharRGBAType*>(p3),
        length1);
484
      }
485
    else
486
      {
487
      vtkGenericWarningMacro("Pixels have unexpected number of components.");
488
489
490
      return;
      }
    }
491
492
  else if (localP->GetDataType() == VTK_FLOAT &&
           localP->GetNumberOfComponents() == 4)
493
    {
Andy Cedilnik's avatar
Andy Cedilnik committed
494
495
496
497
498
    l3 = vtkCompressCompositerCompositePair(
      z1, reinterpret_cast<vtkFloatRGBAType*>(p1),
      z2, reinterpret_cast<vtkFloatRGBAType*>(p2),
      z3, reinterpret_cast<vtkFloatRGBAType*>(p3),
      length1);
499
500
501
    }
  else
    {
502
    vtkGenericWarningMacro("Unexpected pixel type.");
503
504
505
506
507
508
509
510
511
512
513
514
515
516
    return;
    }

  outZ->SetNumberOfTuples(l3);
  outP->SetNumberOfTuples(l3);

  //vtkTimerLog::MarkEndEvent("Coomposite Image Pair");
}



#define vtkTCPow2(j) (1 << (j))

//----------------------------------------------------------------------------
Ken Martin's avatar
Ken Martin committed
517
inline int vtkTCLog2(int j, int& exact)
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
{
  int counter=0;
  exact = 1;
  while(j)
    {
    if ( ( j & 1 ) && (j >> 1) )
      {
      exact = 0;
      }
    j = j >> 1;
    counter++;
    }
  return counter-1;
}

//----------------------------------------------------------------------------
534
void vtkCompressCompositer::CompositeBuffer(vtkDataArray *pBuf,
Andy Cedilnik's avatar
Andy Cedilnik committed
535
                                            vtkFloatArray *zBuf,
536
                                            vtkDataArray *pTmp,
Andy Cedilnik's avatar
Andy Cedilnik committed
537
                                            vtkFloatArray *zTmp)
538
539
{
  int myId = this->Controller->GetLocalProcessId();
540
  int numProcs = this->NumberOfProcesses;
541
542
543
544
  int i, id;
  int exactLog;
  int logProcs = vtkTCLog2(numProcs,exactLog);
  int uncompressedLength = zBuf->GetNumberOfTuples();
Andy Cedilnik's avatar
Andy Cedilnik committed
545
  int bufSize=0;
546
547
548
549
550
551
552
  int numComps = pBuf->GetNumberOfComponents();
  vtkDataArray  *p1, *p2, *p3;
  vtkFloatArray *z1, *z2, *z3;

  //this->Timer->StartTimer();

  // Make sure we have an internal buffer of the correct length.
553
  if (this->InternalPData == NULL ||
554
555
556
557
558
559
      this->InternalPData->GetDataType() != pBuf->GetDataType() ||
      this->InternalPData->GetNumberOfTuples() != pBuf->GetNumberOfTuples() ||
      this->InternalPData->GetSize() < pBuf->GetSize())
    {
    if (this->InternalPData)
      {
Ken Martin's avatar
Ken Martin committed
560
      vtkCompositer::DeleteArray(this->InternalPData);
561
562
      this->InternalPData = NULL;
      }
563
564
565
    if (pBuf->GetDataType() == VTK_UNSIGNED_CHAR)
      {
      this->InternalPData = vtkUnsignedCharArray::New();
Ken Martin's avatar
Ken Martin committed
566
567
568
      vtkCompositer::ResizeUnsignedCharArray(
        static_cast<vtkUnsignedCharArray*>(this->InternalPData),
        numComps, pBuf->GetSize());
569
      }
570
    else
571
572
      {
      this->InternalPData = vtkFloatArray::New();
Ken Martin's avatar
Ken Martin committed
573
574
575
      vtkCompositer::ResizeFloatArray(
        static_cast<vtkFloatArray*>(this->InternalPData),
        numComps, pBuf->GetSize());
576
      }
577
    }
578
  // Now float array.
579
  if (this->InternalZData == NULL ||
580
581
582
583
      this->InternalZData->GetSize() < zBuf->GetSize())
    {
    if (this->InternalZData)
      {
Ken Martin's avatar
Ken Martin committed
584
      vtkCompositer::DeleteArray(this->InternalZData);
585
586
587
      this->InternalZData = NULL;
      }
    this->InternalZData = vtkFloatArray::New();
Ken Martin's avatar
Ken Martin committed
588
589
590
    vtkCompositer::ResizeFloatArray(
      static_cast<vtkFloatArray*>(this->InternalZData),
      1, zBuf->GetSize());
591
592
593
594
595
596
597
598
599
600
601
602
    }

  // Compress the incoming buffers (in place operation).
  this->Compress(zBuf, pBuf, zTmp, pTmp);

  // We are going to need to shuffle these around during compositing.
  p1 = pTmp;
  z1 = zTmp;
  p2 = this->InternalPData;
  z2 = this->InternalZData;

  // not a power of 2 -- need an additional level
603
  if ( !exactLog )
604
605
606
607
608
609
610
    {
    logProcs++;
    }

#ifdef MPIPROALLOC
  vtkCommunicator::SetUseCopy(0);
#endif
611
  for (i = 0; i < logProcs; i++)
612
    {
613
    if ((myId % (int)vtkTCPow2(i)) == 0)
614
      { // Find participants
615
      if ((myId % (int)vtkTCPow2(i+1)) < vtkTCPow2(i))
616
617
618
        {
        // receivers
        id = myId+vtkTCPow2(i);
619

620
621
        // only send or receive if sender or receiver id is valid
        // (handles non-power of 2 cases)
622
        if (id < numProcs)
623
624
625
626
627
628
629
          {
          this->Controller->Receive(&bufSize, 1, id, 98);
          this->Controller->Receive(zBuf->GetPointer(0), bufSize, id, 99);
          this->Controller->Receive(&bufSize, 1, id, 98);
          if (pTmp->GetDataType() == VTK_UNSIGNED_CHAR)
            {
            this->Controller->Receive(reinterpret_cast<unsigned char*>
630
                                      (pBuf->GetVoidPointer(0)),
631
632
633
634
635
                                      bufSize, id, 99);
            }
          else
            {
            this->Controller->Receive(reinterpret_cast<float*>
636
                                      (pBuf->GetVoidPointer(0)),
637
638
                                      bufSize, id, 99);
            }
639

640
641
642
643
644
645
646
647
648
649
650
          // notice the result is stored as the local data
          this->CompositeImagePair(z1, p1, zBuf, pBuf, z2, p2);
          // Swap the temp buffers (p3/z3 are just temporary storage).
          p3 = p1;
          z3 = z1;
          p1 = p2;
          z1 = z2;
          p2 = p3;
          z2 = z3;
          }
        }
651
      else
652
653
        { // The current data is always in buffer 1.
        id = myId-vtkTCPow2(i);
654
        if (id < numProcs)
655
656
657
658
659
660
661
662
663
          {
          bufSize = z1->GetNumberOfTuples();
          this->Controller->Send(&bufSize, 1, id, 98);
          this->Controller->Send(z1->GetPointer(0), bufSize, id, 99);
          bufSize = p1->GetNumberOfTuples() * numComps;
          this->Controller->Send(&bufSize, 1, id, 98);
          if (p1->GetDataType() == VTK_UNSIGNED_CHAR)
            {
            this->Controller->Send(reinterpret_cast<unsigned char*>
664
                                   (p1->GetVoidPointer(0)),
665
666
667
668
669
                                   bufSize, id, 99);
            }
          else
            {
            this->Controller->Send(reinterpret_cast<float*>
670
                                   (p1->GetVoidPointer(0)),
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
                                   bufSize, id, 99);
            }
          }
        }
      }
    }

#ifdef MPIPROALLOC
  vtkCommunicator::SetUseCopy(1);
#endif


  if (myId == 0)
    {
    // Now we want to decompress into the original buffers.
686
    this->Uncompress(z1, p1, zBuf, pBuf, uncompressedLength);
687
688
689
690
691
692
693
694
    }

  //this->Timer->StopTimer();
  //float time = this->Timer->GetElapsedTime();
  //cerr << "Composite " << " took " << time << " seconds.\n";

}

695
696
697



698
699
700
//----------------------------------------------------------------------------
void vtkCompressCompositer::PrintSelf(ostream& os, vtkIndent indent)
{
701
  this->Superclass::PrintSelf(os, indent);
702
703
704
705
}