Skip to content

Commit

Permalink
Merge pull request #2553 from randaz81/zlib_portmonitor
Browse files Browse the repository at this point in the history
depthimage_compression_zlib portmonitor
  • Loading branch information
randaz81 committed Apr 22, 2021
2 parents e886a09 + 40024b3 commit f652002
Show file tree
Hide file tree
Showing 6 changed files with 313 additions and 0 deletions.
6 changes: 6 additions & 0 deletions doc/release/master/zlib_portmonitor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
zlib_portmonitor {#master}
------------------

### PortMonitors

* added new portmonitor `depthimage_compression_zlib` which uses zlib library to compress/decompress (lossless) depth images through the network
1 change: 1 addition & 0 deletions src/portmonitors/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ include(YarpPrintFeature)
yarp_begin_plugin_library(yarppm OPTION YARP_COMPILE_PORTMONITOR_PLUGINS
DEFAULT ON)
add_subdirectory(depthimage_compression_zfp)
add_subdirectory(depthimage_compression_zlib)
add_subdirectory(depthimage_to_mono)
add_subdirectory(depthimage_to_rgb)
add_subdirectory(image_compression_ffmpeg)
Expand Down
57 changes: 57 additions & 0 deletions src/portmonitors/depthimage_compression_zlib/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Copyright (C) 2006-2021 Istituto Italiano di Tecnologia (IIT)
# All rights reserved.
#
# This software may be modified and distributed under the terms of the
# BSD-3-Clause license. See the accompanying LICENSE file for details.

yarp_prepare_plugin(depthimage_compression_zlib
TYPE ZlibMonitorObject
INCLUDE zlibPortmonitor.h
CATEGORY portmonitor
DEPENDS "ENABLE_yarpcar_portmonitor;YARP_HAS_ZLIB"
)

if(SKIP_depthimage_compression_zlib)
return()
endif()

yarp_add_plugin(yarp_pm_depthimage_compression_zlib)

target_sources(yarp_pm_depthimage_compression_zlib
PRIVATE
zlibPortmonitor.cpp
zlibPortmonitor.h
)

target_link_libraries(yarp_pm_depthimage_compression_zlib
PRIVATE
YARP::YARP_os
YARP::YARP_sig
)
list(APPEND YARP_${YARP_PLUGIN_MASTER}_PRIVATE_DEPS
YARP_os
YARP_sig
)

target_include_directories(yarp_pm_depthimage_compression_zlib
SYSTEM PRIVATE
${ZLIB_INCLUDE_DIRS}
)
target_link_libraries(yarp_pm_depthimage_compression_zlib
PRIVATE
${ZLIB_LIBRARIES}
)
# list(APPEND YARP_${YARP_PLUGIN_MASTER}_PRIVATE_DEPS ZLIB) (not using targets)

yarp_install(
TARGETS yarp_pm_depthimage_compression_zlib
EXPORT YARP_${YARP_PLUGIN_MASTER}
COMPONENT ${YARP_PLUGIN_MASTER}
LIBRARY DESTINATION ${YARP_DYNAMIC_PLUGINS_INSTALL_DIR}
ARCHIVE DESTINATION ${YARP_STATIC_PLUGINS_INSTALL_DIR}
YARP_INI DESTINATION ${YARP_PLUGIN_MANIFESTS_INSTALL_DIR}
)

set(YARP_${YARP_PLUGIN_MASTER}_PRIVATE_DEPS ${YARP_${YARP_PLUGIN_MASTER}_PRIVATE_DEPS} PARENT_SCOPE)

set_property(TARGET yarp_pm_depthimage_compression_zlib PROPERTY FOLDER "Plugins/Port Monitor")
9 changes: 9 additions & 0 deletions src/portmonitors/depthimage_compression_zlib/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

depthimage_compression_zlib_portmonitor plugin
======================================================================
Portmonitor plugin for compression and decompression of depth images using zlib library.

Usage:
-----

yarp connect /depthCamera/depthImage:o /view tcp+send.portmonitor+file.depthimage_compression_zlib+recv.portmonitor+file.depthimage_compression_zlib+type.dll
199 changes: 199 additions & 0 deletions src/portmonitors/depthimage_compression_zlib/zlibPortmonitor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
/*
* Copyright (C) 2006-2021 Istituto Italiano di Tecnologia (IIT)
* All rights reserved.
*
* This software may be modified and distributed under the terms of the
* BSD-3-Clause license. See the accompanying LICENSE file for details.
*/

#include "zlibPortmonitor.h"

#include <yarp/os/LogStream.h>
#include <yarp/os/LogComponent.h>
#include <yarp/sig/Image.h>

#include <cstring>
#include <cmath>
#include <algorithm>

#include <zlib.h>

using namespace yarp::os;
using namespace yarp::sig;

namespace {
YARP_LOG_COMPONENT(ZLIBMONITOR,
"yarp.carrier.portmonitor.zlib",
yarp::os::Log::minimumPrintLevel(),
yarp::os::Log::LogTypeReserved,
yarp::os::Log::printCallback(),
nullptr)
}


bool ZlibMonitorObject::create(const yarp::os::Property& options)
{
m_shouldCompress = (options.find("sender_side").asBool());
return true;
}

void ZlibMonitorObject::destroy()
{
}

bool ZlibMonitorObject::setparam(const yarp::os::Property& params)
{
return false;
}

bool ZlibMonitorObject::getparam(yarp::os::Property& params)
{
return false;
}

bool ZlibMonitorObject::accept(yarp::os::Things& thing)
{
if(m_shouldCompress)
{
//sender side / compressor
auto* b = thing.cast_as<ImageOf<PixelFloat>>();
if(b == nullptr)
{
yCError(ZLIBMONITOR, "Expected type ImageOf<PixelFloat> in sender side, but got wrong data type!");
return false;
}
}
else
{
//receiver side / decompressor
auto* b = thing.cast_as<Bottle>();
if(b == nullptr)
{
yCError(ZLIBMONITOR, "Expected type Bottle in receiver side, but got wrong data type!");
return false;
}
}
return true;
}

yarp::os::Things& ZlibMonitorObject::update(yarp::os::Things& thing)
{
if(m_shouldCompress)
{
//sender side / compressor
//it receives an image, it sends a bottle to the network
auto* b = thing.cast_as<ImageOf<PixelFloat>>();

size_t sizeUncompressed= b->getRawImageSize();
const unsigned char* uncompressedData = b->getRawImage();

size_t sizeCompressed = (sizeUncompressed * 1.1) + 12;
unsigned char* compressedData = (unsigned char*) malloc (sizeCompressed);

bool ret= compressData(uncompressedData, sizeUncompressed, compressedData, sizeCompressed);
if(!ret)
{
yCError(ZLIBMONITOR, "Failed to compress, exiting...");
free(compressedData);
return thing;
}

m_data.clear();
Value v(compressedData, sizeCompressed);
m_data.addInt32(b->width());
m_data.addInt32(b->height());
m_data.addInt32(sizeCompressed);
m_data.addInt32(sizeUncompressed);
m_data.add(v);
m_th.setPortWriter(&m_data);

free(compressedData);
}
else
{
//receiver side / decompressor
//it receives a bottle from the network, it creates an image
Bottle* b= thing.cast_as<Bottle>();

size_t w = b->get(0).asInt32();
size_t h = b->get(1).asInt32();
size_t check_sizeCompressed = b->get(2).asInt32();
size_t check_sizeUncompressed = b->get(3).asInt32();
size_t sizeCompressed=b->get(4).asBlobLength();
const unsigned char* CompressedData = (const unsigned char*) b->get(4).asBlob();

size_t sizeUncompressed = w * h * 4;
if (check_sizeUncompressed != sizeUncompressed ||
check_sizeCompressed != sizeCompressed)
{
yCError(ZLIBMONITOR, "Invalid data received: wrong blob size?");
return thing;
}
unsigned char* uncompressedData = (unsigned char*)malloc(sizeUncompressed);

bool ret = decompressData(CompressedData, sizeCompressed, uncompressedData, sizeUncompressed);
if(!ret)
{
yCError(ZLIBMONITOR, "Failed to decompress, exiting...");
free(uncompressedData);
return thing;
}

m_imageOut.resize(w, h);
memcpy(m_imageOut.getRawImage(), uncompressedData, sizeUncompressed);
m_th.setPortWriter(&m_imageOut);

free(uncompressedData);
}

return m_th;
}

int ZlibMonitorObject::compressData(const unsigned char* in, const size_t& in_size, unsigned char* out, size_t& out_size)
{
int z_result = compress((Bytef*)out, (uLongf*)&out_size, (Bytef*)in, in_size);
switch (z_result)
{
case Z_OK:
break;

case Z_MEM_ERROR:
yCError(ZLIBMONITOR, "zlib compression: out of memory");
return false;
break;

case Z_BUF_ERROR:
yCError(ZLIBMONITOR, "zlib compression: output buffer wasn't large enough");
return false;
break;
}

return true;
}

int ZlibMonitorObject::decompressData(const unsigned char* in, const size_t& in_size, unsigned char* out, size_t& out_size)
{
int z_result = uncompress((Bytef*)out, (uLongf*)&out_size, (const Bytef*)in, in_size);
switch (z_result)
{
case Z_OK:
break;

case Z_MEM_ERROR:
yCError(ZLIBMONITOR, "zlib compression: out of memory");
return false;
break;

case Z_BUF_ERROR:
yCError(ZLIBMONITOR, "zlib compression: output buffer wasn't large enough");
return false;
break;

case Z_DATA_ERROR:
yCError(ZLIBMONITOR, "zlib compression: file contains corrupted data");
return false;
break;
}

return true;
}
41 changes: 41 additions & 0 deletions src/portmonitors/depthimage_compression_zlib/zlibPortmonitor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (C) 2006-2021 Istituto Italiano di Tecnologia (IIT)
* All rights reserved.
*
* This software may be modified and distributed under the terms of the
* BSD-3-Clause license. See the accompanying LICENSE file for details.
*/

#ifndef YARP_ZLIB_CARRIER_ZFPPORTMONITOR_H
#define YARP_ZLIB_CARRIER_ZFPPORTMONITOR_H

#include <yarp/os/Bottle.h>
#include <yarp/os/Things.h>
#include <yarp/sig/Image.h>
#include <yarp/os/MonitorObject.h>


class ZlibMonitorObject : public yarp::os::MonitorObject
{
public:
bool create(const yarp::os::Property& options) override;
void destroy() override;

bool setparam(const yarp::os::Property& params) override;
bool getparam(yarp::os::Property& params) override;

bool accept(yarp::os::Things& thing) override;
yarp::os::Things& update(yarp::os::Things& thing) override;

protected:
int compressData (const unsigned char* in, const size_t& in_size, unsigned char* out, size_t& out_size);
int decompressData(const unsigned char* in, const size_t& in_size, unsigned char* out, size_t& out_size);

private:
yarp::os::Things m_th;
yarp::os::Bottle m_data;
bool m_shouldCompress;
yarp::sig::ImageOf<yarp::sig::PixelFloat> m_imageOut;
};

#endif

0 comments on commit f652002

Please sign in to comment.