title: Converting string to IMAGE_T
body: <p>i'm working on a simple graphic application working with raspberry dispmanx.
  My goal is to acquire a png file via stdin (from a RGBA array, formatted as a string, from a python app), convert it into the IMAGE_T format expected by dispmanx in order to display it.</p>
  
  <p>Now, I only have a function that can acquire PNG from file, but it takes too much time to write the image on disk, event on tmpfs.</p>
  
  <p>How can I rewrite this function to work with a string as input ?
  I would have manage this alone, but i don't know how to emulate a file from a variable to feed png_ptr and info_ptr ...</p>
  
  <pre><code>#include &lt;png.h&gt;
  #include &lt;stdlib.h&gt;
  #include "bcm_host.h"
  #include "loadpng.h"
  //-------------------------------------------------------------------------
  
  #ifndef ALIGN_TO_16
  #define ALIGN_TO_16(x) ((x + 15) &amp; ~15)
  #endif
  
  //-------------------------------------------------------------------------
  
  bool
  loadPngData(
      IMAGE_T* image,
      const char *file)
  {
      FILE* fpin = fopen(file, "rb");
  
      if (fpin == NULL)
      {
          fprintf(stderr, "loadpng: can't open file for reading\n");
          return false;
      }
  
      //---------------------------------------------------------------------
  
      png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
                                                   NULL,
                                                   NULL,
                                                   NULL);
  
      if (png_ptr == NULL)
      {
          fclose(fpin);
          return false;
      }
  
      png_infop info_ptr = png_create_info_struct(png_ptr);
  
      if (info_ptr == NULL)
      {
          png_destroy_read_struct(&amp;png_ptr, 0, 0);
          fclose(fpin);
          return false;
      }
  
      if (setjmp(png_jmpbuf(png_ptr)))
      {
          png_destroy_read_struct(&amp;png_ptr, &amp;info_ptr, 0);
          fclose(fpin);
          return false;
      }
  
      //---------------------------------------------------------------------
  
      png_init_io(png_ptr, imgdata);
  
      png_read_info(png_ptr, info_ptr);
  
      //---------------------------------------------------------------------
  
      png_byte colour_type = png_get_color_type(png_ptr, info_ptr);
      png_byte bit_depth = png_get_bit_depth(png_ptr, info_ptr);
  
      VC_IMAGE_TYPE_T type = VC_IMAGE_RGB888;
  
      if (colour_type &amp; PNG_COLOR_MASK_ALPHA)
      {
          type = VC_IMAGE_RGBA32;
      }
  
      initImage(image,
                type,
                png_get_image_width(png_ptr, info_ptr),
                png_get_image_height(png_ptr, info_ptr),
                false);
  
      //---------------------------------------------------------------------
  
      double gamma = 0.0;
  
      if (png_get_gAMA(png_ptr, info_ptr, &amp;gamma))
      {
          png_set_gamma(png_ptr, 2.2, gamma);
      }
  
      //---------------------------------------------------------------------
  
      if (colour_type == PNG_COLOR_TYPE_PALETTE) 
      {
          png_set_palette_to_rgb(png_ptr);
      }
  
      if ((colour_type == PNG_COLOR_TYPE_GRAY) &amp;&amp; (bit_depth &lt; 8))
      {
          png_set_expand_gray_1_2_4_to_8(png_ptr);
      }
  
      if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
      {
          png_set_tRNS_to_alpha(png_ptr);
      }
  
      if (bit_depth == 16)
      {
  #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
          png_set_scale_16(png_ptr);
  #else
          png_set_strip_16(png_ptr);
  #endif
      }
  
      if (colour_type == PNG_COLOR_TYPE_GRAY ||
          colour_type == PNG_COLOR_TYPE_GRAY_ALPHA)
      {
          png_set_gray_to_rgb(png_ptr);
      }
  
      //---------------------------------------------------------------------
  
      png_read_update_info(png_ptr, info_ptr);
  
      //---------------------------------------------------------------------
  
      png_bytepp row_pointers = malloc(image-&gt;height * sizeof(png_bytep));
  
      png_uint_32 j = 0;
      for (j = 0 ; j &lt; image-&gt;height ; ++j)
      {
          row_pointers[j] = image-&gt;buffer + (j * image-&gt;pitch);
      }
  
      //---------------------------------------------------------------------
  
      png_read_image(png_ptr, row_pointers);
  
      //---------------------------------------------------------------------
  
      fclose(fpin);
  
      free(row_pointers);
  
      png_destroy_read_struct(&amp;png_ptr, &amp;info_ptr, 0);
  
      return true;
  }
  </code></pre>
  
  <p>Edit : Image can be provided from python in raw RGBA, or in png format (as a string with header, and chunks). I suppose raw RGBA would faster (skipping png format), but the modifying this function may be more simple with PNG string ...
  Any clue is welcome !</p>