/*
 * hsv2rgb.h
 *
 *  Created on: Aug 3, 2023
 *      Author: true
 */

#ifndef CODE_INC_HSV2RGB_H_
#define CODE_INC_HSV2RGB_H_



#include <stdint.h>


typedef struct color_rgb {
	uint8_t r;
	uint8_t g;
	uint8_t b;
} color_rgb;

typedef struct color_hsv {
	uint16_t h;
	uint8_t s;
	uint8_t v;
} color_hsv;


#define HSV_HUE_SEXTANT		256
#define HSV_HUE_STEPS		(6 * HSV_HUE_SEXTANT)

#define HSV_HUE_MIN			0
#define HSV_HUE_MAX			(HSV_HUE_STEPS - 1)
#define HSV_SAT_MIN			0
#define HSV_SAT_MAX			255
#define HSV_VAL_MIN			0
#define HSV_VAL_MAX			255

/* Options: */
#define HSV_USE_SEXTANT_TEST	/* Limit the hue to 0...360 degrees */


void hsv2rgb_8b(uint16_t h, uint8_t s, uint8_t v, uint8_t *r, uint8_t *g , uint8_t *b);


/*
 * Macros that are common to all implementations
 */
#ifdef HSV_USE_SEXTANT_TEST
#define HSV_SEXTANT_TEST(sextant) \
	if((sextant) > 5) { \
		(sextant) = 5; \
	}

#else
#define HSV_SEXTANT_TEST(sextant)
#endif

/*
 * Pointer swapping:
 * 	sext.	r g b	r<>b	g<>b	r <> g	result
 *	0 0 0	v u c			!u v c	u v c
 *	0 0 1	d v c				d v c
 *	0 1 0	c v u	u v c			u v c
 *	0 1 1	c d v	v d c		d v c	d v c
 *	1 0 0	u c v		u v c		u v c
 *	1 0 1	v c d		v d c	d v c	d v c
 *
 * if(sextant & 2)
 * 	r <-> b
 *
 * if(sextant & 4)
 * 	g <-> b
 *
 * if(!(sextant & 6) {
 * 	if(!(sextant & 1))
 * 		r <-> g
 * } else {
 * 	if(sextant & 1)
 * 		r <-> g
 * }
 */
#define HSV_SWAPPTR(a,b)	do { uint8_t *tmp = (a); (a) = (b); (b) = tmp; } while(0)
#define HSV_POINTER_SWAP(sextant,r,g,b) \
	do { \
		if((sextant) & 2) { \
			HSV_SWAPPTR((r), (b)); \
		} \
		if((sextant) & 4) { \
			HSV_SWAPPTR((g), (b)); \
		} \
		if(!((sextant) & 6)) { \
			if(!((sextant) & 1)) { \
				HSV_SWAPPTR((r), (g)); \
			} \
		} else { \
			if((sextant) & 1) { \
				HSV_SWAPPTR((r), (g)); \
			} \
		} \
	} while(0)



#endif /* CODE_INC_HSV2RGB_H_ */
