siyuan-note/siyuan · error

decode HEIF image: %w

Error message

decode HEIF image: %w

What it means

This wraps a failure from goheic.DecodeBytes, the full pixel decode of the HEIF image (with auto-rotation, a frame size limit of maxPixels, and single-threaded decode). Unlike the config-stage error, the header parsed fine but the actual HEVC/AV1 image data could not be decoded — unsupported profile, corrupt slice data, missing tiles, or decoder resource limits.

Source

Thrown at kernel/heif/convert.go:198

			err = fmt.Errorf("decode HEIF image: %v", recovered)
		}
	}()

	config, err := goheic.DecodeConfigBytes(source)
	if err != nil {
		return nil, fmt.Errorf("read HEIF image dimensions: %w", err)
	}
	if !validDimensions(config.Width, config.Height) {
		return nil, ErrImageTooLarge
	}

	img, err = goheic.DecodeBytes(source, goheic.Options{
		AutoRotate:     true,
		FrameSizeLimit: maxPixels,
		Threads:        1,
	})
	if err != nil {
		return nil, fmt.Errorf("decode HEIF image: %w", err)
	}
	return img, nil
}

func validDimensions(width, height int) bool {
	return width > 0 && height > 0 && width <= maxDimension && height <= maxDimension &&
		uint64(width)*uint64(height) <= uint64(maxPixels)
}

func estimatedJPEGSize(img image.Image) int {
	pixels := int64(img.Bounds().Dx()) * int64(img.Bounds().Dy())
	estimate := pixels / 2
	if estimate < 64*1024 {
		estimate = 64 * 1024
	}
	if estimate > 32*1024*1024 {
		estimate = 32 * 1024 * 1024
	}

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Check the wrapped cause to distinguish unsupported-profile from corrupt-data
  2. Re-acquire the file; if it decodes in Preview.app/another viewer, report it as a decoder capability gap
  3. Convert the photo to JPEG/HEIF-8-bit externally before importing
  4. Lower expectations for very large images — reduce dimensions at capture, since maxPixels caps decode size
Defensive patterns

Strategy: fallback

Validate before calling

cfg, err := h265heic.DecodeConfigBytes(data)
if err == nil && cfg.Width*cfg.Height > platformPixelBudget() {
	return errors.New("image exceeds platform pixel budget")
}

Try / catch

img, err := convert(ctx, data, mode)
if err != nil && strings.Contains(err.Error(), "decode HEIF image:") {
	return externalConvert(data, mode) // system HEIF toolchain
}

Prevention

When it happens

Trigger: convert or ImageSize on a file whose headers parse (DecodeConfigBytes succeeds) but whose image payload fails: unsupported 12-bit/HDR profile, alpha/layer features not implemented, corrupt slice NAL data, or grid images with missing tiles.

Common situations: ProHDR / 10-bit+ iPhone photos using profiles the decoder lacks; HEIFs with depth/auxiliary layers; files damaged after the header region; images exceeding the platform FrameSizeLimit.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/49b1698257d367d4. Report an issue: GitHub.