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