From efad22f21ef69999fe85d7899a0e4bf0e3651b6e Mon Sep 17 00:00:00 2001
From: Abdelrahman <said.abdelrahman89@gmail.com>
Date: Mon, 6 May 2024 00:54:25 +0100
Subject: [PATCH] Fix alpha multiplication for images with unassociated alpha

---
 src/tiff/tiffread.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/src/tiff/tiffread.c b/src/tiff/tiffread.c
index 20ed256..d588342 100644
--- a/src/tiff/tiffread.c
+++ b/src/tiff/tiffread.c
@@ -221,6 +221,8 @@ internal bool read_field(const TiffField *field, TiffImage *img);
 internal bool validate_image_type(const TiffImage *img);
 internal void fread_with_offset(FILE *fp, void *dst, u64 count, u64 offset);
 internal bool valid_tiff_file(const char *file);
+internal f32 u8_normalise(u8 value);
+internal u8 u8_denormalise(f32 value);
 
 Image *read_baseline_tiff(const char *file, Arena *arena) {
   Image *img_out = NULL;
@@ -608,9 +610,11 @@ internal void read_strips(TiffReader *reader) {
         fread_with_offset(reader->fp, &(p->a), 1, alpha_offset);
 
         if (alpha.type == ALPHA_TYPE_UNASSOCIATED) {
-          p->r *= p->a;
-          p->g *= p->a;
-          p->b *= p->a;
+          f32 a_norm = u8_normalise(p->a);
+
+          p->r = u8_denormalise(u8_normalise(p->r) * a_norm);
+          p->g = u8_denormalise(u8_normalise(p->g) * a_norm);
+          p->b = u8_denormalise(u8_normalise(p->b) * a_norm);
         }
       }
 
@@ -857,3 +861,7 @@ internal bool valid_tiff_file(const char *file) {
 
   return true;
 }
+
+internal f32 u8_normalise(u8 value) { return (f32)value / (f32)UINT8_MAX; }
+
+internal u8 u8_denormalise(f32 value) { return (u8)(value * UINT8_MAX); }