diff --git a/CMakeLists.txt b/CMakeLists.txt index 273f342be..b59dee0d9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,7 @@ OPTION(ENABLE_XFCONF "Enable libxfconf-0" ON) OPTION(ENABLE_RPM "Enable rpm" ON) OPTION(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON) OPTION(ENABLE_IMAGEMAGICK6 "Enable imagemagick 6" ON) +OPTION(ENABLE_ZLIB "Enable zlib" ON) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release) @@ -311,6 +312,15 @@ if(ENABLE_IMAGEMAGICK6) endif() endif() +if(ENABLE_ZLIB) + pkg_check_modules(ZLIB zlib) + if(ZLIB_FOUND) + target_compile_definitions(libfastfetch PRIVATE FF_HAVE_ZLIB=1) + else() + message(WARNING "Package zlib not found. Building without support") + endif() +endif() + target_include_directories(libfastfetch PUBLIC ${PROJECT_BINARY_DIR} PUBLIC ${PROJECT_SOURCE_DIR}/src @@ -329,6 +339,7 @@ target_include_directories(libfastfetch PRIVATE ${RPM_INCLUDE_DIRS} PRIVATE ${IMAGEMAGICK7_INCLUDE_DIRS} PRIVATE ${IMAGEMAGICK6_INCLUDE_DIRS} + PRIVATE ${ZLIB_INCLUDE_DIRS} ) target_link_libraries(libfastfetch diff --git a/README.md b/README.md index 2c74fbf70..86a2fb5d0 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ The following libraries are used if present at runtime: * [`libGIO`](https://developer.gnome.org/gio/unstable/): Needed for values that are only stored GSettings. * [`libDConf`](https://developer.gnome.org/dconf/unstable/): Needed for values that are only stored in DConf + Fallback for GSettings. * [`libmagickcore` (ImageMagick)](https://www.imagemagick.org/): Images in terminal using sixel or kitty graphics protocol. +* [`libZ`](https://www.zlib.net/): Faster image output when using kitty graphics protocol. * [`libDBus`](https://www.freedesktop.org/wiki/Software/dbus): Needed for detecting current media player and song. * [`libXFConf`](https://gitlab.xfce.org/xfce/xfconf): Needed for XFWM theme and XFCE Terminal font. * [`librpm`](http://rpm.org/): Needed for rpm package count. diff --git a/completions/bash b/completions/bash index e4258e604..babf52096 100644 --- a/completions/bash +++ b/completions/bash @@ -232,6 +232,8 @@ __fastfetch_completion() "--lib-DBus" "--lib-XFConf" "--lib-RPM" + "--lib-imagemagick" + "--lib-z" "--battery-dir" "--load-config" ) diff --git a/src/common/init.c b/src/common/init.c index 9d4e4b567..c54a22ba7 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -200,6 +200,7 @@ static void defaultConfig(FFinstance* instance) ffStrbufInitA(&instance->config.libXFConf, 0); ffStrbufInitA(&instance->config.librpm, 0); ffStrbufInitA(&instance->config.libImageMagick, 0); + ffStrbufInitA(&instance->config.libZ, 0); ffStrbufInitA(&instance->config.diskFolders, 0); @@ -316,6 +317,9 @@ void ffListFeatures() #ifdef FF_HAVE_IMAGEMAGICK6 "imagemagick6\n" #endif + #ifdef FF_HAVE_ZLIB + "zlib\n" + #endif #ifdef FF_HAVE_XFCONF "xfconf\n" #endif diff --git a/src/data/config.txt b/src/data/config.txt index bb6ab565b..c3310a60f 100644 --- a/src/data/config.txt +++ b/src/data/config.txt @@ -228,3 +228,5 @@ #--lib-DBus /usr/lib/libdbus-1.so #--lib-XFConf /usr/lib/libxfconf-0.so #--lib-rpm /usr/lib/librpm.so +#--lib-imagemagick /usr/lib/libMagickCore-7.Q16HDRI.so +#--lib-z /usr/lib/libz.so diff --git a/src/data/help.txt b/src/data/help.txt index f91bceb56..9adaf17b7 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -119,6 +119,8 @@ Library options: Set the path of a library to load --lib-DBus --lib-XFConf --lib-RPM + --lib-imagemagick + --lib-z Module specific options: --separator-string : Set the string printed by the separator module diff --git a/src/fastfetch.c b/src/fastfetch.c index 3389d5676..c937f0628 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -976,6 +976,8 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con optionParseString(key, value, &instance->config.librpm); else if(strcasecmp(key, "--lib-imagemagick") == 0) optionParseString(key, value, &instance->config.libImageMagick); + else if(strcasecmp(key, "--lib-z") == 0) + optionParseString(key, value, &instance->config.libZ); ////////////////// //Module options// diff --git a/src/fastfetch.h b/src/fastfetch.h index ddad19804..0059e727c 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -137,6 +137,7 @@ typedef struct FFconfig FFstrbuf libXFConf; FFstrbuf librpm; FFstrbuf libImageMagick; + FFstrbuf libZ; FFstrbuf diskFolders; diff --git a/src/logo/image/image.c b/src/logo/image/image.c index b517af82d..63b9f82db 100644 --- a/src/logo/image/image.c +++ b/src/logo/image/image.c @@ -4,6 +4,40 @@ #define FF_KITTY_MAX_CHUNK_SIZE 4096 +#ifdef FF_HAVE_ZLIB +#include + +static bool compressBlob(const FFinstance* instance, void** blob, size_t* length) +{ + FF_LIBRARY_LOAD(zlib, instance->config.libZ, false, "libz.so", 2) + FF_LIBRARY_LOAD_SYMBOL(zlib, compressBound, false) + FF_LIBRARY_LOAD_SYMBOL(zlib, compress2, false) + + uLong compressedLength = ffcompressBound(*length); + void* compressed = malloc(compressedLength); + if(compressed == NULL) + { + dlclose(zlib); + return false; + } + + int compressResult = ffcompress2(compressed, &compressedLength, *blob, *length, Z_BEST_COMPRESSION); + dlclose(zlib); + if(compressResult != Z_OK) + { + free(compressed); + return false; + } + + free(*blob); + + *length = (size_t) compressedLength; + *blob = compressed; + return true; +} + +#endif // FF_HAVE_ZLIB + //We use only the defines from here, that are exactly the same in both versions #ifdef FF_HAVE_IMAGEMAGICK7 #include @@ -44,7 +78,7 @@ static void printImageKittyChunc(char** blob, size_t* length, uint32_t chunkSize *length -= toWrite; } -static bool printImageKitty(ImageInfo* imageInfo, Image* image, ExceptionInfo* ExceptionInfo, uint32_t paddingLeft, ImageMagickFunctions* functions) +static bool printImageKitty(const FFinstance* instance, ImageInfo* imageInfo, Image* image, ExceptionInfo* ExceptionInfo, uint32_t paddingLeft, ImageMagickFunctions* functions) { functions->ffCopyMagickString(imageInfo->magick, "RGBA", 5); @@ -53,16 +87,23 @@ static bool printImageKitty(ImageInfo* imageInfo, Image* image, ExceptionInfo* E if(!checkAllocationResult(blob, length)) return false; - void* encoded = functions->ffBase64Encode(blob, length, &length); + #ifdef FF_HAVE_ZLIB + bool isCompressed = compressBlob(instance, &blob, &length); + #else + FF_UNUSED(instance) + bool isCompressed = false; + #endif + + char* encoded = functions->ffBase64Encode(blob, length, &length); free(blob); if(!checkAllocationResult(encoded, length)) return false; ffPrintCharTimes(' ', paddingLeft); - char* currentPos = (char*) encoded; + char* currentPos = encoded; - printf("\033_Ga=T,f=32,s=%u,v=%u,m=1;\033\\", (uint32_t) image->columns, (uint32_t) image->rows); + printf("\033_Ga=T,f=32,s=%u,v=%u,m=1%s;\033\\", (uint32_t) image->columns, (uint32_t) image->rows, isCompressed ? ",o=z" : ""); while (length > 0) printImageKittyChunc(¤tPos, &length, FF_KITTY_MAX_CHUNK_SIZE); fputs("\033_Gm=0;\033\\", stdout); @@ -159,7 +200,7 @@ FFLogoImageResult ffLogoPrintImageImpl(FFinstance* instance, void* imageMagick, bool printSuccessful; if(type == FF_LOGO_TYPE_KITTY) - printSuccessful = printImageKitty(imageInfoOut, resizedImage, exceptionInfo, instance->config.logoPaddingLeft, &functions); + printSuccessful = printImageKitty(instance, imageInfoOut, resizedImage, exceptionInfo, instance->config.logoPaddingLeft, &functions); else printSuccessful = printImageSixel(imageInfoOut, resizedImage, exceptionInfo, instance->config.logoPaddingLeft, &functions); @@ -179,7 +220,7 @@ FFLogoImageResult ffLogoPrintImageImpl(FFinstance* instance, void* imageMagick, return FF_LOGO_IMAGE_RESULT_SUCCESS; } -#endif +#endif //FF_HAVE_IMAGEMAGICK{6, 7} bool ffLogoPrintImageIfExists(FFinstance* instance, FFLogoType type) {