]> code.delx.au - refind/blobdiff - libeg/image.c
ChromeOS icon.
[refind] / libeg / image.c
index a1238be00bd7771f0fab5034cb6e09f58bf51d4f..9f2262838cead9c9e3482e48395e04a29c2a8390 100644 (file)
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+/*
+ * Modifications copyright (c) 2012-2013 Roderick W. Smith
+ * 
+ * Modifications distributed under the terms of the GNU General Public
+ * License (GPL) version 3 (GPLv3), a copy of which must be distributed
+ * with this source code or binaries made from it.
+ * 
+ */
 
 #include "libegint.h"
 #include "../refind/global.h"
@@ -85,9 +93,10 @@ EG_IMAGE * egCreateFilledImage(IN UINTN Width, IN UINTN Height, IN BOOLEAN HasAl
 
 EG_IMAGE * egCopyImage(IN EG_IMAGE *Image)
 {
-    EG_IMAGE        *NewImage;
+    EG_IMAGE        *NewImage = NULL;
 
-    NewImage = egCreateImage(Image->Width, Image->Height, Image->HasAlpha);
+    if (Image != NULL)
+       NewImage = egCreateImage(Image->Width, Image->Height, Image->HasAlpha);
     if (NewImage == NULL)
         return NULL;
 
@@ -129,8 +138,7 @@ VOID egFreeImage(IN EG_IMAGE *Image)
 // Basic file operations
 //
 
-EFI_STATUS egLoadFile(IN EFI_FILE* BaseDir, IN CHAR16 *FileName,
-                      OUT UINT8 **FileData, OUT UINTN *FileDataLength)
+EFI_STATUS egLoadFile(IN EFI_FILE* BaseDir, IN CHAR16 *FileName, OUT UINT8 **FileData, OUT UINTN *FileDataLength)
 {
     EFI_STATUS          Status;
     EFI_FILE_HANDLE     FileHandle;
@@ -175,7 +183,7 @@ EFI_STATUS egLoadFile(IN EFI_FILE* BaseDir, IN CHAR16 *FileName,
 
 static EFI_GUID ESPGuid = { 0xc12a7328, 0xf81f, 0x11d2, { 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b } };
 
-static EFI_STATUS egFindESP(OUT EFI_FILE_HANDLE *RootDir)
+EFI_STATUS egFindESP(OUT EFI_FILE_HANDLE *RootDir)
 {
     EFI_STATUS          Status;
     UINTN               HandleCount = 0;
@@ -205,7 +213,7 @@ EFI_STATUS egSaveFile(IN EFI_FILE* BaseDir OPTIONAL, IN CHAR16 *FileName,
     }
 
     Status = refit_call5_wrapper(BaseDir->Open, BaseDir, &FileHandle, FileName,
-                           EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0);
+                                 EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0);
     if (EFI_ERROR(Status))
         return Status;
 
@@ -220,19 +228,6 @@ EFI_STATUS egSaveFile(IN EFI_FILE* BaseDir OPTIONAL, IN CHAR16 *FileName,
 // Loading images from files and embedded data
 //
 
-// static CHAR16 * egFindExtension(IN CHAR16 *FileName)
-// {
-//     UINTN i;
-// 
-//     for (i = StrLen(FileName); i >= 0; i--) {
-//         if (FileName[i] == '.')
-//             return FileName + i + 1;
-//         if (FileName[i] == '/' || FileName[i] == '\\')
-//             break;
-//     }
-//     return FileName + StrLen(FileName);
-// }
-
 // Decode the specified image data. 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.
@@ -272,18 +267,12 @@ EG_IMAGE * egLoadImage(IN EFI_FILE* BaseDir, IN CHAR16 *FileName, IN BOOLEAN Wan
 }
 
 // Load an icon from (BaseDir)/Path, extracting the icon of size IconSize x IconSize.
-// If the initial attempt is unsuccessful, try again, replacing the directory
-// component of Path with DEFAULT_ICONS_DIR.
-// Note: The assumption is that BaseDir points to rEFInd's home directory and Path
-// includes one subdirectory level. If this changes in future revisions, it may be
-// necessary to alter the code that tries again with DEFAULT_ICONS_DIR.
 // Returns a pointer to the image data, or NULL if the icon could not be loaded.
 EG_IMAGE * egLoadIcon(IN EFI_FILE* BaseDir, IN CHAR16 *Path, IN UINTN IconSize)
 {
     EFI_STATUS      Status;
     UINT8           *FileData;
     UINTN           FileDataLength;
-    CHAR16          *FileName, FileName2[256];
     EG_IMAGE        *NewImage;
 
     if (BaseDir == NULL || Path == NULL)
@@ -291,13 +280,8 @@ EG_IMAGE * egLoadIcon(IN EFI_FILE* BaseDir, IN CHAR16 *Path, IN UINTN IconSize)
 
     // load file
     Status = egLoadFile(BaseDir, Path, &FileData, &FileDataLength);
-    if (EFI_ERROR(Status)) {
-        FileName = Basename(Path); // Note: FileName is a pointer within Path; DON'T FREE IT!
-        SPrint(FileName2, 255, L"%s\\%s", DEFAULT_ICONS_DIR, FileName);
-        Status = egLoadFile(BaseDir, FileName2, &FileData, &FileDataLength);
-        if (EFI_ERROR(Status))
-           return NULL;
-    }
+    if (EFI_ERROR(Status))
+       return NULL;
 
     // decode it
     NewImage = egDecodeAny(FileData, FileDataLength, IconSize, TRUE);
@@ -311,6 +295,48 @@ EG_IMAGE * egLoadIcon(IN EFI_FILE* BaseDir, IN CHAR16 *Path, IN UINTN IconSize)
     return NewImage;
 } // EG_IMAGE *egLoadIcon()
 
+// Returns an icon of any type from the specified subdirectory using the specified
+// base name. All directory references are relative to BaseDir. For instance, if
+// SubdirName is "myicons" and BaseName is "os_linux", this function will return
+// an image based on "myicons/os_linux.icns" or "myicons/os_linux.png", in that
+// order of preference. Returns NULL if no such file is a valid icon file.
+EG_IMAGE * egLoadIconAnyType(IN EFI_FILE *BaseDir, IN CHAR16 *SubdirName, IN CHAR16 *BaseName, IN UINTN IconSize) {
+   EG_IMAGE *Image = NULL;
+   CHAR16 *Extension;
+   CHAR16 FileName[256];
+   UINTN i = 0;
+
+   while (((Extension = FindCommaDelimited(ICON_EXTENSIONS, i++)) != NULL) && (Image == NULL)) {
+      SPrint(FileName, 255, L"%s\\%s.%s", SubdirName, BaseName, Extension);
+      Image = egLoadIcon(BaseDir, FileName, IconSize);
+      MyFreePool(Extension);
+   } // while()
+
+   return Image;
+} // EG_IMAGE *egLoadIconAnyType()
+
+// Returns an icon with any extension in ICON_EXTENSIONS from either the directory
+// specified by GlobalConfig.IconsDir or DEFAULT_ICONS_DIR. The input BaseName
+// should be the icon name without an extension. For instance, if BaseName is
+// os_linux, GlobalConfig.IconsDir is myicons, DEFAULT_ICONS_DIR is icons, and
+// ICON_EXTENSIONS is "icns,png", this function will return myicons/os_linux.icns,
+// myicons/os_linux.png, icons/os_linux.icns, or icons/os_linux.png, in that
+// order of preference. Returns NULL if no such icon can be found. All file
+// references are relative to SelfDir.
+EG_IMAGE * egFindIcon(IN CHAR16 *BaseName, IN UINTN IconSize) {
+   EG_IMAGE *Image = NULL;
+
+   if (GlobalConfig.IconsDir != NULL) {
+      Image = egLoadIconAnyType(SelfDir, GlobalConfig.IconsDir, BaseName, IconSize);
+   }
+
+   if (Image == NULL) {
+      Image = egLoadIconAnyType(SelfDir, DEFAULT_ICONS_DIR, BaseName, IconSize);
+   }
+
+   return Image;
+} // EG_IMAGE * egFindIcon()
+
 EG_IMAGE * egPrepareEmbeddedImage(IN EG_EMBEDDED_IMAGE *EmbeddedImage, IN BOOLEAN WantAlpha)
 {
     EG_IMAGE            *NewImage;