249 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			C++
		
	
	
			
		
		
	
	
			249 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			C++
		
	
	
#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);
 | 
						||
//                qDebug() << "22------------------DECOMPRESS2 failed.";
 | 
						||
//                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;
 | 
						||
//    }
 | 
						||
//}
 | 
						||
 | 
						||
//static QImage* _raw2QImage(int w, int h, const uint8_t* dat, uint32_t len) {
 | 
						||
//    QImage* out;
 | 
						||
 | 
						||
//    // 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));
 | 
						||
//        }
 | 
						||
//    }
 | 
						||
//    return out;
 | 
						||
//}
 | 
						||
 | 
						||
UpdateData::UpdateData() : QObject(nullptr)
 | 
						||
{
 | 
						||
    _init();
 | 
						||
}
 | 
						||
 | 
						||
UpdateData::UpdateData(int data_type) : QObject(nullptr)
 | 
						||
{
 | 
						||
    _init();
 | 
						||
    m_data_type = data_type;
 | 
						||
}
 | 
						||
 | 
						||
UpdateData::UpdateData(int data_type, uint32_t time_ms) : QObject(nullptr)
 | 
						||
{
 | 
						||
    _init();
 | 
						||
    m_data_type = data_type;
 | 
						||
    m_time_ms = time_ms;
 | 
						||
}
 | 
						||
 | 
						||
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));
 | 
						||
}
 | 
						||
 | 
						||
//UpdateData::UpdateData(uint16_t screen_w, uint16_t screen_h) {
 | 
						||
//    _init();
 | 
						||
//    m_screen_w = screen_w;
 | 
						||
//    m_screen_h = screen_h;
 | 
						||
//}
 | 
						||
 | 
						||
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;
 | 
						||
 | 
						||
    m_screen_w = 0;
 | 
						||
    m_screen_h = 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;
 | 
						||
    for(int i = 0; i < m_images.size(); ++i) {
 | 
						||
        delete m_images[i].img;
 | 
						||
    }
 | 
						||
    m_images.clear();
 | 
						||
 | 
						||
    if(m_data_buf)
 | 
						||
        delete m_data_buf;
 | 
						||
}
 | 
						||
 | 
						||
void UpdateData::set_pointer(uint32_t ts, const TS_RECORD_RDP_POINTER* p) {
 | 
						||
    m_data_type = TYPE_POINTER;
 | 
						||
    m_time_ms = ts;
 | 
						||
    m_pointer = new TS_RECORD_RDP_POINTER;
 | 
						||
    memcpy(m_pointer, p, sizeof(TS_RECORD_RDP_POINTER));
 | 
						||
}
 | 
						||
 | 
						||
#if 0
 | 
						||
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() <= static_cast<int>(sizeof(uint16_t) + sizeof(TS_RECORD_RDP_IMAGE_INFO)))
 | 
						||
            return false;
 | 
						||
 | 
						||
        const uint8_t* dat_ptr = reinterpret_cast<const uint8_t*>(data.data());
 | 
						||
 | 
						||
        uint16_t count = (reinterpret_cast<const uint16_t*>(dat_ptr))[0];
 | 
						||
        uint32_t offset = sizeof(uint16_t);
 | 
						||
 | 
						||
        for(uint16_t i = 0; i < count; ++i) {
 | 
						||
 | 
						||
            const TS_RECORD_RDP_IMAGE_INFO* info = reinterpret_cast<const TS_RECORD_RDP_IMAGE_INFO*>(dat_ptr+offset);
 | 
						||
            offset += sizeof(TS_RECORD_RDP_IMAGE_INFO);
 | 
						||
            //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);
 | 
						||
            const uint8_t* img_dat = dat_ptr + offset;
 | 
						||
            offset += info->dat_len;
 | 
						||
 | 
						||
 | 
						||
            QImage* img = _rdpimg2QImage(info->width, info->height, info->bitsPerPixel, (info->format == TS_RDP_IMG_BMP) ? true : false, img_dat, info->dat_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;
 | 
						||
            UPDATE_IMAGE uimg;
 | 
						||
            uimg.x = info->destLeft;
 | 
						||
            uimg.y = info->destTop;
 | 
						||
            uimg.w = info->destRight - info->destLeft + 1;
 | 
						||
            uimg.h = info->destBottom - info->destTop + 1;
 | 
						||
            uimg.img = img;
 | 
						||
            m_images.push_back(uimg);
 | 
						||
        }
 | 
						||
 | 
						||
        return true;
 | 
						||
    }
 | 
						||
    else if(pkg.type == TS_RECORD_TYPE_RDP_KEYFRAME) {
 | 
						||
        m_data_type = TYPE_IMAGE;
 | 
						||
//        const TS_RECORD_RDP_KEYFRAME_INFO* info = reinterpret_cast<const TS_RECORD_RDP_KEYFRAME_INFO*>(data.data());
 | 
						||
        const uint8_t* img_dat = reinterpret_cast<const uint8_t*>(data.data() + sizeof(TS_RECORD_RDP_KEYFRAME_INFO));
 | 
						||
        uint32_t img_len = data.size() - sizeof(TS_RECORD_RDP_KEYFRAME_INFO);
 | 
						||
 | 
						||
        QImage* img = _raw2QImage((int)m_screen_w, (int)m_screen_h, img_dat, img_len);
 | 
						||
        if(img == nullptr)
 | 
						||
            return false;
 | 
						||
 | 
						||
        UPDATE_IMAGE uimg;
 | 
						||
        uimg.x = 0;
 | 
						||
        uimg.y = 0;
 | 
						||
        uimg.w = m_screen_w;
 | 
						||
        uimg.h = m_screen_h;
 | 
						||
        uimg.img = img;
 | 
						||
        m_images.push_back(uimg);
 | 
						||
 | 
						||
//        m_img = img;
 | 
						||
//        m_img_x = 0;
 | 
						||
//        m_img_y = 0;
 | 
						||
//        m_img_w = m_screen_w;
 | 
						||
//        m_img_h = m_screen_h;
 | 
						||
        return true;
 | 
						||
    }
 | 
						||
 | 
						||
    return false;
 | 
						||
}
 | 
						||
#endif
 | 
						||
 | 
						||
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;
 | 
						||
}
 |