diff --git a/rdpy/display/qt.py b/rdpy/display/qt.py index 632a600..8fc5a12 100644 --- a/rdpy/display/qt.py +++ b/rdpy/display/qt.py @@ -27,6 +27,9 @@ from PyQt4 import QtGui, QtCore from rdpy.protocol.rfb.rfb import RFBClientObserver from rdpy.protocol.rdp.rdp import RDPClientObserver +from rdpy.network.type import UInt16Le, Stream +import rle + class QAdaptor(object): ''' adaptor model with link between protocol @@ -148,6 +151,7 @@ class RDPClientQt(RDPClientObserver, QAdaptor): ''' #TODO if isCompress: + #rle.decode("", Stream(data), width, height, UInt16Le) return imageFormat = None diff --git a/rdpy/display/rle.py b/rdpy/display/rle.py index 40cdeaa..e9295b8 100644 --- a/rdpy/display/rle.py +++ b/rdpy/display/rle.py @@ -16,6 +16,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # +from rdpy.network.error import InvalidExpectedDataException """ Run length Encoding Algorithm implementation @@ -26,23 +27,87 @@ Most of bitmap in RDP protocol use this encoding @see: http://msdn.microsoft.com/en-us/library/dd240593.aspx """ -from rdpy.network.type import UInt8 +from rdpy.network.type import UInt8, UInt16Le, Stream, sizeof -def extractCodeId(data): - ''' - Read first unsigned char - ''' - res = UInt8() - data.readType(res) - return res - -def decode(dst, src, rowDelta): - - insertFgPel = False - firstLine = True +def decode(src, width, height, colorType): + """ + It's a python transcription of rdesktop algorithm + """ + lastopcode = -1 + x = width + prevline = 0 + code = UInt8() + opcode = UInt8() + color1 = colorType() + color2 = colorType() + mix = colorType() + isFillOrMix = False + insertMix = False + fom_mask = 0 + mask = 0 + dst = Stream("\x00" * (width * height * sizeof(colorType()))) while src.dataLen() > 0: - if firstLine: - firstLine = False - insertFgPel = False - + #compute orders + + src.readType(code) + opcode = code >> 4 + count = UInt16Le() + + + if opcode == 0xc or opcode == 0xd or opcode == 0xe: + opcode -= 6 + count = code & 0xf + offset = 16 + elif opcode == 0xf: + opcode = code & 0xf + if opcode < 9: + src.readType(count) + else: + count = UInt16Le(8 if opcode < 0xb else 1) + offset = 0 + else: + opcode >>= 1 + count = UInt16Le((code & 0xf).value) + offset = 32 + + if offset != 0: + isFillOrMix = opcode == 2 or opcode == 7 + if count == 0: + tmp = UInt8() + src.readType(tmp) + if isFillOrMix: + count = UInt16Le((tmp + 1).value) + else: + count = UInt16Le((tmp + offset).value) + elif isFillOrMix: + count <<= 3 + + + if opcode == 0: + if lastopcode == opcode and not (x == width and prevline == 0): + insertMix = True + elif opcode == 3 or opcode == 8: + src.readType(color2) + if opcode == 8: + src.readType(color1) + elif opcode == 6 or opcode == 7: + src.readType(mix) + elif opcode == 9: + mask = 0x03 + opcode = UInt8(0x02) + fom_mask = 5 + + lastopcode = opcode + mixmask = 0 + + while count > 0: + if x > width: + if height <= 0: + raise InvalidExpectedDataException("In RLE decompression height must be greater than 0") + x = 0 + height -= 1 + #prevline = line + return dst + + \ No newline at end of file