This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns binary.core | |
(:require [org.clojars.smee.binary.core :as b] | |
[clojure.java.io :as io] | |
[clojure.core.match :as m]) | |
(:import org.clojars.smee.binary.core.BinaryIO | |
java.io.DataInput)) | |
(defn fixed-string [len] | |
(b/string "ISO-8859-1" :length len)) | |
(defn bytes [len] | |
(b/repeated :byte :length len)) | |
(defn skip [len] | |
(reify org.clojars.smee.binary.core.BinaryIO | |
(read-data [_ big-in little-in] | |
(.skipBytes ^DataInput big-in len) :skipped) | |
(write-data [_ big-out little-out script]))) | |
(defn select-codec [decision-codec selector-fn] | |
(reify org.clojars.smee.binary.core.BinaryIO | |
(read-data [_ big-in little-in] | |
(let [decision-value (b/read-data decision-codec big-in little-in) | |
codec (selector-fn decision-value)] | |
(merge decision-value | |
(b/read-data codec big-in little-in)))) | |
(write-data [_ big-out little-out script]))) | |
;;;;; | |
(def header | |
(b/ordered-map | |
:magic-number (bytes 8))) | |
(def chunk-header | |
(b/ordered-map | |
:length :int-be | |
:type (fixed-string 4))) | |
(defn chunk-codec [& main] | |
(apply b/ordered-map (concat main [:crc (bytes 4)]))) | |
(defn generic-chunk [len] | |
(b/ordered-map | |
:data (bytes len) | |
:crc (bytes 4))) | |
(def select-chunk-codec | |
(select-codec | |
chunk-header | |
(fn [{:keys [length] :as header}] | |
(m/match header | |
{:type "IHDR"} | |
(chunk-codec | |
:width :int-be | |
:height :int-be | |
:bit-depth :byte | |
:color-type :byte | |
:compression-method :byte | |
:filter-method :byte | |
:interlace-method :byte) | |
{:type "pHYs"} | |
(chunk-codec | |
:x-pixels-per-unit :int-be | |
:y-pixels-per-unit :int-be | |
:unit :byte) | |
{:type "bKGD" :length 1} | |
(chunk-codec :index :byte) | |
{:type "bKGD" :length 2} | |
(chunk-codec :gray :short-be) | |
{:type "bKGD" :length 6} | |
(chunk-codec :red :short-be | |
:green :short-be | |
:blue :short-be) | |
{:type "gAMA"} | |
(chunk-codec :gamma :int-be) | |
{:type "IDAT"} | |
(chunk-codec | |
:data (skip length)) | |
{:type "tEXt"} | |
(chunk-codec | |
:data (fixed-string length)) | |
:else (generic-chunk length))))) | |
(def png-file | |
(b/ordered-map | |
:header header | |
:chunks (b/repeated select-chunk-codec))) | |
(defn decode-png [filename] | |
(let [in (io/input-stream filename)] | |
(b/decode png-file in))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment