blob: 058044e420b2a46decbd3fceb0adc9543b2c3cdb [file] [log] [blame]
/*
* 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:
/**
* Enum describing the config of the source data.
*/
enum SrcConfig {
kUnknown, // Invalid type.
kBit, // A single bit to distinguish between white and black
kGray,
kIndex1,
kIndex2,
kIndex4,
kIndex,
kRGB,
kBGR,
kRGBX,
kBGRX,
kRGBA,
kBGRA,
kRGB_565,
};
/*
*
* Result code for the alpha components of a row.
*
*/
typedef uint16_t ResultAlpha;
static const ResultAlpha kOpaque_ResultAlpha = 0xFFFF;
static const ResultAlpha kTransparent_ResultAlpha = 0x0000;
/*
*
* Checks if the result of decoding a row indicates that the row was
* transparent.
*
*/
static bool IsTransparent(ResultAlpha r) {
return kTransparent_ResultAlpha == r;
}
/*
*
* Checks if the result of decoding a row indicates that the row was
* opaque.
*
*/
static bool IsOpaque(ResultAlpha r) {
return kOpaque_ResultAlpha == r;
}
/*
*
* Constructs the proper result code based on accumulated alpha masks
*
*/
static ResultAlpha GetResult(uint8_t zeroAlpha, uint8_t maxAlpha);
/*
*
* Returns bits per pixel for source config
*
*/
static int BitsPerPixel(SrcConfig sc) {
switch (sc) {
case kBit:
case kIndex1:
return 1;
case kIndex2:
return 2;
case kIndex4:
return 4;
case kGray:
case kIndex:
return 8;
case kRGB_565:
return 16;
case kRGB:
case kBGR:
return 24;
case kRGBX:
case kRGBA:
case kBGRX:
case kBGRA:
return 32;
default:
SkASSERT(false);
return 0;
}
}
/*
*
* Returns bytes per pixel for source config
* Raises an error if each pixel is not stored in an even number of bytes
*
*/
static int BytesPerPixel(SrcConfig sc) {
SkASSERT(SkIsAlign8(BitsPerPixel(sc)));
return BitsPerPixel(sc) >> 3;
}
/**
* Create a new SkSwizzler.
* @param SrcConfig Description of the format of the source.
* @param ctable Unowned pointer to an array of up to 256 colors for an
* index source.
* @param dstInfo Describes the destination.
* @param options Indicates if dst is zero-initialized. The
* implementation may choose to skip writing zeroes
* if set to kYes_ZeroInitialized.
* Contains subset information.
* @return A new SkSwizzler or nullptr on failure.
*/
static SkSwizzler* CreateSwizzler(SrcConfig, const SkPMColor* ctable,
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.
* @return A result code describing if the row was fully opaque, fully
* transparent, or neither
*/
ResultAlpha swizzle(void* dst, const uint8_t* SK_RESTRICT src);
/**
* Implement fill using a custom width.
*/
void fill(const SkImageInfo& info, void* dst, size_t rowBytes, uint32_t colorOrIndex,
SkCodec::ZeroInitialized zeroInit) override {
const SkImageInfo fillInfo = info.makeWH(fDstWidth, info.height());
SkSampler::Fill(fillInfo, dst, rowBytes, colorOrIndex, zeroInit);
}
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 ResultAlpha (*RowProc)(void* SK_RESTRICT dstRow,
const uint8_t* SK_RESTRICT src,
int dstWidth, int bpp, int deltaSrc, int offset,
const SkPMColor ctable[]);
const RowProc fRowProc;
const SkPMColor* fColorTable; // Unowned pointer
const int fSrcOffset; // Offset of the src in pixels, allows for partial
// scanline decodes.
int fX0; // Start coordinate for the src, may be different than
// fSrcOffset if we are sampling.
const int fSrcWidth; // Width of the source - i.e. before any sampling.
int fDstWidth; // Width of dst, which may differ with sampling.
int fSampleX; // step between X samples
const int fBPP; // if bitsPerPixel % 8 == 0
// fBPP is bytesPerPixel
// else
// fBPP is bitsPerPixel
SkSwizzler(RowProc proc, const SkPMColor* ctable, int srcOffset, int srcWidth, int bpp);
int onSetSampleX(int) override;
};
#endif // SkSwizzler_DEFINED