diff --git a/src/go.mod b/src/go.mod index b657b16..ac19598 100644 --- a/src/go.mod +++ b/src/go.mod @@ -20,7 +20,7 @@ require ( github.com/stretchr/testify v1.10.0 github.com/valyala/fasthttp v1.59.0 go.mau.fi/libsignal v0.1.2 - go.mau.fi/whatsmeow v0.0.0-20250225112721-b7530f3a5056 + go.mau.fi/whatsmeow v0.0.0-20250305175604-af3dc0346412 google.golang.org/protobuf v1.36.5 ) @@ -58,12 +58,12 @@ require ( github.com/valyala/bytebufferpool v1.0.0 // indirect go.mau.fi/util v0.8.5 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.35.0 // indirect - golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa // indirect - golang.org/x/image v0.24.0 // indirect - golang.org/x/net v0.35.0 // indirect - golang.org/x/sys v0.30.0 // indirect - golang.org/x/text v0.22.0 // indirect + golang.org/x/crypto v0.36.0 // indirect + golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect + golang.org/x/image v0.25.0 // indirect + golang.org/x/net v0.37.0 // indirect + golang.org/x/sys v0.31.0 // indirect + golang.org/x/text v0.23.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/src/go.sum b/src/go.sum index 9c88314..f98a419 100644 --- a/src/go.sum +++ b/src/go.sum @@ -128,6 +128,8 @@ go.mau.fi/util v0.8.5 h1:PwCAAtcfK0XxZ4sdErJyfBMkTEWoQU33aB7QqDDzQRI= go.mau.fi/util v0.8.5/go.mod h1:Ycug9mrbztlahHPEJ6H5r8Nu/xqZaWbE5vPHVWmfz6M= go.mau.fi/whatsmeow v0.0.0-20250225112721-b7530f3a5056 h1:1JQUOpYXhFSEQgXMEWD/ZH38FrIe5i1yjxSBwa0aN/Q= go.mau.fi/whatsmeow v0.0.0-20250225112721-b7530f3a5056/go.mod h1:6hRrUtDWI2wTRClOd6m17GwrFE2a8/p5R4pjJsIVn+U= +go.mau.fi/whatsmeow v0.0.0-20250305175604-af3dc0346412 h1:AM+t3vKEho3zTDOW2g6KvxB7iGNPwp0SFZpmx4slVVU= +go.mau.fi/whatsmeow v0.0.0-20250305175604-af3dc0346412/go.mod h1:6hRrUtDWI2wTRClOd6m17GwrFE2a8/p5R4pjJsIVn+U= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -138,11 +140,19 @@ golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa h1:t2QcU6V556bFjYgu4L6C+6VrCPyJZ+eyRsABUPs1mz4= golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk= +golang.org/x/exp v0.0.0-20250228200357-dead58393ab7 h1:aWwlzYV971S4BXRS9AmqwDLAD85ouC6X+pocatKY58c= +golang.org/x/exp v0.0.0-20250228200357-dead58393ab7/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk= +golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw= +golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM= golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.24.0 h1:AN7zRgVsbvmTfNyqIbbOraYL8mSwcKncEj8ofjgzcMQ= golang.org/x/image v0.24.0/go.mod h1:4b/ITuLfqYq1hqZcjofwctIhi7sZh2WaCjvsBNjjya8= +golang.org/x/image v0.25.0 h1:Y6uW6rH1y5y/LK1J8BPWZtr6yZ7hrsy6hFrXjgsc2fQ= +golang.org/x/image v0.25.0/go.mod h1:tCAmOEGthTtkalusGp1g3xa2gke8J6c2N565dTyl9Rs= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -159,6 +169,10 @@ golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA= +golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I= +golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= +golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -182,6 +196,8 @@ golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -202,6 +218,8 @@ golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= diff --git a/src/pkg/utils/general.go b/src/pkg/utils/general.go index 23b22cc..6f8bfba 100644 --- a/src/pkg/utils/general.go +++ b/src/pkg/utils/general.go @@ -4,9 +4,11 @@ import ( "bytes" "fmt" "image" - _ "image/gif" // Register GIF format - _ "image/jpeg" // Register JPEG format - _ "image/png" // Register PNG format + "image/color" + "image/draw" + _ "image/gif" // Register GIF format + "image/jpeg" // For JPEG encoding + "image/png" // For PNG encoding "io" "log" "net/http" @@ -122,14 +124,100 @@ func GetMetaDataFromURL(url string) (meta Metadata, err error) { // Get image dimensions from the actual image rather than OG tags imageReader := bytes.NewReader(imageData) - img, _, err := image.Decode(imageReader) + img, imgFormat, err := image.Decode(imageReader) if err == nil { bounds := img.Bounds() width := uint32(bounds.Max.X - bounds.Min.X) height := uint32(bounds.Max.Y - bounds.Min.Y) + // Check if image has transparency (alpha channel) + hasTransparency := false + + // Check for transparency by examining image type and pixels + switch v := img.(type) { + case *image.NRGBA: + // NRGBA format - check alpha values + for y := bounds.Min.Y; y < bounds.Max.Y && !hasTransparency; y++ { + for x := bounds.Min.X; x < bounds.Max.X; x++ { + _, _, _, a := v.At(x, y).RGBA() + if a < 0xffff { + hasTransparency = true + break + } + } + } + case *image.RGBA: + // RGBA format - check alpha values + for y := bounds.Min.Y; y < bounds.Max.Y && !hasTransparency; y++ { + for x := bounds.Min.X; x < bounds.Max.X; x++ { + _, _, _, a := v.At(x, y).RGBA() + if a < 0xffff { + hasTransparency = true + break + } + } + } + case *image.NRGBA64: + // NRGBA64 format - check alpha values + for y := bounds.Min.Y; y < bounds.Max.Y && !hasTransparency; y++ { + for x := bounds.Min.X; x < bounds.Max.X; x++ { + _, _, _, a := v.At(x, y).RGBA() + if a < 0xffff { + hasTransparency = true + break + } + } + } + default: + // For other formats, check if the format typically supports transparency + hasTransparency = imgFormat == "png" || imgFormat == "gif" + } + + // If image has transparency, create a new image with white background + if hasTransparency { + log.Printf("Image has transparency, setting white background") + + // Create a new RGBA image with white background + newImg := image.NewRGBA(bounds) + draw.Draw(newImg, bounds, image.NewUniform(color.White), image.Point{}, draw.Src) + + // Draw the original image on top of the white background + draw.Draw(newImg, bounds, img, bounds.Min, draw.Over) + + // Convert the new image back to bytes + var buf bytes.Buffer + switch imgFormat { + case "png": + if err := png.Encode(&buf, newImg); err == nil { + meta.ImageThumb = buf.Bytes() + } else { + log.Printf("Failed to encode PNG image: %v", err) + } + case "jpeg", "jpg": + if err := jpeg.Encode(&buf, newImg, nil); err == nil { + meta.ImageThumb = buf.Bytes() + } else { + log.Printf("Failed to encode JPEG image: %v", err) + } + case "gif": + // Note: Simple conversion to PNG for GIF with transparency + if err := png.Encode(&buf, newImg); err == nil { + meta.ImageThumb = buf.Bytes() + } else { + log.Printf("Failed to encode GIF as PNG: %v", err) + } + default: + // For other formats, try PNG + if err := png.Encode(&buf, newImg); err == nil { + meta.ImageThumb = buf.Bytes() + } else { + log.Printf("Failed to encode image as PNG: %v", err) + } + } + } + // Check if image is square (1:1 ratio) - if width == height { + if width == height && width <= 200 { // For 1:1 ratio, leave width and height as nil meta.Width = nil meta.Height = nil