imgconv.go

 1package clib
 2
 3import (
 4	"bytes"
 5	"image"
 6	"image/png"
 7
 8	_ "image/gif"  // register GIF decoder for image.Decode
 9	_ "image/jpeg" // register JPEG decoder for image.Decode
10)
11
12// DecodeToPNG takes raw image bytes (JPEG, PNG, BMP, GIF, etc.) and returns
13// PNG-encoded bytes along with image dimensions.
14// This is the pure Go fallback used when cgo is not available.
15func DecodeToPNG(data []byte) (ImageConvertResult, bool) {
16	if len(data) == 0 {
17		return ImageConvertResult{}, false
18	}
19
20	img, _, err := image.Decode(bytes.NewReader(data))
21	if err != nil {
22		return ImageConvertResult{}, false
23	}
24
25	var buf bytes.Buffer
26	if err := png.Encode(&buf, img); err != nil {
27		return ImageConvertResult{}, false
28	}
29
30	bounds := img.Bounds()
31	return ImageConvertResult{
32		PNGData: buf.Bytes(),
33		Width:   bounds.Dx(),
34		Height:  bounds.Dy(),
35	}, true
36}
37
38// ImageDimensions returns the width and height of an image without fully
39// decoding pixel data.
40// This is the pure Go fallback — it must fully decode the image since Go's
41// stdlib does not support header-only reads.
42func ImageDimensions(data []byte) (width, height int, ok bool) {
43	if len(data) == 0 {
44		return 0, 0, false
45	}
46
47	img, _, err := image.Decode(bytes.NewReader(data))
48	if err != nil {
49		return 0, 0, false
50	}
51
52	bounds := img.Bounds()
53	return bounds.Dx(), bounds.Dy(), true
54}