// File: lvandeve[P]lodepng/pngdetail.cpp
// Function: printZlibInfo(Data&)
void printZlibInfo(Data& data) {
  data.loadFile();
  if(data.error || !data.isPng()) return;
  const std::vector<unsigned char>& png = data.buffer;

  //Read literal data from all IDAT chunks
  const unsigned char *chunk, *begin, *end;
  end = &png.back() + 1;
  begin = chunk = &png.front() + 8;

  std::vector<unsigned char> compressed;

  while(chunk < end && end - chunk >= 8) {
    char type[5];
    lodepng_chunk_type(type, chunk);
    if(std::string(type).size() != 4) {
      std::cout << "invalid png" << std::endl;
      return;
    }

    if(std::string(type) == "IDAT") {
      const unsigned char* cdata = lodepng_chunk_data_const(chunk);
      unsigned clength = lodepng_chunk_length(chunk);
      if(chunk + clength + 12 > end || clength > png.size() || chunk + clength + 12 < begin) {
        std::cout << "corrupt chunk length" << std::endl;
        return;
      }
      compressed.insert(compressed.end(), cdata, cdata + clength);
    }

    chunk = lodepng_chunk_next_const(chunk, end);
  }

  if(compressed.size() >= 3) {
    int bfinal = compressed[2] & 1;
    int btype = (compressed[2] & 6) >> 1;
    if(bfinal) {
      std::cout << "zlib data stored in a single block, btype: " << btype << std::endl;
    } else {
      std::cout << "zlib data spread over multiple blocks. First block btype: " << btype << std::endl;
    }
  }

  std::cout << "zlib compressed size: " << compressed.size() << std::endl;

  //Decompress all IDAT data (if the while loop ended early, this might fail)
  std::vector<unsigned char> uncompressed;
  data.error = lodepng::decompress(uncompressed, compressed.empty() ? NULL : &compressed[0], compressed.size());
  if(data.error) return;

  std::cout << "zlib uncompressed size: " << uncompressed.size() << std::endl;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1f0, %rsp            # imm = 0x1F0
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
callq 0x31bf0
movq -0x8(%rbp), %rax
cmpl $0x0, 0x2d8(%rax)
jne 0x2acd2
movq -0x8(%rbp), %rdi
callq 0x32360
testb $0x1, %al
jne 0x2acd7
jmp 0x2b32a
movq -0x8(%rbp), %rax
addq $0x20, %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rdi
callq 0x220d0
addq $0x1, %rax
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rdi
callq 0x22110
addq $0x8, %rax
movq %rax, -0x18(%rbp)
movq %rax, -0x20(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x19410
movq -0x18(%rbp), %rcx
xorl %eax, %eax
cmpq -0x28(%rbp), %rcx
movb %al, -0xe1(%rbp)
jae 0x2ad3c
movq -0x28(%rbp), %rax
movq -0x18(%rbp), %rcx
subq %rcx, %rax
cmpq $0x8, %rax
setge %al
movb %al, -0xe1(%rbp)
movb -0xe1(%rbp), %al
testb $0x1, %al
jne 0x2ad4b
jmp 0x2b03e
movq -0x18(%rbp), %rsi
leaq -0x45(%rbp), %rdi
callq 0x3d50
jmp 0x2ad5a
leaq -0x79(%rbp), %rdi
movq %rdi, -0xf0(%rbp)
callq 0x2440
movq -0xf0(%rbp), %rdx
leaq -0x78(%rbp), %rdi
leaq -0x45(%rbp), %rsi
callq 0x2360
jmp 0x2ad80
leaq -0x78(%rbp), %rdi
callq 0x21a0
movq %rax, -0xf8(%rbp)
jmp 0x2ad92
movq -0xf8(%rbp), %rax
subq $0x4, %rax
setne %al
movb %al, -0xf9(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x2170
jmp 0x2adb1
leaq -0x79(%rbp), %rdi
callq 0x22b0
movb -0xf9(%rbp), %al
testb $0x1, %al
jne 0x2adc9
jmp 0x2ae4c
movq 0x1c200(%rip), %rdi     # 0x46fd0
leaq 0xf855(%rip), %rsi      # 0x3a62c
callq 0x2250
movq %rax, -0x108(%rbp)
jmp 0x2ade5
movq -0x108(%rbp), %rdi
movq 0x1c1cd(%rip), %rsi     # 0x46fc0
callq 0x22a0
jmp 0x2adfa
movl $0x1, -0x80(%rbp)
jmp 0x2b321
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x2b335
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x2ae3e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x2170
jmp 0x2ae3c
jmp 0x2ae3e
leaq -0x79(%rbp), %rdi
callq 0x22b0
jmp 0x2b335
leaq -0xa1(%rbp), %rdi
movq %rdi, -0x110(%rbp)
callq 0x2440
movq -0x110(%rbp), %rdx
leaq -0xa0(%rbp), %rdi
leaq -0x45(%rbp), %rsi
callq 0x2360
jmp 0x2ae78
leaq 0xeb2b(%rip), %rsi      # 0x399aa
leaq -0xa0(%rbp), %rdi
callq 0x22220
movb %al, -0x111(%rbp)
jmp 0x2ae93
leaq -0xa0(%rbp), %rdi
callq 0x2170
jmp 0x2aea1
leaq -0xa1(%rbp), %rdi
callq 0x22b0
movb -0x111(%rbp), %al
testb $0x1, %al
jne 0x2aebc
jmp 0x2b018
movq -0x18(%rbp), %rdi
callq 0x3f00
movq %rax, -0x120(%rbp)
jmp 0x2aece
movq -0x120(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0x18(%rbp), %rdi
callq 0x3cf0
movl %eax, -0x124(%rbp)
jmp 0x2aeed
movl -0x124(%rbp), %eax
movl %eax, -0xb4(%rbp)
movq -0x18(%rbp), %rax
movl -0xb4(%rbp), %ecx
addq %rcx, %rax
addq $0xc, %rax
cmpq -0x28(%rbp), %rax
ja 0x2af59
movl -0xb4(%rbp), %eax
movq %rax, -0x138(%rbp)
movq -0x10(%rbp), %rdi
callq 0x19370
movq %rax, -0x130(%rbp)
jmp 0x2af2f
movq -0x138(%rbp), %rax
movq -0x130(%rbp), %rcx
cmpq %rcx, %rax
ja 0x2af59
movq -0x18(%rbp), %rax
movl -0xb4(%rbp), %ecx
addq %rcx, %rax
addq $0xc, %rax
cmpq -0x20(%rbp), %rax
jae 0x2afd1
movq 0x1c070(%rip), %rdi     # 0x46fd0
leaq 0xf6d1(%rip), %rsi      # 0x3a638
callq 0x2250
movq %rax, -0x140(%rbp)
jmp 0x2af75
movq -0x140(%rbp), %rdi
movq 0x1c03d(%rip), %rsi     # 0x46fc0
callq 0x22a0
jmp 0x2af8a
movl $0x1, -0x80(%rbp)
jmp 0x2b321
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x2afc0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0xa0(%rbp), %rdi
callq 0x2170
jmp 0x2afbe
jmp 0x2afc0
leaq -0xa1(%rbp), %rdi
callq 0x22b0
jmp 0x2b335
leaq -0x40(%rbp), %rdi
callq 0x193d0
movq %rax, -0x148(%rbp)
jmp 0x2afe3
movq -0x148(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0xb0(%rbp), %rdx
movl -0xb4(%rbp), %eax
movq %rdx, %rcx
addq %rax, %rcx
movq -0xc0(%rbp), %rsi
leaq -0x40(%rbp), %rdi
callq 0x226c0
jmp 0x2b016
jmp 0x2b018
movq -0x18(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x4130
movq %rax, -0x150(%rbp)
jmp 0x2b02e
movq -0x150(%rbp), %rax
movq %rax, -0x18(%rbp)
jmp 0x2ad12
leaq -0x40(%rbp), %rdi
callq 0x19370
movq %rax, -0x158(%rbp)
jmp 0x2b050
movq -0x158(%rbp), %rax
cmpq $0x3, %rax
jb 0x2b15e
leaq -0x40(%rbp), %rdi
movl $0x2, %esi
callq 0x19560
movq %rax, -0x160(%rbp)
jmp 0x2b078
movq -0x160(%rbp), %rax
movzbl (%rax), %eax
andl $0x1, %eax
movl %eax, -0xc4(%rbp)
leaq -0x40(%rbp), %rdi
movl $0x2, %esi
callq 0x19560
movq %rax, -0x168(%rbp)
jmp 0x2b0a2
movq -0x168(%rbp), %rax
movzbl (%rax), %eax
andl $0x6, %eax
sarl %eax
movl %eax, -0xc8(%rbp)
cmpl $0x0, -0xc4(%rbp)
je 0x2b10e
movq 0x1bf09(%rip), %rdi     # 0x46fd0
leaq 0xf57f(%rip), %rsi      # 0x3a64d
callq 0x2250
movq %rax, -0x170(%rbp)
jmp 0x2b0dc
movq -0x170(%rbp), %rdi
movl -0xc8(%rbp), %esi
callq 0x2420
movq %rax, -0x178(%rbp)
jmp 0x2b0f7
movq -0x178(%rbp), %rdi
movq 0x1bebb(%rip), %rsi     # 0x46fc0
callq 0x22a0
jmp 0x2b10c
jmp 0x2b15c
movq 0x1bebb(%rip), %rdi     # 0x46fd0
leaq 0xf55d(%rip), %rsi      # 0x3a679
callq 0x2250
movq %rax, -0x180(%rbp)
jmp 0x2b12a
movq -0x180(%rbp), %rdi
movl -0xc8(%rbp), %esi
callq 0x2420
movq %rax, -0x188(%rbp)
jmp 0x2b145
movq -0x188(%rbp), %rdi
movq 0x1be6d(%rip), %rsi     # 0x46fc0
callq 0x22a0
jmp 0x2b15a
jmp 0x2b15c
jmp 0x2b15e
movq 0x1be6b(%rip), %rdi     # 0x46fd0
leaq 0xf548(%rip), %rsi      # 0x3a6b4
callq 0x2250
movq %rax, -0x190(%rbp)
jmp 0x2b17a
leaq -0x40(%rbp), %rdi
callq 0x19370
movq %rax, -0x198(%rbp)
jmp 0x2b18c
movq -0x198(%rbp), %rsi
movq -0x190(%rbp), %rdi
callq 0x2080
movq %rax, -0x1a0(%rbp)
jmp 0x2b1a8
movq -0x1a0(%rbp), %rdi
movq 0x1be0a(%rip), %rsi     # 0x46fc0
callq 0x22a0
jmp 0x2b1bd
leaq -0xe0(%rbp), %rdi
callq 0x19410
jmp 0x2b1cb
leaq -0x40(%rbp), %rdi
callq 0x19310
movb %al, -0x1a1(%rbp)
jmp 0x2b1dc
movb -0x1a1(%rbp), %al
testb $0x1, %al
jne 0x2b1e8
jmp 0x2b1f3
xorl %eax, %eax
movq %rax, -0x1b0(%rbp)
jmp 0x2b219
xorl %eax, %eax
movl %eax, %esi
leaq -0x40(%rbp), %rdi
callq 0x19560
movq %rax, -0x1b8(%rbp)
jmp 0x2b209
movq -0x1b8(%rbp), %rax
movq %rax, -0x1b0(%rbp)
jmp 0x2b219
movq -0x1b0(%rbp), %rax
movq %rax, -0x1c8(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x19370
movq %rax, -0x1c0(%rbp)
jmp 0x2b239
movq -0x1c0(%rbp), %rdx
movq -0x1c8(%rbp), %rsi
leaq 0xb00a(%rip), %rcx      # 0x36258
leaq -0xe0(%rbp), %rdi
callq 0x106b0
movl %eax, -0x1cc(%rbp)
jmp 0x2b262
movl -0x1cc(%rbp), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x2d8(%rax)
movq -0x8(%rbp), %rax
cmpl $0x0, 0x2d8(%rax)
je 0x2b2a8
movl $0x1, -0x80(%rbp)
jmp 0x2b311
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0xe0(%rbp), %rdi
callq 0x19430
jmp 0x2b333
movq 0x1bd21(%rip), %rdi     # 0x46fd0
leaq 0xf415(%rip), %rsi      # 0x3a6cb
callq 0x2250
movq %rax, -0x1d8(%rbp)
jmp 0x2b2c4
leaq -0xe0(%rbp), %rdi
callq 0x19370
movq %rax, -0x1e0(%rbp)
jmp 0x2b2d9
movq -0x1e0(%rbp), %rsi
movq -0x1d8(%rbp), %rdi
callq 0x2080
movq %rax, -0x1e8(%rbp)
jmp 0x2b2f5
movq -0x1e8(%rbp), %rdi
movq 0x1bcbd(%rip), %rsi     # 0x46fc0
callq 0x22a0
jmp 0x2b30a
movl $0x0, -0x80(%rbp)
leaq -0xe0(%rbp), %rdi
callq 0x19430
jmp 0x2b31f
jmp 0x2b321
leaq -0x40(%rbp), %rdi
callq 0x19430
addq $0x1f0, %rsp            # imm = 0x1F0
popq %rbp
retq
jmp 0x2b335
leaq -0x40(%rbp), %rdi
callq 0x19430
jmp 0x2b340
jmp 0x2b342
movq -0x50(%rbp), %rdi
callq 0x2430
movq %rax, %rdi
callq 0x19400
nopw %cs:(%rax,%rax)