diff --git a/CHANGELOG.md b/CHANGELOG.md
index 82a8b865939b518e5ace05a6ada9e5d731d5d54c..18386d43e4eb8acb3468acf9d855a11e4a916584 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,8 +13,10 @@ separator is added after every second hexadecimal numeric character. Comments
 after a '#' symbol until the end of the line are ignored.
 E.g. "# comment\n ABCD 1    2\n34B 12\n" are interpreted as {0xAB, 0xCD,
 0x01, 0x02, 0x34, 0x0B, 0x12}.
-### Fixed
-- Fix a bug in the definition in imagette header
+### Changed
+- update the header definition according to PLATO-UVIE-PL-UM-0001 Draft 6
+    - changed version_id from 16 to 32 bit in the generic header. Add spare bits to the adaptive imagette header and the non-imagette header, so that the compressed data start address is 4 byte-aligned.
+- Rename cmp_tool_lib.c to cmp_io.c
 
 ## [0.07] - 13-12-2021
 - **NOTE:**  The behaviour of the cmp_tool has changed. From now on, the compressed data will be preceded by a header by default. The old behaviour can be achieved with the `--no_header` option.
diff --git a/README.md b/README.md
index 2b2802ff04774a5e48eebeb156a19ee2fa127026..325a24c78f8767358abc5604d6463f301955ecf9 100644
--- a/README.md
+++ b/README.md
@@ -75,9 +75,11 @@ RDCU-compatible compression mode depending on if the Model (-m) option is set.
 This command creates the file `myguess.cfg` with the guessed compression parameters.
 
 ### Data Format
+The input data is formatted as hexadecimal numbers.
+For example: `12 AB 34 CD` or `12AB34CD`.
 
-The input data must be formatted as two hex numbers separated by a space.
-For example: `12 AB 34 CD`.
+### User Manual
+You can find the user manual [here](doc).
 
 ## How to use the tool
 
diff --git a/cmp_tool.c b/cmp_tool.c
index 0cf2acd961580d5fabcd8d0798fab7ef7e2f1bff..fd8401f96975fd06a4c82b7a0216758ab33aae2a 100755
--- a/cmp_tool.c
+++ b/cmp_tool.c
@@ -482,21 +482,29 @@ fail:
 
 static enum cmp_ent_data_type cmp_ent_map_cmp_mode_data_type(uint32_t cmp_mode)
 {
+	enum cmp_ent_data_type data_type;
+
 	switch (cmp_mode) {
 	case MODE_RAW:
-		return DATA_TYPE_IMAGETTE;
 	case MODE_MODEL_ZERO:
 	case MODE_DIFF_ZERO:
 	case MODE_MODEL_MULTI:
 	case MODE_DIFF_MULTI:
 		if (print_rdcu_cfg)
-			return DATA_TYPE_IMAGETTE_ADAPTIVE;
+			data_type = DATA_TYPE_IMAGETTE_ADAPTIVE;
 		else
-			return DATA_TYPE_IMAGETTE;
+			data_type = DATA_TYPE_IMAGETTE;
+		break;
 	default:
 		printf("No mapping between compression mode and header data type\n!");
 		return DATA_TYPE_UNKOWN;
 	}
+
+	/* set raw bit if needed */
+	if (raw_mode_is_used(cmp_mode))
+		data_type |= 1UL << RAW_BIT_DATA_TYPE_POS;
+
+	return data_type;
 }
 
 
diff --git a/doc/PLATO-UVIE-PL-UM-0001_0r6.pdf b/doc/PLATO-UVIE-PL-UM-0001_0r6.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..581a47061c76f787b75e04ccf88a5064f370704e
Binary files /dev/null and b/doc/PLATO-UVIE-PL-UM-0001_0r6.pdf differ
diff --git a/include/cmp_entity.h b/include/cmp_entity.h
index 45a1b61ca837fda4ddf3d3fb60ce26fb53b3bd42..2d6bf542f1ec5b0c25f63fd257a2c3fbb325f78d 100644
--- a/include/cmp_entity.h
+++ b/include/cmp_entity.h
@@ -58,13 +58,13 @@ enum cmp_ent_data_type {
 	DATA_TYPE_F_CAM_IMAGETTE_ADAPTIVE,
 	DATA_TYPE_F_CAM_OFFSET,
 	DATA_TYPE_F_CAM_BACKGROUND,
-	DATA_TYPE_UNKOWN = -1
+	DATA_TYPE_UNKOWN = 0x7FFF,
 };
 
-#define GENERIC_HEADER_SIZE 30
+#define GENERIC_HEADER_SIZE 32
 #define SPECIFIC_IMAGETTE_HEADER_SIZE		4
-#define SPECIFIC_IMAGETTE_ADAPTIVE_HEADER_SIZE	10
-#define SPECIFIC_NON_IMAGETTE_HEADER_SIZE	30  /* TBC */
+#define SPECIFIC_IMAGETTE_ADAPTIVE_HEADER_SIZE	12
+#define SPECIFIC_NON_IMAGETTE_HEADER_SIZE	32
 
 #define IMAGETTE_HEADER_SIZE						\
 	(GENERIC_HEADER_SIZE + SPECIFIC_IMAGETTE_HEADER_SIZE)
@@ -75,9 +75,9 @@ enum cmp_ent_data_type {
 
 #define CMP_ENTITY_MAX_SIZE 0xFFFFFFUL
 
-#define RAW_BIT_IN_DATA_TYPE 15U
+#define RAW_BIT_DATA_TYPE_POS 15U
 
-#define CMP_TOOL_VERSION_ID_BIT 0x8000U /* TBC */
+#define CMP_TOOL_VERSION_ID_BIT 0x80000000U
 
 __extension__
 struct timestamp_cmp_ent {
@@ -100,6 +100,7 @@ struct imagette_header {
 			uint16_t ap2_spill_used;	/* Adaptive Spillover threshold used 2 */
 			uint8_t  ap2_golomb_par_used;	/* Adaptive Golomb parameter used 2 */
 			uint8_t  spare2;
+			uint16_t spare3;
 			uint8_t  ap_ima_cmp_data[];	/* compressed data for adaptive imagette specific header */
 		} __attribute__((packed));
 	};
@@ -120,13 +121,14 @@ struct non_imagette_header {
 	uint16_t cmp_par_5_used;	/* compression parameter 5 used */
 	uint32_t spill_6_used:24;	/* spillover threshold 6 used */
 	uint16_t cmp_par_6_used;	/* compression parameter 6 used */
+	uint16_t spare;
 	uint8_t  cmp_data[];
 } __attribute__((packed));
 compile_time_assert(sizeof(struct non_imagette_header) == SPECIFIC_NON_IMAGETTE_HEADER_SIZE, NON_IMAGETTE_HEADER_T_SIZE_IS_NOT_CORRECT);
 
 __extension__
 struct cmp_entity {
-	uint16_t asw_version_id;		/* ICU ASW Version ID */
+	uint32_t version_id;			/* ICU ASW/cmp_tool Version ID */
 	uint32_t cmp_ent_size:24;		/* Compression Entity Size */
 	uint32_t original_size:24;		/* Original Data Size */
 	union {
@@ -161,7 +163,7 @@ size_t cmp_ent_create(struct cmp_entity *ent, enum cmp_ent_data_type data_type,
 
 /* create a compression entity and set the header fields */
 size_t cmp_ent_build(struct cmp_entity *ent, enum cmp_ent_data_type data_type,
-		     uint16_t asw_version_id, uint64_t start_time,
+		     uint32_t version_id, uint64_t start_time,
 		     uint64_t end_time, uint16_t model_id, uint8_t model_counter,
 		     struct cmp_info *info, struct cmp_cfg *cfg);
 
@@ -171,7 +173,7 @@ int cmp_ent_read_imagette_header(struct cmp_entity *ent, struct cmp_info *info);
 
 
 /* set functions for generic compression entity header */
-int cmp_ent_set_asw_version_id(struct cmp_entity *ent, uint32_t asw_version_id);
+int cmp_ent_set_version_id(struct cmp_entity *ent, uint32_t version_id);
 int cmp_ent_set_size(struct cmp_entity *ent, uint32_t cmp_ent_size);
 
 int cmp_ent_set_original_size(struct cmp_entity *ent, uint32_t original_size);
@@ -186,7 +188,7 @@ int cmp_ent_set_fine_end_time(struct cmp_entity *ent, uint16_t fine_time);
 
 int cmp_ent_set_data_type(struct cmp_entity *ent,
 			  enum cmp_ent_data_type data_type);
-int cmp_ent_set_data_type_raw_bit(struct cmp_entity *ent, int raw_bit);
+int cmp_ent_data_type_valid(enum cmp_ent_data_type data_type);
 int cmp_ent_set_cmp_mode(struct cmp_entity *ent, uint32_t cmp_mode_used);
 int cmp_ent_set_model_value(struct cmp_entity *ent, uint32_t model_value_used);
 int cmp_ent_set_model_id(struct cmp_entity *ent, uint32_t model_id);
@@ -233,7 +235,7 @@ int cmp_ent_set_non_ima_cmp_par6(struct cmp_entity *ent, uint32_t cmp_par6_used)
 
 
 /* get functions for generic compression entity header */
-uint16_t cmp_ent_get_asw_version_id(struct cmp_entity *ent);
+uint32_t cmp_ent_get_version_id(struct cmp_entity *ent);
 uint32_t cmp_ent_get_size(struct cmp_entity *ent);
 uint32_t cmp_ent_get_original_size(struct cmp_entity *ent);
 
diff --git a/include/cmp_io.h b/include/cmp_io.h
index 1ad04e5d6b0263fb637da904fb25bc2005d849e8..77dce35b4f571b485267a8fae2ed74b726c38f2b 100644
--- a/include/cmp_io.h
+++ b/include/cmp_io.h
@@ -41,7 +41,7 @@ ssize_t read_file32(const char *file_name, uint32_t *buf, uint32_t samples,
 ssize_t read_file_cmp_entity(const char *file_name, struct cmp_entity *ent,
 			   uint32_t ent_size, int verbose_en);
 
-uint16_t cmp_tool_gen_version_id(const char *version);
+uint32_t cmp_tool_gen_version_id(const char *version);
 
 int write_cmp_data_file(const void *buf, uint32_t buf_size, const char
 			*output_prefix, const char *name_extension, int verbose);
diff --git a/lib/cmp_entity.c b/lib/cmp_entity.c
index 5572f293752ed09f642a9f1bc98865775692920a..84f784d0993f62f12336966ce398ec7ff33f3e1d 100644
--- a/lib/cmp_entity.c
+++ b/lib/cmp_entity.c
@@ -84,6 +84,9 @@ uint32_t cmp_ent_cal_hdr_size(enum cmp_ent_data_type data_type)
 		return 0;
 	}
 
+	if ((data_type >> RAW_BIT_DATA_TYPE_POS) & 1U)
+		return GENERIC_HEADER_SIZE;
+
 	return 0;
 }
 
@@ -109,20 +112,17 @@ int cmp_ent_data_type_valid(enum cmp_ent_data_type data_type)
  * @brief set ICU ASW Version ID in the compression entity header
  *
  * @param ent			pointer to a compression entity
- * @param asw_version_id	the applications software version identifier
+ * @param version_id	the applications software version identifier
  *
  * @returns 0 on success, otherwise error
  */
 
-int cmp_ent_set_asw_version_id(struct cmp_entity *ent, uint32_t asw_version_id)
+int cmp_ent_set_version_id(struct cmp_entity *ent, uint32_t version_id)
 {
 	if (!ent)
 		return -1;
 
-	if (asw_version_id > UINT16_MAX)
-		return -1;
-
-	ent->asw_version_id = cpu_to_be16(asw_version_id);
+	ent->version_id = cpu_to_be32(version_id);
 
 	return 0;
 }
@@ -326,7 +326,8 @@ int cmp_ent_set_fine_end_time(struct cmp_entity *ent, uint16_t fine_time)
 /**
  * @brief set the data product type in the compression entity header
  *
- * @param ent		pointer to a compression entity
+ * @param ent		pointer to a compression entity (including the
+ *	uncompressed data bit)
  * @param data_type	compression entity data product type
  *
  * @returns 0 on success, otherwise error
@@ -338,44 +339,15 @@ int cmp_ent_set_data_type(struct cmp_entity *ent,
 	if (!ent)
 		return -1;
 
-	if ((unsigned int)data_type > 0x7FFF)
+	if (data_type > UINT16_MAX)
 		return -1;
 
-	data_type |= cmp_ent_get_data_type_raw_bit(ent) << RAW_BIT_IN_DATA_TYPE;
-
 	ent->data_type = cpu_to_be16(data_type);
 
 	return 0;
 }
 
 
-/**
- * @brief set the raw bit in the data product field of the compression entity header
- *
- * @param ent		pointer to a compression entity
- * @param raw_bit	raw bit is set if raw_bit is non zero
- *
- * @returns 0 on success, otherwise error
- */
-
-int cmp_ent_set_data_type_raw_bit(struct cmp_entity *ent, int raw_bit)
-{
-	uint16_t data_type;
-
-	if (!ent)
-		return -1;
-
-	if (raw_bit)
-		data_type = cpu_to_be16(ent->data_type) | 1UL << RAW_BIT_IN_DATA_TYPE;
-	else
-		data_type = cpu_to_be16(ent->data_type) & ~(1UL << RAW_BIT_IN_DATA_TYPE);
-
-	ent->data_type =  cpu_to_be16(data_type);
-
-	return 0;
-}
-
-
 /**
  * @brief set the used compression mode in the compression entity header
  *
@@ -967,12 +939,12 @@ int cmp_ent_set_non_ima_cmp_par6(struct cmp_entity *ent, uint32_t cmp_par_6_used
  * @returns the ASW version identifier on success, 0 on error
  */
 
-uint16_t cmp_ent_get_asw_version_id(struct cmp_entity *ent)
+uint32_t cmp_ent_get_version_id(struct cmp_entity *ent)
 {
 	if (!ent)
 		return 0;
 
-	return be16_to_cpu(ent->asw_version_id);
+	return be32_to_cpu(ent->version_id);
 }
 
 
@@ -1133,7 +1105,8 @@ uint16_t cmp_ent_get_fine_end_time(struct cmp_entity *ent)
  *
  * @param ent	pointer to a compression entity
  *
- * @returns the data_type on success, DATA_TYPE_UNKOWN on error
+ * @returns the data_type (including the uncompressed data bit) on success,
+ *	DATA_TYPE_UNKOWN on error
  */
 
 enum cmp_ent_data_type cmp_ent_get_data_type(struct cmp_entity *ent)
@@ -1141,7 +1114,7 @@ enum cmp_ent_data_type cmp_ent_get_data_type(struct cmp_entity *ent)
 	if (!ent)
 		return DATA_TYPE_UNKOWN;
 
-	enum cmp_ent_data_type data_type = be16_to_cpu(ent->data_type) & 0X7FFF;
+	enum cmp_ent_data_type data_type = be16_to_cpu(ent->data_type);
 
 	if (cmp_ent_data_type_valid(data_type))
 		return data_type;
@@ -1163,7 +1136,7 @@ int cmp_ent_get_data_type_raw_bit(struct cmp_entity *ent)
 	if (!ent)
 		return 0;
 
-	return (be16_to_cpu(ent->data_type) >> RAW_BIT_IN_DATA_TYPE) & 1U;
+	return (be16_to_cpu(ent->data_type) >> RAW_BIT_DATA_TYPE_POS) & 1U;
 }
 
 
@@ -1620,6 +1593,9 @@ void *cmp_ent_get_data_buf(struct cmp_entity *ent)
 	if (!ent)
 		return NULL;
 
+	if (cmp_ent_get_data_type_raw_bit(ent))
+		return (uint8_t *)ent + GENERIC_HEADER_SIZE;
+
 	data_type = cmp_ent_get_data_type(ent);
 
 	switch (data_type) {
@@ -1839,13 +1815,15 @@ static int cmp_ent_write_cmp_pars(struct cmp_entity *ent, struct cmp_info *info,
 		return -1;
 	if (cmp_ent_set_cmp_mode(ent, info->cmp_mode_used))
 		return -1;
-	if (cmp_ent_set_data_type_raw_bit(ent, raw_mode_is_used(info->cmp_mode_used)))
-		return -1;
 	if (cmp_ent_set_model_value(ent, info->model_value_used))
 		return -1;
 	if (cmp_ent_set_lossy_cmp_par(ent, info->round_used))
 		return -1;
 
+	if (cmp_ent_get_data_type_raw_bit(ent))
+		/* no specific header is used for raw data we are done */
+		return 0;
+
 	switch (cmp_ent_get_data_type(ent)) {
 	case DATA_TYPE_IMAGETTE_ADAPTIVE:
 	case DATA_TYPE_SAT_IMAGETTE_ADAPTIVE:
@@ -1956,7 +1934,7 @@ size_t cmp_ent_create(struct cmp_entity *ent, enum cmp_ent_data_type data_type,
  * @param ent			pointer to a compression entity; if NULL, the
  *	function returns the needed size
  * @param data_type		compression entity data product type
- * @param asw_version_id	applications software version identifier
+ * @param version_id	applications software version identifier
  * @param start_time		compression start timestamp (coarse and fine)
  * @param end_time		compression end timestamp (coarse and fine)
  * @param model_id		model identifier
@@ -1969,7 +1947,7 @@ size_t cmp_ent_create(struct cmp_entity *ent, enum cmp_ent_data_type data_type,
  */
 
 size_t cmp_ent_build(struct cmp_entity *ent, enum cmp_ent_data_type data_type,
-		     uint16_t asw_version_id, uint64_t start_time,
+		     uint32_t version_id, uint64_t start_time,
 		     uint64_t end_time, uint16_t model_id, uint8_t model_counter,
 		     struct cmp_info *info, struct cmp_cfg *cfg)
 {
@@ -1983,7 +1961,7 @@ size_t cmp_ent_build(struct cmp_entity *ent, enum cmp_ent_data_type data_type,
 		return 0;
 
 	if (ent) {
-		if (cmp_ent_set_asw_version_id(ent, asw_version_id))
+		if (cmp_ent_set_version_id(ent, version_id))
 			return 0;
 		if (cmp_ent_set_start_timestamp(ent, start_time))
 			return 0;
@@ -2216,20 +2194,20 @@ void cmp_ent_print(struct cmp_entity *ent)
 
 static void cmp_ent_parse_generic_header(struct cmp_entity *ent)
 {
-	uint32_t asw_version_id, cmp_ent_size, original_size, cmp_mode_used,
+	uint32_t version_id, cmp_ent_size, original_size, cmp_mode_used,
 		 model_value_used, model_id, model_counter, lossy_cmp_par_used,
 		 start_coarse_time, end_coarse_time;
 	uint16_t start_fine_time, end_fine_time;
 	enum cmp_ent_data_type data_type;
 	int raw_bit;
 
-	asw_version_id = cmp_ent_get_asw_version_id(ent);
-	if (asw_version_id & CMP_TOOL_VERSION_ID_BIT) {
-		uint16_t major = (asw_version_id & 0x7F00U) >> 8U;
-		uint16_t minor = asw_version_id & 0x00FFU;
-		printf("Compressed with cmp_tool version: %u.%02u\n", major,minor);
+	version_id = cmp_ent_get_version_id(ent);
+	if (version_id & CMP_TOOL_VERSION_ID_BIT) {
+		uint16_t major = (version_id & 0x7FFF0000U) >> 16U;
+		uint16_t minor = version_id & 0xFFFFU;
+		printf("Compressed with cmp_tool version: %u.%02u\n", major, minor);
 	} else
-		printf("ICU ASW Version ID: %u\n", asw_version_id);
+		printf("ICU ASW Version ID: %u\n", version_id);
 
 	cmp_ent_size = cmp_ent_get_size(ent);
 	printf("Compression Entity Size: %u byte\n", cmp_ent_size);
diff --git a/lib/cmp_io.c b/lib/cmp_io.c
index f47ff8d60c6e194ea3275f682725beb09bab3385..9f7fd7294ee4884cc7624deea3588b6cad403dbb 100644
--- a/lib/cmp_io.c
+++ b/lib/cmp_io.c
@@ -937,6 +937,7 @@ static const char *skip_space(const char *str)
 static const char *skip_comment(const char *str)
 {
 	char c = *str;
+
 	if (c == '#') {
 		do {
 			str++;
@@ -1040,14 +1041,15 @@ static ssize_t str2uint8_arr(const char *str, uint8_t *data, uint32_t n_word,
 	errno = 0;
 
 	if (!data)
-		n_word =~0;
+		n_word = ~0;
 
 	if (!file_name)
 		file_name = "unknown file name";
 
-	for (i=0; i < n_word; ) {
+	for (i = 0; i < n_word; ) {
 		uint8_t read_val;
 		unsigned char c = *nptr;
+
 		if (c == '\0') {
 			if (!data)  /* finished counting the sample */
 				break;
@@ -1140,15 +1142,15 @@ ssize_t read_file8(const char *file_name, uint8_t *buf, uint32_t n_word, int ver
 	char *file_cpy = NULL;
 	long file_size;
 	ssize_t size;
+	size_t ret_code;
 
 	if (!file_name)
 		abort();
 
 	errno = 0;
-	fp = fopen(file_name, "r");
-	if (fp == NULL) {
+	fp = fopen(file_name, "rb");
+	if (fp == NULL)
 		goto fail;
-	}
 
 	/* Get the number of bytes */
 	if (fseek(fp, 0L, SEEK_END) != 0)
@@ -1172,8 +1174,8 @@ ssize_t read_file8(const char *file_name, uint8_t *buf, uint32_t n_word, int ver
 	}
 
 	/* copy all the text into the file_cpy buffer */
-	size_t ret_code = fread(file_cpy, sizeof(char), file_size, fp);
-	if(ret_code != (size_t)file_size) {
+	ret_code = fread(file_cpy, sizeof(char), file_size, fp);
+	if (ret_code != (size_t)file_size) {
 		if (feof(fp))
 			printf("%s: %s: Error: unexpected end of file.\n", PROGRAM_NAME, file_name);
 		goto fail;
@@ -1304,7 +1306,8 @@ ssize_t read_file_cmp_entity(const char *file_name, struct cmp_entity *ent,
 
 	if (ent) {
 		enum cmp_ent_data_type data_type = cmp_ent_get_data_type(ent);
-		if (data_type == DATA_TYPE_UNKOWN) {
+
+		if (!cmp_ent_data_type_valid(data_type)) {
 			fprintf(stderr, "%s: %s: Error: Compression data type is not supported.\n",
 				PROGRAM_NAME, file_name);
 			return -1;
@@ -1332,11 +1335,11 @@ ssize_t read_file_cmp_entity(const char *file_name, struct cmp_entity *ent,
  * @returns version_id for the compression header; 0 on error
  */
 
-uint16_t cmp_tool_gen_version_id(const char *version)
+uint32_t cmp_tool_gen_version_id(const char *version)
 {
 	char *copy, *token;
 	unsigned int n;
-	uint16_t version_id;
+	uint32_t version_id;
 
 	/*
 	 * version_id bits: msb |xxxx xxxx | xxxx xxxx| lsb
@@ -1348,11 +1351,11 @@ uint16_t cmp_tool_gen_version_id(const char *version)
 	copy = strdup(version);
 	token = strtok(copy, ".");
 	n = atoi(token);
-	if (n > UINT8_MAX) {
+	if (n > UINT16_MAX) {
 		free(copy);
 		return 0;
 	}
-	version_id = ((uint16_t)n) << 8U;
+	version_id = n << 16U;
 	if (version_id & CMP_TOOL_VERSION_ID_BIT) {
 		free(copy);
 		return 0;
@@ -1361,7 +1364,7 @@ uint16_t cmp_tool_gen_version_id(const char *version)
 	token = strtok(NULL, ".");
 	n = atoi(token);
 	free(copy);
-	if (n > UINT8_MAX)
+	if (n > UINT16_MAX)
 		return 0;
 
 	version_id |= n;
diff --git a/test/cmp_tool/cmp_tool_integration_test.py b/test/cmp_tool/cmp_tool_integration_test.py
index 78d2be3c67c9b3bead804dc1f28cb280f24ae08a..f5a022b3538c3e280383eb2af22368bc3201a701 100644
--- a/test/cmp_tool/cmp_tool_integration_test.py
+++ b/test/cmp_tool/cmp_tool_integration_test.py
@@ -13,6 +13,11 @@ EXIT_FAILURE = 1
 EXIT_SUCCESS = 0
 
 
+GENERIC_HEADER_SIZE = 32
+IMAGETTE_HEADER_SIZE = GENERIC_HEADER_SIZE+4
+IMAGETTE_ADAPTIVE_HEADER_SIZE = GENERIC_HEADER_SIZE+12
+NON_IMAGETTE_HEADER_SIZE = GENERIC_HEADER_SIZE+32
+
 def call_cmp_tool(args):
     args = shlex.split(PATH_CMP_TOOL + " " + args)
 
@@ -57,9 +62,8 @@ def cuc_timestamp(now):
 
 
 def read_in_cmp_header(compressed_string):
-    GENERIC_HEADER_SIZE = 30
 
-    header = { 'asw_version_id'     : { 'value': -1, 'bits': 16 },
+    header = { 'asw_version_id'     : { 'value': -1, 'bits': 32 },
                'cmp_ent_size'       : { 'value': -1, 'bits': 24 },
                'original_size'      : { 'value': -1, 'bits': 24 },
                'start_time'         : { 'value': -1, 'bits': 48 },
@@ -69,7 +73,7 @@ def read_in_cmp_header(compressed_string):
                'model_value_used'   : { 'value': -1, 'bits': 8 },
                'model_id'           : { 'value': -1, 'bits': 16 },
                'model_counter'      : { 'value': -1, 'bits': 8 },
-               'spare'              : { 'value': 0, 'bits': 8 },
+               'spare'              : { 'value': -1, 'bits': 8 },
                'lossy_cmp_par_used' : { 'value': -1, 'bits': 16 },
                'spill_used'         : { 'value': -1, 'bits': 16 },
                'golomb_par_used'    : { 'value': -1, 'bits': 8 },
@@ -77,6 +81,7 @@ def read_in_cmp_header(compressed_string):
                'ap1_golomb_par'     : { 'value': -1, 'bits': 8 },
                'ap2_spill_used'     : { 'value': -1, 'bits': 16 },
                'ap2_golomb_par'     : { 'value': -1, 'bits': 8 },
+               'spare_ap_ima'       : { 'value': -1, 'bits': 8 },
                'spill_1_used'       : { 'value': -1, 'bits': 24 },
                'cmp_par_1_used'     : { 'value': -1, 'bits': 16 },
                'spill_2_used'       : { 'value': -1, 'bits': 24 },
@@ -89,6 +94,7 @@ def read_in_cmp_header(compressed_string):
                'cmp_par_5_used'     : { 'value': -1, 'bits': 16 },
                'spill_6_used'       : { 'value': -1, 'bits': 24 },
                'cmp_par_6_used'     : { 'value': -1, 'bits': 16 },
+               'spare_non_ima'      : { 'value': -1, 'bits': 16 },
                'compressed_data'    : { 'value': -1, 'bits': -1 }}
 
     l = 0
@@ -102,13 +108,13 @@ def read_in_cmp_header(compressed_string):
         header[data_field]['value'] = int(compressed_string[l:l+byte_len], 16)
         l += byte_len
         # end of the GENERIC_HEADER
-        if l >= GENERIC_HEADER_SIZE*2:
+        if l/2 >= GENERIC_HEADER_SIZE:
             break
 
-    data_type = header['data_type']['value'] & 0x7FFF
+    data_type = int(header['data_type']['value'])
     # Imagette Headers
     if data_type == 1 or data_type == 2:
-        for data_field in list(header)[12:18]:
+        for data_field in list(header)[12:19]:
             if header[data_field]['bits'] % 4 != 0:
                 raise Exception("only work with 4 bit aligned data fields")
             byte_len = header[data_field]['bits']//4
@@ -116,31 +122,57 @@ def read_in_cmp_header(compressed_string):
             l += byte_len
             # skip adaptive stuff if non adaptive header
             if data_field == 'golomb_par_used' and  data_type == 1:
-                # l +=2
+                l += 2  # spare bits
+                assert(l/2==IMAGETTE_HEADER_SIZE)
                 break
-        l += 2  # spare bits
+        if data_type == 2:
+            assert(l/2== NON_IMAGETTE_HEADER_SIZE)
 
     # Non-Imagette Headers
     elif data_type < 24:
-        for data_field in list(header)[18:30]:
+        for data_field in list(header)[19:31]:
             if header[data_field]['bits'] % 4 != 0:
                 raise Exception("only work with 4 bit aligned data fields")
             byte_len = header[data_field]['bits']//4
             header[data_field]['value'] = int(compressed_string[l:l+byte_len], 16)
             l += byte_len
+        assert(l/2 == NON_IMAGETTE_HEADER_SIZE)
     else:
-        raise Exception("data_type unknown")
+        if (data_type >> 15) == 0: # check if raw mode is set
+            raise Exception("data_type unknown")
 
     header['compressed_data']['value'] = compressed_string[l::]
 
     # version conversion fuu
     version_id = header['asw_version_id']['value']
-    if version_id & 0x8000:
-        header['asw_version_id']['value'] = "%.2f" % (int(version_id & 0x7F00)/256. + int(version_id&0xFF)*0.01)
+    if version_id & 0x80000000:
+        header['asw_version_id']['value'] = "%.2f" % (int(version_id & 0x7FFF0000)//0x8000 + int(version_id&0xFFFF)*0.01)
 
     return header
 
 
+def build_generic_header(asw_version_id, cmp_ent_size, original_size,
+                         start_time, end_time, data_type, cmp_mode_used,
+                         model_value_used, model_id, model_counter,
+                         lossy_cmp_par_used):
+
+    generic_header = ("%08X " % asw_version_id + "%06X " % cmp_ent_size +
+        "%06X " % original_size + "%012X " % start_time +
+        "%012X " % end_time + "%04X " % data_type +
+        "%02X " % cmp_mode_used + "%02X " % model_value_used +
+        "%04X " % model_id + "%02X " % model_counter+ "00 " +
+        "%04X " % lossy_cmp_par_used)
+
+    assert(len(generic_header.replace(" ", ""))/2 == GENERIC_HEADER_SIZE)
+    return generic_header
+
+
+def build_imagette_header(spill_used, golomb_par_used):
+   ima_header = "%04X %02X 00 " % (spill_used, golomb_par_used)
+   assert(len(ima_header.replace(" ", ""))/2 == IMAGETTE_HEADER_SIZE - GENERIC_HEADER_SIZE)
+   return ima_header
+
+
 #get version
 returncode, stdout, stderr = call_cmp_tool("--version")
 assert(returncode == EXIT_SUCCESS)
@@ -378,9 +410,10 @@ def test_compression_diff():
                     assert(info['cmp_size'] == '20')
                     assert(info['cmp_err'] == '0')
                 else:
+                    # import pdb; pdb.set_trace()
                     header = read_in_cmp_header(f.read())
                     assert(header['asw_version_id']['value'] == VERSION)
-                    assert(header['cmp_ent_size']['value'] == 34+4)
+                    assert(header['cmp_ent_size']['value'] == IMAGETTE_HEADER_SIZE+4)
                     assert(header['original_size']['value'] == 10)
                     # todo
                     assert(header['start_time']['value'] < cuc_timestamp(datetime.utcnow()))
@@ -565,7 +598,7 @@ def test_raw_mode_compression():
                 else:
                     header = read_in_cmp_header(f.read())
                     assert(header['asw_version_id']['value'] == VERSION)
-                    assert(header['cmp_ent_size']['value'] == 34+12)
+                    assert(header['cmp_ent_size']['value'] == GENERIC_HEADER_SIZE+12)
                     assert(header['original_size']['value'] == 10)
                     # todo
                     assert(header['start_time']['value'] < cuc_timestamp(datetime.utcnow()))
@@ -647,11 +680,12 @@ def test_guess_option():
                     exp_out = ('', '2', '', '7.27')
                 elif sub_test == 'guess_RDCU_model':
                     exp_out = (
-                        'Importing model file model.dat ... DONE\n', '2', '', '0.23')
+                        'Importing model file model.dat ... DONE\n', '2', '', str(round((5*2)/(IMAGETTE_ADAPTIVE_HEADER_SIZE + 4), 2)))
                         #cmp_size:15bit-> 4byte cmp_data + 40byte header -> 16bit*5/(44Byte*8) '5.33'
                 elif sub_test == 'guess_level_3':
                     exp_out = (
-                        '', '3', ' 0%... 6%... 13%... 19%... 25%... 32%... 38%... 44%... 50%... 57%... 64%... 72%... 80%... 88%... 94%... 100%', '0.26') #11.43
+                        '', '3', ' 0%... 6%... 13%... 19%... 25%... 32%... 38%... 44%... 50%... 57%... 64%... 72%... 80%... 88%... 94%... 100%',
+                        str(round((5*2)/(IMAGETTE_HEADER_SIZE + 4), 2))) #11.43
                     # cmp_size:7 bit -> 4byte cmp_data + 34 byte header -> 16bit*5/(40Byte*8)
                 else:
                     exp_out = ('', '', '')
@@ -891,11 +925,35 @@ def test_wrong_formart_cmp_fiel():
 
 
 def test_sample_used_is_to_big():
-    cmp_data_header = '80 07 00 00 26 00 00 0E 03 9E 1D 5A 67 76 03 9E 1D 5A 67 9F 00 01 02 08 42 23 13 00 00 00 00 3C 07 00 44 44 44 00 \n'
-    #                                        ^ wrong samples_used
-    cmp_data_no_header = '44 44 44 00 \n'
+    cmp_data = '44444400'
+
+    version_id = 0x8001_0042
+    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())
+
+    data_type = 1
+    cmp_mode_used = 2
+    model_value_used = 8
+    model_id = 0xBEEF
+    model_counter = 0
+    lossy_cmp_par_used = 0
+
+    generic_header = build_generic_header(version_id, cmp_ent_size,
+                        original_size, start_time, end_time, data_type,
+                        cmp_mode_used, model_value_used, model_id,
+                        model_counter, lossy_cmp_par_used)
+    spill_used = 60
+    golomb_par_used = 7
+
+    ima_header = build_imagette_header(spill_used, golomb_par_used)
+    cmp_data_header = generic_header + ima_header + cmp_data
+
     info = ("cmp_size = 20\n" + "golomb_par_used = 1\n" + "spill_used = 4\n"
             + "cmp_mode_used = 2\n" +"samples_used=5\n")
+    #                                              ^ wrong samples_used
     cmp_file_name = 'big_cmp_size.cmp'
     info_file_name = 'big_cmp_size.info'
     pars = ['-i %s -d %s --no_header' % (info_file_name, cmp_file_name),
@@ -908,7 +966,7 @@ def test_sample_used_is_to_big():
         for par in pars:
             with open(cmp_file_name, 'w') as f:
                 if '--no_header' in par:
-                    f.write(cmp_data_no_header)
+                    f.write(cmp_data)
                 else:
                     f.write(cmp_data_header)
 
@@ -934,8 +992,9 @@ def test_sample_used_is_to_big():
         del_file(info_file_name)
 
 
-def test_read_in_header():
-    cmp_file_name = 'read_in_header.cmp'
+
+def test_header_wrong_formatted():
+    cmp_file_name = 'read_wrong_format_header.cmp'
 
     # packet wrong formatted
     header = '80 07 00 00 !'
@@ -948,33 +1007,77 @@ def test_read_in_header():
                "Importing compressed data file %s ... FAILED\n" % (cmp_file_name))
         assert(stderr == "cmp_tool: %s: Error read in '!'. The data are not correct formatted.\n" % (cmp_file_name))
 
-        # packet to small
-        header = '80 07 00 00 26 00 00 0C 03 9E 1D 5A 67 76 03 9E 1D 5A 67 9F 00 01 02 08 42 23 13 00 00 00 00 3C 07 00 44 \n'
-        #                                                                                                packet cut-off    ^^ ^^
+    finally:
+        del_file(cmp_file_name)
+
+def test_header_read_in():
+    cmp_file_name = 'test_header_read_in.cmp'
+
+    cmp_data = '44444400'
+
+    version_id = 0x8001_0042
+    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())
+
+    data_type = 1
+    cmp_mode_used = 2
+    model_value_used = 8
+    model_id = 0xBEEF
+    model_counter = 0
+    lossy_cmp_par_used = 0
+
+    generic_header = build_generic_header(version_id, cmp_ent_size,
+                        original_size, start_time, end_time, data_type,
+                        cmp_mode_used, model_value_used, model_id,
+                        model_counter, lossy_cmp_par_used)
+    spill_used = 60
+    golomb_par_used = 7
+
+    ima_header = build_imagette_header(spill_used, golomb_par_used)
+    cmp_ent = generic_header + ima_header + cmp_data
+    # packet to small
+    cmp_ent = cmp_ent[:-4]
+    try:
         with open(cmp_file_name, 'w') as f:
-            f.write(header)
+            f.write(cmp_ent)
         returncode, stdout, stderr = call_cmp_tool('-d %s' % (cmp_file_name))
         assert(returncode == EXIT_FAILURE)
         assert(stdout == CMP_START_STR_DECMP +
                "Importing compressed data file %s ... FAILED\n" % (cmp_file_name))
         assert(stderr == "cmp_tool: %s: The size of the compression entity set in the header of the compression entity is not the same size as the read-in file has.\n" %(cmp_file_name))
 
-        # packet false data type
-        header = '80 07 00 00 26 00 00 0C 03 9E 1D 5A 67 76 03 9E 1D 5A 67 9F 7F FE 02 08 42 23 13 00 00 00 00 3C 07 00 44 44 44 00 \n'
-        #                                                                     ^^ ^^ false data type
+        # false data type
+        data_type = 0x7FFE
+        generic_header = build_generic_header(version_id, cmp_ent_size,
+                        original_size, start_time, end_time, data_type,
+                        cmp_mode_used, model_value_used, model_id,
+                        model_counter, lossy_cmp_par_used)
+        ima_header = build_imagette_header(spill_used, golomb_par_used)
+        cmp_ent = generic_header + ima_header + cmp_data
+        data_type = 1
+
         with open(cmp_file_name, 'w') as f:
-            f.write(header)
+            f.write(cmp_ent)
         returncode, stdout, stderr = call_cmp_tool('-d %s' % (cmp_file_name))
         assert(returncode == EXIT_FAILURE)
         assert(stdout == CMP_START_STR_DECMP +
                "Importing compressed data file %s ... FAILED\n" % (cmp_file_name))
         assert(stderr == "cmp_tool: %s: Error: Compression data type is not supported.\n" % (cmp_file_name))
 
-        # packet false data type
-        header = '80 07 00 00 26 00 00 0C 03 9E 1D 5A 67 76 03 9E 1D 5A 67 9F 00 01 FF 08 42 23 13 00 00 00 00 3C 07 00 44 44 44 00 \n'
-        #                                                                           ^^ false cmp_mode_used
+        # false cmp_mode_used
+        cmp_mode_used = 0xFF
+        generic_header = build_generic_header(version_id, cmp_ent_size,
+                        original_size, start_time, end_time, data_type,
+                        cmp_mode_used, model_value_used, model_id,
+                        model_counter, lossy_cmp_par_used)
+        ima_header = build_imagette_header(spill_used, golomb_par_used)
+        cmp_ent = generic_header + ima_header + cmp_data
+        cmp_mode_used = 2
         with open(cmp_file_name, 'w') as f:
-            f.write(header)
+            f.write(cmp_ent)
         returncode, stdout, stderr = call_cmp_tool('-d %s' % (cmp_file_name))
         assert(returncode == EXIT_FAILURE)
         assert(stdout == CMP_START_STR_DECMP +