// imcat.c // // by Abraham Stolk. // This software is in the Public Domain. #include #include #include #include #if defined(_WIN64) # define STBI_NO_SIMD #endif #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" static int termw=0, termh=0; static int doubleres=0; #if defined(_WIN64) # include static void get_terminal_size(void) { const HANDLE hStdout = GetStdHandle( STD_OUTPUT_HANDLE ); CONSOLE_SCREEN_BUFFER_INFO info; GetConsoleScreenBufferInfo( hStdout, &info ); termw = info.dwSize.X; termh = info.dwSize.Y; if ( !termw ) termw = 80; } static int oldcodepage=0; static void set_console_mode(void) { DWORD mode=0; const HANDLE hStdout = GetStdHandle( STD_OUTPUT_HANDLE ); GetConsoleMode( hStdout, &mode ); mode = mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING; SetConsoleMode( hStdout, mode ); oldcodepage = GetConsoleCP(); SetConsoleCP( 437 ); doubleres = 1; } #else static void get_terminal_size(void) { FILE* f = popen( "stty size", "r" ); if ( !f ) { fprintf( stderr, "Failed to determine terminal size using stty.\n" ); exit( 1 ); } const int num = fscanf( f, "%d %d", &termh, &termw ); assert( num == 2 ); pclose( f ); } static void set_console_mode() {} #endif #define RESETALL "\x1b[0m" static void print_image_single_res( int w, int h, unsigned char* data ) { const int linesz = 16384; char line[ linesz ]; unsigned char* reader = data; for ( int y=0; y= imh ? imh-1 : ey; int sx = cx-kernelradius; sx = sx < 0 ? 0 : sx; int ex = cx+kernelradius; ex = ex >= imw ? imw-1 : ex; for ( int yy = sy; yy <= ey; ++yy ) for ( int xx = sx; xx <= ex; ++xx ) { unsigned char* reader = data + ( yy * imw * 4 ) + xx * 4; acc[ 0 ] += reader[0]; acc[ 1 ] += reader[1]; acc[ 2 ] += reader[2]; acc[ 3 ] += reader[3]; numsamples++; } out[ y ][ x ][ 0 ] = acc[ 0 ] / numsamples; out[ y ][ x ][ 1 ] = acc[ 1 ] / numsamples; out[ y ][ x ][ 2 ] = acc[ 2 ] / numsamples; out[ y ][ x ][ 3 ] = acc[ 3 ] / numsamples; } stbi_image_free( data ); data = 0; if ( doubleres ) print_image_double_res( outw, outh, (unsigned char*) out ); else print_image_single_res( outw, outh, (unsigned char*) out ); return 0; } int main( int argc, char* argv[] ) { if ( argc == 1 || !strcmp( argv[1], "--help" ) ) { fprintf( stderr, "Usage: %s image [image2 .. imageN]\n", argv[0] ); exit( 0 ); } // Step 0: Windows cmd.exe needs to be put in proper console mode. set_console_mode(); // Step 1: figure out the width and height of terminal. get_terminal_size(); //fprintf( stderr, "Your terminal is size %dx%d\n", termw, termh ); // Step 2: Process all images on the command line. for ( int i=1; i