#!/bin/bash -e

##  tiv: Image viewer for Linux terminal  ##

# Character dimensions
# For XTerm (W×H; change with L-Ctrl + RMB):
#   Huge:       10×20
#   Large:       9×18
#   Medium:      8×13
#   Small:       7×14
# * Default:     6×13
#   Tiny:        5×8 (recommended)
#   Unreadable:  1×2 (high resolution, slowest rendering, without double horizontal resolution)
char_w=5
char_h=8
char_w=1
char_h=2

# If file doesn't exist, then die with 'No such file or directory' exit code
if [ ! -f "$1" ]
  then exit 2
  elif grep -q image <<<$(file "$1"); then # If file is image…
    cols_no=$(($(tput cols)*6))
    lines_no=$(tput lines)
    window_w=$((cols_no*char_w))
    window_h=$((lines_no*char_h))
    img_dims=$(identify -format '%w %h' "$1")
    img_w=$(awk '{print $1}' <<<$img_dims)
    img_h=$(awk '{print $2}' <<<$img_dims)
    char_asp_r="($char_w/$char_h)"

# Zoom parameter; you can use decimal comma
    case "$2" in
      "") zoom=100;;
       *) zoom=$(sed -e 's/,/./' <<<$2);;
    esac

# Determine whether the image is landscape or portrait (or square) to ensure the image adapts to window/screen
    if [ $((img_w*window_h)) -gt $((img_h*window_w/6)) ]
      then out_v=$(bc -l <<<"scale=6; $cols_no/$img_w*$zoom*$char_asp_r/6")
      else out_v=$(bc -l <<<"scale=6; $lines_no/$img_h*$zoom")
    fi

# MAIN ENGINE
# printf "\e[;f" = move cursor to top left corner and further:
# * Remove comment (if any)
# * Use first frame from animated image (eg GIF)
# * Convert to 8-bit depth
# * Use Lanczos' (sharp but without distortions) interpolation filter, resize image to fit to the window
# * Center image, fill empty spaces with black
# * Export to ASCII PPM image file format and send to pipe, where:
#    * Remove the PPM header
#    * Align output to $cols_no columns (window width*6 [R G B r g b - FOREGROUND/background])
#    * Convert 'R G B r g b' decimal values to ANSI escape code for set foreground/background color of the '▌' character
# … and print formatted output to STDOUT (or file)
# Reset formatting and move cursor to the top left corner
    printf "\e[;f$(convert -comment "" "$1"[0] -depth 8 -filter Lanczos2 -resize $(bc -l <<<"scale=6; $out_v/$char_asp_r*2")%x${out_v}\
    -background black -gravity center -extent $((cols_no/3))x${lines_no}$3 -compress none ppm:- |\
    tail -n+5 | xargs -n $cols_no |\
    sed -e 's:$: :g;s:\([0-9]\+\) \([0-9]\+\) \([0-9]\+\) \([0-9]\+\) \([0-9]\+\) \([0-9]\+\) :\\e\[38;2;\1;\2;\3;48;2;\4;\5;\6m▌:g')\e[m\e[;f"

# If file is not an image, then exit with 'Wrong medium type' exit code
    else exit 124
fi
