Kitty graphics initial support

This commit is contained in:
Linus Dierheimer
2022-04-13 23:04:42 +02:00
parent d349b7f7fb
commit 3b1314102f
14 changed files with 100 additions and 91 deletions
+1 -1
View File
@@ -61,7 +61,7 @@
# Logo type option:
# Sets the logo type to use.
# Must be auto, builtin, file, raw or sixel.
# Must be auto, builtin, file, raw, sixel or kitty.
# Default is auto.
#--logo-type auto
+2 -1
View File
@@ -21,7 +21,7 @@ General options:
Logo options:
-l,--logo <logo>: set the logo to use. The type is specified by --logo-type. If default: the name of a builtin logo or a path to a file
--logo-type <type>: set the type of the logo given. Must be auto, builtin, file, raw or sixel
--logo-type <type>: set the type of the logo given. Must be auto, builtin, file, raw, sixel or kitty.
--logo-width <width>: set the width of the logo (in characters), if it is an image
--logo-color-[1-9] <color>: overwrite a color in the logo
--logo-padding <padding>: set the padding on the left and the right of the logo
@@ -29,6 +29,7 @@ Logo options:
--logo-padding-right <padding>: set the padding on the right of the logo
--logo-print-remaining <?value>: weather to print the remaining logo, if it has more lines than modules to display
--sixel <file>: short for --logo-type sixel --logo <file>
--kitty <file>: short for --logo-type kitty --logo <file>
Display options:
-s,--structure <structure>: sets the structure of the fetch. Must be a colon separated list of keys. Use "fastfetch --list-modules" to see the ones available.
+7
View File
@@ -733,6 +733,8 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con
instance->config.logoType = FF_LOGO_TYPE_RAW;
else if(strcasecmp(value, "sixel") == 0)
instance->config.logoType = FF_LOGO_TYPE_SIXEL;
else if(strcasecmp(value, "kitty") == 0)
instance->config.logoType = FF_LOGO_TYPE_KITTY;
else
{
fprintf(stderr, "Error: unknown logo type: %s\n", value);
@@ -772,6 +774,11 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con
optionParseString(key, value, &instance->config.logoName);
instance->config.logoType = FF_LOGO_TYPE_SIXEL;
}
else if(strcasecmp(key, "--kitty") == 0)
{
optionParseString(key, value, &instance->config.logoName);
instance->config.logoType = FF_LOGO_TYPE_KITTY;
}
///////////////////
//Display options//
+1
View File
@@ -38,6 +38,7 @@ typedef enum FFLogoType
FF_LOGO_TYPE_FILE, //Raw text file, printed as is.
FF_LOGO_TYPE_RAW, //Raw text file, printed with color codes replacement.
FF_LOGO_TYPE_SIXEL, //Image file, printed as sixel codes.
FF_LOGO_TYPE_KITTY //Image file, printed as kitty graphics protocol
} FFLogoType;
typedef struct FFconfig
+20
View File
@@ -0,0 +1,20 @@
#ifdef FF_HAVE_IMAGEMAGICK6
#include "image.h"
#include <magick/MagickCore.h>
static FF_LIBRARY_SYMBOL(ResizeImage);
static void* logoResize(const void* image, size_t width, size_t height, void* exceptionInfo)
{
return ffResizeImage(image, width, height, UndefinedFilter, 1.0, exceptionInfo);
}
FFLogoImageResult ffLogoPrintImageIM6(FFinstance* instance, FFLogoType type)
{
FF_LIBRARY_LOAD(imageMagick, instance->config.libImageMagick, FF_LOGO_SIXEL_RESULT_INIT_ERROR, "libMagickCore-6.Q16HDRI.so", 8, "libMagickCore-6.Q16.so", 8)
FF_LIBRARY_LOAD_SYMBOL_ADRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_SIXEL_RESULT_INIT_ERROR);
return ffLogoPrintImageImpl(instance, imageMagick, logoResize, type);
}
#endif
+20
View File
@@ -0,0 +1,20 @@
#ifdef FF_HAVE_IMAGEMAGICK7
#include "image.h"
#include <MagickCore/MagickCore.h>
static FF_LIBRARY_SYMBOL(ResizeImage);
static void* logoResize(const void* image, size_t width, size_t height, void* exceptionInfo)
{
return ffResizeImage(image, width, height, UndefinedFilter, exceptionInfo);
}
FFLogoImageResult ffLogoPrintImageIM7(FFinstance* instance, FFLogoType type)
{
FF_LIBRARY_LOAD(imageMagick, instance->config.libImageMagick, FF_LOGO_SIXEL_RESULT_INIT_ERROR, "libMagickCore-7.Q16HDRI.so", 11, "libMagickCore-7.Q16.so", 11)
FF_LIBRARY_LOAD_SYMBOL_ADRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_SIXEL_RESULT_INIT_ERROR);
return ffLogoPrintImageImpl(instance, imageMagick, logoResize, type);
}
#endif
@@ -1,4 +1,4 @@
#include "sixel.h"
#include "image.h"
#if defined(FF_HAVE_IMAGEMAGICK7) || defined(FF_HAVE_IMAGEMAGICK6)
@@ -9,7 +9,7 @@
#include <magick/MagickCore.h>
#endif
FFLogoSixelResult ffLogoPrintSixelImpl(FFinstance* instance, void* imageMagick, FFLogoIMResizeFunc resizeFunc, FFLogoIMWriteFunc writeFunc)
FFLogoImageResult ffLogoPrintImageImpl(FFinstance* instance, void* imageMagick, FFLogoIMResizeFunc resizeFunc, FFLogoType type)
{
struct winsize winsize;
if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize) != 0)
@@ -22,6 +22,8 @@ FFLogoSixelResult ffLogoPrintSixelImpl(FFinstance* instance, void* imageMagick,
FF_LIBRARY_LOAD_SYMBOL(imageMagick, CopyMagickString, FF_LOGO_SIXEL_RESULT_INIT_ERROR)
FF_LIBRARY_LOAD_SYMBOL(imageMagick, ReadImage, FF_LOGO_SIXEL_RESULT_INIT_ERROR)
FF_LIBRARY_LOAD_SYMBOL(imageMagick, DestroyImage, FF_LOGO_SIXEL_RESULT_INIT_ERROR)
FF_LIBRARY_LOAD_SYMBOL(imageMagick, ImageToBlob, FF_LOGO_SIXEL_RESULT_INIT_ERROR)
FF_LIBRARY_LOAD_SYMBOL(imageMagick, Base64Encode, FF_LOGO_SIXEL_RESULT_INIT_ERROR)
ExceptionInfo* exceptionInfo = ffAcquireExceptionInfo();
if(exceptionInfo == NULL)
@@ -83,20 +85,37 @@ FFLogoSixelResult ffLogoPrintSixelImpl(FFinstance* instance, void* imageMagick,
return FF_LOGO_SIXEL_RESULT_RUN_ERROR;
}
ffPrintCharTimes(' ', instance->config.logoPaddingLeft);
if(type == FF_LOGO_TYPE_SIXEL)
ffCopyMagickString(imageInfoOut->magick, "SIXEL", 6);
else //Kitty
ffCopyMagickString(imageInfoOut->magick, "RGBA", 5);
imageInfoOut->file = stdout;
ffCopyMagickString(imageInfoOut->magick, "SIXEL", 6);
MagickBooleanType writeResult = writeFunc(resizedImage, imageInfoOut, exceptionInfo) ? MagickTrue : MagickFalse;
size_t length;
void* data = ffImageToBlob(imageInfoOut, resizedImage, &length, exceptionInfo);
ffDestroyImageInfo(imageInfoOut);
ffDestroyImage(resizedImage);
ffDestroyExceptionInfo(exceptionInfo);
dlclose(imageMagick);
if(writeResult == MagickFalse)
return FF_LOGO_SIXEL_RESULT_RUN_ERROR;
if(data == NULL || length == 0)
return false;
ffPrintCharTimes(' ', instance->config.logoPaddingLeft);
if(type == FF_LOGO_TYPE_KITTY)
{
void* encoded = ffBase64Encode(data, length, &length);
free(data);
data = encoded;
printf("\033_Ga=T,f=32,s=%u,v=%u;", (uint32_t) imagePixelWidth, (uint32_t) imagePixelHeight);
}
fwrite(data, sizeof(char), length, stdout);
free(data);
if(type == FF_LOGO_TYPE_KITTY)
fputs("\033\\", stdout);
instance->state.logoHeight = (uint32_t) (imagePixelHeight / characterPixelHeight);
instance->state.logoWidth = instance->config.logoWidth + instance->config.logoPaddingLeft + instance->config.logoPaddingRight;
@@ -106,16 +125,17 @@ FFLogoSixelResult ffLogoPrintSixelImpl(FFinstance* instance, void* imageMagick,
return FF_LOGO_SIXEL_RESULT_SUCCESS;
}
#endif
bool ffLogoPrintSixelIfExists(FFinstance* instance)
bool ffLogoPrintImageIfExists(FFinstance* instance, FFLogoType type)
{
#if !defined(FF_HAVE_IMAGEMAGICK7) && !defined(FF_HAVE_IMAGEMAGICK6)
FF_UNUSED(instance);
#endif
#ifdef FF_HAVE_IMAGEMAGICK7
FFLogoSixelResult result = ffLogoPrintSixelIM7(instance);
FFLogoImageResult result = ffLogoPrintImageIM7(instance, type);
if(result == FF_LOGO_SIXEL_RESULT_SUCCESS)
return true;
else if(result == FF_LOGO_SIXEL_RESULT_RUN_ERROR)
@@ -123,7 +143,7 @@ bool ffLogoPrintSixelIfExists(FFinstance* instance)
#endif
#ifdef FF_HAVE_IMAGEMAGICK6
return ffLogoPrintSixelIM6(instance) == FF_LOGO_SIXEL_RESULT_SUCCESS;
return ffLogoPrintImageIM6(instance, type) == FF_LOGO_SIXEL_RESULT_SUCCESS;
#endif
return false;
@@ -13,27 +13,26 @@
#define MAGICKCORE_HDRI_ENABLE 1
#define MAGICKCORE_QUANTUM_DEPTH 16
typedef enum FFLogoSixelResult
typedef enum FFLogoImageResult
{
FF_LOGO_SIXEL_RESULT_SUCCESS, //Logo printed
FF_LOGO_SIXEL_RESULT_INIT_ERROR, //Failed to load library, try again with next IM version
FF_LOGO_SIXEL_RESULT_RUN_ERROR //Failed to load / convert image, cancle whole sixel code
} FFLogoSixelResult;
} FFLogoImageResult;
typedef void*(*FFLogoIMResizeFunc)(const void* image, size_t width, size_t height, void* exceptionInfo);
typedef bool(*FFLogoIMWriteFunc)(void* image, const void* imageInfo, void* exceptionInfo);
FFLogoSixelResult ffLogoPrintSixelImpl(FFinstance* instance, void* library, FFLogoIMResizeFunc resizeFunc, FFLogoIMWriteFunc writeFunc);
FFLogoImageResult ffLogoPrintImageImpl(FFinstance* instance, void* library, FFLogoIMResizeFunc resizeFunc, FFLogoType type);
#endif
#ifdef FF_HAVE_IMAGEMAGICK7
FFLogoSixelResult ffLogoPrintSixelIM7(FFinstance* instance);
FFLogoImageResult ffLogoPrintImageIM7(FFinstance* instance, FFLogoType type);
#endif
#ifdef FF_HAVE_IMAGEMAGICK6
#include <math.h>
FFLogoSixelResult ffLogoPrintSixelIM6(FFinstance* instance);
FFLogoSixelResult ffLogoPrintImageIM6(FFinstance* instance, FFLogoType type);
#endif
+4 -4
View File
@@ -162,7 +162,7 @@ static void logoPrintDetected(FFinstance* instance)
{
if(
!ffLogoPrintBuiltinIfExists(instance) &&
!ffLogoPrintSixelIfExists(instance)
!ffLogoPrintImageIfExists(instance, FF_LOGO_TYPE_KITTY)
) logoPrintFile(instance, true);
return;
}
@@ -188,10 +188,10 @@ void ffPrintLogo(FFinstance* instance)
logoPrintFile(instance, true);
else if(instance->config.logoType == FF_LOGO_TYPE_RAW)
logoPrintFile(instance, false);
else if(instance->config.logoType == FF_LOGO_TYPE_SIXEL)
else if(instance->config.logoType == FF_LOGO_TYPE_SIXEL || instance->config.logoType == FF_LOGO_TYPE_KITTY)
{
if(!ffLogoPrintSixelIfExists(instance))
ffLogoPrintUnknown(instance);
if(!ffLogoPrintImageIfExists(instance, instance->config.logoType))
ffLogoPrintBuiltinDetected(instance);
}
else
logoPrintDetected(instance);
+2 -2
View File
@@ -16,7 +16,7 @@ void ffLogoPrintBuiltin(FFinstance* instance);
bool ffLogoPrintBuiltinIfExists(FFinstance* instance);
void ffLogoPrintBuiltinDetected(FFinstance* instance);
//sixel/sixel.c
bool ffLogoPrintSixelIfExists(FFinstance* instance);
//sixel/image.c
bool ffLogoPrintImageIfExists(FFinstance* instance, FFLogoType type);
#endif
-31
View File
@@ -1,31 +0,0 @@
#include "sixel.h"
#ifdef FF_HAVE_IMAGEMAGICK6
#include <magick/MagickCore.h>
static FF_LIBRARY_SYMBOL(ResizeImage);
static FF_LIBRARY_SYMBOL(WriteImage);
static void* logoResizeIM6(const void* image, size_t width, size_t height, void* exceptionInfo)
{
return ffResizeImage(image, width, height, UndefinedFilter, 1.0, exceptionInfo);
}
static bool logoWriteIM6(void* image, const void* imageInfo, void* exceptionInfo)
{
FF_UNUSED(exceptionInfo);
return ffWriteImage(imageInfo, image) == MagickTrue;
}
FFLogoSixelResult ffLogoPrintSixelIM6(FFinstance* instance)
{
FF_LIBRARY_LOAD(imageMagick, instance->config.libImageMagick, FF_LOGO_SIXEL_RESULT_INIT_ERROR, "libMagickCore-6.Q16HDRI.so", 8, "libMagickCore-6.Q16.so", 8)
FF_LIBRARY_LOAD_SYMBOL_ADRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_SIXEL_RESULT_INIT_ERROR);
FF_LIBRARY_LOAD_SYMBOL_ADRESS(imageMagick, ffWriteImage, WriteImage, FF_LOGO_SIXEL_RESULT_INIT_ERROR);
return ffLogoPrintSixelImpl(instance, imageMagick, logoResizeIM6, logoWriteIM6);
}
#endif
-30
View File
@@ -1,30 +0,0 @@
#include "sixel.h"
#ifdef FF_HAVE_IMAGEMAGICK7
#include <MagickCore/MagickCore.h>
static FF_LIBRARY_SYMBOL(ResizeImage);
static FF_LIBRARY_SYMBOL(WriteImage);
static void* logoResizeIM7(const void* image, size_t width, size_t height, void* exceptionInfo)
{
return ffResizeImage(image, width, height, UndefinedFilter, exceptionInfo);
}
static bool logoWriteIM7(void* image, const void* imageInfo, void* exceptionInfo)
{
return ffWriteImage(imageInfo, image, exceptionInfo) == MagickTrue;
}
FFLogoSixelResult ffLogoPrintSixelIM7(FFinstance* instance)
{
FF_LIBRARY_LOAD(imageMagick, instance->config.libImageMagick, FF_LOGO_SIXEL_RESULT_INIT_ERROR, "libMagickCore-7.Q16HDRI.so", 11, "libMagickCore-7.Q16.so", 11)
FF_LIBRARY_LOAD_SYMBOL_ADRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_SIXEL_RESULT_INIT_ERROR);
FF_LIBRARY_LOAD_SYMBOL_ADRESS(imageMagick, ffWriteImage, WriteImage, FF_LOGO_SIXEL_RESULT_INIT_ERROR);
return ffLogoPrintSixelImpl(instance, imageMagick, logoResizeIM7, logoWriteIM7);
}
#endif