FFmpeg
Loading...
Searching...
No Matches
target_sws_fuzzer.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2024 Michael Niedermayer <michael-ffmpeg@niedermayer.cc>
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 "config.h"
22#include "libavutil/avassert.h"
23#include "libavutil/avstring.h"
24#include "libavutil/cpu.h"
25#include "libavutil/imgutils.h"
27#include "libavutil/mem.h"
28#include "libavutil/opt.h"
29
31
32#include "libswscale/swscale.h"
33
34
35int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
36
37static void error(const char *err)
38{
39 fprintf(stderr, "%s", err);
40 exit(1);
41}
42
43static int alloc_plane(uint8_t *data[AV_VIDEO_MAX_PLANES], int stride[AV_VIDEO_MAX_PLANES], int w, int h, int format, int *hshift, int *vshift)
44{
46 ptrdiff_t ptrdiff_stride[AV_VIDEO_MAX_PLANES];
48 if (ret < 0)
49 return -1;
50
51 av_assert0(AV_VIDEO_MAX_PLANES == 4); // Some of the libavutil API has 4 hardcoded so this has undefined behaviour if its not 4
52
54
55 for(int p=0; p<AV_VIDEO_MAX_PLANES; p++) {
56 stride[p] =
57 ptrdiff_stride[p] = FFALIGN(stride[p], 32);
58 }
59 ret = av_image_fill_plane_sizes(size, format, h, ptrdiff_stride);
60 if (ret < 0)
61 return ret;
62
63 for(int p=0; p<AV_VIDEO_MAX_PLANES; p++) {
64 if (size[p]) {
65 data[p] = av_mallocz(size[p] + 32);
66 if (!data[p])
67 return -1;
68 } else
69 data[p] = NULL;
70 }
71 return 0;
72}
73
74static void free_plane(uint8_t *data[AV_VIDEO_MAX_PLANES])
75{
76 for(int p=0; p<AV_VIDEO_MAX_PLANES; p++)
77 av_freep(&data[p]);
78}
79
80static void mapres(unsigned *r0, unsigned *r1) {
81 double d = (double)(*r0*10ll - 9ll*UINT32_MAX) / UINT32_MAX;
82 double a = exp(d) * 16384 / exp(1) ;
83 int ai = (int)round(a);
84 uint64_t maxb = 16384 / ai;
85 *r0 = ai;
86 *r1 = 1 + (*r1 * maxb) / UINT32_MAX;
87}
88
89int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
90 int srcW= 48, srcH = 48;
91 int dstW= 48, dstH = 48;
92 int srcHShift, srcVShift;
93 int dstHShift, dstVShift;
94 unsigned flags = 1;
95 int srcStride[AV_VIDEO_MAX_PLANES] = {0};
96 int dstStride[AV_VIDEO_MAX_PLANES] = {0};
97 int ret;
98 const uint8_t *end = data + size;
99 enum AVPixelFormat srcFormat = AV_PIX_FMT_YUV420P;
100 enum AVPixelFormat dstFormat = AV_PIX_FMT_YUV420P;
101 uint8_t *src[AV_VIDEO_MAX_PLANES] = { 0 };
102 uint8_t *dst[AV_VIDEO_MAX_PLANES] = { 0 };
103 struct SwsContext *sws = NULL;
104 const AVPixFmtDescriptor *desc_src, *desc_dst;
105
106 if (size > 128) {
107 GetByteContext gbc;
108 int64_t flags64;
109
110 size -= 128;
111 bytestream2_init(&gbc, data + size, 128);
112 srcW = bytestream2_get_le32(&gbc);
113 srcH = bytestream2_get_le32(&gbc);
114 dstW = bytestream2_get_le32(&gbc);
115 dstH = bytestream2_get_le32(&gbc);
116
117 mapres(&srcW, &srcH);
118 mapres(&dstW, &dstH);
119
120 flags = bytestream2_get_le32(&gbc);
121
122 unsigned mask = flags & (SWS_POINT |
123 SWS_AREA |
127 SWS_X |
128 SWS_GAUSS |
130 SWS_SINC |
131 SWS_SPLINE |
133 mask &= flags;
134 if (mask && (mask & (mask -1)))
135 return 0; // multiple scalers are set, not possible
136
137 srcFormat = bytestream2_get_le32(&gbc) % AV_PIX_FMT_NB;
138 dstFormat = bytestream2_get_le32(&gbc) % AV_PIX_FMT_NB;
139
140 flags64 = bytestream2_get_le64(&gbc);
141 if (flags64 & 0x10)
143
144 if (av_image_check_size(srcW, srcH, srcFormat, NULL) < 0)
145 srcW = srcH = 23;
146 if (av_image_check_size(dstW, dstH, dstFormat, NULL) < 0)
147 dstW = dstH = 23;
148 //TODO alphablend
149 }
150
151 desc_src = av_pix_fmt_desc_get(srcFormat);
152 desc_dst = av_pix_fmt_desc_get(dstFormat);
153
154 // fprintf(stderr, "%d x %d %s -> %d x %d %s\n", srcW, srcH, desc_src->name, dstW, dstH, desc_dst->name);
155
156 ret = alloc_plane(src, srcStride, srcW, srcH, srcFormat, &srcHShift, &srcVShift);
157 if (ret < 0)
158 goto end;
159
160 ret = alloc_plane(dst, dstStride, dstW, dstH, dstFormat, &dstHShift, &dstVShift);
161 if (ret < 0)
162 goto end;
163
164
165 for(int p=0; p<AV_VIDEO_MAX_PLANES; p++) {
166 int psize = srcStride[p] * AV_CEIL_RSHIFT(srcH, (p == 1 || p == 2) ? srcVShift : 0);
167 if (psize > size)
168 psize = size;
169 if (psize) {
170 memcpy(src[p], data, psize);
171 data += psize;
172 size -= psize;
173 }
174 }
175
176 sws = sws_alloc_context();
177 if (!sws)
178 error("Failed sws allocation");
179
180 av_opt_set_int(sws, "sws_flags", flags, 0);
181 av_opt_set_int(sws, "srcw", srcW, 0);
182 av_opt_set_int(sws, "srch", srcH, 0);
183 av_opt_set_int(sws, "dstw", dstW, 0);
184 av_opt_set_int(sws, "dsth", dstH, 0);
185 av_opt_set_int(sws, "src_format", srcFormat, 0);
186 av_opt_set_int(sws, "dst_format", dstFormat, 0);
187 av_opt_set(sws, "alphablend", "none", 0);
188
189 ret = sws_init_context(sws, NULL, NULL);
190 if (ret < 0)
191 goto end;
192
193 //TODO Slices
194 sws_scale(sws, (const uint8_t * const*)src, srcStride, 0, srcH, dst, dstStride);
195
196end:
197 sws_freeContext(sws);
198
201
202 return 0;
203}
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
static const char *const format[]
Definition af_aiir.c:444
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition bytestream.h:137
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define AV_CEIL_RSHIFT(a, b)
Definition common.h:60
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
int8_t exp
Definition eval.c:76
int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx)
Check if the given dimension of an image is valid, meaning that all bytes of the image can be address...
Definition imgutils.c:318
int av_image_fill_plane_sizes(size_t sizes[4], enum AVPixelFormat pix_fmt, int height, const ptrdiff_t linesizes[4])
Fill plane sizes for an image with pixel format pix_fmt and height height.
Definition imgutils.c:111
int av_image_fill_linesizes(int linesizes[4], enum AVPixelFormat pix_fmt, int width)
Fill plane linesizes for an image with pixel format pix_fmt and width width.
Definition imgutils.c:89
av_warn_unused_result int sws_init_context(SwsContext *sws_context, SwsFilter *srcFilter, SwsFilter *dstFilter)
Initialize the swscaler context sws_context.
Definition utils.c:1884
SwsContext * sws_alloc_context(void)
Allocate an empty SwsContext and set its fields to default values.
Definition utils.c:1032
int attribute_align_arg sws_scale(SwsContext *sws, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[])
swscale wrapper, so we don't need to export the SwsContext.
Definition swscale.c:1626
void sws_freeContext(SwsContext *swsContext)
Free the swscaler context swsContext.
Definition utils.c:2250
@ SWS_SPLINE
unwindowed natural cubic spline
Definition swscale.h:207
@ SWS_BICUBIC
2-tap cubic B-spline
Definition swscale.h:199
@ SWS_AREA
area averaging
Definition swscale.h:202
@ SWS_BICUBLIN
bicubic luma, bilinear chroma
Definition swscale.h:203
@ SWS_BILINEAR
bilinear filtering
Definition swscale.h:198
@ SWS_SINC
unwindowed sinc
Definition swscale.h:205
@ SWS_LANCZOS
3-tap sinc/sinc
Definition swscale.h:206
@ SWS_GAUSS
gaussian approximation
Definition swscale.h:204
@ SWS_FAST_BILINEAR
Scaler selection options.
Definition swscale.h:197
@ SWS_X
experimental
Definition swscale.h:200
@ SWS_POINT
nearest neighbor
Definition swscale.h:201
int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
Definition opt.c:934
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
Definition opt.c:887
int a
misc image utilities
void av_force_cpu_flags(int arg)
Disables cpu detection and forces the specified flags.
Definition cpu.c:81
static av_always_inline av_const double round(double x)
Definition libm.h:446
uint8_t w
Definition llvidencdsp.c:39
static const uint16_t mask[17]
Definition lzw.c:38
#define FFALIGN(x, a)
Definition macros.h:78
Memory handling functions.
const char data[16]
Definition mxf.c:149
AVOptions.
int av_pix_fmt_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift)
Utility function to access log2_chroma_w log2_chroma_h from the pixel format AVPixFmtDescriptor.
Definition pixdesc.c:3488
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3460
#define AV_VIDEO_MAX_PLANES
Maximum number of planes in any pixel format.
Definition pixfmt.h:40
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition pixfmt.h:73
@ AV_PIX_FMT_NB
number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of...
Definition pixfmt.h:508
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition pixdesc.h:69
Main external API structure.
Definition swscale.h:227
#define stride
external API header
#define av_mallocz(s)
#define av_freep(p)
static void mapres(unsigned *r0, unsigned *r1)
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
static int alloc_plane(uint8_t *data[AV_VIDEO_MAX_PLANES], int stride[AV_VIDEO_MAX_PLANES], int w, int h, int format, int *hshift, int *vshift)
static void error(const char *err)
static void free_plane(uint8_t *data[AV_VIDEO_MAX_PLANES])
#define src
Definition vp8dsp.c:248
int size