static int cb_image_menu_generic(nbio_handle_t *nbio)
{
   unsigned width = 0, height = 0;
   int retval;
   if (!nbio)
      return -1;

   if (!rpng_is_valid(nbio->image.handle))
      return -1;

   retval = rpng_nbio_load_image_argb_process(nbio->image.handle,
         &nbio->image.ti.pixels, &width, &height);

   nbio->image.ti.width  = width;
   nbio->image.ti.height = height;

   if (retval == IMAGE_PROCESS_ERROR)
      return -1;
   if (retval == IMAGE_PROCESS_ERROR_END)
      return -1;

   nbio->image.is_blocking_on_processing         = true;
   nbio->image.is_finished                       = false;

   return 0;
}
Exemple #2
0
static bool rpng_load_image_argb(const char *path, uint32_t **data,
      unsigned *width, unsigned *height)
{
   int retval;
   size_t file_len;
   bool              ret = true;
   rpng_t          *rpng = NULL;
   void             *ptr = NULL;
   struct nbio_t* handle = (struct nbio_t*)nbio_open(path, NBIO_READ);

   if (!handle)
      goto end;

   nbio_begin_read(handle);

   while (!nbio_iterate(handle));

   ptr = nbio_get_ptr(handle, &file_len);

   if (!ptr)
   {
      ret = false;
      goto end;
   }

   rpng = rpng_alloc();

   if (!rpng)
   {
      ret = false;
      goto end;
   }

   if (!rpng_set_buf_ptr(rpng, (uint8_t*)ptr))
   {
      ret = false;
      goto end;
   }

   if (!rpng_start(rpng))
   {
      ret = false;
      goto end;
   }

   while (rpng_iterate_image(rpng));

   if (!rpng_is_valid(rpng))
   {
      ret = false;
      goto end;
   }

   do
   {
      retval = rpng_process_image(rpng,
            (void**)data, file_len, width, height);
   }while(retval == IMAGE_PROCESS_NEXT);

   if (retval == IMAGE_PROCESS_ERROR || retval == IMAGE_PROCESS_ERROR_END)
      ret = false;

end:
   if (handle)
      nbio_free(handle);
   if (rpng)
      rpng_free(rpng);
   rpng = NULL;
   if (!ret)
      free(*data);
   return ret;
}
Exemple #3
0
static bool rpng_load_image_argb_iterate(FILE **fd, rpng_t *rpng)
{
   struct png_chunk chunk = {0};
   FILE *file = *fd;

   if (!read_chunk_header_fio(fd, &chunk))
      return false;

   switch (png_chunk_type(&chunk))
   {
      case PNG_CHUNK_NOOP:
      default:
         if (fseek(file, chunk.size + sizeof(uint32_t), SEEK_CUR) < 0)
            return false;
         break;

      case PNG_CHUNK_ERROR:
         return false;

      case PNG_CHUNK_IHDR:
         if (rpng_is_valid(rpng))
            return false;

         if (!png_parse_ihdr_fio(fd, &chunk, &rpng->ihdr))
         {
            png_free_chunk(&chunk);
            return false;
         }

         if (!png_process_ihdr(&rpng->ihdr))
         {
            png_free_chunk(&chunk);
            return false;
         }

         png_free_chunk(&chunk);
         rpng->has_ihdr = true;
         break;

      case PNG_CHUNK_PLTE:
         {
            uint8_t buf[256 * 3];
            unsigned entries = chunk.size / 3;

            if (!rpng->has_ihdr || rpng->has_plte || rpng->has_iend || rpng->has_idat)
               return false;

            if (chunk.size % 3)
               return false;

            if (entries > 256)
               return false;

            if (fread(rpng->palette, 3, entries, *fd) != entries)
               return false;

            if (!png_read_plte(&buf[0], rpng->palette, entries))
               return false;

            if (fseek(*fd, sizeof(uint32_t), SEEK_CUR) < 0)
               return false;

            rpng->has_plte = true;
         }
         break;

      case PNG_CHUNK_IDAT:
         if (!rpng->has_ihdr || rpng->has_iend || (rpng->ihdr.color_type == PNG_IHDR_COLOR_PLT && !rpng->has_plte))
            return false;

         if (!png_realloc_idat(&chunk, &rpng->idat_buf))
            return false;

         if (fread(rpng->idat_buf.data + rpng->idat_buf.size, 1, chunk.size, file) != chunk.size)
            return false;
         if (fseek(file, sizeof(uint32_t), SEEK_CUR) < 0)
            return false;

         rpng->idat_buf.size += chunk.size;

         rpng->has_idat = true;
         break;

      case PNG_CHUNK_IEND:
         if (!rpng->has_ihdr || !rpng->has_idat)
            return false;

         if (fseek(file, sizeof(uint32_t), SEEK_CUR) < 0)
            return false;

         rpng->has_iend = true;
         break;
   }

   return true;
}