summaryrefslogtreecommitdiff
path: root/libavfilter/edge_template.c
diff options
context:
space:
mode:
authorThilo Borgmann <thilo.borgmann@mail.de>2022-07-18 16:09:46 +0200
committerThilo Borgmann <thilo.borgmann@mail.de>2022-07-30 13:17:28 +0200
commitcf1f57443158bcbe84a213e8dc631a302993f9a2 (patch)
tree15ffa8ca7f156df27c594ec63e82139b7c4814f0 /libavfilter/edge_template.c
parent1001bdc5047ec7ed0754a2084b77637028bb82cc (diff)
lavfi/edge_common: Templatify ff_gaussian_blur and ff_sobel
Diffstat (limited to 'libavfilter/edge_template.c')
-rw-r--r--libavfilter/edge_template.c118
1 files changed, 118 insertions, 0 deletions
diff --git a/libavfilter/edge_template.c b/libavfilter/edge_template.c
new file mode 100644
index 0000000000..af33c178af
--- /dev/null
+++ b/libavfilter/edge_template.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2022 Thilo Borgmann <thilo.borgmann _at_ mail.de>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ */
+
+#include "libavutil/avassert.h"
+#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
+
+#undef pixel
+#if DEPTH == 8
+#define pixel uint8_t
+#else
+#define pixel uint16_t
+#endif
+
+#undef fn
+#undef fn2
+#undef fn3
+#define fn3(a,b) ff_##a##_##b
+#define fn2(a,b) fn3(a,b)
+#define fn(a) fn2(a, DEPTH)
+
+void fn(sobel)(int w, int h,
+ uint16_t *dst, int dst_linesize,
+ int8_t *dir, int dir_linesize,
+ const uint8_t *src, int src_linesize, int src_stride)
+{
+ pixel *srcp = (pixel *)src;
+
+ src_stride /= sizeof(pixel);
+ src_linesize /= sizeof(pixel);
+ dst_linesize /= sizeof(pixel);
+
+ for (int j = 1; j < h - 1; j++) {
+ dst += dst_linesize;
+ dir += dir_linesize;
+ srcp += src_linesize;
+ for (int i = 1; i < w - 1; i++) {
+ const int gx =
+ -1*srcp[-src_linesize + (i-1)*src_stride] + 1*srcp[-src_linesize + (i+1)*src_stride]
+ -2*srcp[ (i-1)*src_stride] + 2*srcp[ (i+1)*src_stride]
+ -1*srcp[ src_linesize + (i-1)*src_stride] + 1*srcp[ src_linesize + (i+1)*src_stride];
+ const int gy =
+ -1*srcp[-src_linesize + (i-1)*src_stride] + 1*srcp[ src_linesize + (i-1)*src_stride]
+ -2*srcp[-src_linesize + (i )*src_stride] + 2*srcp[ src_linesize + (i )*src_stride]
+ -1*srcp[-src_linesize + (i+1)*src_stride] + 1*srcp[ src_linesize + (i+1)*src_stride];
+
+ dst[i] = FFABS(gx) + FFABS(gy);
+ dir[i] = get_rounded_direction(gx, gy);
+ }
+ }
+}
+
+void fn(gaussian_blur)(int w, int h,
+ uint8_t *dst, int dst_linesize,
+ const uint8_t *src, int src_linesize, int src_stride)
+{
+ pixel *srcp = (pixel *)src;
+ pixel *dstp = (pixel *)dst;
+
+ src_stride /= sizeof(pixel);
+ src_linesize /= sizeof(pixel);
+ dst_linesize /= sizeof(pixel);
+
+ memcpy(dstp, srcp, w*sizeof(pixel)); dstp += dst_linesize; srcp += src_linesize;
+ memcpy(dstp, srcp, w*sizeof(pixel)); dstp += dst_linesize; srcp += src_linesize;
+ for (int j = 2; j < h - 2; j++) {
+ dstp[0] = srcp[(0)*src_stride];
+ dstp[1] = srcp[(1)*src_stride];
+ for (int i = 2; i < w - 2; i++) {
+ /* Gaussian mask of size 5x5 with sigma = 1.4 */
+ dstp[i] = ((srcp[-2*src_linesize + (i-2)*src_stride] + srcp[2*src_linesize + (i-2)*src_stride]) * 2
+ + (srcp[-2*src_linesize + (i-1)*src_stride] + srcp[2*src_linesize + (i-1)*src_stride]) * 4
+ + (srcp[-2*src_linesize + (i )*src_stride] + srcp[2*src_linesize + (i )*src_stride]) * 5
+ + (srcp[-2*src_linesize + (i+1)*src_stride] + srcp[2*src_linesize + (i+1)*src_stride]) * 4
+ + (srcp[-2*src_linesize + (i+2)*src_stride] + srcp[2*src_linesize + (i+2)*src_stride]) * 2
+
+ + (srcp[ -src_linesize + (i-2)*src_stride] + srcp[ src_linesize + (i-2)*src_stride]) * 4
+ + (srcp[ -src_linesize + (i-1)*src_stride] + srcp[ src_linesize + (i-1)*src_stride]) * 9
+ + (srcp[ -src_linesize + (i )*src_stride] + srcp[ src_linesize + (i )*src_stride]) * 12
+ + (srcp[ -src_linesize + (i+1)*src_stride] + srcp[ src_linesize + (i+1)*src_stride]) * 9
+ + (srcp[ -src_linesize + (i+2)*src_stride] + srcp[ src_linesize + (i+2)*src_stride]) * 4
+
+ + srcp[(i-2)*src_stride] * 5
+ + srcp[(i-1)*src_stride] * 12
+ + srcp[(i )*src_stride] * 15
+ + srcp[(i+1)*src_stride] * 12
+ + srcp[(i+2)*src_stride] * 5) / 159;
+ }
+ dstp[w - 2] = srcp[(w - 2)*src_stride];
+ dstp[w - 1] = srcp[(w - 1)*src_stride];
+
+ dstp += dst_linesize;
+ srcp += src_linesize;
+ }
+ memcpy(dstp, srcp, w*sizeof(pixel)); dstp += dst_linesize; srcp += src_linesize;
+ memcpy(dstp, srcp, w*sizeof(pixel));
+}