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