/*
|
* 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
|