UTFTConverter 0.1.0.0 → 0.1.0.1
raw patch · 7 files changed
+265/−191 lines, 7 filesdep +image-typedep ~base
Dependencies added: image-type
Dependency ranges changed: base
Files
- README.md +15/−6
- UTFTConverter.cabal +60/−57
- main-src/Main.hs +34/−36
- src/Format/C.hs +5/−5
- src/Format/Converter.hs +88/−30
- src/Format/RGB565.hs +37/−38
- tests/Tests.hs +26/−19
README.md view
@@ -30,13 +30,14 @@ * If you specify a non-existing directory as target, it will be created * The length of the array is NOT preceded by `0x` * You can use the flags in any order you want+ * This tool will check the files via magic bytes ## Binaries * precompiled binary for Ubuntu distributions in `bin/UTFTConverter_u` (compiled on Linux Mint 17)- * precompiled binary for Windows in `bin/UTFTConverter_w.exe` (compiled on Windows 7) (TODO)+ * precompiled binary for Windows in `bin/UTFTConverter_w.exe` (compiled on Windows 7) -## Installation:+## Installation via cabal: **Step 1**: Install the Glasgow Haskell Compiler and `cabal` OR the Haskell packaging tool @@ -52,21 +53,29 @@ **Step 2**: When you have `ghc` and `cabal` OR the Haskell Platform installed: -#### If you want the library AND the binary (the easier way) (still to be uploaded on hackage):+#### If you want the library AND the binary (the easier way): * run `cabal install UTFTConverter` * the executable is now at `~/.cabal/bin/UTFTConverter` #### If you want to build it by hand:- * download the JuicyPixels library - `cabal install JuicyPixels`+ * download the JuicyPixels library - `cabal install JuicyPixels` | `stack install * download the git repository - `git clone http://github.com/cirquit/UTFTConverter` * run `make` and the binary is in the same directory OR- * run `cabal install` and the binary is in `/dist/build/` and in your home directory under `~/.cabal/bin/UTFTConverter`+ * run `cabal install` and the binary is in `/dist/build/` and in your home directory under `~/.cabal/bin/UTFTConverter` OR+ * run `stack build && stack install` and the binary is somewhere in your `.stack-work/` ++## Installation via stack:++ * Install stack [Official guide](https://github.com/commercialhaskell/stack/blob/master/doc/GUIDE.md) / [My simplified guide](https://github.com/cirquit/ffp-lib)+ * open your shell and type `stack setup`+ * after that `stack install UTFTConverter`+ * look up the messages where your executable lies+ #### To do: * maybe add resizing with a basic linear algorithm * I'm planning to make a simple API that you can start locally which accepts any below defined formats and responses with the parsed `.raw` file. (another project)- * add `stack` support #### About:
UTFTConverter.cabal view
@@ -1,84 +1,86 @@ name: UTFTConverter category: Graphics, Text-version: 0.1.0.0+version: 0.1.0.1 license: MIT cabal-version: >=1.10 license-file: LICENSE author: Alexander Isenko-maintainer: Alexander Isenko <alex.isenko@googlemail.com>-homepage: www.github.com/cirquit/UTFTConverter-bug-reports: www.github.com/cirquit/UTFTConverter/issues+maintainer: Alexander Isenko <alex.isenko@protonmail.com>+homepage: http://github.com/cirquit/UTFTConverter+bug-reports: http://github.com/cirquit/UTFTConverter/issues build-type: Simple-tested-with: GHC == 7.8.3 synopsis: Processing popular picture formats into .c or .raw format in RGB565 description:- __About:__+ /About:/ . This package was created because I could not find a tool that can be used on UNIX systems to- parse a picture into an array of RGB565 values and save them to a @.c@ or @.raw@ file. Both formats+ parse a picture into an array of 'RGB565' values and save them to a '.c' or '.raw' file. Both formats are used by the <http://www.rinkydinkelectronics.com/library.php?id=51 UTFT library> to display pictures on to a TFT display. . This package includes, but not limited to, an executable which is made to be as identical as possible to the corresponding tool that is also downloaded with the <http://www.rinkydinkelectronics.com/library.php?id=51 UTFT library>. .- __Usage:__ .- >./UTFTConverter <filespec> /c|r [/o <path>] [/t AVR|ARM|PIC32]- >- ><filespec>: File(s) to convert- >parameters: /c - Create output as .c array files- > /r - Create output as .raw files- > /o <path> - Set the output directory to <path>- > /t <platform> - Select target plaform- > AVR : Most Arduinos, Bobuion- > ARM : Arduino Due, Teensy, TI CC3200 LaunchPad- > PIC32 : All chipKit boards- >- >You must specify either /c or /r. All other parameters are optional.- >If /o is ommited the current directory will be used for output.- >If /t is ommited the target platform will be set to AVR.'+ /Usage:/ .+ > ./UTFTConverter <filespec> /c|r [/o <path>] [/t AVR|ARM|PIC32]+ > + > <filespec>: File(s) to convert+ > parameters: /c - Create output as .c array files+ > /r - Create output as .raw files+ > /o <path> - Set the output directory to <path>+ > /t <platform> - Select target plaform+ > AVR : Most Arduinos, Bobuion+ > ARM : Arduino Due, Teensy, TI CC3200 LaunchPad+ > PIC32 : All chipKit boards+ > + > You must specify either /c or /r. All other parameters are optional.+ > If /o is ommited the current directory will be used for output.+ > If /t is ommited the target platform will be set to AVR.' .- __Supported formats:__ .+ /Supported formats:/+ .+ The binary tests if the pictures are encoded correctly via magic bytes using <http://hackage.haskell.org/package/image-type ImageType>. If the extention is wrong, but the encoding is correct, it will still try to convert the picture.+ . The exported library is using <http://hackage.haskell.org/package/JuicyPixels JuicyPixels> to convert incoming .- * @.gif@+ * '.gif' .- * @.png@+ * '.png' .- * @.jpg \/\ .jpe \/\ .jpeg@+ * '.jpg' \/\ '.jpe' \/\ '.jpeg' .- * @.bmp@+ * '.bmp' .- * @.tga@+ * '.tga' .- and translates every pixel to a @RGB565@ format, which is a 4 digit hex number.+ and translates every pixel to a 'RGB565' format, which is a 4 digit hex number. .- __Library:__ .- The only really reusable library is the @Format.RGB565@.+ /Library:/+ .+ The only really reusable library is the 'Format.RGB565'. It support the conversion from .- * @RGB@ to @RGB565@ as @(Word8, Word8, Word8) -> Int@- * @Int@ to @Hex@ as @Int -> String@+ * 'RGB' to 'RGB565' as ('Word8', 'Word8', 'Word8') -> 'Int' .- __Example usage:__+ * 'Int' to 'Hex' as 'Int' -> 'String' .- >>> toRGB565 (0, 0, 255)- 31-- >>> toRGB565Hex (0, 0, 255)- "001F"-- >>> toHex 100- 64-- >>> to4Hex 100- "0064"-- >>> to6Hex 100- "000064"+ .+ /Example usage:/+ .+ > >>> toRGB565 (0, 0, 255)+ > 31+ .+ > >>> toRGB565Hex (0, 0, 255)+ > "001F"+ .+ > >>> toHex 100+ > 64+ .+ > >>> toNHex 6 100+ > "0064" extra-source-files: Makefile@@ -95,10 +97,11 @@ library build-depends:- base >=4.7 && <4.8 ,- filepath >=1.3 && <1.4 ,+ base >=4.7 && <4.9 ,+ filepath >=1.3 && <1.5 , directory >=1.2 && <1.3 ,- time >=1.4 && <1.5 ,+ time >=1.4 && <1.6 ,+ image-type >=0.1.0.0 , bytestring >=0.10 && <0.11 , JuicyPixels >=3.2 && <3.3 @@ -123,10 +126,10 @@ executable UTFTConverter build-depends:- base >=4.7 && <4.8 ,- filepath >=1.3 && <1.4 ,+ base >=4.7 && <4.9 ,+ filepath >=1.3 && <1.5 , directory >=1.2 && <1.3 ,- time >=1.4 && <1.5 ,+ time >=1.4 && <1.6 , bytestring >=0.10 && <0.11 , JuicyPixels >=3.2 && <3.3 , UTFTConverter ==0.1.*@@ -147,10 +150,10 @@ test-suite lib-tests build-depends:- base >=4.7 && <4.8 ,- filepath >=1.3 && <1.4 ,+ base >=4.7 && <4.9 ,+ filepath >=1.3 && <1.5 , directory >=1.2 && <1.3 ,- time >=1.4 && <1.5 ,+ time >=1.4 && <1.6 , bytestring >=0.10 && <0.11 , JuicyPixels >=3.2 && <3.3 , hspec ==2.1.* ,
main-src/Main.hs view
@@ -6,7 +6,7 @@ import System.Environment (getArgs, getProgName) import System.Exit (exitFailure) -import Format.Converter (pictureToC, pictureToRaw)+import Format.Converter (pictureToC, pictureToRaw, toMaybeFormat, Format(..)) import Format.C (Platform(..)) type Args = [String]@@ -14,11 +14,11 @@ data FileType = C | Raw data Option = Option- { outdir :: FilePath- , platform :: Platform- , filetype :: Maybe FileType- , files :: [FilePath]- }+ { outdir :: FilePath+ , platform :: Platform+ , filetype :: Maybe FileType+ , files :: [(Format, FilePath)]+ } main :: IO ()@@ -78,41 +78,39 @@ -- files parser argsParser (fp :xs) opt = do exists <- doesFileExist fp- case (exists, takeExtension fp) of- (True, ".jpg") -> argsParser xs (opt { files = fp : files opt})- (True, ".jpeg") -> argsParser xs (opt { files = fp : files opt})- (True, ".jpe") -> argsParser xs (opt { files = fp : files opt})- (True, ".bmp") -> argsParser xs (opt { files = fp : files opt})- (True, ".png") -> argsParser xs (opt { files = fp : files opt})- (True, ".gif") -> argsParser xs (opt { files = fp : files opt})- (True, ".tga") -> argsParser xs (opt { files = fp : files opt})- (True, _) -> putStrLn ("WARNING: This format is not supported ~ " ++ fp) >> argsParser xs opt- (False, _) -> putStrLn ("WARNING: Unreconized flag ~ " ++ fp) >> argsParser xs opt+ mext <- toMaybeFormat fp+ case (exists, mext) of+ (True, Just ext) -> argsParser xs (opt { files = (ext, fp) : files opt })+ (True, Nothing) -> putStrLn ("WARNING: This format is not supported ~ " ++ fp) >> argsParser xs opt+ (False, _) -> putStrLn ("WARNING: Unreconized flag ~ " ++ fp) >> argsParser xs opt printOpt :: (FilePath, Platform, FileType) -> IO () printOpt (outdir', platform', C) = do- putStrLn $ "Converting to : .c array file(s)"- putStrLn $ "Target platform : " ++ show platform'- putStrLn $ "Output directory : " ++ outdir' ++ "\n"- putStrLn "Processing file(s):"+ putStrLn $ unlines [ "Converting to : .c array file(s)"+ , "Target platform : " ++ show platform'+ , "Output directory : " ++ outdir' ++ "\n"+ , "Processing file(s):"+ ] printOpt (outdir', _, Raw) = do- putStrLn $ "Converting to : .raw file(s)"- putStrLn $ "Output directory : " ++ outdir' ++ "\n"- putStrLn "Processing file(s):"+ putStrLn $ unlines [ "Converting to : .raw file(s)"+ , "Output directory : " ++ outdir' ++ "\n"+ , "Processing file(s):"+ ] help :: IO () help = do name <- getProgName- putStrLn "\nUsage: "- putStrLn $ " " ++ name ++ " <filespec> /c|r [/o <path>] [/t AVR|ARM|PIC32]\n"- putStrLn "<filespec>: File(s) to convert"- putStrLn "parameters: /c - Create output as .c array files"- putStrLn " /r - Create output as .raw files"- putStrLn " /o <path> - Set the output directory to <path>\n"- putStrLn " /t <platform> - Select target plaform"- putStrLn " AVR : Most Arduinos, Bobuion"- putStrLn " ARM : Arduino Due, Teensy, TI CC3200 LaunchPad"- putStrLn " PIC32 : All chipKit boards\n"- putStrLn "You must specify either /c or /r. All other parameters are optional."- putStrLn "If /o is ommited the current directory will be used for output."- putStrLn "If /t is ommited the target platform will be set to AVR."+ putStrLn $ unlines [ "\nUsage: "+ , " " ++ name ++ " <filespec> /c|r [/o <path>] [/t AVR|ARM|PIC32]\n"+ , "<filespec>: File(s) to convert"+ , "parameters: /c - Create output as .c array files"+ , " /r - Create output as .raw files"+ , " /o <path> - Set the output directory to <path>\n"+ , " /t <platform> - Select target plaform"+ , " AVR : Most Arduinos, Bobuion"+ , " ARM : Arduino Due, Teensy, TI CC3200 LaunchPad"+ , " PIC32 : All chipKit boards\n"+ , "You must specify either /c or /r. All other parameters are optional."+ , "If /o is ommited the current directory will be used for output."+ , "If /t is ommited the target platform will be set to AVR."+ ]
src/Format/C.hs view
@@ -11,7 +11,7 @@ module Format.C (toCFile, Platform(..)) where import Data.Time (UTCTime)-import Format.RGB565 (to4Hex)+import Format.RGB565 (toNHex) -- | The Platform datatype has three constructors, for every supported architecture@@ -26,9 +26,9 @@ -- -- * @[String]@ are the hex strings -- * @(String, String)@ is the (filename, file extention)--- * @(Int, Int) is the (width, height)--- * UTCTime is the current time--- * Platform is the desired platform to convert to+-- * @(Int, Int)@ is the (width, height)+-- * @UTCTime@ is the current time+-- * @Platform@ is the desired platform to convert to -- -- The result is a the string which is the full c file with header + unsigned short array + comments --@@ -81,4 +81,4 @@ printHex hx = '0':'x': hx ++ ", " printCom :: Int -> String-printCom n = ' ':' ':'/':'/':' ':'0':'x': to4Hex n ++ ' ':'(': show n ++ ") pixels\n"+printCom n = ' ':' ':'/':'/':' ':'0':'x': toNHex 4 n ++ ' ':'(': show n ++ ") pixels\n"
src/Format/Converter.hs view
@@ -16,18 +16,18 @@ -- * @.bmp@ -- * @.tga@ ----- If it's not any of those formats, an error gets thrown--- If there is an error while decoding the pictures it gets printed out+-- If it's not any of those formats, an error gets thrown and if there is an error while decoding the pictures it only gets printed out (it gets skipped) ----------------------------------------------------------------------------- -module Format.Converter (pictureToRaw, pictureToC) where+module Format.Converter (pictureToRaw, pictureToC, toMaybeFormat, Format(..)) where import qualified Data.ByteString as BS (readFile) import Data.ByteString.Lazy (toStrict) import System.FilePath.Posix (takeBaseName, (</>), takeExtension, takeFileName) import Data.Time (getCurrentTime)+import Data.Char (toUpper) import Codec.Picture.Types import Codec.Picture.Saving (imageToBitmap)@@ -37,17 +37,94 @@ import Codec.Picture.Gif (decodeGif) import Codec.Picture.Tga (decodeTga) +import Codec.ImageType (getFileType)+ import Format.RGB565 (toRGB565Hex) import Format.C (toCFile, Platform()) import Format.Raw (toRawFile) +-- | Currently supported picture formats (by JuicyPixels)+--+data Format = Jpeg+ | Bmp+ | Png+ | Gif+ | Tga++instance Show Format where+ show Jpeg = "jpeg"+ show Bmp = "bmp"+ show Png = "png"+ show Gif = "gif"+ show Tga = "tga"++instance Read Format where+ readsPrec _ e = do+ (s,r) <- lex e+ case map toUpper s of+ "JPEG" -> return (Jpeg, r)+ "JPG" -> return (Jpeg, r)+ "JPE" -> return (Jpeg, r)+ "GIF" -> return (Gif, r)+ "BMP" -> return (Bmp, r)+ "PNG" -> return (Png, r)+ "TGA" -> return (Tga, r)+ _ -> fail "Read Format: no parse"++-- | Checking if the format is supported via magic bytes+-- safe checking for everything unless __.tga__+--+-- __Possible errors:__+-- +-- * It will be problematic in the future if you try to read the file as .tga if it's not encoded as one+--+-- __Example usage:__+--+-- @+-- λ> toMaybeFormat "cat_01_bmp_120x120.bmp"+-- Just Bmp+-- λ> toMaybeFormat "cat_01_bmp_120x120.jpeg"+-- Just Jpeg+-- λ> toMaybeFormat "cat_01_bmp_120x120.jpe"+-- Just Jpeg+-- @++toMaybeFormat :: FilePath -> IO (Maybe Format)+toMaybeFormat fp = do+ mtp <- getFileType fp+ let ext = drop 1 $ takeExtension fp+ validFormats = map show [Jpeg, Bmp, Png, Gif, Tga]+ case (mtp, ext) of+ (Just "jpeg", _)+ | ext `elem` ["jpg", "jpeg", "jpe"] -> return $ Just Jpeg+ (Just tp, _)+ | tp `elem` validFormats, tp == ext -> return $ Just $ read tp+ | tp `elem` validFormats -> do+ putStrLn $ "WARNING: File format is " ++ '.':tp ++ ", not " ++ '.':ext ++ " ~ " ++ fp+ return $ Just $ read fp+ (_, _)+ | "tga" <- ext -> return $ Just Tga+ | otherwise -> return Nothing+++formatToDynImg :: Format -> FilePath -> IO (Maybe DynamicImage)+formatToDynImg f fp = do+ case f of+ Jpeg -> jpgToDynImg fp+ Bmp -> bmpToDynImg fp+ Png -> pngToDynImg fp+ Gif -> gifToDynImg fp+ Tga -> tgaToDynImg fp+-- ft@_ -> error $ "Converter.hs: formatToDynImg:91 - Unsupported Format - " ++ show ft++ -- | pictureToRaw takes a picture, decodes it, parses every pixel to a 4 digit RGB565 hex and saves it to -- a file with the same name and a @.raw@ extention in the specified directory -- -- This function takes two arguments -- -- * first @FilePath@ is the directory to save the file to--- * second @FilePath@ is the filepath to the picture+-- * second @(Format, FilePath)@ is the format and filepath of the picture -- -- __Possible errors:__ --@@ -66,22 +143,12 @@ -- -- @ -- λ> dir <- getCurrentDirectory--- λ> pictureToRaw dir "cat_01_bmp_120x120.bmp"+-- λ> pictureToRaw dir (Bmp, "cat_01_bmp_120x120.bmp") -- cat_01_bmp_120x120.bmp --> cat_01_bmp_120x120.raw -- @ -pictureToRaw :: FilePath -> FilePath -> IO ()-pictureToRaw saveTo fp = do- case takeExtension fp of- (".jpg") -> jpgToDynImg fp >>= dynimgToRaw saveTo fp- (".jpeg") -> jpgToDynImg fp >>= dynimgToRaw saveTo fp- (".jpe") -> jpgToDynImg fp >>= dynimgToRaw saveTo fp- (".bmp") -> bmpToDynImg fp >>= dynimgToRaw saveTo fp- (".png") -> pngToDynImg fp >>= dynimgToRaw saveTo fp- (".gif") -> gifToDynImg fp >>= dynimgToRaw saveTo fp- (".tga") -> tgaToDynImg fp >>= dynimgToRaw saveTo fp- (_) -> error "Argument filter let through some unsupported types"-+pictureToRaw :: FilePath -> (Format, FilePath) -> IO ()+pictureToRaw saveTo (format,fp) = formatToDynImg format fp >>= dynimgToRaw saveTo fp -- | pictureToC takes a picture, decodes it, parses every pixel to a 4 digit RGB565 hex, adds the header -- based on the desired platform and saves it to a file with the same name and a @.c@ extention in the specified@@ -91,7 +158,7 @@ -- -- * @Platform@ is the desired platform to convert to -- * first @FilePath@ is the directory to save the file to--- * second @FilePath@ is the filepath to the picture+-- * second @(Format, FilePath)@ is the format and filepath of the picture -- -- __Possible errors:__ --@@ -110,21 +177,12 @@ -- -- @ -- λ> dir <- getCurrentDirectory--- λ> pictureToC AVR dir "cat_01_bmp_120x120.bmp"+-- λ> pictureToC AVR dir (Bmp, "cat_01_bmp_120x120.bmp") -- cat_01_bmp_120x120.bmp --> cat_01_bmp_120x120.c -- @ -pictureToC :: Platform -> FilePath -> FilePath -> IO ()-pictureToC platform saveTo fp = do- case takeExtension fp of- (".jpg") -> jpgToDynImg fp >>= dynimgToC platform saveTo fp- (".jpeg") -> jpgToDynImg fp >>= dynimgToC platform saveTo fp- (".jpe") -> jpgToDynImg fp >>= dynimgToC platform saveTo fp- (".bmp") -> bmpToDynImg fp >>= dynimgToC platform saveTo fp- (".png") -> pngToDynImg fp >>= dynimgToC platform saveTo fp- (".gif") -> gifToDynImg fp >>= dynimgToC platform saveTo fp- (".tga") -> tgaToDynImg fp >>= dynimgToC platform saveTo fp- (_) -> error "Argument filter let through some unsupported types"+pictureToC :: Platform -> FilePath -> (Format, FilePath) -> IO ()+pictureToC platform saveTo (format,fp) = formatToDynImg format fp >>= dynimgToC platform saveTo fp jpgToDynImg :: FilePath -> IO (Maybe DynamicImage) jpgToDynImg fp = do
src/Format/RGB565.hs view
@@ -9,10 +9,12 @@ -- @Format.RGB565@ exports the functions to convert from a RGB value to RGB565 and the needed hex conversions -- ------------------------------------------------------------------------------module Format.RGB565 (toRGB565, toRGB565Hex, to6Hex, to4Hex, toHex) where+module Format.RGB565 (toRGB565, toRGB565Hex, toNHex, to6Hex, to4Hex, toHex) where import Data.Bits (shiftL, shiftR, (.|.)) import Data.Word (Word8())+import Numeric (showHex)+import Data.Char (toUpper) -- | toRGB565Hex takes a RGB value and converts it into a RGB565 encoded 4 digit hex String@@ -25,7 +27,7 @@ -- @ toRGB565Hex :: (Word8, Word8, Word8) -> String-toRGB565Hex rgb = to4Hex (toRGB565 rgb)+toRGB565Hex rgb = toNHex 4 (toRGB565 rgb) -- | toRGB565 takes a RGB value and converts it into a RGB565 encoded Int --@@ -45,70 +47,67 @@ toInt :: Word8 -> Int toInt = fromIntegral --- | toHex takes an Int and converts it into a hex String+-- | toHex takes an unsigned Int and converts it into a hex String -- -- __Example usage:__ -- -- @ -- λ> toHex 255--- \"F8\"+-- \"FF\" -- @ toHex :: Int -> String-toHex = go ""- where go !acc x =- case quotRem x 16 of- (0,r) -> hex r : acc- (q,r) -> go (hex r : acc) q+toHex = map toUpper . flip showHex "" --- | to4Hex takes an Int and converts it to a hex String and adds zeros until four digits are filled+-- | toNHex takes the desired stringlength __n__ and an unsigned Int and converts it to a hex String and adds zeros until __n__ digits are filled -- -- __Example usage:__ -- -- @+-- λ> toNHex 4 255+-- "00FF"+--+-- λ> toNHex 6 255+-- "0000FF"+-- @+toNHex :: Int -> Int -> String+toNHex n x = map toUpper $ go hx+ where hx = toHex x+ go :: String -> String+ go !str+ | length str < n = go ('0':str)+ | otherwise = str+++-- | to4Hex takes an unsigned Int and converts it to a hex String and adds zeros until four digits are filled+--+-- __Example usage:__+--+-- @ -- λ> to4Hex 255--- "00F8"+-- "00FF" -- @+{-# DEPRECATED to4Hex "Use toNHex 4 instead" #-} to4Hex :: Int -> String-to4Hex x = go hx+to4Hex x = map toUpper $ go hx where hx = toHex x go :: String -> String go !str- | length str < 4 = go ('0':str)+ | length str < 6 = go ('0':str) | otherwise = str --- | to6Hex takes an Int and converts it to a hex String and adds zeros until six digits are filled+-- | to4Hex takes an unsigned Int and converts it to a hex String and adds zeros until six digits are filled -- -- __Example usage:__ -- -- @--- λ> to4Hex 255--- "0000F8"+-- λ> to6Hex 255+-- "0000FF" -- @+{-# DEPRECATED to6Hex "Use toNHex 6 instead" #-} to6Hex :: Int -> String-to6Hex x = go hx+to6Hex x = map toUpper $ go hx where hx = toHex x go :: String -> String go !str | length str < 6 = go ('0':str) | otherwise = str----hex :: Int -> Char-hex 0 = '0'-hex 1 = '1'-hex 2 = '2'-hex 3 = '3'-hex 4 = '4'-hex 5 = '5'-hex 6 = '6'-hex 7 = '7'-hex 8 = '8'-hex 9 = '9'-hex 10 = 'A'-hex 11 = 'B'-hex 12 = 'C'-hex 13 = 'D'-hex 14 = 'E'-hex 15 = 'F'-hex x = error $ "Exceeded bounds of 'hex' - " ++ show x
tests/Tests.hs view
@@ -1,12 +1,13 @@ module Main where -import Format.RGB565 (toHex, to4Hex, toRGB565, toRGB565Hex)-import Format.Converter (pictureToRaw)+import Format.RGB565 (toHex, toNHex, toRGB565, toRGB565Hex)+import Format.Converter (pictureToRaw, toMaybeFormat, Format()) import Test.Hspec import System.Directory (getCurrentDirectory, doesDirectoryExist, createDirectory, getDirectoryContents, removeDirectoryRecursive) import System.FilePath.Posix ((</>))+import Data.Maybe (fromJust) import Data.List (foldl') main :: IO ()@@ -33,19 +34,19 @@ it "toHex should be 10000" $ do toHex 65536 `shouldBe` "10000" - describe "to4Hex" $ do- it "to4Hex 0 should be 0000" $ do- to4Hex 0 `shouldBe` "0000"- it "to4Hex 12 should be 000C" $ do- to4Hex 12 `shouldBe` "000C"- it "to4Hex 198 should be 00C6" $ do- to4Hex 198 `shouldBe` "00C6"- it "to4Hex 122 should be 007A" $ do- to4Hex 122 `shouldBe` "007A"- it "to4Hex 255 should be 00FF" $ do- to4Hex 255 `shouldBe` "00FF"- it "to4Hex 65535 should be FFFF" $ do- to4Hex 65535 `shouldBe` "FFFF"+ describe "toNHex" $ do+ it "toNHex 4 0 should be 0000" $ do+ toNHex 4 0 `shouldBe` "0000"+ it "toNHex 4 12 should be 000C" $ do+ toNHex 4 12 `shouldBe` "000C"+ it "toNHex 4 198 should be 00C6" $ do+ toNHex 4 198 `shouldBe` "00C6"+ it "toNHex 4 122 should be 007A" $ do+ toNHex 4 122 `shouldBe` "007A"+ it "toNHex 4 255 should be 00FF" $ do+ toNHex 4 255 `shouldBe` "00FF"+ it "toNHex 4 65535 should be FFFF" $ do+ toNHex 4 65535 `shouldBe` "FFFF" describe "toRGB565" $ do it "toRGB565 (255, 255, 255) should be 65535" $ do@@ -84,7 +85,7 @@ length (dir1 ++ dir2 ++ dir3) `shouldBe` 15 it "cat_01 pics should be all converted to almost the same .raw-files (>99% similarity)" $ do createDirectory "tmp"- pics <- getExamplePicsPath dir ("tests" </> "examples" </> "cat_01")+ pics <- getExampleFormatPicsPath dir ("tests" </> "examples" </> "cat_01") mapM_ (pictureToRaw (dir </> "tmp")) pics rawfps <- getExamplePicsPath dir "tmp" [p1, p2, p3, p4, p5] <- mapM readFile rawfps@@ -100,7 +101,7 @@ ((r1 + r2 + r3 + r4) / 4) > 98 `shouldBe` True it "cat_02 pics should be all converted to almost the same .raw-files (>99% similarity)" $ do createDirectory "tmp"- pics <- getExamplePicsPath dir ("tests" </> "examples" </> "cat_02")+ pics <- getExampleFormatPicsPath dir ("tests" </> "examples" </> "cat_02") mapM_ (pictureToRaw (dir </> "tmp")) pics rawfps <- getExamplePicsPath dir "tmp" [p1, p2, p3, p4, p5] <- mapM readFile rawfps@@ -116,7 +117,7 @@ ((r1 + r2 + r3 + r4) / 4) > 98 `shouldBe` True it "cat_03 pics should be all converted to almost the same .raw-files (>99% similarity)" $ do createDirectory "tmp"- pics <- getExamplePicsPath dir ("tests" </> "examples" </> "cat_03")+ pics <- getExampleFormatPicsPath dir ("tests" </> "examples" </> "cat_03") mapM_ (pictureToRaw (dir </> "tmp")) pics rawfps <- getExamplePicsPath dir "tmp" [p1, p2, p3, p4, p5] <- mapM readFile rawfps@@ -131,12 +132,18 @@ removeDirectoryRecursive (dir </> "tmp") ((r1 + r2 + r3 + r4) / 4) > 98 `shouldBe` True - getExamplePicsPath :: FilePath -> FilePath -> IO [FilePath] getExamplePicsPath curdir picdir = do content <- getDirectoryContents (curdir </> picdir) let picnames = filter (`notElem` [".", ".."]) content return $ map (\x -> curdir </> picdir </> x) picnames++getExampleFormatPicsPath :: FilePath -> FilePath -> IO [(Format, FilePath)]+getExampleFormatPicsPath curdir picdir = do+ content <- getDirectoryContents (curdir </> picdir)+ let picnames = filter (`notElem` [".", ".."]) content+ picpaths = map (\x -> curdir </> picdir </> x) picnames+ flip zip picpaths . map fromJust <$> mapM toMaybeFormat picpaths picSimilarity :: String -> String -> Double picSimilarity p1 p2 =