png.c 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #include <uefi.h>
  2. /* public domain image loader - http://nothings.org/stb_image.h */
  3. #define STB_IMAGE_IMPLEMENTATION
  4. #include "stb_image.h"
  5. /**
  6. * Display PNG image
  7. */
  8. int main(int argc, char **argv)
  9. {
  10. efi_status_t status;
  11. efi_guid_t gopGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
  12. efi_gop_t *gop = NULL;
  13. FILE *f;
  14. unsigned char *buff;
  15. uint32_t *data;
  16. int w, h, l;
  17. long int size;
  18. stbi__context s;
  19. stbi__result_info ri;
  20. /* load image */
  21. if((f = fopen("\\0C_png\\image.png", "r"))) {
  22. fseek(f, 0, SEEK_END);
  23. size = ftell(f);
  24. fseek(f, 0, SEEK_SET);
  25. buff = (unsigned char*)malloc(size);
  26. if(!buff) {
  27. fprintf(stderr, "unable to allocate memory\n");
  28. return 1;
  29. }
  30. fread(buff, size, 1, f);
  31. fclose(f);
  32. ri.bits_per_channel = 8;
  33. s.read_from_callbacks = 0;
  34. s.img_buffer = s.img_buffer_original = buff;
  35. s.img_buffer_end = s.img_buffer_original_end = buff + size;
  36. data = (uint32_t*)stbi__png_load(&s, &w, &h, &l, 4, &ri);
  37. if(!data) {
  38. fprintf(stdout, "Unable to decode png: %s\n", stbi__g_failure_reason);
  39. return 0;
  40. }
  41. } else {
  42. fprintf(stderr, "Unable to load image\n");
  43. return 0;
  44. }
  45. /* set video mode */
  46. status = BS->LocateProtocol(&gopGuid, NULL, (void**)&gop);
  47. if(!EFI_ERROR(status) && gop) {
  48. status = gop->SetMode(gop, 0);
  49. ST->ConOut->Reset(ST->ConOut, 0);
  50. ST->StdErr->Reset(ST->StdErr, 0);
  51. if(EFI_ERROR(status)) {
  52. fprintf(stderr, "unable to set video mode\n");
  53. return 0;
  54. }
  55. } else {
  56. fprintf(stderr, "unable to get graphics output protocol\n");
  57. return 0;
  58. }
  59. /* png is RGBA, but UEFI needs BGRA */
  60. if(gop->Mode->Information->PixelFormat == PixelBlueGreenRedReserved8BitPerColor ||
  61. (gop->Mode->Information->PixelFormat == PixelBitMask && gop->Mode->Information->PixelInformation.BlueMask != 0xff0000)) {
  62. for(l = 0; l < w * h; l++)
  63. data[l] = ((data[l] & 0xff) << 16) | (data[l] & 0xff00) | ((data[l] >> 16) & 0xff);
  64. }
  65. /* display image */
  66. gop->Blt(gop, data, EfiBltBufferToVideo, 0, 0, (gop->Mode->Information->HorizontalResolution - w) / 2,
  67. (gop->Mode->Information->VerticalResolution - h) / 2, w, h, 0);
  68. /* free resources exit */
  69. free(data);
  70. free(buff);
  71. return 0;
  72. }