diff --git a/lib/common/cmp_entity.c b/lib/common/cmp_entity.c
index 056b41fa49337c4ba758bf929bf0f28daebe621c..afece91b260287c95dcd85b8a47eb06329a04e78 100644
--- a/lib/common/cmp_entity.c
+++ b/lib/common/cmp_entity.c
@@ -2282,7 +2282,7 @@ static void cmp_ent_parse_generic_header(const struct cmp_entity *ent)
 
 		debug_print("Compressed with cmp_tool version: %u.%02u", major, minor);
 	} else
-		debug_print("ICU ASW Version ID: %08" PRIx32, version_id);
+		debug_print("ICU ASW Version ID: 0x%08" PRIx32, version_id);
 
 	cmp_ent_size = cmp_ent_get_size(ent);
 	debug_print("Compression Entity Size: %" PRIu32 " byte", cmp_ent_size);
@@ -2291,16 +2291,16 @@ static void cmp_ent_parse_generic_header(const struct cmp_entity *ent)
 	debug_print("Original Data Size: %" PRIu32 " byte", original_size);
 
 	start_coarse_time = cmp_ent_get_coarse_start_time(ent);
-	debug_print("Compression Coarse Start Time: %" PRIu32, start_coarse_time);
+	debug_print("Compression Coarse Start Time: 0x%" PRIx32, start_coarse_time);
 
 	start_fine_time = cmp_ent_get_fine_start_time(ent);
-	debug_print("Compression Fine Start Time: %d", start_fine_time);
+	debug_print("Compression Fine Start Time: 0x%x", start_fine_time);
 
 	end_coarse_time = cmp_ent_get_coarse_end_time(ent);
-	debug_print("Compression Coarse End Time: %" PRIu32, end_coarse_time);
+	debug_print("Compression Coarse End Time: 0x%" PRIx32, end_coarse_time);
 
 	end_fine_time = cmp_ent_get_fine_end_time(ent);
-	debug_print("Compression Fine End Time: %d", end_fine_time);
+	debug_print("Compression Fine End Time: 0x%x", end_fine_time);
 
 #ifdef HAS_TIME_H
 	{
diff --git a/meson.build b/meson.build
index 7f7954389c057dd32fe8f0b43755a7b254f69867..58c5545974f0d5eef62342dfa6ff1b2243647024 100644
--- a/meson.build
+++ b/meson.build
@@ -1,5 +1,5 @@
 project('cmp_tool', 'c',
-  version : '0.12-b4',
+  version : '0.12',
   meson_version : '>= 0.63',
   license : 'GPL-2.0',
   default_options : [
diff --git a/programs/cmp_io.c b/programs/cmp_io.c
index 81931f19b9a294c7c8b43e90a159f747b4deaa72..9b026343debc55ac6db8093871cb0ceb173b7eee 100644
--- a/programs/cmp_io.c
+++ b/programs/cmp_io.c
@@ -1326,7 +1326,7 @@ ssize_t read_file8(const char *file_name, uint8_t *buf, uint32_t buf_size, int f
 	if (flags & CMP_IO_BINARY) {
 		if (buf) {
 			ret_code = fread(buf, sizeof(uint8_t), buf_size, fp);
-			if (ret_code != (size_t)file_size) {
+			if (ret_code != (size_t)buf_size) {
 				if (feof(fp))
 					printf("%s: %s: Error: unexpected end of file.\n", PROGRAM_NAME, file_name);
 				goto fail;
diff --git a/programs/cmp_tool.c b/programs/cmp_tool.c
index aaa947d1acd65fa590e01117e6881fd0e33b5f50..fc608b2d888436891c0c97540e4e000c0a942419 100644
--- a/programs/cmp_tool.c
+++ b/programs/cmp_tool.c
@@ -39,7 +39,6 @@
 #define BUFFER_LENGTH_DEF_FAKTOR 2
 
 #define DEFAULT_MODEL_ID 53264  /* random default id */
-#define DEFAULT_MODEL_COUNTER 0
 
 
 /* parse a data_type option argument */
@@ -117,11 +116,11 @@ static int io_flags;
 /* if non zero add a compression entity header in front of the compressed data */
 static int include_cmp_header = 1;
 
-/* model ID string set by the --model_id option */
-static const char *model_id_str;
+/* model ID set by the --model_id option */
+static uint32_t model_id = DEFAULT_MODEL_ID;
 
-/* model counter string set by the --model_counter option */
-static const char *model_counter_str;
+/* model counter set by the --model_counter option */
+static uint32_t model_counter;
 
 
 /**
@@ -241,10 +240,20 @@ int main(int argc, char **argv)
 			include_cmp_header = 0;
 			break;
 		case MODEL_ID:
-			model_id_str = optarg;
+			if (atoui32("model_id", optarg, &model_id))
+				return -1;
+			if (model_counter > UINT16_MAX) {
+				fprintf(stderr, "%s: Error: model id value to large.\n", PROGRAM_NAME);
+				return -1;
+			}
 			break;
 		case MODEL_COUTER:
-			model_counter_str = optarg;
+			if (atoui32("model_counter", optarg, &model_counter))
+				return -1;
+			if (model_counter > UINT8_MAX) {
+				fprintf(stderr, "%s: Error: model counter value to large.\n", PROGRAM_NAME);
+				return -1;
+			}
 			break;
 		default:
 			print_help(program_name);
@@ -723,6 +732,15 @@ static int cmp_gernate_rdcu_info(const struct cmp_cfg *cfg, int cmp_size_bit,
 }
 
 
+/**
+ * retrun a current PLATO timestamp
+ */
+uint64_t return_timestamp(void)
+{
+	return cmp_ent_create_timestamp(NULL);
+}
+
+
 /**
  * @brief compress chunk data and write the results to files
  */
@@ -732,9 +750,10 @@ static int compression_of_chunk(void *chunk, uint32_t size, void *model, struct
 	uint32_t bound = compress_chunk_cmp_size_bound(chunk, size);
 	uint32_t *cmp_data;
 	uint32_t cmp_size;
-	enum cmp_error cmp_error;
 	int error;
 
+	compress_chunk_init(&return_timestamp, cmp_tool_gen_version_id(CMP_TOOL_VERSION));
+
 	if (!bound)
 		return -1;
 	cmp_data = calloc(1, bound);
@@ -746,20 +765,26 @@ static int compression_of_chunk(void *chunk, uint32_t size, void *model, struct
 	printf("Compress chunk data ... ");
 	cmp_size = compress_chunk(chunk, size, model, model,
 				  cmp_data, bound, chunk_par);
-	cmp_error = cmp_get_error_code(cmp_size);
-	if (cmp_error != CMP_ERROR_NO_ERROR) {
-		fprintf(stderr, "%s\n", cmp_get_error_string(cmp_error));
-		free(cmp_data);
-		cmp_data = NULL;
-		printf("FAILED\n");
-		return -1;
-	}
+	if (cmp_is_error(cmp_size))
+		goto cmp_chunk_fail;
+
+	cmp_size = compress_chunk_set_model_id_and_counter(cmp_data, cmp_size,
+			(uint16_t)model_id, (uint8_t)model_counter);
+	if (cmp_is_error(cmp_size))
+		goto cmp_chunk_fail;
 
 	printf("DONE\nWrite compressed data to file %s.cmp ... ", output_prefix);
 	error = write_data_to_file(cmp_data, (uint32_t)cmp_size, output_prefix,
 				   ".cmp", io_flags);
+
+cmp_chunk_fail:
 	free(cmp_data);
 	cmp_data = NULL;
+	if (cmp_is_error(cmp_size)) {
+		fprintf(stderr, "%s: %s.\n", PROGRAM_NAME, cmp_get_error_name(cmp_size));
+		printf("FAILED\n");
+		return (int)cmp_get_error_code(cmp_size);
+	}
 	if (error) {
 		printf("FAILED\n");
 		return -1;
@@ -781,8 +806,6 @@ static int compression(struct cmp_cfg *cfg, struct cmp_info *info)
 	size_t s;
 	uint64_t start_time = cmp_ent_create_timestamp(NULL);
 	struct cmp_entity *cmp_entity = NULL;
-	uint8_t model_counter = DEFAULT_MODEL_COUNTER;
-	uint16_t model_id = DEFAULT_MODEL_ID;
 	void *data_to_write_to_file;
 
 	if (cfg->buffer_length == 0) {
@@ -843,29 +866,12 @@ static int compression(struct cmp_cfg *cfg, struct cmp_info *info)
 		goto error_cleanup;
 	}
 
-	if (model_id_str) {
-		uint32_t red_val;
-
-		error = atoui32("model_id", model_id_str, &red_val);
-		if (error || red_val > UINT16_MAX)
-			return -1;
-		model_id = (uint16_t)red_val;
-	}
-	if (model_counter_str) {
-		uint32_t red_val;
-
-		error = atoui32("model_counter", model_counter_str, &red_val);
-		if (error || red_val > UINT8_MAX)
-			return -1;
-		model_counter = (uint8_t)red_val;
-	} else {
-		if (model_mode_is_used(cfg->cmp_mode))
-			model_counter = DEFAULT_MODEL_COUNTER + 1;
-	}
+	if (!model_counter && model_mode_is_used(cfg->cmp_mode))
+		model_counter++;
 
 	s = cmp_ent_build(cmp_entity,  cmp_tool_gen_version_id(CMP_TOOL_VERSION),
-			  start_time, cmp_ent_create_timestamp(NULL), model_id,
-			  model_counter, cfg, cmp_size);
+			  start_time, cmp_ent_create_timestamp(NULL), (uint16_t)model_id,
+			  (uint8_t)model_counter, cfg, cmp_size);
 	if (!s) {
 		fprintf(stderr, "%s: error occurred while creating the compression entity header.\n", PROGRAM_NAME);
 		goto error_cleanup;
diff --git a/test/cmp_tool/cmp_tool_integration_test.py b/test/cmp_tool/cmp_tool_integration_test.py
index 5cadbf231cc39ebe8f12c13d95b9a791df00c7cf..8eb95da31adb180ccd3bb3895f63e9ff90ee6b7c 100755
--- a/test/cmp_tool/cmp_tool_integration_test.py
+++ b/test/cmp_tool/cmp_tool_integration_test.py
@@ -7,9 +7,11 @@ import os
 import math
 import shutil
 from pathlib import Path
+import hashlib
 
 from datetime import datetime
 from datetime import timedelta
+from datetime import timezone
 
 
 EXIT_FAILURE = 1
@@ -78,7 +80,7 @@ def del_directory(directoryPath):
 
 
 def cuc_timestamp(now):
-    epoch = datetime(2020, 1, 1)
+    epoch = datetime(2020, 1, 1, tzinfo=timezone.utc)
     timestamp = (now - epoch).total_seconds()
 
     cuc_coarse = int( math.floor(timestamp) * 256 * 256)
@@ -447,9 +449,9 @@ def test_compression_diff():
                     assert(header['cmp_ent_size']['value'] == IMAGETTE_HEADER_SIZE+3)
                     assert(header['original_size']['value'] == 10)
                     # todo
-                    assert(header['start_time']['value'] < cuc_timestamp(datetime.utcnow()))
+                    assert(header['start_time']['value'] < cuc_timestamp(datetime.now(timezone.utc)))
                     # todo
-                    assert(header['end_timestamp']['value'] < cuc_timestamp(datetime.utcnow()))
+                    assert(header['end_timestamp']['value'] < cuc_timestamp(datetime.now(timezone.utc)))
                     assert(header['data_type']['value'] == 1)
                     assert(header['cmp_mode_used']['value'] == 2)
                     # assert(header['model_value_used']['value'] == 8)
@@ -582,9 +584,9 @@ def test_model_compression():
                 assert(header['cmp_ent_size']['value'] == IMAGETTE_ADAPTIVE_HEADER_SIZE+2)
                 assert(header['original_size']['value'] == 10)
                 # todo
-                assert(header['start_time']['value'] < cuc_timestamp(datetime.utcnow()))
+                assert(header['start_time']['value'] < cuc_timestamp(datetime.now(timezone.utc)))
                 #todo
-                assert(header['end_timestamp']['value'] < cuc_timestamp(datetime.utcnow()))
+                assert(header['end_timestamp']['value'] < cuc_timestamp(datetime.now(timezone.utc)))
                 assert(header['data_type']['value'] == DATA_TYPE_IMAGETTE_ADAPTIVE)
                 assert(header['cmp_mode_used']['value'] == 3)
                 assert(header['model_value_used']['value'] == int(cfg['model_value']))
@@ -691,9 +693,9 @@ def test_raw_mode_compression():
                     assert(header['cmp_ent_size']['value'] == GENERIC_HEADER_SIZE+10)
                     assert(header['original_size']['value'] == 10)
                     # todo
-                    assert(header['start_time']['value'] < cuc_timestamp(datetime.utcnow()))
+                    assert(header['start_time']['value'] < cuc_timestamp(datetime.now(timezone.utc)))
                     #todo
-                    assert(header['end_timestamp']['value'] < cuc_timestamp(datetime.utcnow()))
+                    assert(header['end_timestamp']['value'] < cuc_timestamp(datetime.now(timezone.utc)))
                     assert(header['data_type']['value'] == 1+0x8000)
                     # assert(header['cmp_mode_used']['value'] == 2)
                     # assert(header['model_value_used']['value'] == 8)
@@ -1017,8 +1019,8 @@ def test_sample_used_is_to_big():
     cmp_ent_size = IMAGETTE_HEADER_SIZE + len(cmp_data)//2
     original_size = 0xE # wrong original_size correct is 0xA
 
-    start_time = cuc_timestamp(datetime.utcnow())
-    end_time = cuc_timestamp(datetime.utcnow())
+    start_time = cuc_timestamp(datetime.now(timezone.utc))
+    end_time = cuc_timestamp(datetime.now(timezone.utc))
 
     data_type = 1
     cmp_mode_used = 2
@@ -1083,8 +1085,8 @@ def test_cmp_entity_not_4_byte_aligned():
     cmp_ent_size = IMAGETTE_HEADER_SIZE + len(cmp_data)//2
     original_size = 0xC
 
-    start_time = cuc_timestamp(datetime.utcnow())
-    end_time = cuc_timestamp(datetime.utcnow())
+    start_time = cuc_timestamp(datetime.now(timezone.utc))
+    end_time = cuc_timestamp(datetime.now(timezone.utc))
 
     data_type = 1
     cmp_mode_used = 2
@@ -1177,8 +1179,8 @@ def test_header_read_in():
     cmp_ent_size = IMAGETTE_HEADER_SIZE + len(cmp_data)//2
     original_size = 0xA
 
-    start_time = cuc_timestamp(datetime.utcnow())
-    end_time = cuc_timestamp(datetime.utcnow())
+    start_time = cuc_timestamp(datetime.now(timezone.utc))
+    end_time = cuc_timestamp(datetime.now(timezone.utc))
 
     data_type = 1
     cmp_mode_used = 2
@@ -1414,7 +1416,6 @@ def test_rdcu_pkt():
                      assert(f1.read() == f2.read())
 
     finally:
-        pass
         del_directory('TC_FILES')
         del_file(data_file_name)
         del_file(cfg_file_name)
@@ -1426,5 +1427,59 @@ def test_rdcu_pkt():
         del_file(output_prefix2+'_upmodel.dat')
 
 
+def test_chunk_compression():
+    # decompress the test data
+    output_prefix1 = "ref_short_cadence_1"
+    cmp_data_path1 = "test/cmp_tool/ref_short_cadence_1_cmp.cmp"
+    output_prefix2 = "ref_short_cadence_2"
+    cmp_data_path2 = "test/cmp_tool/ref_short_cadence_2_cmp.cmp"
+
+    try:
+        returncode, stdout, stderr = call_cmp_tool(
+            "--binary -d " + cmp_data_path1 + " -o " + output_prefix1)
+
+        assert(stderr == "")
+        assert(stdout == CMP_START_STR_DECMP +
+               "Importing compressed data file %s ... DONE\n" % (cmp_data_path1) +
+               "Decompress data ... DONE\n" +
+               "Write decompressed data to file %s.dat ... DONE\n" % (output_prefix1))
+        assert(returncode == EXIT_SUCCESS)
+
+        with open(output_prefix1 + '.dat', 'rb') as f:
+            sha1 = hashlib.sha1()
+            while True:
+                chunk = f.read(16 * 1024)
+                if not chunk:
+                    break
+                sha1.update(chunk)
+
+        assert(sha1.hexdigest() == "7d8d94d2ac904f9ff4f934bb691b469a7391ce9e")
+
+        returncode, stdout, stderr = call_cmp_tool(
+            "--binary -d " + cmp_data_path2 + " -m " + output_prefix1 + ".dat -o " + output_prefix2)
+
+        assert(stderr == "")
+        assert(stdout == CMP_START_STR_DECMP +
+               "Importing compressed data file %s ... DONE\n" % (cmp_data_path2) +
+               "Importing model file %s.dat ... DONE\n" % (output_prefix1) +
+               "Decompress data ... DONE\n" +
+               "Write decompressed data to file %s.dat ... DONE\n" % (output_prefix2) +
+               "Write updated model to file %s_upmodel.dat ... DONE\n" % (output_prefix2))
+        assert(returncode == EXIT_SUCCESS)
+
+        with open(output_prefix2 + '.dat', 'rb') as f:
+            sha1 = hashlib.sha1()
+            while True:
+                chunk = f.read(16 * 1024)
+                if not chunk:
+                    break
+                sha1.update(chunk)
+
+        assert(sha1.hexdigest() == "28ecc82a0c44ae7a461c26112b00f65b9b54e66a")
+
+    finally:
+        del_file(output_prefix1+'.dat')
+        del_file(output_prefix2+'.dat')
+        del_file(output_prefix2+'_upmodel.dat')
 
 # TODO: random test
diff --git a/test/cmp_tool/gen_test_data.c b/test/cmp_tool/gen_test_data.c
new file mode 100644
index 0000000000000000000000000000000000000000..05c1ddab03ad7067e7e9465b80bd78bf1f3691de
--- /dev/null
+++ b/test/cmp_tool/gen_test_data.c
@@ -0,0 +1,41 @@
+#include <stdio.h>
+#include <string.h>
+
+#include "../bench/ref_short_cadence_1_cmp.h"
+#include "../bench/ref_short_cadence_2_cmp.h"
+
+
+int main(int argc, char *argv[])
+{
+	int i;
+	FILE *fp;
+	size_t s;
+
+	if (argc < 1)
+		return 1;
+
+	for (i = 1; i < argc; i++) {
+		if (strstr(argv[i], "ref_short_cadence_1_cmp")) {
+			fp = fopen(argv[i], "wb");
+			if(!fp)
+				return 1;
+			s = fwrite(ref_short_cadence_1_cmp, 1, ref_short_cadence_1_cmp_len, fp);
+			fclose(fp);
+			if (s!=ref_short_cadence_1_cmp_len)
+				return 1;
+		} else if (strstr(argv[i], "ref_short_cadence_2_cmp")) {
+			fp = fopen(argv[i], "wb");
+			if(!fp)
+				return 1;
+			s = fwrite(ref_short_cadence_2_cmp, 1, ref_short_cadence_2_cmp_len, fp);
+			fclose(fp);
+			if (s!=ref_short_cadence_2_cmp_len)
+				return 1;
+		} else {
+			fprintf(stderr,"Unknown test data\n");
+			return 1;
+		}
+	}
+
+	return 0;
+}
diff --git a/test/cmp_tool/meson.build b/test/cmp_tool/meson.build
index dfa0ce6d35ecffc3639fbe45c2b3a3a85b9d4198..907a7ee0da6a60fcc4537c2545bf691b304faafe 100644
--- a/test/cmp_tool/meson.build
+++ b/test/cmp_tool/meson.build
@@ -1,12 +1,22 @@
 int_test_file = files('cmp_tool_integration_test.py')
 
+gen_test_data = executable('gen_test_data',
+  'gen_test_data.c',
+   c_args : '-Wno-overlength-strings',
+)
+
+test_data = custom_target('gen_test_data',
+  output : ['ref_short_cadence_1_cmp.cmp', 'ref_short_cadence_2_cmp.cmp'],
+  command : [gen_test_data, '@OUTPUT@']
+)
+
 pytest = find_program('pytest', required : false)
 if pytest.found()
   test('cmp_tool Interface Test',
     pytest,
     args : ['--color=yes', '-vvv', int_test_file],
     env: test_env,
-    depends : cmp_tool_exe,
+    depends : [cmp_tool_exe, test_data],
     timeout : 100,
     workdir : meson.project_build_root())
 else