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