blob: 6c692708f29d199a1df4a7cbee5831f536eaf513 [file] [log] [blame]
enikey27a239d2008-12-19 07:32:05 +00001package com.tightvnc.decoder;
2
enikey6aa2dbc2008-12-19 07:38:11 +00003import com.tightvnc.vncviewer.InStream;
enikey27a239d2008-12-19 07:32:05 +00004import com.tightvnc.vncviewer.RfbInputStream;
enikey6aa2dbc2008-12-19 07:38:11 +00005import com.tightvnc.vncviewer.ZlibInStream;
enikey27a239d2008-12-19 07:32:05 +00006import java.awt.Graphics;
7
8//
9// Class that used for decoding ZRLE encoded data.
10//
11
enikey6aa2dbc2008-12-19 07:38:11 +000012public class ZRLEDecoder extends RawDecoder {
enikey27a239d2008-12-19 07:32:05 +000013
14 public ZRLEDecoder(Graphics g, RfbInputStream is) {
15 super(g, is);
16 }
17
18 public ZRLEDecoder(Graphics g, RfbInputStream is, int frameBufferW,
19 int frameBufferH) {
20 super(g, is, frameBufferW, frameBufferH);
21 }
22
enikey6aa2dbc2008-12-19 07:38:11 +000023 //
24 // Private methods for reading ZRLE data
25 //
26
27 private int readPixel(InStream is) throws Exception {
28 int pix;
29 if (bytesPerPixel == 1) {
30 pix = is.readU8();
31 } else {
32 int p1 = is.readU8();
33 int p2 = is.readU8();
34 int p3 = is.readU8();
35 pix = (p3 & 0xFF) << 16 | (p2 & 0xFF) << 8 | (p1 & 0xFF);
36 }
37 return pix;
38 }
39
40 private void readPixels(InStream is, int[] dst, int count) throws Exception {
41 if (bytesPerPixel == 1) {
42 byte[] buf = new byte[count];
43 is.readBytes(buf, 0, count);
44 for (int i = 0; i < count; i++) {
45 dst[i] = (int)buf[i] & 0xFF;
46 }
47 } else {
48 byte[] buf = new byte[count * 3];
49 is.readBytes(buf, 0, count * 3);
50 for (int i = 0; i < count; i++) {
51 dst[i] = ((buf[i*3+2] & 0xFF) << 16 |
52 (buf[i*3+1] & 0xFF) << 8 |
53 (buf[i*3] & 0xFF));
54 }
55 }
56 }
57
58 private void readZrlePalette(int[] palette, int palSize) throws Exception {
59 readPixels(zrleInStream, palette, palSize);
60 }
61
62 private void readZrleRawPixels(int tw, int th) throws Exception {
63 if (bytesPerPixel == 1) {
64 zrleInStream.readBytes(zrleTilePixels8, 0, tw * th);
65 } else {
66 readPixels(zrleInStream, zrleTilePixels24, tw * th); ///
67 }
68 }
69
70 private void readZrlePackedPixels(int tw, int th, int[] palette, int palSize)
71 throws Exception {
72
73 int bppp = ((palSize > 16) ? 8 :
74 ((palSize > 4) ? 4 : ((palSize > 2) ? 2 : 1)));
75 int ptr = 0;
76
77 for (int i = 0; i < th; i++) {
78 int eol = ptr + tw;
79 int b = 0;
80 int nbits = 0;
81
82 while (ptr < eol) {
83 if (nbits == 0) {
84 b = zrleInStream.readU8();
85 nbits = 8;
86 }
87 nbits -= bppp;
88 int index = (b >> nbits) & ((1 << bppp) - 1) & 127;
89 if (bytesPerPixel == 1) {
90 zrleTilePixels8[ptr++] = (byte)palette[index];
91 } else {
92 zrleTilePixels24[ptr++] = palette[index];
93 }
94 }
95 }
96 }
97
98 private void readZrlePlainRLEPixels(int tw, int th) throws Exception {
99 int ptr = 0;
100 int end = ptr + tw * th;
101 while (ptr < end) {
102 int pix = readPixel(zrleInStream);
103 int len = 1;
104 int b;
105 do {
106 b = zrleInStream.readU8();
107 len += b;
108 } while (b == 255);
109
110 if (!(len <= end - ptr))
111 throw new Exception("ZRLE decoder: assertion failed" +
112 " (len <= end-ptr)");
113
114 if (bytesPerPixel == 1) {
115 while (len-- > 0) zrleTilePixels8[ptr++] = (byte)pix;
116 } else {
117 while (len-- > 0) zrleTilePixels24[ptr++] = pix;
118 }
119 }
120 }
121
122 private void readZrlePackedRLEPixels(int tw, int th, int[] palette)
123 throws Exception {
124
125 int ptr = 0;
126 int end = ptr + tw * th;
127 while (ptr < end) {
128 int index = zrleInStream.readU8();
129 int len = 1;
130 if ((index & 128) != 0) {
131 int b;
132 do {
133 b = zrleInStream.readU8();
134 len += b;
135 } while (b == 255);
136
137 if (!(len <= end - ptr))
138 throw new Exception("ZRLE decoder: assertion failed" +
139 " (len <= end - ptr)");
140 }
141
142 index &= 127;
143 int pix = palette[index];
144
145 if (bytesPerPixel == 1) {
146 while (len-- > 0) zrleTilePixels8[ptr++] = (byte)pix;
147 } else {
148 while (len-- > 0) zrleTilePixels24[ptr++] = pix;
149 }
150 }
151 }
152
153 //
154 // ZRLE encoder's data.
155 //
156
157 private byte[] zrleBuf;
158 private int zrleBufLen = 0;
159 private byte[] zrleTilePixels8;
160 private int[] zrleTilePixels24;
161 private ZlibInStream zrleInStream;
162 private boolean zrleRecWarningShown = false;
enikey27a239d2008-12-19 07:32:05 +0000163}