// File: /workspace/github_c_makefile_star2_O3/hfiguiere[P]exifprobe/process.c
// Function: process_gps_ifd
unsigned long
process_gps_ifd(FILE *inptr,unsigned short byteorder,
                    unsigned long gps_offset,unsigned long fileoffset_base,
                    unsigned long max_offset,struct image_summary *summary_entry,
                    char *parent_name,int ifdnum,int indent)
{
    struct ifd_entry *entry_ptr;
    unsigned long max_value_offset = 0L;
    unsigned long next_ifd_offset,current_offset,max_gps_offset;
    unsigned long start_entry_offset,entry_offset,value_offset;
    int entry_num,num_entries,value_is_offset,use_second_pass;
    int chpr = 0;
    char *fulldirname = CNULL;

    if(inptr == (FILE *)0)
    {
        fprintf(stderr,"%s: no open file pointer to read GPS IFD\n",
                Progname);
        return(0L);
    }

    PUSHCOLOR(GPS_COLOR);
    /* If the gps segment appears to be beyond the start of the       */
    /* parent ifd, mark the start address funny.                      */
    if(max_offset && (gps_offset > max_offset))
        print_tag_address(SECTION,gps_offset + fileoffset_base,indent,"^");
    else
        print_tag_address(SECTION,gps_offset + fileoffset_base,indent,"@");
    if(PRINT_SECTION)
        chpr += printf("<GPS IFD> (in IFD %d)",ifdnum);

    num_entries = read_ushort(inptr,byteorder,gps_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;
    fulldirname = splice(parent_name,".","Gps");

    indent += SMALLINDENT;
    /* The direct entries                                             */
    for(entry_num = 0; entry_num < num_entries; ++entry_num)
    {
        print_tag_address(ENTRY,entry_offset,indent,"@");
        entry_ptr = read_ifd_entry(inptr,byteorder,entry_offset);
        if((entry_ptr->value_type == 0) || (entry_ptr->value_type > DOUBLE) ||
            ferror(inptr) || feof(inptr))
        {
            print_tag_address(ENTRY,entry_offset,indent,"@");
            chpr += printf(" INVALID (%lu)",entry_ptr->value);
            chpr = newline(chpr);
            /* ###%%% replace with check code from process_tiff_ifd() */
            goto blewit;
        }
        entry_offset = current_offset = ftell(inptr);
        value_offset = print_entry(inptr,byteorder,entry_ptr,fileoffset_base,
                                            summary_entry,fulldirname,GPS_IFD,
                                            ifdnum,-1,SMALLINDENT);
        if(value_offset == 0UL)
            value_offset = entry_offset;
        if(value_offset > max_value_offset)
            max_value_offset = value_offset;
        if((PRINT_VALUE_AT_OFFSET) && (is_offset(entry_ptr)))
            ++use_second_pass;
    }

    next_ifd_offset = read_ulong(inptr,byteorder,current_offset);

    /* offsets found in the next pass should be within the bounds of  */
    /* the ifd. The following helps to detect chunks that are written */
    /* "out of place".                                                */
    if(next_ifd_offset > 0L)
    {
        if((PRINT_VALUE) && (PRINT_SECTION) && (PRINT_VALUE_AT_OFFSET))
        {
            print_tag_address(SECTION,current_offset,indent,"@");
            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_gps_offset = next_ifd_offset;
        if(max_offset && (max_gps_offset > max_offset))
            max_gps_offset = max_offset;
    }
    else
    {
        max_gps_offset = max_offset;    
        if((PRINT_VALUE) && (PRINT_SECTION) && (PRINT_VALUE_AT_OFFSET))
        {
            print_tag_address(SECTION,current_offset,indent,"@");
            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;

    /* Make a second pass to print offset values.                     */
    if(use_second_pass)
    {
        if((PRINT_VALUE) && (PRINT_SECTION) && (PRINT_VALUE_AT_OFFSET))
        {
            print_tag_address(SECTION,value_offset,indent,"@");
            chpr += printf("============= VALUES, GPS IFD ============");
            chpr = newline(chpr);
        }

        /* Second pass, to evaluate entries which are stored          */
        /* indirectly (the value requires more than 4 bytes).         */
        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))
            {
                print_tag_address(ENTRY,entry_offset,indent,"@");
                chpr += printf(" INVALID (%lu)",entry_ptr->value);
                chpr = newline(chpr);
                goto blewit;
            }
            current_offset = entry_offset = ftell(inptr);
            switch(entry_ptr->tag)
            {
                default:
                    if((PRINT_VALUE) && ((PRINT_VALUE_AT_OFFSET) && is_offset(entry_ptr)))
                    {
                        print_tag_address(ENTRY,fileoffset_base + entry_ptr->value,
                                            indent,"@");
                        print_tagid(entry_ptr,SMALLINDENT,GPS_IFD);
                        value_offset =
                                    print_offset_value(inptr,byteorder,entry_ptr,
                                                    fileoffset_base,fulldirname,
                                                    GPS_IFD,indent,1);
                    }
                    break;
            }
            if(value_offset > max_value_offset)
                max_value_offset = value_offset;
        }
    }
    else if(current_offset > max_value_offset)
        max_value_offset = current_offset;

    indent -= SMALLINDENT;
    if(max_offset && (gps_offset > max_offset))
    {
        print_tag_address(SECTION,max_value_offset - 1,indent,">");
        max_value_offset = 0L;  /* let the caller know.               */
    }
    else
        print_tag_address(SECTION,max_value_offset - 1,indent,"-");
    if(PRINT_SECTION)
    {
        chpr += printf("</GPS IFD>");
        chpr = newline(chpr);
    }
    POPCOLOR();
    if(next_ifd_offset)
    {
        printred("#========= WARNING! CHAINING NEXT IFD FROM GPS IFD =========");
        chpr = newline(1);
        value_offset = process_tiff_ifd(inptr,byteorder,next_ifd_offset,
                                fileoffset_base,max_offset,NULL,fulldirname,
                                GPS_IFD,-1,-1,indent);
        if(value_offset > max_value_offset)
            max_value_offset = value_offset;
    }
    if(fulldirname)
        free(fulldirname);
    return(max_value_offset);
blewit:
    clearerr(inptr);
    current_offset = ftell(inptr);
    print_tag_address(SECTION,current_offset - 1,indent,"-");
    if(PRINT_SECTION)
    {
        chpr += printf("</GPS IFD>");
        chpr = newline(chpr);
    }
    if(fulldirname)
        free(fulldirname);
    POPCOLOR();
    return(0L);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
testq %rdi, %rdi
je 0x11016
movq %r9, %r14
movq %r8, %r13
movq %rdx, %r15
movl %esi, %r12d
movq %rdi, %rbx
movl 0xa0(%rsp), %edx
testq %r8, %r8
setne %al
cmpq %r8, %r15
seta %sil
andb %al, %sil
movq %rcx, 0x30(%rsp)
addq %rcx, %r15
leaq 0x33fb2(%rip), %rax     # 0x44d24
leaq 0x30363(%rip), %rcx     # 0x410dc
movb %sil, 0x13(%rsp)
testb %sil, %sil
cmovneq %rax, %rcx
movl $0x40000, %edi          # imm = 0x40000
movq %r15, %rsi
callq 0x55eb
leaq 0x473e7(%rip), %rbp     # 0x58180
xorl %eax, %eax
testb $0x4, 0x2(%rbp)
je 0x10db6
leaq 0x33f7e(%rip), %rdi     # 0x44d26
movl 0x98(%rsp), %esi
xorl %eax, %eax
callq 0x3120
movl %eax, 0xc(%rsp)
movzwl %r12w, %r12d
movq %rbx, %rdi
movl %r12d, %esi
movq %r15, %rdx
callq 0x45af
movl %eax, %r15d
movq %rbx, %rdi
callq 0x30b0
testl %eax, %eax
jne 0x10de7
movq %rbx, %rdi
callq 0x31a0
testl %eax, %eax
je 0x10e5d
xorl %r14d, %r14d
movl 0xa0(%rsp), %eax
movl %eax, %r15d
movq %rbx, %rdi
callq 0x31b0
movq %rbx, %rdi
callq 0x3190
leaq -0x1(%rax), %rsi
leaq 0x302ea(%rip), %rcx     # 0x410f9
movl $0x40000, %edi          # imm = 0x40000
movl %r15d, %edx
callq 0x55eb
testb $0x4, 0x2(%rbp)
je 0x10e3b
leaq 0x33f4d(%rip), %rdi     # 0x44d76
xorl %eax, %eax
callq 0x3120
movl 0xc(%rsp), %edi
addl %eax, %edi
callq 0x1707a
testq %r14, %r14
je 0x10e48
movq %r14, %rdi
callq 0x3050
xorl %r14d, %r14d
movq %r14, %rax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movw %r15w, 0x26(%rsp)
movzwl %r15w, %r15d
movq %rbx, %rdi
callq 0x3190
testb $0x4, 0x2(%rbp)
movq %r13, 0x40(%rsp)
movq %rax, 0x48(%rsp)
je 0x10ebc
movq %rax, %rbp
leaq 0x30d16(%rip), %rdi     # 0x41b9f
movl %r15d, %esi
xorl %eax, %eax
callq 0x3120
movl %eax, %r13d
leaq 0x30d0f(%rip), %rdi     # 0x41bac
movq %rbp, %rsi
movq %rbp, %rdx
xorl %eax, %eax
callq 0x3120
movl 0xc(%rsp), %edi
addl %eax, %edi
addl %r13d, %edi
callq 0x1707a
movl %eax, 0xc(%rsp)
movl %r12d, 0x14(%rsp)
leaq 0x30acf(%rip), %rsi     # 0x41997
leaq 0x33474(%rip), %rdx     # 0x44343
movq 0x90(%rsp), %rdi
callq 0x17f99
movq %rax, 0x38(%rsp)
movl 0xa0(%rsp), %eax
addl $0x2, %eax
movq %rax, 0x28(%rsp)
testl %r15d, %r15d
leaq 0x47286(%rip), %rbp     # 0x58180
movl %r15d, 0x54(%rsp)
je 0x11020
movq $0x0, 0x18(%rsp)
movl %r15d, %ebp
movq 0x48(%rsp), %r15
xorl %r12d, %r12d
movl $0x4003333, %edi        # imm = 0x4003333
movq %r15, %rsi
movq 0x28(%rsp), %rdx
leaq 0x301af(%rip), %rcx     # 0x410dc
callq 0x55eb
movq %rbx, %rdi
movl 0x14(%rsp), %esi
movq %r15, %rdx
callq 0x4bcc
movq %rax, %r13
movzwl 0x2(%rax), %eax
addl $-0xd, %eax
cmpw $-0xc, %ax
jb 0x1100a
movq %rbx, %rdi
callq 0x30b0
testl %eax, %eax
jne 0x1100a
movq %rbx, %rdi
callq 0x31a0
testl %eax, %eax
jne 0x1100a
movq %rbx, %rdi
callq 0x3190
movq %rax, %r15
movq %rbx, %rdi
movl 0x14(%rsp), %esi
movq %r13, %rdx
movq 0x30(%rsp), %rcx
movq %r14, %r8
movq 0x38(%rsp), %r9
pushq $0x2
pushq $-0x1
movl 0xa8(%rsp), %eax
pushq %rax
pushq $0x4
callq 0x5749
addq $0x20, %rsp
testq %rax, %rax
cmoveq %r15, %rax
cmpq %r12, %rax
cmovaq %rax, %r12
leaq 0x471bd(%rip), %rax     # 0x58180
testb $0x1, 0x3(%rax)
je 0x10feb
movzwl 0x2(%r13), %edi
callq 0x1646c
cltq
imulq 0x8(%r13), %rax
cmpq $0x5, %rax
movq 0x18(%rsp), %rax
sbbl $-0x1, %eax
movq %rax, 0x18(%rsp)
decl %ebp
jne 0x10f19
cmpl $0x0, 0x18(%rsp)
sete %r13b
leaq 0x4717d(%rip), %rbp     # 0x58180
movq 0x48(%rsp), %r14
jmp 0x1102e
leaq 0x4716f(%rip), %rbp     # 0x58180
jmp 0x113fe
callq 0x33f5
jmp 0x10e48
movb $0x1, %r13b
xorl %r12d, %r12d
movq 0x48(%rsp), %r14
movq %r14, %r15
movq %rbx, %rdi
movl 0x14(%rsp), %esi
movq %r15, %rdx
callq 0x4707
movq (%rbp), %rdx
testb $0x30, %dl
sete %cl
notl %edx
testl $0x1040000, %edx        # imm = 0x1040000
setne %dl
orb %cl, %dl
testq %rax, %rax
je 0x1106c
testb %dl, %dl
je 0x11082
addq 0x30(%rsp), %rax
movq %rax, 0x18(%rsp)
jmp 0x11169
testb %dl, %dl
je 0x110f6
movq $0x0, 0x18(%rsp)
jmp 0x11169
movb %r13b, 0x12(%rsp)
movq %r14, %rbp
leaq 0x3004b(%rip), %rcx     # 0x410dc
movl $0x40000, %edi          # imm = 0x40000
movq %r15, %rsi
movq 0x28(%rsp), %rdx
movq %rax, 0x18(%rsp)
callq 0x55eb
leaq 0x30b44(%rip), %rdi     # 0x41bf3
movq 0x18(%rsp), %rsi
xorl %eax, %eax
callq 0x3120
movl %eax, %r14d
addl 0xc(%rsp), %r14d
movq 0x30(%rsp), %r13
addq %r13, 0x18(%rsp)
movq %rbx, %rdi
callq 0x3190
movq 0x18(%rsp), %rcx
cmpq %rax, %rcx
jae 0x11137
leaq 0x365ba(%rip), %rdi     # 0x476a0
callq 0x5c26
movq $0x0, 0x18(%rsp)
jmp 0x1114e
leaq 0x2ffdf(%rip), %rcx     # 0x410dc
movl $0x40000, %edi          # imm = 0x40000
movq %r15, %rsi
movq 0x28(%rsp), %rdx
callq 0x55eb
leaq 0x30af8(%rip), %rdi     # 0x41c0e
movq $0x0, 0x18(%rsp)
xorl %eax, %eax
callq 0x3120
movl 0xc(%rsp), %edi
addl %eax, %edi
callq 0x1707a
movl %eax, 0xc(%rsp)
jmp 0x11169
leaq 0x3418a(%rip), %rdi     # 0x452c8
movq %r13, %rsi
movq %rcx, %rdx
xorl %eax, %eax
callq 0x3120
addl %eax, %r14d
movl %r14d, %edi
callq 0x1707a
movl %eax, 0xc(%rsp)
movq %rbp, %r14
leaq 0x4701c(%rip), %rbp     # 0x58180
movb 0x12(%rsp), %r13b
movq %rbx, %rdi
callq 0x30b0
testl %eax, %eax
jne 0x11185
movq %rbx, %rdi
callq 0x31a0
testl %eax, %eax
je 0x11445
leaq 0x30a99(%rip), %rdi     # 0x41c25
xorl %eax, %eax
callq 0x3120
movl 0xc(%rsp), %edi
addl %eax, %edi
callq 0x1707a
movl %eax, 0xc(%rsp)
movq 0x46e1f(%rip), %rax     # 0x57fc8
movq (%rax), %rdi
callq 0x17ef7
movq %rbx, %rdi
callq 0x31b0
testb %r13b, %r13b
je 0x111cf
cmpq %r12, %r15
cmovaq %r15, %r12
movq 0x40(%rsp), %r13
jmp 0x1132c
movq (%rbp), %rax
testb $0x30, %al
sete %cl
notl %eax
testl $0x1040000, %eax        # imm = 0x1040000
setne %al
orb %cl, %al
movq 0x40(%rsp), %r13
jne 0x11221
leaq 0x2feea(%rip), %rcx     # 0x410dc
movl $0x40000, %edi          # imm = 0x40000
movq %r15, %rsi
movq 0x28(%rsp), %rdx
callq 0x55eb
leaq 0x33b40(%rip), %rdi     # 0x44d4b
xorl %eax, %eax
callq 0x3120
movl 0xc(%rsp), %edi
addl %eax, %edi
callq 0x1707a
movl %eax, 0xc(%rsp)
cmpw $0x0, 0x26(%rsp)
je 0x1132c
movq %rbx, %rdi
movl 0x14(%rsp), %esi
movq %r14, %rdx
callq 0x4bcc
movq %rax, %r13
movzwl 0x2(%rax), %eax
addl $-0xd, %eax
cmpw $-0xc, %ax
jb 0x113fb
movq %rbx, %rdi
callq 0x30b0
testl %eax, %eax
jne 0x113fb
movq %rbx, %rdi
callq 0x31a0
testl %eax, %eax
jne 0x113fb
movq %rbx, %rdi
callq 0x3190
movq %rax, %r14
movq (%rbp), %rax
testb $0x30, %al
sete %cl
btl $0x18, %eax
setae %al
orb %cl, %al
jne 0x11316
movzwl 0x2(%r13), %edi
callq 0x1646c
cltq
imulq 0x8(%r13), %rax
cmpq $0x5, %rax
jb 0x11316
movq 0x10(%r13), %rsi
movq 0x30(%rsp), %r15
addq %r15, %rsi
movl $0x4003333, %edi        # imm = 0x4003333
movq %r14, %rbp
movq 0x28(%rsp), %r14
movl %r14d, %edx
leaq 0x2fe0f(%rip), %rcx     # 0x410dc
callq 0x55eb
movq %r13, %rdi
movl $0x2, %esi
movl $0x4, %edx
callq 0x684b
movq %rbx, %rdi
movl 0x14(%rsp), %esi
movq %r13, %rdx
movq %r15, %rcx
movq 0x38(%rsp), %r8
movl $0x4, %r9d
pushq $0x1
pushq %r14
movq %rbp, %r14
leaq 0x46e76(%rip), %rbp     # 0x58180
callq 0x5c40
addq $0x10, %rsp
movq %rax, %r15
cmpq %r12, %r15
cmovaq %r15, %r12
decl 0x54(%rsp)
jne 0x1122d
jmp 0x111c5
leaq -0x1(%r12), %rsi
leaq 0x3852a(%rip), %rax     # 0x49862
leaq 0x2fdba(%rip), %rcx     # 0x410f9
xorl %r14d, %r14d
cmpb $0x0, 0x13(%rsp)
cmovneq %rax, %rcx
cmoveq %r12, %r14
movl $0x40000, %edi          # imm = 0x40000
movl 0xa0(%rsp), %edx
callq 0x55eb
testb $0x4, 0x2(%rbp)
movq 0x38(%rsp), %r15
je 0x11384
leaq 0x33a04(%rip), %rdi     # 0x44d76
xorl %eax, %eax
callq 0x3120
movl 0xc(%rsp), %edi
addl %eax, %edi
callq 0x1707a
movq 0x18(%rsp), %rbp
testq %rbp, %rbp
movq 0x30(%rsp), %r12
je 0x113e5
leaq 0x339e7(%rip), %rdi     # 0x44d81
callq 0x5c26
movl $0x1, %edi
callq 0x1707a
subq $0x8, %rsp
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movq %rbx, %rdi
movl 0x1c(%rsp), %esi
movq %rbp, %rdx
movq %r12, %rcx
movq %r13, %r8
xorl %r9d, %r9d
movl 0xa8(%rsp), %r10d
pushq %r10
pushq %rax
pushq %rax
pushq $0x4
pushq %r15
callq 0xcabc
addq $0x30, %rsp
cmpq %r14, %rax
cmovaq %rax, %r14
testq %r15, %r15
je 0x10e4b
movq %r15, %rdi
callq 0x3050
jmp 0x10e4b
movq %r14, %r15
leaq 0x2fcd7(%rip), %rcx     # 0x410dc
movl $0x4003333, %edi        # imm = 0x4003333
movq %r15, %rsi
movq 0x28(%rsp), %r15
movl %r15d, %edx
callq 0x55eb
movq 0x10(%r13), %rsi
leaq 0x33917(%rip), %rdi     # 0x44d3c
xorl %eax, %eax
callq 0x3120
movl 0xc(%rsp), %edi
addl %eax, %edi
callq 0x1707a
movl %eax, 0xc(%rsp)
movq 0x38(%rsp), %r14
jmp 0x10df4
movq %rbx, %rdi
callq 0x3190
movq %rax, %r15
jmp 0x111b9