qcms_color_space_fuzzer.cc 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. // Copyright 2017 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 <cstddef>
  5. #include <cstdint>
  6. #include <iterator>
  7. #include <random>
  8. #include "testing/libfuzzer/fuzzers/color_space_data.h"
  9. #include "third_party/qcms/src/qcms.h"
  10. static constexpr size_t kPixels = 2048 / 4;
  11. static uint32_t pixels[kPixels];
  12. static void GeneratePixels(size_t hash) {
  13. static std::uniform_int_distribution<uint32_t> uniform(0u, ~0u);
  14. std::mt19937_64 random(hash);
  15. for (size_t i = 0; i < std::size(pixels); ++i)
  16. pixels[i] = uniform(random);
  17. }
  18. static qcms_profile* test;
  19. static qcms_profile* srgb;
  20. static void ColorTransform(bool input) {
  21. if (!test)
  22. return;
  23. const qcms_intent intent = QCMS_INTENT_DEFAULT;
  24. const qcms_data_type format = QCMS_DATA_RGBA_8;
  25. auto* transform =
  26. input ? qcms_transform_create(test, format, srgb, format, intent)
  27. : qcms_transform_create(srgb, format, test, format, intent);
  28. if (!transform)
  29. return;
  30. static uint32_t output[kPixels];
  31. qcms_transform_data(transform, pixels, output, kPixels);
  32. qcms_transform_release(transform);
  33. }
  34. static qcms_profile* SelectProfile(size_t hash) {
  35. static qcms_profile* profiles[4] = {
  36. qcms_profile_from_memory(kSRGBData, std::size(kSRGBData)),
  37. qcms_profile_from_memory(kSRGBPara, std::size(kSRGBPara)),
  38. qcms_profile_from_memory(kAdobeData, std::size(kAdobeData)),
  39. qcms_profile_sRGB(),
  40. };
  41. return profiles[hash & 3];
  42. }
  43. inline size_t Hash(const char* data, size_t size, size_t hash = ~0) {
  44. for (size_t i = 0; i < size; ++i)
  45. hash = hash * 131 + *data++;
  46. return hash;
  47. }
  48. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  49. constexpr size_t kSizeLimit = 4 * 1024 * 1024;
  50. if (size < 128 || size > kSizeLimit)
  51. return 0;
  52. test = qcms_profile_from_memory(data, size);
  53. if (!test)
  54. return 0;
  55. const size_t hash = Hash(reinterpret_cast<const char*>(data), size);
  56. srgb = SelectProfile(hash);
  57. GeneratePixels(hash);
  58. qcms_profile_precache_output_transform(srgb);
  59. ColorTransform(true);
  60. qcms_profile_precache_output_transform(test);
  61. ColorTransform(false);
  62. qcms_profile_release(test);
  63. return 0;
  64. }