22
33#if defined(FF_HAVE_IMAGEMAGICK7 ) || defined(FF_HAVE_IMAGEMAGICK6 )
44
5+ #define FF_KITTY_MAX_CHUNK_SIZE 4096
6+
57//We use only the defines from here, that are exactly the same in both versions
68#ifdef FF_HAVE_IMAGEMAGICK7
79 #include <MagickCore/MagickCore.h>
810#else
911 #include <magick/MagickCore.h>
1012#endif
1113
12- FFLogoImageResult ffLogoPrintImageImpl (FFinstance * instance , void * imageMagick , FFLogoIMResizeFunc resizeFunc , FFLogoType type )
14+ typedef struct ImageMagickFunctions
15+ {
16+ FF_LIBRARY_SYMBOL (CopyMagickString )
17+ FF_LIBRARY_SYMBOL (ImageToBlob )
18+ FF_LIBRARY_SYMBOL (Base64Encode )
19+
20+ FFLogoIMWriteFunc writeFunc ;
21+ } ImageMagickFunctions ;
22+
23+ static inline bool checkAllocationResult (void * data , size_t length )
24+ {
25+ if (data == NULL )
26+ return false;
27+
28+ if (length == 0 )
29+ {
30+ free (data );
31+ return false;
32+ }
33+
34+ return true;
35+ }
36+
37+ static void printImageKittyChunc (char * * blob , size_t * length , uint32_t chunkSize )
38+ {
39+ size_t toWrite = chunkSize < * length ? chunkSize : * length ;
40+ fputs ("\033_Gm=1;" , stdout );
41+ fwrite (* blob , sizeof (* * blob ), toWrite , stdout );
42+ fputs ("\033\\" , stdout );
43+ * blob = * blob + toWrite ;
44+ * length -= toWrite ;
45+ }
46+
47+ static bool printImageKitty (ImageInfo * imageInfo , Image * image , ExceptionInfo * ExceptionInfo , uint32_t paddingLeft , ImageMagickFunctions * functions )
48+ {
49+ functions -> ffCopyMagickString (imageInfo -> magick , "RGBA" , 5 );
50+
51+ size_t length ;
52+ void * blob = functions -> ffImageToBlob (imageInfo , image , & length , ExceptionInfo );
53+ if (!checkAllocationResult (blob , length ))
54+ return false;
55+
56+ void * encoded = functions -> ffBase64Encode (blob , length , & length );
57+ free (blob );
58+ if (!checkAllocationResult (encoded , length ))
59+ return false;
60+
61+ ffPrintCharTimes (' ' , paddingLeft );
62+
63+ char * currentPos = (char * ) encoded ;
64+
65+ printf ("\033_Ga=T,f=32,s=%u,v=%u,m=1;\033\\" , (uint32_t ) image -> columns , (uint32_t ) image -> rows );
66+ while (length > 0 )
67+ printImageKittyChunc (& currentPos , & length , FF_KITTY_MAX_CHUNK_SIZE );
68+ fputs ("\033_Gm=0;\033\\" , stdout );
69+
70+ free (encoded );
71+ return true;
72+ }
73+
74+ static bool printImageSixel (ImageInfo * imageInfo , Image * image , ExceptionInfo * exceptionInfo , uint32_t paddingLeft , ImageMagickFunctions * functions )
75+ {
76+ ffPrintCharTimes (' ' , paddingLeft );
77+
78+ functions -> ffCopyMagickString (imageInfo -> magick , "SIXEL" , 6 );
79+ imageInfo -> file = stdout ;
80+ bool writeResult = functions -> writeFunc (imageInfo , image , exceptionInfo );
81+
82+ if (!writeResult )
83+ printf ("\033[%uD" , paddingLeft );
84+
85+ return writeResult ;
86+ }
87+
88+ FFLogoImageResult ffLogoPrintImageImpl (FFinstance * instance , void * imageMagick , FFLogoIMResizeFunc resizeFunc , FFLogoIMWriteFunc writeFunc , FFLogoType type )
1389{
1490 struct winsize winsize ;
1591 if (ioctl (STDOUT_FILENO , TIOCGWINSZ , & winsize ) != 0 )
@@ -19,11 +95,15 @@ FFLogoImageResult ffLogoPrintImageImpl(FFinstance* instance, void* imageMagick,
1995 FF_LIBRARY_LOAD_SYMBOL (imageMagick , DestroyExceptionInfo , FF_LOGO_IMAGE_RESULT_INIT_ERROR )
2096 FF_LIBRARY_LOAD_SYMBOL (imageMagick , AcquireImageInfo , FF_LOGO_IMAGE_RESULT_INIT_ERROR )
2197 FF_LIBRARY_LOAD_SYMBOL (imageMagick , DestroyImageInfo , FF_LOGO_IMAGE_RESULT_INIT_ERROR )
22- FF_LIBRARY_LOAD_SYMBOL (imageMagick , CopyMagickString , FF_LOGO_IMAGE_RESULT_INIT_ERROR )
2398 FF_LIBRARY_LOAD_SYMBOL (imageMagick , ReadImage , FF_LOGO_IMAGE_RESULT_INIT_ERROR )
2499 FF_LIBRARY_LOAD_SYMBOL (imageMagick , DestroyImage , FF_LOGO_IMAGE_RESULT_INIT_ERROR )
25- FF_LIBRARY_LOAD_SYMBOL (imageMagick , ImageToBlob , FF_LOGO_IMAGE_RESULT_INIT_ERROR )
26- FF_LIBRARY_LOAD_SYMBOL (imageMagick , Base64Encode , FF_LOGO_IMAGE_RESULT_INIT_ERROR )
100+
101+ ImageMagickFunctions functions ;
102+ functions .writeFunc = writeFunc ;
103+
104+ FF_LIBRARY_LOAD_SYMBOL_ADRESS (imageMagick , functions .ffCopyMagickString , CopyMagickString , FF_LOGO_IMAGE_RESULT_INIT_ERROR )
105+ FF_LIBRARY_LOAD_SYMBOL_ADRESS (imageMagick , functions .ffImageToBlob , ImageToBlob , FF_LOGO_IMAGE_RESULT_INIT_ERROR )
106+ FF_LIBRARY_LOAD_SYMBOL_ADRESS (imageMagick , functions .ffBase64Encode , Base64Encode , FF_LOGO_IMAGE_RESULT_INIT_ERROR )
27107
28108 ExceptionInfo * exceptionInfo = ffAcquireExceptionInfo ();
29109 if (exceptionInfo == NULL )
@@ -41,7 +121,7 @@ FFLogoImageResult ffLogoPrintImageImpl(FFinstance* instance, void* imageMagick,
41121 }
42122
43123 //+1, because we need to copy the null byte too
44- ffCopyMagickString (imageInfoIn -> filename , instance -> config .logoName .chars , instance -> config .logoName .length + 1 );
124+ functions . ffCopyMagickString (imageInfoIn -> filename , instance -> config .logoName .chars , instance -> config .logoName .length + 1 );
45125
46126 Image * originalImage = ffReadImage (imageInfoIn , exceptionInfo );
47127 ffDestroyImageInfo (imageInfoIn );
@@ -85,37 +165,19 @@ FFLogoImageResult ffLogoPrintImageImpl(FFinstance* instance, void* imageMagick,
85165 return FF_LOGO_IMAGE_RESULT_RUN_ERROR ;
86166 }
87167
88- if (type == FF_LOGO_TYPE_SIXEL )
89- ffCopyMagickString (imageInfoOut -> magick , "SIXEL" , 6 );
90- else //Kitty
91- ffCopyMagickString (imageInfoOut -> magick , "RGBA" , 5 );
92-
93- size_t length ;
94- void * data = ffImageToBlob (imageInfoOut , resizedImage , & length , exceptionInfo );
168+ bool printSuccessful ;
169+ if (type == FF_LOGO_TYPE_KITTY )
170+ printSuccessful = printImageKitty (imageInfoOut , resizedImage , exceptionInfo , instance -> config .logoPaddingLeft , & functions );
171+ else
172+ printSuccessful = printImageSixel (imageInfoOut , resizedImage , exceptionInfo , instance -> config .logoPaddingLeft , & functions );
95173
96174 ffDestroyImageInfo (imageInfoOut );
97175 ffDestroyImage (resizedImage );
98176 ffDestroyExceptionInfo (exceptionInfo );
99177 dlclose (imageMagick );
100178
101- if (data == NULL || length == 0 )
102- return false;
103-
104- ffPrintCharTimes (' ' , instance -> config .logoPaddingLeft );
105-
106- if (type == FF_LOGO_TYPE_KITTY )
107- {
108- void * encoded = ffBase64Encode (data , length , & length );
109- free (data );
110- data = encoded ;
111- printf ("\033_Ga=T,f=32,s=%u,v=%u;" , (uint32_t ) imagePixelWidth , (uint32_t ) imagePixelHeight );
112- }
113-
114- fwrite (data , sizeof (char ), length , stdout );
115- free (data );
116-
117- if (type == FF_LOGO_TYPE_KITTY )
118- fputs ("\033\\" , stdout );
179+ if (!printSuccessful )
180+ return FF_LOGO_IMAGE_RESULT_RUN_ERROR ;
119181
120182 instance -> state .logoHeight = (uint32_t ) (imagePixelHeight / characterPixelHeight );
121183 instance -> state .logoWidth = instance -> config .logoWidth + instance -> config .logoPaddingLeft + instance -> config .logoPaddingRight ;
0 commit comments