@@ -65,6 +65,20 @@ typedef struct ImageData
6565 ExceptionInfo * exceptionInfo ;
6666} ImageData ;
6767
68+ static inline bool checkAllocationResult (void * data , size_t length )
69+ {
70+ if (data == NULL )
71+ return false;
72+
73+ if (length == 0 )
74+ {
75+ free (data );
76+ return false;
77+ }
78+
79+ return true;
80+ }
81+
6882static void finishPrinting (FFinstance * instance , const FFLogoRequestData * requestData )
6983{
7084 instance -> state .logoWidth = (uint32_t ) (requestData -> imagePixelWidth / requestData -> characterPixelWidth ) + instance -> config .logoPaddingLeft + instance -> config .logoPaddingRight ;
@@ -78,45 +92,68 @@ static void finishPrinting(FFinstance* instance, const FFLogoRequestData* reques
7892 printf ("\033[%uA" , instance -> state .logoHeight );
7993}
8094
81- static inline bool checkAllocationResult ( void * data , size_t length )
95+ static void writeResult ( FFinstance * instance , FFLogoRequestData * requestData , const FFstrbuf * result , const char * cacheFileName )
8296{
83- if (data == NULL )
84- return false;
97+ //Write result to stdout
98+ ffPrintCharTimes (' ' , instance -> config .logoPaddingLeft );
99+ fflush (stdout );
100+ ffWriteFDContent (STDOUT_FILENO , result );
85101
86- if ( length == 0 )
87- {
88- free ( data );
89- return false ;
90- }
102+ //Write result to cache file
103+ uint32_t cacheDirLength = requestData -> cacheDir . length ;
104+ ffStrbufAppendS ( & requestData -> cacheDir , cacheFileName );
105+ ffWriteFileContent ( requestData -> cacheDir . chars , result ) ;
106+ ffStrbufSubstrBefore ( & requestData -> cacheDir , cacheDirLength );
91107
92- return true;
108+ //Write height cache file
109+ ffStrbufAppendS (& requestData -> cacheDir , FF_CACHE_FILE_HEIGHT );
110+ FFstrbuf content ;
111+ content .chars = (char * ) & requestData -> imagePixelHeight ;
112+ content .length = sizeof (requestData -> imagePixelHeight );
113+ ffWriteFileContent (requestData -> cacheDir .chars , & content );
114+ ffStrbufSubstrBefore (& requestData -> cacheDir , cacheDirLength );
115+
116+ //Write escape codes to stdout
117+ finishPrinting (instance , requestData );
93118}
94119
95- static void writeCacheFile ( FFLogoRequestData * requestData , const char * filename , char * blob , size_t length )
120+ static bool printImageSixel ( FFinstance * instance , FFLogoRequestData * requestData , const ImageData * imageData )
96121{
97- uint32_t cacheDirLength = requestData -> cacheDir .length ;
98- ffStrbufAppendS (& requestData -> cacheDir , filename );
122+ imageData -> ffCopyMagickString (imageData -> imageInfo -> magick , "SIXEL" , 6 );
99123
100- FFstrbuf cachedContent ;
101- cachedContent . chars = blob ;
102- cachedContent . length = ( uint32_t ) length ;
103- ffWriteFileContent ( requestData -> cacheDir . chars , & cachedContent ) ;
124+ size_t length ;
125+ void * blob = imageData -> ffImageToBlob ( imageData -> imageInfo , imageData -> image , & length , imageData -> exceptionInfo ) ;
126+ if (! checkAllocationResult ( blob , length ))
127+ return false ;
104128
105- ffStrbufSubstrBefore (& requestData -> cacheDir , cacheDirLength );
106- }
129+ FFstrbuf result ;
130+ result .chars = (char * ) blob ;
131+ result .length = (uint32_t ) length ;
107132
133+ writeResult (instance , requestData , & result , FF_CACHE_FILE_SIXEL );
134+
135+ free (blob );
136+ return true;
137+ }
108138
109- static void printImageKittyBlobChunk ( const char * * blob , size_t * length )
139+ static void appendKittyChunk ( FFstrbuf * result , const char * * blob , size_t * length , bool printEscapeCode )
110140{
111- size_t toWrite = FF_KITTY_MAX_CHUNK_SIZE < * length ? FF_KITTY_MAX_CHUNK_SIZE : * length ;
112- fputs ("\033_Gm=1;" , stdout );
113- fwrite (* blob , sizeof (* * blob ), toWrite , stdout );
114- fputs ("\033\\" , stdout );
115- * blob += toWrite ;
116- * length -= toWrite ;
141+ uint32_t chunkSize = * length > FF_KITTY_MAX_CHUNK_SIZE ? FF_KITTY_MAX_CHUNK_SIZE : (uint32_t ) * length ;
142+
143+ if (printEscapeCode )
144+ ffStrbufAppendS (result , "\033_G" );
145+ else
146+ ffStrbufAppendC (result , ',' );
147+
148+ ffStrbufAppendS (result , chunkSize != * length ? "m=1" : "m=0" );
149+ ffStrbufAppendC (result , ';' );
150+ ffStrbufAppendNS (result , chunkSize , * blob );
151+ ffStrbufAppendS (result , "\033\\" );
152+ * length -= chunkSize ;
153+ * blob += chunkSize ;
117154}
118155
119- static bool printImageKitty (const FFinstance * instance , FFLogoRequestData * requestData , const ImageData * imageData )
156+ static bool printImageKitty (FFinstance * instance , FFLogoRequestData * requestData , const ImageData * imageData )
120157{
121158 imageData -> ffCopyMagickString (imageData -> imageInfo -> magick , "RGBA" , 5 );
122159
@@ -136,43 +173,26 @@ static bool printImageKitty(const FFinstance* instance, FFLogoRequestData* reque
136173 if (!checkAllocationResult (chars , length ))
137174 return false;
138175
139- ffPrintCharTimes (' ' , instance -> config .logoPaddingLeft );
176+ FFstrbuf result ;
177+ ffStrbufInitA (& result , (uint32_t ) (length + 1024 ));
140178
141179 const char * currentPos = chars ;
142180 size_t remainingLength = length ;
143181
144- printf ("\033_Ga=T,f=32,s=%u,v=%u%s,m=1;\033\\" , requestData -> imagePixelWidth , requestData -> imagePixelHeight , isCompressed ? ",o=z" : "" );
182+ ffStrbufAppendF (& result , "\033_Ga=T,f=32,s=%u,v=%u" , requestData -> imagePixelWidth , requestData -> imagePixelHeight );
183+ if (isCompressed )
184+ ffStrbufAppendS (& result , ",o=z" );
185+ appendKittyChunk (& result , & currentPos , & remainingLength , false);
145186 while (remainingLength > 0 )
146- printImageKittyBlobChunk (& currentPos , & remainingLength );
147- fputs ("\033_Gm=0;\033\\" , stdout );
187+ appendKittyChunk (& result , & currentPos , & remainingLength , true);
148188
149- if (isCompressed )
150- writeCacheFile (requestData , FF_CACHE_FILE_KITTY_COMPRESSED , chars , length );
151- else
152- writeCacheFile (requestData , FF_CACHE_FILE_KITTY_UNCOMPRESSED , chars , length );
189+ writeResult (instance , requestData , & result , isCompressed ? FF_CACHE_FILE_KITTY_COMPRESSED : FF_CACHE_FILE_KITTY_UNCOMPRESSED );
153190
191+ ffStrbufDestroy (& result );
154192 free (chars );
155193 return true;
156194}
157195
158- static bool printImageSixel (const FFinstance * instance , FFLogoRequestData * requestData , const ImageData * imageData )
159- {
160- imageData -> ffCopyMagickString (imageData -> imageInfo -> magick , "SIXEL" , 6 );
161-
162- size_t length ;
163- void * blob = imageData -> ffImageToBlob (imageData -> imageInfo , imageData -> image , & length , imageData -> exceptionInfo );
164- if (!checkAllocationResult (blob , length ))
165- return false;
166-
167- ffPrintCharTimes (' ' , instance -> config .logoPaddingLeft );
168- fwrite (blob , sizeof (* blob ), length , stdout );
169-
170- writeCacheFile (requestData , FF_CACHE_FILE_SIXEL , blob , length );
171-
172- free (blob );
173- return true;
174- }
175-
176196FFLogoImageResult ffLogoPrintImageImpl (FFinstance * instance , FFLogoRequestData * requestData , const FFIMData * imData )
177197{
178198 FF_LIBRARY_LOAD_SYMBOL (imData -> library , AcquireExceptionInfo , FF_LOGO_IMAGE_RESULT_INIT_ERROR )
@@ -245,101 +265,21 @@ FFLogoImageResult ffLogoPrintImageImpl(FFinstance* instance, FFLogoRequestData*
245265 ffDestroyImage (imageData .image );
246266 ffDestroyExceptionInfo (imageData .exceptionInfo );
247267
248- if (!printSuccessful )
249- return FF_LOGO_IMAGE_RESULT_RUN_ERROR ;
250-
251- //Write height file
252- uint32_t folderPathLength = requestData -> cacheDir .length ;
253- ffStrbufAppendS (& requestData -> cacheDir , FF_CACHE_FILE_HEIGHT );
254-
255- FFstrbuf content ;
256- content .chars = (char * ) & requestData -> imagePixelHeight ;
257- content .length = sizeof (requestData -> imagePixelHeight );
258- ffWriteFileContent (requestData -> cacheDir .chars , & content );
259-
260- ffStrbufSubstrBefore (& requestData -> cacheDir , folderPathLength );
261-
262- finishPrinting (instance , requestData );
263- return FF_LOGO_IMAGE_RESULT_SUCCESS ;
268+ return printSuccessful ? FF_LOGO_IMAGE_RESULT_SUCCESS : FF_LOGO_IMAGE_RESULT_RUN_ERROR ;
264269}
265270
266271#endif //FF_HAVE_IMAGEMAGICK{6, 7}
267272
268- static bool printCachedSixelFile (const FFinstance * instance , const FFLogoRequestData * requestData )
269- {
270- int fd = open (requestData -> cacheDir .chars , O_RDONLY );
271- if (fd == -1 )
272- return false;
273-
274- ffPrintCharTimes (' ' , instance -> config .logoPaddingLeft );
275- fflush (stdout );
276-
277- char buffer [4096 ];
278- ssize_t readBytes ;
279-
280- while ((readBytes = read (fd , buffer , sizeof (buffer ))) > 0 )
281- write (STDOUT_FILENO , buffer , (size_t ) readBytes );
282-
283- close (fd );
284- return true;
285- }
286-
287- static bool printCachedSixel (const FFinstance * instance , FFLogoRequestData * requestData )
273+ static int getCacheFD (FFLogoRequestData * requestData , const char * fileName )
288274{
289275 uint32_t cacheDirLength = requestData -> cacheDir .length ;
290- bool result ;
291-
292- ffStrbufAppendS (& requestData -> cacheDir , FF_CACHE_FILE_SIXEL );
293- result = printCachedSixelFile (instance , requestData );
294- ffStrbufSubstrBefore (& requestData -> cacheDir , cacheDirLength );
295-
296- return result ;
297- }
298-
299- static bool printCachedKittyFile (const FFinstance * instance , const FFLogoRequestData * requestData , bool isCompressed )
300- {
276+ ffStrbufAppendS (& requestData -> cacheDir , fileName );
301277 int fd = open (requestData -> cacheDir .chars , O_RDONLY );
302- if (fd == -1 )
303- return false;
304-
305- char buffer [FF_KITTY_MAX_CHUNK_SIZE ];
306-
307- ffPrintCharTimes (' ' , instance -> config .logoPaddingLeft );
308- printf ("\033_Ga=T,f=32,s=%u,v=%u%s,m=1;\033\\" , requestData -> imagePixelWidth , requestData -> imagePixelHeight , isCompressed ? ",o=z" : "" );
309-
310- ssize_t readBytes ;
311- while ((readBytes = read (fd , buffer , sizeof (buffer ))) > 0 )
312- {
313- fputs ("\033_Gm=1;" ,stdout );
314- fwrite (buffer , 1 , (size_t ) readBytes , stdout );
315- fputs ("\033\\" , stdout );
316- }
317-
318- fputs ("\033_Gm=0;\033\\" , stdout );
319-
320- close (fd );
321- return true;
322- }
323-
324- static bool printCachedKitty (const FFinstance * instance , FFLogoRequestData * requestData )
325- {
326- uint32_t cacheDirLength = requestData -> cacheDir .length ;
327- bool result ;
328-
329- ffStrbufAppendS (& requestData -> cacheDir , FF_CACHE_FILE_KITTY_COMPRESSED );
330- result = printCachedKittyFile (instance , requestData , true);
331278 ffStrbufSubstrBefore (& requestData -> cacheDir , cacheDirLength );
332- if (result )
333- return true;
334-
335- ffStrbufAppendS (& requestData -> cacheDir , FF_CACHE_FILE_KITTY_UNCOMPRESSED );
336- result = printCachedKittyFile (instance , requestData , false);
337- ffStrbufSubstrBefore (& requestData -> cacheDir , cacheDirLength );
338-
339- return result ;
279+ return fd ;
340280}
341281
342- static bool printCached (const FFinstance * instance , FFLogoRequestData * requestData )
282+ static bool printCached (FFinstance * instance , FFLogoRequestData * requestData )
343283{
344284 uint32_t cacheDirLength = requestData -> cacheDir .length ;
345285 ffStrbufAppendS (& requestData -> cacheDir , FF_CACHE_FILE_HEIGHT );
@@ -357,10 +297,31 @@ static bool printCached(const FFinstance* instance, FFLogoRequestData* requestDa
357297 if (requestData -> imagePixelHeight < 1 )
358298 return false;
359299
360- if (requestData -> type == FF_LOGO_TYPE_SIXEL )
361- return printCachedSixel (instance , requestData );
300+ int fd ;
301+ if (requestData -> type == FF_LOGO_TYPE_KITTY )
302+ {
303+ fd = getCacheFD (requestData , FF_CACHE_FILE_KITTY_COMPRESSED );
304+ if (fd == -1 )
305+ fd = getCacheFD (requestData , FF_CACHE_FILE_KITTY_UNCOMPRESSED );
306+ }
362307 else
363- return printCachedKitty (instance , requestData );
308+ fd = getCacheFD (requestData , FF_CACHE_FILE_SIXEL );
309+
310+ if (fd == -1 )
311+ return false;
312+
313+ ffPrintCharTimes (' ' , instance -> config .logoPaddingLeft );
314+ fflush (stdout );
315+
316+ char buffer [32768 ];
317+ ssize_t readBytes ;
318+ while ((readBytes = read (fd , buffer , sizeof (buffer ))) > 0 )
319+ (void ) write (STDOUT_FILENO , buffer , (size_t ) readBytes );
320+
321+ close (fd );
322+
323+ finishPrinting (instance , requestData );
324+ return true;
364325}
365326
366327static bool getTermInfo (struct winsize * winsize )
@@ -417,7 +378,6 @@ bool ffLogoPrintImageIfExists(FFinstance* instance, FFLogoType type)
417378
418379 if (!instance -> config .recache && printCached (instance , & requestData ))
419380 {
420- finishPrinting (instance , & requestData );
421381 ffStrbufDestroy (& requestData .cacheDir );
422382 return true;
423383 }
0 commit comments