teleport/client/tp-player/update_data.cpp

171 lines
4.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "update_data.h"
#include "rle.h"
#include <QImage>
#include <QDebug>
static QImage* _rdpimg2QImage(int w, int h, int bitsPerPixel, bool isCompressed, const uint8_t* dat, uint32_t len) {
QImage* out;
switch(bitsPerPixel) {
case 15:
if(isCompressed) {
uint8_t* _dat = reinterpret_cast<uint8_t*>(calloc(1, w*h*2));
if(!bitmap_decompress1(_dat, w, h, dat, len)) {
free(_dat);
return nullptr;
}
out = new QImage(_dat, w, h, QImage::Format_RGB555);
free(_dat);
}
else {
out = new QImage(QImage(dat, w, h, QImage::Format_RGB555).transformed(QMatrix(1.0, 0.0, 0.0, -1.0, 0.0, 0.0)));
}
return out;
case 16:
if(isCompressed) {
uint8_t* _dat = reinterpret_cast<uint8_t*>(calloc(1, w*h*2));
if(!bitmap_decompress2(_dat, w, h, dat, len)) {
free(_dat);
return nullptr;
}
// TODO: 这里需要进一步优化直接操作QImage的buffer。
out = new QImage(w, h, QImage::Format_RGB16);
for(int y = 0; y < h; y++) {
for(int x = 0; x < w; x++) {
uint16 a = ((uint16*)_dat)[y * w + x];
uint8 r = ((a & 0xf800) >> 11) * 255 / 31;
uint8 g = ((a & 0x07e0) >> 5) * 255 / 63;
uint8 b = (a & 0x001f) * 255 / 31;
out->setPixelColor(x, y, QColor(r,g,b));
}
}
free(_dat);
return out;
}
else {
out = new QImage(QImage(dat, w, h, QImage::Format_RGB16).transformed(QMatrix(1.0, 0.0, 0.0, -1.0, 0.0, 0.0)));
}
return out;
case 24:
case 32:
default:
qDebug() << "--------NOT support UNKNOWN bitsPerPix" << bitsPerPixel;
return nullptr;
}
}
UpdateData::UpdateData() : QObject(nullptr)
{
_init();
}
UpdateData::UpdateData(int data_type) : QObject(nullptr)
{
_init();
m_data_type = data_type;
}
UpdateData::UpdateData(const TS_RECORD_HEADER& hdr) : QObject(nullptr)
{
_init();
m_data_type = TYPE_HEADER_INFO;
m_hdr = new TS_RECORD_HEADER;
memcpy(m_hdr, &hdr, sizeof(TS_RECORD_HEADER));
}
void UpdateData::_init() {
m_data_type = TYPE_UNKNOWN;
m_hdr = nullptr;
m_pointer = nullptr;
m_img = nullptr;
// m_img_info = nullptr;
m_data_buf = nullptr;
m_data_len = 0;
m_time_ms = 0;
}
UpdateData::~UpdateData() {
if(m_hdr)
delete m_hdr;
if(m_pointer)
delete m_pointer;
if(m_img)
delete m_img;
// if(m_img_info)
// delete m_img_info;
if(m_data_buf)
delete m_data_buf;
}
bool UpdateData::parse(const TS_RECORD_PKG& pkg, const QByteArray& data) {
m_time_ms = pkg.time_ms;
if(pkg.type == TS_RECORD_TYPE_RDP_POINTER) {
m_data_type = TYPE_POINTER;
if(data.size() != sizeof(TS_RECORD_RDP_POINTER))
return false;
m_pointer = new TS_RECORD_RDP_POINTER;
memcpy(m_pointer, data.data(), sizeof(TS_RECORD_RDP_POINTER));
return true;
}
else if(pkg.type == TS_RECORD_TYPE_RDP_IMAGE) {
m_data_type = TYPE_IMAGE;
if(data.size() <= sizeof(TS_RECORD_RDP_IMAGE_INFO))
return false;
const TS_RECORD_RDP_IMAGE_INFO* info = reinterpret_cast<const TS_RECORD_RDP_IMAGE_INFO*>(data.data());
const uint8_t* img_dat = reinterpret_cast<const uint8_t*>(data.data() + sizeof(TS_RECORD_RDP_IMAGE_INFO));
uint32_t img_len = data.size() - sizeof(TS_RECORD_RDP_IMAGE_INFO);
QImage* img = _rdpimg2QImage(info->width, info->height, info->bitsPerPixel, (info->format == TS_RDP_IMG_BMP) ? true : false, img_dat, img_len);
if(img == nullptr)
return false;
m_img = img;
m_img_x = info->destLeft;
m_img_y = info->destTop;
m_img_w = info->destRight - info->destLeft + 1;
m_img_h = info->destBottom - info->destTop + 1;
// m_img_info = new TS_RECORD_RDP_IMAGE_INFO;
// memcpy(m_img_info, data.data(), sizeof(TS_RECORD_RDP_IMAGE_INFO));
// m_data_buf = new uint8_t[img_len];
// memcpy(m_data_buf, img_dat, img_len);
// m_data_len = img_len;
return true;
}
else if(pkg.type == TS_RECORD_TYPE_RDP_KEYFRAME) {
return true;
}
return false;
}
void UpdateData::alloc_data(uint32_t len) {
if(m_data_buf)
delete m_data_buf;
m_data_buf = new uint8_t[len];
memset(m_data_buf, 0, len);
m_data_len = len;
}
void UpdateData::attach_data(const uint8_t* dat, uint32_t len) {
if(m_data_buf)
delete m_data_buf;
m_data_buf = new uint8_t[len];
memcpy(m_data_buf, dat, len);
m_data_len = len;
}