// File: /workspace/github_c_makefile_star2_O0/Matthias-Wandel[P]imgcomp/src/exif.c
// Function: ProcessExifDir
static void ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, 
        unsigned ExifLength, int NestingLevel)
{
    int de;
    int a;
    int NumDirEntries;
    char IndentString[25];

    if (NestingLevel > 4){
        ErrNonfatal("Maximum Exif directory nesting exceeded (corrupt Exif header)", 0,0);
        return;
    }

    memset(IndentString, ' ', 25);
    IndentString[NestingLevel * 4] = '\0';


    NumDirEntries = Get16u(DirStart);
    #define DIR_ENTRY_ADDR(Start, Entry) (Start+2+12*(Entry))

    {
        unsigned char * DirEnd;
        DirEnd = DIR_ENTRY_ADDR(DirStart, NumDirEntries);
        if (DirEnd+4 > (OffsetBase+ExifLength)){
            if (DirEnd+2 == OffsetBase+ExifLength || DirEnd == OffsetBase+ExifLength){
                // Version 1.3 of jhead would truncate a bit too much.
                // This also caught later on as well.
            }else{
                ErrNonfatal("Illegally sized Exif subdirectory (%d entries)",NumDirEntries,0);
                return;
            }
        }
    }

    if (ShowTags){
        printf("(dir has %d entries)\n",NumDirEntries);
    }

    for (de=0;de<NumDirEntries;de++){
        int Tag, Format, Components;
        unsigned char * ValuePtr;
        int ByteCount;
        unsigned char * DirEntry;
        DirEntry = DIR_ENTRY_ADDR(DirStart, de);

        Tag = Get16u(DirEntry);
        Format = Get16u(DirEntry+2);
        Components = Get32u(DirEntry+4);

        if ((Format-1) >= NUM_FORMATS) {
            // (-1) catches illegal zero case as unsigned underflows to positive large.
            ErrNonfatal("Illegal number format %d for tag %04x in Exif", Format, Tag);
            continue;
        }

        if ((unsigned)Components > 0x10000){
            ErrNonfatal("Too many components %d for tag %04x in Exif", Components, Tag);
            continue;
        }

        ByteCount = Components * BytesPerFormat[Format];

        if (ByteCount > 4){
            unsigned OffsetVal;
            OffsetVal = Get32u(DirEntry+8);
            // If its bigger than 4 bytes, the dir entry contains an offset.
            if (OffsetVal+ByteCount > ExifLength){
                // Bogus pointer offset and / or bytecount value
                ErrNonfatal("Illegal value pointer for tag %04x in Exif", Tag,0);
                continue;
            }
            ValuePtr = OffsetBase+OffsetVal;
        }else{
            // 4 bytes or less and value is in the dir entry itself
            ValuePtr = DirEntry+8;
        }

        if (ShowTags){
            // Show tag name
            for (a=0;;a++){
                if (a >= TAG_TABLE_SIZE){
                    printf("%s    Unknown Tag %04x Value = ", IndentString, Tag);
                    break;
                }
                if (TagTable[a].Tag == Tag){
                    printf("%s    %s = ",IndentString, TagTable[a].Desc);
                    break;
                }
            }

            // Show tag value.
            switch(Format){
                case FMT_BYTE:
                    if(ByteCount>1){
                        printf("%.*ls\n", ByteCount/2, (wchar_t *)ValuePtr);
                    }else{
                        PrintFormatNumber(ValuePtr, Format, ByteCount);
                        printf("\n");
                    }
                    break;

                case FMT_UNDEFINED:
                    // Undefined is typically an ascii string.

                case FMT_STRING:
                    // String arrays printed without function call (different from int arrays)
                    {
                        int NoPrint = 0;
                        printf("\"");
                        for (a=0;a<ByteCount;a++){
                            if (ValuePtr[a] >= 32){
                                putchar(ValuePtr[a]);
                                NoPrint = 0;
                            }else{
                                // Avoiding indicating too many unprintable characters of proprietary
                                // bits of binary information this program may not know how to parse.
                                if (!NoPrint && a != ByteCount-1){
                                    putchar('?');
                                    NoPrint = 1;
                                }
                            }
                        }
                        printf("\"\n");
                    }
                    break;

                default:
                    // Handle arrays of numbers later (will there ever be?)
                    PrintFormatNumber(ValuePtr, Format, ByteCount);
                    printf("\n");
            }
        }

        // Extract useful components of tag
        switch(Tag){

            case TAG_MAKE:
                strncpy(ImageInfo.CameraMake, (char *)ValuePtr, ByteCount < 31 ? ByteCount : 31);
                break;

            case TAG_MODEL:
                strncpy(ImageInfo.CameraModel, (char *)ValuePtr, ByteCount < 39 ? ByteCount : 39);
                break;

            case TAG_DATETIME_ORIGINAL:
                // If we get a DATETIME_ORIGINAL, we use that one.
                strncpy(ImageInfo.DateTime, (char *)ValuePtr, 19);
                // Fallthru...

            case TAG_DATETIME_DIGITIZED:
            case TAG_DATETIME:
                if (!isdigit(ImageInfo.DateTime[0])){
                    // If we don't already have a DATETIME_ORIGINAL, use whatever
                    // time fields we may have.
                    strncpy(ImageInfo.DateTime, (char *)ValuePtr, 19);
                }
                break;

            case TAG_FNUMBER:
                // Simplest way of expressing aperture, so I trust it the most.
                // (overwrite previously computd value if there is one)
                ImageInfo.ApertureFNumber = (float)ConvertAnyFormat(ValuePtr, Format);
                break;

#if 0 // don't pull in extra math stuff.
            case TAG_APERTURE:
            case TAG_MAXAPERTURE:
                // More relevant info always comes earlier, so only use this field if we don't 
                // have appropriate aperture information yet.
                if (ImageInfo.ApertureFNumber == 0){
                    ImageInfo.ApertureFNumber 
                        = (float)exp(ConvertAnyFormat(ValuePtr, Format)*log(2)*0.5);
                }
                break;

            case TAG_SHUTTERSPEED:
                // More complicated way of expressing exposure time, so only use
                // this value if we don't already have it from somewhere else.
                if (ImageInfo.ExposureTime == 0){
                    ImageInfo.ExposureTime 
                        = (float)(1/exp(ConvertAnyFormat(ValuePtr, Format)*log(2)));
                }
                break;
#endif
            case TAG_FOCALLENGTH:
                // Nice digital cameras actually save the focal length as a function
                // of how farthey are zoomed in.
                ImageInfo.FocalLength = (float)ConvertAnyFormat(ValuePtr, Format);
                break;

            case TAG_SUBJECT_DISTANCE:
                // Inidcates the distacne the autofocus camera is focused to.
                // Tends to be less accurate as distance increases.
                ImageInfo.Distance = (float)ConvertAnyFormat(ValuePtr, Format);
                break;

            case TAG_EXPOSURETIME:
                // Simplest way of expressing exposure time, so I trust it most.
                // (overwrite previously computd value if there is one)
                ImageInfo.ExposureTime = (float)ConvertAnyFormat(ValuePtr, Format);
                break;



            case TAG_FLASH:
                ImageInfo.FlashUsed=(int)ConvertAnyFormat(ValuePtr, Format);
                break;

            case TAG_ORIENTATION:
                ImageInfo.Orientation = (int)ConvertAnyFormat(ValuePtr, Format);
                break;

            case TAG_PIXEL_Y_DIMENSION:
            case TAG_PIXEL_X_DIMENSION:
                // Use largest of height and width to deal with images that have been
                // rotated to portrait format.
                a = (int)ConvertAnyFormat(ValuePtr, Format);
                if (ExifImageWidth < a) ExifImageWidth = a;
                break;

            case TAG_FOCAL_PLANE_XRES:
                FocalplaneXRes = ConvertAnyFormat(ValuePtr, Format);
                break;

            case TAG_FOCAL_PLANE_UNITS:
                switch((int)ConvertAnyFormat(ValuePtr, Format)){
                    case 1: FocalplaneUnits = 25.4; break; // inch
                    case 2: 
                        // According to the information I was using, 2 means meters.
                        // But looking at the Cannon powershot's files, inches is the only
                        // sensible value.
                        FocalplaneUnits = 25.4;
                        break;

                    case 3: FocalplaneUnits = 10;   break;  // centimeter
                    case 4: FocalplaneUnits = 1;    break;  // millimeter
                    case 5: FocalplaneUnits = .001; break;  // micrometer
                }
                break;

            case TAG_EXPOSURE_BIAS:
                ImageInfo.ExposureBias = (float)ConvertAnyFormat(ValuePtr, Format);
                break;

            case TAG_WHITEBALANCE:
                ImageInfo.Whitebalance = (int)ConvertAnyFormat(ValuePtr, Format);
                break;

            case TAG_LIGHT_SOURCE:
                ImageInfo.LightSource = (int)ConvertAnyFormat(ValuePtr, Format);
                break;

            case TAG_METERING_MODE:
                ImageInfo.MeteringMode = (int)ConvertAnyFormat(ValuePtr, Format);
                break;

            case TAG_EXPOSURE_PROGRAM:
                ImageInfo.ExposureProgram = (int)ConvertAnyFormat(ValuePtr, Format);
                break;

            case TAG_EXPOSURE_INDEX:
                if (ImageInfo.ISOequivalent == 0){
                    // Exposure index and ISO equivalent are often used interchangeably,
                    // so we will do the same in jhead.
                    // http://photography.about.com/library/glossary/bldef_ei.htm
                    ImageInfo.ISOequivalent = (int)ConvertAnyFormat(ValuePtr, Format);
                }
                break;

            case TAG_EXPOSURE_MODE:
                ImageInfo.ExposureMode = (int)ConvertAnyFormat(ValuePtr, Format);
                break;

            case TAG_ISO_EQUIVALENT:
                ImageInfo.ISOequivalent = (int)ConvertAnyFormat(ValuePtr, Format);
                break;

            case TAG_DIGITALZOOMRATIO:
                ImageInfo.DigitalZoomRatio = (float)ConvertAnyFormat(ValuePtr, Format);
                break;

            case TAG_EXIF_OFFSET:
                if (ShowTags) printf("%s    Exif Dir:",IndentString);

            case TAG_INTEROP_OFFSET:
                if (Tag == TAG_INTEROP_OFFSET && ShowTags) printf("%s    Interop Dir:",IndentString);
                {
                    unsigned char * SubdirStart;
                    SubdirStart = OffsetBase + Get32u(ValuePtr);
                    if (SubdirStart < OffsetBase || SubdirStart > OffsetBase+ExifLength){
                        ErrNonfatal("Illegal Exif or interop ofset directory link",0,0);
                    }else{
                        ProcessExifDir(SubdirStart, OffsetBase, ExifLength, NestingLevel+1);
                    }
                    continue;
                }
                break;

            case TAG_FOCALLENGTH_35MM:
                // The focal length equivalent 35 mm is a 2.2 tag (defined as of April 2002)
                // if its present, use it to compute equivalent focal length instead of 
                // computing it from sensor geometry and actual focal length.
                ImageInfo.FocalLength35mmEquiv = (unsigned)ConvertAnyFormat(ValuePtr, Format);
                break;

            case TAG_DISTANCE_RANGE:
                // Three possible standard values:
                //   1 = macro, 2 = close, 3 = distant
                ImageInfo.DistanceRange = (int)ConvertAnyFormat(ValuePtr, Format);
                break;



            case TAG_X_RESOLUTION:
                if (NestingLevel==0) {// Only use the values from the top level directory
                    ImageInfo.xResolution = (float)ConvertAnyFormat(ValuePtr,Format);
                    // if yResolution has not been set, use the value of xResolution
                    if (ImageInfo.yResolution == 0.0) ImageInfo.yResolution = ImageInfo.xResolution;
                }
                break;

            case TAG_Y_RESOLUTION:
                if (NestingLevel==0) {// Only use the values from the top level directory
                    ImageInfo.yResolution = (float)ConvertAnyFormat(ValuePtr,Format);
                    // if xResolution has not been set, use the value of yResolution
                    if (ImageInfo.xResolution == 0.0) ImageInfo.xResolution = ImageInfo.yResolution;
                }
                break;

            case TAG_RESOLUTION_UNIT:
                if (NestingLevel==0) {// Only use the values from the top level directory
                    ImageInfo.ResolutionUnit = (int) ConvertAnyFormat(ValuePtr,Format);
                }
                break;

        }
    }


    {
        // In addition to linking to subdirectories via exif tags, 
        // there's also a potential link to another directory at the end of each
        // directory.  this has got to be the result of a committee!
        unsigned char * SubdirStart;
        unsigned Offset;

        if (DIR_ENTRY_ADDR(DirStart, NumDirEntries) + 4 <= OffsetBase+ExifLength){
            Offset = Get32u(DirStart+2+12*NumDirEntries);
            if (Offset){
                SubdirStart = OffsetBase + Offset;
                if (SubdirStart > OffsetBase+ExifLength || SubdirStart < OffsetBase){
                    if (SubdirStart > OffsetBase && SubdirStart < OffsetBase+ExifLength+20){
                        // Jhead 1.3 or earlier would crop the whole directory!
                        // As Jhead produces this form of format incorrectness, 
                        // I'll just let it pass silently
                        if (ShowTags) printf("Thumbnail removed with Jhead 1.3 or earlier\n");
                    }else{
                        ErrNonfatal("Illegal subdirectory link in Exif header",0,0);
                    }
                }else{
                    if (SubdirStart <= OffsetBase+ExifLength){
                        if (ShowTags) printf("%s    Continued directory ",IndentString);
                        ProcessExifDir(SubdirStart, OffsetBase, ExifLength, NestingLevel+1);
                    }
                }
            }
        }else{
            // The exif header ends before the last next directory pointer.
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xd0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movl %ecx, -0x18(%rbp)
cmpl $0x4, -0x18(%rbp)
jle 0x9804
leaq 0x6ee4(%rip), %rdi      # 0x106da
xorl %edx, %edx
movl %edx, %esi
callq 0x8cb0
jmp 0xa4dc
leaq -0x40(%rbp), %rdi
movl $0x20, %esi
movl $0x19, %edx
callq 0x31b0
movl -0x18(%rbp), %eax
shll $0x2, %eax
cltq
movb $0x0, -0x40(%rbp,%rax)
movq -0x8(%rbp), %rdi
callq 0x9120
movl %eax, -0x24(%rbp)
movq -0x8(%rbp), %rax
addq $0x2, %rax
imull $0xc, -0x24(%rbp), %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
addq $0x4, %rax
movq -0x10(%rbp), %rcx
movl -0x14(%rbp), %edx
addq %rdx, %rcx
cmpq %rcx, %rax
jbe 0x98a1
movq -0x48(%rbp), %rax
addq $0x2, %rax
movq -0x10(%rbp), %rcx
movl -0x14(%rbp), %edx
addq %rdx, %rcx
cmpq %rcx, %rax
je 0x9887
movq -0x48(%rbp), %rax
movq -0x10(%rbp), %rcx
movl -0x14(%rbp), %edx
addq %rdx, %rcx
cmpq %rcx, %rax
jne 0x9889
jmp 0x989f
movl -0x24(%rbp), %esi
leaq 0x6e85(%rip), %rdi      # 0x10718
xorl %edx, %edx
callq 0x8cb0
jmp 0xa4dc
jmp 0x98a1
leaq 0xbc08(%rip), %rax      # 0x154b0
cmpl $0x0, (%rax)
je 0x98be
movl -0x24(%rbp), %esi
leaq 0x6e90(%rip), %rdi      # 0x10747
movb $0x0, %al
callq 0x3170
movl $0x0, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
cmpl -0x24(%rbp), %eax
jge 0xa3a9
movq -0x8(%rbp), %rax
addq $0x2, %rax
imull $0xc, -0x1c(%rbp), %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rdi
callq 0x9120
movl %eax, -0x4c(%rbp)
movq -0x70(%rbp), %rdi
addq $0x2, %rdi
callq 0x9120
movl %eax, -0x50(%rbp)
movq -0x70(%rbp), %rdi
addq $0x4, %rdi
callq 0x9280
movl %eax, -0x54(%rbp)
movl -0x50(%rbp), %eax
subl $0x1, %eax
cmpl $0xc, %eax
jl 0x9935
movl -0x50(%rbp), %esi
movl -0x4c(%rbp), %edx
leaq 0x6e32(%rip), %rdi      # 0x1075d
callq 0x8cb0
jmp 0xa39b
cmpl $0x10000, -0x54(%rbp)   # imm = 0x10000
jbe 0x9955
movl -0x54(%rbp), %esi
movl -0x4c(%rbp), %edx
leaq 0x6e40(%rip), %rdi      # 0x1078b
callq 0x8cb0
jmp 0xa39b
movl -0x54(%rbp), %eax
movslq -0x50(%rbp), %rdx
leaq 0x649d(%rip), %rcx      # 0xfe00
imull (%rcx,%rdx,4), %eax
movl %eax, -0x64(%rbp)
cmpl $0x4, -0x64(%rbp)
jle 0x99b1
movq -0x70(%rbp), %rdi
addq $0x8, %rdi
callq 0x9280
movl %eax, -0x74(%rbp)
movl -0x74(%rbp), %eax
addl -0x64(%rbp), %eax
cmpl -0x14(%rbp), %eax
jbe 0x99a1
movl -0x4c(%rbp), %esi
leaq 0x6e22(%rip), %rdi      # 0x107b7
xorl %edx, %edx
callq 0x8cb0
jmp 0xa39b
movq -0x10(%rbp), %rax
movl -0x74(%rbp), %ecx
addq %rcx, %rax
movq %rax, -0x60(%rbp)
jmp 0x99bd
movq -0x70(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x60(%rbp)
leaq 0xbaec(%rip), %rax      # 0x154b0
cmpl $0x0, (%rax)
je 0x9b6d
movl $0x0, -0x20(%rbp)
movslq -0x20(%rbp), %rax
cmpq $0x6a, %rax
jb 0x99f5
leaq -0x40(%rbp), %rsi
movl -0x4c(%rbp), %edx
leaq 0x6df6(%rip), %rdi      # 0x107e2
movb $0x0, %al
callq 0x3170
jmp 0x9a46
movslq -0x20(%rbp), %rcx
leaq 0x9d20(%rip), %rax      # 0x13720
shlq $0x4, %rcx
addq %rcx, %rax
movzwl (%rax), %eax
cmpl -0x4c(%rbp), %eax
jne 0x9a39
leaq -0x40(%rbp), %rsi
movslq -0x20(%rbp), %rcx
leaq 0x9d02(%rip), %rax      # 0x13720
shlq $0x4, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rdx
leaq 0x6dd2(%rip), %rdi      # 0x10802
movb $0x0, %al
callq 0x3170
jmp 0x9a46
jmp 0x9a3b
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
jmp 0x99d4
movl -0x50(%rbp), %eax
movl %eax, -0x90(%rbp)
subl $0x1, %eax
je 0x9a73
jmp 0x9a56
movl -0x90(%rbp), %eax
subl $0x2, %eax
je 0x9abc
jmp 0x9a63
movl -0x90(%rbp), %eax
subl $0x7, %eax
je 0x9abc
jmp 0x9b4e
cmpl $0x1, -0x64(%rbp)
jle 0x9a9a
movl -0x64(%rbp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, %esi
movq -0x60(%rbp), %rdx
leaq 0x6d7d(%rip), %rdi      # 0x1080e
movb $0x0, %al
callq 0x3170
jmp 0x9ab7
movq -0x60(%rbp), %rdi
movl -0x50(%rbp), %esi
movl -0x64(%rbp), %edx
callq 0x92a0
leaq 0x470b(%rip), %rdi      # 0xe1bb
movb $0x0, %al
callq 0x3170
jmp 0x9b6b
movl $0x0, -0x78(%rbp)
leaq 0x46bc(%rip), %rdi      # 0xe186
movb $0x0, %al
callq 0x3170
movl $0x0, -0x20(%rbp)
movl -0x20(%rbp), %eax
cmpl -0x64(%rbp), %eax
jge 0x9b3e
movq -0x60(%rbp), %rax
movslq -0x20(%rbp), %rcx
movzbl (%rax,%rcx), %eax
cmpl $0x20, %eax
jl 0x9b0b
movq -0x60(%rbp), %rax
movslq -0x20(%rbp), %rcx
movzbl (%rax,%rcx), %edi
callq 0x3050
movl $0x0, -0x78(%rbp)
jmp 0x9b31
cmpl $0x0, -0x78(%rbp)
jne 0x9b2f
movl -0x20(%rbp), %eax
movl -0x64(%rbp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
je 0x9b2f
movl $0x3f, %edi
callq 0x3050
movl $0x1, -0x78(%rbp)
jmp 0x9b31
jmp 0x9b33
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
jmp 0x9ad8
leaq 0x6cd0(%rip), %rdi      # 0x10815
movb $0x0, %al
callq 0x3170
jmp 0x9b6b
movq -0x60(%rbp), %rdi
movl -0x50(%rbp), %esi
movl -0x64(%rbp), %edx
callq 0x92a0
leaq 0x4657(%rip), %rdi      # 0xe1bb
movb $0x0, %al
callq 0x3170
jmp 0x9b6d
movl -0x4c(%rbp), %eax
movl %eax, -0x94(%rbp)
subl $0x10f, %eax            # imm = 0x10F
je 0x9db0
jmp 0x9b83
movl -0x94(%rbp), %eax
subl $0x110, %eax            # imm = 0x110
je 0x9e01
jmp 0x9b96
movl -0x94(%rbp), %eax
subl $0x112, %eax            # imm = 0x112
je 0x9f68
jmp 0x9ba9
movl -0x94(%rbp), %eax
subl $0x11a, %eax            # imm = 0x11A
je 0xa2a7
jmp 0x9bbc
movl -0x94(%rbp), %eax
subl $0x11b, %eax            # imm = 0x11B
je 0xa30f
jmp 0x9bcf
movl -0x94(%rbp), %eax
subl $0x128, %eax            # imm = 0x128
je 0xa374
jmp 0x9be2
movl -0x94(%rbp), %eax
subl $0x132, %eax            # imm = 0x132
je 0x9e6e
jmp 0x9bf5
movl -0x94(%rbp), %eax
subl $0x829a, %eax           # imm = 0x829A
je 0x9f22
jmp 0x9c08
movl -0x94(%rbp), %eax
subl $0x829d, %eax           # imm = 0x829D
je 0x9eb6
jmp 0x9c1b
movl -0x94(%rbp), %eax
subl $0x8769, %eax           # imm = 0x8769
je 0xa1a9
jmp 0x9c2e
movl -0x94(%rbp), %eax
subl $0x8822, %eax           # imm = 0x8822
je 0xa0ed
jmp 0x9c41
movl -0x94(%rbp), %eax
subl $0x8827, %eax           # imm = 0x8827
je 0xa163
jmp 0x9c54
movl -0x94(%rbp), %eax
subl $0x9003, %eax           # imm = 0x9003
je 0x9e52
jmp 0x9c67
movl -0x94(%rbp), %eax
subl $0x9004, %eax           # imm = 0x9004
je 0x9e6e
jmp 0x9c7a
movl -0x94(%rbp), %eax
subl $0x9204, %eax           # imm = 0x9204
je 0xa063
jmp 0x9c8d
movl -0x94(%rbp), %eax
subl $0x9206, %eax           # imm = 0x9206
je 0x9efe
jmp 0x9ca0
movl -0x94(%rbp), %eax
subl $0x9207, %eax           # imm = 0x9207
je 0xa0cb
jmp 0x9cb3
movl -0x94(%rbp), %eax
subl $0x9208, %eax           # imm = 0x9208
je 0xa0a9
jmp 0x9cc6
movl -0x94(%rbp), %eax
subl $0x9209, %eax           # imm = 0x9209
je 0x9f46
jmp 0x9cd9
movl -0x94(%rbp), %eax
subl $0x920a, %eax           # imm = 0x920A
je 0x9eda
jmp 0x9cec
movl -0x94(%rbp), %eax
addl $0xffff5ffe, %eax       # imm = 0xFFFF5FFE
subl $0x2, %eax
jb 0x9f8a
jmp 0x9d02
movl -0x94(%rbp), %eax
subl $0xa005, %eax           # imm = 0xA005
je 0xa1c9
jmp 0x9d15
movl -0x94(%rbp), %eax
subl $0xa20e, %eax           # imm = 0xA20E
je 0x9fb6
jmp 0x9d28
movl -0x94(%rbp), %eax
subl $0xa210, %eax           # imm = 0xA210
je 0x9fcf
jmp 0x9d3b
movl -0x94(%rbp), %eax
subl $0xa215, %eax           # imm = 0xA215
je 0xa10f
jmp 0x9d4e
movl -0x94(%rbp), %eax
subl $0xa402, %eax           # imm = 0xA402
je 0xa141
jmp 0x9d61
movl -0x94(%rbp), %eax
subl $0xa403, %eax           # imm = 0xA403
je 0xa087
jmp 0x9d74
movl -0x94(%rbp), %eax
subl $0xa404, %eax           # imm = 0xA404
je 0xa185
jmp 0x9d87
movl -0x94(%rbp), %eax
subl $0xa405, %eax           # imm = 0xA405
je 0xa260
jmp 0x9d9a
movl -0x94(%rbp), %eax
subl $0xa40c, %eax           # imm = 0xA40C
je 0xa285
jmp 0xa399
movq -0x60(%rbp), %rax
movq %rax, -0xa0(%rbp)
cmpl $0x1f, -0x64(%rbp)
jge 0x9dcc
movl -0x64(%rbp), %eax
movl %eax, -0xa4(%rbp)
jmp 0x9dd9
movl $0x1f, %eax
movl %eax, -0xa4(%rbp)
jmp 0x9dd9
movq -0xa0(%rbp), %rsi
movl -0xa4(%rbp), %eax
movslq %eax, %rdx
leaq 0xb6c8(%rip), %rdi      # 0x154b8
addq $0x1008, %rdi           # imm = 0x1008
callq 0x3090
jmp 0xa399
movq -0x60(%rbp), %rax
movq %rax, -0xb0(%rbp)
cmpl $0x27, -0x64(%rbp)
jge 0x9e1d
movl -0x64(%rbp), %eax
movl %eax, -0xb4(%rbp)
jmp 0x9e2a
movl $0x27, %eax
movl %eax, -0xb4(%rbp)
jmp 0x9e2a
movq -0xb0(%rbp), %rsi
movl -0xb4(%rbp), %eax
movslq %eax, %rdx
leaq 0xb677(%rip), %rdi      # 0x154b8
addq $0x1028, %rdi           # imm = 0x1028
callq 0x3090
jmp 0xa399
movq -0x60(%rbp), %rsi
leaq 0xb65b(%rip), %rdi      # 0x154b8
addq $0x1050, %rdi           # imm = 0x1050
movl $0x13, %edx
callq 0x3090
callq 0x3500
movq (%rax), %rax
leaq 0xb63b(%rip), %rcx      # 0x154b8
movsbl 0x1050(%rcx), %ecx
movslq %ecx, %rcx
movzwl (%rax,%rcx,2), %eax
andl $0x800, %eax            # imm = 0x800
cmpl $0x0, %eax
jne 0x9eb1
movq -0x60(%rbp), %rsi
leaq 0xb618(%rip), %rdi      # 0x154b8
addq $0x1050, %rdi           # imm = 0x1050
movl $0x13, %edx
callq 0x3090
jmp 0xa399
movq -0x60(%rbp), %rdi
movl -0x50(%rbp), %esi
callq 0x94a0
cvtsd2ss %xmm0, %xmm0
leaq 0xb5eb(%rip), %rax      # 0x154b8
movss %xmm0, 0x1084(%rax)
jmp 0xa399
movq -0x60(%rbp), %rdi
movl -0x50(%rbp), %esi
callq 0x94a0
cvtsd2ss %xmm0, %xmm0
leaq 0xb5c7(%rip), %rax      # 0x154b8
movss %xmm0, 0x107c(%rax)
jmp 0xa399
movq -0x60(%rbp), %rdi
movl -0x50(%rbp), %esi
callq 0x94a0
cvtsd2ss %xmm0, %xmm0
leaq 0xb5a3(%rip), %rax      # 0x154b8
movss %xmm0, 0x1088(%rax)
jmp 0xa399
movq -0x60(%rbp), %rdi
movl -0x50(%rbp), %esi
callq 0x94a0
cvtsd2ss %xmm0, %xmm0
leaq 0xb57f(%rip), %rax      # 0x154b8
movss %xmm0, 0x1080(%rax)
jmp 0xa399
movq -0x60(%rbp), %rdi
movl -0x50(%rbp), %esi
callq 0x94a0
cvttsd2si %xmm0, %ecx
leaq 0xb55b(%rip), %rax      # 0x154b8
movl %ecx, 0x1078(%rax)
jmp 0xa399
movq -0x60(%rbp), %rdi
movl -0x50(%rbp), %esi
callq 0x94a0
cvttsd2si %xmm0, %ecx
leaq 0xb539(%rip), %rax      # 0x154b8
movl %ecx, 0x106c(%rax)
jmp 0xa399
movq -0x60(%rbp), %rdi
movl -0x50(%rbp), %esi
callq 0x94a0
cvttsd2si %xmm0, %eax
movl %eax, -0x20(%rbp)
movl 0xc5f5(%rip), %eax      # 0x16598
cmpl -0x20(%rbp), %eax
jge 0x9fb1
movl -0x20(%rbp), %eax
movl %eax, 0xc5e7(%rip)      # 0x16598
jmp 0xa399
movq -0x60(%rbp), %rdi
movl -0x50(%rbp), %esi
callq 0x94a0
movsd %xmm0, 0xc5be(%rip)     # 0x16588
jmp 0xa399
movq -0x60(%rbp), %rdi
movl -0x50(%rbp), %esi
callq 0x94a0
cvttsd2si %xmm0, %eax
decl %eax
movl %eax, %ecx
movq %rcx, -0xc0(%rbp)
subl $0x4, %eax
ja 0xa05e
movq -0xc0(%rbp), %rax
leaq 0x5c33(%rip), %rcx      # 0xfc30
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movsd 0x5e3a(%rip), %xmm0     # 0xfe48
movsd %xmm0, 0xc57a(%rip)     # 0x16590
jmp 0xa05e
movsd 0x5e28(%rip), %xmm0     # 0xfe48
movsd %xmm0, 0xc568(%rip)     # 0x16590
jmp 0xa05e
movsd 0x5e0e(%rip), %xmm0     # 0xfe40
movsd %xmm0, 0xc556(%rip)     # 0x16590
jmp 0xa05e
movsd 0x56a4(%rip), %xmm0     # 0xf6e8
movsd %xmm0, 0xc544(%rip)     # 0x16590
jmp 0xa05e
movsd 0x5de2(%rip), %xmm0     # 0xfe38
movsd %xmm0, 0xc532(%rip)     # 0x16590
jmp 0xa399
movq -0x60(%rbp), %rdi
movl -0x50(%rbp), %esi
callq 0x94a0
cvtsd2ss %xmm0, %xmm0
leaq 0xb43e(%rip), %rax      # 0x154b8
movss %xmm0, 0x108c(%rax)
jmp 0xa399
movq -0x60(%rbp), %rdi
movl -0x50(%rbp), %esi
callq 0x94a0
cvttsd2si %xmm0, %ecx
leaq 0xb41a(%rip), %rax      # 0x154b8
movl %ecx, 0x1098(%rax)
jmp 0xa399
movq -0x60(%rbp), %rdi
movl -0x50(%rbp), %esi
callq 0x94a0
cvttsd2si %xmm0, %ecx
leaq 0xb3f8(%rip), %rax      # 0x154b8
movl %ecx, 0x10ac(%rax)
jmp 0xa399
movq -0x60(%rbp), %rdi
movl -0x50(%rbp), %esi
callq 0x94a0
cvttsd2si %xmm0, %ecx
leaq 0xb3d6(%rip), %rax      # 0x154b8
movl %ecx, 0x109c(%rax)
jmp 0xa399
movq -0x60(%rbp), %rdi
movl -0x50(%rbp), %esi
callq 0x94a0
cvttsd2si %xmm0, %ecx
leaq 0xb3b4(%rip), %rax      # 0x154b8
movl %ecx, 0x10a0(%rax)
jmp 0xa399
leaq 0xb3a2(%rip), %rax      # 0x154b8
cmpl $0x0, 0x10a8(%rax)
jne 0xa13c
movq -0x60(%rbp), %rdi
movl -0x50(%rbp), %esi
callq 0x94a0
cvttsd2si %xmm0, %ecx
leaq 0xb382(%rip), %rax      # 0x154b8
movl %ecx, 0x10a8(%rax)
jmp 0xa399
movq -0x60(%rbp), %rdi
movl -0x50(%rbp), %esi
callq 0x94a0
cvttsd2si %xmm0, %ecx
leaq 0xb360(%rip), %rax      # 0x154b8
movl %ecx, 0x10a4(%rax)
jmp 0xa399
movq -0x60(%rbp), %rdi
movl -0x50(%rbp), %esi
callq 0x94a0
cvttsd2si %xmm0, %ecx
leaq 0xb33e(%rip), %rax      # 0x154b8
movl %ecx, 0x10a8(%rax)
jmp 0xa399
movq -0x60(%rbp), %rdi
movl -0x50(%rbp), %esi
callq 0x94a0
cvtsd2ss %xmm0, %xmm0
leaq 0xb31c(%rip), %rax      # 0x154b8
movss %xmm0, 0x1090(%rax)
jmp 0xa399
leaq 0xb300(%rip), %rax      # 0x154b0
cmpl $0x0, (%rax)
je 0xa1c7
leaq -0x40(%rbp), %rsi
leaq 0x6658(%rip), %rdi      # 0x10818
movb $0x0, %al
callq 0x3170
jmp 0xa1c9
cmpl $0xa005, -0x4c(%rbp)    # imm = 0xA005
jne 0xa1f0
leaq 0xb2d7(%rip), %rax      # 0x154b0
cmpl $0x0, (%rax)
je 0xa1f0
leaq -0x40(%rbp), %rsi
leaq 0x663f(%rip), %rdi      # 0x10828
movb $0x0, %al
callq 0x3170
movq -0x10(%rbp), %rax
movq %rax, -0xc8(%rbp)
movq -0x60(%rbp), %rdi
callq 0x9280
movl %eax, %ecx
movq -0xc8(%rbp), %rax
movl %ecx, %ecx
addq %rcx, %rax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rax
cmpq -0x10(%rbp), %rax
jb 0xa233
movq -0x80(%rbp), %rax
movq -0x10(%rbp), %rcx
movl -0x14(%rbp), %edx
addq %rdx, %rcx
cmpq %rcx, %rax
jbe 0xa245
leaq 0x6601(%rip), %rdi      # 0x1083b
xorl %edx, %edx
movl %edx, %esi
callq 0x8cb0
jmp 0xa25b
movq -0x80(%rbp), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
addl $0x1, %ecx
callq 0x97d0
jmp 0xa39b
movq -0x60(%rbp), %rdi
movl -0x50(%rbp), %esi
callq 0x94a0
cvttsd2si %xmm0, %rax
movl %eax, %ecx
leaq 0xb23e(%rip), %rax      # 0x154b8
movl %ecx, 0x1094(%rax)
jmp 0xa399
movq -0x60(%rbp), %rdi
movl -0x50(%rbp), %esi
callq 0x94a0
cvttsd2si %xmm0, %ecx
leaq 0xb21c(%rip), %rax      # 0x154b8
movl %ecx, 0x10b0(%rax)
jmp 0xa399
cmpl $0x0, -0x18(%rbp)
jne 0xa30a
movq -0x60(%rbp), %rdi
movl -0x50(%rbp), %esi
callq 0x94a0
cvtsd2ss %xmm0, %xmm0
leaq 0xb1f4(%rip), %rax      # 0x154b8
movss %xmm0, 0x10b4(%rax)
leaq 0xb1e5(%rip), %rax      # 0x154b8
movss 0x10b8(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0xa308
jp 0xa308
leaq 0xb1c7(%rip), %rax      # 0x154b8
movss 0x10b4(%rax), %xmm0
leaq 0xb1b8(%rip), %rax      # 0x154b8
movss %xmm0, 0x10b8(%rax)
jmp 0xa30a
jmp 0xa399
cmpl $0x0, -0x18(%rbp)
jne 0xa372
movq -0x60(%rbp), %rdi
movl -0x50(%rbp), %esi
callq 0x94a0
cvtsd2ss %xmm0, %xmm0
leaq 0xb18c(%rip), %rax      # 0x154b8
movss %xmm0, 0x10b8(%rax)
leaq 0xb17d(%rip), %rax      # 0x154b8
movss 0x10b4(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0xa370
jp 0xa370
leaq 0xb15f(%rip), %rax      # 0x154b8
movss 0x10b8(%rax), %xmm0
leaq 0xb150(%rip), %rax      # 0x154b8
movss %xmm0, 0x10b4(%rax)
jmp 0xa372
jmp 0xa399
cmpl $0x0, -0x18(%rbp)
jne 0xa397
movq -0x60(%rbp), %rdi
movl -0x50(%rbp), %esi
callq 0x94a0
cvttsd2si %xmm0, %ecx
leaq 0xb127(%rip), %rax      # 0x154b8
movl %ecx, 0x10bc(%rax)
jmp 0xa399
jmp 0xa39b
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x98c5
movq -0x8(%rbp), %rax
addq $0x2, %rax
imull $0xc, -0x24(%rbp), %ecx
movslq %ecx, %rcx
addq %rcx, %rax
addq $0x4, %rax
movq -0x10(%rbp), %rcx
movl -0x14(%rbp), %edx
addq %rdx, %rcx
cmpq %rcx, %rax
ja 0xa4da
movq -0x8(%rbp), %rdi
addq $0x2, %rdi
imull $0xc, -0x24(%rbp), %eax
cltq
addq %rax, %rdi
callq 0x9280
movl %eax, -0x8c(%rbp)
cmpl $0x0, -0x8c(%rbp)
je 0xa4d8
movq -0x10(%rbp), %rax
movl -0x8c(%rbp), %ecx
addq %rcx, %rax
movq %rax, -0x88(%rbp)
movq -0x88(%rbp), %rax
movq -0x10(%rbp), %rcx
movl -0x14(%rbp), %edx
addq %rdx, %rcx
cmpq %rcx, %rax
ja 0xa432
movq -0x88(%rbp), %rax
cmpq -0x10(%rbp), %rax
jae 0xa487
movq -0x88(%rbp), %rax
cmpq -0x10(%rbp), %rax
jbe 0xa475
movq -0x88(%rbp), %rax
movq -0x10(%rbp), %rcx
movl -0x14(%rbp), %edx
addq %rdx, %rcx
addq $0x14, %rcx
cmpq %rcx, %rax
jae 0xa475
leaq 0xb050(%rip), %rax      # 0x154b0
cmpl $0x0, (%rax)
je 0xa473
leaq 0x63fc(%rip), %rdi      # 0x10868
movb $0x0, %al
callq 0x3170
jmp 0xa485
leaq 0x6419(%rip), %rdi      # 0x10895
xorl %edx, %edx
movl %edx, %esi
callq 0x8cb0
jmp 0xa4d6
movq -0x88(%rbp), %rax
movq -0x10(%rbp), %rcx
movl -0x14(%rbp), %edx
addq %rdx, %rcx
cmpq %rcx, %rax
ja 0xa4d4
leaq 0xb00c(%rip), %rax      # 0x154b0
cmpl $0x0, (%rax)
je 0xa4bb
leaq -0x40(%rbp), %rsi
leaq 0x640a(%rip), %rdi      # 0x108be
movb $0x0, %al
callq 0x3170
movq -0x88(%rbp), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
addl $0x1, %ecx
callq 0x97d0
jmp 0xa4d6
jmp 0xa4d8
jmp 0xa4dc
jmp 0xa4dc
addq $0xd0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)