xref: /aosp_15_r20/external/cronet/testing/libfuzzer/fuzzers/libyuv_scale_fuzzer.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2019 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <stddef.h>
6 #include <stdint.h>
7 #include <random>
8 #include <string>
9 
10 #include "testing/libfuzzer/fuzzers/libyuv_scale_fuzzer.h"
11 #include "third_party/libyuv/include/libyuv.h"
12 
FillBufferWithRandomData(uint8_t * dst,size_t len,std::minstd_rand0 rng)13 static void FillBufferWithRandomData(uint8_t* dst,
14                                      size_t len,
15                                      std::minstd_rand0 rng) {
16   size_t i;
17   for (i = 0; i + 3 < len; i += 4) {
18     *reinterpret_cast<uint32_t*>(dst) = rng();
19     dst += 4;
20   }
21   for (; i < len; ++i) {
22     *dst++ = rng();
23   }
24 }
25 
Scale(bool is420,int src_width,int src_height,int dst_width,int dst_height,int filter_num,std::string seed_str)26 void Scale(bool is420,
27            int src_width,
28            int src_height,
29            int dst_width,
30            int dst_height,
31            int filter_num,
32            std::string seed_str) {
33   int src_width_uv, src_height_uv;
34   if (is420) {
35     src_width_uv = (std::abs(src_width) + 1) >> 1;
36     src_height_uv = (std::abs(src_height) + 1) >> 1;
37   } else {
38     src_width_uv = (std::abs(src_width));
39     src_height_uv = (std::abs(src_height));
40   }
41 
42   size_t src_y_plane_size = (std::abs(src_width)) * (std::abs(src_height));
43   size_t src_uv_plane_size = (src_width_uv) * (src_height_uv);
44 
45   int src_stride_y = std::abs(src_width);
46   int src_stride_uv = src_width_uv;
47 
48   uint8_t* src_y = reinterpret_cast<uint8_t*>(malloc(src_y_plane_size));
49   uint8_t* src_u = reinterpret_cast<uint8_t*>(malloc(src_uv_plane_size));
50   uint8_t* src_v = reinterpret_cast<uint8_t*>(malloc(src_uv_plane_size));
51 
52   uint16_t* p_src_y_16 =
53       reinterpret_cast<uint16_t*>(malloc(src_y_plane_size * 2));
54   uint16_t* p_src_u_16 =
55       reinterpret_cast<uint16_t*>(malloc(src_uv_plane_size * 2));
56   uint16_t* p_src_v_16 =
57       reinterpret_cast<uint16_t*>(malloc(src_uv_plane_size * 2));
58 
59   std::seed_seq seed(seed_str.begin(), seed_str.end());
60   std::minstd_rand0 rng(seed);
61 
62   // TODO - consider taking directly as parameters when this code
63   // is being run using FuzzTest, though it would probably require
64   // complex domains to ensure they're the right size.
65   FillBufferWithRandomData(src_y, src_y_plane_size, rng);
66   FillBufferWithRandomData(src_u, src_uv_plane_size, rng);
67   FillBufferWithRandomData(src_v, src_uv_plane_size, rng);
68 
69   for (size_t i = 0; i < src_y_plane_size; ++i) {
70     p_src_y_16[i] = src_y[i];
71   }
72   for (size_t i = 0; i < src_uv_plane_size; ++i) {
73     p_src_u_16[i] = src_u[i];
74     p_src_v_16[i] = src_v[i];
75   }
76 
77   int dst_width_uv, dst_height_uv;
78   if (is420) {
79     dst_width_uv = (dst_width + 1) >> 1;
80     dst_height_uv = (dst_height + 1) >> 1;
81   } else {
82     dst_width_uv = dst_width;
83     dst_height_uv = dst_height;
84   }
85 
86   size_t dst_y_plane_size = (dst_width) * (dst_height);
87   size_t dst_uv_plane_size = (dst_width_uv) * (dst_height_uv);
88 
89   int dst_stride_y = dst_width;
90   int dst_stride_uv = dst_width_uv;
91 
92   uint8_t* dst_y_c = reinterpret_cast<uint8_t*>(malloc(dst_y_plane_size));
93   uint8_t* dst_u_c = reinterpret_cast<uint8_t*>(malloc(dst_uv_plane_size));
94   uint8_t* dst_v_c = reinterpret_cast<uint8_t*>(malloc(dst_uv_plane_size));
95 
96   uint16_t* p_dst_y_16 =
97       reinterpret_cast<uint16_t*>(malloc(dst_y_plane_size * 2));
98   uint16_t* p_dst_u_16 =
99       reinterpret_cast<uint16_t*>(malloc(dst_uv_plane_size * 2));
100   uint16_t* p_dst_v_16 =
101       reinterpret_cast<uint16_t*>(malloc(dst_uv_plane_size * 2));
102 
103   if (is420) {
104     I420Scale(src_y, src_stride_y, src_u, src_stride_uv, src_v, src_stride_uv,
105               src_width, src_height, dst_y_c, dst_stride_y, dst_u_c,
106               dst_stride_uv, dst_v_c, dst_stride_uv, dst_width, dst_height,
107               static_cast<libyuv::FilterMode>(filter_num));
108 
109     I420Scale_16(p_src_y_16, src_stride_y, p_src_u_16, src_stride_uv,
110                  p_src_v_16, src_stride_uv, src_width, src_height, p_dst_y_16,
111                  dst_stride_y, p_dst_u_16, dst_stride_uv, p_dst_v_16,
112                  dst_stride_uv, dst_width, dst_height,
113                  static_cast<libyuv::FilterMode>(filter_num));
114   } else {
115     I444Scale(src_y, src_stride_y, src_u, src_stride_uv, src_v, src_stride_uv,
116               src_width, src_height, dst_y_c, dst_stride_y, dst_u_c,
117               dst_stride_uv, dst_v_c, dst_stride_uv, dst_width, dst_height,
118               static_cast<libyuv::FilterMode>(filter_num));
119 
120     I444Scale_16(p_src_y_16, src_stride_y, p_src_u_16, src_stride_uv,
121                  p_src_v_16, src_stride_uv, src_width, src_height, p_dst_y_16,
122                  dst_stride_y, p_dst_u_16, dst_stride_uv, p_dst_v_16,
123                  dst_stride_uv, dst_width, dst_height,
124                  static_cast<libyuv::FilterMode>(filter_num));
125   }
126 
127   free(src_y);
128   free(src_u);
129   free(src_v);
130 
131   free(p_src_y_16);
132   free(p_src_u_16);
133   free(p_src_v_16);
134 
135   free(dst_y_c);
136   free(dst_u_c);
137   free(dst_v_c);
138 
139   free(p_dst_y_16);
140   free(p_dst_u_16);
141   free(p_dst_v_16);
142 }
143