1 /* 2 Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc. 3 4 Permission is hereby granted, free of charge, to any person obtaining a copy 5 of this software and associated documentation files (the "Software"), to deal 6 in the Software without restriction, including without limitation the rights 7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 copies of the Software, and to permit persons to whom the Software is 9 furnished to do so, subject to the following conditions: 10 11 The above copyright notice and this permission notice shall be included in 12 all copies or substantial portions of the Software. 13 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 THE SOFTWARE. 21 */ 22 23 #include "o3dgcTriangleFans.h" 24 #include "o3dgcArithmeticCodec.h" 25 26 //#define DEBUG_VERBOSE 27 28 namespace o3dgc 29 { 30 #ifdef DEBUG_VERBOSE 31 FILE* g_fileDebugTF = NULL; 32 #endif //DEBUG_VERBOSE 33 SaveUIntData(const Vector<long> & data,BinaryStream & bstream)34 O3DGCErrorCode SaveUIntData(const Vector<long> & data, 35 BinaryStream & bstream) 36 { 37 unsigned long start = bstream.GetSize(); 38 bstream.WriteUInt32ASCII(0); 39 const unsigned long size = data.GetSize(); 40 bstream.WriteUInt32ASCII(size); 41 for(unsigned long i = 0; i < size; ++i) 42 { 43 bstream.WriteUIntASCII(data[i]); 44 } 45 bstream.WriteUInt32ASCII(start, bstream.GetSize() - start); 46 return O3DGC_OK; 47 } SaveIntData(const Vector<long> & data,BinaryStream & bstream)48 O3DGCErrorCode SaveIntData(const Vector<long> & data, 49 BinaryStream & bstream) 50 { 51 unsigned long start = bstream.GetSize(); 52 bstream.WriteUInt32ASCII(0); 53 const unsigned long size = data.GetSize(); 54 bstream.WriteUInt32ASCII(size); 55 for(unsigned long i = 0; i < size; ++i) 56 { 57 bstream.WriteIntASCII(data[i]); 58 } 59 bstream.WriteUInt32ASCII(start, bstream.GetSize() - start); 60 return O3DGC_OK; 61 } SaveBinData(const Vector<long> & data,BinaryStream & bstream)62 O3DGCErrorCode SaveBinData(const Vector<long> & data, 63 BinaryStream & bstream) 64 { 65 unsigned long start = bstream.GetSize(); 66 bstream.WriteUInt32ASCII(0); 67 const unsigned long size = data.GetSize(); 68 long symbol; 69 bstream.WriteUInt32ASCII(size); 70 for(unsigned long i = 0; i < size; ) 71 { 72 symbol = 0; 73 for(unsigned long h = 0; h < O3DGC_BINARY_STREAM_BITS_PER_SYMBOL0 && i < size; ++h) 74 { 75 symbol += (data[i] << h); 76 ++i; 77 } 78 bstream.WriteUCharASCII((unsigned char) symbol); 79 } 80 bstream.WriteUInt32ASCII(start, bstream.GetSize() - start); 81 return O3DGC_OK; 82 } SaveUIntAC(const Vector<long> & data,const unsigned long M,BinaryStream & bstream)83 O3DGCErrorCode CompressedTriangleFans::SaveUIntAC(const Vector<long> & data, 84 const unsigned long M, 85 BinaryStream & bstream) 86 { 87 unsigned long start = bstream.GetSize(); 88 const unsigned int NMAX = data.GetSize() * 8 + 100; 89 const unsigned long size = data.GetSize(); 90 long minValue = O3DGC_MAX_LONG; 91 bstream.WriteUInt32Bin(0); 92 bstream.WriteUInt32Bin(size); 93 if (size > 0) 94 { 95 #ifdef DEBUG_VERBOSE 96 printf("-----------\nsize %i, start %i\n", size, start); 97 fprintf(g_fileDebugTF, "-----------\nsize %i, start %i\n", size, start); 98 #endif //DEBUG_VERBOSE 99 100 for(unsigned long i = 0; i < size; ++i) 101 { 102 if (minValue > data[i]) 103 { 104 minValue = data[i]; 105 } 106 #ifdef DEBUG_VERBOSE 107 printf("%i\t%i\n", i, data[i]); 108 fprintf(g_fileDebugTF, "%i\t%i\n", i, data[i]); 109 #endif //DEBUG_VERBOSE 110 } 111 bstream.WriteUInt32Bin(minValue); 112 if ( m_sizeBufferAC < NMAX ) 113 { 114 delete [] m_bufferAC; 115 m_sizeBufferAC = NMAX; 116 m_bufferAC = new unsigned char [m_sizeBufferAC]; 117 } 118 Arithmetic_Codec ace; 119 ace.set_buffer(NMAX, m_bufferAC); 120 ace.start_encoder(); 121 Adaptive_Data_Model mModelValues(M+1); 122 for(unsigned long i = 0; i < size; ++i) 123 { 124 ace.encode(data[i]-minValue, mModelValues); 125 } 126 unsigned long encodedBytes = ace.stop_encoder(); 127 for(unsigned long i = 0; i < encodedBytes; ++i) 128 { 129 bstream.WriteUChar8Bin(m_bufferAC[i]); 130 } 131 } 132 bstream.WriteUInt32Bin(start, bstream.GetSize() - start); 133 return O3DGC_OK; 134 } SaveBinAC(const Vector<long> & data,BinaryStream & bstream)135 O3DGCErrorCode CompressedTriangleFans::SaveBinAC(const Vector<long> & data, 136 BinaryStream & bstream) 137 { 138 unsigned long start = bstream.GetSize(); 139 const unsigned int NMAX = data.GetSize() * 8 + 100; 140 const unsigned long size = data.GetSize(); 141 bstream.WriteUInt32Bin(0); 142 bstream.WriteUInt32Bin(size); 143 if (size > 0) 144 { 145 if ( m_sizeBufferAC < NMAX ) 146 { 147 delete [] m_bufferAC; 148 m_sizeBufferAC = NMAX; 149 m_bufferAC = new unsigned char [m_sizeBufferAC]; 150 } 151 Arithmetic_Codec ace; 152 ace.set_buffer(NMAX, m_bufferAC); 153 ace.start_encoder(); 154 Adaptive_Bit_Model bModel; 155 #ifdef DEBUG_VERBOSE 156 printf("-----------\nsize %i, start %i\n", size, start); 157 fprintf(g_fileDebugTF, "-----------\nsize %i, start %i\n", size, start); 158 #endif //DEBUG_VERBOSE 159 for(unsigned long i = 0; i < size; ++i) 160 { 161 ace.encode(data[i], bModel); 162 #ifdef DEBUG_VERBOSE 163 printf("%i\t%i\n", i, data[i]); 164 fprintf(g_fileDebugTF, "%i\t%i\n", i, data[i]); 165 #endif //DEBUG_VERBOSE 166 } 167 unsigned long encodedBytes = ace.stop_encoder(); 168 for(unsigned long i = 0; i < encodedBytes; ++i) 169 { 170 bstream.WriteUChar8Bin(m_bufferAC[i]); 171 } 172 } 173 bstream.WriteUInt32Bin(start, bstream.GetSize() - start); 174 return O3DGC_OK; 175 } 176 SaveIntACEGC(const Vector<long> & data,const unsigned long M,BinaryStream & bstream)177 O3DGCErrorCode CompressedTriangleFans::SaveIntACEGC(const Vector<long> & data, 178 const unsigned long M, 179 BinaryStream & bstream) 180 { 181 unsigned long start = bstream.GetSize(); 182 const unsigned int NMAX = data.GetSize() * 8 + 100; 183 const unsigned long size = data.GetSize(); 184 long minValue = 0; 185 bstream.WriteUInt32Bin(0); 186 bstream.WriteUInt32Bin(size); 187 if (size > 0) 188 { 189 #ifdef DEBUG_VERBOSE 190 printf("-----------\nsize %i, start %i\n", size, start); 191 fprintf(g_fileDebugTF, "-----------\nsize %i, start %i\n", size, start); 192 #endif //DEBUG_VERBOSE 193 for(unsigned long i = 0; i < size; ++i) 194 { 195 if (minValue > data[i]) 196 { 197 minValue = data[i]; 198 } 199 #ifdef DEBUG_VERBOSE 200 printf("%i\t%i\n", i, data[i]); 201 fprintf(g_fileDebugTF, "%i\t%i\n", i, data[i]); 202 #endif //DEBUG_VERBOSE 203 } 204 bstream.WriteUInt32Bin(minValue + O3DGC_MAX_LONG); 205 if ( m_sizeBufferAC < NMAX ) 206 { 207 delete [] m_bufferAC; 208 m_sizeBufferAC = NMAX; 209 m_bufferAC = new unsigned char [m_sizeBufferAC]; 210 } 211 Arithmetic_Codec ace; 212 ace.set_buffer(NMAX, m_bufferAC); 213 ace.start_encoder(); 214 Adaptive_Data_Model mModelValues(M+2); 215 Static_Bit_Model bModel0; 216 Adaptive_Bit_Model bModel1; 217 unsigned long value; 218 for(unsigned long i = 0; i < size; ++i) 219 { 220 value = data[i]-minValue; 221 if (value < M) 222 { 223 ace.encode(value, mModelValues); 224 } 225 else 226 { 227 ace.encode(M, mModelValues); 228 ace.ExpGolombEncode(value-M, 0, bModel0, bModel1); 229 } 230 } 231 unsigned long encodedBytes = ace.stop_encoder(); 232 for(unsigned long i = 0; i < encodedBytes; ++i) 233 { 234 bstream.WriteUChar8Bin(m_bufferAC[i]); 235 } 236 } 237 bstream.WriteUInt32Bin(start, bstream.GetSize() - start); 238 return O3DGC_OK; 239 } Save(BinaryStream & bstream,bool encodeTrianglesOrder,O3DGCStreamType streamType)240 O3DGCErrorCode CompressedTriangleFans::Save(BinaryStream & bstream, bool encodeTrianglesOrder, O3DGCStreamType streamType) 241 { 242 #ifdef DEBUG_VERBOSE 243 g_fileDebugTF = fopen("SaveIntACEGC_new.txt", "w"); 244 #endif //DEBUG_VERBOSE 245 246 if (streamType == O3DGC_STREAM_TYPE_ASCII) 247 { 248 SaveUIntData(m_numTFANs , bstream); 249 SaveUIntData(m_degrees , bstream); 250 SaveUIntData(m_configs , bstream); 251 SaveBinData (m_operations, bstream); 252 SaveIntData (m_indices , bstream); 253 if (encodeTrianglesOrder) 254 { 255 SaveUIntData(m_trianglesOrder, bstream); 256 } 257 } 258 else 259 { 260 SaveIntACEGC(m_numTFANs , 4 , bstream); 261 SaveIntACEGC(m_degrees , 16, bstream); 262 SaveUIntAC (m_configs , 10, bstream); 263 SaveBinAC (m_operations, bstream); 264 SaveIntACEGC(m_indices , 8 , bstream); 265 if (encodeTrianglesOrder) 266 { 267 SaveIntACEGC(m_trianglesOrder , 16, bstream); 268 } 269 } 270 #ifdef DEBUG_VERBOSE 271 fclose(g_fileDebugTF); 272 #endif //DEBUG_VERBOSE 273 return O3DGC_OK; 274 } LoadUIntData(Vector<long> & data,const BinaryStream & bstream,unsigned long & iterator)275 O3DGCErrorCode LoadUIntData(Vector<long> & data, 276 const BinaryStream & bstream, 277 unsigned long & iterator) 278 { 279 bstream.ReadUInt32ASCII(iterator); 280 const unsigned long size = bstream.ReadUInt32ASCII(iterator); 281 data.Allocate(size); 282 data.Clear(); 283 for(unsigned long i = 0; i < size; ++i) 284 { 285 data.PushBack(bstream.ReadUIntASCII(iterator)); 286 } 287 return O3DGC_OK; 288 } LoadIntData(Vector<long> & data,const BinaryStream & bstream,unsigned long & iterator)289 O3DGCErrorCode LoadIntData(Vector<long> & data, 290 const BinaryStream & bstream, 291 unsigned long & iterator) 292 { 293 bstream.ReadUInt32ASCII(iterator); 294 const unsigned long size = bstream.ReadUInt32ASCII(iterator); 295 data.Allocate(size); 296 data.Clear(); 297 for(unsigned long i = 0; i < size; ++i) 298 { 299 data.PushBack(bstream.ReadIntASCII(iterator)); 300 } 301 return O3DGC_OK; 302 } LoadBinData(Vector<long> & data,const BinaryStream & bstream,unsigned long & iterator)303 O3DGCErrorCode LoadBinData(Vector<long> & data, 304 const BinaryStream & bstream, 305 unsigned long & iterator) 306 { 307 bstream.ReadUInt32ASCII(iterator); 308 const unsigned long size = bstream.ReadUInt32ASCII(iterator); 309 long symbol; 310 data.Allocate(size * O3DGC_BINARY_STREAM_BITS_PER_SYMBOL0); 311 data.Clear(); 312 for(unsigned long i = 0; i < size;) 313 { 314 symbol = bstream.ReadUCharASCII(iterator); 315 for(unsigned long h = 0; h < O3DGC_BINARY_STREAM_BITS_PER_SYMBOL0; ++h) 316 { 317 data.PushBack(symbol & 1); 318 symbol >>= 1; 319 ++i; 320 } 321 } 322 return O3DGC_OK; 323 } LoadUIntAC(Vector<long> & data,const unsigned long M,const BinaryStream & bstream,unsigned long & iterator)324 O3DGCErrorCode LoadUIntAC(Vector<long> & data, 325 const unsigned long M, 326 const BinaryStream & bstream, 327 unsigned long & iterator) 328 { 329 unsigned long sizeSize = bstream.ReadUInt32Bin(iterator) - 12; 330 unsigned long size = bstream.ReadUInt32Bin(iterator); 331 if (size == 0) 332 { 333 return O3DGC_OK; 334 } 335 long minValue = bstream.ReadUInt32Bin(iterator); 336 unsigned char * buffer = 0; 337 bstream.GetBuffer(iterator, buffer); 338 iterator += sizeSize; 339 data.Allocate(size); 340 Arithmetic_Codec acd; 341 acd.set_buffer(sizeSize, buffer); 342 acd.start_decoder(); 343 Adaptive_Data_Model mModelValues(M+1); 344 #ifdef DEBUG_VERBOSE 345 printf("-----------\nsize %i\n", size); 346 fprintf(g_fileDebugTF, "size %i\n", size); 347 #endif //DEBUG_VERBOSE 348 for(unsigned long i = 0; i < size; ++i) 349 { 350 data.PushBack(acd.decode(mModelValues)+minValue); 351 #ifdef DEBUG_VERBOSE 352 printf("%i\t%i\n", i, data[i]); 353 fprintf(g_fileDebugTF, "%i\t%i\n", i, data[i]); 354 #endif //DEBUG_VERBOSE 355 } 356 return O3DGC_OK; 357 } LoadIntACEGC(Vector<long> & data,const unsigned long M,const BinaryStream & bstream,unsigned long & iterator)358 O3DGCErrorCode LoadIntACEGC(Vector<long> & data, 359 const unsigned long M, 360 const BinaryStream & bstream, 361 unsigned long & iterator) 362 { 363 unsigned long sizeSize = bstream.ReadUInt32Bin(iterator) - 12; 364 unsigned long size = bstream.ReadUInt32Bin(iterator); 365 if (size == 0) 366 { 367 return O3DGC_OK; 368 } 369 long minValue = bstream.ReadUInt32Bin(iterator) - O3DGC_MAX_LONG; 370 unsigned char * buffer = 0; 371 bstream.GetBuffer(iterator, buffer); 372 iterator += sizeSize; 373 data.Allocate(size); 374 Arithmetic_Codec acd; 375 acd.set_buffer(sizeSize, buffer); 376 acd.start_decoder(); 377 Adaptive_Data_Model mModelValues(M+2); 378 Static_Bit_Model bModel0; 379 Adaptive_Bit_Model bModel1; 380 unsigned long value; 381 382 #ifdef DEBUG_VERBOSE 383 printf("-----------\nsize %i\n", size); 384 fprintf(g_fileDebugTF, "size %i\n", size); 385 #endif //DEBUG_VERBOSE 386 for(unsigned long i = 0; i < size; ++i) 387 { 388 value = acd.decode(mModelValues); 389 if ( value == M) 390 { 391 value += acd.ExpGolombDecode(0, bModel0, bModel1); 392 } 393 data.PushBack(value + minValue); 394 #ifdef DEBUG_VERBOSE 395 printf("%i\t%i\n", i, data[i]); 396 fprintf(g_fileDebugTF, "%i\t%i\n", i, data[i]); 397 #endif //DEBUG_VERBOSE 398 } 399 #ifdef DEBUG_VERBOSE 400 fflush(g_fileDebugTF); 401 #endif //DEBUG_VERBOSE 402 return O3DGC_OK; 403 } LoadBinAC(Vector<long> & data,const BinaryStream & bstream,unsigned long & iterator)404 O3DGCErrorCode LoadBinAC(Vector<long> & data, 405 const BinaryStream & bstream, 406 unsigned long & iterator) 407 { 408 unsigned long sizeSize = bstream.ReadUInt32Bin(iterator) - 8; 409 unsigned long size = bstream.ReadUInt32Bin(iterator); 410 if (size == 0) 411 { 412 return O3DGC_OK; 413 } 414 unsigned char * buffer = 0; 415 bstream.GetBuffer(iterator, buffer); 416 iterator += sizeSize; 417 data.Allocate(size); 418 Arithmetic_Codec acd; 419 acd.set_buffer(sizeSize, buffer); 420 acd.start_decoder(); 421 Adaptive_Bit_Model bModel; 422 #ifdef DEBUG_VERBOSE 423 printf("-----------\nsize %i\n", size); 424 fprintf(g_fileDebugTF, "size %i\n", size); 425 #endif //DEBUG_VERBOSE 426 for(unsigned long i = 0; i < size; ++i) 427 { 428 data.PushBack(acd.decode(bModel)); 429 #ifdef DEBUG_VERBOSE 430 printf("%i\t%i\n", i, data[i]); 431 fprintf(g_fileDebugTF, "%i\t%i\n", i, data[i]); 432 #endif //DEBUG_VERBOSE 433 } 434 return O3DGC_OK; 435 } Load(const BinaryStream & bstream,unsigned long & iterator,bool decodeTrianglesOrder,O3DGCStreamType streamType)436 O3DGCErrorCode CompressedTriangleFans::Load(const BinaryStream & bstream, 437 unsigned long & iterator, 438 bool decodeTrianglesOrder, 439 O3DGCStreamType streamType) 440 { 441 #ifdef DEBUG_VERBOSE 442 g_fileDebugTF = fopen("Load_new.txt", "w"); 443 #endif //DEBUG_VERBOSE 444 if (streamType == O3DGC_STREAM_TYPE_ASCII) 445 { 446 LoadUIntData(m_numTFANs , bstream, iterator); 447 LoadUIntData(m_degrees , bstream, iterator); 448 LoadUIntData(m_configs , bstream, iterator); 449 LoadBinData (m_operations, bstream, iterator); 450 LoadIntData (m_indices , bstream, iterator); 451 if (decodeTrianglesOrder) 452 { 453 LoadUIntData(m_trianglesOrder , bstream, iterator); 454 } 455 } 456 else 457 { 458 LoadIntACEGC(m_numTFANs , 4 , bstream, iterator); 459 LoadIntACEGC(m_degrees , 16, bstream, iterator); 460 LoadUIntAC (m_configs , 10, bstream, iterator); 461 LoadBinAC (m_operations, bstream, iterator); 462 LoadIntACEGC(m_indices , 8 , bstream, iterator); 463 if (decodeTrianglesOrder) 464 { 465 LoadIntACEGC(m_trianglesOrder , 16, bstream, iterator); 466 } 467 } 468 469 #ifdef DEBUG_VERBOSE 470 fclose(g_fileDebugTF); 471 #endif //DEBUG_VERBOSE 472 return O3DGC_OK; 473 } 474 } 475 476