mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:14:37 +02:00
Kitty graphics protocol support
This commit is contained in:
+10
-1
@@ -4,17 +4,26 @@
|
||||
#include <magick/MagickCore.h>
|
||||
|
||||
static FF_LIBRARY_SYMBOL(ResizeImage);
|
||||
static FF_LIBRARY_SYMBOL(WriteImage);
|
||||
|
||||
static void* logoResize(const void* image, size_t width, size_t height, void* exceptionInfo)
|
||||
{
|
||||
return ffResizeImage(image, width, height, UndefinedFilter, 1.0, exceptionInfo);
|
||||
}
|
||||
|
||||
static bool logoWrite(void* imageInfo, void* image, void* exceptionInfo)
|
||||
{
|
||||
FF_UNUSED(exceptionInfo);
|
||||
return ffWriteImage(imageInfo, image) == MagickTrue;
|
||||
}
|
||||
|
||||
FFLogoImageResult ffLogoPrintImageIM6(FFinstance* instance, FFLogoType type)
|
||||
{
|
||||
FF_LIBRARY_LOAD(imageMagick, instance->config.libImageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR, "libMagickCore-6.Q16HDRI.so", 8, "libMagickCore-6.Q16.so", 8)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR);
|
||||
return ffLogoPrintImageImpl(instance, imageMagick, logoResize, type);
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(imageMagick, ffWriteImage, WriteImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR);
|
||||
|
||||
return ffLogoPrintImageImpl(instance, imageMagick, logoResize, logoWrite, type);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -4,17 +4,25 @@
|
||||
#include <MagickCore/MagickCore.h>
|
||||
|
||||
static FF_LIBRARY_SYMBOL(ResizeImage);
|
||||
static FF_LIBRARY_SYMBOL(WriteImage);
|
||||
|
||||
static void* logoResize(const void* image, size_t width, size_t height, void* exceptionInfo)
|
||||
{
|
||||
return ffResizeImage(image, width, height, UndefinedFilter, exceptionInfo);
|
||||
}
|
||||
|
||||
static bool logoWrite(void* imageInfo, void* image, void* exceptionInfo)
|
||||
{
|
||||
return ffWriteImage(imageInfo, image, exceptionInfo) == MagickTrue;
|
||||
}
|
||||
|
||||
FFLogoImageResult ffLogoPrintImageIM7(FFinstance* instance, FFLogoType type)
|
||||
{
|
||||
FF_LIBRARY_LOAD(imageMagick, instance->config.libImageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR, "libMagickCore-7.Q16HDRI.so", 11, "libMagickCore-7.Q16.so", 11)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR);
|
||||
return ffLogoPrintImageImpl(instance, imageMagick, logoResize, type);
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(imageMagick, ffWriteImage, WriteImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR);
|
||||
|
||||
return ffLogoPrintImageImpl(instance, imageMagick, logoResize, logoWrite, type);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+92
-30
@@ -2,6 +2,8 @@
|
||||
|
||||
#if defined(FF_HAVE_IMAGEMAGICK7) || defined(FF_HAVE_IMAGEMAGICK6)
|
||||
|
||||
#define FF_KITTY_MAX_CHUNK_SIZE 4096
|
||||
|
||||
//We use only the defines from here, that are exactly the same in both versions
|
||||
#ifdef FF_HAVE_IMAGEMAGICK7
|
||||
#include <MagickCore/MagickCore.h>
|
||||
@@ -9,7 +11,81 @@
|
||||
#include <magick/MagickCore.h>
|
||||
#endif
|
||||
|
||||
FFLogoImageResult ffLogoPrintImageImpl(FFinstance* instance, void* imageMagick, FFLogoIMResizeFunc resizeFunc, FFLogoType type)
|
||||
typedef struct ImageMagickFunctions
|
||||
{
|
||||
FF_LIBRARY_SYMBOL(CopyMagickString)
|
||||
FF_LIBRARY_SYMBOL(ImageToBlob)
|
||||
FF_LIBRARY_SYMBOL(Base64Encode)
|
||||
|
||||
FFLogoIMWriteFunc writeFunc;
|
||||
} ImageMagickFunctions;
|
||||
|
||||
static inline bool checkAllocationResult(void* data, size_t length)
|
||||
{
|
||||
if(data == NULL)
|
||||
return false;
|
||||
|
||||
if(length == 0)
|
||||
{
|
||||
free(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void printImageKittyChunc(char** blob, size_t* length, uint32_t chunkSize)
|
||||
{
|
||||
size_t toWrite = chunkSize < *length ? chunkSize : *length;
|
||||
fputs("\033_Gm=1;", stdout);
|
||||
fwrite(*blob, sizeof(**blob), toWrite, stdout);
|
||||
fputs("\033\\", stdout);
|
||||
*blob = *blob + toWrite;
|
||||
*length -= toWrite;
|
||||
}
|
||||
|
||||
static bool printImageKitty(ImageInfo* imageInfo, Image* image, ExceptionInfo* ExceptionInfo, uint32_t paddingLeft, ImageMagickFunctions* functions)
|
||||
{
|
||||
functions->ffCopyMagickString(imageInfo->magick, "RGBA", 5);
|
||||
|
||||
size_t length;
|
||||
void* blob = functions->ffImageToBlob(imageInfo, image, &length, ExceptionInfo);
|
||||
if(!checkAllocationResult(blob, length))
|
||||
return false;
|
||||
|
||||
void* encoded = functions->ffBase64Encode(blob, length, &length);
|
||||
free(blob);
|
||||
if(!checkAllocationResult(encoded, length))
|
||||
return false;
|
||||
|
||||
ffPrintCharTimes(' ', paddingLeft);
|
||||
|
||||
char* currentPos = (char*) encoded;
|
||||
|
||||
printf("\033_Ga=T,f=32,s=%u,v=%u,m=1;\033\\", (uint32_t) image->columns, (uint32_t) image->rows);
|
||||
while (length > 0)
|
||||
printImageKittyChunc(¤tPos, &length, FF_KITTY_MAX_CHUNK_SIZE);
|
||||
fputs("\033_Gm=0;\033\\", stdout);
|
||||
|
||||
free(encoded);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool printImageSixel(ImageInfo* imageInfo, Image* image, ExceptionInfo* exceptionInfo, uint32_t paddingLeft, ImageMagickFunctions* functions)
|
||||
{
|
||||
ffPrintCharTimes(' ', paddingLeft);
|
||||
|
||||
functions->ffCopyMagickString(imageInfo->magick, "SIXEL", 6);
|
||||
imageInfo->file = stdout;
|
||||
bool writeResult = functions->writeFunc(imageInfo, image, exceptionInfo);
|
||||
|
||||
if(!writeResult)
|
||||
printf("\033[%uD", paddingLeft);
|
||||
|
||||
return writeResult;
|
||||
}
|
||||
|
||||
FFLogoImageResult ffLogoPrintImageImpl(FFinstance* instance, void* imageMagick, FFLogoIMResizeFunc resizeFunc, FFLogoIMWriteFunc writeFunc, FFLogoType type)
|
||||
{
|
||||
struct winsize winsize;
|
||||
if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize) != 0)
|
||||
@@ -19,11 +95,15 @@ FFLogoImageResult ffLogoPrintImageImpl(FFinstance* instance, void* imageMagick,
|
||||
FF_LIBRARY_LOAD_SYMBOL(imageMagick, DestroyExceptionInfo, FF_LOGO_IMAGE_RESULT_INIT_ERROR)
|
||||
FF_LIBRARY_LOAD_SYMBOL(imageMagick, AcquireImageInfo, FF_LOGO_IMAGE_RESULT_INIT_ERROR)
|
||||
FF_LIBRARY_LOAD_SYMBOL(imageMagick, DestroyImageInfo, FF_LOGO_IMAGE_RESULT_INIT_ERROR)
|
||||
FF_LIBRARY_LOAD_SYMBOL(imageMagick, CopyMagickString, FF_LOGO_IMAGE_RESULT_INIT_ERROR)
|
||||
FF_LIBRARY_LOAD_SYMBOL(imageMagick, ReadImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR)
|
||||
FF_LIBRARY_LOAD_SYMBOL(imageMagick, DestroyImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR)
|
||||
FF_LIBRARY_LOAD_SYMBOL(imageMagick, ImageToBlob, FF_LOGO_IMAGE_RESULT_INIT_ERROR)
|
||||
FF_LIBRARY_LOAD_SYMBOL(imageMagick, Base64Encode, FF_LOGO_IMAGE_RESULT_INIT_ERROR)
|
||||
|
||||
ImageMagickFunctions functions;
|
||||
functions.writeFunc = writeFunc;
|
||||
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(imageMagick, functions.ffCopyMagickString, CopyMagickString, FF_LOGO_IMAGE_RESULT_INIT_ERROR)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(imageMagick, functions.ffImageToBlob, ImageToBlob, FF_LOGO_IMAGE_RESULT_INIT_ERROR)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADRESS(imageMagick, functions.ffBase64Encode, Base64Encode, FF_LOGO_IMAGE_RESULT_INIT_ERROR)
|
||||
|
||||
ExceptionInfo* exceptionInfo = ffAcquireExceptionInfo();
|
||||
if(exceptionInfo == NULL)
|
||||
@@ -41,7 +121,7 @@ FFLogoImageResult ffLogoPrintImageImpl(FFinstance* instance, void* imageMagick,
|
||||
}
|
||||
|
||||
//+1, because we need to copy the null byte too
|
||||
ffCopyMagickString(imageInfoIn->filename, instance->config.logoName.chars, instance->config.logoName.length + 1);
|
||||
functions.ffCopyMagickString(imageInfoIn->filename, instance->config.logoName.chars, instance->config.logoName.length + 1);
|
||||
|
||||
Image* originalImage = ffReadImage(imageInfoIn, exceptionInfo);
|
||||
ffDestroyImageInfo(imageInfoIn);
|
||||
@@ -85,37 +165,19 @@ FFLogoImageResult ffLogoPrintImageImpl(FFinstance* instance, void* imageMagick,
|
||||
return FF_LOGO_IMAGE_RESULT_RUN_ERROR;
|
||||
}
|
||||
|
||||
if(type == FF_LOGO_TYPE_SIXEL)
|
||||
ffCopyMagickString(imageInfoOut->magick, "SIXEL", 6);
|
||||
else //Kitty
|
||||
ffCopyMagickString(imageInfoOut->magick, "RGBA", 5);
|
||||
|
||||
size_t length;
|
||||
void* data = ffImageToBlob(imageInfoOut, resizedImage, &length, exceptionInfo);
|
||||
bool printSuccessful;
|
||||
if(type == FF_LOGO_TYPE_KITTY)
|
||||
printSuccessful = printImageKitty(imageInfoOut, resizedImage, exceptionInfo, instance->config.logoPaddingLeft, &functions);
|
||||
else
|
||||
printSuccessful = printImageSixel(imageInfoOut, resizedImage, exceptionInfo, instance->config.logoPaddingLeft, &functions);
|
||||
|
||||
ffDestroyImageInfo(imageInfoOut);
|
||||
ffDestroyImage(resizedImage);
|
||||
ffDestroyExceptionInfo(exceptionInfo);
|
||||
dlclose(imageMagick);
|
||||
|
||||
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);
|
||||
if(!printSuccessful)
|
||||
return FF_LOGO_IMAGE_RESULT_RUN_ERROR;
|
||||
|
||||
instance->state.logoHeight = (uint32_t) (imagePixelHeight / characterPixelHeight);
|
||||
instance->state.logoWidth = instance->config.logoWidth + instance->config.logoPaddingLeft + instance->config.logoPaddingRight;
|
||||
|
||||
@@ -21,8 +21,9 @@ typedef enum FFLogoImageResult
|
||||
} FFLogoImageResult;
|
||||
|
||||
typedef void*(*FFLogoIMResizeFunc)(const void* image, size_t width, size_t height, void* exceptionInfo);
|
||||
typedef bool(*FFLogoIMWriteFunc)(void* imageInfo, void* image, void* exceptionInfo);
|
||||
|
||||
FFLogoImageResult ffLogoPrintImageImpl(FFinstance* instance, void* library, FFLogoIMResizeFunc resizeFunc, FFLogoType type);
|
||||
FFLogoImageResult ffLogoPrintImageImpl(FFinstance* instance, void* library, FFLogoIMResizeFunc resizeFunc, FFLogoIMWriteFunc writeFunc, FFLogoType type);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user