/* * 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 "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){ int j; pixel *srcp = (pixel *)src; pixel *dstp = (pixel *)dst; src_stride /= sizeof(pixel); src_linesize /= sizeof(pixel); dst_linesize /= sizeof(pixel); for (j = 0; j < FFMIN(h, 2); j++) { memcpy(dstp, srcp, w*sizeof(pixel)); dstp += dst_linesize; srcp += src_linesize; } for (; j < h - 2; j++) { int i; for (i = 0; i < FFMIN(w, 2); i++) dstp[i] = srcp[i*src_stride]; for (; 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; } for (; i < w; i++) dstp[i] = srcp[i*src_stride]; dstp += dst_linesize; srcp += src_linesize; } for (; j < h; j++) { memcpy(dstp, srcp, w*sizeof(pixel)); dstp += dst_linesize; srcp += src_linesize; }}
/*
* 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 "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)
{
int j;
pixel *srcp = (pixel *)src;
pixel *dstp = (pixel *)dst;
src_stride /= sizeof(pixel);
src_linesize /= sizeof(pixel);
dst_linesize /= sizeof(pixel);
for (j = 0; j < FFMIN(h, 2); j++) {
memcpy(dstp, srcp, w*sizeof(pixel));
dstp += dst_linesize;
srcp += src_linesize;
}
for (; j < h - 2; j++) {
int i;
for (i = 0; i < FFMIN(w, 2); i++)
dstp[i] = srcp[i*src_stride];
for (; 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;
}
for (; i < w; i++)
dstp[i] = srcp[i*src_stride];
dstp += dst_linesize;
srcp += src_linesize;
}
for (; j < h; j++) {
memcpy(dstp, srcp, w*sizeof(pixel));
dstp += dst_linesize;
srcp += src_linesize;
}
}