/[svn]/libgig/trunk/src/gig.cpp
ViewVC logotype

Diff of /libgig/trunk/src/gig.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1358 by schoenebeck, Sun Sep 30 18:13:33 2007 UTC revision 1381 by schoenebeck, Thu Oct 4 18:57:10 2007 UTC
# Line 255  namespace { Line 255  namespace {
255    
256    
257    
258    // *************** Internal CRC-32 (Cyclic Redundancy Check) functions  ***************
259    // *
260    
261        static uint32_t* __initCRCTable() {
262            static uint32_t res[256];
263    
264            for (int i = 0 ; i < 256 ; i++) {
265                uint32_t c = i;
266                for (int j = 0 ; j < 8 ; j++) {
267                    c = (c & 1) ? 0xedb88320 ^ (c >> 1) : c >> 1;
268                }
269                res[i] = c;
270            }
271            return res;
272        }
273    
274        static const uint32_t* __CRCTable = __initCRCTable();
275    
276        /**
277         * Initialize a CRC variable.
278         *
279         * @param crc - variable to be initialized
280         */
281        inline static void __resetCRC(uint32_t& crc) {
282            crc = 0xffffffff;
283        }
284    
285        /**
286         * Used to calculate checksums of the sample data in a gig file. The
287         * checksums are stored in the 3crc chunk of the gig file and
288         * automatically updated when a sample is written with Sample::Write().
289         *
290         * One should call __resetCRC() to initialize the CRC variable to be
291         * used before calling this function the first time.
292         *
293         * After initializing the CRC variable one can call this function
294         * arbitrary times, i.e. to split the overall CRC calculation into
295         * steps.
296         *
297         * Once the whole data was processed by __calculateCRC(), one should
298         * call __encodeCRC() to get the final CRC result.
299         *
300         * @param buf     - pointer to data the CRC shall be calculated of
301         * @param bufSize - size of the data to be processed
302         * @param crc     - variable the CRC sum shall be stored to
303         */
304        static void __calculateCRC(unsigned char* buf, int bufSize, uint32_t& crc) {
305            for (int i = 0 ; i < bufSize ; i++) {
306                crc = __CRCTable[(crc ^ buf[i]) & 0xff] ^ (crc >> 8);
307            }
308        }
309    
310        /**
311         * Returns the final CRC result.
312         *
313         * @param crc - variable previously passed to __calculateCRC()
314         */
315        inline static uint32_t __encodeCRC(const uint32_t& crc) {
316            return crc ^ 0xffffffff;
317        }
318    
319    
320    
321  // *************** Other Internal functions  ***************  // *************** Other Internal functions  ***************
322  // *  // *
323    
# Line 278  namespace { Line 341  namespace {
341    
342    
343    
 // *************** CRC ***************  
 // *  
   
     const uint32_t* CRC::table(initTable());  
   
     uint32_t* CRC::initTable() {  
         uint32_t* res = new uint32_t[256];  
   
         for (int i = 0 ; i < 256 ; i++) {  
             uint32_t c = i;  
             for (int j = 0 ; j < 8 ; j++) {  
                 c = (c & 1) ? 0xedb88320 ^ (c >> 1) : c >> 1;  
             }  
             res[i] = c;  
         }  
         return res;  
     }  
   
   
   
344  // *************** Sample ***************  // *************** Sample ***************
345  // *  // *
346    
# Line 331  namespace { Line 374  namespace {
374          Instances++;          Instances++;
375          FileNo = fileNo;          FileNo = fileNo;
376    
377            __resetCRC(crc);
378    
379          pCk3gix = waveList->GetSubChunk(CHUNK_ID_3GIX);          pCk3gix = waveList->GetSubChunk(CHUNK_ID_3GIX);
380          if (pCk3gix) {          if (pCk3gix) {
381              uint16_t iSampleGroup = pCk3gix->ReadInt16();              uint16_t iSampleGroup = pCk3gix->ReadInt16();
# Line 1168  namespace { Line 1213  namespace {
1213          // if this is the first write in this sample, reset the          // if this is the first write in this sample, reset the
1214          // checksum calculator          // checksum calculator
1215          if (pCkData->GetPos() == 0) {          if (pCkData->GetPos() == 0) {
1216              crc.reset();              __resetCRC(crc);
1217          }          }
1218          if (GetSize() < SampleCount) throw Exception("Could not write sample data, current sample size to small");          if (GetSize() < SampleCount) throw Exception("Could not write sample data, current sample size to small");
1219          unsigned long res;          unsigned long res;
# Line 1178  namespace { Line 1223  namespace {
1223              res = Channels == 2 ? pCkData->Write(pBuffer, SampleCount << 1, 2) >> 1              res = Channels == 2 ? pCkData->Write(pBuffer, SampleCount << 1, 2) >> 1
1224                                  : pCkData->Write(pBuffer, SampleCount, 2);                                  : pCkData->Write(pBuffer, SampleCount, 2);
1225          }          }
1226          crc.update((unsigned char *)pBuffer, SampleCount * FrameSize);          __calculateCRC((unsigned char *)pBuffer, SampleCount * FrameSize, crc);
1227    
1228          // if this is the last write, update the checksum chunk in the          // if this is the last write, update the checksum chunk in the
1229          // file          // file
1230          if (pCkData->GetPos() == pCkData->GetSize()) {          if (pCkData->GetPos() == pCkData->GetSize()) {
1231              File* pFile = static_cast<File*>(GetParent());              File* pFile = static_cast<File*>(GetParent());
1232              pFile->SetSampleChecksum(this, crc.getValue());              pFile->SetSampleChecksum(this, __encodeCRC(crc));
1233          }          }
1234          return res;          return res;
1235      }      }

Legend:
Removed from v.1358  
changed lines
  Added in v.1381

  ViewVC Help
Powered by ViewVC