Created
September 13, 2021 18:40
-
-
Save IltaySaeedi/3e1971eb562d345d30e30be7610d054b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#r "nuget: ply" | |
open System | |
open FSharp.Control.Tasks | |
open System.Threading.Tasks | |
let bigEndianUInt32 (data : Span<byte>) = | |
let mutable total = 0u | |
if data.Length = 4 then | |
for i = 0 to 3 do | |
let value = data.[i] | |
let shiftNum = 3 - i | |
total <- total + | |
((uint (value / 16uy)) <<< (shiftNum * 8 + 4)) + | |
((uint (value % 16uy)) <<< (shiftNum * 8)) | |
Some total | |
else | |
None | |
let dataArray = [| | |
0x89uy; 0x50uy; 0x4euy; 0x47uy; 0x0duy; 0x0auy; 0x1auy; 0x0auy; | |
0x00uy; 0x00uy; 0x00uy; 0x0duy; 0x49uy; 0x48uy; 0x44uy; 0x52uy; | |
0x00uy; 0x00uy; 0x02uy; 0x00uy; 0x00uy; 0x00uy; 0x02uy; 0x00uy; | |
0x08uy; 0x06uy; 0x00uy; 0x00uy; 0x00uy; 0xf4uy; 0x78uy; 0xd4uy; | |
0xfauy | |
|] | |
let sign = | |
use data = new IO.MemoryStream(dataArray) | |
task { | |
let c = Threading.CancellationToken() | |
let signMemory = Memory<byte>(Array.zeroCreate 8) | |
let chunkLength = Memory<byte>(Array.zeroCreate 4) | |
let chunkType = Memory<byte>(Array.zeroCreate 4) | |
let! _ = data.ReadAsync(signMemory, c) | |
let mutable position = ValueTask<int>(0) | |
if (signMemory.ToArray() = | |
[|137uy; 80uy; 78uy; 71uy; 13uy; 10uy; 26uy; 10uy|]) then | |
// Which one? | |
let! _ = data.ReadAsync(chunkLength, c) | |
do position <- data.ReadAsync(chunkType, c) | |
let chunkLength = chunkLength.Span | |
let ihdrLength = bigEndianUInt32 chunkLength | |
match ihdrLength, chunkType.ToArray() with | |
| Some 13u, [| 73uy; 72uy; 68uy; 82uy|] -> | |
let chunkData = Memory<byte>(Array.zeroCreate (int 13)) | |
let! ihdrData = data.ReadAsync(chunkData, c) | |
let ihdrSpan = | |
chunkData.Span | |
let width = bigEndianUInt32 (ihdrSpan.Slice(0,4)) | |
let height = bigEndianUInt32 (ihdrSpan.Slice(4,4)) | |
return width, height | |
| _ -> | |
return None, None | |
else | |
return None, None | |
} | |
|> Async.AwaitTask | |
|> Async.RunSynchronously |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment