Example #1
0
bool rpng_nbio_load_image_argb_iterate(uint8_t *buf, struct rpng_t *rpng, unsigned *ret)
{
   unsigned i;

   struct png_chunk chunk = {0};

   if (!read_chunk_header(buf, &chunk))
      return false;

#if 0
   for (i = 0; i < 4; i++)
   {
      fprintf(stderr, "chunktype: %c\n", chunk.type[i]);
   }
#endif

   switch (png_chunk_type(&chunk))
   {
      case PNG_CHUNK_NOOP:
      default:
         break;

      case PNG_CHUNK_ERROR:
         goto error;

      case PNG_CHUNK_IHDR:
         if (rpng->has_ihdr || rpng->has_idat || rpng->has_iend)
            goto error;

         if (chunk.size != 13)
            goto error;

         if (!png_parse_ihdr(buf, &rpng->ihdr))
            goto error;

         if (!png_process_ihdr(&rpng->ihdr))
            goto error;

         rpng->has_ihdr = true;
         break;

      case PNG_CHUNK_PLTE:
         {
            unsigned entries = chunk.size / 3;

            if (!rpng->has_ihdr || rpng->has_plte || rpng->has_iend || rpng->has_idat)
               goto error;

            if (chunk.size % 3)
               goto error;

            if (!png_read_plte_into_buf(buf, rpng->palette, entries))
               goto error;

            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)))
            goto error;

         if (!png_realloc_idat(&chunk, &rpng->idat_buf))
            goto error;

         buf += 8;

         for (i = 0; i < chunk.size; i++)
            rpng->idat_buf.data[i + rpng->idat_buf.size] = buf[i];

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

         rpng->has_idat = true;
         break;

      case PNG_CHUNK_IEND:
         if (!(rpng->has_ihdr) || !(rpng->has_idat))
            goto error;

         rpng->has_iend = true;
         goto error;
   }

   *ret = 4 + 4 + chunk.size + 4;

   return true;

error:
   return false;
}
Example #2
0
bool rpng_nbio_load_image_argb_iterate(uint8_t *buf, struct rpng_t *rpng)
{
   unsigned i;

   rpng->chunk.size = 0;
   rpng->chunk.type[0] = '\0';

   if (!read_chunk_header(buf, &rpng->chunk))
      return false;

#if 0
   for (i = 0; i < 4; i++)
   {
      fprintf(stderr, "chunktype: %c\n", chunk.type[i]);
   }
#endif

   switch (png_chunk_type(&rpng->chunk))
   {
      case PNG_CHUNK_NOOP:
      default:
         break;

      case PNG_CHUNK_ERROR:
         return false;

      case PNG_CHUNK_IHDR:
         if (rpng->has_ihdr || rpng->has_idat || rpng->has_iend)
            return false;

         if (rpng->chunk.size != 13)
            return false;

         if (!png_parse_ihdr(buf, &rpng->ihdr))
            return false;

         rpng->has_ihdr = true;
         break;

      case PNG_CHUNK_PLTE:
         {
            unsigned entries = rpng->chunk.size / 3;

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

            if (rpng->chunk.size % 3)
               return false;

            if (!png_read_plte_into_buf(buf, rpng->palette, entries))
               return false;

            rpng->has_plte = true;
         }
         break;

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

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

         buf += 8;

         for (i = 0; i < rpng->chunk.size; i++)
            rpng->idat_buf.data[i + rpng->idat_buf.size] = buf[i];

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

         rpng->has_idat = true;
         break;

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

         rpng->has_iend = true;
         return false;
   }

   return true;
}