]> code.delx.au - refind/commitdiff
New image-scaling code; used for icons and (optionally) for scaling
authorsrs5694 <srs5694@users.sourceforge.net>
Sat, 8 Mar 2014 19:55:11 +0000 (14:55 -0500)
committersrs5694 <srs5694@users.sourceforge.net>
Sat, 8 Mar 2014 19:55:11 +0000 (14:55 -0500)
banners (latter set by new banner_scale option in refind.conf).

NEWS.txt
docs/refind/index.html
libeg/image.c
libeg/libeg.h
libeg/load_icns.c
refind.conf-sample
refind/config.c
refind/global.h
refind/main.c
refind/screen.c

index a1f86870b06236aafbcf230406ef0523c81281ae..ba21e8f1e520aadf0120ad0d50c2079da4a8a2fa 100644 (file)
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -1,6 +1,19 @@
 0.7.8 (?/??/2014):
 ------------------
 
+- rEFInd now automatically scales icons to fit the standard icon sizes.
+  This won't have any effect with the icons that come with rEFInd, but it
+  can help if you want to use another icon, since you needn't scale it in a
+  graphics program before using it. Note that rEFInd uses bitmap icons, so
+  scaling by a huge amount (say, a 16x16 icon to fit the standard 128x128
+  OS icon) is not likely to look good.
+
+- Added new option, banner_scale, that tells rEFInd how to handle banners:
+  Set to "noscale" (the default), banners are not scaled, although they'll
+  be cropped if they're too big for the display. This is the same as the
+  behavior in previous versions. Set to "fillscreen", rEFInd now scales the
+  banner image (larger or smaller) to fill the display.
+
 - Adjusted the post-installation script in refind.spec (used to generate
   RPMs, and therefore also indirectly Debian packages) to search for
   existing shim program files under the filesnames shim.efi and shimx64.efi
index 74e018d491110ee5db406f662e65f68bda3891ea..22723c535f48392d0aab2e80ee9b38f1bea4e6bb 100644 (file)
@@ -206,6 +206,8 @@ href="mailto:rodsmith@rodsbooks.com">rodsmith@rodsbooks.com</a></p>
 
 <li>Matthew J. Garrett, the developer of the shim boot loader to manage Secure Boot, maintains <a href="http://mjg59.dreamwidth.org/">a blog</a> in which he often writes about EFI issues.</li>
 
+<li>Adam Williamson has written a good <a href="https://www.happyassassin.net/2014/01/25/uefi-boot-how-does-that-actually-work-then/">summary of what EFI is and how it works.</a></li>
+
 <li>J. A. Watson has a <a href="http://www.zdnet.com/the-refind-boot-loader-for-uefi-systems-7000010275/">review of rEFInd on an HP laptop</a> on ZDNet. He had serious problems because of the HP's UEFI bugs, but finally got it to work.</li>
 
 <li>James Jesudason has a tutorial on installing Ubuntu 13.04 beta on a Macbook Retina Pro on <a href="http://randomtutor.blogspot.com/2013_02_01_archive.html">this blog page.</a> I'd recommend using a Linux filesystem driver to read the kernel directly from a Linux filesystem rather than copy the kernel to the OS X partition as in the tutorial, but either method will work.</li>
index 9f2262838cead9c9e3482e48395e04a29c2a8390..530589a692d774294422f3eef2841e60fce75a15 100644 (file)
@@ -125,6 +125,67 @@ EG_IMAGE * egCropImage(IN EG_IMAGE *Image, IN UINTN StartX, IN UINTN StartY, IN
    return NewImage;
 } // EG_IMAGE * egCropImage()
 
+// The following function implements a bilinear image scaling algorithm, based on
+// code presented at http://tech-algorithm.com/articles/bilinear-image-scaling/.
+// Resize an image; returns pointer to resized image if successful, NULL otherwise.
+// Calling function is responsible for freeing allocated memory.
+EG_IMAGE * egScaleImage(EG_IMAGE *Image, UINTN NewWidth, UINTN NewHeight) {
+   EG_IMAGE *NewImage = NULL;
+   EG_PIXEL a, b, c, d;
+   UINTN x, y, Index ;
+   UINTN i, j;
+   UINTN Offset = 0;
+   float x_ratio, y_ratio, x_diff, y_diff;
+
+   if ((Image == NULL) || (Image->Height == 0) || (Image->Width == 0) || (NewWidth == 0) || (NewHeight == 0))
+      return NULL;
+
+   if ((Image->Width == NewWidth) && (Image->Height == NewHeight))
+      return (egCopyImage(Image));
+
+   NewImage = egCreateImage(NewWidth, NewHeight, Image->HasAlpha);
+   if (NewImage == NULL)
+      return NULL;
+
+   x_ratio = ((float)(Image->Width-1))/NewWidth ;
+   y_ratio = ((float)(Image->Height-1))/NewHeight ;
+
+   for (i = 0; i < NewHeight; i++) {
+      for (j = 0; j < NewWidth; j++) {
+         x = (UINTN)(x_ratio * j) ;
+         y = (UINTN)(y_ratio * i) ;
+         x_diff = (x_ratio * j) - x ;
+         y_diff = (y_ratio * i) - y ;
+         Index = ((y * Image->Width) + x) ;
+         a = Image->PixelData[Index] ;
+         b = Image->PixelData[Index + 1] ;
+         c = Image->PixelData[Index + Image->Width] ;
+         d = Image->PixelData[Index + Image->Width + 1] ;
+
+         // blue element
+         // Yb = Ab(1-Image->Width)(1-Image->Height) + Bb(Image->Width)(1-Image->Height) + Cb(Image->Height)(1-Image->Width) + Db(wh)
+         NewImage->PixelData[Offset].b = (a.b)*(1-x_diff)*(1-y_diff) + (b.b)*(x_diff)*(1-y_diff) +
+                                         (c.b)*(y_diff)*(1-x_diff)   + (d.b)*(x_diff*y_diff);
+
+         // green element
+         // Yg = Ag(1-Image->Width)(1-Image->Height) + Bg(Image->Width)(1-Image->Height) + Cg(Image->Height)(1-Image->Width) + Dg(wh)
+         NewImage->PixelData[Offset].g = (a.g)*(1-x_diff)*(1-y_diff) + (b.g)*(x_diff)*(1-y_diff) +
+                                         (c.g)*(y_diff)*(1-x_diff)   + (d.g)*(x_diff*y_diff);
+
+         // red element
+         // Yr = Ar(1-Image->Width)(1-Image->Height) + Br(Image->Width)(1-Image->Height) + Cr(Image->Height)(1-Image->Width) + Dr(wh)
+         NewImage->PixelData[Offset].r = (a.r)*(1-x_diff)*(1-y_diff) + (b.r)*(x_diff)*(1-y_diff) +
+                                         (c.r)*(y_diff)*(1-x_diff)   + (d.r)*(x_diff*y_diff);
+
+         // alpha element
+         NewImage->PixelData[Offset++].a = (a.a)*(1-x_diff)*(1-y_diff) + (b.a)*(x_diff)*(1-y_diff) +
+                                           (c.a)*(y_diff)*(1-x_diff)   + (d.a)*(x_diff*y_diff);
+
+      } // for (j...)
+   } // for (i...)
+   return NewImage;
+} // EG_IMAGE * egScaleImage()
+
 VOID egFreeImage(IN EG_IMAGE *Image)
 {
     if (Image != NULL) {
@@ -273,7 +334,7 @@ EG_IMAGE * egLoadIcon(IN EFI_FILE* BaseDir, IN CHAR16 *Path, IN UINTN IconSize)
     EFI_STATUS      Status;
     UINT8           *FileData;
     UINTN           FileDataLength;
-    EG_IMAGE        *NewImage;
+    EG_IMAGE        *Image, *NewImage;
 
     if (BaseDir == NULL || Path == NULL)
         return NULL;
@@ -284,15 +345,17 @@ EG_IMAGE * egLoadIcon(IN EFI_FILE* BaseDir, IN CHAR16 *Path, IN UINTN IconSize)
        return NULL;
 
     // decode it
-    NewImage = egDecodeAny(FileData, FileDataLength, IconSize, TRUE);
+    Image = egDecodeAny(FileData, FileDataLength, IconSize, TRUE);
     FreePool(FileData);
-    if ((NewImage->Width != IconSize) || (NewImage->Height != IconSize)) {
-       Print(L"Warning: Attempt to load icon of the wrong size from '%s'\n", Path);
-       MyFreePool(NewImage);
-       NewImage = NULL;
+    if ((Image->Width != IconSize) || (Image->Height != IconSize)) {
+       NewImage = egScaleImage(Image, IconSize, IconSize);
+       if (!NewImage)
+          Print(L"Warning: Unable to scale icon of the wrong size from '%s'\n", Path);
+       MyFreePool(Image);
+       Image = NewImage;
     }
 
-    return NewImage;
+    return Image;
 } // EG_IMAGE *egLoadIcon()
 
 // Returns an icon of any type from the specified subdirectory using the specified
index c8426d192d9b00769c7f49889f972e452196be25..e94f1eb9b62ac0e07ca32657f68ea6f0a76a0eaf 100644 (file)
@@ -100,6 +100,7 @@ EG_IMAGE * egCreateImage(IN UINTN Width, IN UINTN Height, IN BOOLEAN HasAlpha);
 EG_IMAGE * egCreateFilledImage(IN UINTN Width, IN UINTN Height, IN BOOLEAN HasAlpha, IN EG_PIXEL *Color);
 EG_IMAGE * egCopyImage(IN EG_IMAGE *Image);
 EG_IMAGE * egCropImage(IN EG_IMAGE *Image, IN UINTN StartX, IN UINTN StartY, IN UINTN Width, IN UINTN Height);
+EG_IMAGE * egScaleImage(EG_IMAGE *Image, UINTN NewWidth, UINTN NewHeight);
 VOID egFreeImage(IN EG_IMAGE *Image);
 
 EG_IMAGE * egLoadImage(IN EFI_FILE* BaseDir, IN CHAR16 *FileName, IN BOOLEAN WantAlpha);
index f357ac36d7d9a1ac66507cd288551d6dbbb01e13..ce9e7abcc3000f9dc17e6b89b5c139abda134415 100644 (file)
@@ -36,6 +36,8 @@
 
 #include "libegint.h"
 
+#define MAX_ICNS_SIZES 4
+
 //
 // Decompress .icns RLE data
 //
@@ -97,11 +99,13 @@ EG_IMAGE * egDecodeICNS(IN UINT8 *FileData, IN UINTN FileDataLength, IN UINTN Ic
     EG_IMAGE            *NewImage;
     UINT8               *Ptr, *BufferEnd, *DataPtr, *MaskPtr;
     UINT32              BlockLen, DataLen, MaskLen;
-    UINTN               FetchPixelSize, PixelCount, i;
+    UINTN               PixelCount, i;
     UINT8               *CompData;
     UINTN               CompLen;
     UINT8               *SrcPtr;
     EG_PIXEL            *DestPtr;
+    UINTN               SizesToTry[MAX_ICNS_SIZES + 1] = {IconSize, 128, 48, 32, 16};
+    UINTN               SizeToTry = 0;
 
     if (FileDataLength < 8 || FileData == NULL ||
         FileData[0] != 'i' || FileData[1] != 'c' || FileData[2] != 'n' || FileData[3] != 's') {
@@ -109,68 +113,70 @@ EG_IMAGE * egDecodeICNS(IN UINT8 *FileData, IN UINTN FileDataLength, IN UINTN Ic
         return NULL;
     }
 
-    FetchPixelSize = IconSize;
     for (;;) {
         DataPtr = NULL;
         DataLen = 0;
         MaskPtr = NULL;
         MaskLen = 0;
 
-        Ptr = FileData + 8;
-        BufferEnd = FileData + FileDataLength;
-        // iterate over tagged blocks in the file
-        while (Ptr + 8 <= BufferEnd) {
-            BlockLen = ((UINT32)Ptr[4] << 24) + ((UINT32)Ptr[5] << 16) + ((UINT32)Ptr[6] << 8) + (UINT32)Ptr[7];
-            if (Ptr + BlockLen > BufferEnd)   // block continues beyond end of file
-                break;
-
-            // extract the appropriate blocks for each pixel size
-            if (FetchPixelSize == 128) {
-                if (Ptr[0] == 'i' && Ptr[1] == 't' && Ptr[2] == '3' && Ptr[3] == '2') {
-                    if (Ptr[8] == 0 && Ptr[9] == 0 && Ptr[10] == 0 && Ptr[11] == 0) {
-                        DataPtr = Ptr + 12;
-                        DataLen = BlockLen - 12;
-                    }
-                } else if (Ptr[0] == 't' && Ptr[1] == '8' && Ptr[2] == 'm' && Ptr[3] == 'k') {
-                    MaskPtr = Ptr + 8;
-                    MaskLen = BlockLen - 8;
-                }
-
-            } else if (FetchPixelSize == 48) {
-                if (Ptr[0] == 'i' && Ptr[1] == 'h' && Ptr[2] == '3' && Ptr[3] == '2') {
-                    DataPtr = Ptr + 8;
-                    DataLen = BlockLen - 8;
-                } else if (Ptr[0] == 'h' && Ptr[1] == '8' && Ptr[2] == 'm' && Ptr[3] == 'k') {
-                    MaskPtr = Ptr + 8;
-                    MaskLen = BlockLen - 8;
-                }
-
-            } else if (FetchPixelSize == 32) {
-                if (Ptr[0] == 'i' && Ptr[1] == 'l' && Ptr[2] == '3' && Ptr[3] == '2') {
-                    DataPtr = Ptr + 8;
-                    DataLen = BlockLen - 8;
-                } else if (Ptr[0] == 'l' && Ptr[1] == '8' && Ptr[2] == 'm' && Ptr[3] == 'k') {
-                    MaskPtr = Ptr + 8;
-                    MaskLen = BlockLen - 8;
-                }
-
-            } else if (FetchPixelSize == 16) {
-                if (Ptr[0] == 'i' && Ptr[1] == 's' && Ptr[2] == '3' && Ptr[3] == '2') {
-                    DataPtr = Ptr + 8;
-                    DataLen = BlockLen - 8;
-                } else if (Ptr[0] == 's' && Ptr[1] == '8' && Ptr[2] == 'm' && Ptr[3] == 'k') {
-                    MaskPtr = Ptr + 8;
-                    MaskLen = BlockLen - 8;
-                }
-
-            }
-
-            Ptr += BlockLen;
-        }
+        do {
+           IconSize = SizesToTry[SizeToTry];
+           Ptr = FileData + 8;
+           BufferEnd = FileData + FileDataLength;
+           // iterate over tagged blocks in the file
+           while (Ptr + 8 <= BufferEnd) {
+               BlockLen = ((UINT32)Ptr[4] << 24) + ((UINT32)Ptr[5] << 16) + ((UINT32)Ptr[6] << 8) + (UINT32)Ptr[7];
+               if (Ptr + BlockLen > BufferEnd)   // block continues beyond end of file
+                   break;
+
+               // extract the appropriate blocks for each pixel size
+               if (IconSize == 128) {
+                   if (Ptr[0] == 'i' && Ptr[1] == 't' && Ptr[2] == '3' && Ptr[3] == '2') {
+                       if (Ptr[8] == 0 && Ptr[9] == 0 && Ptr[10] == 0 && Ptr[11] == 0) {
+                           DataPtr = Ptr + 12;
+                           DataLen = BlockLen - 12;
+                       }
+                   } else if (Ptr[0] == 't' && Ptr[1] == '8' && Ptr[2] == 'm' && Ptr[3] == 'k') {
+                       MaskPtr = Ptr + 8;
+                       MaskLen = BlockLen - 8;
+                   }
+
+               } else if (IconSize == 48) {
+                   if (Ptr[0] == 'i' && Ptr[1] == 'h' && Ptr[2] == '3' && Ptr[3] == '2') {
+                       DataPtr = Ptr + 8;
+                       DataLen = BlockLen - 8;
+                   } else if (Ptr[0] == 'h' && Ptr[1] == '8' && Ptr[2] == 'm' && Ptr[3] == 'k') {
+                       MaskPtr = Ptr + 8;
+                       MaskLen = BlockLen - 8;
+                   }
+
+               } else if (IconSize == 32) {
+                   if (Ptr[0] == 'i' && Ptr[1] == 'l' && Ptr[2] == '3' && Ptr[3] == '2') {
+                       DataPtr = Ptr + 8;
+                       DataLen = BlockLen - 8;
+                   } else if (Ptr[0] == 'l' && Ptr[1] == '8' && Ptr[2] == 'm' && Ptr[3] == 'k') {
+                       MaskPtr = Ptr + 8;
+                       MaskLen = BlockLen - 8;
+                   }
+
+               } else if (IconSize == 16) {
+                   if (Ptr[0] == 'i' && Ptr[1] == 's' && Ptr[2] == '3' && Ptr[3] == '2') {
+                       DataPtr = Ptr + 8;
+                       DataLen = BlockLen - 8;
+                   } else if (Ptr[0] == 's' && Ptr[1] == '8' && Ptr[2] == 'm' && Ptr[3] == 'k') {
+                       MaskPtr = Ptr + 8;
+                       MaskLen = BlockLen - 8;
+                   }
+
+               }
+
+               Ptr += BlockLen;
+           }
+        } while ((DataPtr == NULL) && (SizeToTry++ < MAX_ICNS_SIZES));
 
         /* FUTURE: try to load a different size and scale it later
-            if (DataPtr == NULL && FetchPixelSize == 32) {
-                FetchPixelSize = 128;
+            if (DataPtr == NULL && IconSize == 32) {
+                IconSize = 128;
                 continue;
             }
         */
@@ -181,10 +187,10 @@ EG_IMAGE * egDecodeICNS(IN UINT8 *FileData, IN UINTN FileDataLength, IN UINTN Ic
         return NULL;   // no image found
 
     // allocate image structure and buffer
-    NewImage = egCreateImage(FetchPixelSize, FetchPixelSize, WantAlpha);
+    NewImage = egCreateImage(IconSize, IconSize, WantAlpha);
     if (NewImage == NULL)
         return NULL;
-    PixelCount = FetchPixelSize * FetchPixelSize;
+    PixelCount = IconSize * IconSize;
 
     if (DataLen < PixelCount * 3) {
 
index 053beb52b62d0dfa4eca69fedfe9f4de834c6b6a..9d8435732de5fb1c7a2bdb5bd88dbaccbc57331f 100644 (file)
@@ -51,6 +51,14 @@ timeout 20
 #banner hostname.bmp
 #banner mybanner.png
 
+# Specify how to handle banners that aren't exactly the same as the screen
+# size:
+#  noscale     - Crop if too big, show with border if too small
+#  fillscreen  - Fill the screen
+# Default is noscale
+#
+#banner_scale fillscreen
+
 # Custom images for the selection background. There is a big one (144 x 144)
 # for the OS icons, and a small one (64 x 64) for the function icons in the
 # second row. If only a small image is given, that one is also used for
@@ -150,7 +158,7 @@ timeout 20
 #  reboot           - a tag to reboot the computer
 #  firmware         - a tag to reboot the computer into the firmware's
 #                     user interface (ignored on older computers)
-# Default is shell,memtest,apple_recovery,mok_tool,about,shutdown,reboot,firmware
+# Default is shell,memtest,apple_recovery,windows_recovery,mok_tool,about,shutdown,reboot,firmware
 #
 #showtools shell, memtest, mok_tool, about, reboot, exit, firmware
 
index c56c54f1332d3e14fd028a24397cd02754ac4e9d..fd7f677622a37becd917106f77a67ac28dc0a8d5 100644 (file)
@@ -558,6 +558,15 @@ VOID ReadConfig(CHAR16 *FileName)
         } else if (StriCmp(TokenList[0], L"banner") == 0) {
            HandleString(TokenList, TokenCount, &(GlobalConfig.BannerFileName));
 
+        } else if ((StriCmp(TokenList[0], L"banner_scale") == 0) && (TokenCount == 2)) {
+           if (StriCmp(TokenList[1], L"noscale") == 0) {
+              GlobalConfig.BannerScale = BANNER_NOSCALE;
+           } else if (StriCmp(TokenList[1], L"fillscreen") == 0) {
+              GlobalConfig.BannerScale = BANNER_FILLSCREEN;
+           } else {
+              Print(L" unknown banner_type flag: '%s'\n", TokenList[1]);
+           } // if/else
+
         } else if (StriCmp(TokenList[0], L"selection_small") == 0) {
            HandleString(TokenList, TokenCount, &(GlobalConfig.SelectionSmallFileName));
 
index ee4876438a0d1ea566c3c062251f1981e3979100..6641d8b0c483c2009046c2c10eae6129ec1f0b0a 100644 (file)
 #define FS_TYPE_BTRFS          7
 #define FS_TYPE_ISO9660        8
 
+// How to scale banner images
+#define BANNER_NOSCALE         0
+#define BANNER_FILLSCREEN      1
+
 // Names of binaries that can manage MOKs....
 #define MOK_NAMES               L"MokManager.efi,HashTool.efi,HashTool-signed.efi"
 // Directories to search for these MOK-managing programs. Note that SelfDir is
@@ -239,6 +243,7 @@ typedef struct {
    UINTN       LegacyType;
    UINTN       ScanDelay;
    UINTN       ScreensaverTime;
+   UINTN       BannerScale;
    CHAR16      *BannerFileName;
    EG_IMAGE    *ScreenBackground;
    CHAR16      *ConfigFilename;
index f8428d52746d37e1c7fd5d0ca467f598b6827dac..358106701cbb42b4669935ec3a85eceda75b74fe 100644 (file)
@@ -132,6 +132,7 @@ static REFIT_MENU_SCREEN MainMenu       = { L"Main Menu", NULL, 0, NULL, 0, NULL
 static REFIT_MENU_SCREEN AboutMenu      = { L"About", NULL, 0, NULL, 0, NULL, 0, NULL, L"Press Enter to return to main menu", L"" };
 
 REFIT_CONFIG GlobalConfig = { FALSE, FALSE, 0, 0, 0, DONT_CHANGE_TEXT_MODE, 20, 0, 0, GRAPHICS_FOR_OSX, LEGACY_TYPE_MAC, 0, 0,
+                              BANNER_NOSCALE,
                               NULL, NULL, CONFIG_FILE_NAME, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                               { TAG_SHELL, TAG_MEMTEST, TAG_APPLE_RECOVERY, TAG_WINDOWS_RECOVERY, TAG_MOK_TOOL, TAG_ABOUT,
                                 TAG_SHUTDOWN, TAG_REBOOT, TAG_FIRMWARE, 0, 0, 0, 0, 0, 0 }
index 1676cb6118eab111e61c6dada73af9057da14a48..49c7a94b51574f2b5416158bce108fca6609fb97 100644 (file)
@@ -433,33 +433,38 @@ VOID SwitchToGraphicsAndClear(VOID)
         BltClearScreen(TRUE);
 }
 
-VOID BltClearScreen(IN BOOLEAN ShowBanner)
+VOID BltClearScreen(BOOLEAN ShowBanner)
 {
-    static EG_IMAGE *Banner = NULL, *CroppedBanner;
+    static EG_IMAGE *Banner = NULL;
+    EG_IMAGE *NewBanner = NULL;
     INTN BannerPosX, BannerPosY;
     EG_PIXEL Black = { 0x0, 0x0, 0x0, 0 };
 
     if (ShowBanner && !(GlobalConfig.HideUIFlags & HIDEUI_FLAG_BANNER)) {
         // load banner on first call
         if (Banner == NULL) {
-            if (GlobalConfig.BannerFileName == NULL) {
-                Banner = egPrepareEmbeddedImage(&egemb_refind_banner, FALSE);
-            } else {
+            if (GlobalConfig.BannerFileName)
                 Banner = egLoadImage(SelfDir, GlobalConfig.BannerFileName, FALSE);
-                if (Banner && ((Banner->Width > UGAWidth) || (Banner->Height > UGAHeight))) {
-                   CroppedBanner = egCropImage(Banner, 0, 0, (Banner->Width > UGAWidth) ? UGAWidth : Banner->Width,
-                                               (Banner->Height > UGAHeight) ? UGAHeight : Banner->Height);
-                   MyFreePool(Banner);
-                   Banner = CroppedBanner;
-                } // if image too big
-                if (Banner == NULL) {
-                   Banner = egPrepareEmbeddedImage(&egemb_refind_banner, FALSE);
-                } // if unusable image
-            }
-            if (Banner != NULL)
-               MenuBackgroundPixel = Banner->PixelData[0];
+            if (Banner == NULL)
+                Banner = egPrepareEmbeddedImage(&egemb_refind_banner, FALSE);
         }
 
+        if (Banner) {
+           if (GlobalConfig.BannerScale == BANNER_FILLSCREEN) {
+              if ((Banner->Height != UGAHeight) || (Banner->Width != UGAWidth)) {
+                 NewBanner = egScaleImage(Banner, UGAWidth, UGAHeight);
+              } // if
+           } else if ((Banner->Width > UGAWidth) || (Banner->Height > UGAHeight)) {
+              NewBanner = egCropImage(Banner, 0, 0, (Banner->Width > UGAWidth) ? UGAWidth : Banner->Width,
+                                      (Banner->Height > UGAHeight) ? UGAHeight : Banner->Height);
+           } // if/elseif
+           if (NewBanner) {
+              MyFreePool(Banner);
+              Banner = NewBanner;
+           }
+           MenuBackgroundPixel = Banner->PixelData[0];
+        } // if Banner exists
+
         // clear and draw banner
         if (GlobalConfig.ScreensaverTime != -1)
            egClearScreen(&MenuBackgroundPixel);
@@ -476,7 +481,7 @@ VOID BltClearScreen(IN BOOLEAN ShowBanner)
                BltImage(Banner, (UINTN) BannerPosX, (UINTN) BannerPosY);
         }
 
-    } else {
+    } else { // not showing banner
         // clear to menu background color
         egClearScreen(&MenuBackgroundPixel);
     }
@@ -484,7 +489,8 @@ VOID BltClearScreen(IN BOOLEAN ShowBanner)
     GraphicsScreenDirty = FALSE;
     egFreeImage(GlobalConfig.ScreenBackground);
     GlobalConfig.ScreenBackground = egCopyScreen();
-} /* VOID BltClearScreen() */
+} // VOID BltClearScreen()
+
 
 VOID BltImage(IN EG_IMAGE *Image, IN UINTN XPos, IN UINTN YPos)
 {