b62f670934feaa3395014c6225ef05975d4c8d4a
   1#!/bin/bash
   2
   3# tmux requires unrecognized OSC sequences to be wrapped with DCS tmux;
   4# <sequence> ST, and for all ESCs in <sequence> to be replaced with ESC ESC. It
   5# only accepts ESC backslash for ST. We use TERM instead of TMUX because TERM
   6# gets passed through ssh.
   7function print_osc() {
   8    if [[ $TERM == screen* ]] ; then
   9        printf "\033Ptmux;\033\033]"
  10    else
  11        printf "\033]"
  12    fi
  13}
  14
  15# More of the tmux workaround described above.
  16function print_st() {
  17    if [[ $TERM == screen* ]] ; then
  18        printf "\a\033\\"
  19    else
  20        printf "\a"
  21    fi
  22}
  23
  24# print_image filename inline base64contents print_filename
  25#   filename: Filename to convey to client
  26#   inline: 0 or 1
  27#   base64contents: Base64-encoded contents
  28#   print_filename: If non-empty, print the filename 
  29#                   before outputting the image
  30function print_image() {
  31    print_osc
  32    printf '1337;File='
  33    if [[ -n "$1" ]]; then
  34      printf 'name='`printf "%s" "$1" | base64`";"
  35    fi
  36
  37    VERSION=$(base64 --version 2>&1)
  38    if [[ "$VERSION" =~ fourmilab ]]; then
  39      BASE64ARG=-d
  40    elif [[ "$VERSION" =~ GNU ]]; then
  41      BASE64ARG=-di
  42    else
  43      BASE64ARG=-D
  44    fi
  45
  46    printf "%s" "$3" | base64 $BASE64ARG | wc -c | awk '{printf "size=%d",$1}'
  47    printf ";inline=$2"
  48    printf ":"
  49    printf "%s" "$3"
  50    print_st
  51    printf '\n'
  52    if [[ -n "$4" ]]; then
  53      echo $1
  54    fi
  55}
  56
  57function error() {
  58    echo "ERROR: $*" 1>&2
  59}
  60
  61function show_help() {
  62    echo "Usage: imgcat [-p] filename ..." 1>& 2
  63    echo "   or: cat filename | imgcat" 1>& 2
  64}
  65
  66function check_dependency() {
  67  if ! (builtin command -V "$1" > /dev/null 2>& 1); then
  68    echo "imgcat: missing dependency: can't find $1" 1>& 2
  69    exit 1
  70  fi
  71}
  72
  73## Main
  74
  75if [ -t 0 ]; then
  76    has_stdin=f
  77else
  78    has_stdin=t
  79fi
  80
  81# Show help if no arguments and no stdin.
  82if [ $has_stdin = f -a $# -eq 0 ]; then
  83    show_help
  84    exit
  85fi
  86
  87check_dependency awk
  88check_dependency base64
  89check_dependency wc
  90
  91# Look for command line flags.
  92while [ $# -gt 0 ]; do
  93    case "$1" in
  94    -h|--h|--help)
  95        show_help
  96        exit
  97        ;;
  98    -p|--p|--print)
  99        print_filename=1
 100        ;;
 101    -u|--u|--url)
 102        check_dependency curl
 103        encoded_image=$(curl -s "$2" | base64) || (error "No such file or url $2"; exit 2)
 104        has_stdin=f
 105        print_image "$2" 1 "$encoded_image" "$print_filename"
 106        set -- ${@:1:1} "-u" ${@:3}
 107        if [ "$#" -eq 2 ]; then
 108            exit
 109        fi
 110        ;;
 111    -*)
 112        error "Unknown option flag: $1"
 113        show_help
 114        exit 1
 115      ;;
 116    *)
 117        if [ -r "$1" ] ; then
 118            has_stdin=f
 119            print_image "$1" 1 "$(base64 < "$1")" "$print_filename"
 120        else
 121            error "imgcat: $1: No such file or directory"
 122            exit 2
 123        fi
 124        ;;
 125    esac
 126    shift
 127done
 128
 129# Read and print stdin
 130if [ $has_stdin = t ]; then
 131    print_image "" 1 "$(cat | base64)" ""
 132fi
 133
 134exit 0