Ejemplo n.º 1
0
/*
 * Reduce the image (bit depth + color type + palette) without
 * losing any information. The palette (if applicable) and the
 * image data must be present (e.g. by calling png_set_rows(),
 * or by loading IDAT).
 * The parameter reductions indicates the intended reductions.
 * The function returns the successful reductions.
 */
png_uint_32 PNGAPI
opng_reduce_image(png_structp png_ptr, png_infop info_ptr,
   png_uint_32 reductions)
{
   unsigned int color_type;
   png_uint_32 result;

   png_debug(1, "in opng_reduce_image_type\n");

   if (!opng_validate_image(png_ptr, info_ptr))
   {
      png_warning(png_ptr,
         "Image reduction requires the presence of the critical info");
      return OPNG_REDUCE_NONE;
   }

#if 0  /* PNG_INTERLACE must be recognized! */
   if (png_ptr->transformations)
   {
      png_warning(png_ptr,
         "Image reduction cannot be applied "
         "under the presence of transformations");
      return OPNG_REDUCE_NONE;
   }
#endif

   color_type = info_ptr->color_type;

   /* The reductions below must be applied in the given order. */

   /* Try to reduce the high bits and color/alpha channels. */
   result = opng_reduce_bits(png_ptr, info_ptr, reductions);

   /* Try to reduce the palette image. */
   if (color_type == PNG_COLOR_TYPE_PALETTE &&
       (reductions & (OPNG_REDUCE_PALETTE_TO_GRAY |
                      OPNG_REDUCE_PALETTE_FAST |
                      OPNG_REDUCE_8_TO_4_2_1)))
      result |= opng_reduce_palette(png_ptr, info_ptr, reductions);

   /* Try to reduce RGB to palette or grayscale to palette. */
   if (((color_type & ~PNG_COLOR_MASK_ALPHA) == PNG_COLOR_TYPE_GRAY &&
        (reductions & OPNG_REDUCE_GRAY_TO_PALETTE)) ||
       ((color_type & ~PNG_COLOR_MASK_ALPHA) == PNG_COLOR_TYPE_RGB &&
        (reductions & OPNG_REDUCE_RGB_TO_PALETTE)))
   {
      if (!(result & OPNG_REDUCE_PALETTE_TO_GRAY))
         result |= opng_reduce_to_palette(png_ptr, info_ptr, reductions);
   }

   return result;
}
Ejemplo n.º 2
0
/*
 * Imports an image from an PNG file stream.
 * The function returns 0 on success or -1 on error.
 */
int opng_decode_image(struct opng_codec_context *context, FILE *stream, const char *fname, bool force_no_palette)
{
    context->libpng_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, opng_read_error, opng_read_warning);
    context->info_ptr = png_create_info_struct(context->libpng_ptr);
    if (!context->libpng_ptr || !context->info_ptr)
    {
        opng_error(0, "Out of memory");
        png_destroy_read_struct(&context->libpng_ptr, &context->info_ptr, 0);
        exit(1);
    }

    opng_init_image(context->image);
    const char * volatile err_msg;  /* volatile is required by cexcept */
    struct opng_encoding_stats * stats = context->stats;
    opng_init_stats(stats);
    context->stream = stream;
    context->fname = fname;
    if (force_no_palette) {
        png_set_palette_to_rgb(context->libpng_ptr);
    }

    Try
    {
        png_set_keep_unknown_chunks(context->libpng_ptr, PNG_HANDLE_CHUNK_ALWAYS, 0, 0);
        png_set_read_fn(context->libpng_ptr, context, opng_read_data);
        png_read_png(context->libpng_ptr, context->info_ptr, 0, 0);
    }
    Catch (err_msg)
    {
        if (opng_validate_image(context->libpng_ptr, context->info_ptr))
        {
            /* The critical image info has already been loaded.
             * Treat this error as a warning in order to allow data recovery.
             */
            opng_warning(fname, err_msg);
        }
        else
        {
            opng_error(fname, err_msg);
            return -1;
        }
    }
    opng_load_image(context->image, context->libpng_ptr, context->info_ptr);
    return 0;
}
/*
 * Reduce the image (bit depth + color type + palette) without
 * losing any information. The palette (if applicable) and the
 * image data must be present, e.g., by calling png_set_rows(),
 * or by loading IDAT.
 * The parameter reductions indicates the intended reductions.
 * The function returns the successful reductions.
 */
png_uint_32 PNGAPI opng_reduce_image(png_structp png_ptr, png_infop info_ptr, png_uint_32 reductions)
{
   if (!opng_validate_image(png_ptr, info_ptr))
   {
      png_warning(png_ptr, "Image reduction requires the presence of all critical information");
      return OPNG_REDUCE_NONE;
   }

   int color_type = png_get_color_type(png_ptr, info_ptr);


   /* The reductions below must be applied in this particular order. */

  png_uint_32 result = 0;
     if ((color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
                   color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
                 && (reductions & OPNG_REDUCE_DIRTY_ALPHA)
                )
     {result |= opng_reduce_dirty_alpha(png_ptr, info_ptr);}


   /* Try to reduce the high bits and color/alpha channels. */
   result |= opng_reduce_bits(png_ptr, info_ptr, reductions);

   /* Try to reduce the palette image. */
   if (color_type == PNG_COLOR_TYPE_PALETTE &&
       (reductions &
        (OPNG_REDUCE_PALETTE_TO_GRAY |
         OPNG_REDUCE_PALETTE_FAST |
         OPNG_REDUCE_8_TO_4_2_1)))
      result |= opng_reduce_palette(png_ptr, info_ptr, reductions);

   /* Try to reduce RGB to palette or grayscale to palette. */
   if (((color_type & ~PNG_COLOR_MASK_ALPHA) == PNG_COLOR_TYPE_GRAY &&
        (reductions & OPNG_REDUCE_GRAY_TO_PALETTE)) ||
       ((color_type & ~PNG_COLOR_MASK_ALPHA) == PNG_COLOR_TYPE_RGB &&
        (reductions & OPNG_REDUCE_RGB_TO_PALETTE)))
   {
      if (!(result & OPNG_REDUCE_PALETTE_TO_GRAY))
         result |= opng_reduce_to_palette(png_ptr, info_ptr, reductions);
   }

   return result;
}