Coverage Report

Created: 2024-05-20 07:14

/src/skia/src/codec/SkSwizzler.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2015 Google Inc.
3
 *
4
 * Use of this source code is governed by a BSD-style license that can be
5
 * found in the LICENSE file.
6
 */
7
8
#ifndef SkSwizzler_DEFINED
9
#define SkSwizzler_DEFINED
10
11
#include "include/codec/SkCodec.h"
12
#include "include/core/SkColor.h"
13
#include "include/core/SkTypes.h"
14
#include "src/codec/SkSampler.h"
15
16
#include <cstddef>
17
#include <cstdint>
18
#include <memory>
19
20
struct SkEncodedInfo;
21
struct SkIRect;
22
struct SkImageInfo;
23
24
class SkSwizzler : public SkSampler {
25
public:
26
    /**
27
     *  Create a new SkSwizzler.
28
     *  @param encodedInfo Description of the format of the encoded data.
29
     *  @param ctable Unowned pointer to an array of up to 256 colors for an
30
     *                index source.
31
     *  @param dstInfo Describes the destination.
32
     *  @param options Contains partial scanline information and whether the dst is zero-
33
     *                 initialized.
34
     *  @param frame   Is non-NULL if the source pixels are part of an image
35
     *                 frame that is a subset of the full image.
36
     *
37
     *  Note that a deeper discussion of partial scanline subsets and image frame
38
     *  subsets is below.  Currently, we do not support both simultaneously.  If
39
     *  options->fSubset is non-NULL, frame must be NULL.
40
     *
41
     *  @return A new SkSwizzler or nullptr on failure.
42
     */
43
    static std::unique_ptr<SkSwizzler> Make(const SkEncodedInfo& encodedInfo,
44
            const SkPMColor* ctable, const SkImageInfo& dstInfo, const SkCodec::Options&,
45
            const SkIRect* frame = nullptr);
46
47
    /**
48
     *  Create a simplified swizzler that does not need to do format conversion. The swizzler
49
     *  only needs to sample and/or subset.
50
     *
51
     *  @param srcBPP Bytes per pixel of the source.
52
     *  @param dstInfo Describes the destination.
53
     *  @param options Contains partial scanline information and whether the dst is zero-
54
     *                 initialized.
55
     *  @return A new SkSwizzler or nullptr on failure.
56
     */
57
    static std::unique_ptr<SkSwizzler> MakeSimple(int srcBPP, const SkImageInfo& dstInfo,
58
                                                  const SkCodec::Options&);
59
60
    /**
61
     *  Swizzle a line. Generally this will be called height times, once
62
     *  for each row of source.
63
     *  By allowing the caller to pass in the dst pointer, we give the caller
64
     *  flexibility to use the swizzler even when the encoded data does not
65
     *  store the rows in order.  This also improves usability for scaled and
66
     *  subset decodes.
67
     *  @param dst Where we write the output.
68
     *  @param src The next row of the source data.
69
     */
70
    void swizzle(void* dst, const uint8_t* SK_RESTRICT src);
71
72
7.39k
    int fillWidth() const override {
73
7.39k
        return fAllocatedWidth;
74
7.39k
    }
75
76
    /**
77
     *  If fSampleX > 1, the swizzler is sampling every fSampleX'th pixel and
78
     *  discarding the rest.
79
     *
80
     *  This getter is currently used by SkBmpStandardCodec for Bmp-in-Ico decodes.
81
     *  Ideally, the subclasses of SkCodec would have no knowledge of sampling, but
82
     *  this allows us to apply a transparency mask to pixels after swizzling.
83
     */
84
318
    int sampleX() const { return fSampleX; }
85
86
    /**
87
     *  Returns the actual number of pixels written to destination memory, taking
88
     *  scaling, subsetting, and partial frames into account.
89
     */
90
381k
    int swizzleWidth() const { return fSwizzleWidth; }
91
92
    /**
93
     *  Returns the byte offset at which we write to destination memory, taking
94
     *  scaling, subsetting, and partial frames into account.
95
     */
96
0
    size_t swizzleOffsetBytes() const { return fDstOffsetBytes; }
97
98
private:
99
100
    /**
101
     *  Method for converting raw data to Skia pixels.
102
     *  @param dstRow Row in which to write the resulting pixels.
103
     *  @param src Row of src data, in format specified by SrcConfig
104
     *  @param dstWidth Width in pixels of the destination
105
     *  @param bpp if bitsPerPixel % 8 == 0, deltaSrc is bytesPerPixel
106
     *             else, deltaSrc is bitsPerPixel
107
     *  @param deltaSrc bpp * sampleX
108
     *  @param ctable Colors (used for kIndex source).
109
     *  @param offset The offset before the first pixel to sample.
110
                        Is in bytes or bits based on what deltaSrc is in.
111
     */
112
    typedef void (*RowProc)(void* SK_RESTRICT dstRow,
113
                            const uint8_t* SK_RESTRICT src,
114
                            int dstWidth, int bpp, int deltaSrc, int offset,
115
                            const SkPMColor ctable[]);
116
117
    template <RowProc Proc>
118
    static void SkipLeading8888ZerosThen(void* SK_RESTRICT dstRow,
119
                                         const uint8_t* SK_RESTRICT src,
120
                                         int dstWidth, int bpp, int deltaSrc, int offset,
121
                                         const SkPMColor ctable[]);
122
123
    template <RowProc Proc>
124
    static void SkipLeadingGrayAlphaZerosThen(void* dst, const uint8_t* src, int width, int bpp,
125
                                              int deltaSrc, int offset, const SkPMColor ctable[]);
126
127
    // May be NULL.  We have not implemented optimized functions for all supported transforms.
128
    const RowProc       fFastProc;
129
    // Always non-NULL.  Supports sampling.
130
    const RowProc       fSlowProc;
131
    // The actual RowProc we are using.  This depends on if fFastProc is non-NULL and
132
    // whether or not we are sampling.
133
    RowProc             fActualProc;
134
135
    const SkPMColor*    fColorTable;      // Unowned pointer
136
137
    // Subset Swizzles
138
    // There are two types of subset swizzles that we support.  We do not
139
    // support both at the same time.
140
    // TODO: If we want to support partial scanlines for gifs (which may
141
    //       use frame subsets), we will need to support both subsetting
142
    //       modes at the same time.
143
    // (1) Partial Scanlines
144
    //         The client only wants to write a subset of the source pixels
145
    //         to the destination.  This subset is specified to CreateSwizzler
146
    //         using options->fSubset.  We will store subset information in
147
    //         the following fields.
148
    //
149
    //         fSrcOffset:      The starting pixel of the source.
150
    //         fSrcOffsetUnits: Derived from fSrcOffset with two key
151
    //                          differences:
152
    //                          (1) This takes the size of source pixels into
153
    //                          account by multiplying by fSrcBPP.  This may
154
    //                          be measured in bits or bytes depending on
155
    //                          which is natural for the SrcConfig.
156
    //                          (2) If we are sampling, this will be larger
157
    //                          than fSrcOffset * fSrcBPP, since sampling
158
    //                          implies that we will skip some pixels.
159
    //         fDstOffset:      Will be zero.  There is no destination offset
160
    //                          for this type of subset.
161
    //         fDstOffsetBytes: Will be zero.
162
    //         fSrcWidth:       The width of the desired subset of source
163
    //                          pixels, before any sampling is performed.
164
    //         fDstWidth:       Will be equal to fSrcWidth, since this is also
165
    //                          calculated before any sampling is performed.
166
    //                          For this type of subset, the destination width
167
    //                          matches the desired subset of the source.
168
    //         fSwizzleWidth:   The actual number of pixels that will be
169
    //                          written by the RowProc.  This is a scaled
170
    //                          version of fSrcWidth/fDstWidth.
171
    //         fAllocatedWidth: Will be equal to fSwizzleWidth.  For this type
172
    //                          of subset, the number of pixels written is the
173
    //                          same as the actual width of the destination.
174
    // (2) Frame Subset
175
    //         The client will decode the entire width of the source into a
176
    //         subset of destination memory.  This subset is specified to
177
    //         CreateSwizzler in the "frame" parameter.  We store subset
178
    //         information in the following fields.
179
    //
180
    //         fSrcOffset:      Will be zero.  The starting pixel of the source.
181
    //         fSrcOffsetUnits: Will only be non-zero if we are sampling,
182
    //                          since sampling implies that we will skip some
183
    //                          pixels.  Note that this is measured in bits
184
    //                          or bytes depending on which is natural for
185
    //                          SrcConfig.
186
    //         fDstOffset:      First pixel to write in destination.
187
    //         fDstOffsetBytes: fDstOffset * fDstBPP.
188
    //         fSrcWidth:       The entire width of the source pixels, before
189
    //                          any sampling is performed.
190
    //         fDstWidth:       The entire width of the destination memory,
191
    //                          before any sampling is performed.
192
    //         fSwizzleWidth:   The actual number of pixels that will be
193
    //                          written by the RowProc.  This is a scaled
194
    //                          version of fSrcWidth.
195
    //         fAllocatedWidth: The actual number of pixels in destination
196
    //                          memory.  This is a scaled version of
197
    //                          fDstWidth.
198
    //
199
    // If we are not subsetting, these fields are more straightforward.
200
    //         fSrcOffset = fDstOffet = fDstOffsetBytes = 0
201
    //         fSrcOffsetUnits may be non-zero (we will skip the first few pixels when sampling)
202
    //         fSrcWidth = fDstWidth = Full original width
203
    //         fSwizzleWidth = fAllcoatedWidth = Scaled width (if we are sampling)
204
    const int           fSrcOffset;
205
    const int           fDstOffset;
206
    int                 fSrcOffsetUnits;
207
    int                 fDstOffsetBytes;
208
    const int           fSrcWidth;
209
    const int           fDstWidth;
210
    int                 fSwizzleWidth;
211
    int                 fAllocatedWidth;
212
213
    int                 fSampleX;         // Step between X samples
214
    const int           fSrcBPP;          // Bits/bytes per pixel for the SrcConfig
215
                                          // if bitsPerPixel % 8 == 0
216
                                          //     fBPP is bytesPerPixel
217
                                          // else
218
                                          //     fBPP is bitsPerPixel
219
    const int           fDstBPP;          // Bytes per pixel for the destination color type
220
221
    SkSwizzler(RowProc fastProc, RowProc proc, const SkPMColor* ctable, int srcOffset,
222
            int srcWidth, int dstOffset, int dstWidth, int srcBPP, int dstBPP);
223
    static std::unique_ptr<SkSwizzler> Make(const SkImageInfo& dstInfo, RowProc fastProc,
224
            RowProc proc, const SkPMColor* ctable, int srcBPP, int dstBPP,
225
            const SkCodec::Options& options, const SkIRect* frame);
226
227
    int onSetSampleX(int) override;
228
229
};
230
231
#endif // SkSwizzler_DEFINED