First import.
This commit is contained in:
commit
2113c59ed8
4 changed files with 7333 additions and 0 deletions
9
Makefile
Normal file
9
Makefile
Normal file
|
@ -0,0 +1,9 @@
|
|||
imcat: imcat.c
|
||||
cc -Wall -g -o imcat imcat.c -lm
|
||||
|
||||
run: imcat
|
||||
./imcat ~/Desktop/*.png
|
||||
|
||||
clean:
|
||||
rm -f ./imcat
|
||||
|
BIN
images/sampledesktop.png
Normal file
BIN
images/sampledesktop.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 249 KiB |
134
imcat.c
Normal file
134
imcat.c
Normal file
|
@ -0,0 +1,134 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h"
|
||||
|
||||
static int termw=0, termh=0;
|
||||
|
||||
#define RESETALL "\x1b[0m"
|
||||
|
||||
|
||||
static void print_image( int w, int h, unsigned char* data )
|
||||
{
|
||||
const int linesz = 16384;
|
||||
char line[ linesz ];
|
||||
unsigned char* reader = data;
|
||||
|
||||
for ( int y=0; y<h; ++y )
|
||||
{
|
||||
line[0] = 0;
|
||||
for ( int x=0; x<w; ++x )
|
||||
{
|
||||
strncat( line, "\x1b[48;2;", sizeof(line) - strlen(line) - 1 );
|
||||
char tripl[80];
|
||||
unsigned char r = *reader++;
|
||||
unsigned char g = *reader++;
|
||||
unsigned char b = *reader++;
|
||||
unsigned char a = *reader++;
|
||||
(void) a;
|
||||
snprintf( tripl, sizeof(tripl), "%d;%d;%dm ", r,g,b );
|
||||
strncat( line, tripl, sizeof(line) - strlen(line) - 1 );
|
||||
}
|
||||
strncat( line, RESETALL, sizeof(line) - strlen(line) - 1 );
|
||||
puts( line );
|
||||
}
|
||||
assert( reader = data + w * h * 4 );
|
||||
}
|
||||
|
||||
|
||||
static int process_image( const char* nm )
|
||||
{
|
||||
int imw=0,imh=0,n=0;
|
||||
unsigned char *data = stbi_load( nm, &imw, &imh, &n, 4 );
|
||||
if ( !data )
|
||||
return -1;
|
||||
//fprintf( stderr, "%s has dimension %dx%d w %d components.\n", nm, imw, imh, n );
|
||||
|
||||
float aspectratio = imw / (float) imh;
|
||||
float pixels_per_char = imw / (float)termw;
|
||||
if ( pixels_per_char < 1 ) pixels_per_char = 1;
|
||||
int kernelsize = (int) floorf( pixels_per_char );
|
||||
if ( (kernelsize&1) == 0 ) kernelsize--;
|
||||
if ( !kernelsize ) kernelsize=1;
|
||||
const int kernelradius = (kernelsize-1)/2;
|
||||
|
||||
const int outw = imw < termw ? imw : termw;
|
||||
const int outh = (int) roundf( outw / aspectratio );
|
||||
|
||||
//fprintf( stderr, "pixels per char: %f, kernelsize: %d, out: %dx%d\n", pixels_per_char, kernelsize, outw, outh );
|
||||
|
||||
unsigned char out[ outh ][ outw ][ 4 ];
|
||||
for ( int y=0; y<outh; ++y )
|
||||
for ( int x=0; x<outw; ++x )
|
||||
{
|
||||
const int cx = (int) roundf( pixels_per_char * x );
|
||||
const int cy = (int) roundf( pixels_per_char * y );
|
||||
int acc[4] = {0,0,0,0};
|
||||
int numsamples=0;
|
||||
int sy = cy-kernelradius;
|
||||
sy = sy < 0 ? 0 : sy;
|
||||
int ey = cy+kernelradius;
|
||||
ey = ey >= 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;
|
||||
|
||||
print_image( 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 1: figure out the width and height of terminal.
|
||||
FILE* f = popen( "stty size", "r" );
|
||||
if ( !f )
|
||||
{
|
||||
fprintf( stderr, "%s: Failed to determine terminal size using stty.\n", argv[0] );
|
||||
exit( 1 );
|
||||
}
|
||||
const int num = fscanf( f, "%d %d", &termh, &termw );
|
||||
assert( num == 2 );
|
||||
pclose( f );
|
||||
|
||||
fprintf( stderr, "Your terminal is size %dx%d\n", termw, termh );
|
||||
|
||||
for ( int i=1; i<argc; ++i )
|
||||
{
|
||||
const char* nm = argv[ i ];
|
||||
int rv = process_image( nm );
|
||||
if ( rv < 0 )
|
||||
fprintf( stderr, "Could not load image %s\n", nm );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
7190
stb_image.h
Normal file
7190
stb_image.h
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue