comparison src/main/java/com/glavsoft/drawing/ColorDecoder.java @ 0:daa24f8a557b

TightVNC original
author YU
date Thu, 11 Sep 2014 07:30:03 +0900
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:daa24f8a557b
1 // Copyright (C) 2010, 2011, 2012, 2013 GlavSoft LLC.
2 // All rights reserved.
3 //
4 //-------------------------------------------------------------------------
5 // This file is part of the TightVNC software. Please visit our Web site:
6 //
7 // http://www.tightvnc.com/
8 //
9 // This program is free software; you can redistribute it and/or modify
10 // it under the terms of the GNU General Public License as published by
11 // the Free Software Foundation; either version 2 of the License, or
12 // (at your option) any later version.
13 //
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License along
20 // with this program; if not, write to the Free Software Foundation, Inc.,
21 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 //-------------------------------------------------------------------------
23 //
24
25 package com.glavsoft.drawing;
26
27 import com.glavsoft.exceptions.TransportException;
28 import com.glavsoft.rfb.encoding.PixelFormat;
29 import com.glavsoft.transport.Reader;
30
31 public class ColorDecoder {
32 protected byte redShift;
33 protected byte greenShift;
34 protected byte blueShift;
35 public short redMax;
36 public short greenMax;
37 public short blueMax;
38 public final int bytesPerPixel;
39 public final int bytesPerCPixel;
40 public final int bytesPerPixelTight;
41 private final byte[] buff;
42
43 private int startShift;
44 private int startShiftCompact;
45 private int addShiftItem;
46 private final boolean isTightSpecific;
47
48 public ColorDecoder(PixelFormat pf) {
49 redShift = pf.redShift;
50 greenShift = pf.greenShift;
51 blueShift = pf.blueShift;
52 redMax = pf.redMax;
53 greenMax = pf.greenMax;
54 blueMax = pf.blueMax;
55 bytesPerPixel = pf.bitsPerPixel / 8;
56 final long significant = redMax << redShift | greenMax << greenShift | blueMax << blueShift;
57 bytesPerCPixel = pf.depth <= 24 // as in RFB
58 // || 32 == pf.depth) // UltraVNC use this... :(
59 && 32 == pf.bitsPerPixel
60 && ((significant & 0x00ff000000L) == 0 || (significant & 0x000000ffL) == 0)
61 ? 3
62 : bytesPerPixel;
63 bytesPerPixelTight = 24 == pf.depth && 32 == pf.bitsPerPixel ? 3 : bytesPerPixel;
64 buff = new byte[bytesPerPixel];
65 if (0 == pf.bigEndianFlag) {
66 startShift = 0;
67 startShiftCompact = 0;
68 addShiftItem = 8;
69 } else {
70 startShift = pf.bitsPerPixel - 8;
71 startShiftCompact = Math.max(0, pf.depth - 8);
72 addShiftItem = -8;
73 }
74 isTightSpecific = 4==bytesPerPixel && 3==bytesPerPixelTight &&
75 255 == redMax && 255 == greenMax && 255 == blueMax;
76 }
77
78 protected int readColor(Reader reader) throws TransportException {
79 return getColor(reader.readBytes(buff, 0, bytesPerPixel), 0);
80 }
81
82 protected int readCompactColor(Reader reader) throws TransportException {
83 return getCompactColor(reader.readBytes(buff, 0, bytesPerCPixel), 0);
84 }
85
86 protected int readTightColor(Reader reader) throws TransportException {
87 return getTightColor(reader.readBytes(buff, 0, bytesPerPixelTight), 0);
88 }
89
90 protected int convertColor(int rawColor) {
91 return 255 * (rawColor >> redShift & redMax) / redMax << 16 |
92 255 * (rawColor >> greenShift & greenMax) / greenMax << 8 |
93 255 * (rawColor >> blueShift & blueMax) / blueMax;
94 }
95
96 public void fillRawComponents(byte[] comp, byte[] bytes, int offset) {
97 int rawColor = getRawTightColor(bytes, offset);
98 comp[0] = (byte) (rawColor >> redShift & redMax);
99 comp[1] = (byte) (rawColor >> greenShift & greenMax);
100 comp[2] = (byte) (rawColor >> blueShift & blueMax);
101 }
102
103 public int getTightColor(byte[] bytes, int offset) {
104 return convertColor(getRawTightColor(bytes, offset));
105 }
106
107 private int getRawTightColor(byte[] bytes, int offset) {
108 if (isTightSpecific)
109 return (bytes[offset++] & 0xff)<<16 |
110 (bytes[offset++] & 0xff)<<8 |
111 bytes[offset] & 0xff;
112 else
113 return getRawColor(bytes, offset);
114 }
115
116 protected int getColor(byte[] bytes, int offset) {
117 return convertColor(getRawColor(bytes, offset));
118 }
119
120 private int getRawColor(byte[] bytes, int offset) {
121 int shift = startShift;
122 int item = addShiftItem;
123 int rawColor = (bytes[offset++] & 0xff)<<shift;
124 for (int i=1; i<bytesPerPixel; ++i) {
125 rawColor |= (bytes[offset++] & 0xff)<<(shift+=item);
126 }
127 return rawColor;
128 }
129
130 protected int getCompactColor(byte[] bytes, int offset) {
131 int shift = startShiftCompact;
132 int item = addShiftItem;
133 int rawColor = (bytes[offset++] & 0xff)<<shift;
134 for (int i=1; i< bytesPerCPixel; ++i) {
135 rawColor |= (bytes[offset++] & 0xff)<<(shift+=item);
136 }
137 return convertColor(rawColor);
138 }
139
140 }