YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
MjpegDecompression.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
7#include "MjpegLogComponent.h"
8
9#include <yarp/os/Log.h>
10#include <yarp/sig/Image.h>
11
12#include <csetjmp>
13#include <cstdio>
14#include <cstring>
15
16#if defined(_WIN32)
17#define INT32 long // jpeg's definition
18#define QGLOBAL_H 1
19#endif
20
21#ifdef _MSC_VER
22#pragma warning (push)
23#pragma warning (disable : 4091)
24#endif
25
26extern "C" {
27#include <jpeglib.h>
28}
29
30#ifdef _MSC_VER
31#pragma warning (pop)
32#endif
33
34#if defined(_WIN32)
35#undef INT32
36#undef QGLOBAL_H
37#endif
38
39
40using namespace yarp::os;
41using namespace yarp::sig;
42
48
50
52 //net_src_ptr src = (net_src_ptr) cinfo->src;
53}
54
55
57{
58 // The whole JPEG data is expected to reside in the supplied memory
59 // buffer, so any request for more data beyond the given buffer size
60 // is treated as an error.
61 auto* mybuffer = (JOCTET *) cinfo->client_data;
62 yCWarning(MJPEGCARRIER, "JPEG data unusually large");
63 // Insert a fake EOI marker
64 mybuffer[0] = (JOCTET) 0xFF;
66 cinfo->src->next_input_byte = mybuffer;
67 cinfo->src->bytes_in_buffer = 2;
68 return TRUE;
69}
70
72 auto myerr = (net_error_ptr) cinfo->err;
73 (*cinfo->err->output_message) (cinfo);
74 longjmp(myerr->setjmp_buffer, 1);
75}
76
78{
79 auto src = (net_src_ptr) cinfo->src;
80
81 if (num_bytes > 0) {
82 while (num_bytes > (long) src->bytes_in_buffer) {
83 num_bytes -= (long) src->bytes_in_buffer;
84 (void) (*src->fill_input_buffer) (cinfo);
85 }
86 src->next_input_byte += (size_t) num_bytes;
87 src->bytes_in_buffer -= (size_t) num_bytes;
88 }
89}
90
93
94void jpeg_net_src (j_decompress_ptr cinfo, char *buf, int buflen) {
95 net_src_ptr src;
96 if (cinfo->src == nullptr) { /* first time for this JPEG object? */
97 cinfo->src = (struct jpeg_source_mgr *)
98 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
99 sizeof(jpeg_source_mgr));
100 }
101
102 src = (net_src_ptr) cinfo->src;
103 src->init_source = init_net_source;
104 src->fill_input_buffer = fill_net_input_buffer;
105 src->skip_input_data = skip_net_input_data;
106 src->resync_to_restart = jpeg_resync_to_restart; /* use default method */
107 src->term_source = term_net_source;
108 src->bytes_in_buffer = buflen;
109 src->next_input_byte = (JOCTET *)buf;
110}
111
112
114public:
115 bool active{false};
121
123 {
124 memset(&cinfo, 0, sizeof(jpeg_decompress_struct));
125 memset(&jerr, 0, sizeof(net_error_mgr));
126 }
127
129 void* data)
130 {
131 readEnvelopeCallback = callback;
133 return true;
134 }
135
136 void init() {
138 }
139 bool decompress(const Bytes& cimg, FlexImage& img) {
140 if (!active) {
141 init();
142 active = true;
143 }
144 cinfo.client_data = &error_buffer;
145 cinfo.err = jpeg_std_error(&jerr.pub);
146 jerr.pub.error_exit = net_error_exit;
147
148 if (setjmp(jerr.setjmp_buffer)) {
150 return false;
151 }
152
153 jpeg_net_src(&cinfo,(char*)cimg.get(),cimg.length());
157
158 if(cinfo.jpeg_color_space == JCS_GRAYSCALE) {
160 }
161 else
162 {
164 }
165
166 yCTrace(MJPEGCARRIER, "Got image %dx%d", cinfo.output_width, cinfo.output_height);
167 img.resize(cinfo.output_width,cinfo.output_height);
169 //int row_stride = cinfo.output_width * cinfo.output_components;
170
171 int at = 0;
172 while (cinfo.output_scanline < cinfo.output_height) {
173 JSAMPLE *lines[1];
174 lines[0] = (JSAMPLE*)(img.getPixelAddress(0,at));
176 at++;
177 }
178 if(readEnvelopeCallback && cinfo.marker_list && cinfo.marker_list->data_length > 0) {
179 Bytes envelope(reinterpret_cast<char*>(cinfo.marker_list->data), cinfo.marker_list->data_length);
181 }
182 yCTrace(MJPEGCARRIER, "Read image!");
184 return true;
185 }
186
187 void fini() {
189 }
190
192 if (active) {
193 fini();
194 active = false;
195 }
196 }
197};
198
199#define HELPER(x) (*((MjpegDecompressionHelper*)(x)))
200
202 system_resource = new MjpegDecompressionHelper;
203 yCAssert(MJPEGCARRIER, system_resource!=nullptr);
204}
205
207 if (system_resource!=nullptr) {
208 delete &HELPER(system_resource);
209 system_resource = nullptr;
210 }
211}
212
213
215 FlexImage &image) {
216 MjpegDecompressionHelper& helper = HELPER(system_resource);
217 return helper.decompress(data, image);
218}
219
221 void* data)
222{
223 MjpegDecompressionHelper& helper = HELPER(system_resource);
224 return helper.setReadEnvelopeCallback(callback, data);
225}
226
227
229#ifdef MJPEG_AUTOCOMPRESS
230 return true;
231#else
232 return false;
233#endif
234}
@ VOCAB_PIXEL_MONO
Definition Image.h:42
@ VOCAB_PIXEL_RGB
Definition Image.h:44
void jpeg_net_src(j_decompress_ptr cinfo, char *buf, int buflen)
void net_error_exit(j_common_ptr cinfo)
net_error_mgr * net_error_ptr
jpeg_source_mgr * net_src_ptr
void term_net_source(j_decompress_ptr cinfo)
void init_net_source(j_decompress_ptr cinfo)
void skip_net_input_data(j_decompress_ptr cinfo, long num_bytes)
boolean fill_net_input_buffer(j_decompress_ptr cinfo)
const yarp::os::LogComponent & MJPEGCARRIER()
#define HELPER(x)
bool decompress(const Bytes &cimg, FlexImage &img)
bool setReadEnvelopeCallback(yarp::os::InputStream::readEnvelopeCallbackType callback, void *data)
yarp::os::InputStream::readEnvelopeCallbackType readEnvelopeCallback
struct jpeg_decompress_struct cinfo
bool decompress(const yarp::os::Bytes &data, yarp::sig::FlexImage &image)
bool setReadEnvelopeCallback(yarp::os::InputStream::readEnvelopeCallbackType callback, void *data)
A mini-server for performing network communication in the background.
A simple abstraction for a block of bytes.
Definition Bytes.h:24
size_t length() const
Definition Bytes.cpp:22
const char * get() const
Definition Bytes.cpp:27
void(* readEnvelopeCallbackType)(void *, const yarp::os::Bytes &envelope)
Callback type for setting the envelope from a message in carriers that cannot be escaped.
Image class with user control of representation details.
Definition Image.h:374
void setPixelCode(int imgPixelCode)
Definition Image.h:377
void resize(size_t imgWidth, size_t imgHeight)
Reallocate an image to be of a desired size, throwing away its current contents.
Definition Image.cpp:402
unsigned char * getPixelAddress(size_t x, size_t y) const
Get address of a pixel in memory.
Definition Image.h:237
#define yCAssert(component, x)
#define yCTrace(component,...)
#define yCWarning(component,...)
An interface to the operating system, including Port based communication.
struct jpeg_error_mgr pub