/*  Rgbycci.java
 *  Simple program to demonstrate conversion from RGB to YCbCr and vice 
 *  versa using ITU-R recommendation BT.601, and integer-arithmetic.
 *  Since Java does not have data type "unsigned char", we use "int". 
 *  Compile: $javac rgbycci.java
 *  Execute: $java  rgbycci
 */
import java.io.*;

/* Note:
 * 2ˆ16 = 65536
 * kr = 0.299 = 19595 / 2ˆ16
 * kg = 0.587 = 38470 / 2ˆ16
 * Kb = 0.114 = 7471 / 2ˆ16
 * 0.5 = 128 / 255
 * 0.564 = 36962 / 2ˆ16
 * 0.713 = 46727 / 2ˆ16
 * 1.402 = 91881 / 2ˆ16
 * 0.701 = 135 / 255
 * 0.714 = 46793 / 2ˆ16
 * 0.344 = 22544 / 2ˆ16
 * 0.529 = 34668 / 2ˆ16
 * 1.772 = 116129 / 2ˆ16
 * 0.886 = 226 / 255
 */

class Rgbycci {
  public static void main(String[] args) {
    int R, G, B;     //RGB components
    int Y, Cb, Cr;   //YCbCr components
    //some sample values for demo
    R = 252; G = 120; B = 3;

    //convert from RGB to YCbcr
    Y = ( 19595 * R + 38470 * G + 7471 * B ) >> 16;
    Cb = ( 36962 * ( B - Y ) >> 16) + 128;
    Cr = (46727 * ( R - Y ) >> 16) + 128;
    System.out.printf("\nOriginal RGB & corresponding YCbCr values:");
    System.out.printf("\n\tR = %6d, G = %6d, B = %6d", R, G, B );
    System.out.printf("\n\tY = %6d, Cb = %6d, Cr = %6d", Y, Cb, Cr );

    //convert from YCbCr to RGB
    R = Y + (91881 * Cr >> 16) - 179;
    G = Y -( ( 22544 * Cb + 46793 * Cr ) >> 16) + 135;
    B = Y + (116129 * Cb >> 16) - 226;
    System.out.printf("\n\nRecovered RGB values:");
    System.out.printf("\n\tR = %6d, G = %6d, B = %6d\n\n", R, G, B );
  }
}
