// File: /workspace/github_cpp_makefile_star2_O2/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, %r13
movq %rsi, %rdi
callq 0xa990
testb %al, %al
je 0x5028
movq (%r14), %rdi
addq $0x6, %rdi
callq 0xaf25
movl %eax, %ebx
movl %eax, 0x4(%rsp)
movq (%r14), %rdi
addq $0xa, %rdi
callq 0xb036
movq %rax, %r15
movq (%r14), %rdi
addq $0x12, %rdi
callq 0xb0a3
movq %rax, %r12
leaq 0x2a(,%r15,2), %rax
cmpq %rax, 0x8(%r14)
jge 0x4e74
movq 0x10188(%rip), %rdi     # 0x14ff0
leaq 0x93ab(%rip), %rsi      # 0xe21a
jmp 0x4fcc
cmpq $0x5555554, %r15        # imm = 0x5555554
jl 0x4e90
movq 0x1016c(%rip), %rdi     # 0x14ff0
leaq 0x93da(%rip), %rsi      # 0xe265
jmp 0x4fcc
testq %r12, %r12
je 0x4fa5
movq %r13, 0x20(%rsp)
pushq $0x18
popq %rdi
callq 0x4350
movslq %r15d, %rsi
xorps %xmm0, %xmm0
movups %xmm0, (%rax)
andq $0x0, 0x10(%rax)
movq %rax, 0x8(%rsp)
movq %rax, %rdi
callq 0x52ac
movq (%r14), %rbx
addq $0x2a, %rbx
xorl %ebp, %ebp
testq %r15, %r15
cmovleq %rbp, %r15
xorl %r13d, %r13d
subq $0x1, %r15
jb 0x4f54
movq (%r14), %rax
addq 0x8(%r14), %rax
cmpq %rax, %rbx
jae 0x5009
andq $0x0, 0x18(%rsp)
movq %rbx, %rdi
leaq 0x18(%rsp), %rsi
callq 0x995b
movq (%r14), %rcx
addq 0x8(%r14), %rcx
cmpq %rcx, %rax
jae 0x4fea
addq 0x18(%rsp), %rbp
andq $0x0, 0x10(%rsp)
movq %rax, %rdi
leaq 0x10(%rsp), %rsi
callq 0x995b
addq 0x10(%rsp), %r13
movq %rax, %rbx
imulq $0x3e8, %r13, %rax      # imm = 0x3E8
cqto
idivq %r12
movq %rbp, 0x28(%rsp)
movq %rax, 0x30(%rsp)
movq 0x8(%rsp), %rdi
leaq 0x28(%rsp), %rsi
callq 0x6e9a
jmp 0x4ed4
leaq 0x4(%rsp), %rbx
movq 0x20(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rsi
callq 0x5354
movq 0x8(%rsp), %r15
movq %r15, (%rax)
movq %r14, %rdi
movq %rbx, %rsi
callq 0x5354
movq %rax, %rcx
movb $0x1, %al
cmpq %r15, (%rcx)
je 0x4fdb
leaq 0x9370(%rip), %rdi      # 0xe2fd
leaq 0x9079(%rip), %rsi      # 0xe00d
leaq 0x924f(%rip), %rcx      # 0xe1ea
movl $0x43d, %edx            # imm = 0x43D
callq 0x4210
movq 0x10044(%rip), %rdi     # 0x14ff0
leaq 0x92e7(%rip), %rsi      # 0xe29a
callq 0x4340
movl %ebx, %esi
movq %rax, %rdi
callq 0x4240
leaq 0x92f3(%rip), %rsi      # 0xe2bc
movq %rax, %rdi
callq 0x4340
movq %rax, %rdi
callq 0x41b0
xorl %eax, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x92e9(%rip), %rdi      # 0xe2da
leaq 0x9015(%rip), %rsi      # 0xe00d
leaq 0x91eb(%rip), %rcx      # 0xe1ea
movl $0x432, %edx            # imm = 0x432
callq 0x4210
leaq 0x92ca(%rip), %rdi      # 0xe2da
leaq 0x8ff6(%rip), %rsi      # 0xe00d
leaq 0x91cc(%rip), %rcx      # 0xe1ea
movl $0x42c, %edx            # imm = 0x42C
callq 0x4210
leaq 0x91a5(%rip), %rdi      # 0xe1d4
leaq 0x8fd7(%rip), %rsi      # 0xe00d
leaq 0x91ad(%rip), %rcx      # 0xe1ea
movl $0x406, %edx            # imm = 0x406
callq 0x4210
nop