// 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.

library fuchsia.images;

// Specifies how pixels are represented in the image buffer.
enum PixelFormat {
  // BGRA_8
  //
  // A 32-bit four-component unsigned integer format.
  // Byte order: B, G, R, A (little-endian ARGB packed 32-bit word).
  // Equivalent to Skia |kBGRA_8888_SkColorType| color type.
  // Equivalent to Zircon |ARGB_8888| pixel format on little-endian arch.
  BGRA_8 = 0;

  // YUY2
  //
  // 4:2:2 (2x down-sampled UV horizontally; full res UV vertically)
  //
  // A 32-bit component that contains information for 2 pixels:
  // Byte order: Y1, U, Y2, V
  // Unpacks to 2 RGB pixels, where RGB1 = func(Y1, U, V)
  // and RGB2 = func(Y2, U, V)
  // Equivalent to YUV422
  YUY2 = 1;

  // NV12
  //
  // 4:2:0 (2x down-sampled UV in both directions)
  //
  // Offset 0:
  // 8 bit per pixel Y plane with bytes YYY.
  // Offset height * stride:
  // 8 bit UV data interleaved bytes as UVUVUV.
  //
  // Y plane has line stride >= width.
  //
  // In this context, both width and height are required to be even.
  //
  // The UV data is separated into "lines", with each "line" having same byte
  // width as a line of Y data, and same "line" stride as Y data's line stride.
  // The UV data has height / 2 "lines".
  //
  // In converting to RGB, the UV data gets up-scaled by 2x in both directions
  // overall.  This comment is intentionally silent on exactly how UV up-scaling
  // phase/filtering/signal processing works, as it's a complicated topic that
  // can vary by implementation, typically trading off speed and quality of the
  // up-scaling.  See comments in relevant conversion code for approach taken
  // by any given convert path.  The precise relative phase of the UV data is
  // not presently conveyed.
  NV12 = 2;

  // YV12
  //
  // Like I420, except with V and U swapped.
  //
  // 4:2:0 (2x down-sampled UV in both directions)
  //
  // Offset 0:
  // 8 bit per pixel Y plane with bytes YYY.
  // Offset height * stride:
  // 8 bit V data with uv_stride = stride / 2
  // Offset height * stride + uv_stride * height / 2:
  // 8 bit U data with uv_stride = stride / 2
  //
  // Y plane has line stride >= width.
  //
  // Both width and height are required to be even.
  YV12 = 3;
};

// Specifies how pixel color information should be interpreted.
enum ColorSpace {
  SRGB = 0;
};

// Specifies how pixels are arranged in memory.
enum Tiling {
  // Pixels are packed linearly.
  // Equivalent to |VK_IMAGE_TILING_LINEAR|.
  LINEAR = 0;

  // Pixels are packed in a GPU-dependent optimal format.
  // Equivalent to |VK_IMAGE_TILING_OPTIMAL|.
  GPU_OPTIMAL = 1;
};

// Specifies how alpha information should be interpreted.
enum AlphaFormat {
  // Image is considered to be opaque.  Alpha channel is ignored.
  // Blend function is: src.RGB
  OPAQUE = 0;
  // Color channels have been premultiplied by alpha.
  // Blend function is: src.RGB + (dest.RGB * (1 - src.A))
  PREMULTIPLIED = 1;
  // Color channels have not been premultiplied by alpha.
  // Blend function is: (src.RGB * src.A) + (dest.RGB * (1 - src.A))
  NON_PREMULTIPLIED = 2;
};

enum Transform {
  // Pixels are displayed normally.
  NORMAL = 0;

  // Pixels are mirrored left-right.
  FLIP_HORIZONTAL = 1;

  // Pixels are flipped vertically.
  FLIP_VERTICAL = 2;

  // Pixels are flipped vertically and mirrored left-right.
  FLIP_VERTICAL_AND_HORIZONTAL = 3;
};

// Information about a graphical image (texture) including its format and size.
struct ImageInfo {
  // Specifies if the image should be mirrored before displaying.
  Transform transform = NORMAL;

  // The width and height of the image in pixels.
  uint32 width;
  uint32 height;

  // The number of bytes per row in the image buffer.
  uint32 stride;

  // The pixel format of the image.
  PixelFormat pixel_format = BGRA_8;

  // The pixel color space.
  ColorSpace color_space = SRGB;

  // The pixel arrangement in memory.
  Tiling tiling = LINEAR;

  // Specifies the interpretion of the alpha channel, if one exists.
  AlphaFormat alpha_format = OPAQUE;
};