// Aseprite Document Library
// Copyright (c) 2020-2022 Igara Studio S.A.
// Copyright (c) 2001-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.

#ifndef DOC_COLOR_H_INCLUDED
#define DOC_COLOR_H_INCLUDED
#pragma once

#include "base/ints.h"

namespace doc {

// The greatest int type to storage a color for an image in the
// available pixel formats.
typedef uint32_t color_t;

//////////////////////////////////////////////////////////////////////
// RGBA

const uint32_t rgba_r_shift = 0;
const uint32_t rgba_g_shift = 8;
const uint32_t rgba_b_shift = 16;
const uint32_t rgba_a_shift = 24;

const uint32_t rgba_r_mask = 0x000000ff;
const uint32_t rgba_g_mask = 0x0000ff00;
const uint32_t rgba_b_mask = 0x00ff0000;
const uint32_t rgba_rgb_mask = 0x00ffffff;
const uint32_t rgba_a_mask = 0xff000000;

inline uint8_t rgba_getr(uint32_t c)
{
  return (c >> rgba_r_shift) & 0xff;
}

inline uint8_t rgba_getg(uint32_t c)
{
  return (c >> rgba_g_shift) & 0xff;
}

inline uint8_t rgba_getb(uint32_t c)
{
  return (c >> rgba_b_shift) & 0xff;
}

inline uint8_t rgba_geta(uint32_t c)
{
  return (c >> rgba_a_shift) & 0xff;
}

inline uint32_t rgba_seta(uint32_t c, uint8_t a)
{
  return ((c & rgba_rgb_mask) | (a << rgba_a_shift));
}

inline uint32_t rgba(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{
  return ((r << rgba_r_shift) | (g << rgba_g_shift) | (b << rgba_b_shift) | (a << rgba_a_shift));
}

inline int rgb_luma(int r, int g, int b)
{
  return (r * 2126 + g * 7152 + b * 722) / 10000;
}

inline uint8_t rgba_luma(uint32_t c)
{
  return rgb_luma(rgba_getr(c), rgba_getg(c), rgba_getb(c));
}

//////////////////////////////////////////////////////////////////////
// Grayscale

const uint16_t graya_v_shift = 0;
const uint16_t graya_a_shift = 8;

const uint16_t graya_v_mask = 0x00ff;
const uint16_t graya_a_mask = 0xff00;

inline uint8_t graya_getv(uint16_t c)
{
  return (c >> graya_v_shift) & 0xff;
}

inline uint8_t graya_geta(uint16_t c)
{
  return (c >> graya_a_shift) & 0xff;
}

inline uint16_t graya_seta(uint16_t c, uint8_t a)
{
  return ((c & graya_v_mask) | (a << graya_a_shift));
}

inline uint16_t graya(uint8_t v, uint8_t a)
{
  return ((v << graya_v_shift) | (a << graya_a_shift));
}

inline uint16_t gray(uint8_t v)
{
  return graya(v, 255);
}

//////////////////////////////////////////////////////////////////////
// Conversions

typedef color_t (*rgba_to_graya_func)(const color_t c);

color_t rgba_to_graya_using_hsv(const color_t c);
color_t rgba_to_graya_using_hsl(const color_t c);
color_t rgba_to_graya_using_luma(const color_t c);

} // namespace doc

#endif
