1 /*
2 * Copyright (c) 2012-2013 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 */
20
29
36 };
37
39 const AVClass *
class;
///< AVClass context for log and options purpose
54
55 #define OFFSET(x) offsetof(HistogramContext, x)
56 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
57
70 {
"waveform_mirror",
"set waveform mirroring",
OFFSET(waveform_mirror),
AV_OPT_TYPE_INT, {.i64=0}, 0, 1,
FLAGS,
"waveform_mirror"},
77 { NULL }
78 };
79
81
85 };
86
90 };
91
102 };
103
105 {
108
112 break;
115 break;
119 break;
120 default:
122 }
123
125
126 return 0;
127 }
128
133
135 {
137
140
146 break;
147 default:
150 }
151
152 return 0;
153 }
154
156 {
159
164 break;
168 else
170 break;
173 outlink->
h = outlink->
w = 256;
174 break;
175 default:
177 }
178
180
181 return 0;
182 }
183
185 int component,
int intensity,
int offset,
int col_mode)
186 {
189 const int is_chroma = (component == 1 || component == 2);
192 const int src_linesize = inpicref->
linesize[plane];
193 const int dst_linesize = outpicref->
linesize[plane];
194 const int dst_signed_linesize = dst_linesize * (mirror == 1 ? -1 : 1);
196 uint8_t *dst_data = outpicref->
data[plane] + (col_mode ? (offset >> shift_h) * dst_linesize : offset >> shift_w);
197 uint8_t *
const dst_bottom_line = dst_data + dst_linesize * ((256 >> shift_h) - 1);
198 uint8_t *
const dst_line = (mirror ? dst_bottom_line : dst_data);
199 const uint8_t max = 255 - intensity;
204
205 if (!col_mode && mirror)
206 dst_data += 256 >> shift_w;
207 for (y = 0; y < src_h; y++) {
208 const uint8_t *src_data_end = src_data + src_w;
209 dst = dst_line;
210 for (p = src_data; p < src_data_end; p++) {
212 if (col_mode) {
213 target = dst++ + dst_signed_linesize * (*p >> shift_h);
214 } else {
215 if (mirror)
216 target = dst_data - (*p >> shift_w);
217 else
218 target = dst_data + (*p >> shift_w);
219 }
220 if (*target <= max)
221 *target += intensity;
222 else
223 *target = 255;
224 }
225 src_data += src_linesize;
226 dst_data += dst_linesize;
227 }
228 }
229
230
232 {
239 int i, j, k, l;
240
242 if (!out) {
245 }
246
248
249 for (k = 0; k < h->
ncomp; k++) {
250 const int is_chroma = (k == 1 || k == 2);
253 for (i = 0; i < dst_h ; i++)
257 }
258
261 for (k = 0; k < h->
ncomp; k++) {
264 double max_hval_log;
265 unsigned max_hval = 0;
266
269 for (j = 0; j < in->
width; j++)
271 }
272
273 for (i = 0; i < 256; i++)
275 max_hval_log =
log2(max_hval + 1);
276
277 for (i = 0; i < outlink->
w; i++) {
278 int col_height;
279
282 else
284
287 for (l = 0; l < h->
ncomp; l++)
289 } else {
291 }
292 }
295 }
296
297 memset(h->
histogram, 0, 256 *
sizeof(
unsigned));
298 }
299 break;
301 for (k = 0; k < h->
ncomp; k++) {
304 }
305 break;
307 for (i = 0; i < inlink->
h; i++) {
308 const int iw1 = i * in->
linesize[1];
309 const int iw2 = i * in->
linesize[2];
310 for (j = 0; j < inlink->
w; j++) {
311 const int pos = in->
data[1][iw1 + j] * out->
linesize[0] + in->
data[2][iw2 + j];
312 if (out->
data[0][pos] < 255)
314 }
315 }
316 for (i = 0; i < 256; i++) {
318 for (j = 0; j < 256; j++) {
319 if (!dst[j]) {
322 }
323 }
324 }
325 break;
327 for (i = 0; i < inlink->
h; i++) {
328 const int iw1 = i * in->
linesize[1];
329 const int iw2 = i * in->
linesize[2];
330 for (j = 0; j < inlink->
w; j++) {
331 const int u = in->
data[1][iw1 + j];
332 const int v = in->
data[2][iw2 + j];
333 const int pos = u * out->
linesize[0] +
v;
334 if (!out->
data[0][pos])
336 out->
data[1][pos] =
u;
337 out->
data[2][pos] =
v;
338 }
339 }
340 break;
341 default:
343 }
344
347 }
348
350 {
355 },
356 { NULL }
357 };
358
360 {
364 },
365 { NULL }
366 };
367
373 .inputs = inputs,
374 .outputs = outputs,
375 .priv_class = &histogram_class,
376 };