Slow work on colourspace decoding
[jirac.git] / org / diracvideo / Jirac / ColourSpace.java
blobf72ea2015a3500c2da3de5d1c8280ebb046fa2e0
1 package org.diracvideo.Jirac;
2 import java.awt.Dimension;
3 import java.awt.image.BufferedImage;
5 public class ColourSpace {
6 private VideoFormat format;
7 private int rgb_table[][], matrix[][], rgb_pixels[];
8 private int decodeMode;
10 public ColourSpace(int colourmode, VideoFormat fmt) {
11 format = fmt;
12 rgb_pixels = new int[fmt.width*fmt.height];
13 decodeMode = fmt.chromaHShift() | (fmt.chromaVShift() << 1);
14 setupTables();
17 private void setupTables() {
18 matrix = new int[3][3];
19 rgb_table = new int[9][255];
20 setupMatrix(0.2990, 0.1140);
21 for(int c = 0; c < 3; c++) {
22 for(int i = 0; i < 255; i++) {
23 rgb_table[3*c][i] = (matrix[0][c]*i)>>16;
24 rgb_table[3*c+1][i] = (matrix[1][c]*i)>>16;
25 rgb_table[3*c+2][i] = (matrix[2][c]*i)>>16;
30 private void setupMatrix(double kr, double kb) {
31 double kg = 1.0 - kr - kb;
32 int factor = 1 << 16;
33 matrix[0][0] = matrix[1][0] = matrix[2][0] = factor;
34 matrix[0][2] = (int)(2*(1-kr)*factor);
35 matrix[1][1] = (int)((-2*kb*(1-kb)/kg)*factor);
36 matrix[1][2] = (int)((-2*kr*(1-kr)/kg)*factor);
37 matrix[2][1] = (int)(2*(1-kb)*factor);
40 public synchronized void convert(Block yuv[], BufferedImage img) {
41 Dimension lum = yuv[0].s;
42 short[] Y = yuv[0].d, U = yuv[1].d, V = yuv[2].d;
43 switch(decodeMode) {
44 case 0: /* yShift = 0, xShift = 0 */
45 for(int y = 0; y < format.height; y++) {
46 int rgbLine = y*format.width;
47 int yLine = yuv[0].line(y);
48 for(int x = 0; x < format.width; x++)
49 rgb_pixels[rgbLine+x] = YUVtoRGB(Y[yLine+x],U[yLine+x],
50 V[yLine+x]);
53 break;
54 case 1: /* yShift = 0, xShift = 1 */
55 for(int y = 0; y < format.height; y++) {
56 int rgbLine = y*format.width;
57 int yLine = yuv[0].line(y);
58 for(int x = 0; x < format.width; x++)
59 rgb_pixels[rgbLine+x] = YUVtoRGB(Y[yLine+x],U[yLine+x/2],
60 V[yLine+x/2]);
62 break;
63 case 2: /* yShift = 1, xShift = 0 */
64 for(int y = 0; y < format.height; y++) {
65 int rgbLine = y*format.width;
66 int yLine = yuv[0].line(y);
67 int uvLine = yuv[1].line(y/2);
68 for(int x = 0; x < format.width; x++)
69 rgb_pixels[rgbLine+x] = YUVtoRGB(Y[yLine+x],U[uvLine+x],
70 V[uvLine+x]);
72 break;
73 case 3: /* yShift = 1, xShift = 1 */
74 for(int y = 0; y < format.height; y++) {
75 int rgbLine = y*format.width;
76 int yLine = yuv[0].line(y);
77 int uvLine = yuv[1].line(y/2);
78 for(int x = 0; x < format.width; x++)
79 rgb_pixels[rgbLine+x] = YUVtoRGB(Y[yLine+x],U[uvLine+x/2],
80 V[uvLine+x/2]);
82 break;
83 case 4: /* yShift = 2, xShift = 0 */
84 for(int y = 0; y < format.height; y++) {
85 int rgbLine = y*format.width;
86 int yLine = yuv[0].line(y);
87 int uvLine = yuv[1].line(y/4);
88 for(int x = 0; x < format.width; x++)
89 rgb_pixels[rgbLine+x] = YUVtoRGB(Y[yLine+x],U[uvLine+x],
90 V[uvLine+x]);
92 break;
93 case 5: /* yShift = 2, xShift = 1 */
94 for(int y = 0; y < format.height; y++) {
95 int rgbLine = y*format.width;
96 int yLine = yuv[0].line(y);
97 int uvLine = yuv[1].line(y/4);
98 for(int x = 0; x < format.width; x++)
99 rgb_pixels[rgbLine+x] = YUVtoRGB(Y[yLine+x],U[uvLine+x/2],
100 V[uvLine+x/2]);
102 break;
104 img.setRGB(0,0, format.width, format.height,
105 rgb_pixels, 0, format.width);
108 private int YUVtoRGB(short y, short u, short v) {
109 return Util.clamp((y+128),0,255)*0x010101;
112 public String toString() {
113 StringBuilder sb = new StringBuilder();
114 sb.append("org.diracvideo.Jirac.ColourSpace");
115 for(int i = 0; i < 3; i++) {
116 sb.append(String.format("\n%d\t%d\t%d", matrix[i][0],
117 matrix[i][1], matrix[i][2]));
119 return sb.toString();