Skip to content

Instantly share code, notes, and snippets.

@sayurin
Last active April 9, 2023 09:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sayurin/66338344b6a848a6bac6fbffedb98189 to your computer and use it in GitHub Desktop.
Save sayurin/66338344b6a848a6bac6fbffedb98189 to your computer and use it in GitHub Desktop.
module Sayuri.Drawing.Png
open FSharp.NativeInterop
open System
open System.Buffers
open System.Buffers.Binary
open System.Drawing
open System.Drawing.Imaging
open System.IO
open System.IO.Compression
open System.IO.Hashing
open System.Numerics
open System.Runtime.Intrinsics
open System.Runtime.Intrinsics.X86
#nowarn "9"
let private read (bitmap : Bitmap) bytes =
let bitmapData = BitmapData(Width = bitmap.Width, Height = bitmap.Height, Stride = bitmap.Width * 4, PixelFormat = PixelFormat.Format32bppArgb, Scan0 = bytes)
bitmap.LockBits(Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly ||| ImageLockMode.UserInputBuffer, PixelFormat.Format32bppArgb, bitmapData) |> bitmap.UnlockBits
let private relocateIndexed sbytes dbytes pbytes palette4 width height =
NativePtr.write (NativePtr.ofNativeInt pbytes) 0uy
let mutable sptr = sbytes
let mutable dptr = dbytes
let mutable pptr = pbytes + 3n
let mutable colors = 0n
while sptr < sbytes + width * height * 4n && colors < 256 do
NativePtr.write (NativePtr.ofNativeInt dptr) 0uy
dptr <- dptr + 1n
let send = sptr + width * 4n
while sptr < send && colors < 256 do
let mutable index = 0n
do
let pixel = NativePtr.read (NativePtr.ofNativeInt sptr)
let alpha = pixel &&& 0xFF000000u
if alpha = 0x00000000u then () else
if alpha <> 0xFF000000u then colors <- 256 else
while index <= colors && palette4 + index * 4n |> NativePtr.ofNativeInt |> NativePtr.read <> pixel do
index <- index + 1n
if index <= colors then () else
colors <- colors + 1n
if colors = 256 then () else
NativePtr.write (palette4 + colors * 4n |> NativePtr.ofNativeInt) pixel
NativePtr.write (NativePtr.ofNativeInt pptr) (BinaryPrimitives.ReverseEndianness pixel >>> 8) // BGRA to RGB0, 1byte overflow.
pptr <- pptr + 3n
NativePtr.write (NativePtr.ofNativeInt dptr) (byte index)
sptr <- sptr + 4n
dptr <- dptr + 1n
colors < 256
let private relocateAvx2 stride height sbytes dbytes =
let index = Vector256.Create(0x07_04_05_06_03_00_01_02uL, 0x0F_0C_0D_0E_0B_08_09_0AuL, 0x07_04_05_06_03_00_01_02uL, 0x0F_0C_0D_0E_0B_08_09_0AuL).AsByte()
let mutable sptr = sbytes
let mutable dptr = dbytes
while sptr < sbytes + stride * height do
NativePtr.write (NativePtr.ofNativeInt dptr) 0uy
dptr <- dptr + 1n
let sbegin = sptr
let dbegin = dptr
while sptr < sbegin + (stride + nativeint Vector256<byte>.Count - 1n &&& nativeint -Vector256<byte>.Count) do
Vector256.Store(Avx2.Shuffle(NativePtr.ofNativeInt sptr |> Vector256.Load, index), NativePtr.ofNativeInt dptr)
sptr <- sptr + nativeint Vector256<byte>.Count
dptr <- dptr + nativeint Vector256<byte>.Count
sptr <- sbegin + stride
dptr <- dbegin + stride
let private relocateManaged stride height sbytes dbytes =
let mutable sptr = sbytes
let mutable dptr = dbytes
while sptr < sbytes + stride * height do
NativePtr.write (NativePtr.ofNativeInt dptr) 0uy
dptr <- dptr + 1n
let sbegin = sptr
while sptr < sbegin + stride do
let pixel = NativePtr.ofNativeInt sptr |> NativePtr.read
NativePtr.write (NativePtr.ofNativeInt dptr) (pixel &&& 0xFF00FF00u ||| BitOperations.RotateLeft(pixel &&& 0x00FF00FFu, 16))
sptr <- sptr + 4n
dptr <- dptr + 4n
let private compress width height bpp sbytes dbytes dlength =
let compressed = new UnmanagedMemoryStream(NativePtr.ofNativeInt dbytes, 0L, int64 dlength, FileAccess.Write)
do use compressor = new ZLibStream(compressed, CompressionLevel.Fastest, true) in compressor.Write(ReadOnlySpan(NativePtr.ofNativeInt<byte> sbytes |> NativePtr.toVoidPtr, (width * bpp + 1) * height))
int compressed.Length
let private write path (width : int) (height : int) idat length plte =
let colourType, chunks =
match plte with
| Some plte -> 3uy, [| "PLTE"B, Choice2Of2 (plte, 256 * 3); "tRNS"B, Choice1Of2 [| 0uy |] |]
| None -> 6uy, [| |]
let ihdr = [|
yield! BitConverter.GetBytes width |> Array.rev
yield! BitConverter.GetBytes height |> Array.rev
8uy // Bit depth
colourType // Indexed-colour or Truecolour with alpha
0uy // Compression method
0uy // Filter method
0uy // Interlace method
|]
use stream = File.Create path
stream.Write "\x89PNG\r\n\x1A\n"B
for typ_, data in [| "IHDR"B, Choice1Of2 ihdr; yield! chunks; "IDAT"B, Choice2Of2 (idat, length); "IEND"B, Choice1Of2 [||] |] do
let data =
match data with
| Choice1Of2 data -> ReadOnlySpan data
| Choice2Of2 (ptr, length) -> ReadOnlySpan(NativePtr.ofNativeInt<byte> ptr |> NativePtr.toVoidPtr, length)
let crc32 = Crc32()
stream.Write(ReadOnlySpan(BitConverter.GetBytes data.Length |> Array.rev))
stream.Write typ_
crc32.Append typ_
stream.Write data
crc32.Append data
stream.Write(ReadOnlySpan(crc32.GetCurrentHash() |> Array.rev))
let encode path (bitmap : Bitmap) =
use pool1 = MemoryPool<byte>.Shared.Rent (bitmap.Width * 4 * bitmap.Height)
use pool2 = MemoryPool<byte>.Shared.Rent ((bitmap.Width * 4 + 1) * bitmap.Height + 32)
use pin1 = pool1.Memory.Pin()
use pin2 = pool2.Memory.Pin()
let bytes1 = NativePtr.ofVoidPtr<byte> pin1.Pointer |> NativePtr.toNativeInt
let bytes2 = NativePtr.ofVoidPtr<byte> pin2.Pointer |> NativePtr.toNativeInt
let bytes3 = NativePtr.stackalloc<byte> (256 * 3 + 1) |> NativePtr.toNativeInt
read bitmap bytes1
let bpp, palette =
let palette4 = NativePtr.stackalloc<uint32> 256
if relocateIndexed bytes1 bytes2 bytes3 (NativePtr.toNativeInt palette4) (nativeint bitmap.Width) (nativeint bitmap.Height) then 1, Some bytes3 else
if Vector256.IsHardwareAccelerated && Avx2.IsSupported then
relocateAvx2 (nativeint (bitmap.Width * 4)) (nativeint bitmap.Height) bytes1 bytes2
else
relocateManaged (nativeint (bitmap.Width * 4)) (nativeint bitmap.Height) bytes1 bytes2
4, None
let compressedLength = compress bitmap.Width bitmap.Height bpp bytes2 bytes1 pool1.Memory.Length
write path bitmap.Width bitmap.Height bytes1 compressedLength palette
; Assembly listing for method Sayuri.Drawing.Png:relocateAvx2(long,long,long,long)
; Emitting BLENDED_CODE for X64 CPU with AVX - Windows
; Tier-0 compilation
; MinOpts code
; rbp based frame
; fully interruptible
G_M000_IG01: ;; offset=0000H
55 push rbp
4881ECE0000000 sub rsp, 224
C5F877 vzeroupper
488DAC24E0000000 lea rbp, [rsp+E0H]
C5D857E4 vxorps xmm4, xmm4
C5F97FA570FFFFFF vmovdqa xmmword ptr [rbp-90H], xmm4
C5F97F6580 vmovdqa xmmword ptr [rbp-80H], xmm4
C5F97F6590 vmovdqa xmmword ptr [rbp-70H], xmm4
C5F97F65A0 vmovdqa xmmword ptr [rbp-60H], xmm4
48894D10 mov qword ptr [rbp+10H], rcx
48895518 mov qword ptr [rbp+18H], rdx
4C894520 mov qword ptr [rbp+20H], r8
4C894D28 mov qword ptr [rbp+28H], r9
G_M000_IG02: ;; offset=003EH
C5FD10056A010000 vmovupd ymm0, ymmword ptr[reloc @RWD00]
C5FD114590 vmovupd ymmword ptr[rbp-70H], ymm0
488B4D20 mov rcx, qword ptr [rbp+20H]
48894D88 mov qword ptr [rbp-78H], rcx
488B4D28 mov rcx, qword ptr [rbp+28H]
48894D80 mov qword ptr [rbp-80H], rcx
C78548FFFFFFE8030000 mov dword ptr [rbp-B8H], 0x3E8
E9EC000000 jmp G_M000_IG08
G_M000_IG03: ;; offset=006AH
488B4D80 mov rcx, qword ptr [rbp-80H]
C60100 mov byte ptr [rcx], 0
488B4D80 mov rcx, qword ptr [rbp-80H]
48FFC1 inc rcx
48894D80 mov qword ptr [rbp-80H], rcx
488B4D88 mov rcx, qword ptr [rbp-78H]
48898D78FFFFFF mov qword ptr [rbp-88H], rcx
488B4D80 mov rcx, qword ptr [rbp-80H]
48898D70FFFFFF mov qword ptr [rbp-90H], rcx
EB4D jmp SHORT G_M000_IG05
G_M000_IG04: ;; offset=0094H
488B4588 mov rax, qword ptr [rbp-78H]
C5FE6F00 vmovdqu ymm0, ymmword ptr[rax]
C5FD104D90 vmovupd ymm1, ymmword ptr[rbp-70H]
C4E27D00C1 vpshufb ymm0, ymm0, ymm1
C5FD118550FFFFFF vmovupd ymmword ptr[rbp-B0H], ymm0
488B4580 mov rax, qword ptr [rbp-80H]
C5FD108550FFFFFF vmovupd ymm0, ymmword ptr[rbp-B0H]
C5FE7F00 vmovdqu ymmword ptr[rax], ymm0
B820000000 mov eax, 32
4898 cdqe
48034588 add rax, qword ptr [rbp-78H]
48894588 mov qword ptr [rbp-78H], rax
B820000000 mov eax, 32
4898 cdqe
48034580 add rax, qword ptr [rbp-80H]
48894580 mov qword ptr [rbp-80H], rax
G_M000_IG05: ;; offset=00DCH
8B8D48FFFFFF mov ecx, dword ptr [rbp-B8H]
FFC9 dec ecx
898D48FFFFFF mov dword ptr [rbp-B8H], ecx
83BD48FFFFFF00 cmp dword ptr [rbp-B8H], 0
7F11 jg SHORT G_M000_IG07
G_M000_IG06: ;; offset=00F3H
488D8D48FFFFFF lea rcx, [rbp-B8H]
BA74000000 mov edx, 116
E8DC16A45F call CORINFO_HELP_PATCHPOINT
G_M000_IG07: ;; offset=0104H
488B4510 mov rax, qword ptr [rbp+10H]
BA20000000 mov edx, 32
4863D2 movsxd rdx, edx
488D4410FF lea rax, [rax+rdx-01H]
BA20000000 mov edx, 32
F7DA neg edx
4863D2 movsxd rdx, edx
4823C2 and rax, rdx
48038578FFFFFF add rax, qword ptr [rbp-88H]
48394588 cmp qword ptr [rbp-78H], rax
0F8C61FFFFFF jl G_M000_IG04
488B8578FFFFFF mov rax, qword ptr [rbp-88H]
48034510 add rax, qword ptr [rbp+10H]
48894588 mov qword ptr [rbp-78H], rax
488B8570FFFFFF mov rax, qword ptr [rbp-90H]
48034510 add rax, qword ptr [rbp+10H]
48894580 mov qword ptr [rbp-80H], rax
G_M000_IG08: ;; offset=0151H
8B8D48FFFFFF mov ecx, dword ptr [rbp-B8H]
FFC9 dec ecx
898D48FFFFFF mov dword ptr [rbp-B8H], ecx
83BD48FFFFFF00 cmp dword ptr [rbp-B8H], 0
7F11 jg SHORT G_M000_IG10
G_M000_IG09: ;; offset=0168H
488D8D48FFFFFF lea rcx, [rbp-B8H]
BA9D000000 mov edx, 157
E86716A45F call CORINFO_HELP_PATCHPOINT
G_M000_IG10: ;; offset=0179H
488B4D10 mov rcx, qword ptr [rbp+10H]
480FAF4D18 imul rcx, qword ptr [rbp+18H]
48034D20 add rcx, qword ptr [rbp+20H]
48394D88 cmp qword ptr [rbp-78H], rcx
0F8CDAFEFFFF jl G_M000_IG03
G_M000_IG11: ;; offset=0190H
C5F877 vzeroupper
4881C4E0000000 add rsp, 224
5D pop rbp
C3 ret
RWD00 dq 0704050603000102h, 0F0C0D0E0B08090Ah, 0704050603000102h, 0F0C0D0E0B08090Ah
; ------------------------------------------------------------------------------------------
; Assembly listing for method Sayuri.Drawing.Png:relocateAvx2(long,long,long,long)
; Emitting BLENDED_CODE for X64 CPU with AVX - Windows
; Tier-1 compilation
; OSR variant for entry point 0x74
; optimized code
; rsp based frame
; fully interruptible
; No PGO data
G_M000_IG01: ;; offset=0000H
50 push rax
4889B424E8000000 mov qword ptr [rsp+E8H], rsi
C5F877 vzeroupper
488B8C2400010000 mov rcx, qword ptr [rsp+100H]
488B942408010000 mov rdx, qword ptr [rsp+108H]
4C8B842410010000 mov r8, qword ptr [rsp+110H]
C4E17D10842480000000 vmovupd ymm0, ymmword ptr[rsp+80H]
488B442478 mov rax, qword ptr [rsp+78H]
4C8B4C2470 mov r9, qword ptr [rsp+70H]
4C8B542468 mov r10, qword ptr [rsp+68H]
4C8B5C2460 mov r11, qword ptr [rsp+60H]
G_M000_IG02: ;; offset=0042H
488D711F lea rsi, [rcx+1FH]
4883E6E0 and rsi, -32
480FAFD1 imul rdx, rcx
4903D0 add rdx, r8
EB14 jmp SHORT G_M000_IG04
0F1F8000000000 align [7 bytes for IG05]
G_M000_IG03: ;; offset=005AH
41C60100 mov byte ptr [r9], 0
49FFC1 inc r9
4C8BD0 mov r10, rax
4D8BD9 mov r11, r9
G_M000_IG04: ;; offset=0067H
4D8D0432 lea r8, [r10+rsi]
4C3BC0 cmp r8, rax
7E1C jle SHORT G_M000_IG06
G_M000_IG05: ;; offset=0070H
C5FE6F08 vmovdqu ymm1, ymmword ptr[rax]
C4E27500C8 vpshufb ymm1, ymm1, ymm0
C4C17E7F09 vmovdqu ymmword ptr[r9], ymm1
4883C020 add rax, 32
4983C120 add r9, 32
4C3BC0 cmp r8, rax
7FE5 jg SHORT G_M000_IG05
G_M000_IG06: ;; offset=008BH
498D040A lea rax, [r10+rcx]
4D8D0C0B lea r9, [r11+rcx]
483BC2 cmp rax, rdx
7CC2 jl SHORT G_M000_IG03
G_M000_IG07: ;; offset=0098H
C5F877 vzeroupper
4881C4E8000000 add rsp, 232
5E pop rsi
5D pop rbp
C3 ret
; Total bytes of code 165
; ------------------------------------------------------------------------------------------
; Assembly listing for method Sayuri.Drawing.Png:relocateAvx2(long,long,long,long)
; Emitting BLENDED_CODE for X64 CPU with AVX - Windows
; Tier-1 compilation
; optimized code
; rsp based frame
; fully interruptible
; No PGO data
G_M000_IG01: ;; offset=0000H
56 push rsi
C5F877 vzeroupper
G_M000_IG02: ;; offset=0004H
C4E17D100573000000 vmovupd ymm0, ymmword ptr[reloc @RWD00]
498BC0 mov rax, r8
480FAFD1 imul rdx, rcx
4803D0 add rdx, rax
493BD0 cmp rdx, r8
7E4D jle SHORT G_M000_IG06
4C8D411F lea r8, [rcx+1FH]
4983E0E0 and r8, -32
G_M000_IG03: ;; offset=0024H
41C60100 mov byte ptr [r9], 0
49FFC1 inc r9
4C8BD0 mov r10, rax
4D8BD9 mov r11, r9
4B8D3402 lea rsi, [r10+r8]
493BF2 cmp rsi, r10
7E22 jle SHORT G_M000_IG05
660F1F440000 align [6 bytes for IG04]
G_M000_IG04: ;; offset=0040H
C5FE6F08 vmovdqu ymm1, ymmword ptr[rax]
C4E27500C8 vpshufb ymm1, ymm1, ymm0
C4C17E7F09 vmovdqu ymmword ptr[r9], ymm1
4883C020 add rax, 32
4983C120 add r9, 32
483BF0 cmp rsi, rax
7FE5 jg SHORT G_M000_IG04
G_M000_IG05: ;; offset=005BH
498D040A lea rax, [r10+rcx]
4D8D0C0B lea r9, [r11+rcx]
483BD0 cmp rdx, rax
7FBC jg SHORT G_M000_IG03
G_M000_IG06: ;; offset=0068H
C5F877 vzeroupper
5E pop rsi
C3 ret
RWD00 dq 0704050603000102h, 0F0C0D0E0B08090Ah, 0704050603000102h, 0F0C0D0E0B08090Ah
; Total bytes of code 109
; Assembly listing for method Sayuri.Drawing.Png:relocateIndexed(long,long,long,long,long,long):bool
; Emitting BLENDED_CODE for X64 CPU with AVX - Windows
; Tier-0 compilation
; MinOpts code
; rbp based frame
; fully interruptible
G_M000_IG01: ;; offset=0000H
55 push rbp
4881ECA0000000 sub rsp, 160
488DAC24A0000000 lea rbp, [rsp+A0H]
33C0 xor eax, eax
48894584 mov qword ptr [rbp-7CH], rax
89458C mov dword ptr [rbp-74H], eax
C5D857E4 vxorps xmm4, xmm4
C5F97F6590 vmovdqa xmmword ptr [rbp-70H], xmm4
C5F97F65A0 vmovdqa xmmword ptr [rbp-60H], xmm4
C5F97F65B0 vmovdqa xmmword ptr [rbp-50H], xmm4
488945C0 mov qword ptr [rbp-40H], rax
48894D10 mov qword ptr [rbp+10H], rcx
48895518 mov qword ptr [rbp+18H], rdx
4C894520 mov qword ptr [rbp+20H], r8
4C894D28 mov qword ptr [rbp+28H], r9
G_M000_IG02: ;; offset=0040H
488B4D20 mov rcx, qword ptr [rbp+20H]
C60100 mov byte ptr [rcx], 0
488B4D10 mov rcx, qword ptr [rbp+10H]
48894DC0 mov qword ptr [rbp-40H], rcx
488B4D18 mov rcx, qword ptr [rbp+18H]
48894DB8 mov qword ptr [rbp-48H], rcx
488B4D20 mov rcx, qword ptr [rbp+20H]
4883C103 add rcx, 3
48894DB0 mov qword ptr [rbp-50H], rcx
33C9 xor ecx, ecx
48894DA8 mov qword ptr [rbp-58H], rcx
E946010000 jmp G_M000_IG17
G_M000_IG03: ;; offset=006EH
488B4DB8 mov rcx, qword ptr [rbp-48H]
C60100 mov byte ptr [rcx], 0
488B4DB8 mov rcx, qword ptr [rbp-48H]
48FFC1 inc rcx
48894DB8 mov qword ptr [rbp-48H], rcx
488B4DC0 mov rcx, qword ptr [rbp-40H]
488B4530 mov rax, qword ptr [rbp+30H]
488D0C81 lea rcx, [rcx+4*rax]
48894DA0 mov qword ptr [rbp-60H], rcx
E9EF000000 jmp G_M000_IG14
G_M000_IG04: ;; offset=0095H
33C9 xor ecx, ecx
48894D98 mov qword ptr [rbp-68H], rcx
488B4DC0 mov rcx, qword ptr [rbp-40H]
8B09 mov ecx, dword ptr [rcx]
894D94 mov dword ptr [rbp-6CH], ecx
8B4D94 mov ecx, dword ptr [rbp-6CH]
81E1000000FF and ecx, 0xFFFFFFFFFF000000
894D90 mov dword ptr [rbp-70H], ecx
837D9000 cmp dword ptr [rbp-70H], 0
7505 jne SHORT G_M000_IG05
E9A8000000 jmp G_M000_IG13
G_M000_IG05: ;; offset=00BBH
817D90000000FF cmp dword ptr [rbp-70H], 0xFFFFFFFFFF000000
7411 je SHORT G_M000_IG06
B900010000 mov ecx, 256
4863C9 movsxd rcx, ecx
48894DA8 mov qword ptr [rbp-58H], rcx
E98E000000 jmp G_M000_IG13
G_M000_IG06: ;; offset=00D5H
EB0B jmp SHORT G_M000_IG08
G_M000_IG07: ;; offset=00D7H
488B4D98 mov rcx, qword ptr [rbp-68H]
48FFC1 inc rcx
48894D98 mov qword ptr [rbp-68H], rcx
G_M000_IG08: ;; offset=00E2H
488B4D98 mov rcx, qword ptr [rbp-68H]
483B4DA8 cmp rcx, qword ptr [rbp-58H]
7F19 jg SHORT G_M000_IG09
488B4D28 mov rcx, qword ptr [rbp+28H]
488B4598 mov rax, qword ptr [rbp-68H]
8B0C81 mov ecx, dword ptr [rcx+4*rax]
3B4D94 cmp ecx, dword ptr [rbp-6CH]
0F95C1 setne cl
0FB6C9 movzx rcx, cl
894D84 mov dword ptr [rbp-7CH], ecx
EB05 jmp SHORT G_M000_IG10
G_M000_IG09: ;; offset=0105H
33C9 xor ecx, ecx
894D84 mov dword ptr [rbp-7CH], ecx
G_M000_IG10: ;; offset=010AH
837D8400 cmp dword ptr [rbp-7CH], 0
75C7 jne SHORT G_M000_IG07
488B4D98 mov rcx, qword ptr [rbp-68H]
483B4DA8 cmp rcx, qword ptr [rbp-58H]
7F02 jg SHORT G_M000_IG11
EB47 jmp SHORT G_M000_IG13
G_M000_IG11: ;; offset=011CH
488B4DA8 mov rcx, qword ptr [rbp-58H]
48FFC1 inc rcx
48894DA8 mov qword ptr [rbp-58H], rcx
B900010000 mov ecx, 256
4863C9 movsxd rcx, ecx
48394DA8 cmp qword ptr [rbp-58H], rcx
7502 jne SHORT G_M000_IG12
EB2C jmp SHORT G_M000_IG13
G_M000_IG12: ;; offset=0137H
488B4D28 mov rcx, qword ptr [rbp+28H]
488B45A8 mov rax, qword ptr [rbp-58H]
8B5594 mov edx, dword ptr [rbp-6CH]
891481 mov dword ptr [rcx+4*rax], edx
8B4D94 mov ecx, dword ptr [rbp-6CH]
FF151ACE2D00 call [System.Buffers.Binary.BinaryPrimitives:ReverseEndianness(uint):uint]
C1E808 shr eax, 8
488B55B0 mov rdx, qword ptr [rbp-50H]
8902 mov dword ptr [rdx], eax
488B45B0 mov rax, qword ptr [rbp-50H]
4883C003 add rax, 3
488945B0 mov qword ptr [rbp-50H], rax
G_M000_IG13: ;; offset=0163H
488B4598 mov rax, qword ptr [rbp-68H]
488B55B8 mov rdx, qword ptr [rbp-48H]
8802 mov byte ptr [rdx], al
488B45C0 mov rax, qword ptr [rbp-40H]
4883C004 add rax, 4
488945C0 mov qword ptr [rbp-40H], rax
488B45B8 mov rax, qword ptr [rbp-48H]
48FFC0 inc rax
488945B8 mov qword ptr [rbp-48H], rax
G_M000_IG14: ;; offset=0184H
488B4DC0 mov rcx, qword ptr [rbp-40H]
483B4DA0 cmp rcx, qword ptr [rbp-60H]
7D17 jge SHORT G_M000_IG15
B900010000 mov ecx, 256
4863C9 movsxd rcx, ecx
48394DA8 cmp qword ptr [rbp-58H], rcx
0F9CC1 setl cl
0FB6C9 movzx rcx, cl
894D88 mov dword ptr [rbp-78H], ecx
EB05 jmp SHORT G_M000_IG16
G_M000_IG15: ;; offset=01A5H
33C9 xor ecx, ecx
894D88 mov dword ptr [rbp-78H], ecx
G_M000_IG16: ;; offset=01AAH
837D8800 cmp dword ptr [rbp-78H], 0
0F85E1FEFFFF jne G_M000_IG04
G_M000_IG17: ;; offset=01B4H
488B4D30 mov rcx, qword ptr [rbp+30H]
480FAF4D38 imul rcx, qword ptr [rbp+38H]
488B4510 mov rax, qword ptr [rbp+10H]
488D0C88 lea rcx, [rax+4*rcx]
48394DC0 cmp qword ptr [rbp-40H], rcx
7D17 jge SHORT G_M000_IG18
B900010000 mov ecx, 256
4863C9 movsxd rcx, ecx
48394DA8 cmp qword ptr [rbp-58H], rcx
0F9CC1 setl cl
0FB6C9 movzx rcx, cl
894D8C mov dword ptr [rbp-74H], ecx
EB05 jmp SHORT G_M000_IG19
G_M000_IG18: ;; offset=01E2H
33C9 xor ecx, ecx
894D8C mov dword ptr [rbp-74H], ecx
G_M000_IG19: ;; offset=01E7H
837D8C00 cmp dword ptr [rbp-74H], 0
0F857DFEFFFF jne G_M000_IG03
B800010000 mov eax, 256
4898 cdqe
483945A8 cmp qword ptr [rbp-58H], rax
0F9CC0 setl al
0FB6C0 movzx rax, al
G_M000_IG20: ;; offset=0202H
4881C4A0000000 add rsp, 160
5D pop rbp
C3 ret
; Total bytes of code 523
; ------------------------------------------------------------------------------------------
; Assembly listing for method Sayuri.Drawing.Png:relocateIndexed(long,long,long,long,long,long):bool
; Emitting BLENDED_CODE for X64 CPU with AVX - Windows
; Tier-1 compilation
; optimized code
; rsp based frame
; fully interruptible
; No PGO data
G_M000_IG01: ;; offset=0000H
57 push rdi
56 push rsi
55 push rbp
53 push rbx
488B442448 mov rax, qword ptr [rsp+48H]
G_M000_IG02: ;; offset=0009H
41C60000 mov byte ptr [r8], 0
4983C003 add r8, 3
4533D2 xor r10d, r10d
4C8BD8 mov r11, rax
4C0FAF5C2450 imul r11, qword ptr [rsp+50H]
4E8D1C99 lea r11, [rcx+4*r11]
EB6E jmp SHORT G_M000_IG12
G_M000_IG03: ;; offset=0023H
C60200 mov byte ptr [rdx], 0
48FFC2 inc rdx
488D3481 lea rsi, [rcx+4*rax]
EB54 jmp SHORT G_M000_IG11
G_M000_IG04: ;; offset=002FH
33FF xor edi, edi
8B19 mov ebx, dword ptr [rcx]
8BEB mov ebp, ebx
81E5000000FF and ebp, 0xFFFFFFFFFF000000
743C je SHORT G_M000_IG10
81FD000000FF cmp ebp, 0xFFFFFFFFFF000000
740B je SHORT G_M000_IG06
41BA00010000 mov r10d, 256
EB2C jmp SHORT G_M000_IG10
G_M000_IG05: ;; offset=004DH
48FFC7 inc rdi
G_M000_IG06: ;; offset=0050H
493BFA cmp rdi, r10
7F08 jg SHORT G_M000_IG08
41391CB9 cmp dword ptr [r9+4*rdi], ebx
75F2 jne SHORT G_M000_IG05
G_M000_IG07: ;; offset=005BH
EB1C jmp SHORT G_M000_IG10
G_M000_IG08: ;; offset=005DH
49FFC2 inc r10
4981FA00010000 cmp r10, 256
7410 je SHORT G_M000_IG10
G_M000_IG09: ;; offset=0069H
43891C91 mov dword ptr [r9+4*r10], ebx
0FCB bswap ebx
C1EB08 shr ebx, 8
418918 mov dword ptr [r8], ebx
4983C003 add r8, 3
G_M000_IG10: ;; offset=0079H
40883A mov byte ptr [rdx], dil
4883C104 add rcx, 4
48FFC2 inc rdx
G_M000_IG11: ;; offset=0083H
483BCE cmp rcx, rsi
7D09 jge SHORT G_M000_IG12
4981FA00010000 cmp r10, 256
7C9E jl SHORT G_M000_IG04
G_M000_IG12: ;; offset=0091H
493BCB cmp rcx, r11
7D09 jge SHORT G_M000_IG14
G_M000_IG13: ;; offset=0096H
4981FA00010000 cmp r10, 256
7C84 jl SHORT G_M000_IG03
G_M000_IG14: ;; offset=009FH
33C0 xor eax, eax
4981FA00010000 cmp r10, 256
0F9CC0 setl al
G_M000_IG15: ;; offset=00ABH
5B pop rbx
5D pop rbp
5E pop rsi
5F pop rdi
C3 ret
; Total bytes of code 176
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment