/*
 * 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 "util/BigBuffer.h"
#include "Png.h"
#include "Source.h"
#include "util/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) {
    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..");
        }
        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) {
        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::stringEndsWith<char>(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.grayScaleTolerance)) {
        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
