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

#include "include/core/SkAlphaType.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkColorType.h"
#include "include/core/SkData.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkPixmap.h"
#include "include/core/SkRefCnt.h"
#include "include/private/SkMath.h"
#include "src/core/SkCompressedDataUtils.h"
#include "src/core/SkImageFilterTypes.h"
#include "src/core/SkImageFilter_Base.h"
#include "src/image/SkImage_Base.h"
#include "src/image/SkImage_Raster.h"

#include <cstddef>
#include <cstdint>
#include <utility>

class SkImageFilter;
struct SkIPoint;
struct SkIRect;
enum class SkTextureCompressionType;

static bool valid_args(const SkImageInfo& info, size_t rowBytes, size_t* minSize) {
    const int maxDimension = SK_MaxS32 >> 2;

    // TODO(mtklein): eliminate anything here that setInfo() has already checked.
    SkBitmap b;
    if (!b.setInfo(info, rowBytes)) {
        return false;
    }

    if (info.width() <= 0 || info.height() <= 0) {
        return false;
    }
    if (info.width() > maxDimension || info.height() > maxDimension) {
        return false;
    }
    if ((unsigned)info.colorType() > (unsigned)kLastEnum_SkColorType) {
        return false;
    }
    if ((unsigned)info.alphaType() > (unsigned)kLastEnum_SkAlphaType) {
        return false;
    }

    if (kUnknown_SkColorType == info.colorType()) {
        return false;
    }
    if (!info.validRowBytes(rowBytes)) {
        return false;
    }

    size_t size = info.computeByteSize(rowBytes);
    if (SkImageInfo::ByteSizeOverflowed(size)) {
        return false;
    }

    if (minSize) {
        *minSize = size;
    }
    return true;
}

namespace SkImages {
sk_sp<SkImage> RasterFromBitmap(const SkBitmap& bm) {
    if (!bm.pixelRef()) {
        return nullptr;
    }

    return SkImage_Raster::MakeFromBitmap(bm, SkCopyPixelsMode::kIfMutable);
}

sk_sp<SkImage> RasterFromPixmapCopy(const SkPixmap& pmap) {
    size_t size;
    if (!valid_args(pmap.info(), pmap.rowBytes(), &size) || !pmap.addr()) {
        return nullptr;
    }

    // Here we actually make a copy of the caller's pixel data
    sk_sp<SkData> data(SkData::MakeWithCopy(pmap.addr(), size));
    return sk_make_sp<SkImage_Raster>(
            pmap.info(), std::move(data), pmap.rowBytes(), /*mips=*/nullptr, kNeedNewImageUniqueID);
}

sk_sp<SkImage> RasterFromData(const SkImageInfo& info, sk_sp<SkData> data, size_t rowBytes) {
    size_t size;
    if (!valid_args(info, rowBytes, &size) || !data) {
        return nullptr;
    }

    // did they give us enough data?
    if (data->size() < size) {
        return nullptr;
    }

    return sk_make_sp<SkImage_Raster>(
            info, std::move(data), rowBytes, /*mips=*/nullptr, kNeedNewImageUniqueID);
}

sk_sp<SkImage> MakeWithFilter(sk_sp<SkImage> src,
                              const SkImageFilter* filter,
                              const SkIRect& subset,
                              const SkIRect& clipBounds,
                              SkIRect* outSubset,
                              SkIPoint* offset) {
    if (!src || !filter) {
        return nullptr;
    }

    sk_sp<skif::Backend> backend = skif::MakeRasterBackend({}, src->colorType());
    return as_IFB(filter)->makeImageWithFilter(std::move(backend),
                                               std::move(src),
                                               subset,
                                               clipBounds,
                                               outSubset,
                                               offset);
}

// TODO: this could be improved to decode and make use of the mipmap
// levels potentially present in the compressed data. For now, any
// mipmap levels are discarded.
sk_sp<SkImage> RasterFromCompressedTextureData(sk_sp<SkData> data,
                                               int width,
                                               int height,
                                               SkTextureCompressionType type) {
    size_t expectedSize = SkCompressedFormatDataSize(type, {width, height}, false);
    if (!data || data->size() < expectedSize) {
        return nullptr;
    }

    SkAlphaType at =
            SkTextureCompressionTypeIsOpaque(type) ? kOpaque_SkAlphaType : kPremul_SkAlphaType;

    SkImageInfo ii = SkImageInfo::MakeN32(width, height, at);

    if (!valid_args(ii, ii.minRowBytes(), nullptr)) {
        return nullptr;
    }

    SkBitmap bitmap;
    if (!bitmap.tryAllocPixels(ii)) {
        return nullptr;
    }

    if (!SkDecompress(std::move(data), {width, height}, type, &bitmap)) {
        return nullptr;
    }

    bitmap.setImmutable();
    return RasterFromBitmap(bitmap);
}

sk_sp<SkImage> RasterFromPixmap(const SkPixmap& pmap, RasterReleaseProc proc, ReleaseContext ctx) {
    size_t size;
    if (!valid_args(pmap.info(), pmap.rowBytes(), &size) || !pmap.addr()) {
        return nullptr;
    }

    sk_sp<SkData> data(SkData::MakeWithProc(pmap.addr(), size, proc, ctx));
    return sk_make_sp<SkImage_Raster>(
            pmap.info(), std::move(data), pmap.rowBytes(), /*mips=*/nullptr, kNeedNewImageUniqueID);
}

}  // namespace SkImages
