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

#include "fuzz/Fuzz.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkPixmap.h"
#include "include/encode/SkJpegEncoder.h"
#include "include/encode/SkPngEncoder.h"
#include "include/encode/SkWebpEncoder.h"
#include "include/utils/SkRandom.h"
#include "src/core/SkOSFile.h"

#include <vector>

// These values were picked arbitrarily to hopefully limit the size of the
// serialized SkPixmaps.
constexpr int MAX_WIDTH = 512;
constexpr int MAX_HEIGHT = 512;

static SkBitmap make_fuzzed_bitmap(Fuzz* fuzz) {
    SkBitmap bm;
    uint32_t w, h;
    fuzz->nextRange(&w, 1, MAX_WIDTH);
    fuzz->nextRange(&h, 1, MAX_HEIGHT);
    if (!bm.tryAllocPixels(SkImageInfo::MakeN32Premul(w, h))) {
        return bm;
    }
    uint32_t n = w * h;
    fuzz->nextN((SkPMColor*)bm.getPixels(), n);
    return bm;
}

DEF_FUZZ(PNGEncoder, fuzz) {
    auto bm = make_fuzzed_bitmap(fuzz);

    auto opts = SkPngEncoder::Options{};
    fuzz->nextRange(&opts.fZLibLevel, 0, 9);

    SkDynamicMemoryWStream dest;
    SkPngEncoder::Encode(&dest, bm.pixmap(), opts);
}

DEF_FUZZ(JPEGEncoder, fuzz) {
    auto bm = make_fuzzed_bitmap(fuzz);

    auto opts = SkJpegEncoder::Options{};
    fuzz->nextRange(&opts.fQuality, 0, 100);

    SkDynamicMemoryWStream dest;
    (void)SkJpegEncoder::Encode(&dest, bm.pixmap(), opts);
}

DEF_FUZZ(WEBPEncoder, fuzz) {
    auto bm = make_fuzzed_bitmap(fuzz);

    auto opts = SkWebpEncoder::Options{};
    fuzz->nextRange(&opts.fQuality, 0.0f, 100.0f);
    bool lossy;
    fuzz->next(&lossy);
    if (lossy) {
        opts.fCompression = SkWebpEncoder::Compression::kLossy;
    } else {
        opts.fCompression = SkWebpEncoder::Compression::kLossless;
    }

    SkDynamicMemoryWStream dest;
    (void)SkWebpEncoder::Encode(&dest, bm.pixmap(), opts);
}

// Not a real fuzz endpoint, but a helper to take in real, good images
// and dump out a corpus for this fuzzer.
DEF_FUZZ(_MakeEncoderCorpus, fuzz) {
    auto bytes = fuzz->fBytes;
    SkDebugf("bytes %zu\n", bytes->size());
    auto img = SkImage::MakeFromEncoded(bytes);
    if (nullptr == img.get()) {
        SkDebugf("invalid image, could not decode\n");
        return;
    }
    if (img->width() > MAX_WIDTH || img->height() > MAX_HEIGHT) {
        SkDebugf("Too big (%d x %d)\n", img->width(), img->height());
        return;
    }
    std::vector<int32_t> dstPixels;
    int rowBytes = img->width() * 4;
    dstPixels.resize(img->height() * rowBytes);
    SkPixmap pm(SkImageInfo::MakeN32Premul(img->width(), img->height()),
        &dstPixels.front(), rowBytes);
    if (!img->readPixels(nullptr, pm, 0, 0)) {
        SkDebugf("Could not read pixmap\n");
        return;
    }

    SkString s("./encoded_corpus/enc_");
    static SkRandom rand;
    s.appendU32(rand.nextU());
    auto file = sk_fopen(s.c_str(), SkFILE_Flags::kWrite_SkFILE_Flag);
    if (!file) {
        SkDebugf("Can't initialize file\n");
        return;
    }
    auto total = pm.info().bytesPerPixel() * pm.width() * pm.height();
    SkDebugf("Writing %d (%d x %d) bytes\n", total, pm.width(), pm.height());
    // Write out the size in two bytes since that's what the fuzzer will
    // read first.
    uint32_t w = pm.width();
    sk_fwrite(&w, sizeof(uint32_t), file);
    uint32_t h = pm.height();
    sk_fwrite(&h, sizeof(uint32_t), file);
    sk_fwrite(pm.addr(), total, file);
    sk_fclose(file);
}
