// File: sisong[P]ApkDiffPatch/lzma/C/Lzma2Enc.c
// Function: Lzma2Enc_EncodeMt1
static SRes Lzma2Enc_EncodeMt1(
    CLzma2Enc *me,
    CLzma2EncInt *p,
    ISeqOutStreamPtr outStream,
    Byte *outBuf, size_t *outBufSize,
    ISeqInStreamPtr inStream,
    const Byte *inData, size_t inDataSize,
    int finished,
    ICompressProgressPtr progress)
{
  UInt64 unpackTotal = 0;
  UInt64 packTotal = 0;
  size_t outLim = 0;
  CLimitedSeqInStream limitedInStream;

  if (outBuf)
  {
    outLim = *outBufSize;
    *outBufSize = 0;
  }

  if (!p->enc)
  {
    p->propsAreSet = False;
    p->enc = LzmaEnc_Create(me->alloc);
    if (!p->enc)
      return SZ_ERROR_MEM;
  }

  limitedInStream.realStream = inStream;
  if (inStream)
  {
    limitedInStream.vt.Read = LimitedSeqInStream_Read;
  }
  
  if (!outBuf)
  {
    // outStream version works only in one thread. So we use CLzma2Enc::tempBufLzma
    if (!me->tempBufLzma)
    {
      me->tempBufLzma = (Byte *)ISzAlloc_Alloc(me->alloc, LZMA2_CHUNK_SIZE_COMPRESSED_MAX);
      if (!me->tempBufLzma)
        return SZ_ERROR_MEM;
    }
  }

  RINOK(Lzma2EncInt_InitStream(p, &me->props))

  for (;;)
  {
    SRes res = SZ_OK;
    SizeT inSizeCur = 0;

    Lzma2EncInt_InitBlock(p);
    
    LimitedSeqInStream_Init(&limitedInStream);
    limitedInStream.limit = me->props.blockSize;

    if (inStream)
    {
      UInt64 expected = (UInt64)(Int64)-1;
      // inStream version works only in one thread. So we use CLzma2Enc::expectedDataSize
      if (me->expectedDataSize != (UInt64)(Int64)-1
          && me->expectedDataSize >= unpackTotal)
        expected = me->expectedDataSize - unpackTotal;
      if (me->props.blockSize != LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID
          && expected > me->props.blockSize)
        expected = (size_t)me->props.blockSize;

      LzmaEnc_SetDataSize(p->enc, expected);

      RINOK(LzmaEnc_PrepareForLzma2(p->enc,
          &limitedInStream.vt,
          LZMA2_KEEP_WINDOW_SIZE,
          me->alloc,
          me->allocBig))
    }
    else
    {
      inSizeCur = (SizeT)(inDataSize - (size_t)unpackTotal);
      if (me->props.blockSize != LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID
          && inSizeCur > me->props.blockSize)
        inSizeCur = (SizeT)(size_t)me->props.blockSize;
    
      // LzmaEnc_SetDataSize(p->enc, inSizeCur);
      
      RINOK(LzmaEnc_MemPrepare(p->enc,
          inData + (size_t)unpackTotal, inSizeCur,
          LZMA2_KEEP_WINDOW_SIZE,
          me->alloc,
          me->allocBig))
    }

    for (;;)
    {
      size_t packSize = LZMA2_CHUNK_SIZE_COMPRESSED_MAX;
      if (outBuf)
        packSize = outLim - (size_t)packTotal;
      
      res = Lzma2EncInt_EncodeSubblock(p,
          outBuf ? outBuf + (size_t)packTotal : me->tempBufLzma, &packSize,
          outBuf ? NULL : outStream);
      
      if (res != SZ_OK)
        break;

      packTotal += packSize;
      if (outBuf)
        *outBufSize = (size_t)packTotal;
      
      res = Progress(progress, unpackTotal + p->srcPos, packTotal);
      if (res != SZ_OK)
        break;

      /*
      if (LzmaEnc_GetNumAvailableBytes(p->enc) == 0)
        break;
      */

      if (packSize == 0)
        break;
    }
    
    LzmaEnc_Finish(p->enc);
    
    unpackTotal += p->srcPos;
    
    RINOK(res)

    if (p->srcPos != (inStream ? limitedInStream.processed : inSizeCur))
      return SZ_ERROR_FAIL;
    
    if (inStream ? limitedInStream.finished : (unpackTotal == inDataSize))
    {
      if (finished)
      {
        if (outBuf)
        {
          const size_t destPos = *outBufSize;
          if (destPos >= outLim)
            return SZ_ERROR_OUTPUT_EOF;
          outBuf[destPos] = LZMA2_CONTROL_EOF; // 0
          *outBufSize = destPos + 1;
        }
        else
        {
          const Byte b = LZMA2_CONTROL_EOF; // 0;
          if (ISeqOutStream_Write(outStream, &b, 1) != 1)
            return SZ_ERROR_WRITE;
        }
      }
      return SZ_OK;
    }
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xf0, %rsp
movq 0x28(%rbp), %rax
movl 0x20(%rbp), %eax
movq 0x18(%rbp), %rax
movq 0x10(%rbp), %rax
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq %r8, -0x30(%rbp)
movq %r9, -0x38(%rbp)
movq $0x0, -0x40(%rbp)
movq $0x0, -0x48(%rbp)
movq $0x0, -0x50(%rbp)
cmpq $0x0, -0x28(%rbp)
je 0x66577
movq -0x30(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x30(%rbp), %rax
movq $0x0, (%rax)
movq -0x18(%rbp), %rax
cmpq $0x0, (%rax)
jne 0x665b8
movq -0x18(%rbp), %rax
movb $0x0, 0x8(%rax)
movq -0x10(%rbp), %rax
movq 0x78(%rax), %rdi
callq 0x679d0
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
movq -0x18(%rbp), %rax
cmpq $0x0, (%rax)
jne 0x665b6
movl $0x2, -0x4(%rbp)
jmp 0x66a18
jmp 0x665b8
movq -0x38(%rbp), %rax
movq %rax, -0x70(%rbp)
cmpq $0x0, -0x38(%rbp)
je 0x665d2
leaq 0x462(%rip), %rax       # 0x66a30
movq %rax, -0x78(%rbp)
cmpq $0x0, -0x28(%rbp)
jne 0x66624
movq -0x10(%rbp), %rax
cmpq $0x0, 0x70(%rax)
jne 0x66622
movq -0x10(%rbp), %rax
movq 0x78(%rax), %rax
movq (%rax), %rax
movq -0x10(%rbp), %rcx
movq 0x78(%rcx), %rdi
movl $0x10010, %esi          # imm = 0x10010
callq *%rax
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x70(%rax)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x70(%rax)
jne 0x66620
movl $0x2, -0x4(%rbp)
jmp 0x66a18
jmp 0x66622
jmp 0x66624
movq -0x18(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq $0x8, %rsi
callq 0x66b00
movl %eax, -0x7c(%rbp)
cmpl $0x0, -0x7c(%rbp)
je 0x66649
movl -0x7c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x66a18
jmp 0x6664b
movl $0x0, -0x80(%rbp)
movq $0x0, -0x88(%rbp)
movq -0x18(%rbp), %rdi
callq 0x66b90
leaq -0x78(%rbp), %rdi
callq 0x66bc0
movq -0x10(%rbp), %rax
movq 0x50(%rax), %rax
movq %rax, -0x68(%rbp)
cmpq $0x0, -0x38(%rbp)
je 0x66745
movq $-0x1, -0x90(%rbp)
movq -0x10(%rbp), %rax
cmpq $-0x1, 0x68(%rax)
je 0x666bd
movq -0x10(%rbp), %rax
movq 0x68(%rax), %rax
cmpq -0x40(%rbp), %rax
jb 0x666bd
movq -0x10(%rbp), %rax
movq 0x68(%rax), %rax
subq -0x40(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x10(%rbp), %rax
cmpq $-0x1, 0x50(%rax)
je 0x666e8
movq -0x90(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x50(%rcx), %rax
jbe 0x666e8
movq -0x10(%rbp), %rax
movq 0x50(%rax), %rax
movq %rax, -0x90(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rdi
movq -0x90(%rbp), %rsi
callq 0x679b0
movq -0x18(%rbp), %rax
movq (%rax), %rdi
leaq -0x78(%rbp), %rsi
movq -0x10(%rbp), %rax
movq 0x78(%rax), %rcx
movq -0x10(%rbp), %rax
movq 0x80(%rax), %r8
movl $0x200000, %edx         # imm = 0x200000
callq 0x67b60
movl %eax, -0x94(%rbp)
cmpl $0x0, -0x94(%rbp)
je 0x66740
movl -0x94(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x66a18
jmp 0x667d1
movq 0x18(%rbp), %rax
subq -0x40(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x10(%rbp), %rax
cmpq $-0x1, 0x50(%rax)
je 0x6677f
movq -0x88(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x50(%rcx), %rax
jbe 0x6677f
movq -0x10(%rbp), %rax
movq 0x50(%rax), %rax
movq %rax, -0x88(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rdi
movq 0x10(%rbp), %rsi
addq -0x40(%rbp), %rsi
movq -0x88(%rbp), %rdx
movq -0x10(%rbp), %rax
movq 0x78(%rax), %r8
movq -0x10(%rbp), %rax
movq 0x80(%rax), %r9
movl $0x200000, %ecx         # imm = 0x200000
callq 0x67c90
movl %eax, -0x98(%rbp)
cmpl $0x0, -0x98(%rbp)
je 0x667cf
movl -0x98(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x66a18
jmp 0x667d1
jmp 0x667d3
movq $0x10010, -0xa0(%rbp) # imm = 0x10010
cmpq $0x0, -0x28(%rbp)
je 0x667f4
movq -0x50(%rbp), %rax
subq -0x48(%rbp), %rax
movq %rax, -0xa0(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0xc0(%rbp)
cmpq $0x0, -0x28(%rbp)
je 0x66817
movq -0x28(%rbp), %rax
addq -0x48(%rbp), %rax
movq %rax, -0xc8(%rbp)
jmp 0x66826
movq -0x10(%rbp), %rax
movq 0x70(%rax), %rax
movq %rax, -0xc8(%rbp)
movq -0xc8(%rbp), %rax
movq %rax, -0xd0(%rbp)
cmpq $0x0, -0x28(%rbp)
je 0x66846
xorl %eax, %eax
movq %rax, -0xd8(%rbp)
jmp 0x66851
movq -0x20(%rbp), %rax
movq %rax, -0xd8(%rbp)
movq -0xd0(%rbp), %rsi
movq -0xc0(%rbp), %rdi
movq -0xd8(%rbp), %rcx
leaq -0xa0(%rbp), %rdx
callq 0x66bf0
movl %eax, -0x80(%rbp)
cmpl $0x0, -0x80(%rbp)
je 0x6687d
jmp 0x668d3
movq -0xa0(%rbp), %rax
addq -0x48(%rbp), %rax
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x28(%rbp)
je 0x6689e
movq -0x48(%rbp), %rcx
movq -0x30(%rbp), %rax
movq %rcx, (%rax)
movq 0x28(%rbp), %rdi
movq -0x40(%rbp), %rsi
movq -0x18(%rbp), %rax
addq 0x10(%rax), %rsi
movq -0x48(%rbp), %rdx
callq 0x67070
movl %eax, -0x80(%rbp)
cmpl $0x0, -0x80(%rbp)
je 0x668c2
jmp 0x668d3
cmpq $0x0, -0xa0(%rbp)
jne 0x668ce
jmp 0x668d3
jmp 0x667d3
movq -0x18(%rbp), %rax
movq (%rax), %rdi
callq 0x67d10
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rax
addq -0x40(%rbp), %rax
movq %rax, -0x40(%rbp)
movl -0x80(%rbp), %eax
movl %eax, -0xa4(%rbp)
cmpl $0x0, -0xa4(%rbp)
je 0x6690f
movl -0xa4(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x66a18
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0xe0(%rbp)
cmpq $0x0, -0x38(%rbp)
je 0x66932
movq -0x60(%rbp), %rax
movq %rax, -0xe8(%rbp)
jmp 0x66940
movq -0x88(%rbp), %rax
movq %rax, -0xe8(%rbp)
movq -0xe0(%rbp), %rax
movq -0xe8(%rbp), %rcx
cmpq %rcx, %rax
je 0x6695f
movl $0xb, -0x4(%rbp)
jmp 0x66a18
cmpq $0x0, -0x38(%rbp)
je 0x66971
cmpl $0x0, -0x58(%rbp)
jne 0x6697f
jmp 0x66a13
movq -0x40(%rbp), %rax
cmpq 0x18(%rbp), %rax
jne 0x66a13
cmpl $0x0, 0x20(%rbp)
je 0x66a0a
cmpq $0x0, -0x28(%rbp)
je 0x669d7
movq -0x30(%rbp), %rax
movq (%rax), %rax
movq %rax, -0xb0(%rbp)
movq -0xb0(%rbp), %rax
cmpq -0x50(%rbp), %rax
jb 0x669b4
movl $0x7, -0x4(%rbp)
jmp 0x66a18
movq -0x28(%rbp), %rax
movq -0xb0(%rbp), %rcx
movb $0x0, (%rax,%rcx)
movq -0xb0(%rbp), %rcx
addq $0x1, %rcx
movq -0x30(%rbp), %rax
movq %rcx, (%rax)
jmp 0x66a08
movb $0x0, -0xb1(%rbp)
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq -0x20(%rbp), %rdi
leaq -0xb1(%rbp), %rsi
movl $0x1, %edx
callq *%rax
cmpq $0x1, %rax
je 0x66a06
movl $0x9, -0x4(%rbp)
jmp 0x66a18
jmp 0x66a08
jmp 0x66a0a
movl $0x0, -0x4(%rbp)
jmp 0x66a18
jmp 0x6664b
movl -0x4(%rbp), %eax
addq $0xf0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)