;;; -*- mode: lisp; syntax: common-lisp -*-

(defparameter *grays* '(0 85 171 255))

(defun t2b-to-pgm (input-filename output-filename)
  (with-open-file (i input-filename :element-type '(unsigned-byte 8))
    (with-open-file (o output-filename :direction :output :if-exists :supersede)
      (format o "P5~%96 144~%255~%"))
    (with-open-file (o output-filename :direction :output :if-exists :append
                                       :element-type '(unsigned-byte 8))
      (iter (for b = (read-byte i nil))
            (while b)
            (dotimes (k 4)
              (write-byte (elt *grays* (ldb (byte 2 (* (- 3 k) 2)) b)) o))))))

(defun down-color (gray)
  (cond ((<= gray 43) 0)
        ((<= gray 127) 1)
        ((<= gray 213) 2)
        (t 3)))

(defun pgm-to-t2b (input-filename output-filename)
  "Converts a 96x144 ASCII PGM file into a four-color thumbnail."
  (with-open-file (i input-filename)
    (assert (eq (read i) 'P2) () "~a is not an ASCII PGM file" input-filename)
    (assert (= (read i) 96) () "The input width should be 96")
    (assert (= (read i) 144) () "The input height should be 144")
    (let ((colors (read i)))
      (with-open-file (o output-filename :direction :output
                         :if-exists :supersede :element-type '(unsigned-byte 8))
        (iter (repeat #.(* 96 144 1/4))
              (with byte = 0)
              (iter (for k from 3 downto 0)
                    (for color = (read i))
                    (setf (ldb (byte 2 (* k 2)) byte)
                          (down-color (round (* color 255) colors))))
              (write-byte byte o))))))

;;; Use it with ImageMagick:
;;; convert -compress none -geometry 96x144 input.png temp.pgm
;;; (pgm-to-t2b "temp.pgm" "output.t2b")