/*
 * 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);

  png_set_compression_level(write_ptr, options.compression_level);

  // 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
