PageRenderTime 28ms CodeModel.GetById 10ms app.highlight 15ms RepoModel.GetById 1ms app.codeStats 0ms

/dmagick/ColorYUV.d

http://github.com/MikeWey/DMagick
D | 154 lines | 82 code | 20 blank | 52 comment | 3 complexity | ac3cbdb269c64d36882fd97723b212c9 MD5 | raw file
  1/**
  2 * Copyright: Mike Wey 2011
  3 * License:   zlib (See accompanying LICENSE file)
  4 * Authors:   Mike Wey
  5 */
  6
  7module dmagick.ColorYUV;
  8
  9import dmagick.Color;
 10
 11import dmagick.c.magickType;
 12import dmagick.c.quantum;
 13
 14/**
 15 * The YUV color format describes a color by using the color components
 16 * luminance and chrominance. The luminance component (Y) represents the
 17 * brightness information of a color, the chrominance components (U and V)
 18 * contain the color differences.
 19 * 
 20 * The YUV color format was developed for analog TV transmissions to provide
 21 * compatibility between black-and-white television and color television:
 22 * The luminance component is sufficient for black-and-white TV sets,
 23 * whereas color TV sets need the additional chrominance information.
 24 */
 25class ColorYUV : Color
 26{
 27	/** */
 28	this()
 29	{
 30		super();
 31	}
 32
 33	/**
 34	 * Create a YUV Color from the specified doubles.
 35	 * 
 36	 * Params:
 37	 *     y = The luminance as a value between 0.0 and 1.0
 38	 *     u = The U chrominance component as a value between -0.5 and 0.5
 39	 *     v = The V chrominance component as a value between -0.5 and 0.5
 40	 */
 41	this(double y, double u, double v, double opacity = 0)
 42	{
 43		Quantum red, green, blue;
 44
 45		convertYUVToRGB(y, u, v, red, green, blue);
 46
 47		super(red, green, blue, scaleDoubleToQuantum(opacity));
 48	}
 49
 50	/**
 51	 * Create a Color from a X11 color specification string
 52	 */
 53	this(string color)
 54	{
 55		super(color);
 56	}
 57
 58	/**
 59	 * The value for the luminance in the range [0.0 .. 1.0]
 60	 */
 61	void y(double y)
 62	{
 63		double oldY, u, v;
 64
 65		convertRGBToYUV(packet.red, packet.green, packet.blue, oldY, u, v);
 66		convertYUVToRGB(y, u, v, packet.red, packet.green, packet.blue);	
 67	}
 68	///ditto
 69	double y()
 70	{
 71		return 0.299 * scaleQuantumToDouble(packet.red) +
 72		       0.587 * scaleQuantumToDouble(packet.green) +
 73		       0.114 * scaleQuantumToDouble(packet.blue);
 74	}
 75
 76	/**
 77	 * The value for U chrominance component in the range [-0.5 .. 0.5]
 78	 */
 79	void u(double u)
 80	{
 81		double y, oldU, v;
 82
 83		convertRGBToYUV(packet.red, packet.green, packet.blue, y, oldU, v);
 84		convertYUVToRGB(y, u, v, packet.red, packet.green, packet.blue);
 85	}
 86	///ditto
 87	double u()
 88	{
 89		return -0.147 * scaleQuantumToDouble(packet.red) +
 90		       -0.289 * scaleQuantumToDouble(packet.green) +
 91		        0.436 * scaleQuantumToDouble(packet.blue);
 92	}
 93
 94	/**
 95	 * The value for V chrominance component in the range [-0.5 .. 0.5]
 96	 */
 97	void v(double v)
 98	{
 99		double y, u, oldV;
100
101		convertRGBToYUV(packet.red, packet.green, packet.blue, y, u, oldV);
102		convertYUVToRGB(y, u, v, packet.red, packet.green, packet.blue);	
103	}
104	///ditto
105	double v()
106	{
107		return  0.615 * scaleQuantumToDouble(packet.red) +
108		       -0.515 * scaleQuantumToDouble(packet.green) +
109		       -0.100 * scaleQuantumToDouble(packet.blue);
110	}
111
112	/**
113	 * Convert an RGB value to a YUV value.
114	 */
115	private void convertRGBToYUV(Quantum red, Quantum green, Quantum blue, ref double y, ref double u, ref double v)
116	{
117		// ⌈Y⌉ ⌈ 0.299  0.587  0.114⌉ ⌈R⌉
118		// |U|=|-0.147 -0.289  0.436|·|G|
119		// ⌊V⌋ ⌊ 0.615 -0.515 -0.100⌋ ⌊B⌋
120
121		double r = scaleQuantumToDouble(red);
122		double g = scaleQuantumToDouble(green);
123		double b = scaleQuantumToDouble(blue);
124
125		y =  0.299*r +  0.587*g +  0.114*b;
126		u = -0.147*r + -0.289*g +  0.436*b;
127		v =  0.615*r + -0.515*g + -0.100*b;
128	}
129
130	/**
131	 * Convert an YUV value to a RGB value.
132	 */
133	private void convertYUVToRGB(double y, double u, double v, ref Quantum red, ref Quantum green, ref Quantum blue)
134	in
135	{
136		assert(y <=  1   && y >= 0  );
137		assert(u <= -0.5 && u >= 0.5);
138		assert(v <= -0.5 && v >= 0.5);
139	}
140	body
141	{
142		// ⌈R⌉ ⌈ 1.000  0.000  1.140⌉ ⌈Y⌉
143		// |G|=| 1.000 -0.395 -0.581|·|U|
144		// ⌊B⌋ ⌊ 1.000  2.032  0.000⌋ ⌊V⌋
145
146		double r = 1.000*y +  0.000*u +  1.140*v;
147		double g = 1.000*y + -0.395*u + -0.581*v;
148		double b = 1.000*y +  2.032*u +  0.000*v;
149
150		red   = scaleDoubleToQuantum(r);
151		green = scaleDoubleToQuantum(g);
152		blue  = scaleDoubleToQuantum(b);
153	}
154}