/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkPDFConvertType1FontStream.h"

#include <ctype.h>

static bool parsePFBSection(const uint8_t** src, size_t* len, int sectionType,
                            size_t* size) {
    // PFB sections have a two or six bytes header. 0x80 and a one byte
    // section type followed by a four byte section length.  Type one is
    // an ASCII section (includes a length), type two is a binary section
    // (includes a length) and type three is an EOF marker with no length.
    const uint8_t* buf = *src;
    if (*len < 2 || buf[0] != 0x80 || buf[1] != sectionType) {
        return false;
    } else if (buf[1] == 3) {
        return true;
    } else if (*len < 6) {
        return false;
    }

    *size = (size_t)buf[2] | ((size_t)buf[3] << 8) | ((size_t)buf[4] << 16) |
            ((size_t)buf[5] << 24);
    size_t consumed = *size + 6;
    if (consumed > *len) {
        return false;
    }
    *src = *src + consumed;
    *len = *len - consumed;
    return true;
}

static bool parsePFB(const uint8_t* src, size_t size, size_t* headerLen,
                     size_t* dataLen, size_t* trailerLen) {
    const uint8_t* srcPtr = src;
    size_t remaining = size;

    return parsePFBSection(&srcPtr, &remaining, 1, headerLen) &&
           parsePFBSection(&srcPtr, &remaining, 2, dataLen) &&
           parsePFBSection(&srcPtr, &remaining, 1, trailerLen) &&
           parsePFBSection(&srcPtr, &remaining, 3, nullptr);
}

/* The sections of a PFA file are implicitly defined.  The body starts
 * after the line containing "eexec," and the trailer starts with 512
 * literal 0's followed by "cleartomark" (plus arbitrary white space).
 *
 * This function assumes that src is NUL terminated, but the NUL
 * termination is not included in size.
 *
 */
static bool parsePFA(const char* src, size_t size, size_t* headerLen,
                     size_t* hexDataLen, size_t* dataLen, size_t* trailerLen) {
    const char* end = src + size;

    const char* dataPos = strstr(src, "eexec");
    if (!dataPos) {
        return false;
    }
    dataPos += strlen("eexec");
    while ((*dataPos == '\n' || *dataPos == '\r' || *dataPos == ' ') &&
            dataPos < end) {
        dataPos++;
    }
    *headerLen = dataPos - src;

    const char* trailerPos = strstr(dataPos, "cleartomark");
    if (!trailerPos) {
        return false;
    }
    int zeroCount = 0;
    for (trailerPos--; trailerPos > dataPos && zeroCount < 512; trailerPos--) {
        if (*trailerPos == '\n' || *trailerPos == '\r' || *trailerPos == ' ') {
            continue;
        } else if (*trailerPos == '0') {
            zeroCount++;
        } else {
            return false;
        }
    }
    if (zeroCount != 512) {
        return false;
    }

    *hexDataLen = trailerPos - src - *headerLen;
    *trailerLen = size - *headerLen - *hexDataLen;

    // Verify that the data section is hex encoded and count the bytes.
    int nibbles = 0;
    for (; dataPos < trailerPos; dataPos++) {
        if (isspace(*dataPos)) {
            continue;
        }
        if (!isxdigit(*dataPos)) {
            return false;
        }
        nibbles++;
    }
    *dataLen = (nibbles + 1) / 2;

    return true;
}

static int8_t hexToBin(uint8_t c) {
    if (!isxdigit(c)) {
        return -1;
    } else if (c <= '9') {
        return c - '0';
    } else if (c <= 'F') {
        return c - 'A' + 10;
    } else if (c <= 'f') {
        return c - 'a' + 10;
    }
    return -1;
}

sk_sp<SkData> SkPDFConvertType1FontStream(
        std::unique_ptr<SkStreamAsset> srcStream, size_t* headerLen,
        size_t* dataLen, size_t* trailerLen) {
    size_t srcLen = srcStream ? srcStream->getLength() : 0;
    SkASSERT(srcLen);
    if (!srcLen) {
        return nullptr;
    }
    // Flatten and Nul-terminate the source stream so that we can use
    // strstr() to search it.
    SkAutoTMalloc<uint8_t> sourceBuffer(SkToInt(srcLen + 1));
    (void)srcStream->read(sourceBuffer.get(), srcLen);
    sourceBuffer[SkToInt(srcLen)] = 0;
    const uint8_t* src = sourceBuffer.get();

    if (parsePFB(src, srcLen, headerLen, dataLen, trailerLen)) {
        static const int kPFBSectionHeaderLength = 6;
        const size_t length = *headerLen + *dataLen + *trailerLen;
        SkASSERT(length > 0);
        SkASSERT(length + (2 * kPFBSectionHeaderLength) <= srcLen);

        sk_sp<SkData> data(SkData::MakeUninitialized(length));

        const uint8_t* const srcHeader = src + kPFBSectionHeaderLength;
        // There is a six-byte section header before header and data
        // (but not trailer) that we're not going to copy.
        const uint8_t* const srcData = srcHeader + *headerLen + kPFBSectionHeaderLength;
        const uint8_t* const srcTrailer = srcData + *headerLen;

        uint8_t* const resultHeader = (uint8_t*)data->writable_data();
        uint8_t* const resultData = resultHeader + *headerLen;
        uint8_t* const resultTrailer = resultData + *dataLen;

        SkASSERT(resultTrailer + *trailerLen == resultHeader + length);

        memcpy(resultHeader,  srcHeader,  *headerLen);
        memcpy(resultData,    srcData,    *dataLen);
        memcpy(resultTrailer, srcTrailer, *trailerLen);

        return data;
    }

    // A PFA has to be converted for PDF.
    size_t hexDataLen;
    if (!parsePFA((const char*)src, srcLen, headerLen, &hexDataLen, dataLen,
                 trailerLen)) {
        return nullptr;
    }
    const size_t length = *headerLen + *dataLen + *trailerLen;
    SkASSERT(length > 0);
    auto data = SkData::MakeUninitialized(length);
    uint8_t* buffer = (uint8_t*)data->writable_data();

    memcpy(buffer, src, *headerLen);
    uint8_t* const resultData = &(buffer[*headerLen]);

    const uint8_t* hexData = src + *headerLen;
    const uint8_t* trailer = hexData + hexDataLen;
    size_t outputOffset = 0;
    uint8_t dataByte = 0;  // To hush compiler.
    bool highNibble = true;
    for (; hexData < trailer; hexData++) {
        int8_t curNibble = hexToBin(*hexData);
        if (curNibble < 0) {
            continue;
        }
        if (highNibble) {
            dataByte = curNibble << 4;
            highNibble = false;
        } else {
            dataByte |= curNibble;
            highNibble = true;
            resultData[outputOffset++] = dataByte;
        }
    }
    if (!highNibble) {
        resultData[outputOffset++] = dataByte;
    }
    SkASSERT(outputOffset == *dataLen);

    uint8_t* const resultTrailer = &(buffer[SkToInt(*headerLen + outputOffset)]);
    memcpy(resultTrailer, src + *headerLen + hexDataLen, *trailerLen);
    return data;
}
