forked from aoyiduo/woterm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathqkxjpegdecoder.cpp
101 lines (83 loc) · 2.89 KB
/
qkxjpegdecoder.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/*******************************************************************************************
*
* Copyright (C) 2022 Guangzhou AoYiDuo Network Technology Co.,Ltd. All Rights Reserved.
*
* Contact: http://www.aoyiduo.com
*
* this file is used under the terms of the GPLv3[GNU GENERAL PUBLIC LICENSE v3]
* more information follow the website: https://www.gnu.org/licenses/gpl-3.0.en.html
*
*******************************************************************************************/
#include "qkxjpegdecoder.h"
#include <turbojpeg.h>
class QKxJpegDecoderPrivate
{
public:
QKxJpegDecoderPrivate(QKxJpegDecoder *p) {
}
~QKxJpegDecoderPrivate() {
}
bool decode(uchar *rgb, int bytesPerLine, int total, uchar *jpg, int cnt) {
int width = 0, height = 0, jpegsubsamp = 0;
void* decompressor = tjInitDecompress();
if (nullptr == decompressor) {
return false;
}
if (tjDecompressHeader2(decompressor, jpg, cnt, &width, &height, &jpegsubsamp) != 0) {
tjDestroy(decompressor);
return false;
}
if(total < height * bytesPerLine) {
return false;
}
int pitch = tjPixelSize[TJPF::TJPF_BGRX] * width;
int flags = TJFLAG_FASTDCT;
int status = tjDecompress2(decompressor, jpg, cnt, rgb, width, bytesPerLine, height, TJPF::TJPF_BGRX, flags);
if ( status != 0) {
tjDestroy(decompressor);
return false;
}
tjDestroy(decompressor);
return true;
}
bool decompress(uint8_t* data_compressed, uint32_t size, uint8_t* &out_uncompressed, int pixel_format)
{
if (nullptr == data_compressed || nullptr == out_uncompressed) {
return false;
}
int width = 0, height = 0, jpegsubsamp = 0;
void* decompressor = tjInitDecompress();
if (nullptr == decompressor) {
return false;
}
if (tjDecompressHeader2(decompressor, data_compressed, size, &width, &height, &jpegsubsamp) != 0) {
tjDestroy(decompressor);
return false;
}
// pixel_format : TJPF::TJPF_BGR or other
int pitch = tjPixelSize[pixel_format] * width;
uint32_t len = pitch * height;
int flags = TJFLAG_FASTDCT;
int status = tjDecompress2(decompressor, data_compressed, len, out_uncompressed, width, pitch,
height, pixel_format, flags);
if ( status != 0) {
tjDestroy(decompressor);
return false;
}
tjDestroy(decompressor);
return true;
}
};
QKxJpegDecoder::QKxJpegDecoder(QObject *parent)
: QObject(parent)
{
m_prv = new QKxJpegDecoderPrivate(this);
}
QKxJpegDecoder::~QKxJpegDecoder()
{
delete m_prv;
}
bool QKxJpegDecoder::decode(uchar *rgb, int bytesPerLine, int total, uchar *jpg, int cnt)
{
return m_prv->decode(rgb, bytesPerLine, total, jpg, cnt);
}