Copyright 2011 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

package color
RGBToYCbCr converts an RGB triple to a Y'CbCr triple.
The JFIF specification says: Y' = 0.2990*R + 0.5870*G + 0.1140*B Cb = -0.1687*R - 0.3313*G + 0.5000*B + 128 Cr = 0.5000*R - 0.4187*G - 0.0813*B + 128 https://www.w3.org/Graphics/JPEG/jfif3.pdf says Y but means Y'.

	 := int32()
	 := int32()
	 := int32()
yy is in range [0,0xff]. Note that 19595 + 38470 + 7471 equals 65536.
	 := (19595* + 38470* + 7471* + 1<<15) >> 16
The bit twiddling below is equivalent to cb := (-11056*r1 - 21712*g1 + 32768*b1 + 257<<15) >> 16 if cb < 0 { cb = 0 } else if cb > 0xff { cb = ^int32(0) } but uses fewer branches and is faster. Note that the uint8 type conversion in the return statement will convert ^int32(0) to 0xff. The code below to compute cr uses a similar pattern. Note that -11056 - 21712 + 32768 equals 0.
	 := -11056* - 21712* + 32768* + 257<<15
	if uint32()&0xff000000 == 0 {
		 >>= 16
	} else {
		 = ^( >> 31)
	}
Note that 32768 - 27440 - 5328 equals 0.
	 := 32768* - 27440* - 5328* + 257<<15
	if uint32()&0xff000000 == 0 {
		 >>= 16
	} else {
		 = ^( >> 31)
	}

	return uint8(), uint8(), uint8()
}
YCbCrToRGB converts a Y'CbCr triple to an RGB triple.
The JFIF specification says: R = Y' + 1.40200*(Cr-128) G = Y' - 0.34414*(Cb-128) - 0.71414*(Cr-128) B = Y' + 1.77200*(Cb-128) https://www.w3.org/Graphics/JPEG/jfif3.pdf says Y but means Y'. Those formulae use non-integer multiplication factors. When computing, integer math is generally faster than floating point math. We multiply all of those factors by 1<<16 and round to the nearest integer: 91881 = roundToNearestInteger(1.40200 * 65536). 22554 = roundToNearestInteger(0.34414 * 65536). 46802 = roundToNearestInteger(0.71414 * 65536). 116130 = roundToNearestInteger(1.77200 * 65536). Adding a rounding adjustment in the range [0, 1<<16-1] and then shifting right by 16 gives us an integer math version of the original formulae. R = (65536*Y' + 91881 *(Cr-128) + adjustment) >> 16 G = (65536*Y' - 22554 *(Cb-128) - 46802*(Cr-128) + adjustment) >> 16 B = (65536*Y' + 116130 *(Cb-128) + adjustment) >> 16 A constant rounding adjustment of 1<<15, one half of 1<<16, would mean round-to-nearest when dividing by 65536 (shifting right by 16). Similarly, a constant rounding adjustment of 0 would mean round-down. Defining YY1 = 65536*Y' + adjustment simplifies the formulae and requires fewer CPU operations: R = (YY1 + 91881 *(Cr-128) ) >> 16 G = (YY1 - 22554 *(Cb-128) - 46802*(Cr-128)) >> 16 B = (YY1 + 116130 *(Cb-128) ) >> 16 The inputs (y, cb, cr) are 8 bit color, ranging in [0x00, 0xff]. In this function, the output is also 8 bit color, but in the related YCbCr.RGBA method, below, the output is 16 bit color, ranging in [0x0000, 0xffff]. Outputting 16 bit color simply requires changing the 16 to 8 in the "R = etc >> 16" equation, and likewise for G and B. As mentioned above, a constant rounding adjustment of 1<<15 is a natural choice, but there is an additional constraint: if c0 := YCbCr{Y: y, Cb: 0x80, Cr: 0x80} and c1 := Gray{Y: y} then c0.RGBA() should equal c1.RGBA(). Specifically, if y == 0 then "R = etc >> 8" should yield 0x0000 and if y == 0xff then "R = etc >> 8" should yield 0xffff. If we used a constant rounding adjustment of 1<<15, then it would yield 0x0080 and 0xff80 respectively. Note that when cb == 0x80 and cr == 0x80 then the formulae collapse to: R = YY1 >> n G = YY1 >> n B = YY1 >> n where n is 16 for this function (8 bit color output) and 8 for the YCbCr.RGBA method (16 bit color output). The solution is to make the rounding adjustment non-constant, and equal to 257*Y', which ranges over [0, 1<<16-1] as Y' ranges over [0, 255]. YY1 is then defined as: YY1 = 65536*Y' + 257*Y' or equivalently: YY1 = Y' * 0x10101
	 := int32() * 0x10101
	 := int32() - 128
	 := int32() - 128
The bit twiddling below is equivalent to r := (yy1 + 91881*cr1) >> 16 if r < 0 { r = 0 } else if r > 0xff { r = ^int32(0) } but uses fewer branches and is faster. Note that the uint8 type conversion in the return statement will convert ^int32(0) to 0xff. The code below to compute g and b uses a similar pattern.
	 :=  + 91881*
	if uint32()&0xff000000 == 0 {
		 >>= 16
	} else {
		 = ^( >> 31)
	}

	 :=  - 22554* - 46802*
	if uint32()&0xff000000 == 0 {
		 >>= 16
	} else {
		 = ^( >> 31)
	}

	 :=  + 116130*
	if uint32()&0xff000000 == 0 {
		 >>= 16
	} else {
		 = ^( >> 31)
	}

	return uint8(), uint8(), uint8()
}
YCbCr represents a fully opaque 24-bit Y'CbCr color, having 8 bits each for one luma and two chroma components. JPEG, VP8, the MPEG family and other codecs use this color model. Such codecs often use the terms YUV and Y'CbCr interchangeably, but strictly speaking, the term YUV applies only to analog video signals, and Y' (luma) is Y (luminance) after applying gamma correction. Conversion between RGB and Y'CbCr is lossy and there are multiple, slightly different formulae for converting between the two. This package follows the JFIF specification at https://www.w3.org/Graphics/JPEG/jfif3.pdf.
type YCbCr struct {
	Y, Cb, Cr uint8
}

This code is a copy of the YCbCrToRGB function above, except that it returns values in the range [0, 0xffff] instead of [0, 0xff]. There is a subtle difference between doing this and having YCbCr satisfy the Color interface by first converting to an RGBA. The latter loses some information by going to and from 8 bits per channel. For example, this code: const y, cb, cr = 0x7f, 0x7f, 0x7f r, g, b := color.YCbCrToRGB(y, cb, cr) r0, g0, b0, _ := color.YCbCr{y, cb, cr}.RGBA() r1, g1, b1, _ := color.RGBA{r, g, b, 0xff}.RGBA() fmt.Printf("0x%04x 0x%04x 0x%04x\n", r0, g0, b0) fmt.Printf("0x%04x 0x%04x 0x%04x\n", r1, g1, b1) prints: 0x7e18 0x808d 0x7db9 0x7e7e 0x8080 0x7d7d

	 := int32(.Y) * 0x10101
	 := int32(.Cb) - 128
	 := int32(.Cr) - 128
The bit twiddling below is equivalent to r := (yy1 + 91881*cr1) >> 8 if r < 0 { r = 0 } else if r > 0xff { r = 0xffff } but uses fewer branches and is faster. The code below to compute g and b uses a similar pattern.
	 :=  + 91881*
	if uint32()&0xff000000 == 0 {
		 >>= 8
	} else {
		 = ^( >> 31) & 0xffff
	}

	 :=  - 22554* - 46802*
	if uint32()&0xff000000 == 0 {
		 >>= 8
	} else {
		 = ^( >> 31) & 0xffff
	}

	 :=  + 116130*
	if uint32()&0xff000000 == 0 {
		 >>= 8
	} else {
		 = ^( >> 31) & 0xffff
	}

	return uint32(), uint32(), uint32(), 0xffff
}
YCbCrModel is the Model for Y'CbCr colors.
var YCbCrModel Model = ModelFunc(yCbCrModel)

func ( Color) Color {
	if ,  := .(YCbCr);  {
		return 
	}
	, , ,  := .RGBA()
	, ,  := RGBToYCbCr(uint8(>>8), uint8(>>8), uint8(>>8))
	return YCbCr{, , }
}
NYCbCrA represents a non-alpha-premultiplied Y'CbCr-with-alpha color, having 8 bits each for one luma, two chroma and one alpha component.
type NYCbCrA struct {
	YCbCr
	A uint8
}

The first part of this method is the same as YCbCr.RGBA.
	 := int32(.Y) * 0x10101
	 := int32(.Cb) - 128
	 := int32(.Cr) - 128
The bit twiddling below is equivalent to r := (yy1 + 91881*cr1) >> 8 if r < 0 { r = 0 } else if r > 0xff { r = 0xffff } but uses fewer branches and is faster. The code below to compute g and b uses a similar pattern.
	 :=  + 91881*
	if uint32()&0xff000000 == 0 {
		 >>= 8
	} else {
		 = ^( >> 31) & 0xffff
	}

	 :=  - 22554* - 46802*
	if uint32()&0xff000000 == 0 {
		 >>= 8
	} else {
		 = ^( >> 31) & 0xffff
	}

	 :=  + 116130*
	if uint32()&0xff000000 == 0 {
		 >>= 8
	} else {
		 = ^( >> 31) & 0xffff
	}
The second part of this method applies the alpha.
	 := uint32(.A) * 0x101
	return uint32() *  / 0xffff, uint32() *  / 0xffff, uint32() *  / 0xffff, 
}
NYCbCrAModel is the Model for non-alpha-premultiplied Y'CbCr-with-alpha colors.
var NYCbCrAModel Model = ModelFunc(nYCbCrAModel)

func ( Color) Color {
	switch c := .(type) {
	case NYCbCrA:
		return 
	case YCbCr:
		return NYCbCrA{, 0xff}
	}
	, , ,  := .RGBA()
Convert from alpha-premultiplied to non-alpha-premultiplied.
	if  != 0 {
		 = ( * 0xffff) / 
		 = ( * 0xffff) / 
		 = ( * 0xffff) / 
	}

	, ,  := RGBToYCbCr(uint8(>>8), uint8(>>8), uint8(>>8))
	return NYCbCrA{YCbCr{Y: , Cb: , Cr: }, uint8( >> 8)}
}
RGBToCMYK converts an RGB triple to a CMYK quadruple.
func (, ,  uint8) (uint8, uint8, uint8, uint8) {
	 := uint32()
	 := uint32()
	 := uint32()
	 := 
	if  <  {
		 = 
	}
	if  <  {
		 = 
	}
	if  == 0 {
		return 0, 0, 0, 0xff
	}
	 := ( - ) * 0xff / 
	 := ( - ) * 0xff / 
	 := ( - ) * 0xff / 
	return uint8(), uint8(), uint8(), uint8(0xff - )
}
CMYKToRGB converts a CMYK quadruple to an RGB triple.
func (, , ,  uint8) (uint8, uint8, uint8) {
	 := 0xffff - uint32()*0x101
	 := (0xffff - uint32()*0x101) *  / 0xffff
	 := (0xffff - uint32()*0x101) *  / 0xffff
	 := (0xffff - uint32()*0x101) *  / 0xffff
	return uint8( >> 8), uint8( >> 8), uint8( >> 8)
}
CMYK represents a fully opaque CMYK color, having 8 bits for each of cyan, magenta, yellow and black. It is not associated with any particular color profile.
type CMYK struct {
	C, M, Y, K uint8
}

This code is a copy of the CMYKToRGB function above, except that it returns values in the range [0, 0xffff] instead of [0, 0xff].

	 := 0xffff - uint32(.K)*0x101
	 := (0xffff - uint32(.C)*0x101) *  / 0xffff
	 := (0xffff - uint32(.M)*0x101) *  / 0xffff
	 := (0xffff - uint32(.Y)*0x101) *  / 0xffff
	return , , , 0xffff
}
CMYKModel is the Model for CMYK colors.
var CMYKModel Model = ModelFunc(cmykModel)

func ( Color) Color {
	if ,  := .(CMYK);  {
		return 
	}
	, , ,  := .RGBA()
	, , ,  := RGBToCMYK(uint8(>>8), uint8(>>8), uint8(>>8))
	return CMYK{, , , }