/*
 * 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 SkSwizzler_DEFINED
#define SkSwizzler_DEFINED

#include "include/codec/SkCodec.h"
#include "include/core/SkColor.h"
#include "include/core/SkImageInfo.h"
#include "src/codec/SkSampler.h"

class SkSwizzler : public SkSampler {
public:
    /**
     *  Create a new SkSwizzler.
     *  @param encodedInfo Description of the format of the encoded data.
     *  @param ctable Unowned pointer to an array of up to 256 colors for an
     *                index source.
     *  @param dstInfo Describes the destination.
     *  @param options Contains partial scanline information and whether the dst is zero-
     *                 initialized.
     *  @param frame   Is non-NULL if the source pixels are part of an image
     *                 frame that is a subset of the full image.
     *
     *  Note that a deeper discussion of partial scanline subsets and image frame
     *  subsets is below.  Currently, we do not support both simultaneously.  If
     *  options->fSubset is non-NULL, frame must be NULL.
     *
     *  @return A new SkSwizzler or nullptr on failure.
     */
    static std::unique_ptr<SkSwizzler> Make(const SkEncodedInfo& encodedInfo,
            const SkPMColor* ctable, const SkImageInfo& dstInfo, const SkCodec::Options&,
            const SkIRect* frame = nullptr);

    /**
     *  Create a simplified swizzler that does not need to do format conversion. The swizzler
     *  only needs to sample and/or subset.
     *
     *  @param srcBPP Bytes per pixel of the source.
     *  @param dstInfo Describes the destination.
     *  @param options Contains partial scanline information and whether the dst is zero-
     *                 initialized.
     *  @return A new SkSwizzler or nullptr on failure.
     */
    static std::unique_ptr<SkSwizzler> MakeSimple(int srcBPP, const SkImageInfo& dstInfo,
                                                  const SkCodec::Options&);

    /**
     *  Swizzle a line. Generally this will be called height times, once
     *  for each row of source.
     *  By allowing the caller to pass in the dst pointer, we give the caller
     *  flexibility to use the swizzler even when the encoded data does not
     *  store the rows in order.  This also improves usability for scaled and
     *  subset decodes.
     *  @param dst Where we write the output.
     *  @param src The next row of the source data.
     */
    void swizzle(void* dst, const uint8_t* SK_RESTRICT src);

    int fillWidth() const override {
        return fAllocatedWidth;
    }

    /**
     *  If fSampleX > 1, the swizzler is sampling every fSampleX'th pixel and
     *  discarding the rest.
     *
     *  This getter is currently used by SkBmpStandardCodec for Bmp-in-Ico decodes.
     *  Ideally, the subclasses of SkCodec would have no knowledge of sampling, but
     *  this allows us to apply a transparency mask to pixels after swizzling.
     */
    int sampleX() const { return fSampleX; }

    /**
     *  Returns the actual number of pixels written to destination memory, taking
     *  scaling, subsetting, and partial frames into account.
     */
    int swizzleWidth() const { return fSwizzleWidth; }

    /**
     *  Returns the byte offset at which we write to destination memory, taking
     *  scaling, subsetting, and partial frames into account.
     */
    size_t swizzleOffsetBytes() const { return fDstOffsetBytes; }

private:

    /**
     *  Method for converting raw data to Skia pixels.
     *  @param dstRow Row in which to write the resulting pixels.
     *  @param src Row of src data, in format specified by SrcConfig
     *  @param dstWidth Width in pixels of the destination
     *  @param bpp if bitsPerPixel % 8 == 0, deltaSrc is bytesPerPixel
     *             else, deltaSrc is bitsPerPixel
     *  @param deltaSrc bpp * sampleX
     *  @param ctable Colors (used for kIndex source).
     *  @param offset The offset before the first pixel to sample.
                        Is in bytes or bits based on what deltaSrc is in.
     */
    typedef void (*RowProc)(void* SK_RESTRICT dstRow,
                            const uint8_t* SK_RESTRICT src,
                            int dstWidth, int bpp, int deltaSrc, int offset,
                            const SkPMColor ctable[]);

    template <RowProc Proc>
    static void SkipLeading8888ZerosThen(void* SK_RESTRICT dstRow,
                                         const uint8_t* SK_RESTRICT src,
                                         int dstWidth, int bpp, int deltaSrc, int offset,
                                         const SkPMColor ctable[]);

    template <RowProc Proc>
    static void SkipLeadingGrayAlphaZerosThen(void* dst, const uint8_t* src, int width, int bpp,
                                              int deltaSrc, int offset, const SkPMColor ctable[]);

    // May be NULL.  We have not implemented optimized functions for all supported transforms.
    const RowProc       fFastProc;
    // Always non-NULL.  Supports sampling.
    const RowProc       fSlowProc;
    // The actual RowProc we are using.  This depends on if fFastProc is non-NULL and
    // whether or not we are sampling.
    RowProc             fActualProc;

    const SkPMColor*    fColorTable;      // Unowned pointer

    // Subset Swizzles
    // There are two types of subset swizzles that we support.  We do not
    // support both at the same time.
    // TODO: If we want to support partial scanlines for gifs (which may
    //       use frame subsets), we will need to support both subsetting
    //       modes at the same time.
    // (1) Partial Scanlines
    //         The client only wants to write a subset of the source pixels
    //         to the destination.  This subset is specified to CreateSwizzler
    //         using options->fSubset.  We will store subset information in
    //         the following fields.
    //
    //         fSrcOffset:      The starting pixel of the source.
    //         fSrcOffsetUnits: Derived from fSrcOffset with two key
    //                          differences:
    //                          (1) This takes the size of source pixels into
    //                          account by multiplying by fSrcBPP.  This may
    //                          be measured in bits or bytes depending on
    //                          which is natural for the SrcConfig.
    //                          (2) If we are sampling, this will be larger
    //                          than fSrcOffset * fSrcBPP, since sampling
    //                          implies that we will skip some pixels.
    //         fDstOffset:      Will be zero.  There is no destination offset
    //                          for this type of subset.
    //         fDstOffsetBytes: Will be zero.
    //         fSrcWidth:       The width of the desired subset of source
    //                          pixels, before any sampling is performed.
    //         fDstWidth:       Will be equal to fSrcWidth, since this is also
    //                          calculated before any sampling is performed.
    //                          For this type of subset, the destination width
    //                          matches the desired subset of the source.
    //         fSwizzleWidth:   The actual number of pixels that will be
    //                          written by the RowProc.  This is a scaled
    //                          version of fSrcWidth/fDstWidth.
    //         fAllocatedWidth: Will be equal to fSwizzleWidth.  For this type
    //                          of subset, the number of pixels written is the
    //                          same as the actual width of the destination.
    // (2) Frame Subset
    //         The client will decode the entire width of the source into a
    //         subset of destination memory.  This subset is specified to
    //         CreateSwizzler in the "frame" parameter.  We store subset
    //         information in the following fields.
    //
    //         fSrcOffset:      Will be zero.  The starting pixel of the source.
    //         fSrcOffsetUnits: Will only be non-zero if we are sampling,
    //                          since sampling implies that we will skip some
    //                          pixels.  Note that this is measured in bits
    //                          or bytes depending on which is natural for
    //                          SrcConfig.
    //         fDstOffset:      First pixel to write in destination.
    //         fDstOffsetBytes: fDstOffset * fDstBPP.
    //         fSrcWidth:       The entire width of the source pixels, before
    //                          any sampling is performed.
    //         fDstWidth:       The entire width of the destination memory,
    //                          before any sampling is performed.
    //         fSwizzleWidth:   The actual number of pixels that will be
    //                          written by the RowProc.  This is a scaled
    //                          version of fSrcWidth.
    //         fAllocatedWidth: The actual number of pixels in destination
    //                          memory.  This is a scaled version of
    //                          fDstWidth.
    //
    // If we are not subsetting, these fields are more straightforward.
    //         fSrcOffset = fDstOffet = fDstOffsetBytes = 0
    //         fSrcOffsetUnits may be non-zero (we will skip the first few pixels when sampling)
    //         fSrcWidth = fDstWidth = Full original width
    //         fSwizzleWidth = fAllcoatedWidth = Scaled width (if we are sampling)
    const int           fSrcOffset;
    const int           fDstOffset;
    int                 fSrcOffsetUnits;
    int                 fDstOffsetBytes;
    const int           fSrcWidth;
    const int           fDstWidth;
    int                 fSwizzleWidth;
    int                 fAllocatedWidth;

    int                 fSampleX;         // Step between X samples
    const int           fSrcBPP;          // Bits/bytes per pixel for the SrcConfig
                                          // if bitsPerPixel % 8 == 0
                                          //     fBPP is bytesPerPixel
                                          // else
                                          //     fBPP is bitsPerPixel
    const int           fDstBPP;          // Bytes per pixel for the destination color type

    SkSwizzler(RowProc fastProc, RowProc proc, const SkPMColor* ctable, int srcOffset,
            int srcWidth, int dstOffset, int dstWidth, int srcBPP, int dstBPP);
    static std::unique_ptr<SkSwizzler> Make(const SkImageInfo& dstInfo, RowProc fastProc,
            RowProc proc, const SkPMColor* ctable, int srcBPP, int dstBPP,
            const SkCodec::Options& options, const SkIRect* frame);

    int onSetSampleX(int) override;

};
#endif // SkSwizzler_DEFINED
