libheif-hs 0.1.0.0 → 0.2.0.0
raw patch · 7 files changed
+103/−1485 lines, 7 filesdep ~containersPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: containers
API changes (from Hackage documentation)
- Codec.HEIF: newtype EncodeOptions
+ Codec.HEIF: AV1 :: EncodeFormat
+ Codec.HEIF: HEVC :: EncodeFormat
+ Codec.HEIF: [eoFormat] :: EncodeOptions -> EncodeFormat
+ Codec.HEIF: data EncodeFormat
+ Codec.HEIF: data EncodeOptions
- Codec.HEIF: EncodeOptions :: EncodeQuality -> EncodeOptions
+ Codec.HEIF: EncodeOptions :: EncodeQuality -> EncodeFormat -> EncodeOptions
Files
- CHANGELOG.md +8/−0
- README.md +9/−12
- libheif-hs.cabal +3/−5
- src/Codec/HEIF.hs +4/−2
- src/Codec/HEIF/Bindings.hs +56/−32
- test/Main.hs +23/−66
- test/SampleImage.hs +0/−1368
CHANGELOG.md view
@@ -1,5 +1,13 @@ # Revision history for `libheif-hs` +## 0.2.0.0 -- 2026-10-12++* Added AV1 (.avif file extension) support.+* Added `EncodeFormat` data definition, used in a new `EncodeOptions` field.+* Added aom library dependency for AV1 support.+* Removed hard-coded hs-bindgen package from cabal.project because it was released to Hackage.+* Updated README.md.+ ## 0.1.0.0 -- 2026-09-07 * Initial release
README.md view
@@ -1,11 +1,11 @@ # libheif-hs -A minimal Haskell library that decodes `.HEIC` files via +A minimal Haskell codec for `.HEIC` files via [libheif](https://github.com/strukturag/libheif) C bindings. This package is a standard Cabal project designed to integrate seamlessly with [Nix flakes](https://wiki.nixos.org/wiki/Flakes). -It currently exposes a core subset of the HEIF format's available data, with +It exposes a core subset of the HEIF format's available data, with built-in support for WebAssembly (`wasm32-wasi`) cross-compilation. ## Usage@@ -19,16 +19,13 @@ ## How to use the Cabal package without a flake shell -Since some project dependencies (`hs-bindgen-runtime`) are not yet published to hackage, you -must add them them from `cabal.project` in this repository into your local `cabal.project` -file.- You'll also need the following libraries present in pkg-config compiled with at least the flags seen the flake: -* kvazaar-2.3.2 (to encode HEIF)-* libde265-1.1.1 (to decode HEIF)-* libheif-1.23.1+* libheif-1.23.1 +* kvazaar-2.3.2 or newer (to encode HEIF)+* libde265-1.1.1 or newer (to decode HEIF)+* libaom-3.12.1 or newer (to encode and decode AV1) ## Development @@ -63,6 +60,6 @@ # Future work * Expanded API: expose more features of the underlying libheif interface.-* Broader codec support: the dependent libheif is currently compiled only with HEIF format- support. Future versions might expose additional encode/decode formats supported by- libheif such as AVIF, VVC, JPEG, etc.+* Broader codec support: the dependent libheif is currently compiled only with HEIF and AV1 + format support. Future versions might expose additional encode/decode formats supported by+ libheif such as VVC, JPEG, etc.
libheif-hs.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: libheif-hs-version: 0.1.0.0+version: 0.2.0.0 synopsis: Haskell FFI bindings to libheif license: MIT build-type: Simple@@ -66,7 +66,7 @@ , containers >=0.5 && <1 , hs-bindgen-runtime >=0.1 && <0.2 - pkgconfig-depends: libheif, libde265, kvazaar+ pkgconfig-depends: libheif, libde265, kvazaar, aom c-sources: cbits/heif_context_write_shim.c if arch(wasm32)@@ -86,16 +86,14 @@ import: shared-properties type: exitcode-stdio-1.0 main-is: Main.hs- other-modules: SampleImage hs-source-dirs: test build-depends: , base , bytestring- , containers , directory >=1.3.9 && <2 , hspec >=2.11.17 && <2.12 , libheif-hs , temporary >=1.3 && <2 default-language: GHC2024 - pkgconfig-depends: libheif, libde265, kvazaar+ pkgconfig-depends: libheif, libde265, kvazaar, aom
src/Codec/HEIF.hs view
@@ -6,6 +6,7 @@ DecodeOptions (..), Decoded (..), EncodeOptions (..),+ EncodeFormat (..), EncodeQuality (..), Image (..), Metadata (..),@@ -53,6 +54,7 @@ defaultEncodeOptions = EncodeOptions {..} where eoQuality = Lossy 95+ eoFormat = HEVC -- Decoding -------------------------------- @@ -91,7 +93,7 @@ -- | Same as 'encode' but throws 'HeifException'. encodeThrow :: EncodeOptions -> Decoded -> IO BSL.ByteString encodeThrow EncodeOptions {..} Decoded {..} = withContext $ \context -> do- withEncoder context $ \encoder -> do+ withEncoder context eoFormat $ \encoder -> do encodeQuality eoQuality encoder withRGBImage imageWidth imageHeight $ \writableImage -> do withNewRGBPlane writableImage imageWidth imageHeight $ \plane -> do@@ -106,7 +108,7 @@ -- | Same as 'encodeThrow' but writes to a file. encodeToFileThrow :: EncodeOptions -> FilePath -> Decoded -> IO () encodeToFileThrow EncodeOptions {..} file Decoded {..} = withContext $ \context -> do- withEncoder context $ \encoder -> do+ withEncoder context eoFormat $ \encoder -> do encodeQuality eoQuality encoder withRGBImage imageWidth imageHeight $ \writableImage -> do withNewRGBPlane writableImage imageWidth imageHeight $ \plane -> do
src/Codec/HEIF/Bindings.hs view
@@ -12,6 +12,7 @@ Encoder (..), EncodeQuality (..), EncodeOptions (..),+ EncodeFormat (..), DecodeOptions (..), heifVersion, withContext,@@ -66,9 +67,17 @@ doConvertHDRTo8Bit :: Bool } -newtype EncodeOptions+data EncodeFormat+ = -- | Format of .avif files+ AV1+ | -- | Format of .heic files+ HEVC+ deriving (Show)++data EncodeOptions = EncodeOptions- { eoQuality :: EncodeQuality+ { eoQuality :: EncodeQuality,+ eoFormat :: EncodeFormat } constNullPtr :: Bindgen.PtrConst a@@ -170,14 +179,18 @@ HeifImage . Bindgen.unsafeFromPtr <$> Foreign.peek imageOutPtr release (HeifImage ptr) = HEIF.heif_image_release ptr -withEncoder :: Context -> (Encoder -> IO a) -> IO a-withEncoder (Context contextPtr) = bracket acquire release+formatToC :: EncodeFormat -> HEIF.Heif_compression_format+formatToC AV1 = HEIF.Heif_compression_AV1+formatToC HEVC = HEIF.Heif_compression_HEVC++withEncoder :: Context -> EncodeFormat -> (Encoder -> IO a) -> IO a+withEncoder (Context contextPtr) format = bracket acquire release where acquire = Foreign.alloca $ \encoderOutPtr -> do throwIfError $ HEIF.heif_context_get_encoder_for_format contextPtr- HEIF.Heif_compression_HEVC+ (formatToC format) encoderOutPtr Encoder <$> Foreign.peek encoderOutPtr release (Encoder ptr) = HEIF.heif_encoder_release ptr@@ -213,6 +226,25 @@ } deriving (Show, Eq) +copy2D ::+ Foreign.Ptr Bindgen.Word8 -> -- destination+ Int -> -- destination stride+ Foreign.Ptr Bindgen.Word8 -> -- source+ Int -> -- stride+ Int -> -- rowBytes+ Int -> -- height+ IO ()+copy2D dstPtr dstStride srcPtr srcStride rowBytes height+ | dstStride == rowBytes && srcStride == rowBytes =+ copyBytes dstPtr srcPtr (rowBytes * height)+ | otherwise =+ mapM_ copyRow [0 .. height - 1]+ where+ copyRow y = do+ let srcRow = srcPtr `plusPtr` (y * srcStride)+ dstRow = dstPtr `plusPtr` (y * dstStride)+ copyBytes dstRow srcRow rowBytes+ extractImageData :: HeifImage -> IO Image extractImageData (HeifImage imgPtr) = Foreign.alloca $ \strideOutPtr -> do rawPlanePtr <-@@ -224,24 +256,23 @@ heightCInt <- HEIF.heif_image_get_height imgPtr HEIF.Heif_channel_interleaved widthCInt <- HEIF.heif_image_get_width imgPtr HEIF.Heif_channel_interleaved - let stride = fromIntegral strideCSize :: Int- imageHeight :: Natural = fromIntegral heightCInt- imageWidth :: Natural = fromIntegral widthCInt- rowBytes = imageWidth * 3 -- 3 bytes per pixel for RGB- totalExpectedBytes = rowBytes * imageHeight- sourcePtr = Foreign.castPtr (Bindgen.unsafeToPtr rawPlanePtr)-- -- Allocate exactly the memory needed for the final contiguous ByteString- imagePixelsRGB <- BSI.create (fromIntegral totalExpectedBytes) $ \destinationPtr ->- mapM_- ( \row -> do- let currentSrcRow = sourcePtr `plusPtr` (row * stride)- currentDestRow = destinationPtr `plusPtr` (row * fromIntegral rowBytes)- copyBytes currentDestRow currentSrcRow $ fromIntegral rowBytes- )- [0 .. fromIntegral imageHeight - 1]+ let stride = fromIntegral strideCSize+ imageWidth = fromIntegral widthCInt+ imageHeight = fromIntegral heightCInt+ rgbWidth = w * 3+ expectedSize = rgbWidth * h+ w = fromIntegral imageWidth+ h = fromIntegral imageHeight - pure $ Image {..}+ imagePixelsRGB <- BSI.create expectedSize $ \destinationPtr -> do+ copy2D+ destinationPtr+ rgbWidth+ (Foreign.castPtr (Bindgen.unsafeToPtr rawPlanePtr))+ stride+ rgbWidth+ h+ pure Image {..} data MetadataType = Exif | Mime | OtherMetadataType String deriving (Show, Eq)@@ -372,22 +403,15 @@ infoHeight = planeHeight, gotBytes = fromIntegral dataLength }- | planeStride == rgbWidth = copyFast- | otherwise = copyStrided+ | otherwise =+ BSU.unsafeUseAsCStringLen rgbData $ \(srcPtr, _) ->+ copy2D planePtr planeStride (Foreign.castPtr srcPtr) rgbWidth rgbWidth h where w = fromIntegral planeWidth :: Int h = fromIntegral planeHeight :: Int rgbWidth = w * 3 expectedSize = rgbWidth * h dataLength = BS.length rgbData- copyFast = BSU.unsafeUseAsCStringLen rgbData $ \(sourcePtr, len) ->- copyBytes planePtr (Foreign.castPtr sourcePtr) len- copyStrided = BSU.unsafeUseAsCStringLen rgbData $ \(srcPtr, _) -> do- mapM_ (copyRow srcPtr) [0 .. h - 1]- copyRow srcBytePtr y = do- let srcRow = srcBytePtr `plusPtr` (y * rgbWidth)- dstRow = planePtr `plusPtr` (y * planeStride)- copyBytes dstRow srcRow rgbWidth withEncodeImage :: Context -> WritableImage -> Encoder -> (WritableImageHandle -> IO a) -> IO a
test/Main.hs view
@@ -4,10 +4,7 @@ import Codec.HEIF import Control.Monad-import Data.ByteString qualified as BS import Data.ByteString.Lazy qualified as BSL-import Data.Map qualified as M-import SampleImage import System.Directory (doesFileExist) import System.IO.Temp (withSystemTempFile) import Test.Hspec@@ -15,79 +12,39 @@ main :: IO () main = hspec spec -inWasm :: Bool-#if defined(__wasm32__) || defined(__wasm__) || defined(wasm32_HOST_ARCH)-inWasm = True-#else-inWasm = False-#endif- isHEIFException :: HeifError -> HeifSubError -> HeifException -> Bool isHEIFException expectedCode expectedSubcode (LibraryException (Library {..})) = code == expectedCode && subcode == expectedSubcode isHEIFException _ _ _ = False --- wasm has a virtual file system, some test steps are not executed there-itOnNative :: String -> Expectation -> Spec-itOnNative label test = it label $ do- when inWasm $ pendingWith "Test not supported on WASM target"- test- spec :: Spec spec = describe "libheif-hs tests" $ do describe "HEIF library inclusion" $ do- it "The linked library version is 1.23.1" $ do+ it "The linked library version is non empty" $ do x <- heifVersion- x `shouldBe` "1.23.1"+ x `shouldNotBe` "" describe "Image RGB decoding" $ do it "Fails with an empty image" $ do decodeThrow defaultDecodeOptions mempty `shouldThrow` isHEIFException HeifErrorInvalidInput HeifSubErrorUnspecified- itOnNative "Can decode a HEIC file to raw RGB pixels and metadata" $ do- let testFile = "./samples/heic-100x100.heic"- exists <- doesFileExist testFile- exists `shouldBe` True- Decoded {..} <- decodeFromFileThrow defaultDecodeOptions testFile- let Image {..} = decodedImage- expectedWidth = 100- expectedHeight = 100- imageWidth `shouldBe` expectedWidth- imageHeight `shouldBe` expectedHeight- it "Can decode HEIC file ByteString to raw RGB pixels and metadata" $ do- Decoded {..} <- decodeThrow defaultDecodeOptions sampleHEICFile- let Image {..} = decodedImage- expectedWidth = 100- expectedHeight = 100- imageWidth `shouldBe` expectedWidth- imageHeight `shouldBe` expectedHeight- BS.length imagePixelsRGB `shouldBe` fromIntegral (expectedWidth * expectedHeight * 3)- BS.unpack (BS.take 10 imagePixelsRGB)- `shouldBe` [59, 130, 246, 59, 130, 246, 59, 130, 246, 59]-- let Metadata {..} = decodedMetadata- length metadataBlocks `shouldBe` 1- case M.toList metadataBlocks of- [(_, MetadataBlock {..})] -> do- metadataBlockType `shouldBe` Exif- BS.take 4 metadataBlockData `shouldBe` "Exif"- _ -> pure ()- it "Can decode encoded HEIC file" $ do- decoded <- decodeThrow defaultDecodeOptions sampleHEICFile- encoded <- encodeThrow defaultEncodeOptions decoded- decoded' <- decodeThrow defaultDecodeOptions $ BSL.toStrict encoded- decodedMetadata decoded `shouldBe` decodedMetadata decoded'- let image = decodedImage decoded- image' = decodedImage decoded'- compareNumberOfBytes = 10- imageWidth image `shouldBe` imageWidth image'- imageHeight image `shouldBe` imageHeight image'- -- The sample image contains solid colors in the beginning so we can compare only the first- -- part of the image, otherwise because of compression/decompression differences the RGB- -- data is not be byte-to-byte identical- BS.take compareNumberOfBytes (imagePixelsRGB image)- `shouldBe` BS.take compareNumberOfBytes (imagePixelsRGB image')- itOnNative "Can encode HEIC to file" $ do- withSystemTempFile "test.heic" $ \testFile _ -> do- decoded <- decodeThrow defaultDecodeOptions sampleHEICFile- encodeToFileThrow defaultEncodeOptions testFile decoded- doesFileExist testFile >>= (`shouldBe` True)+ forM_+ [ (HEVC, "./samples/heic-100x100.heic"),+ (AV1, "./samples/01-blue-sky.avif")+ ]+ $ \(format, sampleFile) ->+ describe (unwords [show format, "format"]) $ do+ it "Can decode file" $ do+ doesFileExist sampleFile >>= (`shouldBe` True)+ decoded <- decodeFromFileThrow defaultDecodeOptions sampleFile+ encoded <- encodeThrow defaultEncodeOptions {eoFormat = format} decoded+ decoded' <- decodeThrow defaultDecodeOptions $ BSL.toStrict encoded+ decodedMetadata decoded `shouldBe` decodedMetadata decoded'+ let image = decodedImage decoded+ image' = decodedImage decoded'+ imageWidth image `shouldBe` imageWidth image'+ imageHeight image `shouldBe` imageHeight image'+ it "Can encode to file" $ do+ withSystemTempFile "test-libheif-hs" $ \testFile _ -> do+ decoded <- decodeFromFileThrow defaultDecodeOptions sampleFile+ encodeToFileThrow defaultEncodeOptions {eoFormat = format} testFile decoded+ doesFileExist testFile >>= (`shouldBe` True)
− test/SampleImage.hs
@@ -1,1368 +0,0 @@-module SampleImage (sampleHEICFile) where--import Data.ByteString qualified as BS--sampleHEICFile :: BS.ByteString-sampleHEICFile =- BS.pack- [ 0x00,- 0x00,- 0x00,- 0x24,- 0x66,- 0x74,- 0x79,- 0x70,- 0x68,- 0x65,- 0x69,- 0x63,- 0x00,- 0x00,- 0x00,- 0x00,- 0x6d,- 0x69,- 0x66,- 0x31,- 0x4d,- 0x69,- 0x50,- 0x72,- 0x6d,- 0x69,- 0x61,- 0x66,- 0x4d,- 0x69,- 0x48,- 0x42,- 0x68,- 0x65,- 0x69,- 0x63,- 0x00,- 0x00,- 0x01,- 0xc2,- 0x6d,- 0x65,- 0x74,- 0x61,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x21,- 0x68,- 0x64,- 0x6c,- 0x72,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x70,- 0x69,- 0x63,- 0x74,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x24,- 0x64,- 0x69,- 0x6e,- 0x66,- 0x00,- 0x00,- 0x00,- 0x1c,- 0x64,- 0x72,- 0x65,- 0x66,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x01,- 0x00,- 0x00,- 0x00,- 0x0c,- 0x75,- 0x72,- 0x6c,- 0x20,- 0x00,- 0x00,- 0x00,- 0x01,- 0x00,- 0x00,- 0x00,- 0x0e,- 0x70,- 0x69,- 0x74,- 0x6d,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x01,- 0x00,- 0x00,- 0x00,- 0x38,- 0x69,- 0x69,- 0x6e,- 0x66,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x02,- 0x00,- 0x00,- 0x00,- 0x15,- 0x69,- 0x6e,- 0x66,- 0x65,- 0x02,- 0x00,- 0x00,- 0x00,- 0x00,- 0x01,- 0x00,- 0x00,- 0x68,- 0x76,- 0x63,- 0x31,- 0x00,- 0x00,- 0x00,- 0x00,- 0x15,- 0x69,- 0x6e,- 0x66,- 0x65,- 0x02,- 0x00,- 0x00,- 0x01,- 0x00,- 0x02,- 0x00,- 0x00,- 0x45,- 0x78,- 0x69,- 0x66,- 0x00,- 0x00,- 0x00,- 0x00,- 0x1a,- 0x69,- 0x72,- 0x65,- 0x66,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x0e,- 0x63,- 0x64,- 0x73,- 0x63,- 0x00,- 0x02,- 0x00,- 0x01,- 0x00,- 0x01,- 0x00,- 0x00,- 0x00,- 0xe5,- 0x69,- 0x70,- 0x72,- 0x70,- 0x00,- 0x00,- 0x00,- 0xc4,- 0x69,- 0x70,- 0x63,- 0x6f,- 0x00,- 0x00,- 0x00,- 0x13,- 0x63,- 0x6f,- 0x6c,- 0x72,- 0x6e,- 0x63,- 0x6c,- 0x78,- 0x00,- 0x02,- 0x00,- 0x02,- 0x00,- 0x06,- 0x80,- 0x00,- 0x00,- 0x00,- 0x0c,- 0x63,- 0x6c,- 0x6c,- 0x69,- 0x00,- 0xcb,- 0x00,- 0x40,- 0x00,- 0x00,- 0x00,- 0x14,- 0x69,- 0x73,- 0x70,- 0x65,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x64,- 0x00,- 0x00,- 0x00,- 0x64,- 0x00,- 0x00,- 0x00,- 0x09,- 0x69,- 0x72,- 0x6f,- 0x74,- 0x00,- 0x00,- 0x00,- 0x00,- 0x10,- 0x70,- 0x69,- 0x78,- 0x69,- 0x00,- 0x00,- 0x00,- 0x00,- 0x03,- 0x08,- 0x08,- 0x08,- 0x00,- 0x00,- 0x00,- 0x70,- 0x68,- 0x76,- 0x63,- 0x43,- 0x01,- 0x03,- 0x70,- 0x00,- 0x00,- 0x00,- 0xb0,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x1e,- 0xf0,- 0x00,- 0xfc,- 0xfd,- 0xf8,- 0xf8,- 0x00,- 0x00,- 0x0b,- 0x03,- 0xa0,- 0x00,- 0x01,- 0x00,- 0x17,- 0x40,- 0x01,- 0x0c,- 0x01,- 0xff,- 0xff,- 0x03,- 0x70,- 0x00,- 0x00,- 0x03,- 0x00,- 0xb0,- 0x00,- 0x00,- 0x03,- 0x00,- 0x00,- 0x03,- 0x00,- 0x1e,- 0x70,- 0x24,- 0xa1,- 0x00,- 0x01,- 0x00,- 0x22,- 0x42,- 0x01,- 0x01,- 0x03,- 0x70,- 0x00,- 0x00,- 0x03,- 0x00,- 0xb0,- 0x00,- 0x00,- 0x03,- 0x00,- 0x00,- 0x03,- 0x00,- 0x1e,- 0xa0,- 0x14,- 0x20,- 0x71,- 0xc3,- 0xf3,- 0xe2,- 0x1e,- 0xe4,- 0x59,- 0x54,- 0xdc,- 0x08,- 0x08,- 0x18,- 0x02,- 0xa2,- 0x00,- 0x01,- 0x00,- 0x09,- 0x44,- 0x01,- 0xc0,- 0x61,- 0x72,- 0xc8,- 0x44,- 0x53,- 0x64,- 0x00,- 0x00,- 0x00,- 0x19,- 0x69,- 0x70,- 0x6d,- 0x61,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x01,- 0x00,- 0x01,- 0x06,- 0x81,- 0x02,- 0x03,- 0x84,- 0x05,- 0x86,- 0x00,- 0x00,- 0x00,- 0x2c,- 0x69,- 0x6c,- 0x6f,- 0x63,- 0x00,- 0x00,- 0x00,- 0x00,- 0x44,- 0x00,- 0x00,- 0x02,- 0x00,- 0x01,- 0x00,- 0x00,- 0x00,- 0x01,- 0x00,- 0x00,- 0x02,- 0x42,- 0x00,- 0x00,- 0x03,- 0x0e,- 0x00,- 0x02,- 0x00,- 0x00,- 0x00,- 0x01,- 0x00,- 0x00,- 0x01,- 0xf6,- 0x00,- 0x00,- 0x00,- 0x4c,- 0x00,- 0x00,- 0x00,- 0x01,- 0x6d,- 0x64,- 0x61,- 0x74,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x03,- 0x6a,- 0x00,- 0x00,- 0x00,- 0x06,- 0x45,- 0x78,- 0x69,- 0x66,- 0x00,- 0x00,- 0x4d,- 0x4d,- 0x00,- 0x2a,- 0x00,- 0x00,- 0x00,- 0x08,- 0x00,- 0x03,- 0x01,- 0x1a,- 0x00,- 0x05,- 0x00,- 0x00,- 0x00,- 0x01,- 0x00,- 0x00,- 0x00,- 0x32,- 0x01,- 0x1b,- 0x00,- 0x05,- 0x00,- 0x00,- 0x00,- 0x01,- 0x00,- 0x00,- 0x00,- 0x3a,- 0x01,- 0x28,- 0x00,- 0x03,- 0x00,- 0x00,- 0x00,- 0x01,- 0x00,- 0x02,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x00,- 0x48,- 0x00,- 0x00,- 0x00,- 0x01,- 0x00,- 0x00,- 0x00,- 0x48,- 0x00,- 0x00,- 0x00,- 0x01,- 0x00,- 0x00,- 0x03,- 0x0a,- 0x28,- 0x01,- 0xaf,- 0x90,- 0x50,- 0x39,- 0x68,- 0x01,- 0x10,- 0x46,- 0x81,- 0x7c,- 0xff,- 0xec,- 0x0f,- 0xeb,- 0xfe,- 0xa9,- 0x7f,- 0xff,- 0xdd,- 0xf3,- 0x8f,- 0xb1,- 0x6f,- 0xd9,- 0xe6,- 0xb1,- 0xa2,- 0x5f,- 0x95,- 0xff,- 0xf7,- 0x47,- 0xad,- 0xfe,- 0x03,- 0x7d,- 0x22,- 0x7a,- 0x46,- 0x69,- 0xa7,- 0xd3,- 0xc3,- 0x84,- 0xa9,- 0xeb,- 0x60,- 0x93,- 0xbf,- 0xd3,- 0xd3,- 0xe0,- 0x17,- 0x26,- 0x5e,- 0x48,- 0x85,- 0xf9,- 0xf5,- 0x03,- 0xd0,- 0xac,- 0x47,- 0xec,- 0x09,- 0x8c,- 0x8b,- 0x08,- 0x81,- 0x07,- 0x41,- 0x5b,- 0xd5,- 0xc0,- 0xb3,- 0x9d,- 0x90,- 0x96,- 0xd4,- 0x95,- 0x5c,- 0xe9,- 0x79,- 0x8f,- 0x7a,- 0x8a,- 0x22,- 0xe0,- 0x21,- 0xb3,- 0x7d,- 0xa8,- 0xe6,- 0xa8,- 0xb5,- 0x7d,- 0x4d,- 0xe2,- 0x5f,- 0xea,- 0x9c,- 0xc7,- 0x03,- 0x84,- 0xb6,- 0x0b,- 0x99,- 0x4e,- 0xe6,- 0xb7,- 0xc3,- 0x93,- 0x60,- 0x60,- 0xd2,- 0x65,- 0x97,- 0x56,- 0x01,- 0xa0,- 0xc3,- 0xf7,- 0x14,- 0xbd,- 0xcd,- 0xd5,- 0xd2,- 0xf0,- 0x8d,- 0xd3,- 0x76,- 0xf5,- 0x4c,- 0x37,- 0x2a,- 0xe0,- 0x57,- 0x7f,- 0xdf,- 0xd6,- 0x92,- 0xee,- 0x57,- 0x7f,- 0x1b,- 0x26,- 0x31,- 0xbd,- 0x6d,- 0xa0,- 0x04,- 0xca,- 0x30,- 0x5d,- 0x51,- 0x83,- 0x97,- 0x97,- 0x04,- 0x45,- 0xd3,- 0x13,- 0x30,- 0x5e,- 0xd3,- 0x72,- 0xa5,- 0xa2,- 0x9b,- 0x6b,- 0x4a,- 0x03,- 0xea,- 0x98,- 0x5a,- 0xca,- 0xdf,- 0x1d,- 0xe3,- 0x78,- 0x27,- 0x9f,- 0x8d,- 0xa6,- 0xa8,- 0x82,- 0xc5,- 0xef,- 0xce,- 0x35,- 0x09,- 0xa7,- 0xab,- 0x52,- 0x6d,- 0xd9,- 0xdd,- 0x2c,- 0xc6,- 0x7c,- 0xe4,- 0xdb,- 0x2b,- 0x0c,- 0x4b,- 0x06,- 0xf7,- 0xdc,- 0x0e,- 0x4a,- 0x78,- 0x07,- 0xdb,- 0x95,- 0x9d,- 0x36,- 0x71,- 0xf5,- 0x60,- 0xf9,- 0x8f,- 0x96,- 0xbe,- 0xa0,- 0x8c,- 0x56,- 0xe0,- 0x68,- 0x92,- 0x67,- 0xff,- 0x37,- 0xeb,- 0x43,- 0x69,- 0x6a,- 0x8f,- 0x04,- 0xc0,- 0xad,- 0x8e,- 0x1f,- 0xec,- 0x25,- 0xfe,- 0x5c,- 0xcc,- 0x84,- 0x29,- 0x78,- 0x17,- 0x60,- 0x34,- 0x87,- 0xe8,- 0xaf,- 0x30,- 0x8d,- 0xd8,- 0xa2,- 0x50,- 0x30,- 0x0b,- 0x88,- 0x10,- 0x69,- 0x10,- 0x35,- 0x04,- 0xfe,- 0x16,- 0xf1,- 0xe2,- 0xff,- 0x90,- 0x9c,- 0x9e,- 0xe1,- 0x1c,- 0x4d,- 0x4d,- 0x5a,- 0x16,- 0x9a,- 0x5a,- 0x53,- 0xd7,- 0x96,- 0x54,- 0xea,- 0x73,- 0xe9,- 0x3a,- 0x80,- 0x17,- 0x89,- 0x43,- 0xc8,- 0x76,- 0xfe,- 0x47,- 0xb5,- 0xe4,- 0xd9,- 0x87,- 0x86,- 0x3a,- 0xd2,- 0xe6,- 0x92,- 0x87,- 0xb3,- 0x94,- 0x63,- 0xc6,- 0xc1,- 0xf8,- 0x75,- 0x36,- 0xaf,- 0xf8,- 0x92,- 0x2b,- 0xa6,- 0x29,- 0x88,- 0x1b,- 0x5f,- 0x80,- 0x0d,- 0x8a,- 0xe6,- 0xfe,- 0x92,- 0xf9,- 0x6a,- 0x92,- 0x45,- 0x9d,- 0xd6,- 0xb2,- 0x4b,- 0x90,- 0x02,- 0x27,- 0x02,- 0x2d,- 0x39,- 0x3a,- 0xf5,- 0x9a,- 0x60,- 0xac,- 0xe4,- 0xe4,- 0x14,- 0x0d,- 0x55,- 0xfd,- 0x69,- 0x3a,- 0xe5,- 0x1d,- 0xfa,- 0xf9,- 0x3e,- 0xa2,- 0x8a,- 0x9b,- 0xda,- 0x20,- 0xf3,- 0xca,- 0x92,- 0x65,- 0x27,- 0x07,- 0xe3,- 0xe5,- 0x77,- 0x77,- 0xbf,- 0xfd,- 0x41,- 0xb7,- 0xff,- 0x31,- 0x69,- 0xed,- 0x37,- 0x8a,- 0x0a,- 0x01,- 0x56,- 0x32,- 0x37,- 0xb4,- 0x1c,- 0x51,- 0x6b,- 0x62,- 0x89,- 0x66,- 0x74,- 0x4a,- 0x28,- 0x8a,- 0x1b,- 0xf9,- 0x04,- 0x0d,- 0x89,- 0xe7,- 0x4a,- 0xd2,- 0xd0,- 0x72,- 0xd7,- 0xb3,- 0xa9,- 0xe9,- 0x0a,- 0x1f,- 0xbf,- 0x24,- 0x56,- 0x90,- 0xdc,- 0xb5,- 0x47,- 0x67,- 0x82,- 0x3d,- 0x4a,- 0xd6,- 0xfb,- 0x89,- 0x4a,- 0xf0,- 0x7e,- 0xef,- 0xb0,- 0x33,- 0x60,- 0x10,- 0x69,- 0xc4,- 0xdb,- 0x9c,- 0xf7,- 0xa3,- 0xe5,- 0xc4,- 0x1f,- 0xdf,- 0x08,- 0xc2,- 0x8a,- 0xcd,- 0x39,- 0xea,- 0x72,- 0xef,- 0xf3,- 0x73,- 0x6b,- 0x73,- 0xaa,- 0x99,- 0xc5,- 0x56,- 0xaf,- 0x9a,- 0x24,- 0x51,- 0x2c,- 0xe9,- 0xe2,- 0xa0,- 0xef,- 0xd9,- 0xd0,- 0x9b,- 0x3b,- 0xfd,- 0x9f,- 0xe3,- 0xd2,- 0x9f,- 0xff,- 0xf7,- 0x37,- 0x87,- 0xa7,- 0x00,- 0x34,- 0x9a,- 0x12,- 0xc6,- 0xa1,- 0xbb,- 0xd5,- 0xe2,- 0x5f,- 0xc8,- 0xb7,- 0x39,- 0x3a,- 0x4a,- 0x97,- 0xa7,- 0x26,- 0x97,- 0x42,- 0xae,- 0xf4,- 0xb2,- 0x5b,- 0x3c,- 0xbd,- 0x73,- 0x31,- 0xf7,- 0x91,- 0xff,- 0x22,- 0x4e,- 0xad,- 0x3a,- 0xef,- 0x9a,- 0x11,- 0x16,- 0xf0,- 0xa0,- 0x5e,- 0xdc,- 0xc3,- 0x88,- 0x89,- 0x93,- 0x73,- 0x52,- 0x3c,- 0x25,- 0x22,- 0x5f,- 0xa3,- 0xc8,- 0xce,- 0x37,- 0xf9,- 0xe0,- 0xeb,- 0xd5,- 0x7b,- 0x5f,- 0xe0,- 0x05,- 0x0a,- 0x96,- 0xde,- 0xea,- 0x71,- 0x36,- 0xc2,- 0x0f,- 0xc0,- 0xbb,- 0x4d,- 0xd2,- 0x4b,- 0x16,- 0xa0,- 0x02,- 0xe2,- 0xd0,- 0xca,- 0x0f,- 0x8c,- 0x78,- 0x60,- 0xb7,- 0xd9,- 0x33,- 0x36,- 0xff,- 0xb7,- 0xdc,- 0x38,- 0x8e,- 0x3b,- 0xba,- 0xa6,- 0xb7,- 0xd0,- 0x6c,- 0x94,- 0x1e,- 0x61,- 0x2e,- 0x10,- 0xf7,- 0xe2,- 0x14,- 0x30,- 0x4b,- 0xc4,- 0x97,- 0xa4,- 0x18,- 0x36,- 0x37,- 0xc7,- 0xeb,- 0x81,- 0x7a,- 0x47,- 0x19,- 0x71,- 0x51,- 0xf0,- 0x28,- 0x2d,- 0x54,- 0x7c,- 0xc9,- 0xcc,- 0x25,- 0x3d,- 0xd7,- 0xee,- 0x1a,- 0x32,- 0xcf,- 0x63,- 0x1f,- 0x00,- 0x09,- 0x21,- 0x81,- 0xfe,- 0xac,- 0xcb,- 0x39,- 0x92,- 0x17,- 0x49,- 0x10,- 0x12,- 0xf3,- 0x0b,- 0x66,- 0x78,- 0x37,- 0xd0,- 0x11,- 0x8d,- 0x41,- 0x78,- 0x34,- 0x8e,- 0xfa,- 0x8b,- 0x2a,- 0xcb,- 0x68,- 0xbf,- 0xda,- 0xe4,- 0x3c,- 0x31,- 0xd9,- 0xfe,- 0x77,- 0x6b,- 0x1d,- 0x68,- 0x4c,- 0xab,- 0xdd,- 0xc8,- 0x3c,- 0x45,- 0x28,- 0x76,- 0xf9,- 0xd2,- 0x5f,- 0xd1,- 0xf8,- 0x7b,- 0xfc,- 0x2d,- 0x92,- 0x7f,- 0x18,- 0x52,- 0x25,- 0x40,- 0xff,- 0x60,- 0xfe,- 0x00,- 0xa1,- 0x4d,- 0x43,- 0x1c,- 0xf0,- 0x08,- 0x22,- 0x05,- 0x66,- 0xf7,- 0x05,- 0x58,- 0x95,- 0x7d,- 0x14,- 0x13,- 0x75,- 0x4d,- 0x83,- 0x14,- 0xe2,- 0xf3,- 0xce,- 0xf4,- 0xe2,- 0x35,- 0xde,- 0x8f,- 0x6e,- 0xe2,- 0x68,- 0x2d,- 0xc9,- 0x03,- 0xb0,- 0x17,- 0xfb,- 0x60,- 0xaf,- 0xef,- 0x45,- 0x16,- 0xfd,- 0x7d,- 0xd5,- 0xad,- 0x96,- 0xf3,- 0xc7,- 0xcc,- 0x63,- 0x7b,- 0xa0,- 0x54,- 0xc5,- 0xb2,- 0x46,- 0x23,- 0x2b,- 0xd6,- 0xdf,- 0x60,- 0x48,- 0xdf,- 0x07,- 0x5d,- 0x60,- 0x00,- 0x0c,- 0xf9,- 0xc9,- 0x60- ]