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

#include "lib/image-format/image_format.h"

#include <fuchsia/sysmem/c/fidl.h>
#include <fuchsia/sysmem2/llcpp/fidl.h>
#include <lib/sysmem-version/sysmem-version.h>
#include <zircon/assert.h>
#include <zircon/pixelformat.h>

#include <algorithm>
#include <map>
#include <set>

#include <fbl/algorithm.h>

namespace {

using ColorSpace = fuchsia_sysmem2::wire::ColorSpace;
using ColorSpaceType = fuchsia_sysmem2::wire::ColorSpaceType;
using ImageFormat = fuchsia_sysmem2::wire::ImageFormat;
using ImageFormatConstraints = fuchsia_sysmem2::wire::ImageFormatConstraints;
using PixelFormat = fuchsia_sysmem2::wire::PixelFormat;
using PixelFormatType = fuchsia_sysmem2::wire::PixelFormatType;

// There are two aspects of the ColorSpace and PixelFormat that we care about:
//   * bits-per-sample - bits per primary sample (R, G, B, or Y)
//   * RGB vs. YUV - whether the system supports the ColorSpace or PixelFormat
//     representing RGB data or YUV data.  Any given ColorSpace only supports
//     one or the other. Currently any given PixelFormat only supports one or
//     the other and this isn't likely to change.
// While we could just list all the ColorSpace(s) that each PixelFormat could
// plausibly support, expressing in terms of bits-per-sample and RGB vs. YUV is
// perhaps easier to grok.

enum ColorType { kColorType_NONE, kColorType_RGB, kColorType_YUV };

struct SamplingInfo {
  std::set<uint32_t> possible_bits_per_sample;
  ColorType color_type;
};

const std::map<ColorSpaceType, SamplingInfo> kColorSpaceSamplingInfo = {
    {ColorSpaceType::kSrgb, {{8, 10, 12, 16}, kColorType_RGB}},
    {ColorSpaceType::kRec601Ntsc, {{8, 10}, kColorType_YUV}},
    {ColorSpaceType::kRec601NtscFullRange, {{8, 10}, kColorType_YUV}},
    {ColorSpaceType::kRec601Pal, {{8, 10}, kColorType_YUV}},
    {ColorSpaceType::kRec601PalFullRange, {{8, 10}, kColorType_YUV}},
    {ColorSpaceType::kRec709, {{8, 10}, kColorType_YUV}},
    {ColorSpaceType::kRec2020, {{10, 12}, kColorType_YUV}},
    {ColorSpaceType::kRec2100, {{10, 12}, kColorType_YUV}},
};
const std::map<PixelFormatType, SamplingInfo> kPixelFormatSamplingInfo = {
    {PixelFormatType::kR8G8B8A8, {{8}, kColorType_RGB}},
    {PixelFormatType::kBgra32, {{8}, kColorType_RGB}},
    {PixelFormatType::kI420, {{8}, kColorType_YUV}},
    {PixelFormatType::kM420, {{8}, kColorType_YUV}},
    {PixelFormatType::kNv12, {{8}, kColorType_YUV}},
    {PixelFormatType::kYuy2, {{8}, kColorType_YUV}},
    // 8 bits RGB when uncompressed - in this context, MJPEG is essentially
    // pretending to be uncompressed.
    {PixelFormatType::kMjpeg, {{8}, kColorType_RGB}},
    {PixelFormatType::kYv12, {{8}, kColorType_YUV}},
    {PixelFormatType::kBgr24, {{8}, kColorType_RGB}},

    // These use the same colorspaces as regular 8-bit-per-component formats
    {PixelFormatType::kRgb565, {{8}, kColorType_RGB}},
    {PixelFormatType::kRgb332, {{8}, kColorType_RGB}},
    {PixelFormatType::kRgb2220, {{8}, kColorType_RGB}},
    // Expands to RGB
    {PixelFormatType::kL8, {{8}, kColorType_RGB}},
    {PixelFormatType::kR8, {{8}, kColorType_RGB}},
    {PixelFormatType::kR8G8, {{8}, kColorType_RGB}},
    {PixelFormatType::kA2B10G10R10, {{8}, kColorType_RGB}},
    {PixelFormatType::kA2R10G10B10, {{8}, kColorType_RGB}},
};

constexpr uint32_t kTransactionEliminationAlignment = 64;
// The transaction elimination buffer is always reported as plane 3.
constexpr uint32_t kTransactionEliminationPlane = 3;

static uint64_t arm_transaction_elimination_row_size(uint32_t width) {
  uint32_t kTileSize = 32;
  uint32_t kBytesPerTilePerRow = 16;
  uint32_t width_in_tiles = fbl::round_up(width, kTileSize) / kTileSize;
  return fbl::round_up(width_in_tiles * kBytesPerTilePerRow, kTransactionEliminationAlignment);
}

static uint64_t arm_transaction_elimination_buffer_size(uint64_t start, uint32_t width,
                                                        uint32_t height) {
  uint32_t kTileSize = 32;
  uint32_t end = start;
  end = fbl::round_up(end, kTransactionEliminationAlignment);
  uint32_t kHeaderSize = kTransactionEliminationAlignment;
  end += kHeaderSize;
  uint32_t height_in_tiles = fbl::round_up(height, kTileSize) / kTileSize;
  end += arm_transaction_elimination_row_size(width) * 2 * height_in_tiles;
  return end - start;
}

class ImageFormatSet {
 public:
  virtual const char* Name() const = 0;
  virtual bool IsSupported(const PixelFormat& pixel_format) const = 0;
  virtual uint64_t ImageFormatImageSize(const ImageFormat& image_format) const = 0;
  virtual bool ImageFormatPlaneByteOffset(const ImageFormat& image_format, uint32_t plane,
                                          uint64_t* offset_out) const = 0;
  virtual bool ImageFormatPlaneRowBytes(const ImageFormat& image_format, uint32_t plane,
                                        uint32_t* row_bytes_out) const = 0;
};

class IntelTiledFormats : public ImageFormatSet {
 public:
  const char* Name() const override { return "IntelTiledFormats"; }

  bool IsSupported(const PixelFormat& pixel_format) const override {
    if (!pixel_format.has_type())
      return false;
    if (!pixel_format.has_format_modifier_value())
      return false;
    if (pixel_format.type() != PixelFormatType::kR8G8B8A8 &&
        pixel_format.type() != PixelFormatType::kBgra32) {
      return false;
    }
    switch (pixel_format.format_modifier_value()) {
      case fuchsia_sysmem2::wire::kFormatModifierIntelI915XTiled:
      case fuchsia_sysmem2::wire::kFormatModifierIntelI915YTiled:
      case fuchsia_sysmem2::wire::kFormatModifierIntelI915YfTiled:
        return true;
      default:
        return false;
    }
  }
  uint64_t ImageFormatImageSize(const ImageFormat& image_format) const override {
    // See
    // https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-skl-vol05-memory_views.pdf
    constexpr uint32_t kIntelTileByteSize = 4096;
    constexpr uint32_t kIntelYTilePixelWidth = 32;
    constexpr uint32_t kIntelYTileHeight = 4096 / (kIntelYTilePixelWidth * 4);
    constexpr uint32_t kIntelXTilePixelWidth = 128;
    constexpr uint32_t kIntelXTileHeight = 4096 / (kIntelXTilePixelWidth * 4);
    constexpr uint32_t kIntelYFTilePixelWidth = 32;  // For a 4 byte per component format
    constexpr uint32_t kIntelYFTileHeight = 4096 / (kIntelYFTilePixelWidth * 4);
    ZX_DEBUG_ASSERT(IsSupported(image_format.pixel_format()));
    switch (image_format.pixel_format().format_modifier_value()) {
      case fuchsia_sysmem2::wire::kFormatModifierIntelI915XTiled:
        return fbl::round_up(image_format.coded_width(), kIntelXTilePixelWidth) /
               kIntelXTilePixelWidth *
               fbl::round_up(image_format.coded_height(), kIntelXTileHeight) / kIntelXTileHeight *
               kIntelTileByteSize;

      case fuchsia_sysmem2::wire::kFormatModifierIntelI915YTiled:
        return fbl::round_up(image_format.coded_width(), kIntelYTilePixelWidth) /
               kIntelYTilePixelWidth *
               fbl::round_up(image_format.coded_height(), kIntelYTileHeight) / kIntelYTileHeight *
               kIntelTileByteSize;

      case fuchsia_sysmem2::wire::kFormatModifierIntelI915YfTiled:
        return fbl::round_up(image_format.coded_width(), kIntelYFTilePixelWidth) /
               kIntelYFTilePixelWidth *
               fbl::round_up(image_format.coded_height(), kIntelYFTileHeight) / kIntelYFTileHeight *
               kIntelTileByteSize;
      default:
        return 0u;
    }
  }
  bool ImageFormatPlaneByteOffset(const ImageFormat& image_format, uint32_t plane,
                                  uint64_t* offset_out) const override {
    ZX_DEBUG_ASSERT(IsSupported(image_format.pixel_format()));
    if (plane == 0) {
      *offset_out = 0;
      return true;
    }
    return false;
  }
  bool ImageFormatPlaneRowBytes(const ImageFormat& image_format, uint32_t plane,
                                uint32_t* row_bytes_out) const override {
    if (plane == 0) {
      *row_bytes_out = 0;
      return true;
    } else {
      return false;
    }
  }
};
class AfbcFormats : public ImageFormatSet {
 public:
  const char* Name() const override { return "AfbcFormats"; }

  static constexpr uint64_t kAfbcModifierMask =
      fuchsia_sysmem2::wire::kFormatModifierArmTeBit |
      fuchsia_sysmem2::wire::kFormatModifierArmSplitBlockBit |
      fuchsia_sysmem2::wire::kFormatModifierArmSparseBit |
      fuchsia_sysmem2::wire::kFormatModifierArmYuvBit |
      fuchsia_sysmem2::wire::kFormatModifierArmBchBit |
      fuchsia_sysmem2::wire::kFormatModifierArmTiledHeaderBit;
  bool IsSupported(const PixelFormat& pixel_format) const override {
    if (!pixel_format.has_format_modifier_value())
      return false;
    if (!pixel_format.has_type())
      return false;
    if (pixel_format.type() != PixelFormatType::kR8G8B8A8 &&
        pixel_format.type() != PixelFormatType::kBgra32) {
      return false;
    }
    switch (pixel_format.format_modifier_value() & ~kAfbcModifierMask) {
      case fuchsia_sysmem2::wire::kFormatModifierArmAfbc16X16:
      case fuchsia_sysmem2::wire::kFormatModifierArmAfbc32X8:
        return true;
      default:
        return false;
    }
  }

  // Calculate the size of the Raw AFBC image without a transaction elimination buffer.
  uint64_t NonTESize(const ImageFormat& image_format) const {
    // See
    // https://android.googlesource.com/device/linaro/hikey/+/android-o-preview-3/gralloc960/alloc_device.cpp
    constexpr uint32_t kAfbcBodyAlignment = 1024u;
    constexpr uint32_t kTiledAfbcBodyAlignment = 4096u;

    ZX_DEBUG_ASSERT(image_format.has_pixel_format());
    ZX_DEBUG_ASSERT(IsSupported(image_format.pixel_format()));
    uint32_t block_width;
    uint32_t block_height;
    uint32_t width_alignment;
    uint32_t height_alignment;
    bool tiled_header = image_format.pixel_format().format_modifier_value() &
                        fuchsia_sysmem2::wire::kFormatModifierArmTiledHeaderBit;

    switch (image_format.pixel_format().format_modifier_value() & ~kAfbcModifierMask) {
      case fuchsia_sysmem2::wire::kFormatModifierArmAfbc16X16:
        block_width = 16;
        block_height = 16;
        if (!tiled_header) {
          width_alignment = block_width;
          height_alignment = block_height;
        } else {
          width_alignment = 128;
          height_alignment = 128;
        }
        break;

      case fuchsia_sysmem2::wire::kFormatModifierArmAfbc32X8:
        block_width = 32;
        block_height = 8;
        if (!tiled_header) {
          width_alignment = block_width;
          height_alignment = block_height;
        } else {
          width_alignment = 256;
          height_alignment = 64;
        }
        break;
      default:
        return 0;
    }

    uint32_t body_alignment = tiled_header ? kTiledAfbcBodyAlignment : kAfbcBodyAlignment;

    ZX_DEBUG_ASSERT(image_format.pixel_format().has_type());
    ZX_DEBUG_ASSERT(image_format.pixel_format().type() == PixelFormatType::kR8G8B8A8 ||
                    image_format.pixel_format().type() == PixelFormatType::kBgra32);
    constexpr uint32_t kBytesPerPixel = 4;
    constexpr uint32_t kBytesPerBlockHeader = 16;

    ZX_DEBUG_ASSERT(image_format.has_coded_width());
    ZX_DEBUG_ASSERT(image_format.has_coded_height());
    uint64_t block_count =
        fbl::round_up(image_format.coded_width(), width_alignment) / block_width *
        fbl::round_up(image_format.coded_height(), height_alignment) / block_height;
    return block_count * block_width * block_height * kBytesPerPixel +
           fbl::round_up(block_count * kBytesPerBlockHeader, body_alignment);
  }

  uint64_t ImageFormatImageSize(const ImageFormat& image_format) const override {
    uint64_t size = NonTESize(image_format);
    if (image_format.pixel_format().format_modifier_value() &
        fuchsia_sysmem2::wire::kFormatModifierArmTeBit) {
      size += arm_transaction_elimination_buffer_size(size, image_format.coded_width(),
                                                      image_format.coded_height());
    }

    return size;
  }

  bool ImageFormatPlaneByteOffset(const ImageFormat& image_format, uint32_t plane,
                                  uint64_t* offset_out) const override {
    ZX_DEBUG_ASSERT(IsSupported(image_format.pixel_format()));
    if (plane == 0) {
      *offset_out = 0;
      return true;
    } else if (plane == kTransactionEliminationPlane) {
      *offset_out = fbl::round_up(NonTESize(image_format), kTransactionEliminationAlignment);
      return true;
    }
    return false;
  }
  bool ImageFormatPlaneRowBytes(const ImageFormat& image_format, uint32_t plane,
                                uint32_t* row_bytes_out) const override {
    if (plane == 0) {
      *row_bytes_out = 0;
      return true;
    } else if (plane == kTransactionEliminationPlane) {
      *row_bytes_out = arm_transaction_elimination_row_size(image_format.coded_width());
      return true;
    }
    return false;
  }
};

static uint64_t linear_size(uint32_t coded_height, uint32_t bytes_per_row, PixelFormatType type) {
  switch (type) {
    case PixelFormatType::kR8G8B8A8:
    case PixelFormatType::kBgra32:
    case PixelFormatType::kBgr24:
    case PixelFormatType::kRgb565:
    case PixelFormatType::kRgb332:
    case PixelFormatType::kRgb2220:
    case PixelFormatType::kL8:
    case PixelFormatType::kR8:
    case PixelFormatType::kR8G8:
    case PixelFormatType::kA2B10G10R10:
    case PixelFormatType::kA2R10G10B10:
      return coded_height * bytes_per_row;
    case PixelFormatType::kI420:
      return coded_height * bytes_per_row * 3 / 2;
    case PixelFormatType::kM420:
      return coded_height * bytes_per_row * 3 / 2;
    case PixelFormatType::kNv12:
      return coded_height * bytes_per_row * 3 / 2;
    case PixelFormatType::kYuy2:
      return coded_height * bytes_per_row;
    case PixelFormatType::kYv12:
      return coded_height * bytes_per_row * 3 / 2;
    default:
      return 0u;
  }
}

class LinearFormats : public ImageFormatSet {
 public:
  const char* Name() const override { return "LinearFormats"; }

  bool IsSupported(const PixelFormat& pixel_format) const override {
    if (pixel_format.has_format_modifier_value() &&
        pixel_format.format_modifier_value() != fuchsia_sysmem2::wire::kFormatModifierLinear) {
      return false;
    }
    ZX_DEBUG_ASSERT(pixel_format.has_type());
    switch (pixel_format.type()) {
      case PixelFormatType::kInvalid:
      case PixelFormatType::kMjpeg:
        return false;
      case PixelFormatType::kR8G8B8A8:
      case PixelFormatType::kBgra32:
      case PixelFormatType::kBgr24:
      case PixelFormatType::kI420:
      case PixelFormatType::kM420:
      case PixelFormatType::kNv12:
      case PixelFormatType::kYuy2:
      case PixelFormatType::kYv12:
      case PixelFormatType::kRgb565:
      case PixelFormatType::kRgb332:
      case PixelFormatType::kRgb2220:
      case PixelFormatType::kL8:
      case PixelFormatType::kR8:
      case PixelFormatType::kR8G8:
      case PixelFormatType::kA2B10G10R10:
      case PixelFormatType::kA2R10G10B10:
        return true;
    }
    return false;
  }

  uint64_t ImageFormatImageSize(const ImageFormat& image_format) const override {
    ZX_DEBUG_ASSERT(image_format.has_pixel_format());
    ZX_DEBUG_ASSERT(image_format.pixel_format().has_type());
    ZX_DEBUG_ASSERT(IsSupported(image_format.pixel_format()));
    ZX_DEBUG_ASSERT(image_format.has_coded_height());
    ZX_DEBUG_ASSERT(image_format.has_bytes_per_row());
    uint32_t coded_height = image_format.has_coded_height() ? image_format.coded_height() : 0;
    uint32_t bytes_per_row = image_format.has_bytes_per_row() ? image_format.bytes_per_row() : 0;
    return linear_size(coded_height, bytes_per_row, image_format.pixel_format().type());
  }

  bool ImageFormatPlaneByteOffset(const ImageFormat& image_format, uint32_t plane,
                                  uint64_t* offset_out) const override {
    if (plane == 0) {
      *offset_out = 0;
      return true;
    }
    if (plane == 1) {
      switch (image_format.pixel_format().type()) {
        case PixelFormatType::kNv12:
        case PixelFormatType::kI420:
        case PixelFormatType::kYv12:
          *offset_out = image_format.coded_height() * image_format.bytes_per_row();
          return true;
        default:
          return false;
      }
    }
    if (plane == 2) {
      switch (image_format.pixel_format().type()) {
        case PixelFormatType::kI420:
        case PixelFormatType::kYv12:
          *offset_out = image_format.coded_height() * image_format.bytes_per_row();
          *offset_out += image_format.coded_height() / 2 * image_format.bytes_per_row() / 2;
          return true;
        default:
          return false;
      }
    }

    return false;
  }

  bool ImageFormatPlaneRowBytes(const ImageFormat& image_format, uint32_t plane,
                                uint32_t* row_bytes_out) const override {
    if (plane == 0) {
      *row_bytes_out = image_format.bytes_per_row();
      return true;
    } else if (plane == 1) {
      switch (image_format.pixel_format().type()) {
        case PixelFormatType::kNv12:
          *row_bytes_out = image_format.bytes_per_row();
          return true;
        case PixelFormatType::kI420:
        case PixelFormatType::kYv12:
          *row_bytes_out = image_format.bytes_per_row() / 2;
          return true;
        default:
          return false;
      }
    } else if (plane == 2) {
      switch (image_format.pixel_format().type()) {
        case PixelFormatType::kI420:
        case PixelFormatType::kYv12:
          *row_bytes_out = image_format.bytes_per_row() / 2;
          return true;
        default:
          return false;
      }
    }
    return false;
  }
};

constexpr LinearFormats kLinearFormats;

class GoldfishFormats : public ImageFormatSet {
 public:
  const char* Name() const override { return "GoldfishFormats"; }

  bool IsSupported(const PixelFormat& pixel_format) const override {
    if (!pixel_format.has_type()) {
      return false;
    }
    if (!pixel_format.has_format_modifier_value()) {
      return false;
    }
    switch (pixel_format.format_modifier_value()) {
      case fuchsia_sysmem2::wire::kFormatModifierGoogleGoldfishOptimal:
        return true;
      default:
        return false;
    }
  }
  uint64_t ImageFormatImageSize(const ImageFormat& image_format) const override {
    ZX_DEBUG_ASSERT(image_format.has_pixel_format());
    ZX_DEBUG_ASSERT(image_format.pixel_format().has_type());
    ZX_DEBUG_ASSERT(IsSupported(image_format.pixel_format()));
    ZX_DEBUG_ASSERT(image_format.has_coded_height());
    ZX_DEBUG_ASSERT(image_format.has_bytes_per_row());
    uint32_t coded_height = image_format.has_coded_height() ? image_format.coded_height() : 0;
    uint32_t bytes_per_row = image_format.has_bytes_per_row() ? image_format.bytes_per_row() : 0;
    return linear_size(coded_height, bytes_per_row, image_format.pixel_format().type());
  }
  bool ImageFormatPlaneByteOffset(const ImageFormat& image_format, uint32_t plane,
                                  uint64_t* offset_out) const override {
    ZX_DEBUG_ASSERT(IsSupported(image_format.pixel_format()));
    if (plane == 0) {
      *offset_out = 0;
      return true;
    }
    return false;
  }
  bool ImageFormatPlaneRowBytes(const ImageFormat& image_format, uint32_t plane,
                                uint32_t* row_bytes_out) const override {
    if (plane == 0) {
      *row_bytes_out = image_format.bytes_per_row();
      return true;
    } else {
      return false;
    }
  }
};

class ArmTELinearFormats : public ImageFormatSet {
 public:
  const char* Name() const override { return "ArmTELinearFormats"; }

  bool IsSupported(const fuchsia_sysmem2::wire::PixelFormat& pixel_format) const override {
    if (!pixel_format.has_format_modifier_value()) {
      return false;
    }
    if (pixel_format.format_modifier_value() != fuchsia_sysmem2::wire::kFormatModifierArmLinearTe)
      return false;
    switch (pixel_format.type()) {
      case PixelFormatType::kInvalid:
      case PixelFormatType::kMjpeg:
        return false;
      case PixelFormatType::kR8G8B8A8:
      case PixelFormatType::kBgra32:
      case PixelFormatType::kBgr24:
      case PixelFormatType::kI420:
      case PixelFormatType::kM420:
      case PixelFormatType::kNv12:
      case PixelFormatType::kYuy2:
      case PixelFormatType::kYv12:
      case PixelFormatType::kRgb565:
      case PixelFormatType::kRgb332:
      case PixelFormatType::kRgb2220:
      case PixelFormatType::kL8:
      case PixelFormatType::kR8:
      case PixelFormatType::kR8G8:
      case PixelFormatType::kA2B10G10R10:
      case PixelFormatType::kA2R10G10B10:
        return true;
    }
    return false;
  }

  uint64_t ImageFormatImageSize(
      const fuchsia_sysmem2::wire::ImageFormat& image_format) const override {
    ZX_DEBUG_ASSERT(IsSupported(image_format.pixel_format()));
    ZX_DEBUG_ASSERT(image_format.has_coded_width());
    ZX_DEBUG_ASSERT(image_format.has_coded_height());
    ZX_DEBUG_ASSERT(image_format.has_bytes_per_row());
    uint32_t coded_width = image_format.has_coded_width() ? image_format.coded_width() : 0;
    uint32_t coded_height = image_format.has_coded_height() ? image_format.coded_height() : 0;
    uint32_t bytes_per_row = image_format.has_bytes_per_row() ? image_format.bytes_per_row() : 0;
    uint64_t size = linear_size(coded_height, bytes_per_row, image_format.pixel_format().type());
    uint64_t crc_size = arm_transaction_elimination_buffer_size(size, coded_width, coded_height);
    return size + crc_size;
  }

  bool ImageFormatPlaneByteOffset(const fuchsia_sysmem2::wire::ImageFormat& image_format,

                                  uint32_t plane, uint64_t* offset_out) const override {
    if (plane < kTransactionEliminationPlane) {
      return kLinearFormats.ImageFormatPlaneByteOffset(image_format, plane, offset_out);
    } else if (plane == kTransactionEliminationPlane) {
      ZX_DEBUG_ASSERT(image_format.has_coded_height());
      ZX_DEBUG_ASSERT(image_format.has_bytes_per_row());
      uint32_t coded_height = image_format.has_coded_height() ? image_format.coded_height() : 0;
      uint32_t bytes_per_row = image_format.has_bytes_per_row() ? image_format.bytes_per_row() : 0;
      uint64_t size = linear_size(coded_height, bytes_per_row, image_format.pixel_format().type());
      *offset_out = fbl::round_up(size, 64u);
      return true;
    }

    return false;
  }

  bool ImageFormatPlaneRowBytes(const fuchsia_sysmem2::wire::ImageFormat& image_format,
                                uint32_t plane, uint32_t* row_bytes_out) const override {
    if (plane < kTransactionEliminationPlane) {
      return kLinearFormats.ImageFormatPlaneRowBytes(image_format, plane, row_bytes_out);
    } else if (plane == kTransactionEliminationPlane) {
      *row_bytes_out = arm_transaction_elimination_row_size(image_format.coded_width());
      return true;
    }
    return false;
  }
};

constexpr IntelTiledFormats kIntelFormats;
constexpr AfbcFormats kAfbcFormats;
constexpr ArmTELinearFormats kArmTELinearFormats;
constexpr GoldfishFormats kGoldfishFormats;

constexpr const ImageFormatSet* kImageFormats[] = {
    &kLinearFormats, &kIntelFormats, &kAfbcFormats, &kArmTELinearFormats, &kGoldfishFormats,
};

}  // namespace

bool ImageFormatIsPixelFormatEqual(const fuchsia_sysmem2::wire::PixelFormat& a,
                                   const fuchsia_sysmem2::wire::PixelFormat& b) {
  if (a.type() != b.type()) {
    return false;
  }
  uint64_t format_modifier_a = a.has_format_modifier_value()
                                   ? a.format_modifier_value()
                                   : fuchsia_sysmem2::wire::kFormatModifierNone;
  uint64_t format_modifier_b = b.has_format_modifier_value()
                                   ? b.format_modifier_value()
                                   : fuchsia_sysmem2::wire::kFormatModifierNone;
  if (format_modifier_a != format_modifier_b) {
    return false;
  }
  return true;
}

bool ImageFormatIsPixelFormatEqual(const fuchsia_sysmem::wire::PixelFormat& a_v1,
                                   const fuchsia_sysmem::wire::PixelFormat& b_v1) {
  fidl::FidlAllocator allocator;
  PixelFormat a = sysmem::V2CopyFromV1PixelFormat(allocator, a_v1);
  PixelFormat b = sysmem::V2CopyFromV1PixelFormat(allocator, b_v1);
  return ImageFormatIsPixelFormatEqual(a, b);
}

bool ImageFormatIsPixelFormatEqual(const fuchsia_sysmem_PixelFormat& a_v1,
                                   const fuchsia_sysmem_PixelFormat& b_v1) {
  fidl::FidlAllocator allocator;
  PixelFormat a = sysmem::V2CopyFromV1PixelFormat(allocator, a_v1);
  PixelFormat b = sysmem::V2CopyFromV1PixelFormat(allocator, b_v1);
  return ImageFormatIsPixelFormatEqual(a, b);
}

bool ImageFormatIsSupportedColorSpaceForPixelFormat(
    const fuchsia_sysmem2::wire::ColorSpace& color_space,
    const fuchsia_sysmem2::wire::PixelFormat& pixel_format) {
  if (!color_space.has_type())
    return false;
  // Ignore pixel format modifier - assume it has already been checked.
  auto color_space_sampling_info_iter = kColorSpaceSamplingInfo.find(color_space.type());
  if (color_space_sampling_info_iter == kColorSpaceSamplingInfo.end()) {
    return false;
  }
  auto pixel_format_sampling_info_iter = kPixelFormatSamplingInfo.find(pixel_format.type());
  if (pixel_format_sampling_info_iter == kPixelFormatSamplingInfo.end()) {
    return false;
  }
  const SamplingInfo& color_space_sampling_info = color_space_sampling_info_iter->second;
  const SamplingInfo& pixel_format_sampling_info = pixel_format_sampling_info_iter->second;
  if (color_space_sampling_info.color_type != pixel_format_sampling_info.color_type) {
    return false;
  }
  bool is_bits_per_sample_match_found = false;
  for (uint32_t bits_per_sample : color_space_sampling_info.possible_bits_per_sample) {
    auto pixel_format_bits_per_sample_iter =
        pixel_format_sampling_info.possible_bits_per_sample.find(bits_per_sample);
    if (pixel_format_bits_per_sample_iter !=
        pixel_format_sampling_info.possible_bits_per_sample.end()) {
      is_bits_per_sample_match_found = true;
      break;
    }
  }
  if (!is_bits_per_sample_match_found) {
    return false;
  }
  return true;
}

bool ImageFormatIsSupportedColorSpaceForPixelFormat(
    const fuchsia_sysmem::wire::ColorSpace& color_space_v1,
    const fuchsia_sysmem::wire::PixelFormat& pixel_format_v1) {
  fidl::FidlAllocator allocator;
  ColorSpace color_space = sysmem::V2CopyFromV1ColorSpace(allocator, color_space_v1);
  PixelFormat pixel_format = sysmem::V2CopyFromV1PixelFormat(allocator, pixel_format_v1);
  return ImageFormatIsSupportedColorSpaceForPixelFormat(color_space, pixel_format);
}

bool ImageFormatIsSupportedColorSpaceForPixelFormat(
    const fuchsia_sysmem_ColorSpace& color_space_v1,
    const fuchsia_sysmem_PixelFormat& pixel_format_v1) {
  fidl::FidlAllocator allocator;
  ColorSpace color_space = sysmem::V2CopyFromV1ColorSpace(allocator, color_space_v1);
  PixelFormat pixel_format = sysmem::V2CopyFromV1PixelFormat(allocator, pixel_format_v1);
  return ImageFormatIsSupportedColorSpaceForPixelFormat(color_space, pixel_format);
}

bool ImageFormatIsSupported(const fuchsia_sysmem2::wire::PixelFormat& pixel_format) {
  for (auto format_set : kImageFormats) {
    if (format_set->IsSupported(pixel_format)) {
      return true;
    }
  }
  return false;
}

bool ImageFormatIsSupported(const fuchsia_sysmem::wire::PixelFormat& pixel_format_v1) {
  fidl::FidlAllocator allocator;
  PixelFormat pixel_format = sysmem::V2CopyFromV1PixelFormat(allocator, pixel_format_v1);
  return ImageFormatIsSupported(pixel_format);
}

bool ImageFormatIsSupported(const fuchsia_sysmem_PixelFormat* pixel_format_v1) {
  ZX_DEBUG_ASSERT(pixel_format_v1);
  fidl::FidlAllocator allocator;
  PixelFormat pixel_format = sysmem::V2CopyFromV1PixelFormat(allocator, *pixel_format_v1);
  return ImageFormatIsSupported(pixel_format);
}

uint32_t ImageFormatBitsPerPixel(const fuchsia_sysmem2::wire::PixelFormat& pixel_format) {
  ZX_DEBUG_ASSERT(ImageFormatIsSupported(pixel_format));
  switch (pixel_format.type()) {
    case PixelFormatType::kInvalid:
    case PixelFormatType::kMjpeg:
      // impossible; checked previously.
      ZX_DEBUG_ASSERT(false);
      return 0u;
    case PixelFormatType::kR8G8B8A8:
      return 4u * 8u;
    case PixelFormatType::kBgra32:
      return 4u * 8u;
    case PixelFormatType::kBgr24:
      return 3u * 8u;
    case PixelFormatType::kI420:
      return 12u;
    case PixelFormatType::kM420:
      return 12u;
    case PixelFormatType::kNv12:
      return 12u;
    case PixelFormatType::kYuy2:
      return 2u * 8u;
    case PixelFormatType::kYv12:
      return 12u;
    case PixelFormatType::kRgb565:
      return 16u;
    case PixelFormatType::kRgb332:
    case PixelFormatType::kRgb2220:
    case PixelFormatType::kL8:
    case PixelFormatType::kR8:
      return 8u;
    case PixelFormatType::kR8G8:
      return 16u;
    case PixelFormatType::kA2B10G10R10:
    case PixelFormatType::kA2R10G10B10:
      return 2u + 3 * 10u;
  }
  ZX_PANIC("Unknown Pixel Format: %d", static_cast<int>(pixel_format.type()));
  return 0u;
}

uint32_t ImageFormatBitsPerPixel(const fuchsia_sysmem::wire::PixelFormat& pixel_format_v1) {
  fidl::FidlAllocator allocator;
  PixelFormat pixel_format = sysmem::V2CopyFromV1PixelFormat(allocator, pixel_format_v1);
  return ImageFormatBitsPerPixel(pixel_format);
}

// Overall bits per pixel, across all pixel data in the whole image.
uint32_t ImageFormatBitsPerPixel(const fuchsia_sysmem_PixelFormat* pixel_format_v1) {
  ZX_DEBUG_ASSERT(pixel_format_v1);
  fidl::FidlAllocator allocator;
  PixelFormat pixel_format = sysmem::V2CopyFromV1PixelFormat(allocator, *pixel_format_v1);
  return ImageFormatBitsPerPixel(pixel_format);
}

uint32_t ImageFormatStrideBytesPerWidthPixel(
    const fuchsia_sysmem2::wire::PixelFormat& pixel_format) {
  ZX_DEBUG_ASSERT(ImageFormatIsSupported(pixel_format));
  // This list should match the one in garnet/public/rust/fuchsia-framebuffer/src/sysmem.rs.
  switch (pixel_format.type()) {
    case PixelFormatType::kInvalid:
    case PixelFormatType::kMjpeg:
      // impossible; checked previously.
      ZX_DEBUG_ASSERT(false);
      return 0u;
    case PixelFormatType::kR8G8B8A8:
      return 4u;
    case PixelFormatType::kBgra32:
      return 4u;
    case PixelFormatType::kBgr24:
      return 3u;
    case PixelFormatType::kI420:
      return 1u;
    case PixelFormatType::kM420:
      return 1u;
    case PixelFormatType::kNv12:
      return 1u;
    case PixelFormatType::kYuy2:
      return 2u;
    case PixelFormatType::kYv12:
      return 1u;
    case PixelFormatType::kRgb565:
      return 2u;
    case PixelFormatType::kRgb332:
      return 1u;
    case PixelFormatType::kRgb2220:
      return 1u;
    case PixelFormatType::kL8:
      return 1u;
    case PixelFormatType::kR8:
      return 1u;
    case PixelFormatType::kR8G8:
      return 2u;
    case PixelFormatType::kA2B10G10R10:
      return 4u;
    case PixelFormatType::kA2R10G10B10:
      return 4u;
  }
  ZX_PANIC("Unknown Pixel Format: %d", static_cast<int>(pixel_format.type()));
  return 0u;
}

uint32_t ImageFormatStrideBytesPerWidthPixel(
    const fuchsia_sysmem::wire::PixelFormat& pixel_format_v1) {
  fidl::FidlAllocator allocator;
  PixelFormat pixel_format = sysmem::V2CopyFromV1PixelFormat(allocator, pixel_format_v1);
  return ImageFormatStrideBytesPerWidthPixel(pixel_format);
}

uint32_t ImageFormatStrideBytesPerWidthPixel(const fuchsia_sysmem_PixelFormat* pixel_format_v1) {
  ZX_DEBUG_ASSERT(pixel_format_v1);
  fidl::FidlAllocator allocator;
  PixelFormat pixel_format = sysmem::V2CopyFromV1PixelFormat(allocator, *pixel_format_v1);
  return ImageFormatStrideBytesPerWidthPixel(pixel_format);
}

uint64_t ImageFormatImageSize(const fuchsia_sysmem2::wire::ImageFormat& image_format) {
  ZX_DEBUG_ASSERT(image_format.has_pixel_format());
  for (auto format_set : kImageFormats) {
    if (format_set->IsSupported(image_format.pixel_format())) {
      return format_set->ImageFormatImageSize(image_format);
    }
  }
  ZX_PANIC("Unknown Pixel Format: %d", static_cast<int>(image_format.pixel_format().type()));
  return 0;
}

uint64_t ImageFormatImageSize(const fuchsia_sysmem::wire::ImageFormat2& image_format_v1) {
  fidl::FidlAllocator allocator;
  ImageFormat image_format =
      sysmem::V2CopyFromV1ImageFormat(allocator, image_format_v1).take_value();
  return ImageFormatImageSize(image_format);
}

uint64_t ImageFormatImageSize(const fuchsia_sysmem_ImageFormat_2* image_format_v1) {
  ZX_DEBUG_ASSERT(image_format_v1);
  fidl::FidlAllocator allocator;
  ImageFormat image_format =
      sysmem::V2CopyFromV1ImageFormat(allocator, *image_format_v1).take_value();
  return ImageFormatImageSize(image_format);
}

uint32_t ImageFormatCodedWidthMinDivisor(const fuchsia_sysmem2::wire::PixelFormat& pixel_format) {
  ZX_DEBUG_ASSERT(ImageFormatIsSupported(pixel_format));
  switch (pixel_format.type()) {
    case PixelFormatType::kInvalid:
    case PixelFormatType::kMjpeg:
      // impossible; checked previously.
      ZX_DEBUG_ASSERT(false);
      return 0u;
    case PixelFormatType::kR8G8B8A8:
      return 1u;
    case PixelFormatType::kBgra32:
      return 1u;
    case PixelFormatType::kBgr24:
      return 1u;
    case PixelFormatType::kI420:
      return 2u;
    case PixelFormatType::kM420:
      return 2u;
    case PixelFormatType::kNv12:
      return 2u;
    case PixelFormatType::kYuy2:
      return 2u;
    case PixelFormatType::kYv12:
      return 2u;
    case PixelFormatType::kRgb565:
      return 1u;
    case PixelFormatType::kRgb332:
      return 1u;
    case PixelFormatType::kRgb2220:
      return 1u;
    case PixelFormatType::kL8:
      return 1u;
    case PixelFormatType::kR8:
      return 1u;
    case PixelFormatType::kR8G8:
      return 1u;
    case PixelFormatType::kA2B10G10R10:
      return 1u;
    case PixelFormatType::kA2R10G10B10:
      return 1u;
  }
  ZX_PANIC("Unknown Pixel Format: %d", static_cast<int>(pixel_format.type()));
  return 0u;
}

uint32_t ImageFormatCodedWidthMinDivisor(const fuchsia_sysmem::wire::PixelFormat& pixel_format_v1) {
  fidl::FidlAllocator allocator;
  PixelFormat pixel_format = sysmem::V2CopyFromV1PixelFormat(allocator, pixel_format_v1);
  return ImageFormatCodedWidthMinDivisor(pixel_format);
}

uint32_t ImageFormatCodedWidthMinDivisor(const fuchsia_sysmem_PixelFormat* pixel_format_v1) {
  ZX_DEBUG_ASSERT(pixel_format_v1);
  fidl::FidlAllocator allocator;
  PixelFormat pixel_format = sysmem::V2CopyFromV1PixelFormat(allocator, *pixel_format_v1);
  return ImageFormatCodedWidthMinDivisor(pixel_format);
}

uint32_t ImageFormatCodedHeightMinDivisor(const fuchsia_sysmem2::wire::PixelFormat& pixel_format) {
  ZX_DEBUG_ASSERT(ImageFormatIsSupported(pixel_format));
  switch (pixel_format.type()) {
    case PixelFormatType::kInvalid:
    case PixelFormatType::kMjpeg:
      // impossible; checked previously.
      ZX_DEBUG_ASSERT(false);
      return 0u;
    case PixelFormatType::kR8G8B8A8:
      return 1u;
    case PixelFormatType::kBgra32:
      return 1u;
    case PixelFormatType::kBgr24:
      return 1u;
    case PixelFormatType::kI420:
      return 2u;
    case PixelFormatType::kM420:
      return 2u;
    case PixelFormatType::kNv12:
      return 2u;
    case PixelFormatType::kYuy2:
      return 2u;
    case PixelFormatType::kYv12:
      return 2u;
    case PixelFormatType::kRgb565:
      return 1u;
    case PixelFormatType::kRgb332:
      return 1u;
    case PixelFormatType::kRgb2220:
      return 1u;
    case PixelFormatType::kL8:
      return 1u;
    case PixelFormatType::kR8:
      return 1u;
    case PixelFormatType::kR8G8:
      return 1u;
    case PixelFormatType::kA2B10G10R10:
      return 1u;
    case PixelFormatType::kA2R10G10B10:
      return 1u;
  }
  ZX_PANIC("Unknown Pixel Format: %d", static_cast<int>(pixel_format.type()));
  return 0u;
}

uint32_t ImageFormatCodedHeightMinDivisor(
    const fuchsia_sysmem::wire::PixelFormat& pixel_format_v1) {
  fidl::FidlAllocator allocator;
  PixelFormat pixel_format = sysmem::V2CopyFromV1PixelFormat(allocator, pixel_format_v1);
  return ImageFormatCodedHeightMinDivisor(pixel_format);
}

uint32_t ImageFormatCodedHeightMinDivisor(const fuchsia_sysmem_PixelFormat* pixel_format_v1) {
  ZX_DEBUG_ASSERT(pixel_format_v1);
  fidl::FidlAllocator allocator;
  PixelFormat pixel_format = sysmem::V2CopyFromV1PixelFormat(allocator, *pixel_format_v1);
  return ImageFormatCodedHeightMinDivisor(pixel_format);
}

uint32_t ImageFormatSampleAlignment(const fuchsia_sysmem2::wire::PixelFormat& pixel_format) {
  ZX_DEBUG_ASSERT(ImageFormatIsSupported(pixel_format));
  switch (pixel_format.type()) {
    case PixelFormatType::kInvalid:
    case PixelFormatType::kMjpeg:
      // impossible; checked previously.
      ZX_DEBUG_ASSERT(false);
      return 0u;
    case PixelFormatType::kR8G8B8A8:
      return 4u;
    case PixelFormatType::kBgra32:
      return 4u;
    case PixelFormatType::kBgr24:
      return 1u;
    case PixelFormatType::kI420:
      return 2u;
    case PixelFormatType::kM420:
      return 2u;
    case PixelFormatType::kNv12:
      return 2u;
    case PixelFormatType::kYuy2:
      return 2u;
    case PixelFormatType::kYv12:
      return 2u;
    case PixelFormatType::kRgb565:
      return 2u;
    case PixelFormatType::kRgb332:
      return 1u;
    case PixelFormatType::kRgb2220:
      return 1u;
    case PixelFormatType::kL8:
      return 1u;
    case PixelFormatType::kR8:
      return 1u;
    case PixelFormatType::kR8G8:
      return 2u;
    case PixelFormatType::kA2B10G10R10:
      return 4u;
    case PixelFormatType::kA2R10G10B10:
      return 4u;
  }
  ZX_PANIC("Unknown Pixel Format: %d", static_cast<int>(pixel_format.type()));
  return 0u;
}

uint32_t ImageFormatSampleAlignment(const fuchsia_sysmem::wire::PixelFormat& pixel_format_v1) {
  fidl::FidlAllocator allocator;
  PixelFormat pixel_format = sysmem::V2CopyFromV1PixelFormat(allocator, pixel_format_v1);
  return ImageFormatSampleAlignment(pixel_format);
}

uint32_t ImageFormatSampleAlignment(const fuchsia_sysmem_PixelFormat* pixel_format_v1) {
  ZX_DEBUG_ASSERT(pixel_format_v1);
  fidl::FidlAllocator allocator;
  PixelFormat pixel_format = sysmem::V2CopyFromV1PixelFormat(allocator, *pixel_format_v1);
  return ImageFormatSampleAlignment(pixel_format);
}

bool ImageFormatMinimumRowBytes(const fuchsia_sysmem2::wire::ImageFormatConstraints& constraints,
                                uint32_t width, uint32_t* minimum_row_bytes_out) {
  ZX_DEBUG_ASSERT(minimum_row_bytes_out);
  // Caller must set pixel_format.
  ZX_DEBUG_ASSERT(constraints.has_pixel_format());
  // Bytes per row is not well-defined for tiled types.
  if (constraints.pixel_format().has_format_modifier_value() &&
      constraints.pixel_format().format_modifier_value() !=
          fuchsia_sysmem2::wire::kFormatModifierLinear &&
      constraints.pixel_format().format_modifier_value() !=
          fuchsia_sysmem2::wire::kFormatModifierArmLinearTe) {
    return false;
  }
  if ((constraints.has_min_coded_width() && width < constraints.min_coded_width()) ||
      (constraints.has_max_coded_width() && width > constraints.max_coded_width())) {
    return false;
  }
  uint32_t constraints_min_bytes_per_row =
      constraints.has_min_bytes_per_row() ? constraints.min_bytes_per_row() : 0;
  uint32_t constraints_bytes_per_row_divisor =
      constraints.has_bytes_per_row_divisor() ? constraints.bytes_per_row_divisor() : 1;
  // This code should match the code in garnet/public/rust/fuchsia-framebuffer/src/sysmem.rs.
  *minimum_row_bytes_out = fbl::round_up(
      std::max(ImageFormatStrideBytesPerWidthPixel(constraints.pixel_format()) * width,
               constraints_min_bytes_per_row),
      constraints_bytes_per_row_divisor);
  if (constraints.has_max_bytes_per_row() &&
      *minimum_row_bytes_out > constraints.max_bytes_per_row()) {
    return false;
  }
  return true;
}

bool ImageFormatMinimumRowBytes(
    const fuchsia_sysmem::wire::ImageFormatConstraints& image_format_constraints_v1, uint32_t width,
    uint32_t* minimum_row_bytes_out) {
  ZX_DEBUG_ASSERT(minimum_row_bytes_out);
  fidl::FidlAllocator allocator;
  ImageFormatConstraints image_format_constraints =
      sysmem::V2CopyFromV1ImageFormatConstraints(allocator, image_format_constraints_v1)
          .take_value();
  return ImageFormatMinimumRowBytes(image_format_constraints, width, minimum_row_bytes_out);
}

bool ImageFormatMinimumRowBytes(
    const fuchsia_sysmem_ImageFormatConstraints* image_format_constraints_v1, uint32_t width,
    uint32_t* minimum_row_bytes_out) {
  ZX_DEBUG_ASSERT(image_format_constraints_v1);
  ZX_DEBUG_ASSERT(minimum_row_bytes_out);
  fidl::FidlAllocator allocator;
  ImageFormatConstraints image_format_constraints =
      sysmem::V2CopyFromV1ImageFormatConstraints(allocator, *image_format_constraints_v1)
          .take_value();
  return ImageFormatMinimumRowBytes(image_format_constraints, width, minimum_row_bytes_out);
}

bool ImageFormatConvertSysmemToZx(const fuchsia_sysmem2::wire::PixelFormat& pixel_format,
                                  zx_pixel_format_t* zx_pixel_format_out) {
  if (pixel_format.has_format_modifier_value() &&
      (pixel_format.format_modifier_value() != fuchsia_sysmem2::wire::kFormatModifierLinear)) {
    return false;
  }
  switch (pixel_format.type()) {
    case PixelFormatType::kBgra32:
      *zx_pixel_format_out = ZX_PIXEL_FORMAT_ARGB_8888;
      return true;

    case PixelFormatType::kBgr24:
      *zx_pixel_format_out = ZX_PIXEL_FORMAT_RGB_888;
      return true;

    case PixelFormatType::kRgb565:
      *zx_pixel_format_out = ZX_PIXEL_FORMAT_RGB_565;
      return true;

    case PixelFormatType::kRgb332:
      *zx_pixel_format_out = ZX_PIXEL_FORMAT_RGB_332;
      return true;

    case PixelFormatType::kRgb2220:
      *zx_pixel_format_out = ZX_PIXEL_FORMAT_RGB_2220;
      return true;

    case PixelFormatType::kL8:
      *zx_pixel_format_out = ZX_PIXEL_FORMAT_MONO_8;
      return true;

    case PixelFormatType::kNv12:
      *zx_pixel_format_out = ZX_PIXEL_FORMAT_NV12;
      return true;

    case PixelFormatType::kA2B10G10R10:
      *zx_pixel_format_out = ZX_PIXEL_FORMAT_ABGR_2_10_10_10;
      return true;

    case PixelFormatType::kA2R10G10B10:
      *zx_pixel_format_out = ZX_PIXEL_FORMAT_ARGB_2_10_10_10;
      return true;

    default:
      return false;
  }
}

bool ImageFormatConvertSysmemToZx(const fuchsia_sysmem::wire::PixelFormat& pixel_format_v1,
                                  zx_pixel_format_t* zx_pixel_format_out) {
  ZX_DEBUG_ASSERT(zx_pixel_format_out);
  fidl::FidlAllocator allocator;
  PixelFormat pixel_format = sysmem::V2CopyFromV1PixelFormat(allocator, pixel_format_v1);
  return ImageFormatConvertSysmemToZx(pixel_format, zx_pixel_format_out);
}

bool ImageFormatConvertSysmemToZx(const fuchsia_sysmem_PixelFormat* pixel_format_v1,
                                  zx_pixel_format_t* zx_pixel_format_out) {
  ZX_DEBUG_ASSERT(pixel_format_v1);
  ZX_DEBUG_ASSERT(zx_pixel_format_out);
  fidl::FidlAllocator allocator;
  PixelFormat pixel_format = sysmem::V2CopyFromV1PixelFormat(allocator, *pixel_format_v1);
  return ImageFormatConvertSysmemToZx(pixel_format, zx_pixel_format_out);
}

fit::result<fuchsia_sysmem2::wire::PixelFormat> ImageFormatConvertZxToSysmem_v2(
    fidl::AnyAllocator& allocator, zx_pixel_format_t zx_pixel_format) {
  PixelFormat v2b = PixelFormat(allocator);
  v2b.set_format_modifier_value(allocator, fuchsia_sysmem2::wire::kFormatModifierLinear);
  PixelFormatType out_type;
  switch (zx_pixel_format) {
    case ZX_PIXEL_FORMAT_RGB_565:
      out_type = PixelFormatType::kRgb565;
      break;

    case ZX_PIXEL_FORMAT_RGB_332:
      out_type = PixelFormatType::kRgb332;
      break;

    case ZX_PIXEL_FORMAT_RGB_2220:
      out_type = PixelFormatType::kRgb2220;
      break;

    case ZX_PIXEL_FORMAT_ARGB_8888:
      out_type = PixelFormatType::kBgra32;
      break;

    case ZX_PIXEL_FORMAT_RGB_x888:
      // Switch to using alpha.
      out_type = PixelFormatType::kBgra32;
      break;

    case ZX_PIXEL_FORMAT_MONO_8:
      out_type = PixelFormatType::kL8;
      break;

    case ZX_PIXEL_FORMAT_NV12:
      out_type = PixelFormatType::kNv12;
      break;

    case ZX_PIXEL_FORMAT_RGB_888:
      out_type = PixelFormatType::kBgr24;
      break;

    default:
      return fit::error();
  }
  v2b.set_type(allocator, out_type);
  return fit::ok(std::move(v2b));
}

fit::result<fuchsia_sysmem::wire::PixelFormat> ImageFormatConvertZxToSysmem_v1(
    fidl::AnyAllocator& allocator, zx_pixel_format_t zx_pixel_format) {
  auto pixel_format_v2_result = ImageFormatConvertZxToSysmem_v2(allocator, zx_pixel_format);
  if (!pixel_format_v2_result.is_ok()) {
    return fit::error();
  }
  auto pixel_format_v2 = pixel_format_v2_result.take_value();
  auto pixel_format_v1 = sysmem::V1CopyFromV2PixelFormat(pixel_format_v2);
  return fit::ok(std::move(pixel_format_v1));
}

bool ImageFormatConvertZxToSysmem(zx_pixel_format_t zx_pixel_format,
                                  fuchsia_sysmem_PixelFormat* pixel_format_out) {
  ZX_DEBUG_ASSERT(pixel_format_out);
  fidl::FidlAllocator allocator;
  auto pixel_format_v2_result = ImageFormatConvertZxToSysmem_v2(allocator, zx_pixel_format);
  if (!pixel_format_v2_result.is_ok()) {
    return false;
  }
  auto pixel_format_v2 = pixel_format_v2_result.take_value();
  pixel_format_out->type = static_cast<fuchsia_sysmem_PixelFormatType>(pixel_format_v2.type());
  pixel_format_out->has_format_modifier = pixel_format_v2.has_format_modifier_value();
  pixel_format_out->format_modifier.value = pixel_format_v2.format_modifier_value();
  return true;
}

// TODO(dustingreen): From here down need to be converted to operate on v2 natively similar to
// above (merged while 1st sysmem v2 CL was in flight):

fit::result<ImageFormat> ImageConstraintsToFormat(fidl::AnyAllocator& allocator,
                                                  const ImageFormatConstraints& constraints,
                                                  uint32_t width, uint32_t height) {
  if ((constraints.has_min_coded_height() && height < constraints.min_coded_height()) ||
      (constraints.has_max_coded_height() && height > constraints.max_coded_height())) {
    return fit::error();
  }
  if ((constraints.has_min_coded_width() && width < constraints.min_coded_width()) ||
      (constraints.has_max_coded_width() && width > constraints.max_coded_width())) {
    return fit::error();
  }
  ImageFormat result(allocator);
  uint32_t minimum_row_bytes;
  if (ImageFormatMinimumRowBytes(constraints, width, &minimum_row_bytes)) {
    result.set_bytes_per_row(allocator, minimum_row_bytes);
  } else {
    result.set_bytes_per_row(allocator, 0);
  }
  result.set_pixel_format(allocator,
                          sysmem::V2ClonePixelFormat(allocator, constraints.pixel_format()));
  result.set_coded_width(allocator, width);
  result.set_coded_height(allocator, height);
  result.set_display_width(allocator, width);
  result.set_display_height(allocator, height);
  if (constraints.has_color_spaces() && constraints.color_spaces().count()) {
    result.set_color_space(allocator,
                           sysmem::V2CloneColorSpace(allocator, constraints.color_spaces()[0]));
  }
  // result's has_pixel_aspect_ratio field remains un-set which is equivalent to false
  return fit::ok(std::move(result));
}

fit::result<fuchsia_sysmem::wire::ImageFormat2> ImageConstraintsToFormat(
    const fuchsia_sysmem::wire::ImageFormatConstraints& image_format_constraints_v1, uint32_t width,
    uint32_t height) {
  fidl::FidlAllocator allocator;
  ImageFormatConstraints image_format_constraints_v2 =
      sysmem::V2CopyFromV1ImageFormatConstraints(allocator, image_format_constraints_v1)
          .take_value();
  auto v2_out_result =
      ImageConstraintsToFormat(allocator, image_format_constraints_v2, width, height);
  if (!v2_out_result.is_ok()) {
    return fit::error();
  }
  auto v2_out = v2_out_result.take_value();
  auto v1_out_result = sysmem::V1CopyFromV2ImageFormat(v2_out);
  if (!v1_out_result.is_ok()) {
    return fit::error();
  }
  return fit::ok(v1_out_result.take_value());
}

bool ImageConstraintsToFormat(
    const fuchsia_sysmem_ImageFormatConstraints* image_format_constraints_v1, uint32_t width,
    uint32_t height, fuchsia_sysmem_ImageFormat_2* image_format_out) {
  ZX_DEBUG_ASSERT(image_format_constraints_v1);
  ZX_DEBUG_ASSERT(image_format_out);
  fidl::FidlAllocator allocator;
  ImageFormatConstraints image_format_constraints_v2 =
      sysmem::V2CopyFromV1ImageFormatConstraints(allocator, *image_format_constraints_v1)
          .take_value();
  auto v2_out_result =
      ImageConstraintsToFormat(allocator, image_format_constraints_v2, width, height);
  if (!v2_out_result.is_ok()) {
    return false;
  }
  auto v2_out = v2_out_result.take_value();
  auto v1_out_result = sysmem::V1CopyFromV2ImageFormat(v2_out);
  if (!v1_out_result.is_ok()) {
    return false;
  }
  // ImageFormat doesn't have any hanldes, so this struct copy works to convert from v1 LLCPP to
  // v1 FIDL C.  We can remove this whole function when we're done moving away from FIDL C.
  static_assert(sizeof(*image_format_out) == sizeof(v1_out_result.value()));
  *image_format_out = *reinterpret_cast<fuchsia_sysmem_ImageFormat_2*>(&v1_out_result.value());
  return true;
}

bool ImageFormatPlaneByteOffset(const ImageFormat& image_format, uint32_t plane,
                                uint64_t* offset_out) {
  ZX_DEBUG_ASSERT(offset_out);
  for (auto& format_set : kImageFormats) {
    if (format_set->IsSupported(image_format.pixel_format())) {
      return format_set->ImageFormatPlaneByteOffset(image_format, plane, offset_out);
    }
  }
  return false;
}

bool ImageFormatPlaneByteOffset(const fuchsia_sysmem::wire::ImageFormat2& image_format,
                                uint32_t plane, uint64_t* offset_out) {
  ZX_DEBUG_ASSERT(offset_out);
  fidl::FidlAllocator allocator;
  auto image_format_v2_result = sysmem::V2CopyFromV1ImageFormat(allocator, image_format);
  if (!image_format_v2_result.is_ok()) {
    return false;
  }
  auto image_format_v2 = image_format_v2_result.take_value();
  return ImageFormatPlaneByteOffset(image_format_v2, plane, offset_out);
}

bool ImageFormatPlaneByteOffset(const fuchsia_sysmem_ImageFormat_2* image_format, uint32_t plane,
                                uint64_t* offset_out) {
  ZX_DEBUG_ASSERT(image_format);
  ZX_DEBUG_ASSERT(offset_out);
  fidl::FidlAllocator allocator;
  auto image_format_v2_result = sysmem::V2CopyFromV1ImageFormat(allocator, *image_format);
  if (!image_format_v2_result.is_ok()) {
    return false;
  }
  auto image_format_v2 = image_format_v2_result.take_value();
  return ImageFormatPlaneByteOffset(image_format_v2, plane, offset_out);
}

bool ImageFormatPlaneRowBytes(const ImageFormat& image_format, uint32_t plane,
                              uint32_t* row_bytes_out) {
  ZX_DEBUG_ASSERT(row_bytes_out);
  for (auto& format_set : kImageFormats) {
    if (format_set->IsSupported(image_format.pixel_format())) {
      return format_set->ImageFormatPlaneRowBytes(image_format, plane, row_bytes_out);
    }
  }
  return false;
}

bool ImageFormatPlaneRowBytes(const fuchsia_sysmem::wire::ImageFormat2& image_format,
                              uint32_t plane, uint32_t* row_bytes_out) {
  ZX_DEBUG_ASSERT(row_bytes_out);
  fidl::FidlAllocator allocator;
  auto image_format_v2_result = sysmem::V2CopyFromV1ImageFormat(allocator, image_format);
  if (!image_format_v2_result.is_ok()) {
    return false;
  }
  auto image_format_v2 = image_format_v2_result.take_value();
  return ImageFormatPlaneRowBytes(image_format_v2, plane, row_bytes_out);
}

bool ImageFormatPlaneRowBytes(const fuchsia_sysmem_ImageFormat_2* image_format, uint32_t plane,
                              uint32_t* row_bytes_out) {
  ZX_DEBUG_ASSERT(image_format);
  ZX_DEBUG_ASSERT(row_bytes_out);
  fidl::FidlAllocator allocator;
  auto image_format_v2_result = sysmem::V2CopyFromV1ImageFormat(allocator, *image_format);
  if (!image_format_v2_result.is_ok()) {
    return false;
  }
  auto image_format_v2 = image_format_v2_result.take_value();
  return ImageFormatPlaneRowBytes(image_format_v2, plane, row_bytes_out);
}

bool ImageFormatCompatibleWithProtectedMemory(
    const fuchsia_sysmem2::wire::PixelFormat& pixel_format) {
  if (!pixel_format.has_format_modifier_value())
    return true;
  constexpr uint64_t kArmLinearFormat = 0x0800000000000000ul;
  switch (pixel_format.format_modifier_value() & ~AfbcFormats::kAfbcModifierMask) {
    case kArmLinearFormat:
    case fuchsia_sysmem2::wire::kFormatModifierArmAfbc16X16:
    case fuchsia_sysmem2::wire::kFormatModifierArmAfbc32X8:
      // TE formats occasionally need CPU writes to the TE buffer.
      return !(pixel_format.format_modifier_value() &
               fuchsia_sysmem2::wire::kFormatModifierArmTeBit);

    default:
      return true;
  }
}

bool ImageFormatCompatibleWithProtectedMemory(
    const fuchsia_sysmem::wire::PixelFormat& pixel_format_v1) {
  fidl::FidlAllocator allocator;
  auto pixel_format_v2 = sysmem::V2CopyFromV1PixelFormat(allocator, pixel_format_v1);
  return ImageFormatCompatibleWithProtectedMemory(pixel_format_v2);
}

bool ImageFormatCompatibleWithProtectedMemory(const fuchsia_sysmem_PixelFormat* pixel_format) {
  ZX_DEBUG_ASSERT(pixel_format);
  fidl::FidlAllocator allocator;
  auto pixel_format_v2 = sysmem::V2CopyFromV1PixelFormat(allocator, *pixel_format);
  return ImageFormatCompatibleWithProtectedMemory(pixel_format_v2);
}
