packages feed

sixel 0.1.1.1 → 0.1.2.0

raw patch · 5 files changed

+111/−54 lines, 5 filesdep +processdep +temporaryPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: process, temporary

API changes (from Hackage documentation)

- Data.Sixel: demo :: [SixelCmd]
- Data.Sixel: img2sixel' :: Image PixelRGB8 -> ByteString
- Data.Sixel: numDigits :: (Integral a, Ord a, Num a) => a -> Int
- Data.Sixel: pixel2colorMap :: Image PixelRGB8 -> Int -> Int -> SixelCmd
+ Data.Sixel: LatexStr :: String -> Float -> LatexStr
+ Data.Sixel: [strSize] :: LatexStr -> Float
+ Data.Sixel: [toLatexStr] :: LatexStr -> String
+ Data.Sixel: data LatexStr
+ Data.Sixel: instance Data.Sixel.ToSixel Data.Sixel.LatexStr
+ Data.Sixel: instance Data.Sixel.ToSixel Data.Sixel.SixelImage
+ Data.Sixel: instance GHC.Classes.Eq Data.Sixel.LatexStr
+ Data.Sixel: instance GHC.Show.Show Data.Sixel.LatexStr
+ Data.Sixel: instance GHC.Show.Show a => Data.Sixel.ToSixel a
+ Data.Sixel: latex :: String -> LatexStr
+ Data.Sixel: latexStr :: String -> Float -> String
+ Data.Sixel: math :: String -> LatexStr
+ Data.Sixel: putSixel :: ToSixel a => a -> IO ()
- Data.Sixel: ColorMapHLS :: ColorNumber -> Int -> Int -> Int -> SixelCmd
+ Data.Sixel: ColorMapHLS :: ColorNumber -> Int -> Word8 -> Word8 -> SixelCmd
- Data.Sixel: Size :: Int -> Int -> Int -> Int -> SixelCmd
+ Data.Sixel: Size :: Int -> Int -> Width -> Height -> SixelCmd
- Data.Sixel: img2sixel :: Image PixelRGB8 -> String
+ Data.Sixel: img2sixel :: Image PixelRGB8 -> ByteString

Files

CHANGELOG.md view
@@ -3,3 +3,7 @@ ## 0.1.0.0 -- 2020-05-17  * First version.++## 0.1.2.0 -- 2020-05-19++* Support for Latex
csrc/sixel.c view
@@ -16,7 +16,7 @@  int img2sixel(unsigned char* buf, unsigned char* img,int width,int height){-  int i,j;+  int i,j,k;   int p=0;   int c;   int prev = (100 << 16 ) | (100 << 8 ) | 100;@@ -66,6 +66,24 @@ 	putnum(buf,&p,g); 	buf[p++] = ';'; 	putnum(buf,&p,b);+      } else {+	int num;+	for(k=i+1;k<width;k++){+	  int pix = (j*width+k)*3;+	  int r = img[pix]*101/256;+	  int g = img[pix+1]*101/256;+	  int b = img[pix+2]*101/256;+	  int nxt = (r << 16) | (g << 8) | b;+	  if(nxt!=cur){+	    break;+	  }+	}+	num = (k-i)-1;+	if(num > 3){+	  buf[p++] = '!';+	  putnum(buf,&p,num+1);+	  i=k-1;+	}       }       buf[p++] = (1 << (j%6))+0x3f;       prev = cur;
demo.png view

binary file changed (94084 → 127588 bytes)

sixel.cabal view
@@ -1,6 +1,6 @@ cabal-version:       >=1.10 name:                sixel-version:             0.1.1.1+version:             0.1.2.0 synopsis:            Sixel library to show images in a terminal emulator description:         Sixel can show graphics on a terminal emulator. This library is developed to showing images on ghci. license:             BSD3@@ -23,6 +23,8 @@                      , JuicyPixels                      , vector                      , bytestring+                     , process+                     , temporary   c-sources:           csrc/sixel.c  executable sixel-exe
src/Data/Sixel.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE LambdaCase #-}  module Data.Sixel where@@ -14,30 +15,35 @@ import Foreign.C.Types import Foreign.ForeignPtr import Foreign.Ptr-import System.IO.Unsafe+import System.IO.Temp (withSystemTempDirectory)+import System.IO.Unsafe (unsafePerformIO)+import System.Process (readProcessWithExitCode)  foreign import ccall "bufsize" c_bufsize :: CInt -> CInt -> IO CInt  foreign import ccall "img2sixel" c_img2sixel :: Ptr () -> Ptr () -> CInt -> CInt -> IO CInt -img2sixel :: Image PixelRGB8 -> String-img2sixel img = BC.unpack $ img2sixel' img+newtype SixelImage = SixelImage {toSixelString :: String} deriving (Eq) -img2sixel' :: Image PixelRGB8 -> ByteString-img2sixel' img = unsafePerformIO $ do-  let (Image w h vec) = img-  bsize <- c_bufsize (fromIntegral w) (fromIntegral h)-  let (sptr, _) = V.unsafeToForeignPtr0 vec-  B.createAndTrim (fromIntegral bsize) $ \dst -> do-    withForeignPtr sptr $ \src -> do-      len <- c_img2sixel (castPtr dst) (castPtr src) (fromIntegral w) (fromIntegral h)-      return (fromIntegral len)+data LatexStr+  = LatexStr+      { toLatexStr :: String,+        strSize :: Float+      }+  deriving (Eq) -newtype SixelImage = SixelImage {toSixelString :: String} deriving (Eq)+latex :: String -> LatexStr+latex str = LatexStr str 2.5 +math :: String -> LatexStr+math str = LatexStr ("$"++str++"$") 2.5+ instance Show SixelImage where   show (SixelImage img) = img +instance Show LatexStr where+  show str = show $ toSixel str+ type ColorNumber = Word8  type PixelPattern = Word8@@ -49,9 +55,9 @@ data SixelCmd   = Start Int Int Int   | End-  | Size Int Int Int Int+  | Size Int Int Width Height   | ColorMapRGB ColorNumber Word8 Word8 Word8-  | ColorMapHLS ColorNumber Int Int Int+  | ColorMapHLS ColorNumber Int Word8 Word8   | Color ColorNumber   | Sixel PixelPattern   | Repeat Int PixelPattern@@ -75,23 +81,57 @@ instance {-# OVERLAPS #-} Show [SixelCmd] where   show xs = concat $ map show xs -numDigits :: (Integral a, Ord a, Num a) => a -> Int-numDigits n-  | n < 10 = 1-  | otherwise = numDigits (n `div` 10) + 1- class ToSixel a where   toSixel :: a -> SixelImage+  putSixel :: a -> IO () -instance ToSixel [SixelCmd] where+instance {-# OVERLAPS #-} (Show a) => ToSixel a where+  toSixel xs = SixelImage $ show xs+  putSixel xs = putStrLn $ show xs++instance {-# OVERLAPS #-} ToSixel [SixelCmd] where   toSixel xs = SixelImage (concat $ map show xs)+  putSixel xs = putStr $ concat $ map show xs -instance ToSixel DynamicImage where+instance {-# OVERLAPS #-} ToSixel DynamicImage where   toSixel dimg = toSixel $ convertRGB8 dimg+  putSixel img = BC.putStr $ img2sixel $ convertRGB8 img -instance ToSixel (Image PixelRGB8) where-  toSixel img = SixelImage (img2sixel img)+instance {-# OVERLAPS #-} ToSixel (Image PixelRGB8) where+  toSixel img = SixelImage (BC.unpack $ img2sixel img)+  putSixel img = BC.putStr $ img2sixel img +instance {-# OVERLAPS #-} ToSixel SixelImage where+  toSixel = id+  putSixel img = putStr $ show img++latexStr :: String -> Float -> String+latexStr str size =+  "\\documentclass[border=2pt]{standalone}"+    ++ "\\usepackage{amsmath}"+    ++ "\\usepackage{graphicx}"+    ++ "\\usepackage{varwidth}"+    ++ "\\begin{document}"+    ++ "\\begin{varwidth}{\\linewidth}"+    ++ "\\scalebox{"+    ++ show size+    ++ "}{"+    ++ str+    ++ "}"+    ++ "\\end{varwidth}"+    ++ "\\end{document}"++instance ToSixel LatexStr where+  toSixel (LatexStr str size) = unsafePerformIO $ do+    withSystemTempDirectory "sixel" $ \dir -> do+      writeFile (dir ++ "/sixel.tex") (latexStr str size)+      (_,outlog,errlog) <- readProcessWithExitCode "pdflatex" ["-output-directory="++dir ,dir ++ "/sixel.tex"] ""+      readProcessWithExitCode "convert" [dir ++ "/sixel.pdf", "-quality", "90", dir ++ "/sixel.png"] ""+      readImage (dir ++ "/sixel.png") >>= \case+        Left err -> error $ "can not read sixel.png. // " ++ errlog ++ " // " ++ outlog+        Right img -> return $ toSixel img+  putSixel img = putStr $ show $ toSixel img+ --  toSixel img = SixelImage (show (toSixelCmds img))  toSixelCmds :: Image PixelRGB8 -> [SixelCmd]@@ -130,37 +170,30 @@             [footer]           ]    in pixels--pixel2colorMap :: Image PixelRGB8 -> Int -> Int -> SixelCmd-pixel2colorMap img i j =-  let p@(PixelRGB8 r g b) = pixelAt img i j-      rr = fromIntegral $ ((fromIntegral r :: Int) * 101) `div` 256-      gg = fromIntegral $ ((fromIntegral g :: Int) * 101) `div` 256-      bb = fromIntegral $ ((fromIntegral b :: Int) * 101) `div` 256-   in ColorMapRGB 0 rr gg bb+  where+    pixel2colorMap :: Image PixelRGB8 -> Int -> Int -> SixelCmd+    pixel2colorMap img i j =+      let p@(PixelRGB8 r g b) = pixelAt img i j+          rr = fromIntegral $ ((fromIntegral r :: Int) * 101) `div` 256+          gg = fromIntegral $ ((fromIntegral g :: Int) * 101) `div` 256+          bb = fromIntegral $ ((fromIntegral b :: Int) * 101) `div` 256+       in ColorMapRGB 0 rr gg bb --- putImage :: FilePath -> IO ()--- putImage file = do---   readImage file >>= \case---     Left err -> print err---     Right img -> putStr $ toSixelString $ toSixel img+img2sixel :: Image PixelRGB8 -> ByteString+img2sixel img = unsafePerformIO $ do+  let (Image w h vec) = img+  bsize <- c_bufsize (fromIntegral w) (fromIntegral h)+  let (sptr, _) = V.unsafeToForeignPtr0 vec+  B.createAndTrim (fromIntegral bsize) $ \dst -> do+    withForeignPtr sptr $ \src -> do+      len <- c_img2sixel (castPtr dst) (castPtr src) (fromIntegral w) (fromIntegral h)+      return (fromIntegral len) +-- | Display sixel image via ByteString+-- putStr of String is really slow on ghci. (Compiled version is not so slow.)+-- To improve perfomance of rendering on ghci, this function uses putStr of ByteString. putImage :: FilePath -> IO () putImage file = do   readImage file >>= \case     Left err -> print err-    Right img -> BC.putStr $ img2sixel' $ convertRGB8 img--demo :: [SixelCmd]-demo =-  [ Start 0 0 8,-    Size 1 1 100 100,-    ColorMapRGB 0 50 0 0,-    Color 0,-    Sixel 1,-    Sixel 2,-    Sixel 4,-    Sixel 8,-    Sixel 16,-    End-  ]+    Right img -> putSixel img