/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <png.h>
#include <zlib.h>

#include <algorithm>
#include <unordered_map>
#include <unordered_set>

#include "android-base/errors.h"
#include "android-base/logging.h"
#include "android-base/macros.h"
#include "androidfw/Png.h"

namespace android {

// Custom deleter that destroys libpng read and info structs.
class PngReadStructDeleter {
 public:
  PngReadStructDeleter(png_structp read_ptr, png_infop info_ptr)
      : read_ptr_(read_ptr), info_ptr_(info_ptr) {
  }

  ~PngReadStructDeleter() {
    png_destroy_read_struct(&read_ptr_, &info_ptr_, nullptr);
  }

 private:
  png_structp read_ptr_;
  png_infop info_ptr_;

  DISALLOW_COPY_AND_ASSIGN(PngReadStructDeleter);
};

// Custom deleter that destroys libpng write and info structs.
class PngWriteStructDeleter {
 public:
  PngWriteStructDeleter(png_structp write_ptr, png_infop info_ptr)
      : write_ptr_(write_ptr), info_ptr_(info_ptr) {
  }

  ~PngWriteStructDeleter() {
    png_destroy_write_struct(&write_ptr_, &info_ptr_);
  }

 private:
  png_structp write_ptr_;
  png_infop info_ptr_;

  DISALLOW_COPY_AND_ASSIGN(PngWriteStructDeleter);
};

// Custom warning logging method that uses IDiagnostics.
static void LogWarning(png_structp png_ptr, png_const_charp warning_msg) {
  android::IDiagnostics* diag = (android::IDiagnostics*)png_get_error_ptr(png_ptr);
  diag->Warn(android::DiagMessage() << warning_msg);
}

// Custom error logging method that uses IDiagnostics.
static void LogError(png_structp png_ptr, png_const_charp error_msg) {
  android::IDiagnostics* diag = (android::IDiagnostics*)png_get_error_ptr(png_ptr);
  diag->Error(android::DiagMessage() << error_msg);

  // Causes libpng to longjmp to the spot where setjmp was set. This is how libpng does
  // error handling. If this custom error handler method were to return, libpng would, by
  // default, print the error message to stdout and call the same png_longjmp method.
  png_longjmp(png_ptr, 1);
}

static void ReadDataFromStream(png_structp png_ptr, png_bytep buffer, png_size_t len) {
  InputStream* in = (InputStream*)png_get_io_ptr(png_ptr);

  const void* in_buffer;
  size_t in_len;
  if (!in->Next(&in_buffer, &in_len)) {
    if (in->HadError()) {
      std::stringstream error_msg_builder;
      error_msg_builder << "failed reading from input";
      if (!in->GetError().empty()) {
        error_msg_builder << ": " << in->GetError();
      }
      std::string err = error_msg_builder.str();
      png_error(png_ptr, err.c_str());
    }
    return;
  }

  const size_t bytes_read = std::min(in_len, len);
  memcpy(buffer, in_buffer, bytes_read);
  if (bytes_read != in_len) {
    in->BackUp(in_len - bytes_read);
  }
}

static void WriteDataToStream(png_structp png_ptr, png_bytep buffer, png_size_t len) {
  OutputStream* out = (OutputStream*)png_get_io_ptr(png_ptr);

  void* out_buffer;
  size_t out_len;
  while (len > 0) {
    if (!out->Next(&out_buffer, &out_len)) {
      if (out->HadError()) {
        std::stringstream err_msg_builder;
        err_msg_builder << "failed writing to output";
        if (!out->GetError().empty()) {
          err_msg_builder << ": " << out->GetError();
        }
        std::string err = out->GetError();
        png_error(png_ptr, err.c_str());
      }
      return;
    }

    const size_t bytes_written = std::min(out_len, len);
    memcpy(out_buffer, buffer, bytes_written);

    // Advance the input buffer.
    buffer += bytes_written;
    len -= bytes_written;

    // Advance the output buffer.
    out_len -= bytes_written;
  }

  // If the entire output buffer wasn't used, backup.
  if (out_len > 0) {
    out->BackUp(out_len);
  }
}

std::unique_ptr<Image> ReadPng(InputStream* in, IDiagnostics* diag) {
  // Read the first 8 bytes of the file looking for the PNG signature.
  // Bail early if it does not match.
  const png_byte* signature;
  size_t buffer_size;
  if (!in->Next((const void**)&signature, &buffer_size)) {
    if (in->HadError()) {
      diag->Error(android::DiagMessage() << "failed to read PNG signature: " << in->GetError());
    } else {
      diag->Error(android::DiagMessage() << "not enough data for PNG signature");
    }
    return {};
  }

  if (buffer_size < kPngSignatureSize || png_sig_cmp(signature, 0, kPngSignatureSize) != 0) {
    diag->Error(android::DiagMessage() << "file signature does not match PNG signature");
    return {};
  }

  // Start at the beginning of the first chunk.
  in->BackUp(buffer_size - kPngSignatureSize);

  // Create and initialize the png_struct with the default error and warning handlers.
  // The header version is also passed in to ensure that this was built against the same
  // version of libpng.
  png_structp read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
  if (read_ptr == nullptr) {
    diag->Error(android::DiagMessage() << "failed to create libpng read png_struct");
    return {};
  }

  // Create and initialize the memory for image header and data.
  png_infop info_ptr = png_create_info_struct(read_ptr);
  if (info_ptr == nullptr) {
    diag->Error(android::DiagMessage() << "failed to create libpng read png_info");
    png_destroy_read_struct(&read_ptr, nullptr, nullptr);
    return {};
  }

  // Automatically release PNG resources at end of scope.
  PngReadStructDeleter png_read_deleter(read_ptr, info_ptr);

  // libpng uses longjmp to jump to an error handling routine.
  // setjmp will only return true if it was jumped to, aka there was
  // an error.
  if (setjmp(png_jmpbuf(read_ptr))) {
    return {};
  }

  // Handle warnings ourselves via IDiagnostics.
  png_set_error_fn(read_ptr, (png_voidp)&diag, LogError, LogWarning);

  // Set up the read functions which read from our custom data sources.
  png_set_read_fn(read_ptr, (png_voidp)in, ReadDataFromStream);

  // Skip the signature that we already read.
  png_set_sig_bytes(read_ptr, kPngSignatureSize);

  // Read the chunk headers.
  png_read_info(read_ptr, info_ptr);

  // Extract image meta-data from the various chunk headers.
  uint32_t width, height;
  int bit_depth, color_type, interlace_method, compression_method, filter_method;
  png_get_IHDR(read_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_method,
               &compression_method, &filter_method);

  // When the image is read, expand it so that it is in RGBA 8888 format
  // so that image handling is uniform.

  if (color_type == PNG_COLOR_TYPE_PALETTE) {
    png_set_palette_to_rgb(read_ptr);
  }

  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
    png_set_expand_gray_1_2_4_to_8(read_ptr);
  }

  if (png_get_valid(read_ptr, info_ptr, PNG_INFO_tRNS)) {
    png_set_tRNS_to_alpha(read_ptr);
  }

  if (bit_depth == 16) {
    png_set_strip_16(read_ptr);
  }

  if (!(color_type & PNG_COLOR_MASK_ALPHA)) {
    png_set_add_alpha(read_ptr, 0xFF, PNG_FILLER_AFTER);
  }

  if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
    png_set_gray_to_rgb(read_ptr);
  }

  if (interlace_method != PNG_INTERLACE_NONE) {
    png_set_interlace_handling(read_ptr);
  }

  // Once all the options for reading have been set, we need to flush
  // them to libpng.
  png_read_update_info(read_ptr, info_ptr);

  // 9-patch uses int32_t to index images, so we cap the image dimensions to
  // something
  // that can always be represented by 9-patch.
  if (width > std::numeric_limits<int32_t>::max() || height > std::numeric_limits<int32_t>::max()) {
    diag->Error(android::DiagMessage()
                << "PNG image dimensions are too large: " << width << "x" << height);
    return {};
  }

  std::unique_ptr<Image> output_image = std::make_unique<Image>();
  output_image->width = static_cast<int32_t>(width);
  output_image->height = static_cast<int32_t>(height);

  const size_t row_bytes = png_get_rowbytes(read_ptr, info_ptr);
  CHECK(row_bytes == 4 * width);  // RGBA

  // Allocate one large block to hold the image.
  output_image->data = std::unique_ptr<uint8_t[]>(new uint8_t[height * row_bytes]);

  // Create an array of rows that index into the data block.
  output_image->rows = std::unique_ptr<uint8_t*[]>(new uint8_t*[height]);
  for (uint32_t h = 0; h < height; h++) {
    output_image->rows[h] = output_image->data.get() + (h * row_bytes);
  }

  // Actually read the image pixels.
  png_read_image(read_ptr, output_image->rows.get());

  // Finish reading. This will read any other chunks after the image data.
  png_read_end(read_ptr, info_ptr);

  return output_image;
}

// Experimentally chosen constant to be added to the overhead of using color type
// PNG_COLOR_TYPE_PALETTE to account for the uncompressability of the palette chunk.
// Without this, many small PNGs encoded with palettes are larger after compression than
// the same PNGs encoded as RGBA.
constexpr static const size_t kPaletteOverheadConstant = 1024u * 10u;

// Pick a color type by which to encode the image, based on which color type will take
// the least amount of disk space.
//
// 9-patch images traditionally have not been encoded with palettes.
// The original rationale was to avoid dithering until after scaling,
// but I don't think this would be an issue with palettes. Either way,
// our naive size estimation tends to be wrong for small images like 9-patches
// and using palettes balloons the size of the resulting 9-patch.
// In order to not regress in size, restrict 9-patch to not use palettes.

// The options are:
//
// - RGB
// - RGBA
// - RGB + cheap alpha
// - Color palette
// - Color palette + cheap alpha
// - Color palette + alpha palette
// - Grayscale
// - Grayscale + cheap alpha
// - Grayscale + alpha
//
static int PickColorType(int32_t width, int32_t height, bool grayscale,
                         bool convertible_to_grayscale, bool has_nine_patch,
                         size_t color_palette_size, size_t alpha_palette_size) {
  const size_t palette_chunk_size = 16 + color_palette_size * 3;
  const size_t alpha_chunk_size = 16 + alpha_palette_size;
  const size_t color_alpha_data_chunk_size = 16 + 4 * width * height;
  const size_t color_data_chunk_size = 16 + 3 * width * height;
  const size_t grayscale_alpha_data_chunk_size = 16 + 2 * width * height;
  const size_t palette_data_chunk_size = 16 + width * height;

  if (grayscale) {
    if (alpha_palette_size == 0) {
      // This is the smallest the data can be.
      return PNG_COLOR_TYPE_GRAY;
    } else if (color_palette_size <= 256 && !has_nine_patch) {
      // This grayscale has alpha and can fit within a palette.
      // See if it is worth fitting into a palette.
      const size_t palette_threshold = palette_chunk_size + alpha_chunk_size +
                                       palette_data_chunk_size + kPaletteOverheadConstant;
      if (grayscale_alpha_data_chunk_size > palette_threshold) {
        return PNG_COLOR_TYPE_PALETTE;
      }
    }
    return PNG_COLOR_TYPE_GRAY_ALPHA;
  }

  if (color_palette_size <= 256 && !has_nine_patch) {
    // This image can fit inside a palette. Let's see if it is worth it.
    size_t total_size_with_palette = palette_data_chunk_size + palette_chunk_size;
    size_t total_size_without_palette = color_data_chunk_size;
    if (alpha_palette_size > 0) {
      total_size_with_palette += alpha_palette_size;
      total_size_without_palette = color_alpha_data_chunk_size;
    }

    if (total_size_without_palette > total_size_with_palette + kPaletteOverheadConstant) {
      return PNG_COLOR_TYPE_PALETTE;
    }
  }

  if (convertible_to_grayscale) {
    if (alpha_palette_size == 0) {
      return PNG_COLOR_TYPE_GRAY;
    } else {
      return PNG_COLOR_TYPE_GRAY_ALPHA;
    }
  }

  if (alpha_palette_size == 0) {
    return PNG_COLOR_TYPE_RGB;
  }
  return PNG_COLOR_TYPE_RGBA;
}

// Assigns indices to the color and alpha palettes, encodes them, and then invokes
// png_set_PLTE/png_set_tRNS.
// This must be done before writing image data.
// Image data must be transformed to use the indices assigned within the palette.
static void WritePalette(png_structp write_ptr, png_infop write_info_ptr,
                         std::unordered_map<uint32_t, int>* color_palette,
                         std::unordered_set<uint32_t>* alpha_palette) {
  CHECK(color_palette->size() <= 256);
  CHECK(alpha_palette->size() <= 256);

  // Populate the PNG palette struct and assign indices to the color palette.

  // Colors in the alpha palette should have smaller indices.
  // This will ensure that we can truncate the alpha palette if it is
  // smaller than the color palette.
  int index = 0;
  for (uint32_t color : *alpha_palette) {
    (*color_palette)[color] = index++;
  }

  // Assign the rest of the entries.
  for (auto& entry : *color_palette) {
    if (entry.second == -1) {
      entry.second = index++;
    }
  }

  // Create the PNG color palette struct.
  auto color_palette_bytes = std::unique_ptr<png_color[]>(new png_color[color_palette->size()]);

  std::unique_ptr<png_byte[]> alpha_palette_bytes;
  if (!alpha_palette->empty()) {
    alpha_palette_bytes = std::unique_ptr<png_byte[]>(new png_byte[alpha_palette->size()]);
  }

  for (const auto& entry : *color_palette) {
    const uint32_t color = entry.first;
    const int index = entry.second;
    CHECK(index >= 0);
    CHECK(static_cast<size_t>(index) < color_palette->size());

    png_colorp slot = color_palette_bytes.get() + index;
    slot->red = color >> 24;
    slot->green = color >> 16;
    slot->blue = color >> 8;

    const png_byte alpha = color & 0x000000ff;
    if (alpha != 0xff && alpha_palette_bytes) {
      CHECK(static_cast<size_t>(index) < alpha_palette->size());
      alpha_palette_bytes[index] = alpha;
    }
  }

  // The bytes get copied here, so it is safe to release color_palette_bytes at
  // the end of function
  // scope.
  png_set_PLTE(write_ptr, write_info_ptr, color_palette_bytes.get(), color_palette->size());

  if (alpha_palette_bytes) {
    png_set_tRNS(write_ptr, write_info_ptr, alpha_palette_bytes.get(), alpha_palette->size(),
                 nullptr);
  }
}

// Write the 9-patch custom PNG chunks to write_info_ptr. This must be done
// before writing image data.
static void WriteNinePatch(png_structp write_ptr, png_infop write_info_ptr,
                           const NinePatch* nine_patch) {
  // The order of the chunks is important.
  // 9-patch code in older platforms expects the 9-patch chunk to be last.

  png_unknown_chunk unknown_chunks[3];
  memset(unknown_chunks, 0, sizeof(unknown_chunks));

  size_t index = 0;
  size_t chunk_len = 0;

  std::unique_ptr<uint8_t[]> serialized_outline =
      nine_patch->SerializeRoundedRectOutline(&chunk_len);
  strcpy((char*)unknown_chunks[index].name, "npOl");
  unknown_chunks[index].size = chunk_len;
  unknown_chunks[index].data = (png_bytep)serialized_outline.get();
  unknown_chunks[index].location = PNG_HAVE_PLTE;
  index++;

  std::unique_ptr<uint8_t[]> serialized_layout_bounds;
  if (nine_patch->layout_bounds.nonZero()) {
    serialized_layout_bounds = nine_patch->SerializeLayoutBounds(&chunk_len);
    strcpy((char*)unknown_chunks[index].name, "npLb");
    unknown_chunks[index].size = chunk_len;
    unknown_chunks[index].data = (png_bytep)serialized_layout_bounds.get();
    unknown_chunks[index].location = PNG_HAVE_PLTE;
    index++;
  }

  std::unique_ptr<uint8_t[]> serialized_nine_patch = nine_patch->SerializeBase(&chunk_len);
  strcpy((char*)unknown_chunks[index].name, "npTc");
  unknown_chunks[index].size = chunk_len;
  unknown_chunks[index].data = (png_bytep)serialized_nine_patch.get();
  unknown_chunks[index].location = PNG_HAVE_PLTE;
  index++;

  // Handle all unknown chunks. We are manually setting the chunks here,
  // so we will only ever handle our custom chunks.
  png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_ALWAYS, nullptr, 0);

  // Set the actual chunks here. The data gets copied, so our buffers can
  // safely go out of scope.
  png_set_unknown_chunks(write_ptr, write_info_ptr, unknown_chunks, index);
}

bool WritePng(const Image* image, const NinePatch* nine_patch, OutputStream* out,
              const PngOptions& options, IDiagnostics* diag, bool verbose) {
  // Create and initialize the write png_struct with the default error and
  // warning handlers.
  // The header version is also passed in to ensure that this was built against the same
  // version of libpng.
  png_structp write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
  if (write_ptr == nullptr) {
    diag->Error(android::DiagMessage() << "failed to create libpng write png_struct");
    return false;
  }

  // Allocate memory to store image header data.
  png_infop write_info_ptr = png_create_info_struct(write_ptr);
  if (write_info_ptr == nullptr) {
    diag->Error(android::DiagMessage() << "failed to create libpng write png_info");
    png_destroy_write_struct(&write_ptr, nullptr);
    return false;
  }

  // Automatically release PNG resources at end of scope.
  PngWriteStructDeleter png_write_deleter(write_ptr, write_info_ptr);

  // libpng uses longjmp to jump to error handling routines.
  // setjmp will return true only if it was jumped to, aka, there was an error.
  if (setjmp(png_jmpbuf(write_ptr))) {
    return false;
  }

  // Handle warnings with our IDiagnostics.
  png_set_error_fn(write_ptr, (png_voidp)&diag, LogError, LogWarning);

  // Set up the write functions which write to our custom data sources.
  png_set_write_fn(write_ptr, (png_voidp)out, WriteDataToStream, nullptr);

  // We want small files and can take the performance hit to achieve this goal.
  png_set_compression_level(write_ptr, Z_BEST_COMPRESSION);

  // Begin analysis of the image data.
  // Scan the entire image and determine if:
  // 1. Every pixel has R == G == B (grayscale)
  // 2. Every pixel has A == 255 (opaque)
  // 3. There are no more than 256 distinct RGBA colors (palette).
  std::unordered_map<uint32_t, int> color_palette;
  std::unordered_set<uint32_t> alpha_palette;
  bool needs_to_zero_rgb_channels_of_transparent_pixels = false;
  bool grayscale = true;
  int max_gray_deviation = 0;

  for (int32_t y = 0; y < image->height; y++) {
    const uint8_t* row = image->rows[y];
    for (int32_t x = 0; x < image->width; x++) {
      int red = *row++;
      int green = *row++;
      int blue = *row++;
      int alpha = *row++;

      if (alpha == 0) {
        // The color is completely transparent.
        // For purposes of palettes and grayscale optimization,
        // treat all channels as 0x00.
        needs_to_zero_rgb_channels_of_transparent_pixels =
            needs_to_zero_rgb_channels_of_transparent_pixels ||
            (red != 0 || green != 0 || blue != 0);
        red = green = blue = 0;
      }

      // Insert the color into the color palette.
      const uint32_t color = red << 24 | green << 16 | blue << 8 | alpha;
      color_palette[color] = -1;

      // If the pixel has non-opaque alpha, insert it into the
      // alpha palette.
      if (alpha != 0xff) {
        alpha_palette.insert(color);
      }

      // Check if the image is indeed grayscale.
      if (grayscale) {
        if (red != green || red != blue) {
          grayscale = false;
        }
      }

      // Calculate the gray scale deviation so that it can be compared
      // with the threshold.
      max_gray_deviation = std::max(std::abs(red - green), max_gray_deviation);
      max_gray_deviation = std::max(std::abs(green - blue), max_gray_deviation);
      max_gray_deviation = std::max(std::abs(blue - red), max_gray_deviation);
    }
  }

  if (verbose) {
    android::DiagMessage msg;
    msg << " paletteSize=" << color_palette.size() << " alphaPaletteSize=" << alpha_palette.size()
        << " maxGrayDeviation=" << max_gray_deviation
        << " grayScale=" << (grayscale ? "true" : "false");
    diag->Note(msg);
  }

  const bool convertible_to_grayscale = max_gray_deviation <= options.grayscale_tolerance;

  const int new_color_type =
      PickColorType(image->width, image->height, grayscale, convertible_to_grayscale,
                    nine_patch != nullptr, color_palette.size(), alpha_palette.size());

  if (verbose) {
    android::DiagMessage msg;
    msg << "encoding PNG ";
    if (nine_patch) {
      msg << "(with 9-patch) as ";
    }
    switch (new_color_type) {
      case PNG_COLOR_TYPE_GRAY:
        msg << "GRAY";
        break;
      case PNG_COLOR_TYPE_GRAY_ALPHA:
        msg << "GRAY + ALPHA";
        break;
      case PNG_COLOR_TYPE_RGB:
        msg << "RGB";
        break;
      case PNG_COLOR_TYPE_RGB_ALPHA:
        msg << "RGBA";
        break;
      case PNG_COLOR_TYPE_PALETTE:
        msg << "PALETTE";
        break;
      default:
        msg << "unknown type " << new_color_type;
        break;
    }
    diag->Note(msg);
  }

  png_set_IHDR(write_ptr, write_info_ptr, image->width, image->height, 8, new_color_type,
               PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);

  if (new_color_type & PNG_COLOR_MASK_PALETTE) {
    // Assigns indices to the palette, and writes the encoded palette to the
    // libpng writePtr.
    WritePalette(write_ptr, write_info_ptr, &color_palette, &alpha_palette);
    png_set_filter(write_ptr, 0, PNG_NO_FILTERS);
  } else {
    png_set_filter(write_ptr, 0, PNG_ALL_FILTERS);
  }

  if (nine_patch) {
    WriteNinePatch(write_ptr, write_info_ptr, nine_patch);
  }

  // Flush our updates to the header.
  png_write_info(write_ptr, write_info_ptr);

  // Write out each row of image data according to its encoding.
  if (new_color_type == PNG_COLOR_TYPE_PALETTE) {
    // 1 byte/pixel.
    auto out_row = std::unique_ptr<png_byte[]>(new png_byte[image->width]);

    for (int32_t y = 0; y < image->height; y++) {
      png_const_bytep in_row = image->rows[y];
      for (int32_t x = 0; x < image->width; x++) {
        int rr = *in_row++;
        int gg = *in_row++;
        int bb = *in_row++;
        int aa = *in_row++;
        if (aa == 0) {
          // Zero out color channels when transparent.
          rr = gg = bb = 0;
        }

        const uint32_t color = rr << 24 | gg << 16 | bb << 8 | aa;
        const int idx = color_palette[color];
        CHECK(idx != -1);
        out_row[x] = static_cast<png_byte>(idx);
      }
      png_write_row(write_ptr, out_row.get());
    }
  } else if (new_color_type == PNG_COLOR_TYPE_GRAY || new_color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
    const size_t bpp = new_color_type == PNG_COLOR_TYPE_GRAY ? 1 : 2;
    auto out_row = std::unique_ptr<png_byte[]>(new png_byte[image->width * bpp]);

    for (int32_t y = 0; y < image->height; y++) {
      png_const_bytep in_row = image->rows[y];
      for (int32_t x = 0; x < image->width; x++) {
        int rr = in_row[x * 4];
        int gg = in_row[x * 4 + 1];
        int bb = in_row[x * 4 + 2];
        int aa = in_row[x * 4 + 3];
        if (aa == 0) {
          // Zero out the gray channel when transparent.
          rr = gg = bb = 0;
        }

        if (grayscale) {
          // The image was already grayscale, red == green == blue.
          out_row[x * bpp] = in_row[x * 4];
        } else {
          // The image is convertible to grayscale, use linear-luminance of
          // sRGB colorspace:
          // https://en.wikipedia.org/wiki/Grayscale#Colorimetric_.28luminance-preserving.29_conversion_to_grayscale
          out_row[x * bpp] = (png_byte)(rr * 0.2126f + gg * 0.7152f + bb * 0.0722f);
        }

        if (bpp == 2) {
          // Write out alpha if we have it.
          out_row[x * bpp + 1] = aa;
        }
      }
      png_write_row(write_ptr, out_row.get());
    }
  } else if (new_color_type == PNG_COLOR_TYPE_RGB || new_color_type == PNG_COLOR_TYPE_RGBA) {
    const size_t bpp = new_color_type == PNG_COLOR_TYPE_RGB ? 3 : 4;
    if (needs_to_zero_rgb_channels_of_transparent_pixels) {
      // The source RGBA data can't be used as-is, because we need to zero out
      // the RGB values of transparent pixels.
      auto out_row = std::unique_ptr<png_byte[]>(new png_byte[image->width * bpp]);

      for (int32_t y = 0; y < image->height; y++) {
        png_const_bytep in_row = image->rows[y];
        for (int32_t x = 0; x < image->width; x++) {
          int rr = *in_row++;
          int gg = *in_row++;
          int bb = *in_row++;
          int aa = *in_row++;
          if (aa == 0) {
            // Zero out the RGB channels when transparent.
            rr = gg = bb = 0;
          }
          out_row[x * bpp] = rr;
          out_row[x * bpp + 1] = gg;
          out_row[x * bpp + 2] = bb;
          if (bpp == 4) {
            out_row[x * bpp + 3] = aa;
          }
        }
        png_write_row(write_ptr, out_row.get());
      }
    } else {
      // The source image can be used as-is, just tell libpng whether or not to
      // ignore the alpha channel.
      if (new_color_type == PNG_COLOR_TYPE_RGB) {
        // Delete the extraneous alpha values that we appended to our buffer
        // when reading the original values.
        png_set_filler(write_ptr, 0, PNG_FILLER_AFTER);
      }
      png_write_image(write_ptr, image->rows.get());
    }
  } else {
    LOG(FATAL) << "unreachable";
  }

  png_write_end(write_ptr, write_info_ptr);
  return true;
}

}  // namespace android
