Step to UEFI (304)UEFI Shell 下显示JPEG 图片

前面介绍过 OK_JPG 解码库,这次尝试吧代码移植到 UEFI 下。

整体架构和之前介绍的 Windows 下的几乎相同,ok_jpg_read() 即可完成读取和解码。

需要特别注意的是UEFI Graphics Output Protocol 使用的颜色格式通常是 BGR 而不是常见的 RGB 格式,因此,解码之后需要一个函数来调整每个点的表示方法,完整代码如下:

#include <Protocol/GraphicsOutput.h>
#include <Library/UefiApplicationEntryPoint.h>
#include <stdio.h>
#include <stdlib.h>
#include "ok_jpg.h"

EFI_GUID GraphicsOutputProtocolGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
EFI_GRAPHICS_OUTPUT_PROTOCOL          *GraphicsOutput = NULL;

extern EFI_BOOT_SERVICES         *gBS;

// 批量转换图像数据
VOID ConvertRgbToBgr(
    IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *ImageData,
    IN UINTN PixelCount
) {
    UINTN i;
    UINT8 temp;
    
    for (i = 0; i < PixelCount; i++) {
        // 交换 Red 和 Blue 分量
        temp = ImageData[i].Red;
        ImageData[i].Red = ImageData[i].Blue;
        ImageData[i].Blue = temp;
        // Green 和 Reserved 保持不变
    }
}

int main() {
    EFI_STATUS                      Status;

    Status = gBS->LocateProtocol(
                     &GraphicsOutputProtocolGuid,
                     NULL,
                     (VOID **) &GraphicsOutput);
    if (EFI_ERROR(Status))
    {
            GraphicsOutput = NULL;
            printf("Loading Graphics_Output_Protocol error!\n");
            return EFI_SUCCESS;
    }
		
	printf("start\n");
    FILE *file = fopen("my_image.jpg", "rb");
	printf("%d\n",*file);
    ok_jpg image = ok_jpg_read(file, OK_JPG_COLOR_FORMAT_RGBA);
    fclose(file);
    if (image.data) {
        printf("Got image! Size: %li x %li\n", (long)image.width, (long)image.height);
		// 颜色顺序需要调整一下
		ConvertRgbToBgr((EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) image.data,image.width*image.height);
		//显示
		GraphicsOutput->Blt(
                GraphicsOutput,
                (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) image.data,
                EfiBltBufferToVideo,
                0, 0,
                0, 0,
                image.width, image.height, 0);
				
        free(image.data);
    }
    return 0;
}

INF如下:

[Defines]
  INF_VERSION                    = 0x00010006
  BASE_NAME                      = jpgDe
  FILE_GUID                      = 4ea97c46-2026-0417-b442-747010f3ce5f
  MODULE_TYPE                    = UEFI_APPLICATION
  VERSION_STRING                 = 0.1
  ENTRY_POINT                    = ShellCEntryLib

#
#  VALID_ARCHITECTURES           = IA32 X64
#

[Sources]
  JpegDecoder.c
  ok_jpg.c
  
[Packages]
  StdLib/StdLib.dec
  MdePkg/MdePkg.dec
  ShellPkg/ShellPkg.dec
  MdeModulePkg/MdeModulePkg.dec
  
[LibraryClasses]
  LibC
  LibStdio
  DevShell
  
[BuildOptions]
  MSFT:*_*_*_CC_FLAGS = /wd4244

在模拟器中运行结果如下:

完整的代码如下:

参考:

1. https://www.lab-z.com/stu246/ 显示 JPEG 图片的 DXE 驱动

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注