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

#include "src/codec/SkTiffUtility.h"

#include "include/core/SkData.h"
#include "src/codec/SkCodecPriv.h"

#include <cstddef>
#include <utility>

namespace SkTiff {

constexpr size_t kSizeEntry = 12;
constexpr size_t kSizeShort = 2;
constexpr size_t kSizeLong = 4;

bool ImageFileDirectory::IsValidType(uint16_t type) { return type >= 1 && type <= 12; }

size_t ImageFileDirectory::BytesForType(uint16_t type) {
    switch (type) {
        case kTypeUnsignedByte:
            return 1;
        case kTypeAsciiString:
            return 1;
        case kTypeUnsignedShort:
            return kSizeShort;
        case kTypeUnsignedLong:
            return kSizeLong;
        case kTypeUnsignedRational:
            return 8;
        case kTypeSignedByte:
            return 1;
        case kTypeUndefined:
            return 1;
        case kTypeSignedShort:
            return kSizeShort;
        case kTypeSignedLong:
            return kSizeLong;
        case kTypeSignedRational:
            return 8;
        case kTypeSingleFloat:
            return 4;
        case kTypeDoubleFloat:
            return 8;
    }
    return 0;
}

// Helper function for computing the address of an entry.
static const uint8_t* get_entry_address(const SkData* data,
                                        uint32_t ifdOffset,
                                        uint16_t entryIndex) {
    return data->bytes() +           // Base address
           ifdOffset +               // IFD offset
           kSizeShort +              // IFD number of entries
           kSizeEntry * entryIndex;  // Entries
}

// Return true if the IFD starting at |ifdOffset| contains valid number of entries (that doesn't
// overrun |data|).
static bool validate_ifd(const SkData* data,
                         bool littleEndian,
                         uint32_t ifdOffset,
                         bool allowTruncated,
                         uint16_t* outNumEntries,
                         uint32_t* outNextIfdOffset) {
    const uint8_t* dataCurrent = data->bytes();
    size_t dataSize = data->size();

    // Seek to the IFD offset.
    if (dataSize < ifdOffset) {
        SkCodecPrintf("IFD offset is too large.\n");
        return false;
    }
    dataCurrent += ifdOffset;
    dataSize -= ifdOffset;

    // Read the number of entries.
    if (dataSize < kSizeShort) {
        SkCodecPrintf("Insufficient space to store number of entries.\n");
        return false;
    }
    uint16_t numEntries = get_endian_short(dataCurrent, littleEndian);
    dataCurrent += kSizeShort;
    dataSize -= kSizeShort;

    // Check that there is enough space for all entries.
    if (dataSize < kSizeEntry * numEntries) {
        SkCodecPrintf("Insufficient space (%u) to store all %u entries.\n",
                      static_cast<uint32_t>(data->size()),
                      numEntries);
        if (allowTruncated) {
            // Set the number of entries to the number of entries that can be fully read, and set
            // the next IFD offset to 0 (indicating that there is no next IFD).
            *outNumEntries = dataSize / kSizeEntry;
            *outNextIfdOffset = 0;
            return true;
        }
        return false;
    }

    // Save the number of entries.
    *outNumEntries = numEntries;

    // Seek past the entries.
    dataCurrent += kSizeEntry * numEntries;
    dataSize -= kSizeEntry * numEntries;

    // Read the next IFD offset.
    if (dataSize < kSizeLong) {
        SkCodecPrintf("Insufficient space to store next IFD offset.\n");
        if (allowTruncated) {
            // Set the next IFD offset to 0 (indicating that there is no next IFD).
            *outNextIfdOffset = 0;
            return true;
        }
        return false;
    }

    // Save the next IFD offset.
    *outNextIfdOffset = get_endian_int(dataCurrent, littleEndian);
    return true;
}

bool ImageFileDirectory::ParseHeader(const SkData* data,
                                     bool* outLittleEndian,
                                     uint32_t* outIfdOffset) {
    // Read the endianness (4 bytes) and IFD offset (4 bytes).
    if (data->size() < 8) {
        SkCodecPrintf("Tiff header must be at least 8 bytes.\n");
        return false;
    }
    if (!is_valid_endian_marker(data->bytes(), outLittleEndian)) {
        SkCodecPrintf("Tiff header had invalid endian marker 0x%x,0x%x,0x%x,0x%x.\n",
                      data->bytes()[0],
                      data->bytes()[1],
                      data->bytes()[2],
                      data->bytes()[3]);
        return false;
    }
    *outIfdOffset = get_endian_int(data->bytes() + 4, *outLittleEndian);
    return true;
}

std::unique_ptr<ImageFileDirectory> ImageFileDirectory::MakeFromOffset(sk_sp<SkData> data,
                                                                       bool littleEndian,
                                                                       uint32_t ifdOffset,
                                                                       bool allowTruncated) {
    uint16_t numEntries = 0;
    uint32_t nextOffset = 0;
    if (!validate_ifd(
                data.get(), littleEndian, ifdOffset, allowTruncated, &numEntries, &nextOffset)) {
        SkCodecPrintf("Failed to validate IFD.\n");
        return nullptr;
    }
    return std::unique_ptr<ImageFileDirectory>(new ImageFileDirectory(
            std::move(data), littleEndian, ifdOffset, numEntries, nextOffset));
}

ImageFileDirectory::ImageFileDirectory(sk_sp<SkData> data,
                                       bool littleEndian,
                                       uint32_t offset,
                                       uint16_t numEntries,
                                       uint32_t nextIfdOffset)
        : fData(std::move(data))
        , fLittleEndian(littleEndian)
        , fOffset(offset)
        , fNumEntries(numEntries)
        , fNextIfdOffset(nextIfdOffset) {}

uint16_t ImageFileDirectory::getEntryTag(uint16_t entryIndex) const {
    const uint8_t* entry = get_entry_address(fData.get(), fOffset, entryIndex);
    return get_endian_short(entry, fLittleEndian);
}

bool ImageFileDirectory::getEntryRawData(uint16_t entryIndex,
                                         uint16_t* outTag,
                                         uint16_t* outType,
                                         uint32_t* outCount,
                                         const uint8_t** outData,
                                         size_t* outDataSize) const {
    const uint8_t* entry = get_entry_address(fData.get(), fOffset, entryIndex);

    // Read the tag
    const uint16_t tag = get_endian_short(entry, fLittleEndian);
    entry += kSizeShort;

    // Read the type.
    const uint16_t type = get_endian_short(entry, fLittleEndian);
    entry += kSizeShort;
    if (!IsValidType(type)) {
        return false;
    }

    // Read the count.
    const uint32_t count = get_endian_int(entry, fLittleEndian);
    entry += kSizeLong;

    // If the entry fits in the remaining 4 bytes, use that.
    const size_t entryDataBytes = BytesForType(type) * count;
    const uint8_t* entryData = nullptr;
    if (entryDataBytes <= kSizeLong) {
        entryData = entry;
    } else {
        // Otherwise, the next 4 bytes specify an offset where the data can be found.
        const uint32_t entryDataOffset = get_endian_int(entry, fLittleEndian);
        if (fData->size() < entryDataOffset || fData->size() - entryDataOffset < entryDataBytes) {
            return false;
        }
        entryData = fData->bytes() + entryDataOffset;
    }

    if (outTag) *outTag = tag;
    if (outType) *outType = type;
    if (outCount) *outCount = count;
    if (outData) *outData = entryData;
    if (outDataSize) *outDataSize = entryDataBytes;
    return true;
}

sk_sp<SkData> ImageFileDirectory::getEntryUndefinedData(uint16_t entryIndex) const {
    uint16_t type = 0;
    uint32_t count = 0;
    const uint8_t* data = nullptr;
    size_t size = 0;
    if (!getEntryRawData(entryIndex, nullptr, &type, &count, &data, &size)) {
        return nullptr;
    }
    if (type != kTypeUndefined) {
        return nullptr;
    }
    return SkData::MakeSubset(fData.get(), data - fData->bytes(), size);
}

bool ImageFileDirectory::getEntryValuesGeneric(uint16_t entryIndex,
                                               uint16_t type,
                                               uint32_t count,
                                               void* values) const {
    uint16_t entryType = 0;
    uint32_t entryCount = 0;
    const uint8_t* entryData = nullptr;
    if (!getEntryRawData(entryIndex, nullptr, &entryType, &entryCount, &entryData, nullptr)) {
        return false;
    }
    if (type != entryType) {
        return false;
    }
    if (count != entryCount) {
        return false;
    }
    for (uint32_t i = 0; i < count; ++i) {
        const uint8_t* data = entryData + i * BytesForType(kTypeUnsignedLong);
        switch (type) {
            case kTypeUnsignedShort:
                reinterpret_cast<uint16_t*>(values)[i] = get_endian_short(data, fLittleEndian);
                break;
            case kTypeUnsignedLong:
                reinterpret_cast<uint32_t*>(values)[i] = get_endian_int(data, fLittleEndian);
                break;
            case kTypeSignedRational: {
                uint32_t numerator = get_endian_int(data, fLittleEndian);
                uint32_t denominator = get_endian_int(data + kSizeLong, fLittleEndian);
                if (denominator == 0) {
                    // The TIFF specification does not indicate a behavior when the denominator is
                    // zero.  The behavior of returning zero for a denominator of zero is a
                    // preservation of the behavior introduced in https://crrev.com/767874.
                    reinterpret_cast<float*>(values)[i] = 0;
                } else {
                    reinterpret_cast<float*>(values)[i] =
                            numerator / static_cast<float>(denominator);
                }
                break;
            }
            case kTypeUnsignedRational: {
                uint32_t numerator = get_endian_int(data, fLittleEndian);
                uint32_t denominator = get_endian_int(data + kSizeLong, fLittleEndian);
                if (denominator == 0) {
                    // See comments in kTypeSignedRational.
                    reinterpret_cast<float*>(values)[i] = 0.f;
                } else {
                    reinterpret_cast<float*>(values)[i] =
                            numerator / static_cast<float>(denominator);
                }
                break;
            }
            default:
                SkCodecPrintf("Unsupported type %u\n", type);
                return false;
                break;
        }
    }
    return true;
}

}  // namespace SkTiff
