// File: rurban[P]dgnlib/dgnwrite.cpp
// Function: DGNCreate
DGNHandle
      DGNCreate( const char *pszNewFilename, const char *pszSeedFile, 
                 int nCreationFlags, 
                 double dfOriginX, double dfOriginY, double dfOriginZ,
                 int nSubUnitsPerMasterUnit, int nUORPerSubUnit, 
                 const char *pszMasterUnits, const char *pszSubUnits )

{
    DGNInfo *psSeed, *psDGN;
    FILE    *fpNew;
    DGNElemCore *psSrcTCB;

/* -------------------------------------------------------------------- */
/*      Open seed file, and read TCB element.                           */
/* -------------------------------------------------------------------- */
    psSeed = (DGNInfo *) DGNOpen( pszSeedFile, FALSE );
    if( psSeed == NULL )
        return NULL;

    DGNSetOptions( psSeed, DGNO_CAPTURE_RAW_DATA );
    
    psSrcTCB = DGNReadElement( psSeed );

    CPLAssert( psSrcTCB->raw_bytes >= 1536 );
    
/* -------------------------------------------------------------------- */
/*      Open output file.                                               */
/* -------------------------------------------------------------------- */
    fpNew = VSIFOpen( pszNewFilename, "wb" );
    if( fpNew == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "Failed to open output file: %s", pszNewFilename );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Modify TCB appropriately for the output file.                   */
/* -------------------------------------------------------------------- */
    GByte *pabyRawTCB = (GByte *) CPLMalloc(psSrcTCB->raw_bytes);
    
    memcpy( pabyRawTCB, psSrcTCB->raw_data, psSrcTCB->raw_bytes );

    if( !(nCreationFlags & DGNCF_USE_SEED_UNITS) )
    {
        memcpy( pabyRawTCB+1120, pszMasterUnits, 2 );
        memcpy( pabyRawTCB+1122, pszSubUnits, 2 );

        DGN_WRITE_INT32( nUORPerSubUnit, pabyRawTCB+1116 );
        DGN_WRITE_INT32( nSubUnitsPerMasterUnit,pabyRawTCB+1112);
    }
    else
    {
        nUORPerSubUnit = DGN_INT32( pabyRawTCB+1116 );
        nSubUnitsPerMasterUnit = DGN_INT32( pabyRawTCB+1112 );
    }

    if( !(nCreationFlags & DGNCF_USE_SEED_ORIGIN) )
    {
        dfOriginX *= (nUORPerSubUnit * nSubUnitsPerMasterUnit);
        dfOriginY *= (nUORPerSubUnit * nSubUnitsPerMasterUnit);
        dfOriginZ *= (nUORPerSubUnit * nSubUnitsPerMasterUnit);

        memcpy( pabyRawTCB+1240, &dfOriginX, 8 );
        memcpy( pabyRawTCB+1248, &dfOriginY, 8 );
        memcpy( pabyRawTCB+1256, &dfOriginZ, 8 );

        IEEE2DGNDouble( pabyRawTCB+1240 );
        IEEE2DGNDouble( pabyRawTCB+1248 );
        IEEE2DGNDouble( pabyRawTCB+1256 );
    }

/* -------------------------------------------------------------------- */
/*      Write TCB and EOF to new file.                                  */
/* -------------------------------------------------------------------- */
    unsigned char abyEOF[2];
    
    VSIFWrite( pabyRawTCB, psSrcTCB->raw_bytes, 1, fpNew );
    CPLFree( pabyRawTCB );

    abyEOF[0] = 0xff;
    abyEOF[1] = 0xff;
    
    VSIFWrite( abyEOF, 2, 1, fpNew );

    DGNFreeElement( psSeed, psSrcTCB );

/* -------------------------------------------------------------------- */
/*      Close and re-open using DGN API.                                */
/* -------------------------------------------------------------------- */
    VSIFClose( fpNew );

    psDGN = (DGNInfo *) DGNOpen( pszNewFilename, TRUE );

/* -------------------------------------------------------------------- */
/*      Now copy over elements according to options in effect.          */
/* -------------------------------------------------------------------- */
    DGNElemCore *psSrcElement, *psDstElement;

    while( (psSrcElement = DGNReadElement( psSeed )) != NULL )
    {
        if( (nCreationFlags & DGNCF_COPY_WHOLE_SEED_FILE)
            || (psSrcElement->stype == DGNST_COLORTABLE 
                && nCreationFlags & DGNCF_COPY_SEED_FILE_COLOR_TABLE)
            || psSrcElement->element_id <= 2 )
        {
            psDstElement = DGNCloneElement( psSeed, psDGN, psSrcElement );
            DGNWriteElement( psDGN, psDstElement );
            DGNFreeElement( psDGN, psDstElement );
        }

        DGNFreeElement( psSeed, psSrcElement );
    }

    DGNClose( psSeed );
    
    return psDGN;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq 0x10(%rbp), %rax
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movsd %xmm0, -0x28(%rbp)
movsd %xmm1, -0x30(%rbp)
movsd %xmm2, -0x38(%rbp)
movl %ecx, -0x3c(%rbp)
movl %r8d, -0x40(%rbp)
movq %r9, -0x48(%rbp)
movq -0x18(%rbp), %rdi
xorl %esi, %esi
callq 0x177c0
movq %rax, -0x50(%rbp)
cmpq $0x0, -0x50(%rbp)
jne 0x12397
movq $0x0, -0x8(%rbp)
jmp 0x1275e
movq -0x50(%rbp), %rdi
movl $0x1, %esi
callq 0x179d0
movq -0x50(%rbp), %rdi
callq 0xd5e0
movq %rax, -0x68(%rbp)
movq -0x10(%rbp), %rdi
leaq 0x83ad(%rip), %rsi      # 0x1a76a
callq 0x9c80
movq %rax, -0x60(%rbp)
cmpq $0x0, -0x60(%rbp)
jne 0x123f6
movq -0x10(%rbp), %rcx
movl $0x3, %edi
movl $0x4, %esi
leaq 0x838b(%rip), %rdx      # 0x1a76d
movb $0x0, %al
callq 0x5740
movq $0x0, -0x8(%rbp)
jmp 0x1275e
movq -0x68(%rbp), %rax
movslq 0x40(%rax), %rdi
callq 0x3040
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rdi
movq -0x68(%rbp), %rax
movq 0x48(%rax), %rsi
movq -0x68(%rbp), %rax
movslq 0x40(%rax), %rdx
callq 0x2240
movl -0x1c(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
jne 0x1251c
movq -0x70(%rbp), %rax
movq -0x48(%rbp), %rcx
movw (%rcx), %cx
movw %cx, 0x460(%rax)
movq -0x70(%rbp), %rax
movq 0x10(%rbp), %rcx
movw (%rcx), %cx
movw %cx, 0x462(%rax)
movl -0x40(%rbp), %eax
movl %eax, -0x74(%rbp)
movl -0x74(%rbp), %eax
andl $0xff0000, %eax         # imm = 0xFF0000
sarl $0x10, %eax
movb %al, %cl
movq -0x70(%rbp), %rax
movb %cl, 0x45c(%rax)
movl -0x74(%rbp), %eax
andl $0xff000000, %eax       # imm = 0xFF000000
shrl $0x18, %eax
movb %al, %cl
movq -0x70(%rbp), %rax
movb %cl, 0x45d(%rax)
movl -0x74(%rbp), %eax
andl $0xff, %eax
sarl $0x0, %eax
movb %al, %cl
movq -0x70(%rbp), %rax
movb %cl, 0x45e(%rax)
movl -0x74(%rbp), %eax
andl $0xff00, %eax           # imm = 0xFF00
sarl $0x8, %eax
movb %al, %cl
movq -0x70(%rbp), %rax
movb %cl, 0x45f(%rax)
movl -0x3c(%rbp), %eax
movl %eax, -0x78(%rbp)
movl -0x78(%rbp), %eax
andl $0xff0000, %eax         # imm = 0xFF0000
sarl $0x10, %eax
movb %al, %cl
movq -0x70(%rbp), %rax
movb %cl, 0x458(%rax)
movl -0x78(%rbp), %eax
andl $0xff000000, %eax       # imm = 0xFF000000
shrl $0x18, %eax
movb %al, %cl
movq -0x70(%rbp), %rax
movb %cl, 0x459(%rax)
movl -0x78(%rbp), %eax
andl $0xff, %eax
sarl $0x0, %eax
movb %al, %cl
movq -0x70(%rbp), %rax
movb %cl, 0x45a(%rax)
movl -0x78(%rbp), %eax
andl $0xff00, %eax           # imm = 0xFF00
sarl $0x8, %eax
movb %al, %cl
movq -0x70(%rbp), %rax
movb %cl, 0x45b(%rax)
jmp 0x1259e
movq -0x70(%rbp), %rax
movzbl 0x45e(%rax), %eax
movq -0x70(%rbp), %rcx
movzbl 0x45f(%rcx), %ecx
shll $0x8, %ecx
addl %ecx, %eax
movq -0x70(%rbp), %rcx
movzbl 0x45d(%rcx), %ecx
shll $0x10, %ecx
shll $0x8, %ecx
addl %ecx, %eax
movq -0x70(%rbp), %rcx
movzbl 0x45c(%rcx), %ecx
shll $0x10, %ecx
addl %ecx, %eax
movl %eax, -0x40(%rbp)
movq -0x70(%rbp), %rax
movzbl 0x45a(%rax), %eax
movq -0x70(%rbp), %rcx
movzbl 0x45b(%rcx), %ecx
shll $0x8, %ecx
addl %ecx, %eax
movq -0x70(%rbp), %rcx
movzbl 0x459(%rcx), %ecx
shll $0x10, %ecx
shll $0x8, %ecx
addl %ecx, %eax
movq -0x70(%rbp), %rcx
movzbl 0x458(%rcx), %ecx
shll $0x10, %ecx
addl %ecx, %eax
movl %eax, -0x3c(%rbp)
movl -0x1c(%rbp), %eax
andl $0x2, %eax
cmpl $0x0, %eax
jne 0x12649
movl -0x40(%rbp), %eax
imull -0x3c(%rbp), %eax
cvtsi2sd %eax, %xmm0
mulsd -0x28(%rbp), %xmm0
movsd %xmm0, -0x28(%rbp)
movl -0x40(%rbp), %eax
imull -0x3c(%rbp), %eax
cvtsi2sd %eax, %xmm0
mulsd -0x30(%rbp), %xmm0
movsd %xmm0, -0x30(%rbp)
movl -0x40(%rbp), %eax
imull -0x3c(%rbp), %eax
cvtsi2sd %eax, %xmm0
mulsd -0x38(%rbp), %xmm0
movsd %xmm0, -0x38(%rbp)
movq -0x70(%rbp), %rax
movq -0x28(%rbp), %rcx
movq %rcx, 0x4d8(%rax)
movq -0x70(%rbp), %rax
movq -0x30(%rbp), %rcx
movq %rcx, 0x4e0(%rax)
movq -0x70(%rbp), %rax
movq -0x38(%rbp), %rcx
movq %rcx, 0x4e8(%rax)
movq -0x70(%rbp), %rdi
addq $0x4d8, %rdi            # imm = 0x4D8
callq 0xa320
movq -0x70(%rbp), %rdi
addq $0x4e0, %rdi            # imm = 0x4E0
callq 0xa320
movq -0x70(%rbp), %rdi
addq $0x4e8, %rdi            # imm = 0x4E8
callq 0xa320
movq -0x70(%rbp), %rdi
movq -0x68(%rbp), %rax
movslq 0x40(%rax), %rsi
movq -0x60(%rbp), %rcx
movl $0x1, %edx
callq 0x9d80
movq -0x70(%rbp), %rdi
callq 0xa000
movb $-0x1, -0x7a(%rbp)
movb $-0x1, -0x79(%rbp)
leaq -0x7a(%rbp), %rdi
movq -0x60(%rbp), %rcx
movl $0x2, %esi
movl $0x1, %edx
callq 0x9d80
movq -0x50(%rbp), %rdi
movq -0x68(%rbp), %rsi
callq 0x10be0
movq -0x60(%rbp), %rdi
callq 0x9cb0
movq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0x177c0
movq %rax, -0x58(%rbp)
movq -0x50(%rbp), %rdi
callq 0xd5e0
movq %rax, -0x88(%rbp)
cmpq $0x0, %rax
je 0x1274d
movl -0x1c(%rbp), %eax
andl $0x8, %eax
cmpl $0x0, %eax
jne 0x126fd
movq -0x88(%rbp), %rax
cmpl $0x3, 0xc(%rax)
jne 0x126f0
movl -0x1c(%rbp), %eax
andl $0x4, %eax
cmpl $0x0, %eax
jne 0x126fd
movq -0x88(%rbp), %rax
cmpl $0x2, 0x8(%rax)
jg 0x12738
movq -0x50(%rbp), %rdi
movq -0x58(%rbp), %rsi
movq -0x88(%rbp), %rdx
callq 0x12770
movq %rax, -0x90(%rbp)
movq -0x58(%rbp), %rdi
movq -0x90(%rbp), %rsi
callq 0x120d0
movq -0x58(%rbp), %rdi
movq -0x90(%rbp), %rsi
callq 0x10be0
movq -0x50(%rbp), %rdi
movq -0x88(%rbp), %rsi
callq 0x10be0
jmp 0x126b3
movq -0x50(%rbp), %rdi
callq 0x17c20
movq -0x58(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x90, %rsp
popq %rbp
retq
nopl (%rax,%rax)