// File: /workspace/github_cpp_makefile_star2_O3/cpearce[P]OggIndex/src/Decoder.cpp
// Function: DecodeIndex(std::map<unsigned int, std::vector<KeyFrameInfo, std::allocator<KeyFrameInfo>>*, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, std::vector<KeyFrameInfo, std::allocator<KeyFrameInfo>>*>>>&, ogg_packet*)
bool DecodeIndex(KeyFrameIndex& index, ogg_packet* packet) {
  assert(IsIndexPacket(packet));
  ogg_uint32_t serialno = LEUint32(packet->packet + INDEX_SERIALNO_OFFSET);
  ogg_int64_t numKeyPoints = LEUint64(packet->packet + INDEX_NUM_KEYPOINTS_OFFSET);
  ogg_int64_t time_denom = LEInt64(packet->packet + INDEX_TIME_DENOM_OFFSET);
  ogg_int64_t time_multiplier = 1000;

  // Ensure that the packet's not smaller or significantly larger than
  // we expect. These cases denote a malicious or invalid num_key_points
  // field.
  ogg_int64_t min_packet_size = INDEX_KEYPOINT_OFFSET + numKeyPoints * MIN_KEY_POINT_SIZE;
  if (packet->bytes < min_packet_size) {
    // Packet is less than the theoretical minimum size. This means that the
    // num_key_points field is too large for the packet to possibly contain as
    // many packets as it claims to, so the num_key_points field is probably
    // malicious. Don't try decoding this file, we may run out of memory.
    cerr << "WARNING: Possibly malicious number of key points reported in index packet." << endl;
    return false;
  }
  ogg_int64_t max_packet_size = INDEX_KEYPOINT_OFFSET + numKeyPoints * MAX_KEY_POINT_SIZE;
  if (max_packet_size > INT_MAX) {
    cerr << "ERROR: I can't handle index sizes greater than 2^32." << endl;
    return false;
  }

  if (time_denom == 0) {
    cerr << "WARNING: Index packet for stream " << serialno
         << " has 0 timestamp denominator." << endl;
    return false;
  }

  vector<KeyFrameInfo>* keypoints = new vector<KeyFrameInfo>();
  keypoints->reserve((ogg_int32_t)numKeyPoints);
    
  /* Read in key points. */
  unsigned char* p = packet->packet + INDEX_KEYPOINT_OFFSET;
  ogg_int64_t offset = 0;
  ogg_int64_t time = 0;
  for (ogg_int64_t i=0; i<numKeyPoints; i++) {
    assert(p < packet->packet + packet->bytes);

    ogg_int64_t offset_delta = 0;
    p = ReadVariableLength(p, &offset_delta);
    offset += offset_delta;

    assert(p < packet->packet + packet->bytes);
    ogg_int64_t time_delta = 0;
    p = ReadVariableLength(p, &time_delta);
    time += time_delta;
    ogg_int64_t time_ms = (time * time_multiplier) / time_denom;    
    
    keypoints->push_back(KeyFrameInfo(offset, time_ms));
  }
  
  index[serialno] = keypoints;
  
  assert(index[serialno] == keypoints);
  
  return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rsi, %r14
movq %rdi, %r12
movq %rsi, %rdi
callq 0xc15e
testb %al, %al
je 0x5276
movq (%r14), %rdi
addq $0x6, %rdi
callq 0xc7dd
movl %eax, %ebx
movl %eax, 0x4(%rsp)
movq (%r14), %rdi
addq $0xa, %rdi
callq 0xc8ef
movq %rax, %r15
movq (%r14), %rdi
addq $0x12, %rdi
callq 0xc95a
movq %rax, 0x8(%rsp)
leaq 0x2a(,%r15,2), %rax
cmpq %rax, 0x8(%r14)
jge 0x5064
movq 0x11f9a(%rip), %rbx     # 0x16ff0
leaq 0xb1bd(%rip), %rsi      # 0x1021a
movl $0x4a, %edx
jmp 0x5080
cmpq $0x5555554, %r15        # imm = 0x5555554
jl 0x50c0
movq 0x11f7c(%rip), %rbx     # 0x16ff0
leaq 0xb1ea(%rip), %rsi      # 0x10265
movl $0x34, %edx
movq %rbx, %rdi
callq 0x4410
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x4360
movsbl %al, %esi
movq %rbx, %rdi
callq 0x4040
movq %rax, %rdi
callq 0x4250
xorl %eax, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpq $0x0, 0x8(%rsp)
je 0x51fc
movq %r12, 0x20(%rsp)
movl $0x18, %edi
callq 0x4380
movq %rax, %r13
movslq %r15d, %rsi
xorps %xmm0, %xmm0
movups %xmm0, (%rax)
movq $0x0, 0x10(%rax)
movq %rax, %rdi
callq 0x5524
testq %r15, %r15
jle 0x51ac
movq (%r14), %rbp
addq $0x2a, %rbp
xorl %ebx, %ebx
xorl %r12d, %r12d
movq (%r14), %rax
addq 0x8(%r14), %rax
cmpq %rax, %rbp
jae 0x5257
movq $0x0, 0x18(%rsp)
movq %rbp, %rdi
leaq 0x18(%rsp), %rsi
callq 0xad0d
movq (%r14), %rcx
addq 0x8(%r14), %rcx
cmpq %rcx, %rax
jae 0x5238
addq 0x18(%rsp), %r12
movq $0x0, 0x10(%rsp)
movq %rax, %rdi
leaq 0x10(%rsp), %rsi
callq 0xad0d
movq %rax, %rbp
addq 0x10(%rsp), %rbx
imulq $0x3e8, %rbx, %rax      # imm = 0x3E8
cqto
idivq 0x8(%rsp)
movq %r12, 0x28(%rsp)
movq %rax, 0x30(%rsp)
movq 0x8(%r13), %rsi
cmpq 0x10(%r13), %rsi
je 0x5196
movups 0x28(%rsp), %xmm0
movups %xmm0, (%rsi)
addq $0x10, 0x8(%r13)
jmp 0x51a3
movq %r13, %rdi
leaq 0x28(%rsp), %rdx
callq 0x7502
decq %r15
jne 0x510c
leaq 0x4(%rsp), %rbx
movq 0x20(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rsi
callq 0x55cc
movq %r13, (%rax)
movq %r14, %rdi
movq %rbx, %rsi
callq 0x55cc
movq %rax, %rcx
movb $0x1, %al
cmpq %r13, (%rcx)
je 0x50b1
leaq 0xb119(%rip), %rdi      # 0x102fd
leaq 0xae22(%rip), %rsi      # 0x1000d
leaq 0xaff8(%rip), %rcx      # 0x101ea
movl $0x43d, %edx            # imm = 0x43D
callq 0x4210
movq 0x11ded(%rip), %r14     # 0x16ff0
leaq 0xb090(%rip), %rsi      # 0x1029a
movl $0x21, %edx
movq %r14, %rdi
callq 0x4410
movl %ebx, %esi
movq %r14, %rdi
callq 0x4240
movq %rax, %rbx
leaq 0xb091(%rip), %rsi      # 0x102bc
movl $0x1d, %edx
movq %rax, %rdi
jmp 0x5083
leaq 0xb09b(%rip), %rdi      # 0x102da
leaq 0xadc7(%rip), %rsi      # 0x1000d
leaq 0xaf9d(%rip), %rcx      # 0x101ea
movl $0x432, %edx            # imm = 0x432
callq 0x4210
leaq 0xb07c(%rip), %rdi      # 0x102da
leaq 0xada8(%rip), %rsi      # 0x1000d
leaq 0xaf7e(%rip), %rcx      # 0x101ea
movl $0x42c, %edx            # imm = 0x42C
callq 0x4210
leaq 0xaf57(%rip), %rdi      # 0x101d4
leaq 0xad89(%rip), %rsi      # 0x1000d
leaq 0xaf5f(%rip), %rcx      # 0x101ea
movl $0x406, %edx            # imm = 0x406
callq 0x4210
nop