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