1 /*
2 * Copyright (c) 2019 Paul B Mahol
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 * Redistribution and use in source and binary forms, with or without modification,
20 * are permitted provided that the following conditions are met:
21 */
22
27
28 #undef pixel
29 #if DEPTH == 8
30 #define pixel uint8_t
31 #else
32 #define pixel uint16_t
33 #endif
34
35 #undef htype
36 #define htype uint16_t
37
38 #undef fn
39 #undef fn2
40 #undef fn3
41 #define SHIFT ((DEPTH + 1) / 2)
42 #define BINS (1 << SHIFT)
43 #define MASK (BINS - 1)
44 #define fn3(a,b) a##_##b
45 #define fn2(a,b) fn3(a,b)
46 #define fn(a) fn2(a, DEPTH)
47
48 #define PICK_COARSE_BIN(x, y) (BINS * (x) + ((y) >> SHIFT))
49 #define PICK_FINE_BIN(x, y, z) (BINS * ((x) * ((y) >> SHIFT) + (z)) + ((y) & MASK))
50
52 uint8_t *ddst,
int dst_linesize,
int width,
int height,
53 int slice_h_start, int slice_h_end, int jobnr)
54 {
56 htype *ccoarse =
s->coarse[jobnr];
57 htype *cfine =
s->fine[jobnr];
58 const int radius =
s->radius;
59 const int radiusV =
s->radiusV;
65
66 src_linesize /=
sizeof(
pixel);
67 dst_linesize /=
sizeof(
pixel);
68
69 memset(cfine, 0,
s->fine_size *
sizeof(*cfine));
70 memset(ccoarse, 0,
s->coarse_size *
sizeof(*ccoarse));
71
72 srcp =
src +
FFMAX(0, slice_h_start - radiusV) * src_linesize;
73 if (jobnr == 0) {
77 }
78 }
79
80 srcp =
src +
FFMAX(0, slice_h_start - radiusV - (jobnr != 0)) * src_linesize;
81 for (
int i = 0;
i < radiusV + (jobnr != 0) * (1 + radiusV);
i++) {
82 for (
int j = 0; j <
width; j++) {
85 }
86 srcp += src_linesize;
87 }
88
90
91 for (
int i = slice_h_start;
i < slice_h_end;
i++) {
95
96 p = srcp + src_linesize *
FFMAX(0,
i - radiusV - 1);
97 for (
int j = 0; j <
width; j++) {
100 }
101
102 p = srcp + src_linesize *
FFMIN(
height - 1,
i + radiusV);
103 for (
int j = 0; j <
width; j++) {
106 }
107
108 s->hmuladd(coarse, &ccoarse[0], radius,
BINS);
109 for (int j = 0; j < radius; j++)
110 s->hadd(coarse, &ccoarse[
BINS * j],
BINS);
111 for (
int k = 0; k <
BINS; k++)
112 s->hmuladd(&fine[k][0], &cfine[
BINS *
width * k], 2 * radius + 1,
BINS);
113
114 for (
int j = 0; j <
width; j++) {
117
119
120 for (k = 0; k <
BINS; k++) {
121 sum += coarse[k];
122 if (sum > t) {
123 sum -= coarse[k];
124 break;
125 }
126 }
128
129 if (luc[k] <= j - radius) {
130 memset(&fine[k], 0,
BINS *
sizeof(
htype));
131 for (luc[k] = j - radius; luc[k] <
FFMIN(j + radius + 1,
width); luc[k]++)
133 if (luc[k] < j + radius + 1) {
135 luc[k] = j + radius + 1;
136 }
137 } else {
138 for (; luc[k] < j + radius + 1; luc[k]++) {
141 }
142 }
143
145
149 if (sum > t) {
150 dst[j] =
BINS * k +
b;
151 break;
152 }
153 }
155 }
156
157 dst += dst_linesize;
158 }
159 }