// File: /workspace/github_c_makefile_star2_O0/smilingthax[P]libfontembed/sfnt_write.c
// Function: otf_write_sfnt
int otf_write_sfnt(struct _OTF_WRITE_INFO *otw,struct _OTF_WRITE_WOFF *woff,OUTPUT_FN output,void *context) // {{{
{
  int iA;
  const int sfntStartSize=12+16*otw->numTables;

  char *sfntStart=malloc(sfntStartSize);
  if (!sfntStart) {
    fprintf(stderr,"Bad alloc: %s\n", strerror(errno));
    return -1;
  }

  // first pass: calculate table directory / offsets and checksums
  unsigned int globalSum=0;
  int offset=sfntStartSize;
  int headAt=-1;
  for (iA=0;iA<otw->numTables;iA++) {
    struct _OTF_WRITE_TABLE *self=otwTableEntry(otw,iA);

    if (self->tag==OTF_TAG('h','e','a','d')) {
      headAt=iA;
    }

    assert(self->action); // must already be filtered out by otf_intersect_tables
    (*self->action)(self);
    self->info.table.offset=offset;

    offset+=otf_padded(self->info.table.length);
    globalSum+=self->info.table.checkSum;
  }

  // the sfnt header
  const int res=otf_write_header(otw,sfntStart);
  assert(res==sfntStartSize);
  globalSum+=otf_checksum(sfntStart,sfntStartSize);

  int ret=0;
  if (!woff) { // simple sfnt
    // write header + directory
    ret=sfntStartSize;
    (*output)(sfntStart,ret,context);
  }
  free(sfntStart);

  // fix head table checksum
  if (headAt!=-1) {
    struct _OTF_WRITE_TABLE *self=otwTableEntry(otw,headAt);
    if (action_load_data(self)!=0) {
      return -1;
    }
    set_ULONG(self->info.data+8,0xb1b0afba-globalSum); // fix global checksum
    // TODO? >modify head time-stamp?
  }

  // pass 1.5: compress data, write woff header
  if (woff) {
    const int origLength=offset;
    const int woffStartSize=44+20*otw->numTables;

    offset=woffStartSize;
    for (iA=0;iA<otw->numTables;iA++) {
      struct _OTF_WRITE_TABLE *self=otwTableEntry(otw,iA);
      if ( (action_load_data(self)!=0)||
           (action_hlp_compress(self)!=0) ) {
        ret=-1;
        goto done;
      }
      self->info.table.offset=offset;
      offset+=otf_padded(self->info.table.compLength);
    }

    OTF_WOFF_HEADER woffHdr;
    if (otf_prepare_woff_header(&woffHdr,woff,origLength,offset)!=0) {
      ret=-1;
      goto done;
    }
    offset=woffHdr.length;
    ret=otf_write_woff_header(otw,&woffHdr,output,context);
    assert(ret==woffStartSize);
  }

  // second pass: write tables
  for (iA=0;iA<otw->numTables;iA++) {
    struct _OTF_WRITE_TABLE *self=otwTableEntry(otw,iA);
    if (action_load_data(self)!=0) {
      ret=-1;
      goto done;
    }

    const int pad_len=otf_padded(self->info.table.compLength);
    (*output)(self->info.data,pad_len,context);

    (*self->info.free)(self);
    ret+=pad_len;
  }

  if (woff) {
    ret+=otf_write_woff_footer(woff,output,context);
  }
  assert(ret==offset);

done:
  if (ret==-1) {
    for (iA=0;iA<otw->numTables;iA++) {
      (*otw->tables[iA].info.free)(&otw->tables[iA]);
    }
  }
  if (woff) {
    free(woff->metaCompData);
    woff->metaCompData=NULL;
  }
  return ret;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq -0x10(%rbp), %rax
movzwl 0x4(%rax), %eax
shll $0x4, %eax
addl $0xc, %eax
movl %eax, -0x30(%rbp)
movslq -0x30(%rbp), %rdi
callq 0x21d0
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
jne 0xc3a1
movq 0x6c79(%rip), %rax      # 0x12fe0
movq (%rax), %rax
movq %rax, -0xa8(%rbp)
callq 0x2040
movl (%rax), %edi
callq 0x2070
movq -0xa8(%rbp), %rdi
movq %rax, %rdx
leaq 0x1fce(%rip), %rsi      # 0xe35c
movb $0x0, %al
callq 0x21e0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xc7a4
movl $0x0, -0x3c(%rbp)
movl -0x30(%rbp), %eax
movl %eax, -0x40(%rbp)
movl $0xffffffff, -0x44(%rbp) # imm = 0xFFFFFFFF
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
movq -0x10(%rbp), %rcx
movzwl 0x4(%rcx), %ecx
cmpl %ecx, %eax
jge 0xc463
movq -0x10(%rbp), %rdi
movl -0x2c(%rbp), %esi
callq 0xc7b0
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
cmpq $0x68656164, (%rax)     # imm = 0x68656164
jne 0xc3f2
movl -0x2c(%rbp), %eax
movl %eax, -0x44(%rbp)
movq -0x50(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0xc3ff
jmp 0xc41e
leaq 0x3787(%rip), %rdi      # 0xfb8d
leaq 0x3740(%rip), %rsi      # 0xfb4d
movl $0x1ac, %edx            # imm = 0x1AC
leaq 0x3781(%rip), %rcx      # 0xfb9a
callq 0x2100
movq -0x50(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x50(%rbp), %rdi
callq *%rax
movl -0x40(%rbp), %ecx
movq -0x50(%rbp), %rax
movl %ecx, 0x30(%rax)
movq -0x50(%rbp), %rax
movl 0x34(%rax), %edi
callq 0xc2f0
addl -0x40(%rbp), %eax
movl %eax, -0x40(%rbp)
movq -0x50(%rbp), %rax
movl 0x2c(%rax), %eax
addl -0x3c(%rbp), %eax
movl %eax, -0x3c(%rbp)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0xc3bc
movq -0x10(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0xc810
movl %eax, -0x54(%rbp)
movl -0x54(%rbp), %eax
cmpl -0x30(%rbp), %eax
jne 0xc47d
jmp 0xc49c
leaq 0x3770(%rip), %rdi      # 0xfbf4
leaq 0x36c2(%rip), %rsi      # 0xfb4d
movl $0x1b6, %edx            # imm = 0x1B6
leaq 0x3703(%rip), %rcx      # 0xfb9a
callq 0x2100
movq -0x38(%rbp), %rdi
movl -0x30(%rbp), %esi
callq 0xc290
addl -0x3c(%rbp), %eax
movl %eax, -0x3c(%rbp)
movl $0x0, -0x58(%rbp)
cmpq $0x0, -0x18(%rbp)
jne 0xc4d3
movl -0x30(%rbp), %eax
movl %eax, -0x58(%rbp)
movq -0x20(%rbp), %rax
movq -0x38(%rbp), %rdi
movl -0x58(%rbp), %esi
movq -0x28(%rbp), %rdx
callq *%rax
movq -0x38(%rbp), %rdi
callq 0x21b0
cmpl $-0x1, -0x44(%rbp)
je 0xc525
movq -0x10(%rbp), %rdi
movl -0x44(%rbp), %esi
callq 0xc7b0
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rdi
callq 0xc970
cmpl $0x0, %eax
je 0xc50c
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xc7a4
movq -0x60(%rbp), %rax
movq 0x20(%rax), %rdi
addq $0x8, %rdi
movl $0xb1b0afba, %esi       # imm = 0xB1B0AFBA
subl -0x3c(%rbp), %esi
callq 0xca00
cmpq $0x0, -0x18(%rbp)
je 0xc638
movl -0x40(%rbp), %eax
movl %eax, -0x64(%rbp)
movq -0x10(%rbp), %rax
movzwl 0x4(%rax), %eax
imull $0x14, %eax, %eax
addl $0x2c, %eax
movl %eax, -0x68(%rbp)
movl -0x68(%rbp), %eax
movl %eax, -0x40(%rbp)
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
movq -0x10(%rbp), %rcx
movzwl 0x4(%rcx), %ecx
cmpl %ecx, %eax
jge 0xc5c2
movq -0x10(%rbp), %rdi
movl -0x2c(%rbp), %esi
callq 0xc7b0
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rdi
callq 0xc970
cmpl $0x0, %eax
jne 0xc58f
movq -0x70(%rbp), %rdi
callq 0xca60
cmpl $0x0, %eax
je 0xc59b
movl $0xffffffff, -0x58(%rbp) # imm = 0xFFFFFFFF
jmp 0xc729
movl -0x40(%rbp), %ecx
movq -0x70(%rbp), %rax
movl %ecx, 0x30(%rax)
movq -0x70(%rbp), %rax
movl 0x38(%rax), %edi
callq 0xc2f0
addl -0x40(%rbp), %eax
movl %eax, -0x40(%rbp)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0xc554
movq -0x18(%rbp), %rsi
movl -0x64(%rbp), %edx
movl -0x40(%rbp), %ecx
leaq -0x90(%rbp), %rdi
callq 0xcb40
cmpl $0x0, %eax
je 0xc5e9
movl $0xffffffff, -0x58(%rbp) # imm = 0xFFFFFFFF
jmp 0xc729
movl -0x90(%rbp), %eax
movl %eax, -0x40(%rbp)
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rdx
movq -0x28(%rbp), %rcx
leaq -0x90(%rbp), %rsi
callq 0xccb0
movl %eax, -0x58(%rbp)
movl -0x58(%rbp), %eax
cmpl -0x68(%rbp), %eax
jne 0xc617
jmp 0xc636
leaq 0x35e9(%rip), %rdi      # 0xfc07
leaq 0x3528(%rip), %rsi      # 0xfb4d
movl $0x1e3, %edx            # imm = 0x1E3
leaq 0x3569(%rip), %rcx      # 0xfb9a
callq 0x2100
jmp 0xc638
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
movq -0x10(%rbp), %rcx
movzwl 0x4(%rcx), %ecx
cmpl %ecx, %eax
jge 0xc6e0
movq -0x10(%rbp), %rdi
movl -0x2c(%rbp), %esi
callq 0xc7b0
movq %rax, -0x98(%rbp)
movq -0x98(%rbp), %rdi
callq 0xc970
cmpl $0x0, %eax
je 0xc682
movl $0xffffffff, -0x58(%rbp) # imm = 0xFFFFFFFF
jmp 0xc729
movq -0x98(%rbp), %rax
movl 0x38(%rax), %edi
callq 0xc2f0
movl %eax, -0x9c(%rbp)
movq -0x20(%rbp), %rax
movq -0x98(%rbp), %rcx
movq 0x20(%rcx), %rdi
movl -0x9c(%rbp), %esi
movq -0x28(%rbp), %rdx
callq *%rax
movq -0x98(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x98(%rbp), %rdi
callq *%rax
movl -0x9c(%rbp), %eax
addl -0x58(%rbp), %eax
movl %eax, -0x58(%rbp)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0xc63f
cmpq $0x0, -0x18(%rbp)
je 0xc6fe
movq -0x18(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq 0xceb0
addl -0x58(%rbp), %eax
movl %eax, -0x58(%rbp)
movl -0x58(%rbp), %eax
cmpl -0x40(%rbp), %eax
jne 0xc708
jmp 0xc727
leaq 0x350b(%rip), %rdi      # 0xfc1a
leaq 0x3437(%rip), %rsi      # 0xfb4d
movl $0x1f8, %edx            # imm = 0x1F8
leaq 0x3478(%rip), %rcx      # 0xfb9a
callq 0x2100
jmp 0xc729
cmpl $-0x1, -0x58(%rbp)
jne 0xc77e
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
movq -0x10(%rbp), %rcx
movzwl 0x4(%rcx), %ecx
cmpl %ecx, %eax
jge 0xc77c
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x50, %rcx, %rcx
addq %rcx, %rax
movq 0x48(%rax), %rax
movq -0x10(%rbp), %rcx
movq 0x8(%rcx), %rdi
movslq -0x2c(%rbp), %rcx
imulq $0x50, %rcx, %rcx
addq %rcx, %rdi
callq *%rax
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0xc736
jmp 0xc77e
cmpq $0x0, -0x18(%rbp)
je 0xc79e
movq -0x18(%rbp), %rax
movq 0x28(%rax), %rdi
callq 0x21b0
movq -0x18(%rbp), %rax
movq $0x0, 0x28(%rax)
movl -0x58(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0xb0, %rsp
popq %rbp
retq