Coverage Report

Created: 2021-08-22 09:07

/src/skia/include/private/SkEncodedInfo.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2016 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 SkEncodedInfo_DEFINED
9
#define SkEncodedInfo_DEFINED
10
11
#include <memory>
12
13
#include "include/core/SkData.h"
14
#include "include/core/SkImageInfo.h"
15
#include "include/third_party/skcms/skcms.h"
16
17
struct SkEncodedInfo {
18
public:
19
    class ICCProfile {
20
    public:
21
        static std::unique_ptr<ICCProfile> Make(sk_sp<SkData>);
22
        static std::unique_ptr<ICCProfile> Make(const skcms_ICCProfile&);
23
24
109k
        const skcms_ICCProfile* profile() const { return &fProfile; }
25
    private:
26
        ICCProfile(const skcms_ICCProfile&, sk_sp<SkData> = nullptr);
27
28
        skcms_ICCProfile fProfile;
29
        sk_sp<SkData>    fData;
30
    };
31
32
    enum Alpha {
33
        kOpaque_Alpha,
34
        kUnpremul_Alpha,
35
36
        // Each pixel is either fully opaque or fully transparent.
37
        // There is no difference between requesting kPremul or kUnpremul.
38
        kBinary_Alpha,
39
    };
40
41
    /*
42
     * We strive to make the number of components per pixel obvious through
43
     * our naming conventions.
44
     * Ex: kRGB has 3 components.  kRGBA has 4 components.
45
     *
46
     * This sometimes results in redundant Alpha and Color information.
47
     * Ex: kRGB images must also be kOpaque.
48
     */
49
    enum Color {
50
        // PNG, WBMP
51
        kGray_Color,
52
53
        // PNG
54
        kGrayAlpha_Color,
55
56
        // PNG with Skia-specific sBIT
57
        // Like kGrayAlpha, except this expects to be treated as
58
        // kAlpha_8_SkColorType, which ignores the gray component. If
59
        // decoded to full color (e.g. kN32), the gray component is respected
60
        // (so it can share code with kGrayAlpha).
61
        kXAlpha_Color,
62
63
        // PNG
64
        // 565 images may be encoded to PNG by specifying the number of
65
        // significant bits for each channel.  This is a strange 565
66
        // representation because the image is still encoded with 8 bits per
67
        // component.
68
        k565_Color,
69
70
        // PNG, GIF, BMP
71
        kPalette_Color,
72
73
        // PNG, RAW
74
        kRGB_Color,
75
        kRGBA_Color,
76
77
        // BMP
78
        kBGR_Color,
79
        kBGRX_Color,
80
        kBGRA_Color,
81
82
        // JPEG, WEBP
83
        kYUV_Color,
84
85
        // WEBP
86
        kYUVA_Color,
87
88
        // JPEG
89
        // Photoshop actually writes inverted CMYK data into JPEGs, where zero
90
        // represents 100% ink coverage.  For this reason, we treat CMYK JPEGs
91
        // as having inverted CMYK.  libjpeg-turbo warns that this may break
92
        // other applications, but the CMYK JPEGs we see on the web expect to
93
        // be treated as inverted CMYK.
94
        kInvertedCMYK_Color,
95
        kYCCK_Color,
96
    };
97
98
    static SkEncodedInfo Make(int width, int height, Color color, Alpha alpha,
99
3.87k
            int bitsPerComponent) {
100
3.87k
        return Make(width, height, color, alpha, bitsPerComponent, nullptr);
101
3.87k
    }
102
103
    static SkEncodedInfo Make(int width, int height, Color color, Alpha alpha,
104
14.5k
            int bitsPerComponent, std::unique_ptr<ICCProfile> profile) {
105
14.5k
        SkASSERT(1 == bitsPerComponent ||
106
14.5k
                 2 == bitsPerComponent ||
107
14.5k
                 4 == bitsPerComponent ||
108
14.5k
                 8 == bitsPerComponent ||
109
14.5k
                 16 == bitsPerComponent);
110
111
14.5k
        switch (color) {
112
3.69k
            case kGray_Color:
113
3.69k
                SkASSERT(kOpaque_Alpha == alpha);
114
3.69k
                break;
115
232
            case kGrayAlpha_Color:
116
232
                SkASSERT(kOpaque_Alpha != alpha);
117
232
                break;
118
1.15k
            case kPalette_Color:
119
1.15k
                SkASSERT(16 != bitsPerComponent);
120
1.15k
                break;
121
1.37k
            case kRGB_Color:
122
1.59k
            case kBGR_Color:
123
2.12k
            case kBGRX_Color:
124
2.12k
                SkASSERT(kOpaque_Alpha == alpha);
125
2.12k
                SkASSERT(bitsPerComponent >= 8);
126
2.12k
                break;
127
2.78k
            case kYUV_Color:
128
3.36k
            case kInvertedCMYK_Color:
129
3.37k
            case kYCCK_Color:
130
3.37k
                SkASSERT(kOpaque_Alpha == alpha);
131
3.37k
                SkASSERT(8 == bitsPerComponent);
132
3.37k
                break;
133
1.08k
            case kRGBA_Color:
134
1.08k
                SkASSERT(bitsPerComponent >= 8);
135
1.08k
                break;
136
2.65k
            case kBGRA_Color:
137
2.92k
            case kYUVA_Color:
138
2.92k
                SkASSERT(8 == bitsPerComponent);
139
2.92k
                break;
140
0
            case kXAlpha_Color:
141
0
                SkASSERT(kUnpremul_Alpha == alpha);
142
0
                SkASSERT(8 == bitsPerComponent);
143
0
                break;
144
0
            case k565_Color:
145
0
                SkASSERT(kOpaque_Alpha == alpha);
146
0
                SkASSERT(8 == bitsPerComponent);
147
0
                break;
148
0
            default:
149
0
                SkASSERT(false);
150
0
                break;
151
14.5k
        }
152
153
14.5k
        return SkEncodedInfo(width, height, color, alpha, bitsPerComponent, std::move(profile));
154
14.5k
    }
155
156
    /*
157
     * Returns a recommended SkImageInfo.
158
     *
159
     * TODO: Leave this up to the client.
160
     */
161
14.2k
    SkImageInfo makeImageInfo() const {
162
3.69k
        auto ct =  kGray_Color == fColor ? kGray_8_SkColorType   :
163
10.5k
                 kXAlpha_Color == fColor ? kAlpha_8_SkColorType  :
164
10.5k
                    k565_Color == fColor ? kRGB_565_SkColorType  :
165
10.5k
                                           kN32_SkColorType      ;
166
10.0k
        auto alpha = kOpaque_Alpha == fAlpha ? kOpaque_SkAlphaType
167
4.18k
                                             : kUnpremul_SkAlphaType;
168
4.01k
        sk_sp<SkColorSpace> cs = fProfile ? SkColorSpace::Make(*fProfile->profile())
169
10.2k
                                          : nullptr;
170
14.2k
        if (!cs) {
171
10.5k
            cs = SkColorSpace::MakeSRGB();
172
10.5k
        }
173
14.2k
        return SkImageInfo::Make(fWidth, fHeight, ct, alpha, std::move(cs));
174
14.2k
    }
175
176
147k
    int   width() const { return fWidth;  }
177
1.25M
    int  height() const { return fHeight; }
178
21.4k
    Color color() const { return fColor;  }
179
22.5k
    Alpha alpha() const { return fAlpha;  }
180
18.7k
    bool opaque() const { return fAlpha == kOpaque_Alpha; }
181
168k
    const skcms_ICCProfile* profile() const {
182
168k
        if (!fProfile) return nullptr;
183
102k
        return fProfile->profile();
184
102k
    }
185
186
8.75k
    uint8_t bitsPerComponent() const { return fBitsPerComponent; }
187
188
4.06k
    uint8_t bitsPerPixel() const {
189
4.06k
        switch (fColor) {
190
1.21k
            case kGray_Color:
191
1.21k
                return fBitsPerComponent;
192
0
            case kXAlpha_Color:
193
168
            case kGrayAlpha_Color:
194
168
                return 2 * fBitsPerComponent;
195
657
            case kPalette_Color:
196
657
                return fBitsPerComponent;
197
915
            case kRGB_Color:
198
982
            case kBGR_Color:
199
982
            case kYUV_Color:
200
982
            case k565_Color:
201
982
                return 3 * fBitsPerComponent;
202
910
            case kRGBA_Color:
203
972
            case kBGRA_Color:
204
996
            case kBGRX_Color:
205
996
            case kYUVA_Color:
206
1.04k
            case kInvertedCMYK_Color:
207
1.04k
            case kYCCK_Color:
208
1.04k
                return 4 * fBitsPerComponent;
209
0
            default:
210
0
                SkASSERT(false);
211
0
                return 0;
212
4.06k
        }
213
4.06k
    }
214
215
    SkEncodedInfo(const SkEncodedInfo& orig) = delete;
216
    SkEncodedInfo& operator=(const SkEncodedInfo&) = delete;
217
218
14.1k
    SkEncodedInfo(SkEncodedInfo&& orig) = default;
219
    SkEncodedInfo& operator=(SkEncodedInfo&&) = default;
220
221
    // Explicit copy method, to avoid accidental copying.
222
751
    SkEncodedInfo copy() const {
223
751
        auto copy = SkEncodedInfo::Make(fWidth, fHeight, fColor, fAlpha, fBitsPerComponent);
224
751
        if (fProfile) {
225
365
            copy.fProfile = std::make_unique<ICCProfile>(*fProfile);
226
365
        }
227
751
        return copy;
228
751
    }
229
230
private:
231
    SkEncodedInfo(int width, int height, Color color, Alpha alpha,
232
            uint8_t bitsPerComponent, std::unique_ptr<ICCProfile> profile)
233
        : fWidth(width)
234
        , fHeight(height)
235
        , fColor(color)
236
        , fAlpha(alpha)
237
        , fBitsPerComponent(bitsPerComponent)
238
        , fProfile(std::move(profile))
239
14.5k
    {}
240
241
    int                         fWidth;
242
    int                         fHeight;
243
    Color                       fColor;
244
    Alpha                       fAlpha;
245
    uint8_t                     fBitsPerComponent;
246
    std::unique_ptr<ICCProfile> fProfile;
247
};
248
249
#endif