// File: /workspace/github_cpp_makefile_star2_O2/lvandeve[P]lodepng/pngdetail.cpp
// Function: showExifIFD(unsigned char const*, unsigned long, unsigned long, bool, bool, bool)
void showExifIFD(const unsigned char* exif, size_t size, size_t ifd_pos, bool big_endian, bool is_thumbnail, bool is_sub) {
  size_t pos = ifd_pos;
  size_t sub_ifd = 0;
  if(pos + 2 > size) {
    std::cout << "EXIF IFD out of range: " << pos << std::endl;
    return;
  }
  size_t num_entries = readExifUint16(exif, size, pos, big_endian);
  if(is_sub) {
    std::cout << "EXIF Sub-IFD at " << pos << ", num entries: " << num_entries << std::endl;
  } else if(is_thumbnail) {
    std::cout << "EXIF Thumbnail IFD at " << pos << ", num entries: " << num_entries << std::endl;
  } else {
    std::cout << "EXIF IFD at " << pos << ", num entries: " << num_entries << std::endl;
  }
  pos += 2;
  for(size_t i = 0; i < num_entries; i++) {
    if(pos + 12 > size) {
      std::cout << "EXIF IFD entry out of range: " << pos << std::endl;
      return;
    }
    uint32_t tag_number = readExifUint16(exif, size, pos, big_endian);
    uint32_t format = readExifUint16(exif, size, pos + 2, big_endian);
    uint32_t num = readExifUint32(exif, size, pos + 4, big_endian);
    uint32_t offset = readExifUint32(exif, size, pos + 8, big_endian);
    uint32_t component_size = 1;
    if(format == 3 || format == 8) component_size = 2;
    else if(format == 4 || format == 9 || format == 11) component_size = 4;
    else if(format == 5 || format == 10 || format == 12) component_size = 8;
    size_t len = num * component_size;
    if(len <= 4) offset = pos + 8; // small value is stored in the offset itself
    pos += 12;

    if(format < 1 || format > 12) {
      std::cout << "EXIF unknown entry format" << std::endl;
      return;
    }
    if(is_thumbnail) std::cout << "EXIF tag (thumbnail): ";
    else std::cout << "EXIF tag: ";
    // Only show some common tags by full name
    if(tag_number == 256) std::cout << "Umage Width";
    else if(tag_number == 257) std::cout << "Image Height";
    else if(tag_number == 259) std::cout << "Compression";
    else if(tag_number == 269) std::cout << "Document Name";
    else if(tag_number == 270) std::cout << "Image Description";
    else if(tag_number == 274) std::cout << "Orientation";
    else if(tag_number == 282) std::cout << "X Resolution";
    else if(tag_number == 283) std::cout << "Y Resolution";
    else if(tag_number == 296) std::cout << "Resolution Unit";
    else if(tag_number == 513) std::cout << "Thumbnail Offset";
    else if(tag_number == 514) std::cout << "Thumbnail Size";
    else if(tag_number == 33434) std::cout << "Exposure Time";
    else if(tag_number == 33432) std::cout << "Copyright";
    else if(tag_number == 36864) std::cout << "Exif Version";
    else if(tag_number == 37510) std::cout << "User Comment";
    else std::cout << "#" << tag_number; // tag for which we don't show a name here
    std::cout << ": ";

    if(offset + len > size) {
      std::cout << "EXIF data out of range" << std::endl;
      return;
    }
    if(len == 0) {
      std::cout << "[empty]" << std::endl;
      continue;
    }

    if(format == 1) {
      std::cout << (uint32_t)exif[offset];
    } else if(format == 2) {
      for(size_t j = 0; j < len; j++) {
        if(!exif[offset + j]) break; // NULL terminator
        std::cout << exif[offset + j];
      }
    } else if(format == 3) {
      std::cout << readExifUint16(exif, size, offset, big_endian);
    } else if(format == 4) {
      if(tag_number == 34665) sub_ifd = readExifUint32(exif, size, offset, big_endian);
      else std::cout << readExifUint32(exif, size, offset, big_endian);
    } else if(format == 5) {
      double n = readExifUint32(exif, size, offset, big_endian);
      double d = readExifUint32(exif, size, offset + 4, big_endian);
      std::cout << (n / d);
    } else if(format == 7 && len > 8 && exif[offset + 0] == 'A' && exif[offset + 1] == 'S' &&
              exif[offset + 2] == 'C' && exif[offset + 3] == 'I' && exif[offset + 4] == 'I') {
      for(size_t j = 8; j < len; j++) std::cout << exif[offset + j];
    } else if(format == 7 && len == 4 && tag_number == 36864) {
      for(size_t j = 0; j < len; j++) std::cout << exif[offset + j];
    } else if(format == 8) {
      std::cout << (int32_t)readExifUint16(exif, size, offset, big_endian);
    } else if(format == 9) {
      std::cout << (int16_t)readExifUint32(exif, size, offset, big_endian);
    } else if(format == 10) {
      double n = (int32_t)readExifUint32(exif, size, offset, big_endian);
      double d = (int32_t)readExifUint32(exif, size, offset + 4, big_endian);
      std::cout << (n / d);
    } else {
      // Formats like double not handled here
      std::cout << "[format " << format << ", len " << len << "]";
    }
    std::cout << std::endl;
  }
  if(pos + 4 > size) {
    std::cout << "EXIF IFD footer out of range" << std::endl;
    return;
  }
  size_t next_ifd = readExifUint32(exif, size, pos, big_endian);

  // The > checks are to guarantee progress rather than infinity recursion, though it does mean
  // that an odd EXIF that places later parts earlier in the file won't be supported correctly
  if(sub_ifd && sub_ifd > ifd_pos && sub_ifd != next_ifd) {
    showExifIFD(exif, size, sub_ifd, big_endian, is_thumbnail, true);
  }
  if(next_ifd && next_ifd > ifd_pos) {
    showExifIFD(exif, size, sub_ifd, big_endian, true, is_sub);
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movl %r8d, %r11d
movq %rdx, %r12
movq %rsi, %r14
movq %rdi, (%rsp)
leaq 0x7898(%rip), %rdx      # 0x1f2ec
leaq 0x78a8(%rip), %rsi      # 0x1f303
leaq 0x7869(%rip), %rdi      # 0x1f2cb
leaq 0x78df(%rip), %r8       # 0x1f348
leaq 0x78ef(%rip), %r10      # 0x1f35f
movq 0xf559(%rip), %r15      # 0x26fd0
leaq 0x785e(%rip), %rbx      # 0x1f2dc
movl %ecx, 0x2c(%rsp)
movzbl %cl, %eax
movl %eax, 0x1c(%rsp)
movl %r9d, 0x40(%rsp)
leaq 0x2(%r12), %r13
cmpq %r14, %r13
ja 0x182a6
cmpb $0x0, 0x2c(%rsp)
je 0x17ab5
movq (%rsp), %rax
movzwl (%rax,%r12), %eax
rolw $0x8, %ax
movzwl %ax, %ebp
jmp 0x17abe
movq (%rsp), %rax
movzwl (%rax,%r12), %ebp
movl %r11d, 0x44(%rsp)
testb $0x1, %r11b
cmovneq %rdx, %rsi
cmovneq %r8, %r10
movq %r10, 0x58(%rsp)
testb %r9b, %r9b
cmovneq %rdi, %rsi
movq %r15, %rdi
callq 0x2210
movq %rax, %rdi
movq %r12, 0x50(%rsp)
movq %r12, %rsi
callq 0x2150
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2210
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2150
movq %rax, %rdi
callq 0x2100
xorl %ebx, %ebx
movq $0x0, 0x48(%rsp)
movq %rbp, 0x8(%rsp)
movq %r13, %r12
cmpq %rbp, %rbx
je 0x181a8
leaq 0xc(%r12), %rdx
cmpq %r14, %rdx
ja 0x1824d
leaq 0x2(%r12), %rax
cmpq %r14, %rax
movq %rdx, 0x20(%rsp)
movq %rbx, 0x10(%rsp)
jbe 0x17b67
leaq 0x4(%r12), %rcx
cmpq %r14, %rcx
movq (%rsp), %r15
jbe 0x17b8e
movl $0x0, 0x30(%rsp)
jmp 0x17bbe
cmpb $0x0, 0x2c(%rsp)
movq (%rsp), %r15
je 0x17bab
movzwl (%r15,%r12), %ecx
rolw $0x8, %cx
movzwl %cx, %esi
leaq 0x4(%r12), %rcx
cmpq %r14, %rcx
movl %esi, 0x30(%rsp)
jbe 0x17b9d
jmp 0x17bbe
movl $0x0, 0x30(%rsp)
cmpb $0x0, 0x2c(%rsp)
je 0x17bc2
movzwl (%r15,%rax), %eax
rolw $0x8, %ax
movzwl %ax, %ebx
jmp 0x17bc7
movzwl (%r15,%r12), %esi
leaq 0x4(%r12), %rcx
cmpq %r14, %rcx
movl %esi, 0x30(%rsp)
jbe 0x17bc2
xorl %ebx, %ebx
jmp 0x17bc7
movzwl (%r15,%rax), %ebx
leaq 0x4(%r12), %rdx
movq %r15, %rdi
movq %r14, %rsi
movl 0x1c(%rsp), %ebp
movl %ebp, %ecx
callq 0x179f9
movl %eax, %r13d
addq $0x8, %r12
movq %r15, %rdi
movq %r14, %r15
movq %r14, %rsi
movq %r12, %rdx
movl %ebp, %ecx
callq 0x179f9
movl %eax, %esi
pushq $0x2
popq %rax
movl %eax, %ebp
cmpl $0x3, %ebx
movq %rbx, %rdx
je 0x17c45
movl %eax, %ebp
cmpl $0x8, %edx
je 0x17c45
cmpl $0x4, %edx
sete %al
movl %edx, %ecx
andl $-0x3, %ecx
cmpl $0x9, %ecx
sete %cl
orb %al, %cl
pushq $0x4
popq %rax
movl %eax, %ebp
jne 0x17c45
pushq $0x1
popq %rax
movl %eax, %ebp
cmpl $0xc, %edx
ja 0x17c45
movl $0x1420, %eax           # imm = 0x1420
btl %edx, %eax
pushq $0x1
popq %rax
movl %eax, %ebp
jae 0x17c45
pushq $0x8
popq %rax
movl %eax, %ebp
imull %r13d, %ebp
cmpl $0x5, %ebp
cmovael %esi, %r12d
leal -0xd(%rdx), %eax
cmpl $-0xd, %eax
movl 0x30(%rsp), %ebx
jbe 0x1826d
movq %rsi, 0x38(%rsp)
movq %rdx, 0x60(%rsp)
movq 0xf35f(%rip), %rdi      # 0x26fd0
movq 0x58(%rsp), %rsi
callq 0x2210
cmpl $0x9286, %ebx           # imm = 0x9286
je 0x17d7a
cmpl $0x101, %ebx            # imm = 0x101
movq %r15, %r14
movq 0xf339(%rip), %r13      # 0x26fd0
movq %r13, %rdi
je 0x17d38
cmpl $0x103, %ebx            # imm = 0x103
je 0x17dc8
cmpl $0x10d, %ebx            # imm = 0x10D
je 0x17d5c
cmpl $0x10e, %ebx            # imm = 0x10E
je 0x17d44
cmpl $0x112, %ebx            # imm = 0x112
je 0x17dda
cmpl $0x11a, %ebx            # imm = 0x11A
je 0x17d68
cmpl $0x11b, %ebx            # imm = 0x11B
je 0x17de3
cmpl $0x128, %ebx            # imm = 0x128
je 0x17d9e
cmpl $0x201, %ebx            # imm = 0x201
je 0x17dd1
cmpl $0x202, %ebx            # imm = 0x202
je 0x17dbf
cmpl $0x8298, %ebx           # imm = 0x8298
je 0x17d50
cmpl $0x829a, %ebx           # imm = 0x829A
je 0x17d95
cmpl $0x9000, %ebx           # imm = 0x9000
je 0x17d71
cmpl $0x100, %ebx            # imm = 0x100
jne 0x17da7
leaq 0x7637(%rip), %rsi      # 0x1f36a
jmp 0x17dea
leaq 0x7637(%rip), %rsi      # 0x1f376
jmp 0x17dea
leaq 0x7652(%rip), %rsi      # 0x1f39d
jmp 0x17dea
leaq 0x76bc(%rip), %rsi      # 0x1f413
jmp 0x17dea
leaq 0x762c(%rip), %rsi      # 0x1f38f
jmp 0x17dea
leaq 0x764c(%rip), %rsi      # 0x1f3bb
jmp 0x17dea
leaq 0x76a5(%rip), %rsi      # 0x1f41d
jmp 0x17dea
movq 0xf24f(%rip), %r13      # 0x26fd0
movq %r13, %rdi
leaq 0x769f(%rip), %rsi      # 0x1f42a
callq 0x2210
movq %r15, %r14
jmp 0x17def
leaq 0x7669(%rip), %rsi      # 0x1f405
jmp 0x17dea
leaq 0x7630(%rip), %rsi      # 0x1f3d5
jmp 0x17dea
leaq 0x6b29(%rip), %rsi      # 0x1e8d7
callq 0x2210
movl %ebx, %esi
movq %rax, %rdi
callq 0x2150
jmp 0x17def
leaq 0x7630(%rip), %rsi      # 0x1f3f6
jmp 0x17dea
leaq 0x75b4(%rip), %rsi      # 0x1f383
jmp 0x17dea
leaq 0x760d(%rip), %rsi      # 0x1f3e5
jmp 0x17dea
leaq 0x75ce(%rip), %rsi      # 0x1f3af
jmp 0x17dea
leaq 0x75de(%rip), %rsi      # 0x1f3c8
callq 0x2210
movq %r13, %rdi
leaq 0x7563(%rip), %rsi      # 0x1f35c
callq 0x2210
movl %r12d, %r13d
movq %r13, %rax
addq %rbp, %rax
cmpq %r14, %rax
ja 0x1827d
testq %rbp, %rbp
je 0x17e4b
movq 0x60(%rsp), %rdx
leal -0x1(%rdx), %eax
cmpl $0x4, %eax
ja 0x17f69
leaq 0x6243(%rip), %rcx      # 0x1e070
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq (%rsp), %rax
movzbl (%rax,%r13), %esi
movq 0xf18a(%rip), %r15      # 0x26fd0
jmp 0x17f17
movq 0xf17e(%rip), %r15      # 0x26fd0
movq %r15, %rdi
leaq 0x75f2(%rip), %rsi      # 0x1f44e
callq 0x2210
movq %rax, %rdi
jmp 0x17f22
movq (%rsp), %r15
movq %r15, %rdi
movq %r14, %rsi
movq %r13, %rdx
movl 0x1c(%rsp), %ebx
movl %ebx, %ecx
callq 0x179f9
movl %eax, %eax
cvtsi2sd %rax, %xmm0
movsd %xmm0, 0x30(%rsp)
addl $0x4, %r12d
movq %r15, %rdi
movq %r14, %rsi
movq %r12, %rdx
movl %ebx, %ecx
callq 0x179f9
movl %eax, %eax
cvtsi2sd %rax, %xmm1
movsd 0x30(%rsp), %xmm0
divsd %xmm1, %xmm0
movq 0xf116(%rip), %r15      # 0x26fd0
movq %r15, %rdi
callq 0x2330
jmp 0x17f1f
leaq 0x2(%r13), %rax
cmpq %r14, %rax
movq 0xf0fe(%rip), %r15      # 0x26fd0
jbe 0x18030
xorl %esi, %esi
movq 0x8(%rsp), %rbp
movq 0x10(%rsp), %rbx
jmp 0x180bc
movq (%rsp), %rdi
movq %r14, %rsi
movq %r13, %rdx
movl 0x1c(%rsp), %ecx
callq 0x179f9
movl %eax, %esi
cmpl $0x8769, %ebx           # imm = 0x8769
movq 0xf0c5(%rip), %r15      # 0x26fd0
jne 0x17f17
movq %r15, %rdi
movq %rsi, 0x48(%rsp)
jmp 0x17f22
movq %r15, %rdi
callq 0x2150
movq %r15, %rdi
movq 0x20(%rsp), %r13
movq 0x8(%rsp), %rbp
movq 0x10(%rsp), %rbx
callq 0x2100
incq %rbx
jmp 0x17b21
addq (%rsp), %r13
xorl %ebx, %ebx
movq 0xf085(%rip), %r15      # 0x26fd0
cmpq %rbx, %rbp
je 0x17f1f
movb (%r13,%rbx), %al
testb %al, %al
je 0x17f1f
movsbl %al, %esi
movq %r15, %rdi
callq 0x2270
incq %rbx
jmp 0x17f4b
cmpl $0x7, %edx
jne 0x17ff3
cmpl $0x9, %ebp
jb 0x17ff3
movq (%rsp), %rax
cmpb $0x41, (%rax,%r13)
jne 0x17ff3
movq 0x38(%rsp), %rax
incl %eax
movq (%rsp), %rcx
cmpb $0x53, (%rcx,%rax)
jne 0x17ff3
movq 0x38(%rsp), %rax
addl $0x2, %eax
movq (%rsp), %rcx
cmpb $0x43, (%rcx,%rax)
jne 0x17ff3
movq 0x38(%rsp), %rax
addl $0x3, %eax
movq (%rsp), %rcx
cmpb $0x49, (%rcx,%rax)
jne 0x17ff3
movq 0x38(%rsp), %rcx
addl $0x4, %ecx
movq (%rsp), %rax
cmpb $0x49, (%rax,%rcx)
jne 0x17ff3
addq (%rsp), %r13
pushq $0x8
popq %rbx
movq 0xeff9(%rip), %r15      # 0x26fd0
cmpq %rbx, %rbp
je 0x17f1f
movsbl (%r13,%rbx), %esi
movq %r15, %rdi
callq 0x2270
incq %rbx
jmp 0x17fd7
cmpl $0x7, %edx
jne 0x1805b
cmpl $0x9000, %ebx           # imm = 0x9000
jne 0x1805b
cmpl $0x4, %ebp
jne 0x1805b
addq (%rsp), %r13
xorl %ebx, %ebx
movq 0xefbe(%rip), %r15      # 0x26fd0
movq 0x8(%rsp), %rbp
cmpq $0x4, %rbx
je 0x1804e
movsbl (%r13,%rbx), %esi
movq %r15, %rdi
callq 0x2270
incq %rbx
jmp 0x18017
cmpb $0x0, 0x2c(%rsp)
movq (%rsp), %rax
movq 0x10(%rsp), %rbx
je 0x180b2
movzwl (%rax,%r13), %eax
rolw $0x8, %ax
movzwl %ax, %esi
jmp 0x180b7
movq %r15, %rdi
movq 0x20(%rsp), %r13
jmp 0x17f2c
cmpl $0xa, %edx
je 0x180fb
cmpl $0x9, %edx
je 0x180d1
cmpl $0x8, %edx
jne 0x1813a
leaq 0x2(%r13), %rax
xorl %esi, %esi
cmpq %r14, %rax
movq 0xef4e(%rip), %r15      # 0x26fd0
movq 0x8(%rsp), %rbp
movq 0x10(%rsp), %rbx
ja 0x1819b
cmpb $0x0, 0x2c(%rsp)
je 0x18192
movq (%rsp), %rax
movzwl (%rax,%r13), %eax
rolw $0x8, %ax
movzwl %ax, %esi
jmp 0x1819b
movzwl (%rax,%r13), %esi
movq 0x8(%rsp), %rbp
movq %r15, %rdi
callq 0x2150
movq %r15, %rdi
movq 0x20(%rsp), %r13
jmp 0x17f31
movq (%rsp), %rdi
movq %r14, %rsi
movq %r13, %rdx
movl 0x1c(%rsp), %ecx
callq 0x179f9
movswl %ax, %esi
movq 0xeee2(%rip), %r15      # 0x26fd0
movq %r15, %rdi
callq 0x21f0
jmp 0x17f1f
movq (%rsp), %r15
movq %r15, %rdi
movq %r14, %rsi
movq %r13, %rdx
movl 0x1c(%rsp), %ebx
movl %ebx, %ecx
callq 0x179f9
cvtsi2sd %eax, %xmm0
movsd %xmm0, 0x30(%rsp)
addl $0x4, %r12d
movq %r15, %rdi
movq %r14, %rsi
movq %r12, %rdx
movl %ebx, %ecx
callq 0x179f9
cvtsi2sd %eax, %xmm1
jmp 0x17ea9
movq 0xee8f(%rip), %rbx      # 0x26fd0
movq %rbx, %rdi
leaq 0x730b(%rip), %rsi      # 0x1f456
movq %rdx, %r15
callq 0x2210
movl %r15d, %esi
movq %rbx, %r15
movq %rax, %rdi
callq 0x2150
movq %rax, %rdi
leaq 0x72f4(%rip), %rsi      # 0x1f45f
callq 0x2210
movq %rax, %rdi
movq %rbp, %rsi
callq 0x2150
movq %rax, %rdi
leaq 0x59ed(%rip), %rsi      # 0x1db72
callq 0x2210
movq %rbx, %rdi
jmp 0x17f22
movq (%rsp), %rax
movzwl (%rax,%r13), %esi
movq %r15, %rdi
callq 0x2390
jmp 0x180c4
leaq 0x4(%r12), %rax
cmpq %r14, %rax
ja 0x182b6
movq (%rsp), %rdi
movq %r14, %rsi
movq %r12, %rdx
movl 0x1c(%rsp), %ecx
callq 0x179f9
movl %eax, %ebx
movq 0x50(%rsp), %r12
movq 0x48(%rsp), %r13
cmpq %r12, %r13
jbe 0x18200
cmpq %rbx, %r13
je 0x18200
movzbl 0x44(%rsp), %r8d
andl $0x1, %r8d
movq (%rsp), %rdi
movq %r14, %rsi
movq %r13, %rdx
movl 0x1c(%rsp), %ecx
pushq $0x1
popq %r9
callq 0x17a32
movb $0x1, %r11b
cmpq %rbx, %r12
movl 0x40(%rsp), %r9d
leaq 0x70da(%rip), %rdx      # 0x1f2ec
leaq 0x70ea(%rip), %rsi      # 0x1f303
leaq 0x70ab(%rip), %rdi      # 0x1f2cb
leaq 0x7121(%rip), %r8       # 0x1f348
leaq 0x7131(%rip), %r10      # 0x1f35f
leaq 0x70a7(%rip), %rbx      # 0x1f2dc
movq %r13, %r12
jb 0x17a8e
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0xed7c(%rip), %rdi      # 0x26fd0
leaq 0x70b5(%rip), %rsi      # 0x1f310
callq 0x2210
movq %rax, %rdi
movq %r12, %rsi
callq 0x2150
jmp 0x18290
movq 0xed5c(%rip), %rdi      # 0x26fd0
leaq 0x70b3(%rip), %rsi      # 0x1f32e
jmp 0x1828b
movq 0xed4c(%rip), %rdi      # 0x26fd0
leaq 0x71ac(%rip), %rsi      # 0x1f437
callq 0x2210
movq %rax, %rdi
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x2100
movq 0xed23(%rip), %rdi      # 0x26fd0
leaq 0x6fff(%rip), %rsi      # 0x1f2b3
jmp 0x1825b
movq 0xed13(%rip), %rdi      # 0x26fd0
leaq 0x71a2(%rip), %rsi      # 0x1f466
jmp 0x1828b