1 
2 /*
3  * Copyright 2011 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 #ifndef SkScaledBitmapSampler_DEFINED
9 #define SkScaledBitmapSampler_DEFINED
10 
11 #include "SkTypes.h"
12 #include "SkColor.h"
13 #include "SkImageDecoder.h"
14 
15 class SkBitmap;
16 
17 class SkScaledBitmapSampler {
18 public:
19     SkScaledBitmapSampler(int origWidth, int origHeight, int cellSize);
20 
scaledWidth()21     int scaledWidth() const { return fScaledWidth; }
scaledHeight()22     int scaledHeight() const { return fScaledHeight; }
23 
srcY0()24     int srcY0() const { return fY0; }
srcDX()25     int srcDX() const { return fDX; }
srcDY()26     int srcDY() const { return fDY; }
27 
28     enum SrcConfig {
29         kGray,  // 1 byte per pixel
30         kIndex, // 1 byte per pixel
31         kRGB,   // 3 bytes per pixel
32         kRGBX,  // 4 byes per pixel (ignore 4th)
33         kRGBA,  // 4 bytes per pixel
34         kRGB_565 // 2 bytes per pixel
35     };
36 
37     struct Options {
38         bool fDither;
39         bool fPremultiplyAlpha;
40         bool fSkipZeros;
OptionsOptions41         explicit Options(const SkImageDecoder &dec)
42             : fDither(dec.getDitherImage())
43             , fPremultiplyAlpha(!dec.getRequireUnpremultipliedColors())
44             , fSkipZeros(dec.getSkipWritingZeroes())
45             { }
46     };
47 
48     // Given a dst bitmap (with pixels already allocated) and a src-config,
49     // prepares iterator to process the src colors and write them into dst.
50     // Returns false if the request cannot be fulfulled.
51     bool begin(SkBitmap* dst, SrcConfig sc, const SkImageDecoder& decoder,
52                const SkPMColor* = nullptr);
53     bool begin(SkBitmap* dst, SrcConfig sc, const Options& opts,
54                const SkPMColor* = nullptr);
55     // call with row of src pixels, for y = 0...scaledHeight-1.
56     // returns true if the row had non-opaque alpha in it
57     bool next(const uint8_t* SK_RESTRICT src);
58 
59     // Like next(), but specifies the y value of the source row, so the
60     // rows can come in any order. If the row is not part of the output
61     // sample, it will be skipped. Only sampleInterlaced OR next should
62     // be called for one SkScaledBitmapSampler.
63     bool sampleInterlaced(const uint8_t* SK_RESTRICT src, int srcY);
64 
65     typedef bool (*RowProc)(void* SK_RESTRICT dstRow,
66                             const uint8_t* SK_RESTRICT src,
67                             int width, int deltaSrc, int y,
68                             const SkPMColor[]);
69 
70 private:
71     int fScaledWidth;
72     int fScaledHeight;
73 
74     int fX0;    // first X coord to sample
75     int fY0;    // first Y coord (scanline) to sample
76     int fDX;    // step between X samples
77     int fDY;    // step between Y samples
78 
79 #ifdef SK_DEBUG
80     // Keep track of whether the caller is using next or sampleInterlaced.
81     // Only one can be used per sampler.
82     enum SampleMode {
83         kUninitialized_SampleMode,
84         kConsecutive_SampleMode,
85         kInterlaced_SampleMode,
86     };
87 
88     SampleMode fSampleMode;
89 #endif
90 
91     // setup state
92     char*   fDstRow; // points into bitmap's pixels
93     size_t  fDstRowBytes;
94     int     fCurrY; // used for dithering
95     int     fSrcPixelSize;  // 1, 3, 4
96     RowProc fRowProc;
97 
98     // optional reference to the src colors if the src is a palette model
99     const SkPMColor* fCTable;
100 
101 #ifdef SK_DEBUG
102     // Helper class allowing a test to have access to fRowProc.
103     friend class RowProcTester;
104 #endif
105 };
106 
107 #endif
108