diff --git a/Makefile.inc b/Makefile.inc index 414ef76c10..b5665a79e0 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -356,6 +356,41 @@ cbfs-files-processor-struct= \ rm -f $(2).tmp) \ $(eval DEPENDENCIES += $(2).d) +####################################################################### +# Convert image to YCC 4:2:0 JPEG +# +# In two steps: +# 1. Convert to RGB colors, optionally resize and store as BMP. +# 2. Round final size to multiples of 16, optionally swap colors, +# convert (back) to sRGB and store as JPEG. +# The split is necessary because we don't know the exact, scaled +# size due to aspect-ratio. Note: IM v7 would allow us to do the +# calculations in one command using %[fx:...] syntax. +# +# arg1: image input file +# arg2: output jpg +cbfs-files-processor-jpg420= \ + $(eval $(2): $(1) $(KCONFIG_AUTOCONFIG); \ + printf " CONVERT $$<\n"; \ + res=$(CONFIG_BOOTSPLASH_CONVERT_RESOLUTION); \ + res=$$$$(convert $$< \ + -colorspace RGB \ + $$(BOOTSPLASH_RESIZE-y) \ + -format '%wx%h' -write info: \ + bmp:$$@); \ + convert $$@ \ + $$(BOOTSPLASH_ROUND16) \ + $$(BOOTSPLASH_COLORSWAP-y) \ + -colorspace sRGB \ + -quality $$(CONFIG_BOOTSPLASH_CONVERT_QUALITY)% \ + -interlace none -colorspace YCC -sampling-factor 4:2:0 \ + jpg:$$@) +BOOTSPLASH_FLOOR = $$(($${res%%x*} & ~15))x$$(($${res\#\#*x} & ~15)) +BOOTSPLASH_RESIZE-$(CONFIG_BOOTSPLASH_CONVERT_RESIZE) = -resize $(BOOTSPLASH_FLOOR) +BOOTSPLASH_CEIL = $$((($${res%%x*} + 15) & ~15))x$$((($${res\#\#*x} + 15) & ~15)) +BOOTSPLASH_ROUND16 = -background black -gravity center -extent $(BOOTSPLASH_CEIL) +BOOTSPLASH_COLORSWAP-$(CONFIG_BOOTSPLASH_CONVERT_COLORSWAP) := -channel-fx 'red<=>blue' + ####################################################################### # Add handler for arbitrary files in CBFS $(call add-special-class,cbfs-files) @@ -1281,10 +1316,19 @@ cbfs-files-y += build_info build_info-file := $(obj)/build_info build_info-type := raw +ifeq ($(CONFIG_BOOTSPLASH_CONVERT),y) +ifeq ($(shell command -v convert),) +$(error CONFIG_BOOTSPLASH_CONVERT requires the convert program (part of ImageMagick)) +endif +cbfs-files-$(CONFIG_BOOTSPLASH_IMAGE) += bootsplash.jpg +bootsplash.jpg-file := $(call strip_quotes,$(CONFIG_BOOTSPLASH_FILE)):jpg420 +bootsplash.jpg-type := bootsplash +else BOOTSPLASH_SUFFIX=$(suffix $(call strip_quotes,$(CONFIG_BOOTSPLASH_FILE))) cbfs-files-$(CONFIG_BOOTSPLASH_IMAGE) += bootsplash$(BOOTSPLASH_SUFFIX) bootsplash$(BOOTSPLASH_SUFFIX)-file := $(call strip_quotes,$(CONFIG_BOOTSPLASH_FILE)) bootsplash$(BOOTSPLASH_SUFFIX)-type := bootsplash +endif # Ensure that no payload segment overlaps with memory regions used by ramstage # (not for x86 since it can relocate itself in that case) diff --git a/src/Kconfig b/src/Kconfig index f5ba4fc784..ea6f341f78 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -447,7 +447,54 @@ config BOOTSPLASH_FILE # Default value set at the end of the file help The path and filename of the file to use as graphical bootsplash - screen. The file format has to be jpg. + screen. The file format has to be JPEG with YCC 4:2:0 color sampling + unless converted with "Pre-process bootsplash file with ImageMagick". + + The image can only be displayed by coreboot if it's smaller or has + the same size as the framebuffer resolution. Width and height have + to be a multiple of 16 pixels. + + Setting these constraints allows a leaner implementation in coreboot. + The minimum necessary ImageMagick command line seems to be: + $ convert input.img -colorspace YCC -sampling-factor 4:2:0 bootsplash.jpg + +config BOOTSPLASH_CONVERT + bool "Pre-process bootsplash file with ImageMagick" + depends on BOOTSPLASH_IMAGE + help + Use ImageMagick (`convert` program) to convert a bootsplash image + to the supported JPEG format. + +config BOOTSPLASH_CONVERT_QUALITY + int "Bootsplash JPEG target quality (%)" + depends on BOOTSPLASH_CONVERT + range 1 100 + # Default value set at the end of the file + +config BOOTSPLASH_CONVERT_RESIZE + bool "Resize bootsplash image" + depends on BOOTSPLASH_CONVERT + help + Resize the image to the given resolution. Aspect ratio will be kept, + adding black bars as necessary. + +config BOOTSPLASH_CONVERT_RESOLUTION + string "Bootsplash image target size" + depends on BOOTSPLASH_CONVERT_RESIZE + # Default value set at the end of the file + help + Target image resolution given as x, e.g. 1024x768. + Values not divisible by 16 will be rounded down. + + When using coreboot to display the bootsplash image (CONFIG_BOOTSPLASH), + set this lower or equal to the minimum resolution you expect. + +config BOOTSPLASH_CONVERT_COLORSWAP + bool "Swap red and blue color channels" + depends on BOOTSPLASH_CONVERT + help + The JPEG decoder currently ignores the framebuffer color order. + If your colors seem all wrong, try this option. config FW_CONFIG bool "Firmware Configuration Probing" @@ -1444,6 +1491,14 @@ config BOOTSPLASH_FILE depends on BOOTSPLASH_IMAGE default "bootsplash.jpg" +config BOOTSPLASH_CONVERT_QUALITY + depends on BOOTSPLASH_CONVERT + default 80 + +config BOOTSPLASH_CONVERT_RESOLUTION + depends on BOOTSPLASH_CONVERT_RESIZE + default "1024x768" + config CBFS_SIZE default ROM_SIZE