/*
 * 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/BigBuffer.h"
#include "androidfw/ResourceTypes.h"
#include "androidfw/Source.h"
#include "trace/TraceBuffer.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) {
  android::BigBuffer* outBuffer = reinterpret_cast<android::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) {
  android::IDiagnostics* diag =
      reinterpret_cast<android::IDiagnostics*>(png_get_error_ptr(readPtr));
  diag->Warn(android::DiagMessage() << warningMessage);
}

static bool readPng(android::IDiagnostics* diag, png_structp readPtr, png_infop infoPtr,
                    PngInfo* outInfo) {
  if (setjmp(png_jmpbuf(readPtr))) {
    diag->Error(android::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(android::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(android::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(android::IDiagnostics* diag, png_structp writePtr, png_infop infoPtr,
                     PngInfo* info, int grayScaleTolerance) {
  if (setjmp(png_jmpbuf(writePtr))) {
    diag->Error(android::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(android::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(android::DiagMessage() << "has " << paletteEntries << " colors"
                                          << (hasTransparency ? " (with alpha)" : "")
                                          << ", using PNG_COLOR_TYPE_PALLETTE");
        break;
      case PNG_COLOR_TYPE_GRAY:
        diag->Note(android::DiagMessage() << "is opaque gray, using PNG_COLOR_TYPE_GRAY");
        break;
      case PNG_COLOR_TYPE_GRAY_ALPHA:
        diag->Note(android::DiagMessage() << "is gray + alpha, using PNG_COLOR_TYPE_GRAY_ALPHA");
        break;
      case PNG_COLOR_TYPE_RGB:
        diag->Note(android::DiagMessage() << "is opaque RGB, using PNG_COLOR_TYPE_RGB");
        break;
      case PNG_COLOR_TYPE_RGB_ALPHA:
        diag->Note(android::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(android::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(android::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 android::Source& source, std::istream* input, android::BigBuffer* outBuffer,
                  const PngOptions& options) {
  TRACE_CALL();
  png_byte signature[kPngSignatureSize];

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

  // If the PNG signature doesn't match, bail early.
  if (png_sig_cmp(signature, 0, kPngSignatureSize) != 0) {
    mDiag->Error(android::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(android::DiagMessage() << "failed to allocate read ptr");
    goto bail;
  }

  infoPtr = png_create_info_struct(readPtr);
  if (!infoPtr) {
    mDiag->Error(android::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(android::DiagMessage() << errorMsg);
      goto bail;
    }
  }

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

  writeInfoPtr = png_create_info_struct(writePtr);
  if (!writeInfoPtr) {
    mDiag->Error(android::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
