libyuv_scale_fuzzer.cc 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include <fuzzer/FuzzedDataProvider.h>
  5. #include <stddef.h>
  6. #include <stdint.h>
  7. #include <random>
  8. #include "third_party/libyuv/include/libyuv.h"
  9. void FillBufferWithRandomData(uint8_t* dst, size_t len, std::minstd_rand0 rng) {
  10. size_t i;
  11. for (i = 0; i + 3 < len; i += 4) {
  12. *reinterpret_cast<uint32_t*>(dst) = rng();
  13. dst += 4;
  14. }
  15. for (; i < len; ++i) {
  16. *dst++ = rng();
  17. }
  18. }
  19. static void Scale(bool is420,
  20. int src_width,
  21. int src_height,
  22. int dst_width,
  23. int dst_height,
  24. int filter_num,
  25. std::string seed_str) {
  26. int src_width_uv, src_height_uv;
  27. if (is420) {
  28. src_width_uv = (std::abs(src_width) + 1) >> 1;
  29. src_height_uv = (std::abs(src_height) + 1) >> 1;
  30. } else {
  31. src_width_uv = (std::abs(src_width));
  32. src_height_uv = (std::abs(src_height));
  33. }
  34. size_t src_y_plane_size = (std::abs(src_width)) * (std::abs(src_height));
  35. size_t src_uv_plane_size = (src_width_uv) * (src_height_uv);
  36. int src_stride_y = std::abs(src_width);
  37. int src_stride_uv = src_width_uv;
  38. uint8_t* src_y = reinterpret_cast<uint8_t*>(malloc(src_y_plane_size));
  39. uint8_t* src_u = reinterpret_cast<uint8_t*>(malloc(src_uv_plane_size));
  40. uint8_t* src_v = reinterpret_cast<uint8_t*>(malloc(src_uv_plane_size));
  41. uint16_t* p_src_y_16 =
  42. reinterpret_cast<uint16_t*>(malloc(src_y_plane_size * 2));
  43. uint16_t* p_src_u_16 =
  44. reinterpret_cast<uint16_t*>(malloc(src_uv_plane_size * 2));
  45. uint16_t* p_src_v_16 =
  46. reinterpret_cast<uint16_t*>(malloc(src_uv_plane_size * 2));
  47. std::seed_seq seed(seed_str.begin(), seed_str.end());
  48. std::minstd_rand0 rng(seed);
  49. FillBufferWithRandomData(src_y, src_y_plane_size, rng);
  50. FillBufferWithRandomData(src_u, src_uv_plane_size, rng);
  51. FillBufferWithRandomData(src_v, src_uv_plane_size, rng);
  52. for (size_t i = 0; i < src_y_plane_size; ++i) {
  53. p_src_y_16[i] = src_y[i];
  54. }
  55. for (size_t i = 0; i < src_uv_plane_size; ++i) {
  56. p_src_u_16[i] = src_u[i];
  57. p_src_v_16[i] = src_v[i];
  58. }
  59. int dst_width_uv, dst_height_uv;
  60. if (is420) {
  61. dst_width_uv = (dst_width + 1) >> 1;
  62. dst_height_uv = (dst_height + 1) >> 1;
  63. } else {
  64. dst_width_uv = dst_width;
  65. dst_height_uv = dst_height;
  66. }
  67. size_t dst_y_plane_size = (dst_width) * (dst_height);
  68. size_t dst_uv_plane_size = (dst_width_uv) * (dst_height_uv);
  69. int dst_stride_y = dst_width;
  70. int dst_stride_uv = dst_width_uv;
  71. uint8_t* dst_y_c = reinterpret_cast<uint8_t*>(malloc(dst_y_plane_size));
  72. uint8_t* dst_u_c = reinterpret_cast<uint8_t*>(malloc(dst_uv_plane_size));
  73. uint8_t* dst_v_c = reinterpret_cast<uint8_t*>(malloc(dst_uv_plane_size));
  74. uint16_t* p_dst_y_16 =
  75. reinterpret_cast<uint16_t*>(malloc(dst_y_plane_size * 2));
  76. uint16_t* p_dst_u_16 =
  77. reinterpret_cast<uint16_t*>(malloc(dst_uv_plane_size * 2));
  78. uint16_t* p_dst_v_16 =
  79. reinterpret_cast<uint16_t*>(malloc(dst_uv_plane_size * 2));
  80. if (is420) {
  81. I420Scale(src_y, src_stride_y, src_u, src_stride_uv, src_v, src_stride_uv,
  82. src_width, src_height, dst_y_c, dst_stride_y, dst_u_c,
  83. dst_stride_uv, dst_v_c, dst_stride_uv, dst_width, dst_height,
  84. static_cast<libyuv::FilterMode>(filter_num));
  85. I420Scale_16(p_src_y_16, src_stride_y, p_src_u_16, src_stride_uv,
  86. p_src_v_16, src_stride_uv, src_width, src_height, p_dst_y_16,
  87. dst_stride_y, p_dst_u_16, dst_stride_uv, p_dst_v_16,
  88. dst_stride_uv, dst_width, dst_height,
  89. static_cast<libyuv::FilterMode>(filter_num));
  90. } else {
  91. I444Scale(src_y, src_stride_y, src_u, src_stride_uv, src_v, src_stride_uv,
  92. src_width, src_height, dst_y_c, dst_stride_y, dst_u_c,
  93. dst_stride_uv, dst_v_c, dst_stride_uv, dst_width, dst_height,
  94. static_cast<libyuv::FilterMode>(filter_num));
  95. I444Scale_16(p_src_y_16, src_stride_y, p_src_u_16, src_stride_uv,
  96. p_src_v_16, src_stride_uv, src_width, src_height, p_dst_y_16,
  97. dst_stride_y, p_dst_u_16, dst_stride_uv, p_dst_v_16,
  98. dst_stride_uv, dst_width, dst_height,
  99. static_cast<libyuv::FilterMode>(filter_num));
  100. }
  101. free(src_y);
  102. free(src_u);
  103. free(src_v);
  104. free(p_src_y_16);
  105. free(p_src_u_16);
  106. free(p_src_v_16);
  107. free(dst_y_c);
  108. free(dst_u_c);
  109. free(dst_v_c);
  110. free(p_dst_y_16);
  111. free(p_dst_u_16);
  112. free(p_dst_v_16);
  113. }
  114. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  115. FuzzedDataProvider provider(data, size);
  116. // Limit width and height for performance.
  117. int src_width = provider.ConsumeIntegralInRange<int>(1, 256);
  118. int src_height = provider.ConsumeIntegralInRange<int>(1, 256);
  119. int filter_num =
  120. provider.ConsumeIntegralInRange<int>(0, libyuv::FilterMode::kFilterBox);
  121. int dst_width = provider.ConsumeIntegralInRange<int>(1, 256);
  122. int dst_height = provider.ConsumeIntegralInRange<int>(1, 256);
  123. std::string seed = provider.ConsumeRemainingBytesAsString();
  124. Scale(true, src_width, src_height, dst_width, dst_height, filter_num, seed);
  125. Scale(false, src_width, src_height, dst_width, dst_height, filter_num, seed);
  126. return 0;
  127. }