From 2845e0003ed3a7960257ef19b139627ee69523dc Mon Sep 17 00:00:00 2001
From: Dan Brown <ssddanbrown@googlemail.com>
Date: Thu, 9 Feb 2023 15:14:41 +0000
Subject: [PATCH] Got favicons better supported, can't get transparency right

Digging deeper, I don't think PHPGD supports 32bit bmp output which
complicates matters.
---
 app/Uploads/FaviconHandler.php |  19 +++++++++++++++----
 public/favicon.ico             | Bin 3134 -> 3134 bytes
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/app/Uploads/FaviconHandler.php b/app/Uploads/FaviconHandler.php
index f61e7ae64..39f8b12ca 100644
--- a/app/Uploads/FaviconHandler.php
+++ b/app/Uploads/FaviconHandler.php
@@ -28,6 +28,8 @@ class FaviconHandler
         $bmpData = $image->encode('bmp');
         $icoData = $this->bmpToIco($bmpData, 32, 32);
 
+//        file_put_contents(public_path('icon.bmp'), $bmpData);
+//        file_put_contents(public_path('icon-test.png'), $image->encode('png'));
         file_put_contents($targetPath, $icoData);
     }
 
@@ -54,6 +56,9 @@ class FaviconHandler
     {
         // Trim off the header of the bitmap file
         $rawBmpData = substr($bmpData, 14);
+        // Double the height in the "BITMAPINFOHEADER" since, when in an ICO file, half
+        // of the image data is expected to be a mask.
+        $rawBmpData[8] = hex2bin(dechex($height * 2));
 
         // ICO header
         $header = pack('v', 0x00); // Reserved. Must always be 0
@@ -66,17 +71,23 @@ class FaviconHandler
         $entry .= "\0"; // Color palette, typically 0
         $entry .= "\0"; // Reserved
 
+        // AND mask
+//        $pxCount = $width * $height;
+//        $pxMask = hex2bin('00000000');
+//        $mask = str_repeat($pxMask, $pxCount);
+        $mask = '';
+
         // Color planes, Appears to remain 1 for bmp image data
         $entry .= pack('v', 0x01);
         // Bits per pixel, can range from 1 to 32. From testing conversion
-        // via intervention from png typically provides this as 32.
-        $entry .= pack('v', 0x20);
+        // via intervention from png typically provides this as 24.
+        $entry .= pack('v', 0x18);
         // Size of the image data in bytes
-        $entry .= pack('V', strlen($rawBmpData));
+        $entry .= pack('V', strlen($rawBmpData) + strlen($mask));
         // Offset of the bmp data from file start
         $entry .= pack('V', strlen($header) + strlen($entry) + 4);
 
         // Join & return the combined parts of the ICO image data
-        return $header . $entry . $rawBmpData;
+        return $header . $entry . $rawBmpData . $mask;
     }
 }
diff --git a/public/favicon.ico b/public/favicon.ico
index e047657ccad8c38f318f2bda36f0809a9b0c878f..e114831177f415bd8dfb65b3f6f9d5988796a7b5 100644
GIT binary patch
literal 3134
zcmd5;X-pht7+(JiODm<KMr*B#Mon$JVm)d-qQ+QbVzp6Q6QlKPjQ&uGX(egGa<m+_
z2nw`P<S4XMkXo=DrRA`tWoCC_mt}93W$%0T1nM*U?F>VqhEjgGJG=Sjo%eg*?|t5D
zM4}t;U9(1n|C>b_H;P1QB9SNqKZrz|@MGoi51#$+KC#PFxWYkKY$k@q@}3WXk+5%~
zTO!TBMP0i!U{w%v*KdWznTa~24Z{Z>q_UI9MdzlDw`GO{_UmzkoX}^wsH%E}M;<BJ
zK<C^<Zsmn{SqCelQ=x0MLXd-AlfLB(O0pt>R-9p@YJ)C=-z**b{SDrtvivEJ=1lDJ
zVuJ$kNHk#XEtKuMjeyX(t0y|M7^mKN>N`3ob@cE{UgLSEqII}r17}67X?UM;YRJK^
z78LgBOf0_f;n|Ii+XFVG^+LI<U@a$1f>ZiGK4Bc1$=;$l$LPq4ggn5RZvsNUMLy5*
zZnwHi@ynAuva<XcxI=EG`L~+S?qi%<ee)a|?Nm){I&y`T=yXJ0d_UPJFI<PfAqh1{
z-=(sXi4c)>Dp~?oCEU?8?x3>8oP51wq}e+@C`^OV%ICd?0hSQXm!QuAC^~nQu{|^B
z)R{W=(79;@0SuVW6)+B*^HVUR{B@&S-RaSEE6SfH3iwwYdEGxTWS2G0rm-YN*Yr`)
zZ6sDgL6@d(8z{039g!7hBsPNQ=Fh<Zc#v}8jz1D>j=l#6t%DVCmMGIXD-Eq*F-~2)
z4AY4a98R3cjmCno;x+UuD>o;Qairf~_Kja~jx>*ytmlN{vFa_d{kJCobJI*6KL(Lk
zZQrBfh)}lw4om+*#y+M!{vjnvaLBj}(dn?f@E)QweBc3i3V&7ATR7w-MAoA{i_ByL
z+Omt1tR#=*Mfci<s{NK>b?sYxuoR__xm0aleV?-OIj8|Y=$ph-X<qt7cQ)hF8Ct)F
zzX^oGb+(I#*>KlygU;~5hn&Mr@w$F>)_Ub;kG>a}iqc0pVKUpPEOPr$HG&%sxpgOY
z2JC9fKnZ*#I&7b5{{fXXetI`T&uwJ8kgDo6-^3-S{5Z^UaxpmJ5I7EVQjsvxC<Ff8
z>W(?q>)#1jM{Jj>WJPy#2#NkiZfVI1!=JklP;*b7G@lD7%YXzK$TGlj2!2qxd}=Am
zo^Xx*?a`f6Ry?~PvQUU{Pxk%9IMlimAM*j_B1n-40zVREsGL=@f;%n$lrnae_Sgq}
z1qsovwpNrr;!^(QG4zifdV$wL2BPkefg!&wIu#yo-_2%k*Iqg=;ViGYxJ9zM=1u>k
z+)mZXi|<QpiC0i0>IeU*g0Y&di-VdI2;mkqSmUX0krJlPEWT5LA9TF9i4gb!OTsNn
zSj!66TF#dTY@^zS?ckZ<lcowQA-~ml@*93mEr?G`QXKLob=}*1P0d$RaGfd?unRjj
zOyIhrT?@C<60xFeBeK`6?QyHx6=jbLp9<H=TerF!XhMA65i)MjnfWb94~&(d*NjXs
zwq?S1ZQ~B`U>W$CuS!mtEw`XsPfj}@pSOZ>ImwSpNs6KQGng><<l|k1K+$=tO<jA@
zmy9P9T}4^3$)oT4Z)DygQHziJFUhz^uZ~Xy)YMK&l0vK?C+&2--%Q!*y4X~BK~8wg
z`3qu2__~7m?i^{soEkm!B1~W&nNIJCguT~_EVRX1nT|RHa|#myXLiVrF^(~E2BH4a
g*1+Lj7t=BQ-I}iDLgvpy07JgXCA`1!Aj`P;7iM)(t^fc4

literal 3134
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
JG-yoG{{`3W2Q>fy