-
Notifications
You must be signed in to change notification settings - Fork 3
/
mpo.cpp
113 lines (100 loc) · 3.64 KB
/
mpo.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
102
103
104
105
106
107
108
109
110
111
112
113
/*
* File : mpo.cpp
* Author: AbsurdePhoton
*
* v1 2018/07/08
*
* Reads MPO stereo image files
*
*/
#include <QPixmap>
#include <QFile>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
bool MPO2Pixmap(QString source, vector<QPixmap>& vector) {
int count = 0;
int index, fileLength;
int secondImageStart = 0;
QFile imageFile(source); // open MPO file as datastream
if (imageFile.exists()) {
imageFile.open(QIODevice::ReadOnly); // read-only mode
QDataStream dataInfilestream(&imageFile);
fileLength = imageFile.size();
// read data from stream
QVector<uchar> imageData(fileLength); // data vector
while(!dataInfilestream.atEnd()) {
dataInfilestream >> imageData[count++];
}
imageFile.close();
// look for marker of second image at (+/- 10%) half of the full MPO file
for (index = (int)(fileLength * 0.40); index < (int)(fileLength * 0.60); index++) {
if ((imageData[index] == 0xFF) && (imageData[index+1] == 0xD8) \
&& (imageData[index+2] == 0xFF) && (imageData[index+3] == 0xE1)) {
secondImageStart = index;
break;
};
}
if (secondImageStart == 0) { // no separator found
return false;
}
// QPixmap variables to store the images
QPixmap *leftView = new QPixmap;
QPixmap *rightView = new QPixmap;
// copy the 2 jpegs in buffers
leftView->loadFromData(&imageData[0], (secondImageStart - 1));
rightView->loadFromData(&imageData[secondImageStart], (fileLength - secondImageStart));
// decode jpegs in pointer array
std::vector<QPixmap> stereoImages(2);
stereoImages[0] = *leftView;
stereoImages[1] = *rightView;
// return pointer array
vector = stereoImages;
return true;
}
else return false;
}
bool MPO2Mat(QString source, vector<cv::Mat>& vector)
{
int count = 0;
int index, fileLength;
int secondImageStart = 0;
QFile imageFile(source); // open MPO file as datastream
// open if exist
if (imageFile.exists()) {
imageFile.open(QIODevice::ReadOnly); // read-only mode
QDataStream dataInfilestream(&imageFile);
// get file length
fileLength = imageFile.size();
// read data from stream
QVector<uchar> imageData(fileLength); // data vector
while(!dataInfilestream.atEnd()) {
dataInfilestream >> imageData[count++];
}
imageFile.close();
// look for marker of second image at (+/- 10%) half of the full MPO file
for (index = (int)(fileLength * 0.40); index < (int)(fileLength * 0.60); index++) {
if ((imageData[index] == 0xFF) && (imageData[index+1] == 0xD8) \
&& (imageData[index+2] == 0xFF) && (imageData[index+3] == 0xE1)) {
secondImageStart = index;
break;
}
}
if (secondImageStart == 0) { // no separator found
return false;
}
// return buffers : 2 jpegs
std::vector<cv::Mat> ret(2);
// copy the 2 jpegs in buffers
QVector<uchar> leftImageData = imageData.mid(0,secondImageStart - 1);
QVector<uchar> rightImageData = imageData.mid(secondImageStart,fileLength - secondImageStart);
// decode jpegs in Mat containers
ret[0] = imdecode(leftImageData.toStdVector(), IMREAD_COLOR);
ret[1] = imdecode(rightImageData.toStdVector(), IMREAD_COLOR);
// return pointer array
vector = ret;
// success
return true;
}
else return false;
}