| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * Copyright (c) 2026 Zhao Zhili <quinkblack@foxmail.com> | ||
| 3 | * | ||
| 4 | * This file is part of FFmpeg. | ||
| 5 | * | ||
| 6 | * FFmpeg is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU Lesser General Public | ||
| 8 | * License as published by the Free Software Foundation; either | ||
| 9 | * version 2.1 of the License, or (at your option) any later version. | ||
| 10 | * | ||
| 11 | * FFmpeg is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 14 | * Lesser General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU Lesser General Public | ||
| 17 | * License along with FFmpeg; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <string.h> | ||
| 22 | |||
| 23 | #include "libavutil/mem_internal.h" | ||
| 24 | #include "libavcodec/pngdsp.h" | ||
| 25 | |||
| 26 | #include "checkasm.h" | ||
| 27 | |||
| 28 | #define BUF_SIZE 4096 | ||
| 29 | |||
| 30 | #define randomize_buf(buf, size) \ | ||
| 31 | do { \ | ||
| 32 | for (int i = 0; i < size; i++) \ | ||
| 33 | buf[i] = (uint8_t)rnd(); \ | ||
| 34 | } while (0) | ||
| 35 | |||
| 36 | 14 | static void check_add_bytes_l2(const PNGDSPContext *c) | |
| 37 | { | ||
| 38 | 14 | LOCAL_ALIGNED_16(uint8_t, dst0, [BUF_SIZE]); | |
| 39 | 14 | LOCAL_ALIGNED_16(uint8_t, dst1, [BUF_SIZE]); | |
| 40 | 14 | LOCAL_ALIGNED_16(uint8_t, src, [2], [BUF_SIZE]); | |
| 41 | |||
| 42 | 14 | declare_func(void, uint8_t * dst, const uint8_t *src1, | |
| 43 | const uint8_t *src2, int w); | ||
| 44 | |||
| 45 |
2/2✓ Branch 1 taken 57344 times.
✓ Branch 2 taken 14 times.
|
57358 | randomize_buf(dst0, BUF_SIZE); |
| 46 | 14 | memcpy(dst1, dst0, BUF_SIZE); | |
| 47 |
2/2✓ Branch 1 taken 57344 times.
✓ Branch 2 taken 14 times.
|
57358 | randomize_buf(src[0], BUF_SIZE); |
| 48 |
2/2✓ Branch 1 taken 57344 times.
✓ Branch 2 taken 14 times.
|
57358 | randomize_buf(src[1], BUF_SIZE); |
| 49 | |||
| 50 | 14 | const int size[] = {15, 2043, 4096}; | |
| 51 |
2/2✓ Branch 0 taken 42 times.
✓ Branch 1 taken 14 times.
|
56 | for (int i = 0; i < FF_ARRAY_ELEMS(size); i++) { |
| 52 |
2/2✓ Branch 1 taken 6 times.
✓ Branch 2 taken 36 times.
|
42 | if (check_func(c->add_bytes_l2, "add_bytes_l2_%d", size[i])) { |
| 53 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
|
6 | call_ref(dst0, src[0], src[1], size[i]); |
| 54 | 6 | call_new(dst1, src[0], src[1], size[i]); | |
| 55 | 6 | checkasm_check(uint8_t, dst0, BUF_SIZE, dst1, BUF_SIZE, BUF_SIZE, 1, "dst"); | |
| 56 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
|
6 | if (size[i] == BUF_SIZE) |
| 57 |
1/18✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
|
2 | bench_new(dst1, src[0], src[1], BUF_SIZE); |
| 58 | } | ||
| 59 | } | ||
| 60 | 14 | } | |
| 61 | |||
| 62 | 14 | static void check_add_paeth_prediction(const PNGDSPContext *c) | |
| 63 | { | ||
| 64 | 14 | LOCAL_ALIGNED_16(uint8_t, dst0_buf, [BUF_SIZE]); | |
| 65 | 14 | LOCAL_ALIGNED_16(uint8_t, dst1_buf, [BUF_SIZE]); | |
| 66 | 14 | LOCAL_ALIGNED_16(uint8_t, src, [BUF_SIZE]); | |
| 67 | 14 | LOCAL_ALIGNED_16(uint8_t, top_buf, [BUF_SIZE]); | |
| 68 | |||
| 69 |
2/2✓ Branch 1 taken 57344 times.
✓ Branch 2 taken 14 times.
|
57358 | randomize_buf(dst0_buf, BUF_SIZE); |
| 70 |
2/2✓ Branch 1 taken 57344 times.
✓ Branch 2 taken 14 times.
|
57358 | randomize_buf(src, BUF_SIZE); |
| 71 |
2/2✓ Branch 1 taken 57344 times.
✓ Branch 2 taken 14 times.
|
57358 | randomize_buf(top_buf, BUF_SIZE); |
| 72 | |||
| 73 | 14 | declare_func(void, uint8_t * dst, const uint8_t *src, | |
| 74 | const uint8_t *top, int w, int bpp); | ||
| 75 | |||
| 76 | 14 | const int bpps[] = {3, 4, 6, 8}; | |
| 77 |
2/2✓ Branch 0 taken 56 times.
✓ Branch 1 taken 14 times.
|
70 | for (int i = 0; i < FF_ARRAY_ELEMS(bpps); i++) { |
| 78 | 56 | int bpp = bpps[i]; | |
| 79 |
2/2✓ Branch 1 taken 8 times.
✓ Branch 2 taken 48 times.
|
56 | if (check_func(c->add_paeth_prediction, "add_paeth_prediction_%d", bpp)) { |
| 80 | // add_paeth_prediction reads start from (dst - bpp) and (top - bpp). | ||
| 81 | 8 | uint8_t *dst0 = &dst0_buf[bpp]; | |
| 82 | 8 | uint8_t *dst1 = &dst1_buf[bpp]; | |
| 83 | 8 | uint8_t *top = &top_buf[bpp]; | |
| 84 | 8 | int w = (BUF_SIZE - bpp) / bpp * bpp; | |
| 85 | |||
| 86 | // dst buffer is both read and written, so dst0 and dst1 must remain the same before test | ||
| 87 | 8 | memcpy(dst1_buf, dst0_buf, BUF_SIZE); | |
| 88 | |||
| 89 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
|
8 | call_ref(dst0, src, top, w, bpp); |
| 90 | 8 | call_new(dst1, src, top, w, bpp); | |
| 91 | |||
| 92 | /* This match the use case in ff_png_filter_row, that x86 asm version of | ||
| 93 | * add_paeth_prediction doesn't write last two bytes for bpp = 3 and 6. | ||
| 94 | * The C function takes care to rewrite the last 3 bytes. | ||
| 95 | */ | ||
| 96 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
|
8 | if (bpp & 3) { |
| 97 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
|
16 | for (int j = w - 3; j < w; j++) |
| 98 | 12 | dst1[j] = dst0[j]; | |
| 99 | } | ||
| 100 | // check dst_buf to ensure there is no overwrite | ||
| 101 | 8 | checkasm_check(uint8_t, dst0_buf, 0, dst1_buf, 0, BUF_SIZE, 1, "dst"); | |
| 102 |
1/18✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
|
8 | bench_new(dst1, src, top, w, bpp); |
| 103 | } | ||
| 104 | } | ||
| 105 | 14 | } | |
| 106 | |||
| 107 | 14 | void checkasm_check_png(void) | |
| 108 | { | ||
| 109 | PNGDSPContext c; | ||
| 110 | |||
| 111 | 14 | ff_pngdsp_init(&c); | |
| 112 | |||
| 113 | 14 | check_add_bytes_l2(&c); | |
| 114 | 14 | report("add_bytes_l2"); | |
| 115 | 14 | check_add_paeth_prediction(&c); | |
| 116 | 14 | report("add_paeth_prediction"); | |
| 117 | 14 | } | |
| 118 |