title: Restore MP3 file from binary data
body: <p>My taks is to restore an mp3 file, wich is coded bit-per-bit in a PNG file. I got the right bits from the PNG RGB data (per pixel) in a vector. I'm using C++.</p>
  
  <p>I have to go through the png file and read the RGB data of a pixel: then I have 3 decimal values. From binary representation of the decimal values, I need the least smallest local value. The 11 pixels shows on 33 bits the length of the mp3. Then i decode all of the binary data from the pixels, and put in a vector;</p>
  
  <pre><code>#include &lt;unistd.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  #include &lt;stdarg.h&gt;
  #include &lt;vector&gt;
  #include &lt;math.h&gt;
  #include &lt;iostream&gt;
  #include &lt;fstream&gt;
  
  #define PNG_DEBUG 3
  #include &lt;png.h&gt;
  
  void abort_(const char * s, ...)
  {
          va_list args;
          va_start(args, s);
          vfprintf(stderr, s, args);
          fprintf(stderr, "\n");
          va_end(args);
          abort();
  }
  
  void itob(short n, std::vector&lt;int&gt; &amp;bin)
  {
      int d = n;
  
      if (n &gt; 1)
      {
          d = n % 2;
          itob(n / 2, bin);
      }
      bin.push_back(d);
  }
  
  void btoi(unsigned int&amp; n, std::vector&lt;int&gt; bin)
  {
      n = 0;
      int k = 32;
      for(int i = 0; i &lt; bin.size() ; i++){
          if(bin[i] == 1){
              long int num = pow(2,k);
              n += num;
          }
          k--;
      }
  }
  
  int x, y;
  
  int width, height;
  png_byte color_type;
  png_byte bit_depth;
  
  png_structp png_ptr;
  png_infop info_ptr;
  int number_of_passes;
  png_bytep * row_pointers;
  
  void read_png_file()
  {
          unsigned char header[8];    // 8 is the maximum size that can be checked
  
          /* open file and test for it being a png */
          FILE *fp = fopen("image.png", "rb");
          if (!fp)
                  abort_("[read_png_file] File %s could not be opened for reading", "image.png");
          fread(header, 1, 8, fp);
          if (png_sig_cmp(header, 0, 8))
                  abort_("[read_png_file] File %s is not recognized as a PNG file", "image.png");
  
  
          /* initialize stuff */
          png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  
          if (!png_ptr)
                  abort_("[read_png_file] png_create_read_struct failed");
  
          info_ptr = png_create_info_struct(png_ptr);
          if (!info_ptr)
                  abort_("[read_png_file] png_create_info_struct failed");
  
          png_init_io(png_ptr, fp);
          png_set_sig_bytes(png_ptr, 8);
  
          png_read_info(png_ptr, info_ptr);
  
          width = png_get_image_width(png_ptr, info_ptr);
          height = png_get_image_height(png_ptr, info_ptr);
          color_type = png_get_color_type(png_ptr, info_ptr);
          bit_depth = png_get_bit_depth(png_ptr, info_ptr);
  
          number_of_passes = png_set_interlace_handling(png_ptr);
          png_read_update_info(png_ptr, info_ptr);
  
          row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height);
          for (y=0; y&lt;height; y++)
                  row_pointers[y] = (png_byte*) malloc(png_get_rowbytes(png_ptr,info_ptr));
  
          png_read_image(png_ptr, row_pointers);
  
          fclose(fp);
  }
  
  
  void process_file(void)
  {
          if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_RGBA)
                  abort_("[process_file] input file is PNG_COLOR_TYPE_RGB but must be PNG_COLOR_TYPE_RGB "
                         "(lacks the alpha channel)");
  
          if (png_get_color_type(png_ptr, info_ptr) != PNG_COLOR_TYPE_RGB)
                  abort_("[process_file] color_type of input file must be PNG_COLOR_TYPE_RGB (%d) (is %d)",
                         PNG_COLOR_TYPE_RGBA, png_get_color_type(png_ptr, info_ptr));
  
          printf("width: %d\nheight: %d\n", width, height);
  
          int mHeader = 33; unsigned int mSize = 0;
          std::vector&lt;int&gt; mSizeByBites;
          for (y=0; y&lt;height; y++) {
              png_byte* row = row_pointers[y];
              for (x=0; x&lt;width; x++) {
                      png_byte* ptr = &amp;(row[x*3]);
                      if(mHeader == 0){ break; }
                      mHeader-=3;
  
                      std::vector&lt;int&gt; b;
  
                      itob(ptr[0], b);
                      mSizeByBites.push_back(b[b.size()-1]);
                      b.clear();
  
                      itob(ptr[1], b);
                      mSizeByBites.push_back(b[b.size()-1]);
                      b.clear();
  
                      itob(ptr[2], b);
                      mSizeByBites.push_back(b[b.size()-1]);
                      b.clear();
                  }
              if(mHeader == 0){ break; }
          }
  
  
          for(int i =0; i&lt;mSizeByBites.size(); i++){
              printf("%d", mSizeByBites[i]);
          }
          btoi(mSize, mSizeByBites);
          printf(" = %i\n", mSize);
  
          std::vector&lt;int&gt; mDataBaBites;
  
          for (y=0; y&lt;height; y++) {
              png_byte* row = row_pointers[y];
              for (x=0; x&lt;width; x++) {
                  if(mSize &lt;= 0){ break; }
  
                  png_byte* ptr = &amp;(row[x*3]);
                  std::vector&lt;int&gt; b;
  
                  itob(ptr[0], b);
                  mDataBaBites.push_back(b[b.size()-1]);
                  b.clear();
                  mSize--;
                  if(mSize &lt;= 0){ break; }
                  itob(ptr[1], b);
                  mDataBaBites.push_back(b[b.size()-1]);
                  b.clear();
                  mSize--;
                  if(mSize &lt;= 0){ break; }
                  itob(ptr[2], b);
                  mDataBaBites.push_back(b[b.size()-1]);
                  b.clear();
                  mSize--;
                  if(mSize &lt;= 0){ break; }
                  printf("%i\n", mSize);
              }
              if(mSize&lt;=0){ break; }
          }
  
          std::ofstream output("result.mp3", std::ios::out | std::ios::binary);
  
          printf("[D] Writing to file start:    %li\n", mDataBaBites.size());
          output.write( (char*)(&amp;mDataBaBites[0]), mDataBaBites.size() );
          output.close();
  
  }
  
  
  int main(int argc, char **argv)
  {
  
          read_png_file();
          process_file();
  
          return 0;
  }
  </code></pre>
  
  <p>Now I have no clue, how to write it in a file, wich i can play as an mp3. I tried to convert the bits to hexa.</p>
  
  <p>What is the correct format of an mp3 file? How can I write the bits in the correct format?</p>