title: Compressing a 'char' array using bit packing in C
body: <p>I have a large array (around 1 MB) of type <code>unsigned char</code> (i.e. <code>uint8_t</code>). I know that the bytes in it can have only one of 5 values (i.e. 0, 1, 2, 3, 4). Moreover we do not need to preserve '3's from the input, they can be safely lost when we encode/decode.</p>
  
  <p>So I guessed bit packing would be the simplest way to compress it, so every byte can be converted to 2 bits (<code>00</code>, <code>01</code>..., <code>11</code>). </p>
  
  <p>As mentioned all elements of value 3 can be removed (i.e. saved as 0). Which gives me option to save '4' as '3'. While reconstructing (decompressing) I restore 3's to 4's.</p>
  
  <p>I wrote a small function for the compression but I feel this has too many operations and just not efficient enough. Any code snippets or suggestion on how to make it more efficient or faster (hopefully keeping the readability) will be very much helpful.</p>
  
  <pre><code>/// Compress by packing ...
  void compressByPacking (uint8_t* out, uint8_t* in, uint32_t length)
  {
      for (int loop = 0; loop &lt; length/4; loop ++, in += 4, out++)
      {
        uint8_t temp[4];
  
        for (int small_loop = 0; small_loop &lt; 4; small_loop++)
        {
          temp[small_loop] = *in;           // Load into local variable
  
          if (temp[small_loop] == 3)        // 3's are discarded
            temp[small_loop] = 0;
          else if (temp[small_loop] == 4)   // and 4's are converted to 3
            temp[small_loop] = 3;
  
        } // end small loop
  
        // Pack the bits into write pointer
        *out = (uint8_t)((temp[0] &amp; 0x03) &lt;&lt; 6) |
                        ((temp[1] &amp; 0x03) &lt;&lt; 4) |
                        ((temp[2] &amp; 0x03) &lt;&lt; 2) |
                        ((temp[3] &amp; 0x03));
  
      } // end loop
   }
  </code></pre>
  
  <ul>
  <li>Edited to make the problem more clear as it looked like I'm trying to save 5 values into 2 bits. Thanks to @Brian Cain for suggested wording.</li>
  <li><a href="https://codereview.stackexchange.com/questions/169596/compressing-a-char-array-using-bit-packing-using-c">Cross-posted on Code Review.</a></li>
  </ul>