This source file includes following definitions.
- clip
 
#include <assert.h>
#include <errno.h>
#include <math.h>
#include <png.h>
#include <string.h>
#include "encoder_png.h"
PngEncoder::PngEncoder() {}
inline uint8_t clip(float value) {
  if (value < 0) {
    return 0x00;
  } else if (value >= 255) {
    return 0xff;
  } else {
    return static_cast<uint8_t>(round(value));
  }
}
bool PngEncoder::Encode(const struct heif_image_handle* handle,
    const struct heif_image* image, const std::string& filename) {
  png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr,
      nullptr, nullptr);
  if (!png_ptr) {
    fprintf(stderr, "libpng initialization failed (1)\n");
    return false;
  }
  png_infop info_ptr = png_create_info_struct(png_ptr);
  if (!png_ptr) {
    png_destroy_write_struct(&png_ptr, nullptr);
    fprintf(stderr, "libpng initialization failed (2)\n");
    return false;
  }
  FILE* fp = fopen(filename.c_str(), "wb");
  if (!fp) {
    fprintf(stderr, "Can't open %s: %s\n", filename.c_str(), strerror(errno));
    png_destroy_write_struct(&png_ptr, &info_ptr);
    return false;
  }
  if (setjmp(png_jmpbuf(png_ptr))) {
    png_destroy_write_struct(&png_ptr, &info_ptr);
    fclose(fp);
    fprintf(stderr, "Error while encoding image\n");
    return false;
  }
  png_init_io(png_ptr, fp);
  bool withAlpha = (heif_image_get_chroma_format(image) == heif_chroma_interleaved_32bit);
  int width = heif_image_get_width(image, heif_channel_interleaved);
  int height = heif_image_get_height(image, heif_channel_interleaved);
  const int bitDepth = 8;
  const int colorType = withAlpha ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB;
  png_set_IHDR(png_ptr, info_ptr, width, height, bitDepth, colorType,
      PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
  png_write_info(png_ptr, info_ptr);
  uint8_t** row_pointers = new uint8_t*[height];
  int stride_rgb;
  const uint8_t* row_rgb = heif_image_get_plane_readonly(image,
      heif_channel_interleaved, &stride_rgb);
  for (int y = 0; y < height; ++y) {
    row_pointers[y] = const_cast<uint8_t*>(&row_rgb[y * stride_rgb]);
  }
  png_write_image(png_ptr, row_pointers);
  png_write_end(png_ptr, nullptr);
  png_destroy_write_struct(&png_ptr, &info_ptr);
  delete[] row_pointers;
  fclose(fp);
  return true;
}