libvisiontransfer  5.2.0
imagepair.cpp
1 /*******************************************************************************
2  * Copyright (c) 2018 Nerian Vision Technologies
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *******************************************************************************/
14 
15 #include <iostream>
16 #include <fstream>
17 #include <stdexcept>
18 #include <cstring>
19 #include "visiontransfer/imagepair.h"
20 
21 #ifdef _WIN32
22 #include <winsock2.h>
23 #else
24 #include <arpa/inet.h>
25 #endif
26 
28  : width(0), height(0), qMatrix(NULL), timeSec(0), timeMicrosec(0),
29  seqNum(0), minDisparity(0), maxDisparity(0), disparityPair(false),
30  referenceCounter(NULL) {
31  formats[0] = FORMAT_8_BIT;
32  formats[1] = FORMAT_8_BIT;
33  data[0] = NULL;
34  data[1] = NULL;
35  rowStride[0] = 0;
36  rowStride[1] = 1;
37 }
38 
40  copyData(*this, other, true);
41 }
42 
43 ImagePair& ImagePair::operator= (ImagePair const& other) {
44  if(&other != this) {
45  decrementReference();
46  copyData(*this, other, true);
47  }
48  return *this;
49 }
50 
51 ImagePair::~ImagePair() {
52  decrementReference();
53 }
54 
55 void ImagePair::copyData(ImagePair& dest, const ImagePair& src, bool countRef) {
56  dest.width = src.width;
57  dest.height = src.height;
58 
59  for(int i=0; i<2; i++) {
60  dest.rowStride[i] = src.rowStride[i];
61  dest.formats[i] = src.formats[i];
62  dest.data[i] = src.data[i];
63  }
64 
65  dest.qMatrix = src.qMatrix;
66  dest.timeSec = src.timeSec;
67  dest.timeMicrosec = src.timeMicrosec;
68  dest.seqNum = src.seqNum;
69  dest.minDisparity = src.minDisparity;
70  dest.maxDisparity = src.maxDisparity;
71  dest.disparityPair = src.disparityPair;
72  dest.referenceCounter = src.referenceCounter;
73 
74  if(dest.referenceCounter != nullptr && countRef) {
75  (*dest.referenceCounter)++;
76  }
77 }
78 
79 void ImagePair::decrementReference() {
80  if(referenceCounter != nullptr && --(*referenceCounter) == 0) {
81  delete []data[0];
82  delete []data[1];
83  delete []qMatrix;
84 
85  data[0] = nullptr;
86  data[1] = nullptr;
87  qMatrix = nullptr;
88  }
89 }
90 
91 void ImagePair::writePgmFile(int imageNumber, const char* fileName) const {
92  if(imageNumber < 0 || imageNumber >1) {
93  throw std::runtime_error("Illegal image number!");
94  }
95 
96  std::fstream strm(fileName, std::ios::out | std::ios::binary);
97 
98  // Write PGM header
99  int maxVal, bytesPixel;
100  if(formats[imageNumber] == FORMAT_8_BIT) {
101  maxVal = 255;
102  bytesPixel = 1;
103  } else { // 12 bit
104  maxVal = 4095;
105  bytesPixel = 2;
106  }
107 
108  strm << "P5 " << width << " " << height << " " << maxVal << std::endl;
109 
110  // Write image data
111  for(int y = 0; y < height; y++) {
112  for(int x = 0; x < width; x++) {
113  unsigned char* pixel = &data[imageNumber][y*rowStride[imageNumber] + x*bytesPixel];
114  if(bytesPixel == 2) {
115  // Swap endianess
116  unsigned short swapped = htons(*reinterpret_cast<unsigned short*>(pixel));
117  strm.write(reinterpret_cast<char*>(&swapped), sizeof(swapped));
118  } else {
119  strm.write(reinterpret_cast<char*>(pixel), 1);
120  }
121  }
122  }
123 }
124 
126  dest.decrementReference();
127  copyData(dest, *this, false);
128 
129  dest.qMatrix = new float[16];
130  memcpy(const_cast<float*>(dest.qMatrix), qMatrix, sizeof(float)*16);
131 
132  for(int i=0; i<2; i++) {
133  int bytesPixel = formats[i] == FORMAT_8_BIT ? 1 : 2;
134  dest.rowStride[i] = width*bytesPixel;
135  dest.data[i] = new unsigned char[height*dest.rowStride[i]];
136 
137  // Convert possibly different row strides
138  for(int y = 0; y < height; y++) {
139  memcpy(&dest.data[i][y*dest.rowStride[i]], &data[i][y*rowStride[i]],
140  dest.rowStride[i]);
141  }
142  }
143 
144  dest.referenceCounter = new int;
145  (*dest.referenceCounter) = 1;
146 }
void copyTo(ImagePair &dest)
Makes a deep copy of this image pair.
Definition: imagepair.cpp:125
ImagePair()
Default constructor creating an image pair with no pixel data.
Definition: imagepair.cpp:27
void writePgmFile(int imageNumber, const char *fileName) const
Writes one image of the pair to a PGM file.
Definition: imagepair.cpp:91
A set of two images, which are usually the left camera image and the disparity map.
Definition: imagepair.h:30
8-bit greyscale format
Definition: imagepair.h:37
Nerian Vision Technologies