LCOV - code coverage report
Current view: top level - third_party/LercLib - BitStuffer2.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 251 284 88.4 %
Date: 2024-11-21 22:18:42 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /*
       2             : Copyright 2015 Esri
       3             : 
       4             : Licensed under the Apache License, Version 2.0 (the "License");
       5             : you may not use this file except in compliance with the License.
       6             : You may obtain a copy of the License at
       7             : 
       8             : http://www.apache.org/licenses/LICENSE-2.0
       9             : 
      10             : Unless required by applicable law or agreed to in writing, software
      11             : distributed under the License is distributed on an "AS IS" BASIS,
      12             : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      13             : See the License for the specific language governing permissions and
      14             : limitations under the License.
      15             : 
      16             : A local copy of the license and additional notices are located with the
      17             : source distribution at:
      18             : 
      19             : http://github.com/Esri/lerc/
      20             : 
      21             : Contributors:  Thomas Maurer
      22             : */
      23             : 
      24             : #include <algorithm>
      25             : #include <cassert>
      26             : #include "Defines.h"
      27             : #include "BitStuffer2.h"
      28             : 
      29             : using namespace std;
      30             : USING_NAMESPACE_LERC
      31             : 
      32             : // -------------------------------------------------------------------------- ;
      33             : 
      34             : // if you change Encode(...) / Decode(...), don't forget to update ComputeNumBytesNeeded(...)
      35             : 
      36       42549 : bool BitStuffer2::EncodeSimple(Byte** ppByte, const vector<unsigned int>& dataVec, int lerc2Version) const
      37             : {
      38       42549 :   if (!ppByte || dataVec.empty())
      39           0 :     return false;
      40             : 
      41       42549 :   unsigned int maxElem = *max_element(dataVec.begin(), dataVec.end());
      42       42549 :   int numBits = 0;
      43      150067 :   while ((numBits < 32) && (maxElem >> numBits))
      44      107518 :     numBits++;
      45             : 
      46       42549 :   if (numBits >= 32)
      47           0 :     return false;
      48             : 
      49       42549 :   Byte numBitsByte = (Byte)numBits;
      50       42549 :   unsigned int numElements = (unsigned int)dataVec.size();
      51       42549 :   unsigned int numUInts = (numElements * numBits + 31) / 32;
      52             : 
      53             :   // use the upper 2 bits to encode the type used for numElements: Byte, ushort, or uint
      54       42549 :   int n = NumBytesUInt(numElements);
      55       42549 :   int bits67 = (n == 4) ? 0 : 3 - n;
      56       42549 :   numBitsByte |= bits67 << 6;
      57             : 
      58             :   // bit5 = 0 means simple mode
      59             : 
      60       42549 :   **ppByte = numBitsByte;
      61       42549 :   (*ppByte)++;
      62             : 
      63       42549 :   if (!EncodeUInt(ppByte, numElements, n))
      64           0 :     return false;
      65             : 
      66       42549 :   if (numUInts > 0)    // numBits can be 0, then we only write the header
      67             :   {
      68       42549 :     if (lerc2Version >= 3)
      69       18287 :       BitStuff(ppByte, dataVec, numBits);
      70             :     else
      71       24262 :       BitStuff_Before_Lerc2v3(ppByte, dataVec, numBits);
      72             :   }
      73             : 
      74       42549 :   return true;
      75             : }
      76             : 
      77             : // -------------------------------------------------------------------------- ;
      78             : 
      79      220916 : bool BitStuffer2::EncodeLut(Byte** ppByte, const vector<pair<unsigned int, unsigned int> >& sortedDataVec, int lerc2Version) const
      80             : {
      81      220916 :   if (!ppByte || sortedDataVec.empty())
      82           0 :     return false;
      83             : 
      84      220916 :   if (sortedDataVec[0].first != 0)    // corresponds to min
      85           0 :     return false;
      86             : 
      87             :   // collect the different values for the lut
      88      220916 :   unsigned int numElem = (unsigned int)sortedDataVec.size();
      89      220916 :   unsigned int indexLut = 0;
      90             : 
      91      220916 :   m_tmpLutVec.resize(0);    // omit the 0 throughout that corresponds to min
      92      220916 :   m_tmpIndexVec.assign(numElem, 0);
      93             : 
      94    14708400 :   for (unsigned int i = 1; i < numElem; i++)
      95             :   {
      96    14487500 :     unsigned int prev = sortedDataVec[i - 1].first;
      97    14487500 :     m_tmpIndexVec[sortedDataVec[i - 1].second] = indexLut;
      98             : 
      99    14487500 :     if (sortedDataVec[i].first != prev)
     100             :     {
     101      320862 :       m_tmpLutVec.push_back(sortedDataVec[i].first);
     102      320862 :       indexLut++;
     103             :     }
     104             :   }
     105      220916 :   m_tmpIndexVec[sortedDataVec[numElem - 1].second] = indexLut;    // don't forget the last one
     106             : 
     107             :   // write first 2 data elements same as simple, but bit5 set to 1
     108      220916 :   unsigned int maxElem = m_tmpLutVec.back();
     109      220916 :   int numBits = 0;
     110     1182940 :   while ((numBits < 32) && (maxElem >> numBits))
     111      962025 :     numBits++;
     112             : 
     113      220916 :   if (numBits >= 32)
     114           0 :     return false;
     115             : 
     116      220916 :   Byte numBitsByte = (Byte)numBits;
     117             : 
     118             :   // use the upper 2 bits to encode the type used for numElem: byte, ushort, or uint
     119      220916 :   int n = NumBytesUInt(numElem);
     120      220916 :   int bits67 = (n == 4) ? 0 : 3 - n;
     121      220916 :   numBitsByte |= bits67 << 6;
     122             : 
     123      220916 :   numBitsByte |= (1 << 5);    // bit 5 = 1 means lut mode
     124             : 
     125      220916 :   **ppByte = numBitsByte;
     126      220916 :   (*ppByte)++;
     127             : 
     128      220916 :   if (!EncodeUInt(ppByte, numElem, n))    // numElements = numIndexes to lut
     129           0 :     return false;
     130             : 
     131      220916 :   unsigned int nLut = (unsigned int)m_tmpLutVec.size();
     132      220916 :   if (nLut < 1 || nLut >= 255)
     133           0 :     return false;
     134             : 
     135      220916 :   **ppByte = (Byte)nLut + 1;    // size of lut, incl the 0
     136      220916 :   (*ppByte)++;
     137             : 
     138      220916 :   if (lerc2Version >= 3)
     139        1112 :     BitStuff(ppByte, m_tmpLutVec, numBits);    // lut
     140             :   else
     141      219804 :     BitStuff_Before_Lerc2v3(ppByte, m_tmpLutVec, numBits);
     142             : 
     143      220916 :   int nBitsLut = 0;
     144      496289 :   while (nLut >> nBitsLut)    // indexes are in [0 .. nLut]
     145      275373 :     nBitsLut++;
     146             : 
     147      220916 :   if (lerc2Version >= 3)
     148        1112 :     BitStuff(ppByte, m_tmpIndexVec, nBitsLut);    // indexes
     149             :   else
     150      219804 :     BitStuff_Before_Lerc2v3(ppByte, m_tmpIndexVec, nBitsLut);
     151             : 
     152      220916 :   return true;
     153             : }
     154             : 
     155             : // -------------------------------------------------------------------------- ;
     156             : 
     157             : // if you change Encode(...) / Decode(...), don't forget to update ComputeNumBytesNeeded(...)
     158             : 
     159      113518 : bool BitStuffer2::Decode(const Byte** ppByte, size_t& nBytesRemaining, vector<unsigned int>& dataVec, size_t maxElementCount, int lerc2Version) const
     160             : {
     161      113518 :   if (!ppByte || nBytesRemaining < 1)
     162           0 :     return false;
     163             : 
     164      113518 :   Byte numBitsByte = **ppByte;
     165      113518 :   (*ppByte)++;
     166      113518 :   nBytesRemaining--;
     167             : 
     168      113518 :   int bits67 = numBitsByte >> 6;
     169      113518 :   int nb = (bits67 == 0) ? 4 : 3 - bits67;
     170             : 
     171      113518 :   bool doLut = (numBitsByte & (1 << 5)) ? true : false;    // bit 5
     172      113518 :   numBitsByte &= 31;    // bits 0-4;
     173      113518 :   int numBits = numBitsByte;
     174             : 
     175      113518 :   unsigned int numElements = 0;
     176      113518 :   if (!DecodeUInt(ppByte, nBytesRemaining, numElements, nb))
     177           0 :     return false;
     178      113518 :   if (numElements > maxElementCount)
     179           0 :     return false;
     180             : 
     181      113518 :   if (!doLut)
     182             :   {
     183       38554 :     if (numBits > 0)    // numBits can be 0
     184             :     {
     185       38554 :       if (lerc2Version >= 3)
     186             :       {
     187       30346 :         if (!BitUnStuff(ppByte, nBytesRemaining, dataVec, numElements, numBits))
     188           0 :           return false;
     189             :       }
     190             :       else
     191             :       {
     192        8208 :         if (!BitUnStuff_Before_Lerc2v3(ppByte, nBytesRemaining, dataVec, numElements, numBits))
     193           0 :           return false;
     194             :       }
     195             :     }
     196             :   }
     197             :   else
     198             :   {
     199       74964 :     if (numBits == 0)  // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum
     200           0 :       return false;
     201       74964 :     if (nBytesRemaining < 1)
     202           0 :       return false;
     203             : 
     204       74964 :     Byte nLutByte = **ppByte;
     205       74964 :     (*ppByte)++;
     206       74964 :     nBytesRemaining--;
     207             : 
     208       74964 :     int nLut = nLutByte - 1;
     209             : 
     210             :     // unstuff lut w/o the 0
     211       74964 :     if (lerc2Version >= 3)
     212             :     {
     213         982 :       if (!BitUnStuff(ppByte, nBytesRemaining, m_tmpLutVec, nLut, numBits))
     214           0 :         return false;
     215             :     }
     216             :     else
     217             :     {
     218       73982 :       if (!BitUnStuff_Before_Lerc2v3(ppByte, nBytesRemaining, m_tmpLutVec, nLut, numBits))
     219           0 :         return false;
     220             :     }
     221             : 
     222       74964 :     int nBitsLut = 0;
     223      169423 :     while (nLut >> nBitsLut)
     224       94459 :       nBitsLut++;
     225       74964 :     if (nBitsLut == 0)
     226           0 :       return false;
     227             : 
     228       74964 :     if (lerc2Version >= 3)
     229             :     {
     230             :       // unstuff indexes
     231         982 :       if (!BitUnStuff(ppByte, nBytesRemaining, dataVec, numElements, nBitsLut))
     232           0 :         return false;
     233             : 
     234             :       // replace indexes by values
     235             : #if defined(__GNUC__)
     236             : #pragma GCC diagnostic push
     237             : #pragma GCC diagnostic ignored "-Wnull-dereference"
     238             : #endif
     239         982 :       m_tmpLutVec.insert(m_tmpLutVec.begin(), 0);    // put back in the 0
     240             : #if defined(__GNUC__)
     241             : #pragma GCC diagnostic pop
     242             : #endif
     243       61462 :       for (unsigned int i = 0; i < numElements; i++)
     244             :       {
     245             : #ifdef GDAL_COMPILATION
     246       60480 :         if (dataVec[i] >= m_tmpLutVec.size())
     247           0 :           return false;
     248             : #endif
     249       60480 :         dataVec[i] = m_tmpLutVec[dataVec[i]];
     250             :       }
     251             :     }
     252             :     else
     253             :     {
     254             :       // unstuff indexes
     255       73982 :       if (!BitUnStuff_Before_Lerc2v3(ppByte, nBytesRemaining, dataVec, numElements, nBitsLut))
     256           0 :         return false;
     257             : 
     258             :       // replace indexes by values
     259             : #if defined(__GNUC__)
     260             : #pragma GCC diagnostic push
     261             : #pragma GCC diagnostic ignored "-Wnull-dereference"
     262             : #endif
     263       73982 :       m_tmpLutVec.insert(m_tmpLutVec.begin(), 0);    // put back in the 0
     264             : #if defined(__GNUC__)
     265             : #pragma GCC diagnostic pop
     266             : #endif
     267     4992960 :       for (unsigned int i = 0; i < numElements; i++)
     268             :       {
     269     4918980 :         if (dataVec[i] >= m_tmpLutVec.size())
     270           0 :           return false;
     271             : 
     272     4918980 :         dataVec[i] = m_tmpLutVec[dataVec[i]];
     273             :       }
     274             :     }
     275             :   }
     276             : 
     277      113518 :   return true;
     278             : }
     279             : 
     280             : // -------------------------------------------------------------------------- ;
     281             : 
     282      709569 : unsigned int BitStuffer2::ComputeNumBytesNeededLut(const vector<pair<unsigned int, unsigned int> >& sortedDataVec, bool& doLut)
     283             : {
     284      709569 :   unsigned int maxElem = sortedDataVec.back().first;
     285      709569 :   unsigned int numElem = (unsigned int)sortedDataVec.size();
     286             : 
     287      709569 :   int numBits = 0;
     288     3591790 :   while ((numBits < 32) && (maxElem >> numBits))
     289     2882220 :     numBits++;
     290      709569 :   unsigned int numBytes = 1 + NumBytesUInt(numElem) + ((numElem * numBits + 7) >> 3);
     291             : 
     292             :   // go through and count how often the value changes
     293      709569 :   int nLut = 0;
     294    71172000 :   for (unsigned int i = 1; i < numElem; i++)
     295    70462500 :     if (sortedDataVec[i].first != sortedDataVec[i - 1].first)
     296     1145300 :       nLut++;
     297             : 
     298      709569 :   int nBitsLut = 0;
     299     1655040 :   while (nLut >> nBitsLut)
     300      945475 :     nBitsLut++;
     301             : 
     302      709569 :   unsigned int numBitsTotalLut = nLut * numBits;    // num bits w/o the 0
     303      709569 :   unsigned int numBytesLut = 1 + NumBytesUInt(numElem) + 1 + ((numBitsTotalLut + 7) >> 3) + ((numElem * nBitsLut + 7) >> 3);
     304             : 
     305      709569 :   doLut = numBytesLut < numBytes;
     306      709569 :   return min(numBytesLut, numBytes);
     307             : }
     308             : 
     309             : // -------------------------------------------------------------------------- ;
     310             : // -------------------------------------------------------------------------- ;
     311             : 
     312      463870 : void BitStuffer2::BitStuff_Before_Lerc2v3(Byte** ppByte, const vector<unsigned int>& dataVec, int numBits)
     313             : {
     314      463870 :   unsigned int numElements = (unsigned int)dataVec.size();
     315      463870 :   unsigned int numUInts = (numElements * numBits + 31) / 32;
     316      463870 :   unsigned int numBytes = numUInts * sizeof(unsigned int);
     317      463870 :   unsigned int* arr = (unsigned int*)(*ppByte);
     318             : 
     319      463870 :   memset(arr, 0, numBytes);
     320             : 
     321             :   // do the stuffing
     322      463870 :   const unsigned int* srcPtr = &dataVec[0];
     323      463870 :   unsigned int* dstPtr = arr;
     324      463870 :   int bitPos = 0;
     325             : 
     326    17363600 :   for (unsigned int i = 0; i < numElements; i++)
     327             :   {
     328    16899800 :     if (32 - bitPos >= numBits)
     329             :     {
     330             :       unsigned int dstValue;
     331    16897100 :       memcpy(&dstValue, dstPtr, sizeof(unsigned int));
     332    16897100 :       dstValue |= (*srcPtr++) << (32 - bitPos - numBits);
     333    16897100 :       memcpy(dstPtr, &dstValue, sizeof(unsigned int));
     334    16897100 :       bitPos += numBits;
     335    16897100 :       if (bitPos == 32)    // shift >= 32 is undefined
     336             :       {
     337      641691 :         bitPos = 0;
     338      641691 :         dstPtr++;
     339             :       }
     340             :     }
     341             :     else
     342             :     {
     343             :       unsigned int dstValue;
     344        2634 :       int n = numBits - (32 - bitPos);
     345        2634 :       memcpy(&dstValue, dstPtr, sizeof(unsigned int));
     346        2634 :       dstValue |= (*srcPtr) >> n;
     347        2634 :       memcpy(dstPtr, &dstValue, sizeof(unsigned int));
     348        2634 :       dstPtr++;
     349        2634 :       memcpy(&dstValue, dstPtr, sizeof(unsigned int));
     350        2634 :       dstValue |= (*srcPtr++) << (32 - n);
     351        2634 :       memcpy(dstPtr, &dstValue, sizeof(unsigned int));
     352        2634 :       bitPos = n;
     353             :     }
     354             :   }
     355             : 
     356             :   // save the 0-3 bytes not used in the last UInt
     357      463870 :   unsigned int numBytesNotNeeded = NumTailBytesNotNeeded(numElements, numBits);
     358      463870 :   unsigned int n = numBytesNotNeeded;
     359     1060330 :   for (; n; --n)
     360             :   {
     361             :     unsigned int dstValue;
     362      596462 :     memcpy(&dstValue, dstPtr, sizeof(unsigned int));
     363      596462 :     dstValue >>= 8;
     364      596462 :     memcpy(dstPtr, &dstValue, sizeof(unsigned int));
     365             :   }
     366             : 
     367      463870 :   *ppByte += numBytes - numBytesNotNeeded;
     368      463870 : }
     369             : 
     370             : // -------------------------------------------------------------------------- ;
     371             : 
     372      156172 : bool BitStuffer2::BitUnStuff_Before_Lerc2v3(const Byte** ppByte, size_t& nBytesRemaining,
     373             :     vector<unsigned int>& dataVec, unsigned int numElements, int numBits) const
     374             : {
     375      156172 :   if (numElements == 0 || numBits >= 32)
     376           0 :     return false;
     377      156172 :   unsigned long long numUIntsLL = ((unsigned long long)numElements * numBits + 31) / 32;
     378      156172 :   unsigned long long numBytesLL = numUIntsLL * sizeof(unsigned int);
     379      156172 :   size_t numBytes = (size_t)numBytesLL; // could theoretically overflow on 32 bit system
     380      156172 :   size_t numUInts = (size_t)numUIntsLL;
     381      156172 :   unsigned int ntbnn = NumTailBytesNotNeeded(numElements, numBits);
     382      156172 :   if (numBytes != numBytesLL || nBytesRemaining + ntbnn < numBytes)
     383           0 :     return false;
     384             : 
     385             :   try
     386             :   {
     387      156172 :     dataVec.resize(numElements, 0);    // init with 0
     388      156172 :     m_tmpBitStuffVec.resize(numUInts);
     389             :   }
     390           0 :   catch( const std::exception& )
     391             :   {
     392           0 :     return false;
     393             :   }
     394             : 
     395      156172 :   m_tmpBitStuffVec[numUInts - 1] = 0;    // set last uint to 0
     396             : 
     397      156172 :   unsigned int nBytesToCopy = (numElements * numBits + 7) / 8;
     398      156172 :   memcpy(&m_tmpBitStuffVec[0], *ppByte, nBytesToCopy);
     399             : 
     400      156172 :   unsigned int* pLastULong = &m_tmpBitStuffVec[numUInts - 1];
     401      356374 :   while (ntbnn)
     402             :   {
     403      200202 :     -- ntbnn;
     404      200202 :     *pLastULong <<= 8;
     405             :   }
     406             : 
     407      156172 :   unsigned int* srcPtr = &m_tmpBitStuffVec[0];
     408      156172 :   unsigned int* dstPtr = &dataVec[0];
     409      156172 :   int bitPos = 0;
     410             : 
     411     5855250 :   for (unsigned int i = 0; i < numElements; i++)
     412             :   {
     413     5699080 :     if (32 - bitPos >= numBits)
     414             :     {
     415             :       unsigned int val;
     416     5697570 :       memcpy(&val, srcPtr, sizeof(unsigned int));
     417     5697570 :       unsigned int n = val << bitPos;
     418     5697570 :       *dstPtr++ = n >> (32 - numBits);
     419     5697570 :       bitPos += numBits;
     420             : 
     421     5697570 :       if (bitPos == 32)    // shift >= 32 is undefined
     422             :       {
     423      216619 :         bitPos = 0;
     424      216619 :         srcPtr++;
     425             :       }
     426             :     }
     427             :     else
     428             :     {
     429             :       unsigned int val;
     430        1511 :       memcpy(&val, srcPtr, sizeof(unsigned int));
     431        1511 :       srcPtr++;
     432        1511 :       unsigned int n = val << bitPos;
     433        1511 :       *dstPtr = n >> (32 - numBits);
     434        1511 :       bitPos -= (32 - numBits);
     435        1511 :       memcpy(&val, srcPtr, sizeof(unsigned int));
     436        1511 :       *dstPtr++ |= val >> (32 - bitPos);
     437             :     }
     438             :   }
     439             : 
     440      156172 :   *ppByte += nBytesToCopy;
     441      156172 :   nBytesRemaining -= nBytesToCopy;
     442             : 
     443      156172 :   return true;
     444             : }
     445             : 
     446             : // -------------------------------------------------------------------------- ;
     447             : 
     448             : // starting with version Lerc2v3: integer >> into local uint buffer, plus final memcpy
     449             : 
     450       20511 : void BitStuffer2::BitStuff(Byte** ppByte, const vector<unsigned int>& dataVec, int numBits) const
     451             : {
     452       20511 :   unsigned int numElements = (unsigned int)dataVec.size();
     453       20511 :   unsigned int numUInts = (numElements * numBits + 31) / 32;
     454       20511 :   unsigned int numBytes = numUInts * sizeof(unsigned int);
     455             : 
     456       20511 :   m_tmpBitStuffVec.resize(numUInts);
     457       20511 :   unsigned int* dstPtr = &m_tmpBitStuffVec[0];
     458             : 
     459       20511 :   memset(dstPtr, 0, numBytes);
     460             : 
     461             :   // do the stuffing
     462       20511 :   const unsigned int* srcPtr = &dataVec[0];
     463       20511 :   int bitPos = 0;
     464       20511 :   assert(numBits <= 32); // to avoid coverity warning about large shift a bit later, when doing (*srcPtr++) >> (32 - bitPos)
     465             : 
     466     1354360 :   for (unsigned int i = 0; i < numElements; i++)
     467             :   {
     468     1333840 :     if (32 - bitPos >= numBits)
     469             :     {
     470     1253960 :       *dstPtr |= (*srcPtr++) << bitPos;
     471     1253960 :       bitPos += numBits;
     472     1253960 :       if (bitPos == 32)    // shift >= 32 is undefined
     473             :       {
     474       97956 :         dstPtr++;
     475       97956 :         bitPos = 0;
     476             :       }
     477             :     }
     478             :     else
     479             :     {
     480       79880 :       *dstPtr++ |= (*srcPtr) << bitPos;
     481       79880 :       *dstPtr |= (*srcPtr++) >> (32 - bitPos);
     482       79880 :       bitPos += numBits - 32;
     483             :     }
     484             :   }
     485             : 
     486             :   // copy the bytes to the outgoing byte stream
     487       20511 :   size_t numBytesUsed = numBytes - NumTailBytesNotNeeded(numElements, numBits);
     488             : #ifdef CSA_BUILD
     489             :   assert( numElements );
     490             : #endif
     491       20511 :   memcpy(*ppByte, m_tmpBitStuffVec.data(), numBytesUsed);
     492             : 
     493       20511 :   *ppByte += numBytesUsed;
     494       20511 : }
     495             : 
     496             : // -------------------------------------------------------------------------- ;
     497             : 
     498       32310 : bool BitStuffer2::BitUnStuff(const Byte** ppByte, size_t& nBytesRemaining, vector<unsigned int>& dataVec,
     499             :   unsigned int numElements, int numBits) const
     500             : {
     501       32310 :   if (numElements == 0 || numBits >= 32)
     502           0 :     return false;
     503       32310 :   unsigned long long numUIntsLL = ((unsigned long long)numElements * numBits + 31) / 32;
     504       32310 :   unsigned long long numBytesLL = numUIntsLL * sizeof(unsigned int);
     505       32310 :   size_t numBytes = (size_t)numBytesLL; // could theoretically overflow on 32 bit system
     506       32310 :   if (numBytes != numBytesLL)
     507           0 :     return false;
     508       32310 :   size_t numUInts = (size_t)numUIntsLL;
     509             : 
     510             :   // copy the bytes from the incoming byte stream
     511       32310 :   const size_t numBytesUsed = numBytes - NumTailBytesNotNeeded(numElements, numBits);
     512             : 
     513       32310 :   if (nBytesRemaining < numBytesUsed)
     514           0 :     return false;
     515             : 
     516             :   try
     517             :   {
     518       32310 :     dataVec.resize(numElements);
     519             :   }
     520           0 :   catch( const std::exception& )
     521             :   {
     522           0 :     return false;
     523             :   }
     524             : 
     525             :   try
     526             :   {
     527       32310 :     m_tmpBitStuffVec.resize(numUInts);
     528             :   }
     529           0 :   catch( const std::exception& )
     530             :   {
     531           0 :     return false;
     532             :   }
     533             : 
     534       32310 :   m_tmpBitStuffVec[numUInts - 1] = 0;    // set last uint to 0
     535             : 
     536       32310 :   memcpy(&m_tmpBitStuffVec[0], *ppByte, numBytesUsed);
     537             : 
     538             :   // do the un-stuffing
     539       32310 :   unsigned int* srcPtr = &m_tmpBitStuffVec[0];
     540       32310 :   unsigned int* dstPtr = &dataVec[0];
     541       32310 :   int bitPos = 0;
     542       32310 :   int nb = 32 - numBits;
     543             : 
     544     2089430 :   for (unsigned int i = 0; i < numElements; i++)
     545             :   {
     546     2057120 :     if (nb - bitPos >= 0)
     547             :     {
     548     1948520 :       *dstPtr++ = ((*srcPtr) << (nb - bitPos)) >> nb;
     549     1948520 :       bitPos += numBits;
     550     1948520 :       if (bitPos == 32)    // shift >= 32 is undefined
     551             :       {
     552      159164 :         srcPtr++;
     553      159164 :         bitPos = 0;
     554             :       }
     555             :     }
     556             :     else
     557             :     {
     558      108600 :       *dstPtr = (*srcPtr++) >> bitPos;
     559      108600 :       *dstPtr++ |= ((*srcPtr) << (64 - numBits - bitPos)) >> nb;
     560      108600 :       bitPos -= nb;
     561             :     }
     562             :   }
     563             : 
     564       32310 :   *ppByte += numBytesUsed;
     565       32310 :   nBytesRemaining -= numBytesUsed;
     566       32310 :   return true;
     567             : }
     568             : 
     569             : // -------------------------------------------------------------------------- ;
     570             : 

Generated by: LCOV version 1.14