Logo: support raw image type

For raw image type, fastfetch nether parses the file content, nor tries to detect the image size from the file. It's useful to print pre-converted sixel image.
This commit is contained in:
李通洲
2023-01-01 12:37:39 +08:00
parent 9f93ca8019
commit 4a781d8471
5 changed files with 48 additions and 7 deletions
+10
View File
@@ -104,6 +104,16 @@ Printing images as logo is supported using Sixel / Kitty / iTerm graphics protoc
* Kitty: Because [kitty support png](https://sw.kovidgoyal.net/kitty/graphics-protocol/#png-data) natively, using `png` image file with both `--logo-width` and `--logo-height` being specified is recommanded to get maximum performance. Otherwise, imagemagick is required to convert image to RGBA data.
* iTerm: [Since iTerm supports a lot of image format](https://iterm2.com/documentation-images.html), imagemagick support is not required. However, both `--logo-width` and `--logo-height` must be specified since fastfetch has no idea about the size of the image.
* Chafa: Requires imagemagick support.
* Raw: use a pre-converted image file so that fastfetch don't need to convert the image format on the fly.
```shell
# brew install libsixel
$ img2sixel image.png -o image.sixel
$ fastfetch --raw image.sixel --logo-width 30 --logo-height 15
# wget https://iterm2.com/utilities/imgcat && chmod +x imgcat
$ imgcat image.png > image.raw
$ fastfetch --raw image.raw --logo-width 30 --logo-height 15
```
##### Package managers
```
+6
View File
@@ -958,6 +958,7 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con
"sixel", FF_LOGO_TYPE_IMAGE_SIXEL,
"kitty", FF_LOGO_TYPE_IMAGE_KITTY,
"chafa", FF_LOGO_TYPE_IMAGE_CHAFA,
"raw", FF_LOGO_TYPE_IMAGE_RAW,
NULL
);
}
@@ -1036,6 +1037,11 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con
optionParseString(key, value, &instance->config.logo.source);
instance->config.logo.type = FF_LOGO_TYPE_IMAGE_ITERM;
}
else if(strcasecmp(key, "--raw") == 0)
{
optionParseString(key, value, &instance->config.logo.source);
instance->config.logo.type = FF_LOGO_TYPE_IMAGE_RAW;
}
else if(strcasecmp(key, "--chafa-fg-only") == 0)
instance->config.logo.chafaFgOnly = optionParseBoolean(value);
else if(strcasecmp(key, "--chafa-symbols") == 0)
+1
View File
@@ -37,6 +37,7 @@ typedef enum FFLogoType
FF_LOGO_TYPE_IMAGE_KITTY, //image file, printed as kitty graphics protocol
FF_LOGO_TYPE_IMAGE_ITERM, //image file, printed as iterm graphics protocol
FF_LOGO_TYPE_IMAGE_CHAFA, //image file, printed as ascii art using libchafa
FF_LOGO_TYPE_IMAGE_RAW, //image file, printed as raw binary string
} FFLogoType;
typedef enum FFBinaryPrefixType
+1 -1
View File
@@ -39,7 +39,7 @@ static bool printImageIterm(FFinstance* instance)
ffStrbufInit(&buf);
if(!ffAppendFileBuffer(instance->config.logo.source.chars, &buf))
{
fputs("Logo: failed to load image file\n", stderr);
fputs("Logo: Failed to load image file\n", stderr);
return false;
}
+30 -6
View File
@@ -8,6 +8,16 @@
#include <ctype.h>
#include <string.h>
static void ffLogoPrintCharsRaw(FFinstance* instance, const char* data, size_t length)
{
fputs(FASTFETCH_TEXT_MODIFIER_BOLT, stdout);
ffPrintCharTimes(' ', instance->config.logo.paddingLeft);
fwrite(data, length, 1, stdout);
printf("\033[9999999D\n\033[%uA", instance->config.logo.height);
instance->state.logoWidth = instance->config.logo.paddingLeft + instance->config.logo.width + instance->config.logo.paddingRight;
instance->state.logoHeight = instance->config.logo.height;
}
void ffLogoPrintChars(FFinstance* instance, const char* data, bool doColorReplacement)
{
uint32_t currentlineLength = 0;
@@ -271,19 +281,23 @@ static void logoPrintData(FFinstance* instance, bool doColorReplacement) {
logoApplyColorsDetected(instance);
}
static bool logoPrintFileIfExists(FFinstance* instance, bool doColorReplacement)
static bool logoPrintFileIfExists(FFinstance* instance, bool doColorReplacement, bool raw)
{
FFstrbuf content;
ffStrbufInitA(&content, 2047);
ffStrbufInit(&content);
if(!ffAppendFileBuffer(instance->config.logo.source.chars, &content))
{
ffStrbufDestroy(&content);
fputs("Logo: Failed to load file content from logo source\n", stderr);
return false;
}
logoApplyColorsDetected(instance);
ffLogoPrintChars(instance, content.chars, doColorReplacement);
if(raw)
ffLogoPrintCharsRaw(instance, content.chars, content.length);
else
ffLogoPrintChars(instance, content.chars, doColorReplacement);
ffStrbufDestroy(&content);
return true;
}
@@ -304,13 +318,23 @@ static void logoPrintKnownType(FFinstance* instance)
if(instance->config.logo.type == FF_LOGO_TYPE_BUILTIN)
successfull = logoPrintBuiltinIfExists(instance, instance->config.logo.source.chars);
else if(instance->config.logo.type == FF_LOGO_TYPE_FILE)
successfull = logoPrintFileIfExists(instance, true);
successfull = logoPrintFileIfExists(instance, true, false);
else if(instance->config.logo.type == FF_LOGO_TYPE_FILE_RAW)
successfull = logoPrintFileIfExists(instance, false);
successfull = logoPrintFileIfExists(instance, false, false);
else if(instance->config.logo.type == FF_LOGO_TYPE_DATA)
logoPrintData(instance, true);
else if(instance->config.logo.type == FF_LOGO_TYPE_DATA_RAW)
logoPrintData(instance, false);
else if(instance->config.logo.type == FF_LOGO_TYPE_IMAGE_RAW)
{
if(instance->config.logo.width == 0 || instance->config.logo.height == 0)
{
fputs("both `--logo-width` and `--logo-height` must be specified\n", stderr);
successfull = false;
}
else
successfull = logoPrintFileIfExists(instance, false, true);
}
else //image
successfull = logoPrintImageIfExists(instance, instance->config.logo.type);
@@ -362,7 +386,7 @@ void ffLogoPrint(FFinstance* instance)
return;
//Try to load the logo as a file. If it succeeds, print it and return.
if(logoPrintFileIfExists(instance, true))
if(logoPrintFileIfExists(instance, true, false))
return;
logoPrintDetected(instance);