// File: /workspace/github_c_makefile_star2_O3/hfiguiere[P]exifprobe/print.c
// Function: process_private_ifd
unsigned long
process_private_ifd(FILE *inptr,unsigned short byteorder,
                    unsigned long subifd_offset,unsigned long fileoffset_base,
                    unsigned long max_offset,unsigned short subifd_ident,
                    struct image_summary *summary_entry,char *parent_name,
                    char *prefix,int make,int model,int indent)
{
    struct ifd_entry *entry_ptr;
    unsigned long max_value_offset = 0L;
    unsigned long next_ifd_offset,current_offset,max_subifd_offset;
    unsigned long start_entry_offset,entry_offset,value_offset;
    int entry_num,num_entries,value_is_offset,use_second_pass;
    int chpr = 0;

    if(inptr == (FILE *)0)
    {
        fprintf(stderr,"%s: no open file pointer to read makernote %s subifd\n",
                Progname,parent_name);
        return(0L);
    }
    if(summary_entry)
        summary_entry->filesubformat |= FILESUBFMT_MNSUBIFD;

    /* If the section appears to be beyond the end of the parent ifd, */
    /* mark the start address to call attention.                      */
    if(max_offset && ((subifd_offset + fileoffset_base) > max_offset))
        prefix = "+";

    max_subifd_offset = max_offset;
    print_tag_address(SECTION,subifd_offset + fileoffset_base,indent,prefix);
    if(PRINT_SECTION)
        chpr += printf("<%s SubIFD> (in MakerNote)",parent_name);

    num_entries = read_ushort(inptr,byteorder,subifd_offset + fileoffset_base);
    if(ferror(inptr) || feof(inptr))
        goto blewit;
    current_offset = entry_offset = start_entry_offset = ftell(inptr);
    if(PRINT_SECTION)
    {
        chpr += printf(" %d entries ",num_entries);
        chpr += printf("starting at file offset %#lx=%lu",
                                            current_offset,current_offset);
            chpr = newline(chpr);
    }
    use_second_pass = value_is_offset = 0;

    /* The direct entries                                             */
    for(entry_num = 0; entry_num < num_entries; ++entry_num)
    {
        entry_ptr = read_ifd_entry(inptr,byteorder,entry_offset);
        if((entry_ptr->value_type == 0) || (entry_ptr->value_type > DOUBLE) ||
            ferror(inptr) || feof(inptr))
        {
            int invalid_entry = 0;
            unsigned long limit_offset = 0L;

            print_tag_address(ENTRY,entry_offset,indent,prefix);
            chpr += printf(" INVALID MAKERNOTE SUBIFD ENTRY (%lu)",entry_ptr->value);
            chpr = newline(chpr);
            clearerr(inptr);
            current_offset = ftell(inptr);
            if(max_offset > 0)
                limit_offset = max_offset;
            else
            {
                if(fseek(inptr,0L,SEEK_END) != -1)
                {
                    limit_offset = ftell(inptr);
                    fseek(inptr,current_offset,SEEK_SET);
                }
            }
            /* If there's an error on input, or we can't check    */
            /* for absurd num_entries, give up.                   */
            if(!ferror(inptr) && (limit_offset > 0))
            {
                /* If the number of entries would read past the   */
                /* size of the IFD, or past EOF, give up          */
                if((entry_offset + (12 * num_entries)) < limit_offset)
                {
                    /* Limit the number of consecutive failures.  */
                    /* An apparently valid entry resets the count */
                    /* to 0.                                      */
                    if(invalid_entry++ < MAX_INVALID_ENTRIES)
                    {
                        entry_offset = current_offset;
                        continue;
                    }
                }
            }
            chpr = newline(chpr);
            goto blewit;
        }
        current_offset = ftell(inptr);

        print_tag_address(ENTRY,entry_offset,indent,prefix);
        value_offset = print_private_entry(inptr,byteorder,entry_ptr,fileoffset_base,
                                            subifd_ident,summary_entry,parent_name,
                                            prefix,make,model,SUBINDENT);
        if(value_offset == 0UL)
            value_offset = current_offset;
        if(value_offset > max_value_offset)
            max_value_offset = value_offset;
        if((PRINT_VALUE_AT_OFFSET) && (is_offset(entry_ptr)))
            ++use_second_pass;
        entry_offset = current_offset;
    }

    next_ifd_offset = read_ulong(inptr,byteorder,current_offset);

    /* offsets found in the next pass should be within the bounds of  */
    /* the parent ifd. The following helps to detect chunks that are  */
    /* written "out of place".                                        */

    /* There should be no next_ifd_offset (it should be 0)            */
    /* ###%%% prepare for chains?                                     */
    if(next_ifd_offset > 0L)
    {
        /* ###%%% report unwillingness to handle chained IFDs         */
        if((PRINT_ADDRESS) && (PRINT_VALUE) && (PRINT_VALUE_AT_OFFSET))
        {
            print_tag_address(ENTRY,current_offset,indent,prefix);
            extraindent(SUBINDENT);
            chpr += printf("**** next IFD offset %lu  ",next_ifd_offset);
            next_ifd_offset += fileoffset_base;
            if(next_ifd_offset < ftell(inptr))
            {
                printred("BAD NEXT IFD OFFSET");
                next_ifd_offset = 0L;
            }
            else
                chpr += printf("(+ %lu = %#lx/%lu)",fileoffset_base,
                                        next_ifd_offset,next_ifd_offset);
            chpr = newline(chpr);
        }
        else
            next_ifd_offset += fileoffset_base;
        /* This should never happen                                   */
        max_subifd_offset = next_ifd_offset;
    }
    else
    {
        if((PRINT_ADDRESS) && (PRINT_VALUE) && (PRINT_VALUE_AT_OFFSET))
        {
            print_tag_address(ENTRY,current_offset,indent,prefix);
            extraindent(SUBINDENT);
            chpr += printf("**** next IFD offset 0");
            chpr = newline(chpr);
        }
    }

    if(ferror(inptr) || feof(inptr))
    {
        chpr += printf(" READ NEXT IFD OFFSET FAILED ");
        chpr = newline(chpr);
        why(stdout);
        clearerr(inptr);    /* keep going...                          */
    }
    else
        current_offset = ftell(inptr);

    value_offset = current_offset;

    /* Second pass, to evaluate entries which are stored indirectly.  */
    /* This occurs when the value requires more than 4 bytes, AND for */
    /* certain LONG values which are intended to be used as offsets   */
    if(use_second_pass)
    {
        if((PRINT_VALUE) && (PRINT_ADDRESS) && (PRINT_VALUE_AT_OFFSET))
        {
            print_tag_address(ENTRY,value_offset,indent,prefix);
            extraindent(SUBINDENT);
            chpr += printf("============= VALUES, %s IFD ============",parent_name);
            chpr = newline(chpr);
        }

        entry_offset = start_entry_offset;
        for(entry_num = 0; entry_num < num_entries; ++entry_num)
        {
            entry_ptr = read_ifd_entry(inptr,byteorder,entry_offset);
            if((entry_ptr->value_type == 0) || (entry_ptr->value_type > DOUBLE) ||
                ferror(inptr) || feof(inptr))
            {
                /* If the first pass made it through invalid entries, */
                /* this pass should just ignore them and quietly      */
                /* continue.                                          */
                clearerr(inptr);
                entry_offset = current_offset = ftell(inptr);
                continue;
            }
            current_offset = entry_offset = ftell(inptr);
            if(is_offset(entry_ptr) ||
                        private_value_is_offset(make,subifd_ident,entry_ptr->tag))
            {
                value_offset = print_offset_pe_value(inptr,byteorder,
                                            entry_ptr,fileoffset_base,
                                            subifd_ident,summary_entry,
                                            parent_name,prefix,indent,
                                            make,model,1);
            }
            if(value_offset > max_value_offset)
                max_value_offset = value_offset;
        }
    }
    else if(current_offset > max_value_offset)
        max_value_offset = current_offset;

    if(max_offset && (max_value_offset > max_offset))
    {
        max_value_offset = max_offset;
        print_tag_address(SECTION,max_value_offset - 1,indent,">");
    }
    else
        print_tag_address(SECTION,max_value_offset - 1,indent,"-");
    if(PRINT_SECTION)
    {
        chpr += printf("</%s SubIFD> (in MakerNote)",parent_name);
        chpr = newline(chpr);
    }

    return(max_value_offset);
blewit:
    clearerr(inptr);
    current_offset = ftell(inptr);
    print_tag_address(SECTION,current_offset - 1,indent,"-");
    if(PRINT_SECTION)
    {
        chpr += printf("</EXIF IFD>");
        chpr = newline(chpr);
    }
    return(0L);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movl %r9d, 0x34(%rsp)
movq %r8, 0x48(%rsp)
movq 0xa8(%rsp), %r13
testq %rdi, %rdi
je 0x9c5c
movq %rdx, %rbx
movl %esi, %r15d
movq %rdi, %r12
movl 0xc8(%rsp), %r14d
movq 0xb0(%rsp), %rax
movq 0xa0(%rsp), %rdx
testq %rdx, %rdx
je 0x9912
orb $0x2, 0x19(%rdx)
movq %rcx, 0x40(%rsp)
addq %rcx, %rbx
movq 0x48(%rsp), %rdx
cmpq %rdx, %rbx
leaq 0x38259(%rip), %rcx     # 0x41b82
cmovbeq %rax, %rcx
testq %rdx, %rdx
cmoveq %rax, %rcx
movl $0x40000, %edi          # imm = 0x40000
movq %rbx, %rsi
movl %r14d, %edx
movq %rcx, 0x20(%rsp)
callq 0x55eb
leaq 0x4e830(%rip), %rbp     # 0x58180
xorl %eax, %eax
testb $0x4, 0x2(%rbp)
je 0x9969
leaq 0x38225(%rip), %rdi     # 0x41b84
movq %r13, %rsi
xorl %eax, %eax
callq 0x3120
movl %eax, 0x4(%rsp)
movzwl %r15w, %r15d
movq %r12, %rdi
movl %r15d, %esi
movq %rbx, %rdx
callq 0x45af
movl %eax, %ebx
movq %r12, %rdi
callq 0x30b0
testl %eax, %eax
jne 0x999c
movl %r15d, %r13d
movq %r12, %rdi
callq 0x31a0
testl %eax, %eax
je 0x99fb
movq %r12, %rdi
callq 0x31b0
movq %r12, %rdi
callq 0x3190
leaq -0x1(%rax), %rsi
leaq 0x37742(%rip), %rcx     # 0x410f9
movl $0x40000, %edi          # imm = 0x40000
movl %r14d, %edx
callq 0x55eb
testb $0x4, 0x2(%rbp)
jne 0x99ce
xorl %ebx, %ebx
jmp 0x99e9
leaq 0x3814e(%rip), %rdi     # 0x41b23
xorl %ebx, %ebx
xorl %eax, %eax
callq 0x3120
movl 0x4(%rsp), %edi
addl %eax, %edi
callq 0x1707a
movq %rbx, %rax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movzwl %bx, %r15d
movq %r12, %rdi
callq 0x3190
testb $0x4, 0x2(%rbp)
movq %rax, 0x38(%rsp)
movw %bx, 0x1e(%rsp)
je 0x9a52
leaq 0x38181(%rip), %rdi     # 0x41b9f
movl %r15d, %esi
movq %rax, %rbp
xorl %eax, %eax
callq 0x3120
movl %eax, %ebx
leaq 0x38178(%rip), %rdi     # 0x41bac
movq %rbp, %rsi
movq %rbp, %rdx
xorl %eax, %eax
callq 0x3120
movl 0x4(%rsp), %edi
addl %eax, %edi
addl %ebx, %edi
callq 0x1707a
movl %eax, 0x4(%rsp)
movq %r12, 0x8(%rsp)
testl %r15d, %r15d
movl %r13d, %ebx
movq %r15, 0x58(%rsp)
je 0x9c69
leal (,%r15,4), %eax
leal (%rax,%rax,2), %eax
movq %rax, 0x10(%rsp)
movzwl 0x34(%rsp), %eax
movl %eax, 0x50(%rsp)
movl %r15d, %ebp
movl $0x0, 0x30(%rsp)
movq 0x38(%rsp), %r13
movq $0x0, 0x28(%rsp)
movl %ebx, 0x54(%rsp)
movq 0x8(%rsp), %r12
movq %r12, %rdi
movl %ebx, %esi
movq %r13, %rdx
callq 0x4bcc
movq %rax, %r15
movzwl 0x2(%rax), %eax
addl $-0xd, %eax
cmpw $-0xc, %ax
jb 0x9adc
movq %r12, %rdi
callq 0x30b0
testl %eax, %eax
jne 0x9adc
movq %r12, %rdi
callq 0x31a0
testl %eax, %eax
je 0x9baa
movl $0x4003333, %edi        # imm = 0x4003333
movq %r13, %rbx
movq %r13, %rsi
movl %r14d, %edx
movq 0x20(%rsp), %rcx
callq 0x55eb
movq 0x10(%r15), %rsi
leaq 0x380ce(%rip), %rdi     # 0x41bcd
xorl %eax, %eax
callq 0x3120
movl 0x4(%rsp), %edi
addl %eax, %edi
callq 0x1707a
movl %eax, 0x4(%rsp)
movq %r12, %rdi
callq 0x31b0
movq %r12, %rdi
callq 0x3190
movq %rax, %r15
movq 0x48(%rsp), %rax
movq %rax, %r13
testq %rax, %rax
jne 0x9b67
movq %r12, %rdi
xorl %esi, %esi
movl $0x2, %edx
callq 0x3210
movl $0x0, %r13d
cmpl $-0x1, %eax
je 0x9b67
movq %r12, %rdi
callq 0x3190
movq %rax, %r13
movq %r12, %rdi
movq %r15, %rsi
xorl %edx, %edx
callq 0x3210
movq %r12, %rdi
callq 0x30b0
testq %r13, %r13
je 0x9d55
testl %eax, %eax
jne 0x9d55
addq 0x10(%rsp), %rbx
cmpq %r13, %rbx
jae 0x9d55
movq %r15, %r13
movl 0xc8(%rsp), %r14d
movl 0x54(%rsp), %ebx
decl %ebp
jne 0x9a9e
jmp 0x9c7f
movq %r12, %rdi
callq 0x3190
movq %rax, 0x60(%rsp)
movl $0x4003333, %edi        # imm = 0x4003333
movq %r13, %rsi
movl %r14d, %edx
movl %ebx, %r13d
movq 0x20(%rsp), %rbx
movq %rbx, %rcx
callq 0x55eb
subq $0x8, %rsp
movq %r12, %rdi
movl %r13d, %r12d
movl %r13d, %esi
movq %r15, %rdx
movq 0x48(%rsp), %rcx
movl 0x58(%rsp), %r8d
movq 0xa8(%rsp), %r9
pushq $0x2
movl 0xd0(%rsp), %eax
pushq %rax
movl 0xd0(%rsp), %eax
pushq %rax
pushq %rbx
movq 0x88(%rsp), %r13
pushq 0xd0(%rsp)
callq 0xa07b
addq $0x30, %rsp
testq %rax, %rax
cmoveq %r13, %rax
movq 0x28(%rsp), %rcx
cmpq %rcx, %rax
cmovaq %rax, %rcx
movq %rcx, 0x28(%rsp)
leaq 0x4e542(%rip), %rax     # 0x58180
testb $0x1, 0x3(%rax)
je 0x9c54
movq %r15, %rdi
callq 0xff89
cmpl $0x1, %eax
sbbl $-0x1, 0x30(%rsp)
movl %r12d, %ebx
jmp 0x9b9d
movq %r13, %rdi
callq 0x336a
jmp 0x99ca
movq %r14, %rbp
movb $0x1, %r12b
movq $0x0, 0x28(%rsp)
movq 0x38(%rsp), %r13
jmp 0x9c8b
movq %r14, %rbp
cmpl $0x0, 0x30(%rsp)
sete %r12b
movq 0x8(%rsp), %rdi
movl %ebx, %esi
movq %r13, %rdx
callq 0x4707
movq %rax, %r15
leaq 0x4e4dc(%rip), %rax     # 0x58180
movq (%rax), %rax
testl $0x30000, %eax          # imm = 0x30000
sete %cl
testb $0x30, %al
sete %dl
orb %cl, %dl
btl $0x18, %eax
setae %al
orb %dl, %al
testq %r15, %r15
je 0x9d7b
testb %al, %al
jne 0x9d7f
movb %r12b, 0x10(%rsp)
movq %r13, %rsi
movl $0x4003333, %edi        # imm = 0x4003333
movl %ebp, %edx
movq 0x20(%rsp), %rcx
callq 0x55eb
leaq 0x4e490(%rip), %rax     # 0x58180
testb $0x30, 0x3(%rax)
je 0x9d00
movl $0x2, %edi
callq 0x5716
leaq 0x37eec(%rip), %rdi     # 0x41bf3
movq %r15, %rsi
xorl %eax, %eax
callq 0x3120
movl %eax, %r12d
addl 0x4(%rsp), %r12d
movq 0x40(%rsp), %r14
addq %r14, %r15
movq 0x8(%rsp), %rdi
callq 0x3190
cmpq %rax, %r15
jae 0x9dc5
leaq 0x3735c(%rip), %rdi     # 0x41097
leaq 0x3d95e(%rip), %rsi     # 0x476a0
xorl %eax, %eax
callq 0x3120
movl %eax, %edi
callq 0x17a82
jmp 0x9ddf
movl 0x4(%rsp), %edi
callq 0x1707a
movl %eax, 0x4(%rsp)
movl 0xc8(%rsp), %r14d
leaq 0x4e40f(%rip), %rbp     # 0x58180
movq 0x8(%rsp), %r12
jmp 0x999c
testb %al, %al
je 0x9d84
movl %ebx, %r14d
jmp 0x9df3
movl $0x4003333, %edi        # imm = 0x4003333
movq %r13, %rsi
movl %ebp, %edx
movq 0x20(%rsp), %rcx
callq 0x55eb
leaq 0x4e3e1(%rip), %rax     # 0x58180
testb $0x30, 0x3(%rax)
je 0x9daf
movl $0x2, %edi
callq 0x5716
leaq 0x37e58(%rip), %rdi     # 0x41c0e
xorl %eax, %eax
callq 0x3120
movl %eax, %edi
addl 0x4(%rsp), %edi
jmp 0x9de7
leaq 0x3b4fc(%rip), %rdi     # 0x452c8
movq %r14, %rsi
movq %r15, %rdx
movq %r15, %rcx
xorl %eax, %eax
callq 0x3120
addl %eax, %r12d
movl %r12d, %edi
movb 0x10(%rsp), %r12b
movl %ebx, %r14d
callq 0x1707a
movl %eax, 0x4(%rsp)
movq 0x8(%rsp), %rbx
movq %rbx, %rdi
callq 0x30b0
testl %eax, %eax
jne 0x9e14
movq %rbx, %rdi
callq 0x31a0
testl %eax, %eax
je 0x9ee5
leaq 0x37e0a(%rip), %rdi     # 0x41c25
xorl %eax, %eax
callq 0x3120
movl 0x4(%rsp), %edi
addl %eax, %edi
callq 0x1707a
movl %eax, 0x4(%rsp)
movq 0x4e190(%rip), %rax     # 0x57fc8
movq (%rax), %rdi
callq 0x17ef7
movq %rbx, %rdi
callq 0x31b0
movq %r13, 0x10(%rsp)
testb %r12b, %r12b
je 0x9e68
movq 0x28(%rsp), %rbx
movq 0x10(%rsp), %rax
cmpq %rbx, %rax
cmovaq %rax, %rbx
jmp 0xa016
leaq 0x4e311(%rip), %rax     # 0x58180
movq (%rax), %rax
btl $0x18, %eax
movq 0x28(%rsp), %rbx
jae 0x9ef5
movl %eax, %ecx
andl $0x30, %ecx
movq 0x58(%rsp), %r13
movq 0x8(%rsp), %r12
je 0x9f05
andl $0x30000, %eax          # imm = 0x30000
je 0x9f05
movl $0x4003333, %edi        # imm = 0x4003333
movq 0x10(%rsp), %rsi
movl %ebp, %edx
movq 0x20(%rsp), %rcx
callq 0x55eb
leaq 0x4e2ce(%rip), %rax     # 0x58180
testb $0x30, 0x3(%rax)
je 0x9ec2
movl $0x2, %edi
callq 0x5716
leaq 0x37d7a(%rip), %rdi     # 0x41c43
movq 0xa8(%rsp), %rsi
xorl %eax, %eax
callq 0x3120
movl 0x4(%rsp), %edi
addl %eax, %edi
callq 0x1707a
jmp 0x9f09
movq %rbx, %rdi
callq 0x3190
movq %rax, %r13
jmp 0x9e48
movl 0x4(%rsp), %eax
movq 0x58(%rsp), %r13
movq 0x8(%rsp), %r12
jmp 0x9f09
movl 0x4(%rsp), %eax
cmpw $0x0, 0x1e(%rsp)
movl %eax, 0x4(%rsp)
je 0xa016
movzwl 0x34(%rsp), %eax
movl %eax, 0x8(%rsp)
movq 0x38(%rsp), %rdx
movq %r12, %rdi
movl %r14d, %esi
callq 0x4bcc
movq %rax, %r15
movzwl 0x2(%rax), %eax
addl $-0xd, %eax
cmpw $-0xc, %ax
jb 0x9f5a
movq %r12, %rdi
callq 0x30b0
testl %eax, %eax
jne 0x9f5a
movq %r12, %rdi
callq 0x31a0
testl %eax, %eax
je 0x9f77
movq %r12, %rdi
callq 0x31b0
movq %r12, %rdi
callq 0x3190
movq %rax, %rdx
decl %r13d
jne 0x9f27
jmp 0xa00f
movq %r12, %rdi
callq 0x3190
movq %rax, %rbp
movq %r15, %rdi
callq 0xff89
testl %eax, %eax
je 0x9fde
movq %r12, %rdi
movl %r14d, %esi
movq %r15, %rdx
movq 0x40(%rsp), %rcx
movl 0x8(%rsp), %r8d
movq 0xa0(%rsp), %r9
pushq $0x1
movl 0xc8(%rsp), %eax
pushq %rax
movl 0xc8(%rsp), %eax
pushq %rax
movl 0xe0(%rsp), %eax
pushq %rax
pushq 0x40(%rsp)
pushq 0xd0(%rsp)
callq 0xa340
addq $0x30, %rsp
movq %rax, 0x10(%rsp)
jmp 0x9ffb
movl 0xb8(%rsp), %eax
cmpl $0xd, %eax
jne 0x9ffb
movzwl (%r15), %esi
movl 0x8(%rsp), %edi
callq 0x30b4f
testl %eax, %eax
jne 0x9f8e
movq 0x10(%rsp), %rax
cmpq %rbx, %rax
cmovaq %rax, %rbx
movq %rbp, %rdx
jmp 0x9f6d
movl 0xc8(%rsp), %ebp
movq 0x48(%rsp), %rdx
testq %rdx, %rdx
setne %al
cmpq %rdx, %rbx
seta %cl
testb %cl, %al
cmovneq %rdx, %rbx
leaq 0x3f82e(%rip), %rax     # 0x49862
leaq 0x370be(%rip), %rcx     # 0x410f9
cmovneq %rax, %rcx
leaq -0x1(%rbx), %rsi
movl $0x40000, %edi          # imm = 0x40000
movl %ebp, %edx
callq 0x55eb
leaq 0x4e12a(%rip), %rax     # 0x58180
testb $0x4, 0x2(%rax)
je 0x99e9
leaq 0x37c06(%rip), %rdi     # 0x41c6d
movq 0xa8(%rsp), %rsi
xorl %eax, %eax
callq 0x3120
jmp 0x99de