diff --git a/lib/common/cmp_data_types.c b/lib/common/cmp_data_types.c
index 42d0831e482c52815daef331c2541ff6f1a194c6..d6283ce2017639cfe97cad88485a4ca1bd27e1d9 100644
--- a/lib/common/cmp_data_types.c
+++ b/lib/common/cmp_data_types.c
@@ -645,8 +645,12 @@ static void be_to_cpus_16(uint16_t *a, uint32_t samples)
 {
 	uint32_t i;
 
-	for (i = 0; i < samples; ++i)
-		be16_to_cpus(&a[i]);
+	for (i = 0; i < samples; ++i) {
+		uint16_t tmp;
+
+		tmp = be16_to_cpu(get_unaligned(&a[i]));
+		put_unaligned(tmp, &a[i]);
+	}
 }
 
 
diff --git a/lib/common/compiler.h b/lib/common/compiler.h
index 9f4d8b614a3837174c9d564fc196d73784209eea..fea1ca51e460e8ade92c3c0ec5c1df4234e144d2 100644
--- a/lib/common/compiler.h
+++ b/lib/common/compiler.h
@@ -47,11 +47,71 @@
 
 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
 
-/* optimisation barrier */
-#define barrier() __asm__ __volatile__("": : :"memory")
+#define bitsizeof(x)  (CHAR_BIT * sizeof(x))
 
-#define cpu_relax() barrier()
+#define maximum_signed_value_of_type(a) \
+    (INTMAX_MAX >> (bitsizeof(intmax_t) - bitsizeof(a)))
+
+#define maximum_unsigned_value_of_type(a) \
+    (UINTMAX_MAX >> (bitsizeof(uintmax_t) - bitsizeof(a)))
+
+/*
+ * Signed integer overflow is undefined in C, so here's a helper macro
+ * to detect if the sum of two integers will overflow.
+ *
+ * Requires: a >= 0, typeof(a) equals typeof(b)
+ */
+#define signed_add_overflows(a, b) \
+    ((b) > maximum_signed_value_of_type(a) - (a))
+
+#define unsigned_add_overflows(a, b) \
+    ((b) > maximum_unsigned_value_of_type(a) - (a))
+
+
+#define __get_unaligned_t(type, ptr) ({								\
+	const struct { type x; } __attribute__((packed)) *__pptr = (__typeof__(__pptr))(ptr);	\
+	__pptr->x;										\
+})
+
+#define __put_unaligned_t(type, val, ptr) do {							\
+	struct { type x; } __attribute__((packed)) *__pptr = (__typeof__(__pptr))(ptr);		\
+	__pptr->x = (val);									\
+} while (0)
+
+
+/**
+ * @brief read from an unaligned address
+ *
+ * @param ptr	pointer to the address to read from (can be unaligned)
+ *
+ * @return the value read from the (unaligned) address in system endianness
+ * @note the size of the value is determined by the pointer type
+ */
+
+#define get_unaligned(ptr)	__get_unaligned_t(__typeof__(*(ptr)), (ptr))
+
+
+/**
+ * @brief write to an unaligned address
+ *
+ * @param val	the value to write
+ * @param ptr	pointer to the address to write to (can be unaligned)
+ *
+ * @note the size of the value is determined by the pointer type
+ */
+
+#define put_unaligned(val, ptr) __put_unaligned_t(__typeof__(*(ptr)), (val), (ptr))
+
+
+/**
+ * @brief mark a variable as unused to suppress compiler warnings.
+ *
+ * This macro is used to indicate that a variable is intentionally left unused
+ * in the code. It helps suppress compiler warnings about unused variables.
+ *
+ * @param x The variable to mark as unused.
+ */
 
 #define UNUSED(x) (void)(x)
 
-#endif
+#endif /* COMPILER_H */
diff --git a/lib/icu_compress/cmp_icu.c b/lib/icu_compress/cmp_icu.c
index 05a47e77dabed3bdbe91c4e5f4186822f0e2b69b..5ce498c1b9b86caca32c969bbe3733d8d3efb1d6 100644
--- a/lib/icu_compress/cmp_icu.c
+++ b/lib/icu_compress/cmp_icu.c
@@ -867,7 +867,7 @@ static int compress_imagette(const struct cmp_cfg *cfg, int stream_len)
 	uint16_t *up_model_buf = NULL;
 
 	if (model_mode_is_used(cfg->cmp_mode)) {
-		model = model_buf[0];
+		model = get_unaligned(&model_buf[0]);
 		next_model_p = &model_buf[1];
 		up_model_buf = cfg->icu_new_model_buf;
 	}
@@ -892,17 +892,18 @@ static int compress_imagette(const struct cmp_cfg *cfg, int stream_len)
 				max_data_bits, cfg);
 
 	for (i = 0;; i++) {
-		stream_len = encode_value(data_buf[i], model, stream_len, &setup);
+		stream_len = encode_value(get_unaligned(&data_buf[i]),
+					  model, stream_len, &setup);
 		if (stream_len <= 0)
 			break;
 
 		if (up_model_buf)
-			up_model_buf[i] = cmp_up_model(data_buf[i], model, cfg->model_value,
-						       setup.lossy_par);
+			up_model_buf[i] = cmp_up_model(get_unaligned(&data_buf[i]),
+						       model, cfg->model_value, setup.lossy_par);
 		if (i >= cfg->samples-1)
 			break;
 
-		model = next_model_p[i];
+		model = get_unaligned(&next_model_p[i]);
 	}
 	return stream_len;
 }
@@ -2356,7 +2357,6 @@ static int32_t cmp_collection(uint8_t *col, uint8_t *model, uint8_t *updated_mod
 		uint8_t subservice = cmp_col_get_subservice(col_hdr);
 		uint16_t col_data_length = cmp_col_get_data_length(col_hdr);
 
-
 		cfg->data_type = convert_subservice_to_cmp_data_type(subservice);
 
 		if (!size_of_a_sample(cfg->data_type))