// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Converts an Input protobuf Message to a string that can be successfully read
// by SkImageFilter::Deserialize and used as an image filter. The string
// is essentially a valid flattened skia image filter. Note: We will sometimes
// not use the exact values given to us by LPM in cases where those particular
// values cause issues with OOMs and timeouts. Other times, we may write a value
// that isn't exactly the same as the one given to us by LPM, since we may want
// to write invalid values that the proto definition forbids (eg a number that
// is not in enum).  Also note that the skia unflattening code is necessary to
// apply the output of the converter to a canvas, but it isn't the main target
// of the fuzzer. This means that we will generally try to produce output that
// can be applied to a canvas, even if we will consequently be unable to produce
// outputs that allow us to reach paths in the unflattening code (in particular,
// code that handles invalid input). We make this tradeoff because being applied
// to a canvas makes an image filter more likely to cause bugs than if it were
// just deserialized.  Thus, increasing the chance that a filter is applied is
// more important than hitting all paths in unflattening, particularly if those
// paths return nullptr because they've detected an invalid filter. The mutated
// enum values are a case where we knowingly generate output that may not be
// unflattened successfully, which is why we mutate enums relatively
// infrequently.
// Note that since this is a work in progress and skia serialization is a
// moving target, not everything is finished. Many of these parts of the code
// are #defined out if DEVELOPMENT is not defined.

#include "testing/libfuzzer/proto/skia_image_filter_proto_converter.h"

#include <ctype.h>
#include <stdlib.h>

#include <algorithm>
#include <cmath>
#include <limits>
#include <random>
#include <set>
#include <string>
#include <tuple>
#include <unordered_map>
#include <vector>

#include "base/logging.h"
#include "third_party/protobuf/src/google/protobuf/descriptor.h"
#include "third_party/protobuf/src/google/protobuf/message.h"
#include "third_party/protobuf/src/google/protobuf/repeated_field.h"
#include "third_party/skia/include/core/SkPoint.h"
#include "third_party/skia/include/core/SkRect.h"

using google::protobuf::Descriptor;
using google::protobuf::EnumDescriptor;
using google::protobuf::EnumValueDescriptor;
using google::protobuf::FieldDescriptor;
using google::protobuf::Message;
using google::protobuf::Reflection;

namespace skia_image_filter_proto_converter {

// Visit the skia flattenable that is stored on the oneof FIELD field of MSG if
// not flattenable_visited and MSG.has_FIELD. Sets flattenable_visited to true
// if the MSG.FIELD() is visited. Note that `bool flattenable_visited` must be
// defined false in the same context that this macro is used, before it can be
// used.
#define VISIT_ONEOF_FLATTENABLE(MSG, FIELD)                    \
  if (MSG.has_##FIELD() && !IsBlacklisted(#FIELD)) {           \
    CHECK(!flattenable_visited);                               \
    if (PreVisitFlattenable(FieldToFlattenableName(#FIELD))) { \
      Visit(MSG.FIELD());                                      \
      PostVisitFlattenable();                                  \
    }                                                          \
    flattenable_visited = true;                                \
  }

// Visit FIELD if FIELD is set or if no other field on message was visited
// (this should be used at the end of a series of calls to
// VISIT_ONEOF_FLATTENABLE).
// Note FIELD should not be a message that contains itself by default.
// This is used for messages like ImageFilterChild where we must visit one of
// the fields in a oneof. Even though protobuf doesn't mandate that one of these
// be set, we can still visit one of them if they are not set and protobuf will
// return the default values for each field on that message.
#define VISIT_DEFAULT_FLATTENABLE(MSG, FIELD)                  \
  VISIT_ONEOF_FLATTENABLE(MSG, FIELD);                         \
  if (!flattenable_visited) {                                  \
    flattenable_visited = true;                                \
    if (PreVisitFlattenable(FieldToFlattenableName(#FIELD))) { \
      Visit(MSG.FIELD());                                      \
      PostVisitFlattenable();                                  \
    }                                                          \
  }

// Visit FIELD if it is set on MSG, or write a NULL to indicate it is not
// present.
#define VISIT_OPT_OR_NULL(MSG, FIELD) \
  if (MSG.has_##FIELD()) {            \
    Visit(MSG.FIELD());               \
  } else {                            \
    WriteNum(0);                      \
  }

// Call VisitPictureTag on picture_tag.FIELD() if it is set.
#define VISIT_OPT_TAG(FIELD, TAG)              \
  if (picture_tag.has_##FIELD()) {             \
    VisitPictureTag(picture_tag.FIELD(), TAG); \
  }

// Copied from third_party/skia/include/core/SkTypes.h:SkSetFourByteTag.
#define SET_FOUR_BYTE_TAG(A, B, C, D) \
  (((A) << 24) | ((B) << 16) | ((C) << 8) | (D))

// The following enums and constants are copied from various parts of the skia
// codebase.
enum FlatFlags {
  kHasTypeface_FlatFlag = 0x1,
  kHasEffects_FlatFlag = 0x2,
  kFlatFlagMask = 0x3,
};

enum LightType {
  kDistant_LightType,
  kPoint_LightType,
  kSpot_LightType,
};

// Copied from SkVertices.cpp.
enum VerticesConstants {
  kMode_Mask = 0x0FF,
  kHasTexs_Mask = 0x100,
  kHasColors_Mask = 0x200,
};

// Copied from SerializationOffsets in SkPath.h. Named PathSerializationOffsets
// to avoid conflicting with PathRefSerializationOffsets. Both enums were named
// SerializationOffsets in skia.
enum PathSerializationOffsets {
  kType_SerializationShift = 28,
  kDirection_SerializationShift = 26,
  kIsVolatile_SerializationShift = 25,
  kConvexity_SerializationShift = 16,
  kFillType_SerializationShift = 8,
};

// Copied from SerializationOffsets in SkPathRef.h. Named
// PathRefSerializationOffsets to avoid conflicting with
// PathSerializationOffsets. Both enums were named SerializationOffsets in skia.
enum PathRefSerializationOffsets {
  kLegacyRRectOrOvalStartIdx_SerializationShift = 28,
  kLegacyRRectOrOvalIsCCW_SerializationShift = 27,
  kLegacyIsRRect_SerializationShift = 26,
  kIsFinite_SerializationShift = 25,
  kLegacyIsOval_SerializationShift = 24,
  kSegmentMask_SerializationShift = 0
};

const uint32_t Converter::kPictEofTag = SET_FOUR_BYTE_TAG('e', 'o', 'f', ' ');

const uint32_t Converter::kProfileLookupTable[] = {
    SET_FOUR_BYTE_TAG('m', 'n', 't', 'r'),
    SET_FOUR_BYTE_TAG('s', 'c', 'n', 'r'),
    SET_FOUR_BYTE_TAG('p', 'r', 't', 'r'),
    SET_FOUR_BYTE_TAG('s', 'p', 'a', 'c'),
};

const uint32_t Converter::kInputColorSpaceLookupTable[] = {
    SET_FOUR_BYTE_TAG('R', 'G', 'B', ' '),
    SET_FOUR_BYTE_TAG('C', 'M', 'Y', 'K'),
    SET_FOUR_BYTE_TAG('G', 'R', 'A', 'Y'),
};

const uint32_t Converter::kPCSLookupTable[] = {
    SET_FOUR_BYTE_TAG('X', 'Y', 'Z', ' '),
    SET_FOUR_BYTE_TAG('L', 'a', 'b', ' '),
};

const uint32_t Converter::kTagLookupTable[] = {
    SET_FOUR_BYTE_TAG('r', 'X', 'Y', 'Z'),
    SET_FOUR_BYTE_TAG('g', 'X', 'Y', 'Z'),
    SET_FOUR_BYTE_TAG('b', 'X', 'Y', 'Z'),
    SET_FOUR_BYTE_TAG('r', 'T', 'R', 'C'),
    SET_FOUR_BYTE_TAG('g', 'T', 'R', 'C'),
    SET_FOUR_BYTE_TAG('b', 'T', 'R', 'C'),
    SET_FOUR_BYTE_TAG('k', 'T', 'R', 'C'),
    SET_FOUR_BYTE_TAG('A', '2', 'B', '0'),
    SET_FOUR_BYTE_TAG('c', 'u', 'r', 'v'),
    SET_FOUR_BYTE_TAG('p', 'a', 'r', 'a'),
    SET_FOUR_BYTE_TAG('m', 'l', 'u', 'c'),
};

const char Converter::kSkPictReaderTag[] = {'r', 'e', 'a', 'd'};
const char Converter::kPictureMagicString[] = {'s', 'k', 'i', 'a',
                                               'p', 'i', 'c', 't'};

const uint8_t Converter::kCountNibBits[] = {0, 1, 1, 2, 1, 2, 2, 3,
                                            1, 2, 2, 3, 2, 3, 3, 4};

// The rest of the Converter attributes are not copied from skia.
const int Converter::kFlattenableDepthLimit = 3;
const int Converter::kColorTableBufferLength = 256;
uint8_t Converter::kColorTableBuffer[kColorTableBufferLength];
const int Converter::kNumBound = 20;
const uint8_t Converter::kMutateEnumDenominator = 40;

// Does not include SkSumPathEffect, SkComposePathEffect or SkRegion
// since they don't use the VISIT FLATTENABLE macros.
const string_map_t Converter::kFieldToFlattenableName = {
    {"path_1d_path_effect", "SkPath1DPathEffect"},
    {"path_2d_path_effect", "SkPath2DPathEffect"},
    {"alpha_threshold_filter_impl", "SkAlphaThresholdFilterImpl"},
    {"arithmetic_image_filter", "SkArithmeticImageFilter"},
    {"blur_image_filter_impl", "SkBlurImageFilterImpl"},
    {"blur_mask_filter_impl", "SkBlurMaskFilterImpl"},
    {"color_4_shader", "SkColor4Shader"},
    {"color_filter_image_filter", "SkColorFilterImageFilter"},
    {"color_filter_shader", "SkColorFilterShader"},
    {"color_matrix_filter_row_major_255", "SkColorMatrixFilterRowMajor255"},
    {"color_shader", "SkColorShader"},
    {"compose_color_filter", "SkComposeColorFilter"},
    {"compose_image_filter", "SkComposeImageFilter"},
    {"compose_shader", "SkComposeShader"},
    {"corner_path_effect", "SkCornerPathEffect"},
    {"dash_impl", "SkDashImpl"},
    {"diffuse_lighting_image_filter", "SkDiffuseLightingImageFilter"},
    {"dilate_image_filter", "SkDilateImageFilter"},
    {"discrete_path_effect", "SkDiscretePathEffect"},
    {"displacement_map_effect", "SkDisplacementMapEffect"},
    {"drop_shadow_image_filter", "SkDropShadowImageFilter"},
    {"emboss_mask_filter", "SkEmbossMaskFilter"},
    {"empty_shader", "SkEmptyShader"},
    {"image_shader", "SkImageShader"},
    {"image_source", "SkImageSource"},
    {"line_2d_path_effect", "SkLine2DPathEffect"},
    {"linear_gradient", "SkLinearGradient"},
    {"local_matrix_image_filter", "SkLocalMatrixImageFilter"},
    {"local_matrix_shader", "SkLocalMatrixShader"},
    {"luma_color_filter", "SkLumaColorFilter"},
    {"magnifier_image_filter", "SkMagnifierImageFilter"},
    {"matrix_convolution_image_filter", "SkMatrixConvolutionImageFilter"},
    {"matrix_image_filter", "SkMatrixImageFilter"},
    {"merge_image_filter", "SkMergeImageFilter"},
    {"mode_color_filter", "SkModeColorFilter"},
    {"offset_image_filter", "SkOffsetImageFilter"},
    {"overdraw_color_filter", "SkOverdrawColorFilter"},
    {"paint_image_filter", "SkPaintImageFilter"},
    {"picture_image_filter", "SkPictureImageFilter"},
    {"picture_shader", "SkPictureShader"},
    {"radial_gradient", "SkRadialGradient"},
    {"specular_lighting_image_filter", "SkSpecularLightingImageFilter"},
    {"sweep_gradient", "SkSweepGradient"},
    {"tile_image_filter", "SkTileImageFilter"},
    {"two_point_conical_gradient", "SkTwoPointConicalGradient"},
    {"xfermode_image_filter", "SkXfermodeImageFilter"},
    {"xfermode_image_filter__base", "SkXfermodeImageFilter_Base"},
    {"srgb_gamma_color_filter", "SkSRGBGammaColorFilter"},
    {"high_contrast__filter", "SkHighContrast_Filter"},
    {"table__color_filter", "SkTable_ColorFilter"},
    {"to_srgb_color_filter", "SkToSRGBColorFilter"},
    {"layer_draw_looper", "SkLayerDrawLooper"},
    {"perlin_noise_shader_impl", "SkPerlinNoiseShaderImpl"},
    {"erode_image_filter", "SkErodeImageFilter"},
};

const std::set<std::string> Converter::kMisbehavedFlattenableBlacklist = {
    "matrix_image_filter",   // Causes OOMs.
    "discrete_path_effect",  // Causes timeouts.
    "path_1d_path_effect",   // Causes timeouts.
};

// We don't care about default values of attributes because Reset() sets them to
// correct values and is called by Convert(), the only important public
// function.
Converter::Converter() {
  CHECK_GT(kMutateEnumDenominator, 2);
}

Converter::~Converter() {}

Converter::Converter(const Converter& other) {}

std::string Converter::FieldToFlattenableName(
    const std::string& field_name) const {
  CHECK(kFieldToFlattenableName.find(field_name) !=
        kFieldToFlattenableName.end());

  return kFieldToFlattenableName.at(field_name);
}

void Converter::Reset() {
  output_.clear();
  bound_positive_ = false;
  dont_mutate_enum_ = true;
  pair_path_effect_depth_ = 0;
  flattenable_depth_ = 0;
  stroke_style_used_ = false;
  in_compose_color_filter_ = false;
// In production we don't need attributes used by ICC code since it is not
// built for production code.
#ifdef DEVELOPMENT
  tag_offset_ = 0;
  icc_base_ = 0;
#endif  // DEVELOPMENT
}

std::string Converter::Convert(const Input& input) {
  Reset();
  rand_gen_ = std::mt19937(input.rng_seed());
  enum_mutator_chance_distribution_ =
      std::uniform_int_distribution<>(2, kMutateEnumDenominator);

  // This will recursively call Visit on each proto flattenable until all of
  // them are converted to strings and stored in output_.
  Visit(input.image_filter());
  CheckAlignment();
  return std::string(&output_[0], output_.size());
}

void Converter::Visit(const CropRectangle& crop_rectangle) {
  Visit(crop_rectangle.rectangle());
  WriteNum(BoundNum(crop_rectangle.flags()));
}

void Converter::Visit(const Rectangle& rectangle) {
  WriteRectangle(GetValidRectangle(rectangle.left(), rectangle.top(),
                                   rectangle.right(), rectangle.bottom()));
}

std::tuple<float, float, float, float>
Converter::GetValidRectangle(float left, float top, float right, float bottom) {
  bool initial = bound_positive_;
  bound_positive_ = true;
  left = BoundFloat(left);
  top = BoundFloat(top);
  right = BoundFloat(right);
  bottom = BoundFloat(bottom);

  if (right < left)
    right = left;

  if (bottom < top)
    bottom = top;

  // Inspired by SkValidationUtils.h:SkIsValidRect
  CHECK_LE(left, right);
  CHECK_LE(top, bottom);
  CHECK(IsFinite(right - left));
  CHECK(IsFinite(bottom - top));
  bound_positive_ = initial;
  return std::make_tuple(left, top, right, bottom);
}

std::tuple<int32_t, int32_t, int32_t, int32_t> Converter::GetValidIRect(
    int32_t left,
    int32_t top,
    int32_t right,
    int32_t bottom) {
  auto float_rectangle = GetValidRectangle(left, top, right, bottom);
  return std::make_tuple(static_cast<int32_t>(std::get<0>(float_rectangle)),
                         static_cast<int32_t>(std::get<1>(float_rectangle)),
                         static_cast<int32_t>(std::get<2>(float_rectangle)),
                         static_cast<int32_t>(std::get<3>(float_rectangle)));
}

template <typename T>
void Converter::WriteRectangle(std::tuple<T, T, T, T> rectangle) {
  WriteNum(std::get<0>(rectangle));
  WriteNum(std::get<1>(rectangle));
  WriteNum(std::get<2>(rectangle));
  WriteNum(std::get<3>(rectangle));
}

void Converter::Visit(const LightChild& light_child) {
  if (light_child.has_point_light())
    Visit(light_child.point_light());
  else if (light_child.has_spot_light())
    Visit(light_child.spot_light());
  else
    Visit(light_child.distant_light());
}

void Converter::Visit(const LightParent& light_parent) {
  if (light_parent.light_child().has_point_light())
    WriteNum(kPoint_LightType);
  else if (light_parent.light_child().has_spot_light())
    WriteNum(kSpot_LightType);
  else  // Assume we have distant light
    WriteNum(kDistant_LightType);
  Visit(light_parent.color());
  Visit(light_parent.light_child());
}

void Converter::Visit(const ImageFilterChild& image_filter_child) {
  bool flattenable_visited = false;
  VISIT_ONEOF_FLATTENABLE(image_filter_child, specular_lighting_image_filter);
  VISIT_ONEOF_FLATTENABLE(image_filter_child, matrix_image_filter);
  VISIT_ONEOF_FLATTENABLE(image_filter_child, arithmetic_image_filter);
  VISIT_ONEOF_FLATTENABLE(image_filter_child, alpha_threshold_filter_impl);
  VISIT_ONEOF_FLATTENABLE(image_filter_child, blur_image_filter_impl);
  VISIT_ONEOF_FLATTENABLE(image_filter_child, color_filter_image_filter);
  VISIT_ONEOF_FLATTENABLE(image_filter_child, compose_image_filter);
  VISIT_ONEOF_FLATTENABLE(image_filter_child, displacement_map_effect);
  VISIT_ONEOF_FLATTENABLE(image_filter_child, drop_shadow_image_filter);
  VISIT_ONEOF_FLATTENABLE(image_filter_child, local_matrix_image_filter);
  VISIT_ONEOF_FLATTENABLE(image_filter_child, magnifier_image_filter);
  VISIT_ONEOF_FLATTENABLE(image_filter_child, matrix_convolution_image_filter);
  VISIT_ONEOF_FLATTENABLE(image_filter_child, merge_image_filter);
  VISIT_ONEOF_FLATTENABLE(image_filter_child, dilate_image_filter);
  VISIT_ONEOF_FLATTENABLE(image_filter_child, erode_image_filter);
  VISIT_ONEOF_FLATTENABLE(image_filter_child, offset_image_filter);
  VISIT_ONEOF_FLATTENABLE(image_filter_child, picture_image_filter);
  VISIT_ONEOF_FLATTENABLE(image_filter_child, tile_image_filter);
  VISIT_ONEOF_FLATTENABLE(image_filter_child, xfermode_image_filter__base);
  VISIT_ONEOF_FLATTENABLE(image_filter_child, xfermode_image_filter);
  VISIT_ONEOF_FLATTENABLE(image_filter_child, diffuse_lighting_image_filter);
  VISIT_ONEOF_FLATTENABLE(image_filter_child, image_source);
  VISIT_DEFAULT_FLATTENABLE(image_filter_child, paint_image_filter);
}

void Converter::Visit(
    const DiffuseLightingImageFilter& diffuse_lighting_image_filter) {
  Visit(diffuse_lighting_image_filter.parent(), 1);
  Visit(diffuse_lighting_image_filter.light());
  WriteNum(diffuse_lighting_image_filter.surface_scale());
  // Can't be negative, see:
  // https://www.w3.org/TR/SVG/filters.html#feDiffuseLightingElement
  const float kd = fabs(BoundFloat(diffuse_lighting_image_filter.kd()));
  WriteNum(kd);
}

void Converter::Visit(const XfermodeImageFilter& xfermode_image_filter) {
  Visit(xfermode_image_filter.parent(), 2);
  WriteNum(xfermode_image_filter.mode());
}

void Converter::Visit(
    const XfermodeImageFilter_Base& xfermode_image_filter__base) {
  Visit(xfermode_image_filter__base.parent(), 2);
  WriteNum(xfermode_image_filter__base.mode());
}

void Converter::Visit(const TileImageFilter& tile_image_filter) {
  Visit(tile_image_filter.parent(), 1);
  Visit(tile_image_filter.src());
  Visit(tile_image_filter.dst());
}

void Converter::Visit(const OffsetImageFilter& offset_image_filter) {
  Visit(offset_image_filter.parent(), 1);
  Visit(offset_image_filter.offset());
}

void Converter::Visit(const HighContrast_Filter& high_contrast__filter) {
  WriteFields(high_contrast__filter, 1, 2);
  // Use contrast as a seed.
  WriteNum(GetRandomFloat(high_contrast__filter.contrast(), -1.0, 1.0));
}

void Converter::Visit(const MergeImageFilter& merge_image_filter) {
  Visit(merge_image_filter.parent(), merge_image_filter.parent().inputs_size());
}

void Converter::Visit(const ErodeImageFilter& erode_image_filter) {
  Visit(erode_image_filter.parent(), 1);
  bool initial = bound_positive_;
  bound_positive_ = true;
  WriteFields(erode_image_filter, 2);
  bound_positive_ = initial;
}

template <typename T>
T Converter::BoundNum(T num, int upper_bound) const {
  if (bound_positive_)
    num = Abs(num);
  if (num >= 0) {
    return num % upper_bound;
  } else {
    // Don't let negative numbers be too negative.
    return num % -upper_bound;
  }
}

template <typename T>
T Converter::BoundNum(T num) {
  return BoundNum(num, kNumBound);
}

float Converter::BoundFloat(float num) {
  return BoundFloat(num, kNumBound);
}

float Converter::BoundFloat(float num, const float num_bound) {
  // Don't allow nans infs, they can cause OOMs.
  if (!IsFinite(num))
    num = GetRandomFloat(&rand_gen_);

  float result;
  if (num >= 0)
    result = fmod(num, num_bound);
  else if (bound_positive_)
    result = fmod(fabsf(num), num_bound);
  else
    // Bound negative numbers.
    result = fmod(num, -num_bound);
  if (!IsFinite(result))
    return BoundFloat(num);
  return result;
}

void Converter::Visit(const DilateImageFilter& dilate_image_filter) {
  Visit(dilate_image_filter.parent(), 1);
  // Make sure WriteFields writes positive values for width and height.
  // Save the value of bound_positive_ and restore it after WriteFields
  // returns.
  bool initial_bound_positive = bound_positive_;
  bound_positive_ = true;
  WriteFields(dilate_image_filter, 2);
  bound_positive_ = initial_bound_positive;
}

void Converter::Visit(
    const MatrixConvolutionImageFilter& matrix_convolution_image_filter) {
  Visit(matrix_convolution_image_filter.parent(), 1);
  // Avoid timeouts from having to generate too many random numbers.
  // TODO(metzman): actually calculate the limit based on this bound (eg 31 x 1
  // probably doesn't need to be bounded).
  const int upper_bound = 30;

  // Use 2 instead of 1 to avoid FPEs in BoundNum.
  int32_t width = std::max(
      2, BoundNum(Abs(matrix_convolution_image_filter.width()), upper_bound));

  WriteNum(width);

  int32_t height = std::max(
      2, BoundNum(Abs(matrix_convolution_image_filter.height()), upper_bound));

  WriteNum(height);

  std::mt19937 rand_gen(matrix_convolution_image_filter.kernel_seed());
  const uint32_t kernel_size = width * height;
  WriteNum(kernel_size);
  // Use rand_gen to ensure we have a large enough kernel.
  for (uint32_t kernel_counter = 0; kernel_counter < kernel_size;
       kernel_counter++) {
    float kernel_element = GetRandomFloat(&rand_gen);
    WriteNum(kernel_element);
  }
  WriteFields(matrix_convolution_image_filter, 5, 6);

  const uint32_t offset_x =
      std::max(0, matrix_convolution_image_filter.offset_x());

  const uint32_t offset_y =
      std::max(0, matrix_convolution_image_filter.offset_y());

  WriteNum(BoundNum(offset_x, width - 1));
  WriteNum(BoundNum(offset_y, height - 1));
  WriteFields(matrix_convolution_image_filter, 9);
}

void Converter::Visit(const MagnifierImageFilter& magnifier_image_filter) {
  Visit(magnifier_image_filter.parent(), 1);
  Visit(magnifier_image_filter.src());
  const float inset = fabs(BoundFloat(magnifier_image_filter.inset()));
  CHECK(IsFinite(inset));
  WriteNum(inset);
}

void Converter::Visit(const LocalMatrixImageFilter& local_matrix_image_filter) {
  // TODO(metzman): Make it so that deserialization always succeeds by ensuring
  // the type isn't kAffine_Mask or KPerspectiveMask (see constructor for
  // SkLocalMatrixImageFilter).
  Visit(local_matrix_image_filter.parent(), 1);
  Visit(local_matrix_image_filter.matrix(), true);
}

void Converter::Visit(const ImageSource& image_source) {
  WriteNum(image_source.filter_quality());
  auto src_rect = GetValidRectangle(
      image_source.src().left(), image_source.src().top(),
      image_source.src().right(), image_source.src().bottom());

  // See SkImageSource::Make for why we mandate width and height be at least
  // .01.  This is such a small difference that we won't bother bounding again.
  float left = std::get<0>(src_rect);
  float* right = &std::get<2>(src_rect);
  if ((*right - left) <= 0.0f)
    *right += .01;

  float top = std::get<1>(src_rect);
  float* bottom = &std::get<3>(src_rect);
  if ((*bottom - top) <= 0.0f)
    *bottom += .01;

  WriteRectangle(src_rect);
  Visit(image_source.dst());
  Visit(image_source.image());
}

void Converter::Visit(const DropShadowImageFilter& drop_shadow_image_filter) {
  Visit(drop_shadow_image_filter.parent(), 1);
  WriteFields(drop_shadow_image_filter, 2);
}

void Converter::Visit(const DisplacementMapEffect& displacement_map_effect) {
  Visit(displacement_map_effect.parent(), 2);
  bool initial = dont_mutate_enum_;
  dont_mutate_enum_ = true;
  WriteFields(displacement_map_effect, 2);
  dont_mutate_enum_ = initial;
}

void Converter::Visit(const ComposeImageFilter& compose_image_filter) {
  Visit(compose_image_filter.parent(), 2);
}

void Converter::Visit(const ColorFilterImageFilter& color_filter_image_filter) {
  Visit(color_filter_image_filter.parent(), 1);
  Visit(color_filter_image_filter.color_filter());
}

void Converter::Visit(const BlurImageFilterImpl& blur_image_filter_impl) {
  Visit(blur_image_filter_impl.parent(), 1);
  WriteFields(blur_image_filter_impl, 2);
}

void Converter::Visit(
    const AlphaThresholdFilterImpl& alpha_threshold_filter_impl) {
  Visit(alpha_threshold_filter_impl.parent(), 1);
  WriteFields(alpha_threshold_filter_impl, 2, 3);
  Visit(alpha_threshold_filter_impl.rgn());
}

std::tuple<int32_t, int32_t, int32_t, int32_t> Converter::WriteNonEmptyIRect(
    const IRect& irect) {
  // Make sure bounds do not specify an empty rectangle.
  // See SkRect.h:202
  auto rectangle =
      GetValidIRect(irect.left(), irect.top(), irect.right(), irect.bottom());

  // Ensure top and right are greater than left and top.
  if (irect.left() >= irect.right() || irect.top() >= irect.bottom()) {
    std::get<2>(rectangle) = std::get<0>(rectangle) + 1;
    std::get<3>(rectangle) = std::get<1>(rectangle) + 1;
  }
  WriteRectangle(rectangle);
  return rectangle;
}

void Converter::Visit(const Region& region) {
  // Write simple region.
  WriteNum(0);
  WriteNonEmptyIRect(region.bounds());

// Complex regions are not finished.
#ifdef DEVELOPMENT
  enum { kRunTypeSentinel = 0x7FFFFFFF };
  auto rectangle = WriteNonEmptyIRect(region.bounds());
  const int32_t bound_left = std::get<0>(rectangle);
  const int32_t bound_top = std::get<1>(rectangle);
  const int32_t bound_right = std::get<2>(rectangle);
  const int32_t bound_bottom = std::get<3>(rectangle);

  const int32_t y_span_count =
      BoundNum(std::max(1, Abs(region.y_span_count())));

  const int32_t interval_count = BoundNum(std::max(1, Abs(region.interval_())));

  WriteNum(run_count);
  WriteNum(y_span_count);
  WriteNum(interval_count);

  // See SkRegion::validate_run.
  // Really this is two less, but we will write the two sentinels
  ourselves const int32_t run_count = 3 * y_span_count + 2 * interval_count;
  CHECK(run_count >= 7);

  WriteNum(run_count + 2);
  // Write runs.

  // Write top.
  Write(bound_top);

  WriteNum(kRunTypeSentinel);
  WriteNum(kRunTypeSentinel);
#endif  // DEVELOPMENT
}

void Converter::Visit(const PictureInfo& picture_info) {
  WriteArray(kPictureMagicString, sizeof(kPictureMagicString));
  WriteNum(picture_info.version());
  Visit(picture_info.rectangle());
  if (picture_info.version() < PictureInfo::kRemoveHeaderFlags_Version)
    WriteNum(picture_info.flags());
}

void Converter::Visit(const ImageFilterParent& image_filter,
                      const int num_inputs_required) {
  CHECK_GE(num_inputs_required, 0);
  if (!num_inputs_required) {
    WriteNum(0);
  } else {
    WriteNum(num_inputs_required);
    WriteBool(true);
    Visit(image_filter.default_input());
    int num_inputs = 1;
    for (const auto& input : image_filter.inputs()) {
      if (num_inputs++ >= num_inputs_required)
        break;
      WriteBool(true);
      Visit(input);
    }
    for (; num_inputs < num_inputs_required; num_inputs++) {
      // Copy default_input until we have enough.
      WriteBool(true);
      Visit(image_filter.default_input());
    }
  }
  Visit(image_filter.crop_rectangle());
}

void Converter::Visit(const ArithmeticImageFilter& arithmetic_image_filter) {
  Visit(arithmetic_image_filter.parent(), 2);

  // This is field is ignored, but write kSrcOver (3) as the flattening code
  // does.
  // TODO(metzman): change to enum value (SkBlendMode::kSrcOver) when it
  // is uncommented, for now just write, its value: 3.
  WriteNum(3);

  WriteFields(arithmetic_image_filter, 2);
}

void Converter::Visit(
    const SpecularLightingImageFilter& specular_lighting_image_filter) {
  Visit(specular_lighting_image_filter.image_filter_parent(), 1);
  Visit(specular_lighting_image_filter.light());
  WriteNum(BoundFloat(specular_lighting_image_filter.surface_scale()) * 255);
  WriteNum(fabs(BoundFloat(specular_lighting_image_filter.ks())));
  WriteNum(BoundFloat(specular_lighting_image_filter.shininess()));
}

void Converter::RecordSize() {
  // Reserve space to overwrite when we are done writing whatever size we are
  // recording.
  WriteNum(0);
  start_sizes_.push_back(output_.size());
}

size_t Converter::PopStartSize() {
  CHECK_GT(start_sizes_.size(), static_cast<size_t>(0));
  const size_t back = start_sizes_.back();
  start_sizes_.pop_back();
  return back;
}

template <typename T>
void Converter::WriteNum(const T num) {
  if (sizeof(T) > 4) {
    CHECK(num <= UINT32_MAX);
    uint32_t four_byte_num = static_cast<uint32_t>(num);
    char num_arr[sizeof(four_byte_num)];
    memcpy(num_arr, &four_byte_num, sizeof(four_byte_num));
    for (size_t idx = 0; idx < sizeof(four_byte_num); idx++)
      output_.push_back(num_arr[idx]);
    return;
  }
  char num_arr[sizeof(T)];
  memcpy(num_arr, &num, sizeof(T));
  for (size_t idx = 0; idx < sizeof(T); idx++)
    output_.push_back(num_arr[idx]);
}

void Converter::InsertSize(const size_t size, const uint32_t position) {
  char size_arr[sizeof(uint32_t)];
  memcpy(size_arr, &size, sizeof(uint32_t));

  for (size_t idx = 0; idx < sizeof(uint32_t); idx++) {
    const size_t output__idx = position + idx - sizeof(uint32_t);
    CHECK_LT(output__idx, output_.size());
    output_[output__idx] = size_arr[idx];
  }
}

void Converter::WriteBytesWritten() {
  const size_t start_size = PopStartSize();
  CHECK_LT(start_size, std::numeric_limits<uint32_t>::max());
  const size_t end_size = output_.size();
  CHECK_LE(start_size, end_size);
  const size_t bytes_written = end_size - start_size;
  CHECK_LT(bytes_written, std::numeric_limits<uint32_t>::max());
  InsertSize(bytes_written, start_size);
}

void Converter::WriteString(const std::string str) {
  WriteNum(str.size());
  const char* c_str = str.c_str();
  for (size_t idx = 0; idx < str.size(); idx++)
    output_.push_back(c_str[idx]);

  output_.push_back('\0');  // Add trailing NULL.

  Pad(str.size() + 1);
}

void Converter::WriteArray(
    const google::protobuf::RepeatedField<uint32_t>& repeated_field,
    const size_t size) {
  WriteNum(size * sizeof(uint32_t));  // Array size.
  for (uint32_t element : repeated_field)
    WriteNum(element);
  // Padding is not a concern because uint32_ts are 4 bytes.
}

void Converter::WriteArray(const char* arr, const size_t size) {
  WriteNum(size);
  for (size_t idx = 0; idx < size; idx++)
    output_.push_back(arr[idx]);

  for (unsigned idx = 0; idx < size % 4; idx++)
    output_.push_back('\0');
}

void Converter::WriteBool(const bool bool_val) {
  // bools are usually written as 32 bit integers in skia flattening.
  WriteNum(static_cast<uint32_t>(bool_val));
}

void Converter::WriteNum(const char (&num_arr)[4]) {
  for (size_t idx = 0; idx < 4; idx++)
    output_.push_back(num_arr[idx]);
}

void Converter::Visit(const PictureShader& picture_shader) {
  // PictureShader cannot be autovisited because matrix cannot be.
  Visit(picture_shader.matrix());
  WriteFields(picture_shader, 2, 3);
  Visit(picture_shader.rect());
  WriteBool(false);
}

void Converter::Visit(const Message& msg) {
  WriteFields(msg);
}

// Visit the Message elements of repeated_field, using the type-specific Visit
// methods (thanks to templating).
template <class T>
void Converter::Visit(
    const google::protobuf::RepeatedPtrField<T>& repeated_field) {
  for (const T& single_field : repeated_field)
    Visit(single_field);
}

void Converter::Visit(const PictureImageFilter& picture_image_filter) {
  WriteBool(picture_image_filter.has_picture());
  if (picture_image_filter.has_picture())
    Visit(picture_image_filter.picture());
  // Allow 0x0 rectangles to sometimes be written even though it will mess up
  // make_localspace_filter.
  Visit(picture_image_filter.crop_rectangle());
  if (picture_image_filter.has_picture()) {
    if (picture_image_filter.picture().info().version() <
        PictureInfo::kRemoveHeaderFlags_Version)

      WriteNum(picture_image_filter.resolution());
  }
}

void Converter::Visit(const PictureData& picture_data) {
  for (auto& tag : picture_data.tags()) {
    Visit(tag);
  }
  Visit(picture_data.reader_tag());

  WriteNum(kPictEofTag);
}

void Converter::VisitPictureTag(const PaintPictureTag& paint_picture_tag,
                                uint32_t tag) {
  WriteNum(tag);
  WriteNum(1);  // Size.
  Visit(paint_picture_tag.paint());
}

void Converter::VisitPictureTag(const PathPictureTag& path_picture_tag,
                                uint32_t tag) {
  WriteNum(tag);
  WriteNum(1);  // Size.
  WriteNum(1);  // Count.
  Visit(path_picture_tag.path());
}

template <class T>
void Converter::VisitPictureTag(const T& picture_tag_child, uint32_t tag) {
  WriteNum(tag);
  WriteNum(1);
  Visit(picture_tag_child);
}

void Converter::Visit(const ReaderPictureTag& reader) {
  WriteNum(SET_FOUR_BYTE_TAG('r', 'e', 'a', 'd'));
  const uint32_t size = sizeof(uint32_t) * (1 + reader.later_bytes_size());
  WriteNum(size);
  WriteNum(size);
  WriteNum(reader.first_bytes());
  for (auto bytes : reader.later_bytes())
    WriteNum(bytes);
}

// Copied from SkPaint.cpp.
static uint32_t pack_4(unsigned a, unsigned b, unsigned c, unsigned d) {
  CHECK_EQ(a, (uint8_t)a);
  CHECK_EQ(b, (uint8_t)b);
  CHECK_EQ(c, (uint8_t)c);
  CHECK_EQ(d, (uint8_t)d);
  return (a << 24) | (b << 16) | (c << 8) | d;
}

// Copied from SkPaint.cpp.
static uint32_t pack_paint_flags(unsigned flags,
                                 unsigned hint,
                                 unsigned align,
                                 unsigned filter,
                                 unsigned flatFlags) {
  // left-align the fields of "known" size, and right-align the last (flatFlags)
  // so it can easily add more bits in the future.
  return (flags << 16) | (hint << 14) | (align << 12) | (filter << 10) |
         flatFlags;
}

bool Converter::IsFinite(float num) const {
  // If num is inf, -inf, nan or -nan then num*0 will be nan.
  return !std::isnan(num * 0);
}

void Converter::Visit(const Paint& paint) {
  WriteFields(paint, 1, 6);

  uint8_t flat_flags = 0;
  if (paint.has_effects())
    flat_flags |= kHasEffects_FlatFlag;

  WriteNum(pack_paint_flags(paint.flags(), paint.hinting(), paint.align(),
                            paint.filter_quality(), flat_flags));

  int style = paint.style();
  Paint::StrokeCap stroke_cap = paint.stroke_cap();

  if (stroke_style_used_) {
    style = Paint::kFill_Style;
  } else if (style == Paint::kStrokeAndFill_Style ||
             style == Paint::kStroke_Style) {
    stroke_style_used_ = true;
    // Avoid timeouts.
    stroke_cap = Paint::kButt_Cap;
  }

  uint32_t tmp =
      pack_4(stroke_cap, paint.stroke_join(),
             (style << 4) | paint.text_encoding(), paint.blend_mode());

  WriteNum(tmp);  // See https://goo.gl/nYJfTy

  if (paint.has_effects())
    Visit(paint.effects());
}

void Converter::Visit(const PaintEffects& paint_effects) {
  // There should be a NULL written for every paint_effects field that is not
  // set.
  VISIT_OPT_OR_NULL(paint_effects, path_effect);
  VISIT_OPT_OR_NULL(paint_effects, shader);
  VISIT_OPT_OR_NULL(paint_effects, mask_filter);
  VISIT_OPT_OR_NULL(paint_effects, color_filter);
  WriteNum(0);  // Write ignored number where rasterizer used to be.
  VISIT_OPT_OR_NULL(paint_effects, looper);
  VISIT_OPT_OR_NULL(paint_effects, image_filter);
}

void Converter::Visit(const ColorFilterChild& color_filter_child) {
  bool flattenable_visited = false;
  VISIT_ONEOF_FLATTENABLE(color_filter_child,
                          color_matrix_filter_row_major_255);

  if (!in_compose_color_filter_)
    VISIT_ONEOF_FLATTENABLE(color_filter_child, compose_color_filter);

  VISIT_ONEOF_FLATTENABLE(color_filter_child, srgb_gamma_color_filter);
  VISIT_ONEOF_FLATTENABLE(color_filter_child, high_contrast__filter);
  VISIT_ONEOF_FLATTENABLE(color_filter_child, luma_color_filter);
  VISIT_ONEOF_FLATTENABLE(color_filter_child, overdraw_color_filter);
  VISIT_ONEOF_FLATTENABLE(color_filter_child, table__color_filter);
  VISIT_ONEOF_FLATTENABLE(color_filter_child, to_srgb_color_filter);
  VISIT_DEFAULT_FLATTENABLE(color_filter_child, mode_color_filter);
}

void Converter::Visit(const Color4f& color_4f) {
  WriteFields(color_4f);
}

void Converter::Visit(const GradientDescriptor& gradient_descriptor) {
  // See SkGradientShaderBase::Descriptor::flatten in SkGradientShader.cpp.
  enum GradientSerializationFlags {
    // Bits 29:31 used for various boolean flags
    kHasPosition_GSF = 0x80000000,
    kHasLocalMatrix_GSF = 0x40000000,
    kHasColorSpace_GSF = 0x20000000,

    // Bits 12:28 unused

    // Bits 8:11 for fTileMode
    kTileModeShift_GSF = 8,
    kTileModeMask_GSF = 0xF,

    // Bits 0:7 for fGradFlags (note that kForce4fContext_PrivateFlag is 0x80)
    kGradFlagsShift_GSF = 0,
    kGradFlagsMask_GSF = 0xFF,
  };

  uint32_t flags = 0;
  if (gradient_descriptor.has_pos())
    flags |= kHasPosition_GSF;
  if (gradient_descriptor.has_local_matrix())
    flags |= kHasLocalMatrix_GSF;
  if (gradient_descriptor.has_color_space())
    flags |= kHasColorSpace_GSF;
  flags |= (gradient_descriptor.tile_mode() << kTileModeShift_GSF);
  uint32_t grad_flags =
      (gradient_descriptor.grad_flags() % (kGradFlagsMask_GSF + 1));
  CHECK_LE(grad_flags, kGradFlagsMask_GSF);
  WriteNum(flags);

  const uint32_t count = gradient_descriptor.colors_size();

  WriteNum(count);
  for (auto& color : gradient_descriptor.colors())
    Visit(color);

  Visit(gradient_descriptor.color_space());

  WriteNum(count);
  for (uint32_t counter = 0; counter < count; counter++)
    WriteNum(gradient_descriptor.pos());

  Visit(gradient_descriptor.local_matrix());
}

void Converter::Visit(const GradientParent& gradient_parent) {
  Visit(gradient_parent.gradient_descriptor());
}

void Converter::Visit(const ToSRGBColorFilter& to_srgb_color_filter) {
  Visit(to_srgb_color_filter.color_space());
}

void Converter::Visit(const LooperChild& looper) {
  if (PreVisitFlattenable("SkLayerDrawLooper")) {
    Visit(looper.layer_draw_looper());
    PostVisitFlattenable();
  }
}

// Copied from SkPackBits.cpp.
static uint8_t* flush_diff8(uint8_t* dst, const uint8_t* src, size_t count) {
  while (count > 0) {
    size_t n = count > 128 ? 128 : count;
    *dst++ = (uint8_t)(n + 127);
    memcpy(dst, src, n);
    src += n;
    dst += n;
    count -= n;
  }
  return dst;
}

// Copied from SkPackBits.cpp.
static uint8_t* flush_same8(uint8_t dst[], uint8_t value, size_t count) {
  while (count > 0) {
    size_t n = count > 128 ? 128 : count;
    *dst++ = (uint8_t)(n - 1);
    *dst++ = (uint8_t)value;
    count -= n;
  }
  return dst;
}

// Copied from SkPackBits.cpp.
static size_t compute_max_size8(size_t srcSize) {
  // Worst case is the number of 8bit values + 1 byte per (up to) 128 entries.
  return ((srcSize + 127) >> 7) + srcSize;
}

// Copied from SkPackBits.cpp.
static size_t pack8(const uint8_t* src,
                    size_t srcSize,
                    uint8_t* dst,
                    size_t dstSize) {
  if (dstSize < compute_max_size8(srcSize)) {
    return 0;
  }

  uint8_t* const origDst = dst;
  const uint8_t* stop = src + srcSize;

  for (intptr_t count = stop - src; count > 0; count = stop - src) {
    if (1 == count) {
      *dst++ = 0;
      *dst++ = *src;
      break;
    }

    unsigned value = *src;
    const uint8_t* s = src + 1;

    if (*s == value) {  // accumulate same values...
      do {
        s++;
        if (s == stop) {
          break;
        }
      } while (*s == value);
      dst = flush_same8(dst, value, (size_t)(s - src));
    } else {  // accumulate diff values...
      do {
        if (++s == stop) {
          goto FLUSH_DIFF;
        }
        // only stop if we hit 3 in a row,
        // otherwise we get bigger than compuatemax
      } while (*s != s[-1] || s[-1] != s[-2]);
      s -= 2;  // back up so we don't grab the "same" values that follow
    FLUSH_DIFF:
      dst = flush_diff8(dst, src, (size_t)(s - src));
    }
    src = s;
  }
  return dst - origDst;
}

const uint8_t* Converter::ColorTableToArray(const ColorTable& color_table) {
  float* dst = reinterpret_cast<float*>(kColorTableBuffer);
  const int array_size = 64;
  // Now write the 256 fields.
  const Descriptor* descriptor = color_table.GetDescriptor();
  CHECK(descriptor);
  const Reflection* reflection = color_table.GetReflection();
  CHECK(reflection);
  for (int field_num = 1; field_num <= array_size; field_num++, dst++) {
    const FieldDescriptor* field_descriptor =
        descriptor->FindFieldByNumber(field_num);
    CHECK(field_descriptor);
    *dst = BoundFloat(reflection->GetFloat(color_table, field_descriptor));
  }
  return kColorTableBuffer;
}

void Converter::Visit(const Table_ColorFilter& table__color_filter) {
  // See SkTable_ColorFilter::SkTable_ColorFilter
  enum {
    kA_Flag = 1 << 0,
    kR_Flag = 1 << 1,
    kG_Flag = 1 << 2,
    kB_Flag = 1 << 3,
  };
  unsigned flags = 0;
  uint8_t f_storage[4 * kColorTableBufferLength];
  uint8_t* dst = f_storage;

  if (table__color_filter.has_table_a()) {
    memcpy(dst, ColorTableToArray(table__color_filter.table_a()),
           kColorTableBufferLength);

    dst += kColorTableBufferLength;
    flags |= kA_Flag;
  }
  if (table__color_filter.has_table_r()) {
    memcpy(dst, ColorTableToArray(table__color_filter.table_r()),
           kColorTableBufferLength);

    dst += kColorTableBufferLength;
    flags |= kR_Flag;
  }
  if (table__color_filter.has_table_g()) {
    memcpy(dst, ColorTableToArray(table__color_filter.table_g()),
           kColorTableBufferLength);

    dst += kColorTableBufferLength;
    flags |= kG_Flag;
  }
  if (table__color_filter.has_table_b()) {
    memcpy(dst, ColorTableToArray(table__color_filter.table_b()),
           kColorTableBufferLength);

    dst += kColorTableBufferLength;
    flags |= kB_Flag;
  }
  uint8_t storage[5 * kColorTableBufferLength];
  const int count = kCountNibBits[flags & 0xF];
  const size_t size = pack8(f_storage, count * kColorTableBufferLength, storage,
                            sizeof(storage));

  CHECK_LE(flags, UINT32_MAX);
  const uint32_t flags_32 = (uint32_t)flags;
  WriteNum(flags_32);
  WriteNum((uint32_t)size);
  for (size_t idx = 0; idx < size; idx++)
    output_.push_back(storage[idx]);
  Pad(output_.size());
}

void Converter::Visit(const ComposeColorFilter& compose_color_filter) {
  CHECK(!in_compose_color_filter_);
  in_compose_color_filter_ = true;
  Visit(compose_color_filter.outer());
  Visit(compose_color_filter.inner());
  in_compose_color_filter_ = false;
}

void Converter::Visit(const OverdrawColorFilter& overdraw_color_filter) {
  // This is written as a byte array (length-in-bytes followed by data).
  const uint32_t num_fields = 6;
  const uint32_t arr_size = num_fields * sizeof(uint32_t);
  WriteNum(arr_size);
  WriteFields(overdraw_color_filter);
}

void Converter::Visit(
    const ColorMatrixFilterRowMajor255& color_matrix_filter_row_major_255) {
  Visit(color_matrix_filter_row_major_255.color_filter_matrix());
}

void Converter::Visit(const ColorFilterMatrix& color_filter_matrix) {
  static const int kColorFilterMatrixNumFields = 20;
  WriteNum(kColorFilterMatrixNumFields);
  WriteFields(color_filter_matrix);
}

void Converter::Visit(const LayerDrawLooper& layer_draw_looper) {
  WriteNum(layer_draw_looper.layer_infos_size());
  for (auto& layer_info : layer_draw_looper.layer_infos()) {
    Visit(layer_info);
#ifdef AVOID_MISBEHAVIOR
    break;  // Only write 1 to avoid timeouts.
#endif
  }
}

void Converter::Visit(const LayerInfo& layer_info) {
  WriteNum(0);
  // Don't mutate these enum values or else a crash will be caused
  bool initial = dont_mutate_enum_;
  dont_mutate_enum_ = true;
  WriteFields(layer_info, 1, 4);
  dont_mutate_enum_ = initial;
  Visit(layer_info.paint());
}

void Converter::Visit(const PairPathEffect& pair) {
  // Don't allow nesting of PairPathEffects for performance reasons
  if (pair_path_effect_depth_ >= 1)
    return;
  if (flattenable_depth_ > kFlattenableDepthLimit)
    return;
  pair_path_effect_depth_ += 1;
  flattenable_depth_ += 1;

  std::string name;
  if (pair.type() == PairPathEffect::SUM)
    name = "SkSumPathEffect";
  else
    name = "SkComposePathEffect";
  WriteString(name);
  RecordSize();

  Visit(pair.path_effect_1());
  Visit(pair.path_effect_2());

  WriteBytesWritten();  // Flattenable size.
  CheckAlignment();
  pair_path_effect_depth_ -= 1;
  flattenable_depth_ -= 1;
}

// See SkPathRef::writeToBuffer
void Converter::Visit(const PathRef& path_ref) {
  // Bound segment_mask to avoid timeouts and for proper behavior.
  const int32_t packed =
      (((path_ref.is_finite() & 1) << kIsFinite_SerializationShift) |
       (ToUInt8(path_ref.segment_mask()) << kSegmentMask_SerializationShift));

  WriteNum(packed);
  WriteNum(0);
  std::vector<SkPoint> points;
  if (path_ref.verbs_size()) {
    WriteNum(path_ref.verbs_size() + 1);
    uint32_t num_points = 1;  // The last move will add 1 point.
    uint32_t num_conics = 0;
    for (auto& verb : path_ref.verbs()) {
      switch (verb.value()) {
        case ValidVerb::kMove_Verb:
        case ValidVerb::kLine_Verb:
          num_points += 1;
          break;
        case ValidVerb::kConic_Verb:
          num_conics += 1;
          FALLTHROUGH;
        case ValidVerb::kQuad_Verb:
          num_points += 2;
          break;
        case ValidVerb::kCubic_Verb:
          num_points += 3;
          break;
        case ValidVerb::kClose_Verb:
          break;
        default:
          NOTREACHED();
      }
    }
    WriteNum(num_points);
    WriteNum(num_conics);
  } else {
    WriteNum(0);
    WriteNum(0);
    WriteNum(0);
  }

  for (auto& verb : path_ref.verbs()) {
    const uint8_t value = verb.value();
    WriteNum(value);
  }
  // Verbs must start (they are written backwards) with kMove_Verb (0).
  if (path_ref.verbs_size()) {
    uint8_t value = ValidVerb::kMove_Verb;
    WriteNum(value);
  }

  // Write points
  for (auto& verb : path_ref.verbs()) {
    switch (verb.value()) {
      case ValidVerb::kMove_Verb:
      case ValidVerb::kLine_Verb: {
        Visit(verb.point1());
        AppendAsSkPoint(points, verb.point1());
        break;
      }
      case ValidVerb::kConic_Verb:
      case ValidVerb::kQuad_Verb: {
        Visit(verb.point1());
        Visit(verb.point2());
        AppendAsSkPoint(points, verb.point1());
        AppendAsSkPoint(points, verb.point2());
        break;
      }
      case ValidVerb::kCubic_Verb:
        Visit(verb.point1());
        Visit(verb.point2());
        Visit(verb.point3());
        AppendAsSkPoint(points, verb.point1());
        AppendAsSkPoint(points, verb.point2());
        AppendAsSkPoint(points, verb.point3());
        break;
      default:
        break;
    }
  }
  // Write point of the Move Verb we put at the end.
  if (path_ref.verbs_size()) {
    Visit(path_ref.first_verb().point1());
    AppendAsSkPoint(points, path_ref.first_verb().point1());
  }

  // Write conic weights.
  for (auto& verb : path_ref.verbs()) {
    if (verb.value() == ValidVerb::kConic_Verb)
      WriteNum(verb.conic_weight());
  }

  SkRect skrect;
  skrect.setBoundsCheck(&points[0], points.size());
  WriteNum(skrect.fLeft);
  WriteNum(skrect.fTop);
  WriteNum(skrect.fRight);
  WriteNum(skrect.fBottom);
}

void Converter::AppendAsSkPoint(std::vector<SkPoint>& sk_points,
                                const Point& proto_point) const {
  SkPoint sk_point;
  sk_point.fX = proto_point.x();
  sk_point.fY = proto_point.y();
  sk_points.push_back(sk_point);
}

void Converter::Visit(const Path& path) {
  enum SerializationVersions {
    kPathPrivFirstDirection_Version = 1,
    kPathPrivLastMoveToIndex_Version = 2,
    kPathPrivTypeEnumVersion = 3,
    kCurrent_Version = 3
  };

  enum FirstDirection {
    kCW_FirstDirection,
    kCCW_FirstDirection,
    kUnknown_FirstDirection,
  };

  int32_t packed = (path.convexity() << kConvexity_SerializationShift) |
                   (path.fill_type() << kFillType_SerializationShift) |
                   (path.first_direction() << kDirection_SerializationShift) |
                   (path.is_volatile() << kIsVolatile_SerializationShift) |
                   kCurrent_Version;

  // TODO(metzman): Allow writing as RRect.
  WriteNum(packed);
  WriteNum(path.last_move_to_index());
  Visit(path.path_ref());
  Pad(output_.size());
  CheckAlignment();
}

void Converter::Visit(const BlurMaskFilter& blur_mask_filter) {
  // Sigma must be a finite number <= 0.
  float sigma = fabs(BoundFloat(blur_mask_filter.sigma()));
  sigma = 1 ? sigma == 0 : sigma;
  WriteNum(sigma);
  const bool old_value = dont_mutate_enum_;
  dont_mutate_enum_ = true;
  WriteFields(blur_mask_filter, 2, 3);
  dont_mutate_enum_ = old_value;
  Visit(blur_mask_filter.occluder());
}

void Converter::CheckAlignment() const {
  CHECK_EQ(output_.size() % 4, static_cast<size_t>(0));
}

void Converter::Visit(const ShaderChild& shader) {
  bool flattenable_visited = false;
  VISIT_ONEOF_FLATTENABLE(shader, color_4_shader);
  VISIT_ONEOF_FLATTENABLE(shader, color_filter_shader);
  VISIT_ONEOF_FLATTENABLE(shader, image_shader);
  VISIT_ONEOF_FLATTENABLE(shader, compose_shader);
  VISIT_ONEOF_FLATTENABLE(shader, empty_shader);
  VISIT_ONEOF_FLATTENABLE(shader, picture_shader);
  VISIT_ONEOF_FLATTENABLE(shader, perlin_noise_shader_impl);
  VISIT_ONEOF_FLATTENABLE(shader, local_matrix_shader);
  VISIT_ONEOF_FLATTENABLE(shader, linear_gradient);
  VISIT_ONEOF_FLATTENABLE(shader, radial_gradient);
  VISIT_ONEOF_FLATTENABLE(shader, sweep_gradient);
  VISIT_ONEOF_FLATTENABLE(shader, two_point_conical_gradient);
  VISIT_DEFAULT_FLATTENABLE(shader, color_shader);
}

void Converter::Visit(
    const TwoPointConicalGradient& two_point_conical_gradient) {
  Visit(two_point_conical_gradient.parent());
  WriteFields(two_point_conical_gradient, 2, 5);
}

void Converter::Visit(const LinearGradient& linear_gradient) {
  Visit(linear_gradient.parent());
  WriteFields(linear_gradient, 2, 3);
}

void Converter::Visit(const SweepGradient& sweep_gradient) {
  Visit(sweep_gradient.parent());
  WriteFields(sweep_gradient, 2, 4);
}

void Converter::Visit(const RadialGradient& radial_gradient) {
  Visit(radial_gradient.parent());
  WriteFields(radial_gradient, 2, 3);
}

// Don't compile unfinished (dead) code in production.
#ifdef DEVELOPMENT
// ICC handling code is unfinished.
// TODO(metzman): Finish implementing ICC.

// Copied from https://goo.gl/j78F6Z
static constexpr uint32_t kTAG_lut8Type = SET_FOUR_BYTE_TAG('m', 'f', 't', '1');
static constexpr uint32_t kTAG_lut16Type =
    SET_FOUR_BYTE_TAG('m', 'f', 't', '2');
void Converter::Visit(const ICC& icc) {
  icc_base_ = output_.size();
  const uint32_t header_size = sizeof(uint8_t) * 4;
  uint32_t tag_count = 0;
  uint32_t tags_size = 0;
  if (icc.color_space().has_a2b0()) {
    if (icc.color_space().a2b0().has_lut8()) {
      tags_size =
          GetLut8Size(icc.color_space().a2b0().lut8()) + kICCTagTableEntrySize;
    } else if (icc.color_space().a2b0().has_lut16()) {
      tags_size = GetLut16Size(icc.color_space().a2b0().lut16()) +
                  kICCTagTableEntrySize;
    } else {
      NOTREACHED();
    }
    tag_count = 1;
  } else {
    NOTREACHED();
  }

  const uint32_t profile_size = sizeof(float) * 33 + tags_size;
  const uint32_t size = profile_size + sizeof(profile_size) + header_size;
  WriteNum(size);

  // Header.
  WriteColorSpaceVersion();
  WriteNum(ToUInt8(icc.named()));
  WriteNum(ToUInt8(GammaNamed::kNonStandard_SkGammaNamed));
  WriteNum(kICC_Flag);

  WriteNum(profile_size);
  WriteBigEndian(profile_size);
  WriteIgnoredFields(1);
  uint32_t version = icc.version() % 5;
  version <<= 24;
  WriteBigEndian(version);
  WriteBigEndian(kProfileLookupTable[icc.profile_class()]);
  WriteBigEndian(kInputColorSpaceLookupTable[icc.input_color_space()]);
  WriteBigEndian(kPCSLookupTable[icc.pcs()]);
  WriteIgnoredFields(3);
  WriteBigEndian(SET_FOUR_BYTE_TAG('a', 'c', 's', 'p'));
  WriteIgnoredFields(6);
  WriteBigEndian(icc.rendering_intent());
  WriteBigEndian(BoundIlluminant(icc.illuminant_x(), 0.96420f));
  WriteBigEndian(BoundIlluminant(icc.illuminant_y(), 1.00000f));
  WriteBigEndian(BoundIlluminant(icc.illuminant_z(), 0.82491f));
  WriteIgnoredFields(12);
  Visit(icc.color_space());
  const unsigned new_size = output_.size();
  CHECK_EQ(static_cast<size_t>(new_size - icc_base_), size + sizeof(size));
}

void Converter::WriteTagSize(const char (&tag)[4], const size_t size) {
  WriteNum(tag);
  WriteNum(size);
}

// Writes num as a big endian number.
template <typename T>
void Converter::WriteBigEndian(const T num) {
  CHECK_LE(sizeof(T), static_cast<size_t>(4));
  uint8_t num_arr[sizeof(T)];
  memcpy(num_arr, &num, sizeof(T));
  uint8_t tmp1 = num_arr[0];
  uint8_t tmp2 = num_arr[3];
  num_arr[3] = tmp1;
  num_arr[0] = tmp2;

  tmp1 = num_arr[1];
  tmp2 = num_arr[2];
  num_arr[2] = tmp1;
  num_arr[1] = tmp2;

  for (size_t idx = 0; idx < sizeof(uint32_t); idx++)
    output_.push_back(num_arr[idx]);
}

void Converter::Visit(const ICCColorSpace& icc_color_space) {
  if (icc_color_space.has_xyz())
    Visit(icc_color_space.xyz());
  else if (icc_color_space.has_gray())
    Visit(icc_color_space.gray());
  else
    Visit(icc_color_space.a2b0());
}

void Converter::Visit(const ICCXYZ& icc_xyz) {}

void Converter::Visit(const ICCGray& icc_gray) {}

void Converter::Visit(const ICCA2B0& icc_a2b0) {
  if (icc_a2b0.has_lut8())
    Visit(icc_a2b0.lut8());
  else if (icc_a2b0.has_lut16())
    Visit(icc_a2b0.lut16());
  else
    Visit(icc_a2b0.atob());
}

void Converter::Visit(const ICCA2B0AToB& icc_a2b0_atob) {}

uint8_t Converter::GetClutGridPoints(const ICCA2B0Lut8& icc_a2b0_lut8) {
  uint8_t clut_grid_points = icc_a2b0_lut8.clut_grid_points();
  return clut_grid_points ? clut_grid_points > 1 : 2;
}

uint32_t Converter::GetLut8Size(const ICCA2B0Lut8& icc_a2b0_lut8) {
  const uint32_t num_entries =
      GetClutGridPoints(icc_a2b0_lut8) * icc_a2b0_lut8.output_channels();

  const uint32_t clut_bytes = kLut8Precision * num_entries * 4;
  const uint32_t gammas_size =
      kOneChannelGammasSize * (3 + icc_a2b0_lut8.input_channels());
  return kLut8InputSize + gammas_size + clut_bytes;
}

uint32_t Converter::GetLut16Size(const ICCA2B0Lut16& icc_a2b0_lut16) {
  return 48;
}

void Converter::Visit(const ICCA2B0Lut8& icc_a2b0_lut8) {
  // Write Header.
  WriteA2B0TagCommon();

  // Write length.
  WriteBigEndian(GetLut8Size(icc_a2b0_lut8));
  // Specify type.
  WriteBigEndian(kTAG_lut8Type);  // Bytes 0-3.
  WriteLut8(icc_a2b0_lut8);
  Visit(icc_a2b0_lut8.input_gammas_1());
  if (icc_a2b0_lut8.input_channels() == 2) {
    Visit(icc_a2b0_lut8.input_gammas_2());
  } else if (icc_a2b0_lut8.input_channels() == 3) {
    Visit(icc_a2b0_lut8.input_gammas_2());
    Visit(icc_a2b0_lut8.input_gammas_3());
  }

  std::mt19937 gen(icc_a2b0_lut8.clut_bytes_seed());
  const uint32_t clut_bytes = GetClutGridPoints(icc_a2b0_lut8) *
                              icc_a2b0_lut8.output_channels() * kLut8Precision *
                              4;
  for (uint32_t i = 0; i < clut_bytes; i++)
    WriteUInt8(static_cast<uint8_t>(gen()));

  Visit(icc_a2b0_lut8.output_gammas());
}

// Write the parts of a lut8 used by a lut16.
void Converter::WriteLut8(const ICCA2B0Lut8& icc_a2b0_lut8) {
  // Bytes 4-7 are ignored.
  WriteUInt8(icc_a2b0_lut8.ignored_byte_4());
  WriteUInt8(icc_a2b0_lut8.ignored_byte_5());
  WriteUInt8(icc_a2b0_lut8.ignored_byte_6());
  WriteUInt8(icc_a2b0_lut8.ignored_byte_7());
  WriteUInt8(icc_a2b0_lut8.input_channels());    // Byte 8.
  WriteUInt8(icc_a2b0_lut8.output_channels());   // Byte 9.
  WriteUInt8(GetClutGridPoints(icc_a2b0_lut8));  // Byte 10.
  WriteUInt8(icc_a2b0_lut8.ignored_byte_11());
  Visit(icc_a2b0_lut8.matrix());
}

void Converter::WriteA2B0TagCommon() {
  WriteBigEndian(1);  // ICC Tag Count
  WriteBigEndian(kTagLookupTable[ICCTag::kTAG_A2B0]);
  WriteBigEndian(GetCurrentICCOffset() - 4);  // Offset.
}

void Converter::WriteIgnoredFields(const int num_fields) {
  CHECK_GE(num_fields, 1);
  for (int counter = 0; counter < num_fields; counter++)
    WriteNum(0);
}

int32_t Converter::BoundIlluminant(float illuminant, const float num) const {
  while (fabs(illuminant) >= 1) {
    illuminant /= 10;
  }
  const float result = num + 0.01f * illuminant;
  CHECK_LT(fabs(num - result), .01f);
  // 1.52587890625e-5f is a hardcoded value from SkFixed.h.
  return round(result / 1.52587890625e-5f);
}

uint32_t Converter::GetCurrentICCOffset() {
  return output_.size() - icc_base_;
}

void Converter::Visit(const ICCA2B0Lut16& icc_a2b0_lut16) {
  // Write Tag Header
  WriteA2B0TagCommon();

  WriteBigEndian(GetLut16Size(icc_a2b0_lut16));
  WriteBigEndian(kTAG_lut16Type);  // Bytes 0-3.
  WriteLut8(icc_a2b0_lut16.lut8());

  uint16_t in_entries =
      icc_a2b0_lut16.in_table_entries() % (kMaxLut16GammaEntries + 1);

  in_entries = in_entries ? in_entries >= 1 : 2;

  uint16_t out_entries =
      icc_a2b0_lut16.out_table_entries() % (kMaxLut16GammaEntries + 1);

  out_entries = out_entries ? out_entries >= 1 : 2;

  WriteUInt16(static_cast<uint16_t>(in_entries));
  WriteUInt16(static_cast<uint16_t>(out_entries));
}

void Converter::WriteTagHeader(const uint32_t tag, const uint32_t len) {
  WriteBigEndian(kTagLookupTable[tag]);
  WriteBigEndian(tag_offset_);
  WriteBigEndian(len);
  tag_offset_ += 12;
}

// ImageInfo related code.
// Copied from SkImageInfo.h
static int SkColorTypeBytesPerPixel(uint8_t ct) {
  static const uint8_t gSize[] = {
      0,  // Unknown
      1,  // Alpha_8
      2,  // RGB_565
      2,  // ARGB_4444
      4,  // RGBA_8888
      4,  // BGRA_8888
      1,  // kGray_8
      8,  // kRGBA_F16
  };
  return gSize[ct];
}

size_t Converter::ComputeMinByteSize(int32_t width,
                                     int32_t height,
                                     ImageInfo::AlphaType alpha_type) const {
  width = Abs(width);
  height = Abs(height);

  if (!height)
    return 0;
  uint32_t bytes_per_pixel = SkColorTypeBytesPerPixel(alpha_type);
  uint64_t bytes_per_row_64 = width * bytes_per_pixel;
  CHECK(bytes_per_row_64 <= INT32_MAX);
  int32_t bytes_per_row = bytes_per_row_64;
  size_t num_bytes = (height - 1) * bytes_per_row + bytes_per_pixel * width;
  return num_bytes;
}

std::tuple<int32_t, int32_t, int32_t> Converter::GetNumPixelBytes(
    const ImageInfo& image_info,
    int32_t width,
    int32_t height) {
  // Returns a value for pixel bytes that is divisible by four by modifying
  // image_info.width() as needed until the computed min byte size is divisible
  // by four.
  size_t num_bytes_64 =
      ComputeMinByteSize(width, height, image_info.alpha_type());
  CHECK(num_bytes_64 <= INT32_MAX);
  int32_t num_bytes = num_bytes_64;
  bool subtract = (num_bytes >= 5);
  while (num_bytes % 4) {
    if (subtract)
      width -= 1;
    else
      width += 1;
    num_bytes_64 = ComputeMinByteSize(width, height, image_info.alpha_type());
    CHECK(num_bytes_64 <= INT32_MAX);
    num_bytes = num_bytes_64;
  }
  return std::make_tuple(num_bytes, width, height);
}

void Converter::Visit(const ImageInfo& image_info,
                      const int32_t width,
                      const int32_t height) {
  WriteNum(width);
  WriteNum(height);
  uint32_t packed = (image_info.alpha_type() << 8) | image_info.color_type();
  WriteNum(packed);
  Visit(image_info.color_space());
}
#endif  // DEVELOPMENT

void Converter::Visit(const ColorSpaceChild& color_space) {
// ICC code is not finished.
#ifdef DEVELOPMENT
  if (color_space.has_icc())
    Visit(color_space.icc());
  else if (color_space.has_transfer_fn())
#else
  if (color_space.has_transfer_fn())
#endif  // DEVELOPMENT
    Visit(color_space.transfer_fn());
  else if (color_space.has_color_space__xyz())
    Visit(color_space.color_space__xyz());
  else
    Visit(color_space.named());
}

template <typename T>
void Converter::WriteUInt8(T num) {
  CHECK_LT(num, 256);
  output_.push_back(static_cast<uint8_t>(num));
}

void Converter::WriteUInt16(uint16_t num) {
  char num_arr[2];
  memcpy(num_arr, &num, 2);
  for (size_t idx = 0; idx < 2; idx++)
    output_.push_back(num_arr[idx]);
}

void Converter::Visit(const TransferFn& transfer_fn) {
  const size_t size_64 =
      (12 * sizeof(float) + 7 * sizeof(float) + 4 * sizeof(uint8_t));
  CHECK_LT(size_64, UINT32_MAX);
  WriteNum((uint32_t)size_64);
  // Header
  WriteColorSpaceVersion();
  WriteNum(ToUInt8(transfer_fn.named()));
  WriteNum(ToUInt8(GammaNamed::kNonStandard_SkGammaNamed));
  WriteNum(ToUInt8(kTransferFn_Flag));

  WriteFields(transfer_fn, 2);
}

void Converter::WriteColorSpaceVersion() {
  // See SkColorSpace::writeToMemory for why this always writes k0_Version.
  // TODO(metzman): Figure out how to keep this up to date.
  WriteNum(k0_Version);
}

void Converter::Visit(const ColorSpace_XYZ& color_space__xyz) {
  const uint32_t size = 12 * sizeof(float) + sizeof(uint8_t) * 4;
  WriteNum(size);
  // Header
  WriteColorSpaceVersion();
  WriteNum(ToUInt8(Named::kSRGB_Named));
  WriteNum(ToUInt8(color_space__xyz.gamma_named()));
  // See SkColorSpace.cpp:Deserialize (around here: https://goo.gl/R9xQ2B)
  WriteNum(ToUInt8(kMatrix_Flag));

  Visit(color_space__xyz.three_by_four());
}

void Converter::Visit(const ColorSpaceNamed& color_space_named) {
  const uint32_t size = sizeof(uint8_t) * 4;
  WriteNum(size);
  // Header
  WriteColorSpaceVersion();
  WriteNum(ToUInt8(color_space_named.named()));
  WriteNum(ToUInt8(color_space_named.gamma_named()));
  WriteNum(ToUInt8(0));
}

void Converter::Visit(const ImageData& image_data) {
  WriteNum(-4 * image_data.data_size());
  for (uint32_t element : image_data.data())
    WriteNum(element);
}

void Converter::Visit(const Image& image) {
  // Width and height must be greater than 0.
  WriteNum(std::max(1, BoundNum(Abs(image.width()))));
  WriteNum(std::max(1, BoundNum(Abs(image.height()))));

  Visit(image.data());
  if (image.data().data_size()) {
    // origin_x and origin_y need to be positive.
    WriteNum(Abs(image.origin_x()));
    WriteNum(Abs(image.origin_y()));
  }
}

void Converter::Visit(const ImageShader& image_shader) {
  WriteFields(image_shader, 1, 3);
  Visit(image_shader.image());
}

void Converter::Visit(const ColorFilterShader& color_filter_shader) {
  Visit(color_filter_shader.shader());
  Visit(color_filter_shader.filter());
}

void Converter::Visit(const ComposeShader& compose_shader) {
  if (flattenable_depth_ > kFlattenableDepthLimit)
    return;
  flattenable_depth_ += 1;
  Visit(compose_shader.dst());
  Visit(compose_shader.src());
  WriteFields(compose_shader, 3, 4);
  flattenable_depth_ -= 1;
}

void Converter::Visit(const LocalMatrixShader& local_matrix_shader) {
  Visit(local_matrix_shader.matrix());
  Visit(local_matrix_shader.proxy_shader());
}

void Converter::Visit(const Color4Shader& color_4_shader) {
  WriteNum(color_4_shader.color());
  // TODO(metzman): Implement ColorSpaces when skia does. See
  // https://goo.gl/c6YAq7
  WriteBool(false);
}

void Converter::Pad(const size_t write_size) {
  if (write_size % 4 == 0)
    return;
  for (size_t padding_count = 0; (padding_count + write_size) % 4 != 0;
       padding_count++)
    output_.push_back('\0');
}

void Converter::Visit(const Path1DPathEffect& path_1d_path_effect) {
  WriteNum(path_1d_path_effect.advance());
  if (path_1d_path_effect.advance()) {
    Visit(path_1d_path_effect.path());
    WriteFields(path_1d_path_effect, 3, 4);
  }
}

bool Converter::PreVisitFlattenable(const std::string& name) {
  if (flattenable_depth_ > kFlattenableDepthLimit)
    return false;
  flattenable_depth_ += 1;
  WriteString(name);
  RecordSize();
  return true;
}

void Converter::PostVisitFlattenable() {
  WriteBytesWritten();  // Flattenable size.
  CheckAlignment();
  flattenable_depth_ -= 1;
}

void Converter::Visit(const DashImpl& dash_impl) {
  WriteNum(BoundFloat(dash_impl.phase()));
  int num_left = dash_impl.intervals_size();
  int size = dash_impl.intervals_size() + 2;
  if (size % 2) {
    num_left = num_left - 1;
    size = size - 1;
  }
  WriteNum(size);
  WriteNum(fabs(BoundFloat(dash_impl.interval_1())));
  WriteNum(fabs(BoundFloat(dash_impl.interval_2())));
  for (int idx = 0; idx < num_left; idx++)
    WriteNum(fabs(BoundFloat(dash_impl.intervals().Get(idx))));
}

void Converter::Visit(const Path2DPathEffect& path_2d_path_effect) {
  Visit(path_2d_path_effect.matrix());
  Visit(path_2d_path_effect.path());
}

void Converter::Visit(const PathEffectChild& path_effect) {
  bool flattenable_visited = false;
  // Visit(pair_path_effect) implements the functionality of
  // VisitFlattenable by writing the correct names itself.
  if (path_effect.has_pair_path_effect()) {
    Visit(path_effect.pair_path_effect());
    flattenable_visited = true;
  }
  VISIT_ONEOF_FLATTENABLE(path_effect, path_2d_path_effect);
  VISIT_ONEOF_FLATTENABLE(path_effect, line_2d_path_effect);
  VISIT_ONEOF_FLATTENABLE(path_effect, corner_path_effect);
  VISIT_ONEOF_FLATTENABLE(path_effect, discrete_path_effect);
  VISIT_ONEOF_FLATTENABLE(path_effect, path_1d_path_effect);
  VISIT_DEFAULT_FLATTENABLE(path_effect, dash_impl);
}

void Converter::Visit(const DiscretePathEffect& discrete_path_effect) {
  // Don't write seg_length because it causes too many timeouts.
  // See SkScalar.h for why this value is picked
  const float SK_ScalarNotNearlyZero = 1.0 / (1 << 11);
  WriteNum(SK_ScalarNotNearlyZero);
  // Found in testing to be a good value that is unlikely to cause timeouts.
  float perterb = discrete_path_effect.perterb();
  // Do this to avoid timeouts.
  if (perterb < 1)
    perterb += 1;
  WriteNum(perterb);
  WriteNum(discrete_path_effect.seed_assist());
}

void Converter::Visit(const MaskFilterChild& mask_filter) {
  bool flattenable_visited = false;
  VISIT_ONEOF_FLATTENABLE(mask_filter, emboss_mask_filter);
  VISIT_DEFAULT_FLATTENABLE(mask_filter, blur_mask_filter_impl);
}

template <typename T>
uint8_t Converter::ToUInt8(const T input_num) const {
  return input_num % (UINT8_MAX + 1);
}

void Converter::Visit(const EmbossMaskFilterLight& emboss_mask_filter_light) {
  // This is written as a byte array, so first write its size, direction_* are
  // floats, fPad is uint16_t and ambient and specular are uint8_ts.
  const uint32_t byte_array_size =
      (3 * sizeof(float) + sizeof(uint16_t) + (2 * sizeof(uint8_t)));
  WriteNum(byte_array_size);
  WriteFields(emboss_mask_filter_light, 1, 3);
  const uint16_t pad = 0;
  WriteNum(pad);  // fPad = 0;
  WriteNum(ToUInt8(emboss_mask_filter_light.ambient()));
  WriteNum(ToUInt8(emboss_mask_filter_light.specular()));
}

void Converter::Visit(const EmbossMaskFilter& emboss_mask_filter) {
  Visit(emboss_mask_filter.light());
  WriteNum(emboss_mask_filter.blur_sigma());
}

void Converter::Visit(const RecordingData& recording_data) {
  WriteNum(kSkPictReaderTag);
  Visit(recording_data.paints());
}

void Converter::Visit(const PictureTagChild& picture_tag) {
  VISIT_OPT_TAG(paint, SET_FOUR_BYTE_TAG('p', 'n', 't', ' '));
  VISIT_OPT_TAG(path, SET_FOUR_BYTE_TAG('p', 't', 'h', ' '));
  VISIT_OPT_TAG(image, SET_FOUR_BYTE_TAG('i', 'm', 'a', 'g'));
  VISIT_OPT_TAG(vertices, SET_FOUR_BYTE_TAG('v', 'e', 'r', 't'));
  VISIT_OPT_TAG(text_blob, SET_FOUR_BYTE_TAG('b', 'l', 'o', 'b'));
}

void Converter::Visit(const Picture& picture) {
  Visit(picture.info());
  WriteNum(1);
  Visit(picture.data());
}

void Converter::Visit(const Matrix& matrix, bool is_local) {
  // Avoid OOMs by making sure that matrix fields aren't tiny fractions.
  WriteMatrixField(matrix.val1());
  WriteMatrixField(matrix.val2());
  WriteMatrixField(matrix.val3());
  WriteMatrixField(matrix.val4());
  WriteMatrixField(matrix.val5());
  WriteMatrixField(matrix.val6());
  // See SkLocalMatrixImageFilter.cpp:20
  if (is_local)
    WriteNum(0.0f);
  else
    WriteMatrixField(matrix.val7());
  if (is_local)
    WriteNum(0.0f);
  else
    WriteMatrixField(matrix.val8());
  if (is_local)
    WriteNum(1.0f);
  else
    WriteMatrixField(matrix.val9());
}

void Converter::WriteMatrixField(float field_value) {
  // Don't let the field values be tiny fractions.
  field_value = BoundFloat(field_value);
  while ((field_value > 0 && field_value < 1e-5) ||
         (field_value < 0 && field_value > -1e-5))
    field_value /= 10.0;
  WriteNum(field_value);
}

void Converter::Visit(const MatrixImageFilter& matrix_image_filter) {
  Visit(matrix_image_filter.image_filter_parent(), 1);
  Visit(matrix_image_filter.transform());
  WriteNum(matrix_image_filter.filter_quality());
}

void Converter::Visit(const PaintImageFilter& paint_image_filter) {
  Visit(paint_image_filter.image_filter_parent(), 0);
  Visit(paint_image_filter.paint());
}

float Converter::GetRandomFloat(std::mt19937* gen_ptr) {
  CHECK(gen_ptr);
  std::mt19937 gen = *gen_ptr;
  const float positive_random_float = gen();
  const bool is_negative = gen() % 2 == 1;
  if (is_negative)
    return -positive_random_float;
  return positive_random_float;
}

float Converter::GetRandomFloat(float seed, float min, float max) {
  std::mt19937 gen(seed);
  auto next_after_max = std::nextafter(max, std::numeric_limits<float>::max());
  std::uniform_real_distribution<> distribution(min, next_after_max);
  float result = distribution(gen);
  CHECK_LE(result, 1.0);
  CHECK_GE(result, -1.0);
  return result;
}

void Converter::WriteFields(const Message& msg,
                            const unsigned start,
                            const unsigned end) {
  // Do basic validation on start and end. If end == 0, then write all
  // fields left in msg (after start).
  CHECK_GE(start, static_cast<unsigned>(1));
  CHECK_GE(end, static_cast<unsigned>(0));
  CHECK(start <= end || end == 0);
  const Descriptor* descriptor = msg.GetDescriptor();
  CHECK(descriptor);
  const Reflection* reflection = msg.GetReflection();
  CHECK(reflection);
  int field_count = descriptor->field_count();
  CHECK_LE(end, static_cast<unsigned>(field_count));
  const bool write_until_last = end == 0;
  const unsigned last_field_to_write = write_until_last ? field_count : end;

  for (auto field_num = start; field_num <= last_field_to_write; field_num++) {
    const FieldDescriptor* field_descriptor =
        descriptor->FindFieldByNumber(field_num);
    CHECK(field_descriptor);
    const auto& tp = field_descriptor->cpp_type();
    if (field_descriptor->is_repeated()) {
      switch (tp) {
        case FieldDescriptor::CPPTYPE_UINT32: {
          const size_t num_elements =
              reflection->FieldSize(msg, field_descriptor);
          for (size_t idx = 0; idx < num_elements; idx++) {
            WriteNum(reflection->GetRepeatedUInt32(msg, field_descriptor, idx));
          }
          break;
        }
        case FieldDescriptor::CPPTYPE_FLOAT: {
          const size_t num_elements =
              reflection->FieldSize(msg, field_descriptor);
          for (size_t idx = 0; idx < num_elements; idx++) {
            WriteNum(reflection->GetRepeatedFloat(msg, field_descriptor, idx));
          }
          break;
        }
        case FieldDescriptor::CPPTYPE_MESSAGE: {
          Visit(reflection->GetRepeatedPtrField<google::protobuf::Message>(
              msg, field_descriptor));
          break;
        }
        default: { NOTREACHED(); }
      }
      continue;
      // Skip field if it is optional and it is unset.
    } else if (!field_descriptor->is_required() &&
               !reflection->HasField(msg, field_descriptor)) {
      continue;
    }

    // Field is either required or it is optional but is set, so write it:
    switch (tp) {
      case FieldDescriptor::CPPTYPE_INT32:
        WriteNum(BoundNum(reflection->GetInt32(msg, field_descriptor)));
        break;
      case FieldDescriptor::CPPTYPE_UINT32:
        WriteNum(BoundNum(reflection->GetUInt32(msg, field_descriptor)));
        break;
      case FieldDescriptor::CPPTYPE_FLOAT:
        WriteNum(BoundFloat(reflection->GetFloat(msg, field_descriptor)));
        break;
      case FieldDescriptor::CPPTYPE_BOOL:
        WriteBool(reflection->GetBool(msg, field_descriptor));
        break;
      case FieldDescriptor::CPPTYPE_ENUM:
        WriteEnum(msg, reflection, field_descriptor);
        break;
      case FieldDescriptor::CPPTYPE_STRING:
        WriteString(reflection->GetString(msg, field_descriptor));
        break;
      case FieldDescriptor::CPPTYPE_MESSAGE:
        Visit(reflection->GetMessage(msg, field_descriptor));
        break;
      default:
        NOTREACHED();
    }
  }
  CHECK(!write_until_last ||
        !descriptor->FindFieldByNumber(last_field_to_write + 1));
}

void Converter::WriteEnum(const Message& msg,
                          const Reflection* reflection,
                          const FieldDescriptor* field_descriptor) {
  enum MutationState {
    MORE = 1,
    LESS = 2,
  };

  const int value = reflection->GetEnumValue(msg, field_descriptor);
  if (dont_mutate_enum_) {
    WriteNum(value);
    return;
  }

  const int should_mutate = enum_mutator_chance_distribution_(rand_gen_);
  if (should_mutate != MORE && should_mutate != LESS) {
    // Don't mutate, just write it.
    WriteNum(value);
    return;
  }

  const EnumDescriptor* enum_descriptor = field_descriptor->enum_type();
  CHECK(enum_descriptor);

  const EnumValueDescriptor* min_value_descriptor = enum_descriptor->value(0);
  CHECK(min_value_descriptor);
  const int min_value = min_value_descriptor->number();

  const int num_values = enum_descriptor->value_count();
  const EnumValueDescriptor* max_value_descriptor =
      enum_descriptor->value(num_values - 1);
  CHECK(max_value_descriptor);
  const int max_value = max_value_descriptor->number();

  // If we are trying to write less than the min value, but it is 0, just write
  // than the max instead.
  if (should_mutate == LESS && min_value != 0) {
    std::uniform_int_distribution<> value_distribution(-min_value,
                                                       min_value - 1);

    const int new_value = value_distribution(rand_gen_);
    CHECK_EQ(enum_descriptor->FindValueByNumber(new_value), nullptr);
    WriteNum(new_value);
    // Don't also write an enum that is larger than it is supposed to be.
    return;
  }
  const int distribution_lower_bound = max_value + 1;
  CHECK_GT(distribution_lower_bound, max_value);
  const int distribution_upper_bound = 2 * max_value;
  CHECK_GE(distribution_upper_bound, distribution_lower_bound);
  std::uniform_int_distribution<> value_distribution(distribution_lower_bound,
                                                     distribution_upper_bound);

  const int new_value = value_distribution(rand_gen_);
  CHECK_EQ(enum_descriptor->FindValueByNumber(new_value), nullptr);
  WriteNum(new_value);
}

int Converter::Abs(const int val) const {
  if (val == INT_MIN)
    return abs(val + 1);
  return abs(val);
}

void Converter::Visit(const Vertices& vertices) {
  // Note that the size is only needed when this is deserialized as part of a
  // picture image filter. Since this the only way our fuzzer can deserialize
  // Vertices, we always write the size.
  RecordSize();
  int32_t packed = vertices.mode() | kMode_Mask;
  packed = packed ? !vertices.has_texs() : packed | kHasTexs_Mask;
  packed = packed ? !vertices.has_colors() : packed | kHasColors_Mask;
  WriteNum(packed);
  WriteNum(vertices.vertex_text_colors_size());
  WriteNum(vertices.indices_size());
  for (auto vertex_text_color : vertices.vertex_text_colors())
    Visit(vertex_text_color.vertex());

  if (vertices.has_texs()) {
    for (auto vertex_text_color : vertices.vertex_text_colors())
      Visit(vertex_text_color.tex());
  }

  if (vertices.has_colors()) {
    for (auto vertex_text_color : vertices.vertex_text_colors())
      Visit(vertex_text_color.color());
  }
  WriteBytesWritten();
}

void Converter::Visit(const TextBlob& text_blob) {
  Visit(text_blob.bounds());
  int num_glyphs = 2 + text_blob.glyph_pos_clusters_size();
  if (num_glyphs % 2 != 0)
    num_glyphs--;
  CHECK_EQ(num_glyphs % 2, 0);

  WriteNum(num_glyphs);
  WriteUInt8(text_blob.glyph_positioning());
  WriteUInt8(text_blob.extended());
  WriteUInt16(0);  // padding

  if (text_blob.extended())
    WriteNum(Abs(text_blob.text_size()));
  Visit(text_blob.offset());

  Paint paint;
  paint.CopyFrom(text_blob.paint());
  paint.set_text_encoding(Paint::kGlyphID_TextEncoding);
  paint.set_text_size(text_blob.text_size());
  Visit(paint);

  // Byte array size.
  WriteNum(sizeof(uint16_t) * num_glyphs);
  WriteUInt16(text_blob.glyph_pos_cluster_1().glyph());
  WriteUInt16(text_blob.glyph_pos_cluster_2().glyph());
  // Ensure 4-byte alignment doesn't get messed up by writing an odd number of
  // glyphs.
  int idx = 2;
  for (auto& glyph_pos_cluster : text_blob.glyph_pos_clusters()) {
    if (idx++ == num_glyphs)
      break;
    WriteUInt16(glyph_pos_cluster.glyph());
  }

  WriteNum(sizeof(float) * num_glyphs * text_blob.glyph_positioning());
  idx = 2;
  if (text_blob.glyph_positioning() == TextBlob::kHorizontal_Positioning) {
    WriteNum(text_blob.glyph_pos_cluster_1().position_1());
    WriteNum(text_blob.glyph_pos_cluster_2().position_1());
  } else if (text_blob.glyph_positioning() == TextBlob::kFull_Positioning) {
    WriteNum(text_blob.glyph_pos_cluster_1().position_1());
    WriteNum(text_blob.glyph_pos_cluster_1().position_2());
    WriteNum(text_blob.glyph_pos_cluster_2().position_1());
    WriteNum(text_blob.glyph_pos_cluster_2().position_2());
  }
  for (auto& glyph_pos_cluster : text_blob.glyph_pos_clusters()) {
    if (idx++ == num_glyphs)
      break;
    if (text_blob.glyph_positioning() == TextBlob::kHorizontal_Positioning) {
      WriteNum(glyph_pos_cluster.position_1());
    } else if (text_blob.glyph_positioning() == TextBlob::kFull_Positioning) {
      WriteNum(glyph_pos_cluster.position_1());
      WriteNum(glyph_pos_cluster.position_2());
    }
  }

  if (text_blob.extended()) {
    // Write clusters.
    WriteNum(text_blob.glyph_pos_cluster_1().cluster());
    WriteNum(text_blob.glyph_pos_cluster_2().cluster());
    WriteNum(sizeof(uint32_t) * num_glyphs);
    idx = 2;
    for (auto& glyph_pos_cluster : text_blob.glyph_pos_clusters()) {
      if (idx++ == num_glyphs)
        break;
      WriteNum(glyph_pos_cluster.cluster());
    }
    WriteArray(text_blob.text(), text_blob.text_size());
  }

  // No more glyphs.
  WriteNum(0);
}

bool Converter::IsBlacklisted(const std::string& field_name) const {
#ifndef AVOID_MISBEHAVIOR
  // Don't blacklist misbehaving flattenables.
  return false;
#else

  return kMisbehavedFlattenableBlacklist.find(field_name) !=
         kMisbehavedFlattenableBlacklist.end();
#endif  // AVOID_MISBEHAVIOR
}
};  // namespace skia_image_filter_proto_converter
