/*
 * 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 "BigBuffer.h"
#include "Logger.h"
#include "Png.h"
#include "Source.h"
#include "Util.h"

#include <androidfw/ResourceTypes.h>
#include <iostream>
#include <png.h>
#include <sstream>
#include <string>
#include <vector>
#include <zlib.h>

namespace aapt {

constexpr bool kDebug = false;
constexpr size_t kPngSignatureSize = 8u;

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) {
    SourceLogger* logger = reinterpret_cast<SourceLogger*>(png_get_error_ptr(readPtr));
    logger->warn() << warningMessage << "." << std::endl;
}


static bool readPng(png_structp readPtr, png_infop infoPtr, PngInfo* outInfo,
                    std::string* outError) {
    if (setjmp(png_jmpbuf(readPtr))) {
        *outError = "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");
            }
        }
    }
}*/

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

static void analyze_image(SourceLogger* logger, 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) {
            logger->note() << "forcing image to gray (max deviation = " << maxGrayDeviation
                           << ")."
                           << std::endl;
            *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(png_structp writePtr, png_infop infoPtr, PngInfo* info,
                     int grayScaleTolerance, SourceLogger* logger, std::string* outError) {
    if (setjmp(png_jmpbuf(writePtr))) {
        *outError = "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) {
        logger->note() << "writing image: w = " << info->width
                       << ", h = " << info->height
                       << std::endl;
    }

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

    analyze_image(logger, *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:
            logger->note() << "has " << paletteEntries
                           << " colors" << (hasTransparency ? " (with alpha)" : "")
                           << ", using PNG_COLOR_TYPE_PALLETTE."
                           << std::endl;
            break;
        case PNG_COLOR_TYPE_GRAY:
            logger->note() << "is opaque gray, using PNG_COLOR_TYPE_GRAY." << std::endl;
            break;
        case PNG_COLOR_TYPE_GRAY_ALPHA:
            logger->note() << "is gray + alpha, using PNG_COLOR_TYPE_GRAY_ALPHA." << std::endl;
            break;
        case PNG_COLOR_TYPE_RGB:
            logger->note() << "is opaque RGB, using PNG_COLOR_TYPE_RGB." << std::endl;
            break;
        case PNG_COLOR_TYPE_RGB_ALPHA:
            logger->note() << "is RGB + alpha, using PNG_COLOR_TYPE_RGB_ALPHA." << std::endl;
            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) {
            logger->note() << "adding 9-patch info..." << std::endl;
        }
        strcpy((char*)unknowns[pIndex].name, "npTc");
        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;
        strcpy((char*)unknowns[oIndex].name, "npOl");
        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;
            strcpy((char*)unknowns[bIndex].name, "npLb");
            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) {
        logger->note() << "image written: w = " << width << ", h = " << height
                       << ", d = " << bitDepth << ", colors = " << colorType
                       << ", inter = " << interlaceType << ", comp = " << compressionType
                       << std::endl;
    }
    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 Options& options, std::string* outError) {
    png_byte signature[kPngSignatureSize];

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

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

    SourceLogger logger(source);
    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) {
        *outError = "failed to allocate read ptr";
        goto bail;
    }

    infoPtr = png_create_info_struct(readPtr);
    if (!infoPtr) {
        *outError = "failed to allocate info ptr";
        goto bail;
    }

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

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

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

    if (util::stringEndsWith<char>(source.path, ".9.png")) {
        if (!do9Patch(&pngInfo, outError)) {
            goto bail;
        }
    }

    writePtr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, nullptr, nullptr);
    if (!writePtr) {
        *outError = "failed to allocate write ptr";
        goto bail;
    }

    writeInfoPtr = png_create_info_struct(writePtr);
    if (!writeInfoPtr) {
        *outError = "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(writePtr, writeInfoPtr, &pngInfo, options.grayScaleTolerance, &logger,
                  outError)) {
        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
