/*
 * Copyright (C) 2015 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 <png.h>
#include <zlib.h>

#include <iostream>
#include <sstream>
#include <string>
#include <vector>

#include "androidfw/ResourceTypes.h"

#include "Source.h"
#include "util/BigBuffer.h"
#include "util/Util.h"

namespace aapt {

constexpr bool kDebug = false;

struct PngInfo {
  ~PngInfo() {
    for (png_bytep row : rows) {
      if (row != nullptr) {
        delete[] row;
      }
    }

    delete[] xDivs;
    delete[] yDivs;
  }

  void* serialize9Patch() {
    void* serialized = android::Res_png_9patch::serialize(info9Patch, xDivs,
                                                          yDivs, colors.data());
    reinterpret_cast<android::Res_png_9patch*>(serialized)->deviceToFile();
    return serialized;
  }

  uint32_t width = 0;
  uint32_t height = 0;
  std::vector<png_bytep> rows;

  bool is9Patch = false;
  android::Res_png_9patch info9Patch;
  int32_t* xDivs = nullptr;
  int32_t* yDivs = nullptr;
  std::vector<uint32_t> colors;

  // Layout padding.
  bool haveLayoutBounds = false;
  int32_t layoutBoundsLeft;
  int32_t layoutBoundsTop;
  int32_t layoutBoundsRight;
  int32_t layoutBoundsBottom;

  // Round rect outline description.
  int32_t outlineInsetsLeft;
  int32_t outlineInsetsTop;
  int32_t outlineInsetsRight;
  int32_t outlineInsetsBottom;
  float outlineRadius;
  uint8_t outlineAlpha;
};

static void readDataFromStream(png_structp readPtr, png_bytep data,
                               png_size_t length) {
  std::istream* input =
      reinterpret_cast<std::istream*>(png_get_io_ptr(readPtr));
  if (!input->read(reinterpret_cast<char*>(data), length)) {
    png_error(readPtr, strerror(errno));
  }
}

static void writeDataToStream(png_structp writePtr, png_bytep data,
                              png_size_t length) {
  BigBuffer* outBuffer = reinterpret_cast<BigBuffer*>(png_get_io_ptr(writePtr));
  png_bytep buf = outBuffer->NextBlock<png_byte>(length);
  memcpy(buf, data, length);
}

static void flushDataToStream(png_structp /*writePtr*/) {}

static void logWarning(png_structp readPtr, png_const_charp warningMessage) {
  IDiagnostics* diag =
      reinterpret_cast<IDiagnostics*>(png_get_error_ptr(readPtr));
  diag->Warn(DiagMessage() << warningMessage);
}

static bool readPng(IDiagnostics* diag, png_structp readPtr, png_infop infoPtr,
                    PngInfo* outInfo) {
  if (setjmp(png_jmpbuf(readPtr))) {
    diag->Error(DiagMessage() << "failed reading png");
    return false;
  }

  png_set_sig_bytes(readPtr, kPngSignatureSize);
  png_read_info(readPtr, infoPtr);

  int colorType, bitDepth, interlaceType, compressionType;
  png_get_IHDR(readPtr, infoPtr, &outInfo->width, &outInfo->height, &bitDepth,
               &colorType, &interlaceType, &compressionType, nullptr);

  if (colorType == PNG_COLOR_TYPE_PALETTE) {
    png_set_palette_to_rgb(readPtr);
  }

  if (colorType == PNG_COLOR_TYPE_GRAY && bitDepth < 8) {
    png_set_expand_gray_1_2_4_to_8(readPtr);
  }

  if (png_get_valid(readPtr, infoPtr, PNG_INFO_tRNS)) {
    png_set_tRNS_to_alpha(readPtr);
  }

  if (bitDepth == 16) {
    png_set_strip_16(readPtr);
  }

  if (!(colorType & PNG_COLOR_MASK_ALPHA)) {
    png_set_add_alpha(readPtr, 0xFF, PNG_FILLER_AFTER);
  }

  if (colorType == PNG_COLOR_TYPE_GRAY ||
      colorType == PNG_COLOR_TYPE_GRAY_ALPHA) {
    png_set_gray_to_rgb(readPtr);
  }

  png_set_interlace_handling(readPtr);
  png_read_update_info(readPtr, infoPtr);

  const uint32_t rowBytes = png_get_rowbytes(readPtr, infoPtr);
  outInfo->rows.resize(outInfo->height);
  for (size_t i = 0; i < outInfo->height; i++) {
    outInfo->rows[i] = new png_byte[rowBytes];
  }

  png_read_image(readPtr, outInfo->rows.data());
  png_read_end(readPtr, infoPtr);
  return true;
}

static void checkNinePatchSerialization(android::Res_png_9patch* inPatch,
                                        void* data) {
  size_t patchSize = inPatch->serializedSize();
  void* newData = malloc(patchSize);
  memcpy(newData, data, patchSize);
  android::Res_png_9patch* outPatch = inPatch->deserialize(newData);
  outPatch->fileToDevice();
  // deserialization is done in place, so outPatch == newData
  assert(outPatch == newData);
  assert(outPatch->numXDivs == inPatch->numXDivs);
  assert(outPatch->numYDivs == inPatch->numYDivs);
  assert(outPatch->paddingLeft == inPatch->paddingLeft);
  assert(outPatch->paddingRight == inPatch->paddingRight);
  assert(outPatch->paddingTop == inPatch->paddingTop);
  assert(outPatch->paddingBottom == inPatch->paddingBottom);
  /*    for (int i = 0; i < outPatch->numXDivs; i++) {
          assert(outPatch->getXDivs()[i] == inPatch->getXDivs()[i]);
      }
      for (int i = 0; i < outPatch->numYDivs; i++) {
          assert(outPatch->getYDivs()[i] == inPatch->getYDivs()[i]);
      }
      for (int i = 0; i < outPatch->numColors; i++) {
          assert(outPatch->getColors()[i] == inPatch->getColors()[i]);
      }*/
  free(newData);
}

/*static void dump_image(int w, int h, const png_byte* const* rows, int
color_type) {
    int i, j, rr, gg, bb, aa;

    int bpp;
    if (color_type == PNG_COLOR_TYPE_PALETTE || color_type ==
PNG_COLOR_TYPE_GRAY) {
        bpp = 1;
    } else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
        bpp = 2;
    } else if (color_type == PNG_COLOR_TYPE_RGB || color_type ==
PNG_COLOR_TYPE_RGB_ALPHA) {
        // We use a padding byte even when there is no alpha
        bpp = 4;
    } else {
        printf("Unknown color type %d.\n", color_type);
    }

    for (j = 0; j < h; j++) {
        const png_byte* row = rows[j];
        for (i = 0; i < w; i++) {
            rr = row[0];
            gg = row[1];
            bb = row[2];
            aa = row[3];
            row += bpp;

            if (i == 0) {
                printf("Row %d:", j);
            }
            switch (bpp) {
            case 1:
                printf(" (%d)", rr);
                break;
            case 2:
                printf(" (%d %d", rr, gg);
                break;
            case 3:
                printf(" (%d %d %d)", rr, gg, bb);
                break;
            case 4:
                printf(" (%d %d %d %d)", rr, gg, bb, aa);
                break;
            }
            if (i == (w - 1)) {
                printf("\n");
            }
        }
    }
}*/

#ifdef MAX
#undef MAX
#endif
#ifdef ABS
#undef ABS
#endif

#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define ABS(a) ((a) < 0 ? -(a) : (a))

static void analyze_image(IDiagnostics* diag, const PngInfo& imageInfo,
                          int grayscaleTolerance, png_colorp rgbPalette,
                          png_bytep alphaPalette, int* paletteEntries,
                          bool* hasTransparency, int* colorType,
                          png_bytepp outRows) {
  int w = imageInfo.width;
  int h = imageInfo.height;
  int i, j, rr, gg, bb, aa, idx;
  uint32_t colors[256], col;
  int num_colors = 0;
  int maxGrayDeviation = 0;

  bool isOpaque = true;
  bool isPalette = true;
  bool isGrayscale = true;

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

  if (kDebug) {
    printf("Initial image data:\n");
    // dump_image(w, h, imageInfo.rows.data(), PNG_COLOR_TYPE_RGB_ALPHA);
  }

  for (j = 0; j < h; j++) {
    const png_byte* row = imageInfo.rows[j];
    png_bytep out = outRows[j];
    for (i = 0; i < w; i++) {
      rr = *row++;
      gg = *row++;
      bb = *row++;
      aa = *row++;

      int odev = maxGrayDeviation;
      maxGrayDeviation = MAX(ABS(rr - gg), maxGrayDeviation);
      maxGrayDeviation = MAX(ABS(gg - bb), maxGrayDeviation);
      maxGrayDeviation = MAX(ABS(bb - rr), maxGrayDeviation);
      if (maxGrayDeviation > odev) {
        if (kDebug) {
          printf("New max dev. = %d at pixel (%d, %d) = (%d %d %d %d)\n",
                 maxGrayDeviation, i, j, rr, gg, bb, aa);
        }
      }

      // Check if image is really grayscale
      if (isGrayscale) {
        if (rr != gg || rr != bb) {
          if (kDebug) {
            printf("Found a non-gray pixel at %d, %d = (%d %d %d %d)\n", i, j,
                   rr, gg, bb, aa);
          }
          isGrayscale = false;
        }
      }

      // Check if image is really opaque
      if (isOpaque) {
        if (aa != 0xff) {
          if (kDebug) {
            printf("Found a non-opaque pixel at %d, %d = (%d %d %d %d)\n", i, j,
                   rr, gg, bb, aa);
          }
          isOpaque = false;
        }
      }

      // Check if image is really <= 256 colors
      if (isPalette) {
        col = (uint32_t)((rr << 24) | (gg << 16) | (bb << 8) | aa);
        bool match = false;
        for (idx = 0; idx < num_colors; idx++) {
          if (colors[idx] == col) {
            match = true;
            break;
          }
        }

        // Write the palette index for the pixel to outRows optimistically
        // We might overwrite it later if we decide to encode as gray or
        // gray + alpha
        *out++ = idx;
        if (!match) {
          if (num_colors == 256) {
            if (kDebug) {
              printf("Found 257th color at %d, %d\n", i, j);
            }
            isPalette = false;
          } else {
            colors[num_colors++] = col;
          }
        }
      }
    }
  }

  *paletteEntries = 0;
  *hasTransparency = !isOpaque;
  int bpp = isOpaque ? 3 : 4;
  int paletteSize = w * h + bpp * num_colors;

  if (kDebug) {
    printf("isGrayscale = %s\n", isGrayscale ? "true" : "false");
    printf("isOpaque = %s\n", isOpaque ? "true" : "false");
    printf("isPalette = %s\n", isPalette ? "true" : "false");
    printf("Size w/ palette = %d, gray+alpha = %d, rgb(a) = %d\n", paletteSize,
           2 * w * h, bpp * w * h);
    printf("Max gray deviation = %d, tolerance = %d\n", maxGrayDeviation,
           grayscaleTolerance);
  }

  // Choose the best color type for the image.
  // 1. Opaque gray - use COLOR_TYPE_GRAY at 1 byte/pixel
  // 2. Gray + alpha - use COLOR_TYPE_PALETTE if the number of distinct
  // combinations
  //     is sufficiently small, otherwise use COLOR_TYPE_GRAY_ALPHA
  // 3. RGB(A) - use COLOR_TYPE_PALETTE if the number of distinct colors is
  // sufficiently
  //     small, otherwise use COLOR_TYPE_RGB{_ALPHA}
  if (isGrayscale) {
    if (isOpaque) {
      *colorType = PNG_COLOR_TYPE_GRAY;  // 1 byte/pixel
    } else {
      // Use a simple heuristic to determine whether using a palette will
      // save space versus using gray + alpha for each pixel.
      // This doesn't take into account chunk overhead, filtering, LZ
      // compression, etc.
      if (isPalette && (paletteSize < 2 * w * h)) {
        *colorType = PNG_COLOR_TYPE_PALETTE;  // 1 byte/pixel + 4 bytes/color
      } else {
        *colorType = PNG_COLOR_TYPE_GRAY_ALPHA;  // 2 bytes per pixel
      }
    }
  } else if (isPalette && (paletteSize < bpp * w * h)) {
    *colorType = PNG_COLOR_TYPE_PALETTE;
  } else {
    if (maxGrayDeviation <= grayscaleTolerance) {
      diag->Note(DiagMessage() << "forcing image to gray (max deviation = "
                               << maxGrayDeviation << ")");
      *colorType = isOpaque ? PNG_COLOR_TYPE_GRAY : PNG_COLOR_TYPE_GRAY_ALPHA;
    } else {
      *colorType = isOpaque ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA;
    }
  }

  // Perform postprocessing of the image or palette data based on the final
  // color type chosen

  if (*colorType == PNG_COLOR_TYPE_PALETTE) {
    // Create separate RGB and Alpha palettes and set the number of colors
    *paletteEntries = num_colors;

    // Create the RGB and alpha palettes
    for (int idx = 0; idx < num_colors; idx++) {
      col = colors[idx];
      rgbPalette[idx].red = (png_byte)((col >> 24) & 0xff);
      rgbPalette[idx].green = (png_byte)((col >> 16) & 0xff);
      rgbPalette[idx].blue = (png_byte)((col >> 8) & 0xff);
      alphaPalette[idx] = (png_byte)(col & 0xff);
    }
  } else if (*colorType == PNG_COLOR_TYPE_GRAY ||
             *colorType == PNG_COLOR_TYPE_GRAY_ALPHA) {
    // If the image is gray or gray + alpha, compact the pixels into outRows
    for (j = 0; j < h; j++) {
      const png_byte* row = imageInfo.rows[j];
      png_bytep out = outRows[j];
      for (i = 0; i < w; i++) {
        rr = *row++;
        gg = *row++;
        bb = *row++;
        aa = *row++;

        if (isGrayscale) {
          *out++ = rr;
        } else {
          *out++ = (png_byte)(rr * 0.2126f + gg * 0.7152f + bb * 0.0722f);
        }
        if (!isOpaque) {
          *out++ = aa;
        }
      }
    }
  }
}

static bool writePng(IDiagnostics* diag, png_structp writePtr,
                     png_infop infoPtr, PngInfo* info, int grayScaleTolerance) {
  if (setjmp(png_jmpbuf(writePtr))) {
    diag->Error(DiagMessage() << "failed to write png");
    return false;
  }

  uint32_t width, height;
  int colorType, bitDepth, interlaceType, compressionType;

  png_unknown_chunk unknowns[3];
  unknowns[0].data = nullptr;
  unknowns[1].data = nullptr;
  unknowns[2].data = nullptr;

  png_bytepp outRows =
      (png_bytepp)malloc((int)info->height * sizeof(png_bytep));
  if (outRows == (png_bytepp)0) {
    printf("Can't allocate output buffer!\n");
    exit(1);
  }
  for (uint32_t i = 0; i < info->height; i++) {
    outRows[i] = (png_bytep)malloc(2 * (int)info->width);
    if (outRows[i] == (png_bytep)0) {
      printf("Can't allocate output buffer!\n");
      exit(1);
    }
  }

  png_set_compression_level(writePtr, Z_BEST_COMPRESSION);

  if (kDebug) {
    diag->Note(DiagMessage() << "writing image: w = " << info->width
                             << ", h = " << info->height);
  }

  png_color rgbPalette[256];
  png_byte alphaPalette[256];
  bool hasTransparency;
  int paletteEntries;

  analyze_image(diag, *info, grayScaleTolerance, rgbPalette, alphaPalette,
                &paletteEntries, &hasTransparency, &colorType, outRows);

  // If the image is a 9-patch, we need to preserve it as a ARGB file to make
  // sure the pixels will not be pre-dithered/clamped until we decide they are
  if (info->is9Patch &&
      (colorType == PNG_COLOR_TYPE_RGB || colorType == PNG_COLOR_TYPE_GRAY ||
       colorType == PNG_COLOR_TYPE_PALETTE)) {
    colorType = PNG_COLOR_TYPE_RGB_ALPHA;
  }

  if (kDebug) {
    switch (colorType) {
      case PNG_COLOR_TYPE_PALETTE:
        diag->Note(DiagMessage() << "has " << paletteEntries << " colors"
                                 << (hasTransparency ? " (with alpha)" : "")
                                 << ", using PNG_COLOR_TYPE_PALLETTE");
        break;
      case PNG_COLOR_TYPE_GRAY:
        diag->Note(DiagMessage()
                   << "is opaque gray, using PNG_COLOR_TYPE_GRAY");
        break;
      case PNG_COLOR_TYPE_GRAY_ALPHA:
        diag->Note(DiagMessage()
                   << "is gray + alpha, using PNG_COLOR_TYPE_GRAY_ALPHA");
        break;
      case PNG_COLOR_TYPE_RGB:
        diag->Note(DiagMessage() << "is opaque RGB, using PNG_COLOR_TYPE_RGB");
        break;
      case PNG_COLOR_TYPE_RGB_ALPHA:
        diag->Note(DiagMessage()
                   << "is RGB + alpha, using PNG_COLOR_TYPE_RGB_ALPHA");
        break;
    }
  }

  png_set_IHDR(writePtr, infoPtr, info->width, info->height, 8, colorType,
               PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
               PNG_FILTER_TYPE_DEFAULT);

  if (colorType == PNG_COLOR_TYPE_PALETTE) {
    png_set_PLTE(writePtr, infoPtr, rgbPalette, paletteEntries);
    if (hasTransparency) {
      png_set_tRNS(writePtr, infoPtr, alphaPalette, paletteEntries,
                   (png_color_16p)0);
    }
    png_set_filter(writePtr, 0, PNG_NO_FILTERS);
  } else {
    png_set_filter(writePtr, 0, PNG_ALL_FILTERS);
  }

  if (info->is9Patch) {
    int chunkCount = 2 + (info->haveLayoutBounds ? 1 : 0);
    int pIndex = info->haveLayoutBounds ? 2 : 1;
    int bIndex = 1;
    int oIndex = 0;

    // Chunks ordered thusly because older platforms depend on the base 9 patch
    // data being last
    png_bytep chunkNames = info->haveLayoutBounds
                               ? (png_bytep) "npOl\0npLb\0npTc\0"
                               : (png_bytep) "npOl\0npTc";

    // base 9 patch data
    if (kDebug) {
      diag->Note(DiagMessage() << "adding 9-patch info..");
    }
    memcpy((char*)unknowns[pIndex].name, "npTc", 5);
    unknowns[pIndex].data = (png_byte*)info->serialize9Patch();
    unknowns[pIndex].size = info->info9Patch.serializedSize();
    // TODO: remove the check below when everything works
    checkNinePatchSerialization(&info->info9Patch, unknowns[pIndex].data);

    // automatically generated 9 patch outline data
    int chunkSize = sizeof(png_uint_32) * 6;
    memcpy((char*)unknowns[oIndex].name, "npOl", 5);
    unknowns[oIndex].data = (png_byte*)calloc(chunkSize, 1);
    png_byte outputData[chunkSize];
    memcpy(&outputData, &info->outlineInsetsLeft, 4 * sizeof(png_uint_32));
    ((float*)outputData)[4] = info->outlineRadius;
    ((png_uint_32*)outputData)[5] = info->outlineAlpha;
    memcpy(unknowns[oIndex].data, &outputData, chunkSize);
    unknowns[oIndex].size = chunkSize;

    // optional optical inset / layout bounds data
    if (info->haveLayoutBounds) {
      int chunkSize = sizeof(png_uint_32) * 4;
      memcpy((char*)unknowns[bIndex].name, "npLb", 5);
      unknowns[bIndex].data = (png_byte*)calloc(chunkSize, 1);
      memcpy(unknowns[bIndex].data, &info->layoutBoundsLeft, chunkSize);
      unknowns[bIndex].size = chunkSize;
    }

    for (int i = 0; i < chunkCount; i++) {
      unknowns[i].location = PNG_HAVE_PLTE;
    }
    png_set_keep_unknown_chunks(writePtr, PNG_HANDLE_CHUNK_ALWAYS, chunkNames,
                                chunkCount);
    png_set_unknown_chunks(writePtr, infoPtr, unknowns, chunkCount);

#if PNG_LIBPNG_VER < 10600
    // Deal with unknown chunk location bug in 1.5.x and earlier.
    png_set_unknown_chunk_location(writePtr, infoPtr, 0, PNG_HAVE_PLTE);
    if (info->haveLayoutBounds) {
      png_set_unknown_chunk_location(writePtr, infoPtr, 1, PNG_HAVE_PLTE);
    }
#endif
  }

  png_write_info(writePtr, infoPtr);

  png_bytepp rows;
  if (colorType == PNG_COLOR_TYPE_RGB ||
      colorType == PNG_COLOR_TYPE_RGB_ALPHA) {
    if (colorType == PNG_COLOR_TYPE_RGB) {
      png_set_filler(writePtr, 0, PNG_FILLER_AFTER);
    }
    rows = info->rows.data();
  } else {
    rows = outRows;
  }
  png_write_image(writePtr, rows);

  if (kDebug) {
    printf("Final image data:\n");
    // dump_image(info->width, info->height, rows, colorType);
  }

  png_write_end(writePtr, infoPtr);

  for (uint32_t i = 0; i < info->height; i++) {
    free(outRows[i]);
  }
  free(outRows);
  free(unknowns[0].data);
  free(unknowns[1].data);
  free(unknowns[2].data);

  png_get_IHDR(writePtr, infoPtr, &width, &height, &bitDepth, &colorType,
               &interlaceType, &compressionType, nullptr);

  if (kDebug) {
    diag->Note(DiagMessage() << "image written: w = " << width
                             << ", h = " << height << ", d = " << bitDepth
                             << ", colors = " << colorType
                             << ", inter = " << interlaceType
                             << ", comp = " << compressionType);
  }
  return true;
}

constexpr uint32_t kColorWhite = 0xffffffffu;
constexpr uint32_t kColorTick = 0xff000000u;
constexpr uint32_t kColorLayoutBoundsTick = 0xff0000ffu;

enum class TickType { kNone, kTick, kLayoutBounds, kBoth };

static TickType tickType(png_bytep p, bool transparent, const char** outError) {
  png_uint_32 color = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);

  if (transparent) {
    if (p[3] == 0) {
      return TickType::kNone;
    }
    if (color == kColorLayoutBoundsTick) {
      return TickType::kLayoutBounds;
    }
    if (color == kColorTick) {
      return TickType::kTick;
    }

    // Error cases
    if (p[3] != 0xff) {
      *outError =
          "Frame pixels must be either solid or transparent "
          "(not intermediate alphas)";
      return TickType::kNone;
    }

    if (p[0] != 0 || p[1] != 0 || p[2] != 0) {
      *outError = "Ticks in transparent frame must be black or red";
    }
    return TickType::kTick;
  }

  if (p[3] != 0xFF) {
    *outError = "White frame must be a solid color (no alpha)";
  }
  if (color == kColorWhite) {
    return TickType::kNone;
  }
  if (color == kColorTick) {
    return TickType::kTick;
  }
  if (color == kColorLayoutBoundsTick) {
    return TickType::kLayoutBounds;
  }

  if (p[0] != 0 || p[1] != 0 || p[2] != 0) {
    *outError = "Ticks in white frame must be black or red";
    return TickType::kNone;
  }
  return TickType::kTick;
}

enum class TickState { kStart, kInside1, kOutside1 };

static bool getHorizontalTicks(png_bytep row, int width, bool transparent,
                               bool required, int32_t* outLeft,
                               int32_t* outRight, const char** outError,
                               uint8_t* outDivs, bool multipleAllowed) {
  *outLeft = *outRight = -1;
  TickState state = TickState::kStart;
  bool found = false;

  for (int i = 1; i < width - 1; i++) {
    if (tickType(row + i * 4, transparent, outError) == TickType::kTick) {
      if (state == TickState::kStart ||
          (state == TickState::kOutside1 && multipleAllowed)) {
        *outLeft = i - 1;
        *outRight = width - 2;
        found = true;
        if (outDivs != NULL) {
          *outDivs += 2;
        }
        state = TickState::kInside1;
      } else if (state == TickState::kOutside1) {
        *outError = "Can't have more than one marked region along edge";
        *outLeft = i;
        return false;
      }
    } else if (!*outError) {
      if (state == TickState::kInside1) {
        // We're done with this div.  Move on to the next.
        *outRight = i - 1;
        outRight += 2;
        outLeft += 2;
        state = TickState::kOutside1;
      }
    } else {
      *outLeft = i;
      return false;
    }
  }

  if (required && !found) {
    *outError = "No marked region found along edge";
    *outLeft = -1;
    return false;
  }
  return true;
}

static bool getVerticalTicks(png_bytepp rows, int offset, int height,
                             bool transparent, bool required, int32_t* outTop,
                             int32_t* outBottom, const char** outError,
                             uint8_t* outDivs, bool multipleAllowed) {
  *outTop = *outBottom = -1;
  TickState state = TickState::kStart;
  bool found = false;

  for (int i = 1; i < height - 1; i++) {
    if (tickType(rows[i] + offset, transparent, outError) == TickType::kTick) {
      if (state == TickState::kStart ||
          (state == TickState::kOutside1 && multipleAllowed)) {
        *outTop = i - 1;
        *outBottom = height - 2;
        found = true;
        if (outDivs != NULL) {
          *outDivs += 2;
        }
        state = TickState::kInside1;
      } else if (state == TickState::kOutside1) {
        *outError = "Can't have more than one marked region along edge";
        *outTop = i;
        return false;
      }
    } else if (!*outError) {
      if (state == TickState::kInside1) {
        // We're done with this div.  Move on to the next.
        *outBottom = i - 1;
        outTop += 2;
        outBottom += 2;
        state = TickState::kOutside1;
      }
    } else {
      *outTop = i;
      return false;
    }
  }

  if (required && !found) {
    *outError = "No marked region found along edge";
    *outTop = -1;
    return false;
  }
  return true;
}

static bool getHorizontalLayoutBoundsTicks(png_bytep row, int width,
                                           bool transparent,
                                           bool /* required */,
                                           int32_t* outLeft, int32_t* outRight,
                                           const char** outError) {
  *outLeft = *outRight = 0;

  // Look for left tick
  if (tickType(row + 4, transparent, outError) == TickType::kLayoutBounds) {
    // Starting with a layout padding tick
    int i = 1;
    while (i < width - 1) {
      (*outLeft)++;
      i++;
      if (tickType(row + i * 4, transparent, outError) !=
          TickType::kLayoutBounds) {
        break;
      }
    }
  }

  // Look for right tick
  if (tickType(row + (width - 2) * 4, transparent, outError) ==
      TickType::kLayoutBounds) {
    // Ending with a layout padding tick
    int i = width - 2;
    while (i > 1) {
      (*outRight)++;
      i--;
      if (tickType(row + i * 4, transparent, outError) !=
          TickType::kLayoutBounds) {
        break;
      }
    }
  }
  return true;
}

static bool getVerticalLayoutBoundsTicks(png_bytepp rows, int offset,
                                         int height, bool transparent,
                                         bool /* required */, int32_t* outTop,
                                         int32_t* outBottom,
                                         const char** outError) {
  *outTop = *outBottom = 0;

  // Look for top tick
  if (tickType(rows[1] + offset, transparent, outError) ==
      TickType::kLayoutBounds) {
    // Starting with a layout padding tick
    int i = 1;
    while (i < height - 1) {
      (*outTop)++;
      i++;
      if (tickType(rows[i] + offset, transparent, outError) !=
          TickType::kLayoutBounds) {
        break;
      }
    }
  }

  // Look for bottom tick
  if (tickType(rows[height - 2] + offset, transparent, outError) ==
      TickType::kLayoutBounds) {
    // Ending with a layout padding tick
    int i = height - 2;
    while (i > 1) {
      (*outBottom)++;
      i--;
      if (tickType(rows[i] + offset, transparent, outError) !=
          TickType::kLayoutBounds) {
        break;
      }
    }
  }
  return true;
}

static void findMaxOpacity(png_bytepp rows, int startX, int startY, int endX,
                           int endY, int dX, int dY, int* outInset) {
  uint8_t maxOpacity = 0;
  int inset = 0;
  *outInset = 0;
  for (int x = startX, y = startY; x != endX && y != endY;
       x += dX, y += dY, inset++) {
    png_byte* color = rows[y] + x * 4;
    uint8_t opacity = color[3];
    if (opacity > maxOpacity) {
      maxOpacity = opacity;
      *outInset = inset;
    }
    if (opacity == 0xff) return;
  }
}

static uint8_t maxAlphaOverRow(png_bytep row, int startX, int endX) {
  uint8_t maxAlpha = 0;
  for (int x = startX; x < endX; x++) {
    uint8_t alpha = (row + x * 4)[3];
    if (alpha > maxAlpha) maxAlpha = alpha;
  }
  return maxAlpha;
}

static uint8_t maxAlphaOverCol(png_bytepp rows, int offsetX, int startY,
                               int endY) {
  uint8_t maxAlpha = 0;
  for (int y = startY; y < endY; y++) {
    uint8_t alpha = (rows[y] + offsetX * 4)[3];
    if (alpha > maxAlpha) maxAlpha = alpha;
  }
  return maxAlpha;
}

static void getOutline(PngInfo* image) {
  int midX = image->width / 2;
  int midY = image->height / 2;
  int endX = image->width - 2;
  int endY = image->height - 2;

  // find left and right extent of nine patch content on center row
  if (image->width > 4) {
    findMaxOpacity(image->rows.data(), 1, midY, midX, -1, 1, 0,
                   &image->outlineInsetsLeft);
    findMaxOpacity(image->rows.data(), endX, midY, midX, -1, -1, 0,
                   &image->outlineInsetsRight);
  } else {
    image->outlineInsetsLeft = 0;
    image->outlineInsetsRight = 0;
  }

  // find top and bottom extent of nine patch content on center column
  if (image->height > 4) {
    findMaxOpacity(image->rows.data(), midX, 1, -1, midY, 0, 1,
                   &image->outlineInsetsTop);
    findMaxOpacity(image->rows.data(), midX, endY, -1, midY, 0, -1,
                   &image->outlineInsetsBottom);
  } else {
    image->outlineInsetsTop = 0;
    image->outlineInsetsBottom = 0;
  }

  int innerStartX = 1 + image->outlineInsetsLeft;
  int innerStartY = 1 + image->outlineInsetsTop;
  int innerEndX = endX - image->outlineInsetsRight;
  int innerEndY = endY - image->outlineInsetsBottom;
  int innerMidX = (innerEndX + innerStartX) / 2;
  int innerMidY = (innerEndY + innerStartY) / 2;

  // assuming the image is a round rect, compute the radius by marching
  // diagonally from the top left corner towards the center
  image->outlineAlpha = std::max(
      maxAlphaOverRow(image->rows[innerMidY], innerStartX, innerEndX),
      maxAlphaOverCol(image->rows.data(), innerMidX, innerStartY, innerStartY));

  int diagonalInset = 0;
  findMaxOpacity(image->rows.data(), innerStartX, innerStartY, innerMidX,
                 innerMidY, 1, 1, &diagonalInset);

  /* Determine source radius based upon inset:
   *     sqrt(r^2 + r^2) = sqrt(i^2 + i^2) + r
   *     sqrt(2) * r = sqrt(2) * i + r
   *     (sqrt(2) - 1) * r = sqrt(2) * i
   *     r = sqrt(2) / (sqrt(2) - 1) * i
   */
  image->outlineRadius = 3.4142f * diagonalInset;

  if (kDebug) {
    printf("outline insets %d %d %d %d, rad %f, alpha %x\n",
           image->outlineInsetsLeft, image->outlineInsetsTop,
           image->outlineInsetsRight, image->outlineInsetsBottom,
           image->outlineRadius, image->outlineAlpha);
  }
}

static uint32_t getColor(png_bytepp rows, int left, int top, int right,
                         int bottom) {
  png_bytep color = rows[top] + left * 4;

  if (left > right || top > bottom) {
    return android::Res_png_9patch::TRANSPARENT_COLOR;
  }

  while (top <= bottom) {
    for (int i = left; i <= right; i++) {
      png_bytep p = rows[top] + i * 4;
      if (color[3] == 0) {
        if (p[3] != 0) {
          return android::Res_png_9patch::NO_COLOR;
        }
      } else if (p[0] != color[0] || p[1] != color[1] || p[2] != color[2] ||
                 p[3] != color[3]) {
        return android::Res_png_9patch::NO_COLOR;
      }
    }
    top++;
  }

  if (color[3] == 0) {
    return android::Res_png_9patch::TRANSPARENT_COLOR;
  }
  return (color[3] << 24) | (color[0] << 16) | (color[1] << 8) | color[2];
}

static bool do9Patch(PngInfo* image, std::string* outError) {
  image->is9Patch = true;

  int W = image->width;
  int H = image->height;
  int i, j;

  const int maxSizeXDivs = W * sizeof(int32_t);
  const int maxSizeYDivs = H * sizeof(int32_t);
  int32_t* xDivs = image->xDivs = new int32_t[W];
  int32_t* yDivs = image->yDivs = new int32_t[H];
  uint8_t numXDivs = 0;
  uint8_t numYDivs = 0;

  int8_t numColors;
  int numRows;
  int numCols;
  int top;
  int left;
  int right;
  int bottom;
  memset(xDivs, -1, maxSizeXDivs);
  memset(yDivs, -1, maxSizeYDivs);
  image->info9Patch.paddingLeft = image->info9Patch.paddingRight = -1;
  image->info9Patch.paddingTop = image->info9Patch.paddingBottom = -1;
  image->layoutBoundsLeft = image->layoutBoundsRight = 0;
  image->layoutBoundsTop = image->layoutBoundsBottom = 0;

  png_bytep p = image->rows[0];
  bool transparent = p[3] == 0;
  bool hasColor = false;

  const char* errorMsg = nullptr;
  int errorPixel = -1;
  const char* errorEdge = nullptr;

  int colorIndex = 0;
  std::vector<png_bytep> newRows;

  // Validate size...
  if (W < 3 || H < 3) {
    errorMsg = "Image must be at least 3x3 (1x1 without frame) pixels";
    goto getout;
  }

  // Validate frame...
  if (!transparent &&
      (p[0] != 0xFF || p[1] != 0xFF || p[2] != 0xFF || p[3] != 0xFF)) {
    errorMsg = "Must have one-pixel frame that is either transparent or white";
    goto getout;
  }

  // Find left and right of sizing areas...
  if (!getHorizontalTicks(p, W, transparent, true, &xDivs[0], &xDivs[1],
                          &errorMsg, &numXDivs, true)) {
    errorPixel = xDivs[0];
    errorEdge = "top";
    goto getout;
  }

  // Find top and bottom of sizing areas...
  if (!getVerticalTicks(image->rows.data(), 0, H, transparent, true, &yDivs[0],
                        &yDivs[1], &errorMsg, &numYDivs, true)) {
    errorPixel = yDivs[0];
    errorEdge = "left";
    goto getout;
  }

  // Copy patch size data into image...
  image->info9Patch.numXDivs = numXDivs;
  image->info9Patch.numYDivs = numYDivs;

  // Find left and right of padding area...
  if (!getHorizontalTicks(image->rows[H - 1], W, transparent, false,
                          &image->info9Patch.paddingLeft,
                          &image->info9Patch.paddingRight, &errorMsg, nullptr,
                          false)) {
    errorPixel = image->info9Patch.paddingLeft;
    errorEdge = "bottom";
    goto getout;
  }

  // Find top and bottom of padding area...
  if (!getVerticalTicks(image->rows.data(), (W - 1) * 4, H, transparent, false,
                        &image->info9Patch.paddingTop,
                        &image->info9Patch.paddingBottom, &errorMsg, nullptr,
                        false)) {
    errorPixel = image->info9Patch.paddingTop;
    errorEdge = "right";
    goto getout;
  }

  // Find left and right of layout padding...
  getHorizontalLayoutBoundsTicks(image->rows[H - 1], W, transparent, false,
                                 &image->layoutBoundsLeft,
                                 &image->layoutBoundsRight, &errorMsg);

  getVerticalLayoutBoundsTicks(image->rows.data(), (W - 1) * 4, H, transparent,
                               false, &image->layoutBoundsTop,
                               &image->layoutBoundsBottom, &errorMsg);

  image->haveLayoutBounds =
      image->layoutBoundsLeft != 0 || image->layoutBoundsRight != 0 ||
      image->layoutBoundsTop != 0 || image->layoutBoundsBottom != 0;

  if (image->haveLayoutBounds) {
    if (kDebug) {
      printf("layoutBounds=%d %d %d %d\n", image->layoutBoundsLeft,
             image->layoutBoundsTop, image->layoutBoundsRight,
             image->layoutBoundsBottom);
    }
  }

  // use opacity of pixels to estimate the round rect outline
  getOutline(image);

  // If padding is not yet specified, take values from size.
  if (image->info9Patch.paddingLeft < 0) {
    image->info9Patch.paddingLeft = xDivs[0];
    image->info9Patch.paddingRight = W - 2 - xDivs[1];
  } else {
    // Adjust value to be correct!
    image->info9Patch.paddingRight = W - 2 - image->info9Patch.paddingRight;
  }
  if (image->info9Patch.paddingTop < 0) {
    image->info9Patch.paddingTop = yDivs[0];
    image->info9Patch.paddingBottom = H - 2 - yDivs[1];
  } else {
    // Adjust value to be correct!
    image->info9Patch.paddingBottom = H - 2 - image->info9Patch.paddingBottom;
  }

  /*    if (kDebug) {
          printf("Size ticks for %s: x0=%d, x1=%d, y0=%d, y1=%d\n", imageName,
                  xDivs[0], xDivs[1],
                  yDivs[0], yDivs[1]);
          printf("padding ticks for %s: l=%d, r=%d, t=%d, b=%d\n", imageName,
                  image->info9Patch.paddingLeft, image->info9Patch.paddingRight,
                  image->info9Patch.paddingTop,
     image->info9Patch.paddingBottom);
      }*/

  // Remove frame from image.
  newRows.resize(H - 2);
  for (i = 0; i < H - 2; i++) {
    newRows[i] = image->rows[i + 1];
    memmove(newRows[i], newRows[i] + 4, (W - 2) * 4);
  }
  image->rows.swap(newRows);

  image->width -= 2;
  W = image->width;
  image->height -= 2;
  H = image->height;

  // Figure out the number of rows and columns in the N-patch
  numCols = numXDivs + 1;
  if (xDivs[0] == 0) {  // Column 1 is strechable
    numCols--;
  }
  if (xDivs[numXDivs - 1] == W) {
    numCols--;
  }
  numRows = numYDivs + 1;
  if (yDivs[0] == 0) {  // Row 1 is strechable
    numRows--;
  }
  if (yDivs[numYDivs - 1] == H) {
    numRows--;
  }

  // Make sure the amount of rows and columns will fit in the number of
  // colors we can use in the 9-patch format.
  if (numRows * numCols > 0x7F) {
    errorMsg = "Too many rows and columns in 9-patch perimeter";
    goto getout;
  }

  numColors = numRows * numCols;
  image->info9Patch.numColors = numColors;
  image->colors.resize(numColors);

  // Fill in color information for each patch.

  uint32_t c;
  top = 0;

  // The first row always starts with the top being at y=0 and the bottom
  // being either yDivs[1] (if yDivs[0]=0) of yDivs[0].  In the former case
  // the first row is stretchable along the Y axis, otherwise it is fixed.
  // The last row always ends with the bottom being bitmap.height and the top
  // being either yDivs[numYDivs-2] (if yDivs[numYDivs-1]=bitmap.height) or
  // yDivs[numYDivs-1]. In the former case the last row is stretchable along
  // the Y axis, otherwise it is fixed.
  //
  // The first and last columns are similarly treated with respect to the X
  // axis.
  //
  // The above is to help explain some of the special casing that goes on the
  // code below.

  // The initial yDiv and whether the first row is considered stretchable or
  // not depends on whether yDiv[0] was zero or not.
  for (j = (yDivs[0] == 0 ? 1 : 0); j <= numYDivs && top < H; j++) {
    if (j == numYDivs) {
      bottom = H;
    } else {
      bottom = yDivs[j];
    }
    left = 0;
    // The initial xDiv and whether the first column is considered
    // stretchable or not depends on whether xDiv[0] was zero or not.
    for (i = xDivs[0] == 0 ? 1 : 0; i <= numXDivs && left < W; i++) {
      if (i == numXDivs) {
        right = W;
      } else {
        right = xDivs[i];
      }
      c = getColor(image->rows.data(), left, top, right - 1, bottom - 1);
      image->colors[colorIndex++] = c;
      if (kDebug) {
        if (c != android::Res_png_9patch::NO_COLOR) {
          hasColor = true;
        }
      }
      left = right;
    }
    top = bottom;
  }

  assert(colorIndex == numColors);

  if (kDebug && hasColor) {
    for (i = 0; i < numColors; i++) {
      if (i == 0) printf("Colors:\n");
      printf(" #%08x", image->colors[i]);
      if (i == numColors - 1) printf("\n");
    }
  }
getout:
  if (errorMsg) {
    std::stringstream err;
    err << "9-patch malformed: " << errorMsg;
    if (errorEdge) {
      err << "." << std::endl;
      if (errorPixel >= 0) {
        err << "Found at pixel #" << errorPixel << " along " << errorEdge
            << " edge";
      } else {
        err << "Found along " << errorEdge << " edge";
      }
    }
    *outError = err.str();
    return false;
  }
  return true;
}

bool Png::process(const Source& source, std::istream* input,
                  BigBuffer* outBuffer, const PngOptions& options) {
  png_byte signature[kPngSignatureSize];

  // Read the PNG signature first.
  if (!input->read(reinterpret_cast<char*>(signature), kPngSignatureSize)) {
    mDiag->Error(DiagMessage() << strerror(errno));
    return false;
  }

  // If the PNG signature doesn't match, bail early.
  if (png_sig_cmp(signature, 0, kPngSignatureSize) != 0) {
    mDiag->Error(DiagMessage() << "not a valid png file");
    return false;
  }

  bool result = false;
  png_structp readPtr = nullptr;
  png_infop infoPtr = nullptr;
  png_structp writePtr = nullptr;
  png_infop writeInfoPtr = nullptr;
  PngInfo pngInfo = {};

  readPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, nullptr, nullptr);
  if (!readPtr) {
    mDiag->Error(DiagMessage() << "failed to allocate read ptr");
    goto bail;
  }

  infoPtr = png_create_info_struct(readPtr);
  if (!infoPtr) {
    mDiag->Error(DiagMessage() << "failed to allocate info ptr");
    goto bail;
  }

  png_set_error_fn(readPtr, reinterpret_cast<png_voidp>(mDiag), nullptr,
                   logWarning);

  // Set the read function to read from std::istream.
  png_set_read_fn(readPtr, (png_voidp)input, readDataFromStream);

  if (!readPng(mDiag, readPtr, infoPtr, &pngInfo)) {
    goto bail;
  }

  if (util::EndsWith(source.path, ".9.png")) {
    std::string errorMsg;
    if (!do9Patch(&pngInfo, &errorMsg)) {
      mDiag->Error(DiagMessage() << errorMsg);
      goto bail;
    }
  }

  writePtr =
      png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, nullptr, nullptr);
  if (!writePtr) {
    mDiag->Error(DiagMessage() << "failed to allocate write ptr");
    goto bail;
  }

  writeInfoPtr = png_create_info_struct(writePtr);
  if (!writeInfoPtr) {
    mDiag->Error(DiagMessage() << "failed to allocate write info ptr");
    goto bail;
  }

  png_set_error_fn(writePtr, nullptr, nullptr, logWarning);

  // Set the write function to write to std::ostream.
  png_set_write_fn(writePtr, (png_voidp)outBuffer, writeDataToStream,
                   flushDataToStream);

  if (!writePng(mDiag, writePtr, writeInfoPtr, &pngInfo,
                options.grayscale_tolerance)) {
    goto bail;
  }

  result = true;
bail:
  if (readPtr) {
    png_destroy_read_struct(&readPtr, &infoPtr, nullptr);
  }

  if (writePtr) {
    png_destroy_write_struct(&writePtr, &writeInfoPtr);
  }
  return result;
}

}  // namespace aapt
