• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

dox/Hybrid/vtkX3DExporterFIWriterHelper.h

Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   Visualization Toolkit
00004   Module:    $RCSfile: vtkX3DExporterFIWriterHelper.h,v $
00005 
00006   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
00007   All rights reserved.
00008   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
00009 
00010      This software is distributed WITHOUT ANY WARRANTY; without even
00011      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00012      PURPOSE.  See the above copyright notice for more information.
00013 
00014 =========================================================================*/
00015 #ifndef __vtkX3DExporterFIWriterHelper_h
00016 #define __vtkX3DExporterFIWriterHelper_h
00017 
00018 //#include "vtkX3DExporterFIByteWriter.h"
00019 #include "vtkZLibDataCompressor.h"
00020 #include <cassert>
00021 
00022 #define EXPONENT_MASK_32 0x7f800000
00023 #define MANTISSA_MASK_32 0x007fffff
00024 
00025 #ifndef max
00026 #define max(a,b) (((a) > (b)) ? (a) : (b))
00027 #endif
00028 class vtkX3DExporterFIWriterHelper 
00029 {
00030 public:
00031   union float_to_unsigned_int_to_bytes
00032       {
00033         float f;
00034         unsigned int ui;
00035         unsigned char ub[4]; // unsigned bytes
00036       };
00037 
00038   template<typename T>
00039     static inline void EncodeFloatFI(vtkX3DExporterFIByteWriter* writer, T* value, size_t size)
00040       {
00041       // We want to start at position 3
00042       assert(writer->CurrentBytePos == 2);
00043 
00044       // ITU C.19.3.4: If the alternative encoding-algorithm is present, 
00045       // then the two bits '11' (discriminant) are appended
00046       writer->PutBits("11");
00047       // ITU 10.8.1: This encoding algorithm has a vocabulary table index of 7,
00048       writer->PutBits(7-1, 8);
00049 
00050       vtkstd::string bytes;
00051       char byte[4];
00052       for (size_t i = 0; i < size; i++)
00053         {
00054         float_to_unsigned_int_to_bytes v;
00055         v.f = value[i];
00056 
00057         // Avoid -0
00058         if (v.ui == 0x80000000)
00059           {
00060           v.f = 0;
00061           }
00062 
00063         byte[0] = v.ub[3];
00064         byte[1] = v.ub[2];
00065         byte[2] = v.ub[1];
00066         byte[3] = v.ub[0];
00067 
00068         bytes.append(byte, 4);
00069         }
00070       EncodeNonEmptyByteString5(writer, bytes);
00071       }
00072 
00073   template<typename T>
00074     static inline void EncodeIntegerFI(vtkX3DExporterFIByteWriter* writer, T* value, size_t size)
00075       {
00076       // We want to start at position 3
00077       assert(writer->CurrentBytePos == 2);
00078 
00079       // ITU C.19.3.4: If the alternative encoding-algorithm is present, 
00080       // then the two bits '11' (discriminant) are appended
00081       writer->PutBits("11");
00082       // ITU 10.8.1: This encoding algorithm has a vocabulary table index of 4,
00083       writer->PutBits(4-1, 8);
00084       vtkstd::string bytes;
00085       for(size_t i = 0; i < size; i++)
00086         {
00087         int v = value[i];
00088         int f = ReverseBytes(&v);
00089         char *p = reinterpret_cast <char*> (&f);
00090         bytes.append(p, 4);
00091         }
00092       EncodeNonEmptyByteString5(writer, bytes);
00093       }
00094 
00095   static inline void EncodeCharacterString3(vtkX3DExporterFIByteWriter* writer, vtkstd::string value)
00096     {
00097     // We want to start at position 3
00098     assert(writer->CurrentBytePos == 2);
00099 
00100     // ITU C.19.3.1 If the alternative utf-8 is present, then the two bits '00' 
00101     // are appended to the bit stream.
00102     writer->PutBits("00");
00103     // ITU C.19.4: The component bytes is encoded as described in C.23.
00104     EncodeNonEmptyByteString5(writer, value);
00105     }
00106 
00107   // ITU C.23: Encoding of the NonEmptyByteString starting
00108   // on the fifth bit of an byte
00109   static inline void EncodeNonEmptyByteString5(vtkX3DExporterFIByteWriter* writer, vtkstd::string value)
00110     {
00111     int length = static_cast<int>(value.length());
00112     if (length <= 8)
00113       {
00114       writer->PutBit(0);
00115       writer->PutBits(length - 1, 3);
00116       }
00117     else if (length <= 264)
00118       {
00119       writer->PutBits("1000");
00120       writer->PutBits(length - 9, 8);
00121       }
00122     else
00123       {
00124       writer->PutBits("1100");
00125       writer->PutBits(length - 265, 32);
00126       }
00127     writer->PutBytes(value.c_str(), length);
00128     }
00129 
00130 
00131   // ITU C.27: Encoding of integers in the range 1 to 2^20
00132   // starting on the third bit of an byte
00133   static inline void EncodeInteger3(vtkX3DExporterFIByteWriter* writer, unsigned int value)
00134     {
00135     // We want to start at position 3
00136     assert(writer->CurrentBytePos == 2);
00137 
00138     if (value <= 32) // ITU  C.27.2
00139       {
00140       writer->PutBit(0);
00141       writer->PutBits(value - 1, 5);
00142       }
00143     else if (value <= 2080) // ITU C.27.3
00144       {
00145       writer->PutBits("100");
00146       writer->PutBits(value - 33, 11);
00147       }
00148     else if (value < 526368) // ITU C.27.4
00149       {
00150       writer->PutBits("101");
00151       writer->PutBits(value - 2081, 19);
00152       }
00153     else // ITU C.27.5
00154       {
00155       writer->PutBits("1100000000");
00156       writer->PutBits(value - 526369, 20);
00157       }
00158     }
00159 
00160   // ITU C.25: Encoding of integers in the range 1 to 2^20
00161   // starting on the second bit of an byte
00162   static inline void EncodeInteger2(vtkX3DExporterFIByteWriter* writer, unsigned int value)
00163     {
00164     // We want to start at position 2
00165     assert(writer->CurrentBytePos == 1);
00166 
00167     if (value <= 64) // ITU  C.25.2
00168       {
00169       writer->PutBits("0");
00170       writer->PutBits(value - 1, 6);
00171       }
00172     else if (value <= 8256) // ITU C.25.3
00173       {
00174       writer->PutBits("10");
00175       writer->PutBits(value - 65, 13);
00176       }
00177     else // ITU C.25.4
00178       {
00179       writer->PutBits("110");
00180       writer->PutBits(value - 8257, 20);
00181       }
00182     }
00183 
00184   static inline void EncodeLineFeed(vtkX3DExporterFIByteWriter* writer)
00185     {
00186     static bool firstTime = true;
00187     writer->FillByte();
00188     if (firstTime)
00189       {
00190       writer->PutBits("1001000000001010");
00191       firstTime = false;
00192       }
00193     else
00194       {
00195       //cout << "Encode NOT the first time" << endl;
00196       writer->PutBits("10100000");
00197       }
00198     }
00199 
00200 private:
00201 
00202   static int ReverseBytes(int* x) {
00203     /* break x apart, then put it back together backwards */
00204     int part1 = (*x)  & 0xFF;
00205     int part2 = ((*x) >> 8) & 0xFF;
00206     int part3 = ((*x) >> 16) & 0xFF;
00207     int part4 = ((*x) >> 24) & 0xFF;
00208     return (part1 << 24) | ( part2 << 16) | (part3 << 8) | part4;
00209   }
00210 
00211 
00212   friend class X3DEncoderFunctions;
00213 };
00214 
00215 class X3DEncoderFunctions {
00216 
00217 
00218 
00219 public:
00220   template<typename T>
00221     static inline void EncodeIntegerDeltaZ(vtkX3DExporterFIByteWriter* writer, T* value, size_t size, vtkZLibDataCompressor* compressor,  bool image = false)
00222       {
00223       // We want to start at position 3
00224       assert(writer->CurrentBytePos == 2);
00225 
00226       // ITU C.19.3.4: If the alternative encoding-algorithm is present, 
00227       // then the two bits '11' (discriminant) are appended
00228       writer->PutBits("11");
00229       // ITU 10.8.1: This encoding algorithm has a vocabulary table index of 33
00230       writer->PutBits(34-1, 8);
00231 
00232       // compute delta
00233       char span = 0;
00234       size_t i = 0;
00235       int f; unsigned char *p;
00236       vtkstd::vector<unsigned char> deltas;
00237 
00238       if (image)
00239         {
00240         span = 0;
00241         for(i = 0; i < size; i++)
00242           {
00243           int v = 1 + (value[i]);
00244           int *vp = reinterpret_cast<int*>(&v);
00245           f = vtkX3DExporterFIWriterHelper::ReverseBytes(vp);
00246           p = reinterpret_cast <unsigned char*> (&f);
00247           deltas.push_back(p[0]);
00248           deltas.push_back(p[1]);
00249           deltas.push_back(p[2]);
00250           deltas.push_back(p[3]);
00251           }
00252         compressor->SetCompressionLevel(9);
00253         }
00254       else
00255         {
00256         for (i = 0; i < 20; i++)
00257           {
00258           if (value[i] == -1)
00259             {
00260             span = static_cast<char>(i) + 1;
00261             break;
00262             }
00263           }
00264         if (!span) span = 4;
00265 
00266         for(i = 0; i < static_cast<size_t>(span); i++)
00267           {
00268           int v = 1 + value[i];
00269           int *vp = reinterpret_cast<int*>(&v);
00270           f = vtkX3DExporterFIWriterHelper::ReverseBytes(vp);
00271 
00272           p = reinterpret_cast <unsigned char*> (&f);
00273           deltas.push_back(p[0]);
00274           deltas.push_back(p[1]);
00275           deltas.push_back(p[2]);
00276           deltas.push_back(p[3]);
00277           }
00278         for(i = span; i < size; i++)
00279           {
00280           int v = 1 + (value[i] - value[i-span]);
00281           f = vtkX3DExporterFIWriterHelper::ReverseBytes(&v);
00282 
00283           p = reinterpret_cast <unsigned char*> (&f);
00284           deltas.push_back(p[0]);
00285           deltas.push_back(p[1]);
00286           deltas.push_back(p[2]);
00287           deltas.push_back(p[3]);
00288           }
00289         }
00290 
00291       size_t bufferSize = deltas.size() + static_cast<unsigned int>(ceil(deltas.size()*0.001)) + 12;
00292       unsigned char* buffer = new unsigned char[bufferSize];
00293       size_t newSize = compressor->Compress(&deltas[0],static_cast<unsigned long>(deltas.size()), buffer, static_cast<unsigned long>(bufferSize));
00294 
00295       vtkstd::string bytes;
00296       int size32 = static_cast<int>(size);
00297       int size32_reversed = vtkX3DExporterFIWriterHelper::ReverseBytes(&size32);
00298       char *s = reinterpret_cast <char*> (&size32_reversed);
00299       bytes.append(s, 4);
00300       bytes.append(&span, 1);
00301 
00302       for (i = 0; i < newSize; i++)
00303         {
00304         unsigned char c = buffer[i];
00305         bytes += c;
00306         }
00307       delete buffer;
00308 
00309       vtkX3DExporterFIWriterHelper::EncodeNonEmptyByteString5(writer, bytes);
00310       if (image) 
00311         {
00312         compressor->SetCompressionLevel(5);
00313         }
00314       }
00315 
00316   static inline void EncodeQuantizedzlibFloatArray(vtkX3DExporterFIByteWriter* writer, const double* value, size_t size, vtkZLibDataCompressor* compressor)
00317     {
00318     // We want to start at position 3
00319     assert(writer->CurrentBytePos == 2);
00320 
00321     // ITU C.19.3.4: If the alternative encoding-algorithm is present, 
00322     // then the two bits '11' (discriminant) are appended
00323     writer->PutBits("11");
00324     // ITU 10.8.1: This encoding algorithm has a vocabulary table index of 33
00325     writer->PutBits(34, 8);
00326 
00327     unsigned char* bytes = new unsigned char[size*4];
00328     unsigned char* bytepos = bytes;
00329     vtkstd::string bytesCompressed;
00330     size_t i;
00331 
00332     const double* vd = value;
00333     for (i = 0; i < size; i++)
00334       {
00335       union float_to_unsigned_int_to_bytes
00336       {
00337         float f;
00338         unsigned int ui;
00339         unsigned char ub[4]; // unsigned bytes
00340       };
00341       float_to_unsigned_int_to_bytes v;
00342       v.f = (*vd) * 2.0;
00343 
00344       // Avoid -0
00345       if (v.ui == 0x80000000)
00346         {
00347         v.f = 0.0f;
00348         }
00349       //vtkGenericWarningMacro(<< "value: " << v << " bytes: " << (int)s[0] << " " << (int)s[1] << " " << (int)s[2] << " " << (int)s[3]);
00350       *bytepos++ = v.ub[3];
00351       *bytepos++ = v.ub[2];
00352       *bytepos++ = v.ub[1];
00353       *bytepos++ = v.ub[0];
00354       vd++;
00355       }
00356 
00357 
00358     // Compress the data
00359     size_t bufferSize = (size * 4) + static_cast<size_t>(ceil((size * 4)*0.001)) + 12;
00360     unsigned char* buffer = new unsigned char[bufferSize];
00361     size_t newSize = compressor->Compress(bytes,
00362       static_cast<unsigned long>(size * 4), buffer,
00363       static_cast<unsigned long>(bufferSize));
00364 
00365     char *s;
00366     // Put the number of bits for exponent
00367     bytesCompressed += static_cast<char>(8);
00368     // Put the number of bits for mantissa
00369     bytesCompressed += static_cast<char>(23);
00370     // Put the length
00371     int length = static_cast<int>(size*4);
00372     int length_reversed = vtkX3DExporterFIWriterHelper::ReverseBytes(&length);
00373     s = reinterpret_cast <char*> (&length_reversed);
00374     bytesCompressed.append(s, 4);
00375 
00376     // Put the number of floats
00377     int numFloats = static_cast<int>(size);
00378     int numFloats_reversed = vtkX3DExporterFIWriterHelper::ReverseBytes(&numFloats);;
00379     s = reinterpret_cast <char*> (&numFloats_reversed);
00380     bytesCompressed.append(s, 4);
00381 
00382     for (i = 0; i < newSize; i++)
00383       {
00384       unsigned char c = buffer[i];
00385       bytesCompressed += c;
00386       }
00387     vtkX3DExporterFIWriterHelper::EncodeNonEmptyByteString5(writer, bytesCompressed);
00388     delete buffer;
00389     delete bytes;
00390     }
00391 
00392 };
00393 
00394 #endif

Generated by  doxygen 1.7.1