Coverage Report

Created: 2022-08-24 06:17

/src/x265/source/common/picyuv.cpp
Line
Count
Source (jump to first uncovered line)
1
/*****************************************************************************
2
 * Copyright (C) 2013-2020 MulticoreWare, Inc
3
 *
4
 * Authors: Steve Borho <steve@borho.org>
5
 *          Min Chen <chenm003@163.com>
6
 *
7
 * This program is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 2 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
20
 *
21
 * This program is also available under a commercial proprietary license.
22
 * For more information, contact us at license @ x265.com.
23
 *****************************************************************************/
24
25
#include "common.h"
26
#include "picyuv.h"
27
#include "slice.h"
28
#include "primitives.h"
29
30
using namespace X265_NS;
31
32
PicYuv::PicYuv()
33
1.39k
{
34
1.39k
    m_picBuf[0] = NULL;
35
1.39k
    m_picBuf[1] = NULL;
36
1.39k
    m_picBuf[2] = NULL;
37
38
1.39k
    m_picOrg[0] = NULL;
39
1.39k
    m_picOrg[1] = NULL;
40
1.39k
    m_picOrg[2] = NULL;
41
42
1.39k
    m_cuOffsetY = NULL;
43
1.39k
    m_cuOffsetC = NULL;
44
1.39k
    m_buOffsetY = NULL;
45
1.39k
    m_buOffsetC = NULL;
46
47
1.39k
    m_maxLumaLevel = 0;
48
1.39k
    m_avgLumaLevel = 0;
49
50
1.39k
    m_maxChromaULevel = 0;
51
1.39k
    m_avgChromaULevel = 0;
52
53
1.39k
    m_maxChromaVLevel = 0;
54
1.39k
    m_avgChromaVLevel = 0;
55
56
#if (X265_DEPTH > 8)
57
    m_minLumaLevel = 0xFFFF;
58
    m_minChromaULevel = 0xFFFF;
59
    m_minChromaVLevel = 0xFFFF;
60
#else
61
1.39k
    m_minLumaLevel = 0xFF;
62
1.39k
    m_minChromaULevel = 0xFF;
63
1.39k
    m_minChromaVLevel = 0xFF;
64
1.39k
#endif
65
66
1.39k
    m_stride = 0;
67
1.39k
    m_strideC = 0;
68
1.39k
    m_hChromaShift = 0;
69
1.39k
    m_vChromaShift = 0;
70
1.39k
}
71
72
bool PicYuv::create(x265_param* param, bool picAlloc, pixel *pixelbuf)
73
1.39k
{
74
1.39k
    m_param = param;
75
1.39k
    uint32_t picWidth = m_param->sourceWidth;
76
1.39k
    uint32_t picHeight = m_param->sourceHeight;
77
1.39k
    uint32_t picCsp = m_param->internalCsp;
78
1.39k
    m_picWidth  = picWidth;
79
1.39k
    m_picHeight = picHeight;
80
1.39k
    m_hChromaShift = CHROMA_H_SHIFT(picCsp);
81
1.39k
    m_vChromaShift = CHROMA_V_SHIFT(picCsp);
82
1.39k
    m_picCsp = picCsp;
83
84
1.39k
    uint32_t numCuInWidth = (m_picWidth + param->maxCUSize - 1)  / param->maxCUSize;
85
1.39k
    uint32_t numCuInHeight = (m_picHeight + param->maxCUSize - 1) / param->maxCUSize;
86
87
1.39k
    m_lumaMarginX = param->maxCUSize + 32; // search margin and 8-tap filter half-length, padded for 32-byte alignment
88
1.39k
    m_lumaMarginY = param->maxCUSize + 16; // margin for 8-tap filter and infinite padding
89
1.39k
    m_stride = (numCuInWidth * param->maxCUSize) + (m_lumaMarginX << 1);
90
91
1.39k
    int maxHeight = numCuInHeight * param->maxCUSize;
92
1.39k
    if (pixelbuf)
93
0
        m_picOrg[0] = pixelbuf;
94
1.39k
    else
95
1.39k
    {
96
1.39k
        if (picAlloc)
97
1.39k
        {
98
1.39k
            CHECKED_MALLOC(m_picBuf[0], pixel, m_stride * (maxHeight + (m_lumaMarginY * 2)));
99
1.39k
            m_picOrg[0] = m_picBuf[0] + m_lumaMarginY * m_stride + m_lumaMarginX;
100
1.39k
        }
101
1.39k
    }
102
103
1.39k
    if (picCsp != X265_CSP_I400)
104
1.39k
    {
105
1.39k
        m_chromaMarginX = m_lumaMarginX;  // keep 16-byte alignment for chroma CTUs
106
1.39k
        m_chromaMarginY = m_lumaMarginY >> m_vChromaShift;
107
1.39k
        m_strideC = ((numCuInWidth * m_param->maxCUSize) >> m_hChromaShift) + (m_chromaMarginX * 2);
108
1.39k
        if (picAlloc)
109
1.39k
        {
110
1.39k
            CHECKED_MALLOC(m_picBuf[1], pixel, m_strideC * ((maxHeight >> m_vChromaShift) + (m_chromaMarginY * 2)));
111
1.39k
            CHECKED_MALLOC(m_picBuf[2], pixel, m_strideC * ((maxHeight >> m_vChromaShift) + (m_chromaMarginY * 2)));
112
113
1.39k
            m_picOrg[1] = m_picBuf[1] + m_chromaMarginY * m_strideC + m_chromaMarginX;
114
1.39k
            m_picOrg[2] = m_picBuf[2] + m_chromaMarginY * m_strideC + m_chromaMarginX;
115
1.39k
        }
116
1.39k
    }
117
0
    else
118
0
    {
119
0
        m_picBuf[1] = m_picBuf[2] = NULL;
120
0
        m_picOrg[1] = m_picOrg[2] = NULL;
121
0
    }
122
1.39k
    return true;
123
124
0
fail:
125
0
    return false;
126
1.39k
}
127
128
int PicYuv::getLumaBufLen(uint32_t picWidth, uint32_t picHeight, uint32_t picCsp)
129
0
{
130
0
    m_picWidth = picWidth;
131
0
    m_picHeight = picHeight;
132
0
    m_hChromaShift = CHROMA_H_SHIFT(picCsp);
133
0
    m_vChromaShift = CHROMA_V_SHIFT(picCsp);
134
0
    m_picCsp = picCsp;
135
136
0
    uint32_t numCuInWidth = (m_picWidth + m_param->maxCUSize - 1) / m_param->maxCUSize;
137
0
    uint32_t numCuInHeight = (m_picHeight + m_param->maxCUSize - 1) / m_param->maxCUSize;
138
139
0
    m_lumaMarginX = m_param->maxCUSize + 32; // search margin and 8-tap filter half-length, padded for 32-byte alignment
140
0
    m_lumaMarginY = m_param->maxCUSize + 16; // margin for 8-tap filter and infinite padding
141
0
    m_stride = (numCuInWidth * m_param->maxCUSize) + (m_lumaMarginX << 1);
142
143
0
    int maxHeight = numCuInHeight * m_param->maxCUSize;
144
0
    int bufLen = (int)(m_stride * (maxHeight + (m_lumaMarginY * 2)));
145
146
0
    return bufLen;
147
0
}
148
149
/* the first picture allocated by the encoder will be asked to generate these
150
 * offset arrays. Once generated, they will be provided to all future PicYuv
151
 * allocated by the same encoder. */
152
bool PicYuv::createOffsets(const SPS& sps)
153
698
{
154
698
    uint32_t numPartitions = 1 << (m_param->unitSizeDepth * 2);
155
156
698
    if (m_picCsp != X265_CSP_I400)
157
698
    {
158
698
        CHECKED_MALLOC(m_cuOffsetY, intptr_t, sps.numCuInWidth * sps.numCuInHeight);
159
698
        CHECKED_MALLOC(m_cuOffsetC, intptr_t, sps.numCuInWidth * sps.numCuInHeight);
160
3.87k
        for (uint32_t cuRow = 0; cuRow < sps.numCuInHeight; cuRow++)
161
3.17k
        {
162
17.1k
            for (uint32_t cuCol = 0; cuCol < sps.numCuInWidth; cuCol++)
163
13.9k
            {
164
13.9k
                m_cuOffsetY[cuRow * sps.numCuInWidth + cuCol] = m_stride * cuRow * m_param->maxCUSize + cuCol * m_param->maxCUSize;
165
13.9k
                m_cuOffsetC[cuRow * sps.numCuInWidth + cuCol] = m_strideC * cuRow * (m_param->maxCUSize >> m_vChromaShift) + cuCol * (m_param->maxCUSize >> m_hChromaShift);
166
13.9k
            }
167
3.17k
        }
168
169
698
        CHECKED_MALLOC(m_buOffsetY, intptr_t, (size_t)numPartitions);
170
698
        CHECKED_MALLOC(m_buOffsetC, intptr_t, (size_t)numPartitions);
171
130k
        for (uint32_t idx = 0; idx < numPartitions; ++idx)
172
130k
        {
173
130k
            intptr_t x = g_zscanToPelX[idx];
174
130k
            intptr_t y = g_zscanToPelY[idx];
175
130k
            m_buOffsetY[idx] = m_stride * y + x;
176
130k
            m_buOffsetC[idx] = m_strideC * (y >> m_vChromaShift) + (x >> m_hChromaShift);
177
130k
        }
178
698
    }
179
0
    else
180
0
    {
181
0
        CHECKED_MALLOC(m_cuOffsetY, intptr_t, sps.numCuInWidth * sps.numCuInHeight);
182
0
        for (uint32_t cuRow = 0; cuRow < sps.numCuInHeight; cuRow++)
183
0
        for (uint32_t cuCol = 0; cuCol < sps.numCuInWidth; cuCol++)
184
0
            m_cuOffsetY[cuRow * sps.numCuInWidth + cuCol] = m_stride * cuRow * m_param->maxCUSize + cuCol * m_param->maxCUSize;
185
186
0
        CHECKED_MALLOC(m_buOffsetY, intptr_t, (size_t)numPartitions);
187
0
        for (uint32_t idx = 0; idx < numPartitions; ++idx)
188
0
        {
189
0
            intptr_t x = g_zscanToPelX[idx];
190
0
            intptr_t y = g_zscanToPelY[idx];
191
0
            m_buOffsetY[idx] = m_stride * y + x;
192
0
        }
193
0
    }
194
698
    return true;
195
196
0
fail:
197
0
    return false;
198
698
}
199
200
void PicYuv::destroy()
201
1.39k
{
202
1.39k
    X265_FREE(m_picBuf[0]);
203
1.39k
    X265_FREE(m_picBuf[1]);
204
1.39k
    X265_FREE(m_picBuf[2]);
205
1.39k
}
206
207
/* Copy pixels from an x265_picture into internal PicYuv instance.
208
 * Shift pixels as necessary, mask off bits above X265_DEPTH for safety. */
209
void PicYuv::copyFromPicture(const x265_picture& pic, const x265_param& param, int padx, int pady)
210
698
{
211
    /* m_picWidth is the width that is being encoded, padx indicates how many
212
     * of those pixels are padding to reach multiple of MinCU(4) size.
213
     *
214
     * Internally, we need to extend rows out to a multiple of 16 for lowres
215
     * downscale and other operations. But those padding pixels are never
216
     * encoded.
217
     *
218
     * The same applies to m_picHeight and pady */
219
220
    /* width and height - without padsize (input picture raw width and height) */
221
698
    int width = m_picWidth - padx;
222
698
    int height = m_picHeight - pady;
223
224
    /* internal pad to multiple of 16x16 blocks */
225
698
    uint8_t rem = width & 15;
226
227
698
    padx = rem ? 16 - rem : padx;
228
698
    rem = height & 15;
229
698
    pady = rem ? 16 - rem : pady;
230
231
    /* add one more row and col of pad for downscale interpolation, fixes
232
     * warnings from valgrind about using uninitialized pixels */
233
698
    padx++;
234
698
    pady++;
235
698
    m_picCsp = pic.colorSpace;
236
237
698
    X265_CHECK(pic.bitDepth >= 8, "pic.bitDepth check failure");
238
239
698
    uint64_t lumaSum;
240
698
    uint64_t cbSum;
241
698
    uint64_t crSum;
242
698
    lumaSum = cbSum = crSum = 0;
243
244
698
    if (m_param->bCopyPicToFrame)
245
698
    {
246
698
        if (pic.bitDepth == 8)
247
698
        {
248
#if (X265_DEPTH > 8)
249
        {
250
            pixel *yPixel = m_picOrg[0];
251
252
            uint8_t *yChar = (uint8_t*)pic.planes[0];
253
            int shift = (X265_DEPTH - 8);
254
255
            primitives.planecopy_cp(yChar, pic.stride[0] / sizeof(*yChar), yPixel, m_stride, width, height, shift);
256
257
            if (param.internalCsp != X265_CSP_I400)
258
            {
259
                pixel *uPixel = m_picOrg[1];
260
                pixel *vPixel = m_picOrg[2];
261
262
                uint8_t *uChar = (uint8_t*)pic.planes[1];
263
                uint8_t *vChar = (uint8_t*)pic.planes[2];
264
265
                primitives.planecopy_cp(uChar, pic.stride[1] / sizeof(*uChar), uPixel, m_strideC, width >> m_hChromaShift, height >> m_vChromaShift, shift);
266
                primitives.planecopy_cp(vChar, pic.stride[2] / sizeof(*vChar), vPixel, m_strideC, width >> m_hChromaShift, height >> m_vChromaShift, shift);
267
            }
268
        }
269
#else /* Case for (X265_DEPTH == 8) */
270
            // TODO: Does we need this path? may merge into above in future
271
698
        {
272
698
            pixel *yPixel = m_picOrg[0];
273
698
            uint8_t *yChar = (uint8_t*)pic.planes[0];
274
275
117k
            for (int r = 0; r < height; r++)
276
116k
            {
277
116k
                memcpy(yPixel, yChar, width * sizeof(pixel));
278
279
116k
                yPixel += m_stride;
280
116k
                yChar += pic.stride[0] / sizeof(*yChar);
281
116k
            }
282
283
698
            if (param.internalCsp != X265_CSP_I400)
284
698
            {
285
698
                pixel *uPixel = m_picOrg[1];
286
698
                pixel *vPixel = m_picOrg[2];
287
288
698
                uint8_t *uChar = (uint8_t*)pic.planes[1];
289
698
                uint8_t *vChar = (uint8_t*)pic.planes[2];
290
291
59.1k
                for (int r = 0; r < height >> m_vChromaShift; r++)
292
58.4k
                {
293
58.4k
                    memcpy(uPixel, uChar, (width >> m_hChromaShift) * sizeof(pixel));
294
58.4k
                    memcpy(vPixel, vChar, (width >> m_hChromaShift) * sizeof(pixel));
295
296
58.4k
                    uPixel += m_strideC;
297
58.4k
                    vPixel += m_strideC;
298
58.4k
                    uChar += pic.stride[1] / sizeof(*uChar);
299
58.4k
                    vChar += pic.stride[2] / sizeof(*vChar);
300
58.4k
                }
301
698
            }
302
698
        }
303
698
#endif /* (X265_DEPTH > 8) */
304
698
        }
305
0
        else /* pic.bitDepth > 8 */
306
0
        {
307
            /* defensive programming, mask off bits that are supposed to be zero */
308
0
            uint16_t mask = (1 << X265_DEPTH) - 1;
309
0
            int shift = abs(pic.bitDepth - X265_DEPTH);
310
0
            pixel *yPixel = m_picOrg[0];
311
312
0
            uint16_t *yShort = (uint16_t*)pic.planes[0];
313
314
0
            if (pic.bitDepth > X265_DEPTH)
315
0
            {
316
                /* shift right and mask pixels to final size */
317
0
                primitives.planecopy_sp(yShort, pic.stride[0] / sizeof(*yShort), yPixel, m_stride, width, height, shift, mask);
318
0
            }
319
0
            else /* Case for (pic.bitDepth <= X265_DEPTH) */
320
0
            {
321
                /* shift left and mask pixels to final size */
322
0
                primitives.planecopy_sp_shl(yShort, pic.stride[0] / sizeof(*yShort), yPixel, m_stride, width, height, shift, mask);
323
0
            }
324
325
0
            if (param.internalCsp != X265_CSP_I400)
326
0
            {
327
0
                pixel *uPixel = m_picOrg[1];
328
0
                pixel *vPixel = m_picOrg[2];
329
330
0
                uint16_t *uShort = (uint16_t*)pic.planes[1];
331
0
                uint16_t *vShort = (uint16_t*)pic.planes[2];
332
333
0
                if (pic.bitDepth > X265_DEPTH)
334
0
                {
335
0
                    primitives.planecopy_sp(uShort, pic.stride[1] / sizeof(*uShort), uPixel, m_strideC, width >> m_hChromaShift, height >> m_vChromaShift, shift, mask);
336
0
                    primitives.planecopy_sp(vShort, pic.stride[2] / sizeof(*vShort), vPixel, m_strideC, width >> m_hChromaShift, height >> m_vChromaShift, shift, mask);
337
0
                }
338
0
                else /* Case for (pic.bitDepth <= X265_DEPTH) */
339
0
                {
340
0
                    primitives.planecopy_sp_shl(uShort, pic.stride[1] / sizeof(*uShort), uPixel, m_strideC, width >> m_hChromaShift, height >> m_vChromaShift, shift, mask);
341
0
                    primitives.planecopy_sp_shl(vShort, pic.stride[2] / sizeof(*vShort), vPixel, m_strideC, width >> m_hChromaShift, height >> m_vChromaShift, shift, mask);
342
0
                }
343
0
            }
344
0
        }
345
698
    }
346
0
    else
347
0
    {
348
0
        m_picOrg[0] = (pixel*)pic.planes[0];
349
0
        m_picOrg[1] = (pixel*)pic.planes[1];
350
0
        m_picOrg[2] = (pixel*)pic.planes[2];
351
0
    }
352
353
698
    pixel *Y = m_picOrg[0];
354
698
    pixel *U = m_picOrg[1];
355
698
    pixel *V = m_picOrg[2];
356
357
698
    pixel *yPic = m_picOrg[0];
358
698
    pixel *uPic = m_picOrg[1];
359
698
    pixel *vPic = m_picOrg[2];
360
361
698
    if(param.minLuma != 0 || param.maxLuma != PIXEL_MAX)
362
0
    {
363
0
        for (int r = 0; r < height; r++)
364
0
        {
365
0
            for (int c = 0; c < width; c++)
366
0
            {
367
0
                yPic[c] = X265_MIN(yPic[c], (pixel)param.maxLuma);
368
0
                yPic[c] = X265_MAX(yPic[c], (pixel)param.minLuma);
369
0
            }
370
0
            yPic += m_stride;
371
0
        }
372
0
    }
373
698
    yPic = m_picOrg[0];
374
698
    if (param.csvLogLevel >= 2 || param.maxCLL || param.maxFALL)
375
0
    {
376
0
        for (int r = 0; r < height; r++)
377
0
        {
378
0
            for (int c = 0; c < width; c++)
379
0
            {
380
0
                m_maxLumaLevel = X265_MAX(yPic[c], m_maxLumaLevel);
381
0
                m_minLumaLevel = X265_MIN(yPic[c], m_minLumaLevel);
382
0
                lumaSum += yPic[c];
383
0
            }
384
0
            yPic += m_stride;
385
0
        }
386
0
        m_avgLumaLevel = (double)lumaSum / (m_picHeight * m_picWidth);
387
0
    }
388
698
    if (param.csvLogLevel >= 2)
389
0
    {
390
0
        if (param.internalCsp != X265_CSP_I400)
391
0
        {
392
0
            for (int r = 0; r < height >> m_vChromaShift; r++)
393
0
            {
394
0
                for (int c = 0; c < width >> m_hChromaShift; c++)
395
0
                {
396
0
                    m_maxChromaULevel = X265_MAX(uPic[c], m_maxChromaULevel);
397
0
                    m_minChromaULevel = X265_MIN(uPic[c], m_minChromaULevel);
398
0
                    cbSum += uPic[c];
399
400
0
                    m_maxChromaVLevel = X265_MAX(vPic[c], m_maxChromaVLevel);
401
0
                    m_minChromaVLevel = X265_MIN(vPic[c], m_minChromaVLevel);
402
0
                    crSum += vPic[c];
403
0
                }
404
405
0
                uPic += m_strideC;
406
0
                vPic += m_strideC;
407
0
            }
408
0
            m_avgChromaULevel = (double)cbSum / ((height >> m_vChromaShift) * (width >> m_hChromaShift));
409
0
            m_avgChromaVLevel = (double)crSum / ((height >> m_vChromaShift) * (width >> m_hChromaShift));
410
0
        }
411
0
    }
412
413
#if HIGH_BIT_DEPTH
414
    bool calcHDRParams = !!param.minLuma || (param.maxLuma != PIXEL_MAX);
415
    /* Apply min/max luma bounds for HDR pixel manipulations */
416
    if (calcHDRParams)
417
    {
418
        X265_CHECK(pic.bitDepth == 10, "HDR stats can be applied/calculated only for 10bpp content");
419
        uint64_t sumLuma;
420
        m_maxLumaLevel = primitives.planeClipAndMax(Y, m_stride, width, height, &sumLuma, (pixel)param.minLuma, (pixel)param.maxLuma);
421
        m_avgLumaLevel = (double) sumLuma / (m_picHeight * m_picWidth);
422
    }
423
#else
424
698
    (void) param;
425
698
#endif
426
427
    /* extend the right edge if width was not multiple of the minimum CU size */
428
117k
    for (int r = 0; r < height; r++)
429
116k
    {
430
886k
        for (int x = 0; x < padx; x++)
431
770k
            Y[width + x] = Y[width - 1];
432
116k
        Y += m_stride;
433
116k
    }
434
435
    /* extend the bottom if height was not multiple of the minimum CU size */
436
698
    Y = m_picOrg[0] + (height - 1) * m_stride;
437
5.33k
    for (int i = 1; i <= pady; i++)
438
4.64k
        memcpy(Y + i * m_stride, Y, (width + padx) * sizeof(pixel));
439
440
698
    if (param.internalCsp != X265_CSP_I400)
441
698
    {
442
59.1k
        for (int r = 0; r < height >> m_vChromaShift; r++)
443
58.4k
        {
444
221k
            for (int x = 0; x < padx >> m_hChromaShift; x++)
445
163k
            {
446
163k
                U[(width >> m_hChromaShift) + x] = U[(width >> m_hChromaShift) - 1];
447
163k
                V[(width >> m_hChromaShift) + x] = V[(width >> m_hChromaShift) - 1];
448
163k
            }
449
450
58.4k
            U += m_strideC;
451
58.4k
            V += m_strideC;
452
58.4k
        }
453
454
698
        U = m_picOrg[1] + ((height >> m_vChromaShift) - 1) * m_strideC;
455
698
        V = m_picOrg[2] + ((height >> m_vChromaShift) - 1) * m_strideC;
456
457
2.66k
        for (int j = 1; j <= pady >> m_vChromaShift; j++)
458
1.97k
        {
459
1.97k
            memcpy(U + j * m_strideC, U, ((width + padx) >> m_hChromaShift) * sizeof(pixel));
460
1.97k
            memcpy(V + j * m_strideC, V, ((width + padx) >> m_hChromaShift) * sizeof(pixel));
461
1.97k
        }
462
698
    }
463
698
}
464
465
namespace X265_NS {
466
467
template<uint32_t OUTPUT_BITDEPTH_DIV8>
468
static void md5_block(MD5Context& md5, const pixel* plane, uint32_t n)
469
0
{
470
    /* create a 64 byte buffer for packing pixel's into */
471
0
    uint8_t buf[64 / OUTPUT_BITDEPTH_DIV8][OUTPUT_BITDEPTH_DIV8];
472
473
0
    for (uint32_t i = 0; i < n; i++)
474
0
    {
475
0
        pixel pel = plane[i];
476
        /* perform bitdepth and endian conversion */
477
0
        for (uint32_t d = 0; d < OUTPUT_BITDEPTH_DIV8; d++)
478
0
            buf[i][d] = (uint8_t)(pel >> (d * 8));
479
0
    }
480
481
0
    MD5Update(&md5, (uint8_t*)buf, n * OUTPUT_BITDEPTH_DIV8);
482
0
}
Unexecuted instantiation: picyuv.cpp:void x265::md5_block<1u>(x265::MD5Context&, unsigned char const*, unsigned int)
Unexecuted instantiation: picyuv.cpp:void x265::md5_block<2u>(x265::MD5Context&, unsigned char const*, unsigned int)
483
484
/* Update md5 with all samples in plane in raster order, each sample
485
 * is adjusted to OUTBIT_BITDEPTH_DIV8 */
486
template<uint32_t OUTPUT_BITDEPTH_DIV8>
487
static void md5_plane(MD5Context& md5, const pixel* plane, uint32_t width, uint32_t height, intptr_t stride)
488
0
{
489
    /* N is the number of samples to process per md5 update.
490
     * All N samples must fit in buf */
491
0
    uint32_t N = 32;
492
0
    uint32_t width_modN = width % N;
493
0
    uint32_t width_less_modN = width - width_modN;
494
495
0
    for (uint32_t y = 0; y < height; y++)
496
0
    {
497
        /* convert pel's into uint32_t chars in little endian byte order.
498
         * NB, for 8bit data, data is truncated to 8bits. */
499
0
        for (uint32_t x = 0; x < width_less_modN; x += N)
500
0
            md5_block<OUTPUT_BITDEPTH_DIV8>(md5, &plane[y * stride + x], N);
501
502
        /* mop up any of the remaining line */
503
0
        md5_block<OUTPUT_BITDEPTH_DIV8>(md5, &plane[y * stride + width_less_modN], width_modN);
504
0
    }
505
0
}
Unexecuted instantiation: picyuv.cpp:void x265::md5_plane<1u>(x265::MD5Context&, unsigned char const*, unsigned int, unsigned int, long)
Unexecuted instantiation: picyuv.cpp:void x265::md5_plane<2u>(x265::MD5Context&, unsigned char const*, unsigned int, unsigned int, long)
506
507
void updateCRC(const pixel* plane, uint32_t& crcVal, uint32_t height, uint32_t width, intptr_t stride)
508
0
{
509
0
    uint32_t crcMsb;
510
0
    uint32_t bitVal;
511
0
    uint32_t bitIdx;
512
513
0
    for (uint32_t y = 0; y < height; y++)
514
0
    {
515
0
        for (uint32_t x = 0; x < width; x++)
516
0
        {
517
            // take CRC of first pictureData byte
518
0
            for (bitIdx = 0; bitIdx < 8; bitIdx++)
519
0
            {
520
0
                crcMsb = (crcVal >> 15) & 1;
521
0
                bitVal = (plane[y * stride + x] >> (7 - bitIdx)) & 1;
522
0
                crcVal = (((crcVal << 1) + bitVal) & 0xffff) ^ (crcMsb * 0x1021);
523
0
            }
524
525
#if _MSC_VER
526
#pragma warning(disable: 4127) // conditional expression is constant
527
#endif
528
            // take CRC of second pictureData byte if bit depth is greater than 8-bits
529
0
            if (X265_DEPTH > 8)
530
0
            {
531
0
                for (bitIdx = 0; bitIdx < 8; bitIdx++)
532
0
                {
533
0
                    crcMsb = (crcVal >> 15) & 1;
534
0
                    bitVal = (plane[y * stride + x] >> (15 - bitIdx)) & 1;
535
0
                    crcVal = (((crcVal << 1) + bitVal) & 0xffff) ^ (crcMsb * 0x1021);
536
0
                }
537
0
            }
538
0
        }
539
0
    }
540
0
}
541
542
void crcFinish(uint32_t& crcVal, uint8_t digest[16])
543
0
{
544
0
    uint32_t crcMsb;
545
546
0
    for (int bitIdx = 0; bitIdx < 16; bitIdx++)
547
0
    {
548
0
        crcMsb = (crcVal >> 15) & 1;
549
0
        crcVal = ((crcVal << 1) & 0xffff) ^ (crcMsb * 0x1021);
550
0
    }
551
552
0
    digest[0] = (crcVal >> 8)  & 0xff;
553
0
    digest[1] =  crcVal        & 0xff;
554
0
}
555
556
void updateChecksum(const pixel* plane, uint32_t& checksumVal, uint32_t height, uint32_t width, intptr_t stride, int row, uint32_t cuHeight)
557
0
{
558
0
    uint8_t xor_mask;
559
560
0
    for (uint32_t y = row * cuHeight; y < ((row * cuHeight) + height); y++)
561
0
    {
562
0
        for (uint32_t x = 0; x < width; x++)
563
0
        {
564
0
            xor_mask = (uint8_t)((x & 0xff) ^ (y & 0xff) ^ (x >> 8) ^ (y >> 8));
565
0
            checksumVal = (checksumVal + ((plane[y * stride + x] & 0xff) ^ xor_mask)) & 0xffffffff;
566
567
0
            if (X265_DEPTH > 8)
568
0
                checksumVal = (checksumVal + ((plane[y * stride + x] >> 7 >> 1) ^ xor_mask)) & 0xffffffff;
569
0
        }
570
0
    }
571
0
}
572
573
void checksumFinish(uint32_t checksum, uint8_t digest[16])
574
0
{
575
0
    digest[0] = (checksum >> 24) & 0xff;
576
0
    digest[1] = (checksum >> 16) & 0xff;
577
0
    digest[2] = (checksum >> 8)  & 0xff;
578
0
    digest[3] =  checksum        & 0xff;
579
0
}
580
581
void updateMD5Plane(MD5Context& md5, const pixel* plane, uint32_t width, uint32_t height, intptr_t stride)
582
0
{
583
    /* choose an md5_plane packing function based on the system bitdepth */
584
0
    typedef void(*MD5PlaneFunc)(MD5Context&, const pixel*, uint32_t, uint32_t, intptr_t);
585
0
    MD5PlaneFunc md5_plane_func;
586
0
    md5_plane_func = X265_DEPTH <= 8 ? (MD5PlaneFunc)md5_plane<1> : (MD5PlaneFunc)md5_plane<2>;
587
588
0
    md5_plane_func(md5, plane, width, height, stride);
589
0
}
590
}