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

#include "include/utils/SkAnimCodecPlayer.h"

#include "include/codec/SkCodec.h"
#include "include/codec/SkEncodedOrigin.h"
#include "include/core/SkAlphaType.h"
#include "include/core/SkBlendMode.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkData.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkSize.h"
#include "include/core/SkTypes.h"
#include "src/codec/SkCodecImageGenerator.h"

#include <algorithm>
#include <cstddef>
#include <memory>
#include <utility>
#include <vector>

SkAnimCodecPlayer::SkAnimCodecPlayer(std::unique_ptr<SkCodec> codec) : fCodec(std::move(codec)) {
    fImageInfo = fCodec->getInfo();
    fFrameInfos = fCodec->getFrameInfo();
    fImages.resize(fFrameInfos.size());

    // change the interpretation of fDuration to a end-time for that frame
    size_t dur = 0;
    for (auto& f : fFrameInfos) {
        dur += f.fDuration;
        f.fDuration = dur;
    }
    fTotalDuration = dur;

    if (!fTotalDuration) {
        // Static image -- may or may not have returned a single frame info.
        fFrameInfos.clear();
        fImages.clear();
        fImages.push_back(SkImage::MakeFromGenerator(
                              SkCodecImageGenerator::MakeFromCodec(std::move(fCodec))));
    }
}

SkAnimCodecPlayer::~SkAnimCodecPlayer() {}

SkISize SkAnimCodecPlayer::dimensions() const {
    if (!fCodec) {
        auto image = fImages.front();
        return image ? image->dimensions() : SkISize::MakeEmpty();
    }
    if (SkEncodedOriginSwapsWidthHeight(fCodec->getOrigin())) {
        return { fImageInfo.height(), fImageInfo.width() };
    }
    return { fImageInfo.width(), fImageInfo.height() };
}

sk_sp<SkImage> SkAnimCodecPlayer::getFrameAt(int index) {
    SkASSERT((unsigned)index < fFrameInfos.size());

    if (fImages[index]) {
        return fImages[index];
    }

    size_t rb = fImageInfo.minRowBytes();
    size_t size = fImageInfo.computeByteSize(rb);
    auto data = SkData::MakeUninitialized(size);

    SkCodec::Options opts;
    opts.fFrameIndex = index;

    const auto origin = fCodec->getOrigin();
    const auto orientedDims = this->dimensions();
    const auto originMatrix = SkEncodedOriginToMatrix(origin, orientedDims.width(),
                                                              orientedDims.height());

    SkPaint paint;
    paint.setBlendMode(SkBlendMode::kSrc);

    auto imageInfo = fImageInfo;
    if (fFrameInfos[index].fAlphaType != kOpaque_SkAlphaType && imageInfo.isOpaque()) {
        imageInfo = imageInfo.makeAlphaType(kPremul_SkAlphaType);
    }
    const int requiredFrame = fFrameInfos[index].fRequiredFrame;
    if (requiredFrame != SkCodec::kNoFrame && fImages[requiredFrame]) {
        auto requiredImage = fImages[requiredFrame];
        auto canvas = SkCanvas::MakeRasterDirect(imageInfo, data->writable_data(), rb);
        if (origin != kDefault_SkEncodedOrigin) {
            // The required frame is stored after applying the origin. Undo that,
            // because the codec decodes prior to applying the origin.
            // FIXME: Another approach would be to decode the frame's delta on top
            // of transparent black, and then draw that through the origin matrix
            // onto the required frame. To do that, SkCodec needs to expose the
            // rectangle of the delta and the blend mode, so we can handle
            // kRestoreBGColor frames and Blend::kSrc.
            SkMatrix inverse;
            SkAssertResult(originMatrix.invert(&inverse));
            canvas->concat(inverse);
        }
        canvas->drawImage(requiredImage, 0, 0, SkSamplingOptions(), &paint);
        opts.fPriorFrame = requiredFrame;
    }

    if (SkCodec::kSuccess != fCodec->getPixels(imageInfo, data->writable_data(), rb, &opts)) {
        return nullptr;
    }

    auto image = SkImage::MakeRasterData(imageInfo, std::move(data), rb);
    if (origin != kDefault_SkEncodedOrigin) {
        imageInfo = imageInfo.makeDimensions(orientedDims);
        rb = imageInfo.minRowBytes();
        size = imageInfo.computeByteSize(rb);
        data = SkData::MakeUninitialized(size);
        auto canvas = SkCanvas::MakeRasterDirect(imageInfo, data->writable_data(), rb);
        canvas->concat(originMatrix);
        canvas->drawImage(image, 0, 0, SkSamplingOptions(), &paint);
        image = SkImage::MakeRasterData(imageInfo, std::move(data), rb);
    }
    return fImages[index] = image;
}

sk_sp<SkImage> SkAnimCodecPlayer::getFrame() {
    SkASSERT(fTotalDuration > 0 || fImages.size() == 1);

    return fTotalDuration > 0
        ? this->getFrameAt(fCurrIndex)
        : fImages.front();
}

bool SkAnimCodecPlayer::seek(uint32_t msec) {
    if (!fTotalDuration) {
        return false;
    }

    msec %= fTotalDuration;

    auto lower = std::lower_bound(fFrameInfos.begin(), fFrameInfos.end(), msec,
                                  [](const SkCodec::FrameInfo& info, uint32_t msec) {
                                      return (uint32_t)info.fDuration <= msec;
                                  });
    int prevIndex = fCurrIndex;
    fCurrIndex = lower - fFrameInfos.begin();
    return fCurrIndex != prevIndex;
}


