Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 如何将(StorableArray(Int,Int)Word8)转换为lazy ByteString?_Arrays_Haskell_Bytestring - Fatal编程技术网

Arrays 如何将(StorableArray(Int,Int)Word8)转换为lazy ByteString?

Arrays 如何将(StorableArray(Int,Int)Word8)转换为lazy ByteString?,arrays,haskell,bytestring,Arrays,Haskell,Bytestring,我试图加载一个PNG文件,获取未压缩的RGBA字节,然后将它们发送到gzip或zlib包 pngload包以(StorableArray(Int,Int)字8的形式返回图像数据,而压缩包采用lazy ByteStrings。因此,我试图构建一个(StorableArray(Int,Int)Word8->ByteString)函数 到目前为止,我已经尝试了以下方法: import qualified Codec.Image.PNG as PNG import Control.Monad (mapM

我试图加载一个PNG文件,获取未压缩的RGBA字节,然后将它们发送到gzip或zlib包

pngload包以(StorableArray(Int,Int)字8的形式返回图像数据,而压缩包采用lazy ByteStrings。因此,我试图构建一个(StorableArray(Int,Int)Word8->ByteString)函数

到目前为止,我已经尝试了以下方法:

import qualified Codec.Image.PNG as PNG
import Control.Monad (mapM)
import Data.Array.Storable (withStorableArray)
import qualified Data.ByteString.Lazy as LB (ByteString, pack, take)
import Data.Word (Word8)
import Foreign (Ptr, peekByteOff)

main = do
    -- Load PNG into "image"...
    bytes <- withStorableArray 
        (PNG.imageData image)
        (bytesFromPointer lengthOfImageData)

bytesFromPointer :: Int -> Ptr Word8 -> IO LB.ByteString
bytesFromPointer count pointer = LB.pack $ 
    mapM (peekByteOff pointer) [0..(count-1)]
将合格的Codec.Image.PNG导入为PNG
导入控制.Monad(mapM)
导入Data.Array.Storable(使用StorableArray)
将符合条件的Data.ByteString.Lazy导入为LB(ByteString、pack、take)
导入数据。Word(Word8)
进口国外(Ptr、peekByteOff)
main=do
--将PNG加载到“图像”。。。
字节Ptr字8->IO LB.ByteString
bytesFromPointer count指针=LB.pack$
mapM(peekByteOff指针)[0..(计数-1]
这会导致堆栈内存不足,因此很明显我做了一些非常错误的事情。我可以用Ptr和ForeignPtr尝试更多的东西,但是其中有很多“不安全”的功能


任何帮助都将不胜感激;我相当困惑。

一般来说,打包和解包对性能是个坏主意。如果您有一个Ptr,长度以字节为单位,则可以通过两种不同的方式生成strict bytestring:

像这样:

import qualified Codec.Image.PNG as PNG
import Control.Monad
import Data.Array.Storable (withStorableArray)

import Codec.Compression.GZip

import qualified Data.ByteString.Lazy   as L
import qualified Data.ByteString.Unsafe as S

import Data.Word
import Foreign

-- Pack a Ptr Word8 as a strict bytestring, then box it to a lazy one, very
-- efficiently
bytesFromPointer :: Int -> Ptr Word8 -> IO L.ByteString
bytesFromPointer n ptr = do
    s <- S.unsafePackCStringLen (castPtr ptr, n)
    return $! L.fromChunks [s]

-- Dummies, since they were not provided 
image = undefined
lengthOfImageData = 10^3

-- Load a PNG, and compress it, writing it back to disk
main = do
    bytes <- withStorableArray
        (PNG.imageData image)
        (bytesFromPointer lengthOfImageData)
    L.writeFile "foo" . compress $ bytes
将合格的Codec.Image.PNG导入为PNG
进口管制
导入Data.Array.Storable(使用StorableArray)
导入Codec.Compression.GZip
将限定的Data.ByteString.Lazy作为L导入
将限定数据.ByteString.S导入为S
导入数据.Word
进口国外
--将一个PTRWord8打包为一个严格的bytestring,然后将其打包为一个懒惰的,非常
--有效地
bytesFromPointer::Int->Ptr Word8->IO L.ByteString
bytesFromPointer n ptr=do
s您的“bytesFromPointer”的问题在于,您从pngload中获取压缩表示形式,即StorableArray,并且希望通过中间列表将其转换为另一个压缩表示形式,即ByteString。有时懒惰意味着中间列表不会在内存中构建,但这里的情况并非如此

“mapM”是初犯。如果展开
mapM(peekByteOff指针)[0..(计数-1)]

el0 <- peekByteOff pointer 0
el1 <- peekByteOff pointer 1
el2 <- peekByteOff pointer 2
...
eln <- peekByteOff pointer (count-1)
return [el0,el1,el2,...eln]
el0