{-# LANGUAGE OverloadedStrings #-}
module Codec.Picture.Blurhash.Internal.Base83 where
import Control.Monad (guard)
import Data.Foldable (foldlM)
import Data.Word (Word8)
import qualified Data.ByteString.Lazy as BS
import qualified Data.ByteString.Lazy.Builder as BS
import qualified Data.Map as Map
import qualified Data.Vector as V
base83Encode :: Int -> Int -> Maybe BS.Builder
base83Encode toEncode len = do
guard $ (toEncode `div` 83 ^ len) == 0
mconcat <$>
traverse
(\i -> do
let digit = toEncode `div` (83 ^ (len - i)) `mod` 83
BS.word8 <$> alphabet V.!? digit)
[1..len]
base83Decode :: BS.ByteString -> Either Word8 Int
base83Decode toDecode = foldlM acc 0 $ BS.unpack toDecode
where
acc ret word = maybe (Left word) (Right . (+ (ret * 83))) $ Map.lookup word charToIndex
charToIndex :: Map.Map Word8 Int
charToIndex = V.ifoldl' (\mapping index char -> Map.insert char index mapping) mempty alphabet
alphabet :: V.Vector Word8
alphabet = V.fromList $
BS.unpack
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$%*+,-.:;=?@[]^_{|}~"