/*
 * 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 "SkCodec.h"
#include "SkColor.h"
#include "SkImageInfo.h"
#include "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
