diff --git a/CMakeLists.txt b/CMakeLists.txt
index 15ef5027ad40ee1889dd154357f91e35fab3064f..d12b4d1a411847972b0fa1380a4b487d81ac7b09 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -20,6 +20,7 @@ find_package( Threads REQUIRED )
 find_package( URIParser REQUIRED )
 find_package( MsgPack REQUIRED )
 find_package( LibSGM )
+find_package( ZLIB REQUIRED )
 
 # Readline library is not required on Windows
 # May also entirely remove dependence on this... it should be optional at least.
diff --git a/reconstruct/CMakeLists.txt b/reconstruct/CMakeLists.txt
index f12c0305782ea375f7937a5a187b1f58b09d94d6..8dfbccded397b975de49f7782068ebeb59e19dc0 100644
--- a/reconstruct/CMakeLists.txt
+++ b/reconstruct/CMakeLists.txt
@@ -12,6 +12,6 @@ add_executable(ftl-reconstruct ${REPSRC})
 add_dependencies(ftl-reconstruct ftlnet)
 
 #target_include_directories(cv-node PUBLIC ${PROJECT_SOURCE_DIR}/include)
-target_link_libraries(ftl-reconstruct Threads::Threads ${OpenCV_LIBS} glog::glog ftlnet)
+target_link_libraries(ftl-reconstruct Threads::Threads ZLIB::ZLIB ${OpenCV_LIBS} glog::glog ftlnet)
 
 
diff --git a/reconstruct/src/main.cpp b/reconstruct/src/main.cpp
index f35adb20d604e8fb7c48fba34965ec5aeb6623aa..806e17bb9336d40bca4164c5ab83ef297298e772 100644
--- a/reconstruct/src/main.cpp
+++ b/reconstruct/src/main.cpp
@@ -6,6 +6,7 @@
 
 #include <glog/logging.h>
 #include <ftl/config.h>
+#include <zlib.h>
 
 #include <string>
 #include <map>
@@ -114,23 +115,47 @@ static void process_options(const map<string, string> &opts) {
 
 static void run(const string &file) {
 	Universe net(config["net"]);
-	Mat rgb;
+	Mat rgb, depth;
 	mutex m;
 	
 	// Make sure connections are complete
 	sleep_for(milliseconds(500));
 
-	net.subscribe(config["source"], [&rgb,&m](const vector<unsigned char> &jpg) {
+	net.subscribe(config["source"], [&rgb,&m,&depth](const vector<unsigned char> &jpg, const vector<unsigned char> &d) {
 		unique_lock<mutex> lk(m);
 		cv::imdecode(jpg, cv::IMREAD_COLOR, &rgb);
 		//LOG(INFO) << "Received JPG : " << rgb.cols;
+		
+		depth = Mat(rgb.size(), CV_32FC1);
+		
+		z_stream infstream;
+		infstream.zalloc = Z_NULL;
+		infstream.zfree = Z_NULL;
+		infstream.opaque = Z_NULL;
+		// setup "b" as the input and "c" as the compressed output
+		infstream.avail_in = (uInt)d.size(); // size of input
+		infstream.next_in = (Bytef *)d.data(); // input char array
+		infstream.avail_out = (uInt)depth.step*depth.rows; // size of output
+		infstream.next_out = (Bytef *)depth.data; // output char array
+		 
+		// the actual DE-compression work.
+		inflateInit(&infstream);
+		inflate(&infstream, Z_NO_FLUSH);
+		inflateEnd(&infstream);
 	});
 	
 	while (true) {
+		Mat idepth;
+		
 		unique_lock<mutex> lk(m);
 		if (rgb.cols > 0) {
 			cv::imshow("RGB", rgb);
 		}
+		if (depth.cols > 0) {
+			depth.convertTo(idepth, CV_8U, 255.0f / 256.0f);  // TODO(nick)
+    		applyColorMap(idepth, idepth, cv::COLORMAP_JET);
+			cv::imshow("Depth", idepth);
+		}
 		lk.unlock();
 		if (cv::waitKey(40) == 27) break;
 	}
diff --git a/vision/CMakeLists.txt b/vision/CMakeLists.txt
index 28c79e0d8e3b32394527fa5e626f4ec285d9dbec..b07dcc8b2b2ff88da956604849aa0661ff5675ab 100644
--- a/vision/CMakeLists.txt
+++ b/vision/CMakeLists.txt
@@ -47,6 +47,6 @@ set_property(TARGET ftl-vision PROPERTY CUDA_SEPARABLE_COMPILATION ON)
 endif()
 
 #target_include_directories(cv-node PUBLIC ${PROJECT_SOURCE_DIR}/include)
-target_link_libraries(ftl-vision Threads::Threads libelas ${OpenCV_LIBS} ${LIBSGM_LIBRARIES} ${CUDA_LIBRARIES} glog::glog ftlnet)
+target_link_libraries(ftl-vision Threads::Threads ZLIB::ZLIB libelas ${OpenCV_LIBS} ${LIBSGM_LIBRARIES} ${CUDA_LIBRARIES} glog::glog ftlnet)
 
 
diff --git a/vision/src/streamer.cpp b/vision/src/streamer.cpp
index 79ef05b6bb20f1c0b34485ee71ff95ae9c56c0f4..848c8596f1af54d30260c55ff593258bb796fe76 100644
--- a/vision/src/streamer.cpp
+++ b/vision/src/streamer.cpp
@@ -1,6 +1,7 @@
 #include <glog/logging.h>
 #include <ftl/streamer.hpp>
 #include <vector>
+#include <zlib.h>
 
 using ftl::Streamer;
 using ftl::net::Universe;
@@ -22,8 +23,25 @@ void Streamer::send(const Mat &rgb, const Mat &depth) {
 	// Compress the rgb as jpeg.
 	vector<unsigned char> rgb_buf;
 	cv::imencode(".jpg", rgb, rgb_buf);
-	net_.publish(uri_, rgb_buf);
 	
-	LOG(INFO) << "JPG Size = " << ((float)rgb_buf.size() / (1024.0f*1024.0f)) << "Mb";
+	vector<unsigned char> d_buf;
+	d_buf.resize(depth.step*depth.rows);
+	z_stream defstream;
+    defstream.zalloc = Z_NULL;
+    defstream.zfree = Z_NULL;
+    defstream.opaque = Z_NULL;
+    defstream.avail_in = depth.step*depth.rows;
+    defstream.next_in = (Bytef *)depth.data; // input char array
+    defstream.avail_out = (uInt)depth.step*depth.rows; // size of output
+    defstream.next_out = (Bytef *)d_buf.data(); // output char array
+    
+    deflateInit(&defstream, Z_BEST_COMPRESSION);
+    deflate(&defstream, Z_FINISH);
+    deflateEnd(&defstream);
+    
+    d_buf.resize(defstream.total_out);
+    LOG(INFO) << "Depth Size = " << ((float)d_buf.size() / (1024.0f*1024.0f));
+    
+    net_.publish(uri_, rgb_buf, d_buf);
 }