]> code.delx.au - refind/blobdiff - libeg/image.c
Improved submenu and information menu appearance over a full-screen
[refind] / libeg / image.c
index 39039dab73efc29592ab221ef36e342c68764729..e940942e670e9155ff8a92ac69a18abc6c61bc01 100644 (file)
@@ -39,6 +39,7 @@
 #include "../refind/lib.h"
 #include "../refind/screen.h"
 #include "../include/refit_call_wrapper.h"
+#include "lodepng.h"
 
 #define MAX_FILE_SIZE (1024*1024*1024)
 
@@ -94,6 +95,27 @@ EG_IMAGE * egCopyImage(IN EG_IMAGE *Image)
     return NewImage;
 }
 
+// Returns a smaller image composed of the specified crop area from the larger area.
+// If the specified area is larger than is in the original, returns NULL.
+EG_IMAGE * egCropImage(IN EG_IMAGE *Image, IN UINTN StartX, IN UINTN StartY, IN UINTN Width, IN UINTN Height) {
+   EG_IMAGE *NewImage = NULL;
+   UINTN x, y;
+
+   if (((StartX + Width) > Image->Width) || ((StartY + Height) > Image->Height))
+      return NULL;
+
+   NewImage = egCreateImage(Width, Height, Image->HasAlpha);
+   if (NewImage == NULL)
+      return NULL;
+
+   for (y = 0; y < Height; y++) {
+      for (x = 0; x < Width; x++) {
+         NewImage->PixelData[y * NewImage->Width + x] = Image->PixelData[(y + StartY) * Image->Width + x + StartX];
+      }
+   }
+   return NewImage;
+} // EG_IMAGE * egCropImage()
+
 VOID egFreeImage(IN EG_IMAGE *Image)
 {
     if (Image != NULL) {
@@ -211,6 +233,9 @@ static CHAR16 * egFindExtension(IN CHAR16 *FileName)
     return FileName + StrLen(FileName);
 }
 
+// Decode the specified data as the specified format. The IconSize parameter is
+// relevant only for ICNS, for which it selects which ICNS sub-image is decoded.
+// Returns a pointer to the resulting EG_IMAGE or NULL if decoding failed.
 static EG_IMAGE * egDecodeAny(IN UINT8 *FileData, IN UINTN FileDataLength,
                               IN CHAR16 *Format, IN UINTN IconSize, IN BOOLEAN WantAlpha)
 {
@@ -225,6 +250,8 @@ static EG_IMAGE * egDecodeAny(IN UINT8 *FileData, IN UINTN FileDataLength,
       NewImage = egDecodeBMP(FileData, FileDataLength, IconSize, WantAlpha);
    } else if ((StriCmp(Format, L"ICNS") == 0) || (StriCmp(Format, L"icns") == 0)) {
       NewImage = egDecodeICNS(FileData, FileDataLength, IconSize, WantAlpha);
+   } else if ((StriCmp(Format, L"PNG") == 0) || (StriCmp(Format, L"png") == 0)) {
+      NewImage = egDecodePNG(FileData, FileDataLength, IconSize, WantAlpha);
    } // if/else
 
    return NewImage;
@@ -283,6 +310,11 @@ EG_IMAGE * egLoadIcon(IN EFI_FILE* BaseDir, IN CHAR16 *Path, IN UINTN IconSize)
     // decode it
     NewImage = egDecodeAny(FileData, FileDataLength, egFindExtension(Path), 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;
+    }
 
     return NewImage;
 } // EG_IMAGE *egLoadIcon()
@@ -442,7 +474,7 @@ VOID egRawCopy(IN OUT EG_PIXEL *CompBasePtr, IN EG_PIXEL *TopBasePtr,
 {
     UINTN       x, y;
     EG_PIXEL    *TopPtr, *CompPtr;
-    
+
     for (y = 0; y < Height; y++) {
         TopPtr = TopBasePtr;
         CompPtr = CompBasePtr;
@@ -464,7 +496,7 @@ VOID egRawCompose(IN OUT EG_PIXEL *CompBasePtr, IN EG_PIXEL *TopBasePtr,
     UINTN       Alpha;
     UINTN       RevAlpha;
     UINTN       Temp;
-    
+
     for (y = 0; y < Height; y++) {
         TopPtr = TopBasePtr;
         CompPtr = CompBasePtr;
@@ -499,17 +531,18 @@ VOID egComposeImage(IN OUT EG_IMAGE *CompImage, IN EG_IMAGE *TopImage, IN UINTN
 
     // compose
     if (CompWidth > 0) {
-        if (CompImage->HasAlpha) {
-            CompImage->HasAlpha = FALSE;
-            egSetPlane(PLPTR(CompImage, a), 0, CompImage->Width * CompImage->Height);
-        }
+//         if (CompImage->HasAlpha) {
+//             CompImage->HasAlpha = FALSE;
+//             egSetPlane(PLPTR(CompImage, a), 0, CompImage->Width * CompImage->Height);
+//         }
 
-        if (TopImage->HasAlpha)
+        if (TopImage->HasAlpha) {
             egRawCompose(CompImage->PixelData + PosY * CompImage->Width + PosX, TopImage->PixelData,
                          CompWidth, CompHeight, CompImage->Width, TopImage->Width);
-        else
+        } else {
             egRawCopy(CompImage->PixelData + PosY * CompImage->Width + PosX, TopImage->PixelData,
                       CompWidth, CompHeight, CompImage->Width, TopImage->Width);
+        }
     }
 }