1 /** 2 * Copyright: Mike Wey 2011 3 * License: zlib (See accompanying LICENSE file) 4 * Authors: Mike Wey 5 */ 6 7 module dmagick.ColorYUV; 8 9 import dmagick.Color; 10 11 import dmagick.c.magickType; 12 import 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 */ 25 class 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 }