title: libpng error: PNG unsigned integer out of range
body: <p>When trying to read a PNG from memory I came across this funky error:</p>
  
  <pre><code>libpng error:: PNG unsigned integer out of range
  </code></pre>
  
  <p>This error is caused by </p>
  
  <pre><code>png_read_info(png_ptr,info_ptr);
  </code></pre>
  
  <p>Which uses following handler:</p>
  
  <pre><code>static void ReadDataFromBuffer(png_structp png_ptr, png_bytep outBytes,
      png_size_t byteCountToRead){
          PNGDataPtr dataptr=(PNGDataPtr)png_get_io_ptr(png_ptr);
          png_uint_32 i;
          cout&lt;&lt;byteCountToRead&lt;&lt;endl;
          cout&lt;&lt;&amp;outBytes&lt;&lt;endl;
          cout&lt;&lt;dataptr-&gt;len&lt;&lt;endl;
          cout&lt;&lt;dataptr-&gt;p&lt;&lt;endl;
  
          if(byteCountToRead&gt;dataptr-&gt;len){
              png_error(png_ptr,"EOF");
              return;
          }
  
          for(i=0;i&lt;byteCountToRead;i++){
  
              outBytes[i]=dataptr-&gt;p[i];
          }
          dataptr-&gt;p+=byteCountToRead;
          dataptr-&gt;len-=byteCountToRead;
          png_uint_32 a = png_get_uint_32(outBytes);
          cout&lt;&lt;a&lt;&lt;" "&lt;&lt;PNG_UINT_31_MAX&lt;&lt;endl;
  
  }
  </code></pre>
  
  <p>Through some intensive searching I found that the error gets called by the following code in
  pgnrutil.c:</p>
  
  <pre><code>png_uint_32 /* PRIVATE */
  png_get_uint_31(png_structp png_ptr, png_bytep buf)
  {
      png_uint_32 i = png_get_uint_32(buf);
      if (i &gt; PNG_UINT_31_MAX)
      png_error(png_ptr, "PNG unsigned integer out of range.\n");
      return (i);
  }
  </code></pre>
  
  <p>So I checked the value of png_get_uint_32(outBytes) and it was indeed higher than PNG_UINT_31_MAX, 230374511 to be exact.</p>
  
  <p>How do I fix this?</p>
  
  <p>Edit: </p>
  
  <p>Some clarification on the PNGDataPtr:</p>
  
  <pre><code>typedef struct{
      png_bytep p;
      png_uint_32 len;
  } PNGData,*PNGDataPtr;
  </code></pre>
  
  <p>When calling</p>
  
  <pre><code>png_set_read_fn(png_ptr,(png_voidp) &amp;pngdata, ReadDataFromBuffer);
  </code></pre>
  
  <p>pngdata represents a PNGData object, which has a pointer to my databuffer which contains the entire PNG in memory, and len contains the size of the entire PNG, which is between 40 and 80KB</p>
  
  <p>Edit: Here's a link to a png I get when I use fwrite to save the received databuffer: <a href="https://www.dropbox.com/s/m5enp9jljglhs5c/test.png" rel="noreferrer">https://www.dropbox.com/s/m5enp9jljglhs5c/test.png</a></p>