Coverage Report

Created: 2024-09-14 07:19

/src/skia/src/core/SkConvertPixels.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2014 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
#include "src/core/SkConvertPixels.h"
8
9
#include "include/core/SkColorType.h"
10
#include "include/core/SkImageInfo.h"
11
#include "include/core/SkSize.h"
12
#include "include/private/SkColorData.h"
13
#include "include/private/base/SkAssert.h"
14
#include "include/private/base/SkTPin.h"
15
#include "include/private/base/SkTemplates.h"
16
#include "src/base/SkHalf.h"
17
#include "src/base/SkRectMemcpy.h"
18
#include "src/core/SkColorSpaceXformSteps.h"
19
#include "src/core/SkImageInfoPriv.h"
20
#include "src/core/SkRasterPipeline.h"
21
#include "src/core/SkRasterPipelineOpContexts.h"
22
#include "src/core/SkSwizzlePriv.h"
23
24
#include <cstdint>
25
#include <cstring>
26
#include <initializer_list>
27
28
static bool rect_memcpy(const SkImageInfo& dstInfo,       void* dstPixels, size_t dstRB,
29
                        const SkImageInfo& srcInfo, const void* srcPixels, size_t srcRB,
30
138k
                        const SkColorSpaceXformSteps& steps) {
31
    // We can copy the pixels when no color type, alpha type, or color space changes.
32
138k
    if (dstInfo.colorType() != srcInfo.colorType()) {
33
119k
        return false;
34
119k
    }
35
18.8k
    if (dstInfo.colorType() != kAlpha_8_SkColorType
36
18.8k
            && steps.flags.mask() != 0b00000) {
37
90
        return false;
38
90
    }
39
40
18.7k
    SkRectMemcpy(dstPixels, dstRB,
41
18.7k
                 srcPixels, srcRB, dstInfo.minRowBytes(), dstInfo.height());
42
18.7k
    return true;
43
18.8k
}
44
45
static bool swizzle_or_premul(const SkImageInfo& dstInfo,       void* dstPixels, size_t dstRB,
46
                              const SkImageInfo& srcInfo, const void* srcPixels, size_t srcRB,
47
119k
                              const SkColorSpaceXformSteps& steps) {
48
171k
    auto is_8888 = [](SkColorType ct) {
49
171k
        return ct == kRGBA_8888_SkColorType || ct == kBGRA_8888_SkColorType;
50
171k
    };
51
119k
    if (!is_8888(dstInfo.colorType()) ||
52
119k
        !is_8888(srcInfo.colorType()) ||
53
119k
        steps.flags.linearize         ||
54
119k
        steps.flags.gamut_transform   ||
55
119k
#if !defined(SK_ARM_HAS_NEON)
56
119k
        steps.flags.unpremul          ||
57
119k
#endif
58
119k
        steps.flags.encode) {
59
118k
        return false;
60
118k
    }
61
62
1.23k
    const bool swapRB = dstInfo.colorType() != srcInfo.colorType();
63
64
1.23k
    void (*fn)(uint32_t*, const uint32_t*, int) = nullptr;
65
66
1.23k
    if (steps.flags.premul) {
67
0
        fn = swapRB ? SkOpts::RGBA_to_bgrA
68
0
                    : SkOpts::RGBA_to_rgbA;
69
1.23k
    } else if (steps.flags.unpremul) {
70
0
        fn = swapRB ? SkOpts::rgbA_to_BGRA
71
0
                    : SkOpts::rgbA_to_RGBA;
72
1.23k
    } else {
73
        // If we're not swizzling, we ought to have used rect_memcpy().
74
1.23k
        SkASSERT(swapRB);
75
1.23k
        fn = SkOpts::RGBA_to_BGRA;
76
1.23k
    }
77
78
7.49M
    for (int y = 0; y < dstInfo.height(); y++) {
79
7.49M
        fn((uint32_t*)dstPixels, (const uint32_t*)srcPixels, dstInfo.width());
80
7.49M
        dstPixels = SkTAddOffset<void>(dstPixels, dstRB);
81
7.49M
        srcPixels = SkTAddOffset<const void>(srcPixels, srcRB);
82
7.49M
    }
83
1.23k
    return true;
84
119k
}
SkConvertPixels.cpp:swizzle_or_premul(SkImageInfo const&, void*, unsigned long, SkImageInfo const&, void const*, unsigned long, SkColorSpaceXformSteps const&)
Line
Count
Source
47
119k
                              const SkColorSpaceXformSteps& steps) {
48
119k
    auto is_8888 = [](SkColorType ct) {
49
119k
        return ct == kRGBA_8888_SkColorType || ct == kBGRA_8888_SkColorType;
50
119k
    };
51
119k
    if (!is_8888(dstInfo.colorType()) ||
52
119k
        !is_8888(srcInfo.colorType()) ||
53
119k
        steps.flags.linearize         ||
54
119k
        steps.flags.gamut_transform   ||
55
119k
#if !defined(SK_ARM_HAS_NEON)
56
119k
        steps.flags.unpremul          ||
57
119k
#endif
58
119k
        steps.flags.encode) {
59
118k
        return false;
60
118k
    }
61
62
1.23k
    const bool swapRB = dstInfo.colorType() != srcInfo.colorType();
63
64
1.23k
    void (*fn)(uint32_t*, const uint32_t*, int) = nullptr;
65
66
1.23k
    if (steps.flags.premul) {
67
0
        fn = swapRB ? SkOpts::RGBA_to_bgrA
68
0
                    : SkOpts::RGBA_to_rgbA;
69
1.23k
    } else if (steps.flags.unpremul) {
70
0
        fn = swapRB ? SkOpts::rgbA_to_BGRA
71
0
                    : SkOpts::rgbA_to_RGBA;
72
1.23k
    } else {
73
        // If we're not swizzling, we ought to have used rect_memcpy().
74
1.23k
        SkASSERT(swapRB);
75
1.23k
        fn = SkOpts::RGBA_to_BGRA;
76
1.23k
    }
77
78
7.49M
    for (int y = 0; y < dstInfo.height(); y++) {
79
7.49M
        fn((uint32_t*)dstPixels, (const uint32_t*)srcPixels, dstInfo.width());
80
7.49M
        dstPixels = SkTAddOffset<void>(dstPixels, dstRB);
81
7.49M
        srcPixels = SkTAddOffset<const void>(srcPixels, srcRB);
82
7.49M
    }
83
1.23k
    return true;
84
119k
}
Unexecuted instantiation: SkConvertPixels.cpp:swizzle_or_premul(SkImageInfo const&, void*, unsigned long, SkImageInfo const&, void const*, unsigned long, SkColorSpaceXformSteps const&)
85
86
static bool convert_to_alpha8(const SkImageInfo& dstInfo,       void* vdst, size_t dstRB,
87
                              const SkImageInfo& srcInfo, const void*  src, size_t srcRB,
88
118k
                              const SkColorSpaceXformSteps&) {
89
118k
    if (dstInfo.colorType() != kAlpha_8_SkColorType) {
90
105k
        return false;
91
105k
    }
92
13.0k
    auto dst = (uint8_t*)vdst;
93
94
13.0k
    switch (srcInfo.colorType()) {
95
0
        case kUnknown_SkColorType:
96
0
        case kAlpha_8_SkColorType: {
97
            // Unknown should never happen.
98
            // Alpha8 should have been handled by rect_memcpy().
99
0
            SkASSERT(false);
100
0
            return false;
101
0
        }
102
103
0
        case kA16_unorm_SkColorType: {
104
0
            auto src16 = (const uint16_t*) src;
105
0
            for (int y = 0; y < srcInfo.height(); y++) {
106
0
                for (int x = 0; x < srcInfo.width(); x++) {
107
0
                    dst[x] = src16[x] >> 8;
108
0
                }
109
0
                dst = SkTAddOffset<uint8_t>(dst, dstRB);
110
0
                src16 = SkTAddOffset<const uint16_t>(src16, srcRB);
111
0
            }
112
0
            return true;
113
0
        }
114
115
0
        case kGray_8_SkColorType:
116
0
        case kRGB_565_SkColorType:
117
0
        case kR8G8_unorm_SkColorType:
118
0
        case kR16G16_unorm_SkColorType:
119
0
        case kR16G16_float_SkColorType:
120
0
        case kRGB_888x_SkColorType:
121
0
        case kRGB_101010x_SkColorType:
122
0
        case kBGR_101010x_SkColorType:
123
0
        case kBGR_101010x_XR_SkColorType:
124
0
        case kRGB_F16F16F16x_SkColorType:
125
0
        case kR8_unorm_SkColorType: {
126
0
            for (int y = 0; y < srcInfo.height(); ++y) {
127
0
               memset(dst, 0xFF, srcInfo.width());
128
0
               dst = SkTAddOffset<uint8_t>(dst, dstRB);
129
0
            }
130
0
            return true;
131
0
        }
132
133
0
        case kARGB_4444_SkColorType: {
134
0
            auto src16 = (const uint16_t*) src;
135
0
            for (int y = 0; y < srcInfo.height(); y++) {
136
0
                for (int x = 0; x < srcInfo.width(); x++) {
137
0
                    dst[x] = SkPacked4444ToA32(src16[x]);
138
0
                }
139
0
                dst = SkTAddOffset<uint8_t>(dst, dstRB);
140
0
                src16 = SkTAddOffset<const uint16_t>(src16, srcRB);
141
0
            }
142
0
            return true;
143
0
        }
144
145
0
        case kBGRA_8888_SkColorType:
146
0
        case kRGBA_8888_SkColorType:
147
0
        case kSRGBA_8888_SkColorType: {
148
0
            auto src32 = (const uint32_t*) src;
149
0
            for (int y = 0; y < srcInfo.height(); y++) {
150
0
                for (int x = 0; x < srcInfo.width(); x++) {
151
0
                    dst[x] = src32[x] >> 24;
152
0
                }
153
0
                dst = SkTAddOffset<uint8_t>(dst, dstRB);
154
0
                src32 = SkTAddOffset<const uint32_t>(src32, srcRB);
155
0
            }
156
0
            return true;
157
0
        }
158
159
0
        case kRGBA_1010102_SkColorType:
160
0
        case kBGRA_1010102_SkColorType: {
161
0
            auto src32 = (const uint32_t*) src;
162
0
            for (int y = 0; y < srcInfo.height(); y++) {
163
0
                for (int x = 0; x < srcInfo.width(); x++) {
164
0
                    dst[x] = (src32[x] >> 30) * 0x55;
165
0
                }
166
0
                dst = SkTAddOffset<uint8_t>(dst, dstRB);
167
0
                src32 = SkTAddOffset<const uint32_t>(src32, srcRB);
168
0
            }
169
0
            return true;
170
0
        }
171
172
0
        case kRGBA_F16Norm_SkColorType:
173
0
        case kRGBA_F16_SkColorType: {
174
0
            auto src64 = (const uint64_t*) src;
175
0
            for (int y = 0; y < srcInfo.height(); y++) {
176
0
                for (int x = 0; x < srcInfo.width(); x++) {
177
0
                    dst[x] = (uint8_t) (255.0f * SkHalfToFloat(src64[x] >> 48));
178
0
                }
179
0
                dst = SkTAddOffset<uint8_t>(dst, dstRB);
180
0
                src64 = SkTAddOffset<const uint64_t>(src64, srcRB);
181
0
            }
182
0
            return true;
183
0
        }
184
185
13.0k
        case kRGBA_F32_SkColorType: {
186
13.0k
            auto rgba = (const float*)src;
187
26.0k
            for (int y = 0; y < srcInfo.height(); y++) {
188
26.0k
                for (int x = 0; x < srcInfo.width(); x++) {
189
13.0k
                    dst[x] = (uint8_t)(255.0f * rgba[4*x+3]);
190
13.0k
                }
191
13.0k
                dst  = SkTAddOffset<uint8_t>(dst, dstRB);
192
13.0k
                rgba = SkTAddOffset<const float>(rgba, srcRB);
193
13.0k
            }
194
13.0k
            return true;
195
0
        }
196
197
0
        case kA16_float_SkColorType: {
198
0
            auto srcF16 = (const uint16_t*) src;
199
0
            for (int y = 0; y < srcInfo.height(); y++) {
200
0
                for (int x = 0; x < srcInfo.width(); x++) {
201
0
                    dst[x] = (uint8_t) (255.0f * SkHalfToFloat(srcF16[x]));
202
0
                }
203
0
                dst = SkTAddOffset<uint8_t>(dst, dstRB);
204
0
                srcF16 = SkTAddOffset<const uint16_t>(srcF16, srcRB);
205
0
            }
206
0
            return true;
207
0
        }
208
209
0
        case kBGRA_10101010_XR_SkColorType: {
210
0
            auto src64 = (const uint64_t*) src;
211
0
            for (int y = 0; y < srcInfo.height(); y++) {
212
0
                for (int x = 0; x < srcInfo.width(); x++) {
213
0
                    static constexpr int64_t kZero = 384;
214
0
                    static constexpr int64_t kRange = 510;
215
0
                    static constexpr int64_t kMaxU8 = 0xff;
216
0
                    static constexpr int64_t kMinU8 = 0x00;
217
0
                    static constexpr int64_t kDivisor = kRange / kMaxU8;
218
0
                    int64_t raw_alpha = src64[x] >> 54;
219
                    // f(384) = 0
220
                    // f(894) = 255
221
0
                    int64_t alpha =
222
0
                            SkTPin((raw_alpha - kZero) / kDivisor, kMinU8, kMaxU8);
223
0
                    dst[x] = static_cast<uint8_t>(alpha);
224
0
                }
225
0
                dst = SkTAddOffset<uint8_t>(dst, dstRB);
226
0
                src64 = SkTAddOffset<const uint64_t>(src64, srcRB);
227
0
            }
228
0
            return true;
229
0
        }
230
0
        case kRGBA_10x6_SkColorType:
231
0
        case kR16G16B16A16_unorm_SkColorType: {
232
0
            auto src64 = (const uint64_t*) src;
233
0
            for (int y = 0; y < srcInfo.height(); y++) {
234
0
                for (int x = 0; x < srcInfo.width(); x++) {
235
0
                    dst[x] = (src64[x] >> 48) >> 8;
236
0
                }
237
0
                dst = SkTAddOffset<uint8_t>(dst, dstRB);
238
0
                src64 = SkTAddOffset<const uint64_t>(src64, srcRB);
239
0
            }
240
0
            return true;
241
0
        }
242
13.0k
    }
243
0
    return false;
244
13.0k
}
SkConvertPixels.cpp:convert_to_alpha8(SkImageInfo const&, void*, unsigned long, SkImageInfo const&, void const*, unsigned long, SkColorSpaceXformSteps const&)
Line
Count
Source
88
118k
                              const SkColorSpaceXformSteps&) {
89
118k
    if (dstInfo.colorType() != kAlpha_8_SkColorType) {
90
105k
        return false;
91
105k
    }
92
13.0k
    auto dst = (uint8_t*)vdst;
93
94
13.0k
    switch (srcInfo.colorType()) {
95
0
        case kUnknown_SkColorType:
96
0
        case kAlpha_8_SkColorType: {
97
            // Unknown should never happen.
98
            // Alpha8 should have been handled by rect_memcpy().
99
0
            SkASSERT(false);
100
0
            return false;
101
0
        }
102
103
0
        case kA16_unorm_SkColorType: {
104
0
            auto src16 = (const uint16_t*) src;
105
0
            for (int y = 0; y < srcInfo.height(); y++) {
106
0
                for (int x = 0; x < srcInfo.width(); x++) {
107
0
                    dst[x] = src16[x] >> 8;
108
0
                }
109
0
                dst = SkTAddOffset<uint8_t>(dst, dstRB);
110
0
                src16 = SkTAddOffset<const uint16_t>(src16, srcRB);
111
0
            }
112
0
            return true;
113
0
        }
114
115
0
        case kGray_8_SkColorType:
116
0
        case kRGB_565_SkColorType:
117
0
        case kR8G8_unorm_SkColorType:
118
0
        case kR16G16_unorm_SkColorType:
119
0
        case kR16G16_float_SkColorType:
120
0
        case kRGB_888x_SkColorType:
121
0
        case kRGB_101010x_SkColorType:
122
0
        case kBGR_101010x_SkColorType:
123
0
        case kBGR_101010x_XR_SkColorType:
124
0
        case kRGB_F16F16F16x_SkColorType:
125
0
        case kR8_unorm_SkColorType: {
126
0
            for (int y = 0; y < srcInfo.height(); ++y) {
127
0
               memset(dst, 0xFF, srcInfo.width());
128
0
               dst = SkTAddOffset<uint8_t>(dst, dstRB);
129
0
            }
130
0
            return true;
131
0
        }
132
133
0
        case kARGB_4444_SkColorType: {
134
0
            auto src16 = (const uint16_t*) src;
135
0
            for (int y = 0; y < srcInfo.height(); y++) {
136
0
                for (int x = 0; x < srcInfo.width(); x++) {
137
0
                    dst[x] = SkPacked4444ToA32(src16[x]);
138
0
                }
139
0
                dst = SkTAddOffset<uint8_t>(dst, dstRB);
140
0
                src16 = SkTAddOffset<const uint16_t>(src16, srcRB);
141
0
            }
142
0
            return true;
143
0
        }
144
145
0
        case kBGRA_8888_SkColorType:
146
0
        case kRGBA_8888_SkColorType:
147
0
        case kSRGBA_8888_SkColorType: {
148
0
            auto src32 = (const uint32_t*) src;
149
0
            for (int y = 0; y < srcInfo.height(); y++) {
150
0
                for (int x = 0; x < srcInfo.width(); x++) {
151
0
                    dst[x] = src32[x] >> 24;
152
0
                }
153
0
                dst = SkTAddOffset<uint8_t>(dst, dstRB);
154
0
                src32 = SkTAddOffset<const uint32_t>(src32, srcRB);
155
0
            }
156
0
            return true;
157
0
        }
158
159
0
        case kRGBA_1010102_SkColorType:
160
0
        case kBGRA_1010102_SkColorType: {
161
0
            auto src32 = (const uint32_t*) src;
162
0
            for (int y = 0; y < srcInfo.height(); y++) {
163
0
                for (int x = 0; x < srcInfo.width(); x++) {
164
0
                    dst[x] = (src32[x] >> 30) * 0x55;
165
0
                }
166
0
                dst = SkTAddOffset<uint8_t>(dst, dstRB);
167
0
                src32 = SkTAddOffset<const uint32_t>(src32, srcRB);
168
0
            }
169
0
            return true;
170
0
        }
171
172
0
        case kRGBA_F16Norm_SkColorType:
173
0
        case kRGBA_F16_SkColorType: {
174
0
            auto src64 = (const uint64_t*) src;
175
0
            for (int y = 0; y < srcInfo.height(); y++) {
176
0
                for (int x = 0; x < srcInfo.width(); x++) {
177
0
                    dst[x] = (uint8_t) (255.0f * SkHalfToFloat(src64[x] >> 48));
178
0
                }
179
0
                dst = SkTAddOffset<uint8_t>(dst, dstRB);
180
0
                src64 = SkTAddOffset<const uint64_t>(src64, srcRB);
181
0
            }
182
0
            return true;
183
0
        }
184
185
13.0k
        case kRGBA_F32_SkColorType: {
186
13.0k
            auto rgba = (const float*)src;
187
26.0k
            for (int y = 0; y < srcInfo.height(); y++) {
188
26.0k
                for (int x = 0; x < srcInfo.width(); x++) {
189
13.0k
                    dst[x] = (uint8_t)(255.0f * rgba[4*x+3]);
190
13.0k
                }
191
13.0k
                dst  = SkTAddOffset<uint8_t>(dst, dstRB);
192
13.0k
                rgba = SkTAddOffset<const float>(rgba, srcRB);
193
13.0k
            }
194
13.0k
            return true;
195
0
        }
196
197
0
        case kA16_float_SkColorType: {
198
0
            auto srcF16 = (const uint16_t*) src;
199
0
            for (int y = 0; y < srcInfo.height(); y++) {
200
0
                for (int x = 0; x < srcInfo.width(); x++) {
201
0
                    dst[x] = (uint8_t) (255.0f * SkHalfToFloat(srcF16[x]));
202
0
                }
203
0
                dst = SkTAddOffset<uint8_t>(dst, dstRB);
204
0
                srcF16 = SkTAddOffset<const uint16_t>(srcF16, srcRB);
205
0
            }
206
0
            return true;
207
0
        }
208
209
0
        case kBGRA_10101010_XR_SkColorType: {
210
0
            auto src64 = (const uint64_t*) src;
211
0
            for (int y = 0; y < srcInfo.height(); y++) {
212
0
                for (int x = 0; x < srcInfo.width(); x++) {
213
0
                    static constexpr int64_t kZero = 384;
214
0
                    static constexpr int64_t kRange = 510;
215
0
                    static constexpr int64_t kMaxU8 = 0xff;
216
0
                    static constexpr int64_t kMinU8 = 0x00;
217
0
                    static constexpr int64_t kDivisor = kRange / kMaxU8;
218
0
                    int64_t raw_alpha = src64[x] >> 54;
219
                    // f(384) = 0
220
                    // f(894) = 255
221
0
                    int64_t alpha =
222
0
                            SkTPin((raw_alpha - kZero) / kDivisor, kMinU8, kMaxU8);
223
0
                    dst[x] = static_cast<uint8_t>(alpha);
224
0
                }
225
0
                dst = SkTAddOffset<uint8_t>(dst, dstRB);
226
0
                src64 = SkTAddOffset<const uint64_t>(src64, srcRB);
227
0
            }
228
0
            return true;
229
0
        }
230
0
        case kRGBA_10x6_SkColorType:
231
0
        case kR16G16B16A16_unorm_SkColorType: {
232
0
            auto src64 = (const uint64_t*) src;
233
0
            for (int y = 0; y < srcInfo.height(); y++) {
234
0
                for (int x = 0; x < srcInfo.width(); x++) {
235
0
                    dst[x] = (src64[x] >> 48) >> 8;
236
0
                }
237
0
                dst = SkTAddOffset<uint8_t>(dst, dstRB);
238
0
                src64 = SkTAddOffset<const uint64_t>(src64, srcRB);
239
0
            }
240
0
            return true;
241
0
        }
242
13.0k
    }
243
0
    return false;
244
13.0k
}
Unexecuted instantiation: SkConvertPixels.cpp:convert_to_alpha8(SkImageInfo const&, void*, unsigned long, SkImageInfo const&, void const*, unsigned long, SkColorSpaceXformSteps const&)
245
246
// Default: Use the pipeline.
247
static void convert_with_pipeline(const SkImageInfo& dstInfo, void* dstRow, int dstStride,
248
                                  const SkImageInfo& srcInfo, const void* srcRow, int srcStride,
249
105k
                                  const SkColorSpaceXformSteps& steps) {
250
105k
    SkRasterPipeline_MemoryCtx src = { const_cast<void*>(srcRow), srcStride },
251
105k
                               dst = {                   dstRow,  dstStride };
252
253
105k
    SkRasterPipeline_<256> pipeline;
254
105k
    pipeline.appendLoad(srcInfo.colorType(), &src);
255
105k
    steps.apply(&pipeline);
256
105k
    pipeline.appendStore(dstInfo.colorType(), &dst);
257
105k
    pipeline.run(0,0, srcInfo.width(), srcInfo.height());
258
105k
}
259
260
bool SkConvertPixels(const SkImageInfo& dstInfo,       void* dstPixels, size_t dstRB,
261
138k
                     const SkImageInfo& srcInfo, const void* srcPixels, size_t srcRB) {
262
138k
    SkASSERT(dstInfo.dimensions() == srcInfo.dimensions());
263
138k
    SkASSERT(SkImageInfoValidConversion(dstInfo, srcInfo));
264
265
138k
    int srcStride = (int)(srcRB / srcInfo.bytesPerPixel());
266
138k
    int dstStride = (int)(dstRB / dstInfo.bytesPerPixel());
267
138k
    if ((size_t)srcStride * srcInfo.bytesPerPixel() != srcRB ||
268
138k
        (size_t)dstStride * dstInfo.bytesPerPixel() != dstRB) {
269
0
        return false;
270
0
    }
271
272
138k
    SkColorSpaceXformSteps steps{srcInfo.colorSpace(), srcInfo.alphaType(),
273
138k
                                 dstInfo.colorSpace(), dstInfo.alphaType()};
274
275
376k
    for (auto fn : {rect_memcpy, swizzle_or_premul, convert_to_alpha8}) {
276
376k
        if (fn(dstInfo, dstPixels, dstRB, srcInfo, srcPixels, srcRB, steps)) {
277
32.9k
            return true;
278
32.9k
        }
279
376k
    }
280
105k
    convert_with_pipeline(dstInfo, dstPixels, dstStride, srcInfo, srcPixels, srcStride, steps);
281
105k
    return true;
282
138k
}