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

#ifndef SkScanlineDecoder_DEFINED
#define SkScanlineDecoder_DEFINED

#include "SkTypes.h"
#include "SkCodec.h"
#include "SkTemplates.h"
#include "SkImageInfo.h"

class SkScanlineDecoder : public SkNoncopyable {
public:
    /**
     *  Clean up after reading/skipping scanlines.
     *
     *  It is possible that not all scanlines will have been read/skipped.  In
     *  fact, in the case of subset decodes, it is likely that there will be
     *  scanlines at the bottom of the image that have been ignored.
     */
    virtual ~SkScanlineDecoder() {}

    /**
     *  Write the next countLines scanlines into dst.
     *
     *  @param dst Must be non-null, and large enough to hold countLines
     *      scanlines of size rowBytes.
     *  @param countLines Number of lines to write.
     *  @param rowBytes Number of bytes per row. Must be large enough to hold
     *      a scanline based on the SkImageInfo used to create this object.
     */
    SkCodec::Result getScanlines(void* dst, int countLines, size_t rowBytes) {
        if ((rowBytes < fDstInfo.minRowBytes() && countLines > 1 ) || countLines <= 0
                || fCurrScanline + countLines > fDstInfo.height()) {
            return SkCodec::kInvalidParameters;
        }
        const SkCodec::Result result = this->onGetScanlines(dst, countLines, rowBytes);
        fCurrScanline += countLines;
        return result;
    }

    /**
     *  Skip count scanlines.
     *
     *  The default version just calls onGetScanlines and discards the dst.
     *  NOTE: If skipped lines are the only lines with alpha, this default
     *  will make reallyHasAlpha return true, when it could have returned
     *  false.
     */
    SkCodec::Result skipScanlines(int countLines) {
        if (fCurrScanline + countLines > fDstInfo.height()) {
            // Arguably, we could just skip the scanlines which are remaining,
            // and return kSuccess. We choose to return invalid so the client
            // can catch their bug.
            return SkCodec::kInvalidParameters;
        }
        const SkCodec::Result result = this->onSkipScanlines(countLines);
        fCurrScanline += countLines;
        return result;
    }

    /**
     *  Some images may initially report that they have alpha due to the format
     *  of the encoded data, but then never use any colors which have alpha
     *  less than 100%. This function can be called *after* decoding to
     *  determine if such an image truly had alpha. Calling it before decoding
     *  is undefined.
     *  FIXME: see skbug.com/3582.
     */
    bool reallyHasAlpha() const {
        return this->onReallyHasAlpha();
    }

protected:
    SkScanlineDecoder(const SkImageInfo& requested)
        : fDstInfo(requested)
        , fCurrScanline(0) {}

    virtual bool onReallyHasAlpha() const { return false; }

    const SkImageInfo& dstInfo() const { return fDstInfo; }

private:
    const SkImageInfo   fDstInfo;
    int                 fCurrScanline;

    // Naive default version just calls onGetScanlines on temp memory.
    virtual SkCodec::Result onSkipScanlines(int countLines) {
        SkAutoMalloc storage(fDstInfo.minRowBytes());
        // Note that we pass 0 to rowBytes so we continue to use the same memory.
        // Also note that while getScanlines checks that rowBytes is big enough,
        // onGetScanlines bypasses that check.
        // Calling the virtual method also means we do not double count
        // countLines.
        return this->onGetScanlines(storage.get(), countLines, 0);
    }

    virtual SkCodec::Result onGetScanlines(void* dst, int countLines,
                                                    size_t rowBytes) = 0;

};
#endif // SkScanlineDecoder_DEFINED
