title: Base64 image file encoding with C++
body: <p>I am writing some simple code to encode files to base64. I have a short c++ code that reads a file into a vector and converts it to unsigned char*. I do this so I can properly use the encoding function I got.</p>
  
  <p>The problem: It works with text files (of different sizes), but it won't work with image files. And I can't figure it out why. What gives?</p>
  
  <p>For an simple <code>text.txt</code> containing the text <code>abcd</code>, the output for both my code and a bash <code>$( base64 text.txt )</code> is the same.</p>
  
  <p>On the other hand, when I input an image the output is something like <code>iVBORwOKGgoAAAAAAA......AAA==</code> or sometimes it ends with an <code>corrupted size vs prev_size Aborted (core dumped)</code>, the first few bytes are correct.</p>
  
  <p>The code:</p>
  
  <pre><code>static std::vector&lt;char&gt; readBytes(char const* filename)
  {
      std::ifstream ifs(filename, std::ios::binary|std::ios::ate);
      std::ifstream::pos_type pos = ifs.tellg();
      std::vector&lt;char&gt; result(pos);
      ifs.seekg(0, std::ios::beg);
      ifs.read(&amp;result[0], pos);
  
      return result;
  }
  
  static char Base64Digits[] =
   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  
  int ToBase64Simple( const BYTE* pSrc, int nLenSrc, char* pDst, int nLenDst )
  {
     int nLenOut= 0;
     while ( nLenSrc &gt; 0 ) {
  
        if (nLenOut+4 &gt; nLenDst) {
        cout &lt;&lt; "error\n";
        return(0); // error
        }
  
        // read three source bytes (24 bits)
        BYTE s1= pSrc[0];   // (but avoid reading past the end)
        BYTE s2= 0; if (nLenSrc&gt;1) s2=pSrc[1]; //------ corrected, thanks to  jprichey
        BYTE s3= 0; if (nLenSrc&gt;2) s3=pSrc[2];
  
        DWORD n;
        n =  s1;    // xxx1
        n &lt;&lt;= 8;    // xx1x
        n |= s2;    // xx12
        n &lt;&lt;= 8;    // x12x
        n |= s3;    // x123
  
        //-------------- get four 6-bit values for lookups
        BYTE m4= n &amp; 0x3f;  n &gt;&gt;= 6;
        BYTE m3= n &amp; 0x3f;  n &gt;&gt;= 6;
        BYTE m2= n &amp; 0x3f;  n &gt;&gt;= 6;
        BYTE m1= n &amp; 0x3f;
  
        //------------------ lookup the right digits for output
        BYTE b1 = Base64Digits[m1];
        BYTE b2 = Base64Digits[m2];
        BYTE b3 = Base64Digits[m3];
        BYTE b4 = Base64Digits[m4];
  
        //--------- end of input handling
        *pDst++ = b1;
        *pDst++ = b2;
        if ( nLenSrc &gt;= 3 ) {  // 24 src bits left to encode, output xxxx
           *pDst++ = b3;
           *pDst++ = b4;
        }
        if ( nLenSrc == 2 ) {  // 16 src bits left to encode, output xxx=
           *pDst++ = b3;
           *pDst++ = '=';
           }
        if ( nLenSrc == 1 ) {  // 8 src bits left to encode, output xx==
           *pDst++ = '=';
           *pDst++ = '=';
        }
        pSrc    += 3;
        nLenSrc -= 3;
        nLenOut += 4;
     }
     // Could optionally append a NULL byte like so:
     *pDst++= 0; nLenOut++;
     return( nLenOut );
  }
  
  int main(int argc, char* argv[])
  {
      std::vector&lt;char&gt; mymsg;
      mymsg = readBytes(argv[1]);
      char* arr = &amp;mymsg[0];
      int len = mymsg.size();
      int lendst = ((len+2)/3)*4;
      unsigned char* uarr = (unsigned char *) malloc(len*sizeof(unsigned char));
      char* dst = (char *) malloc(lendst*sizeof(char));;
      mymsg.clear(); //free()
  
      // convert to unsigned char
      strncpy((char*)uarr, arr, len);
  
      int lenOut = ToBase64Simple(uarr, len, dst, lendst);
      free(uarr);
  
      int cont = 0;
      while (cont &lt; lenOut) //(dst[cont] != 0)
          cout &lt;&lt; dst[cont++];
      cout &lt;&lt; "\n";
  }
  </code></pre>
  
  <p>Any insight is welcomed.</p>