// File: /workspace/github_c_makefile_star2_O3/phoboslab[P]pl_mpeg/./pl_mpeg.h
// Function: plm_audio_decode_header
int plm_audio_decode_header(plm_audio_t *self) {
	if (!plm_buffer_has(self->buffer, 48)) {
		return 0;
	}

	plm_buffer_skip_bytes(self->buffer, 0x00);
	int sync = plm_buffer_read(self->buffer, 11);


	// Attempt to resync if no syncword was found. This sucks balls. The MP2 
	// stream contains a syncword just before every frame (11 bits set to 1).
	// However, this syncword is not guaranteed to not occur elsewhere in the
	// stream. So, if we have to resync, we also have to check if the header 
	// (samplerate, bitrate) differs from the one we had before. This all
	// may still lead to garbage data being decoded :/

	if (sync != PLM_AUDIO_FRAME_SYNC && !plm_audio_find_frame_sync(self)) {
		return 0;
	}

	self->version = plm_buffer_read(self->buffer, 2);
	self->layer = plm_buffer_read(self->buffer, 2);
	int hasCRC = !plm_buffer_read(self->buffer, 1);

	if (
		self->version != PLM_AUDIO_MPEG_1 ||
		self->layer != PLM_AUDIO_LAYER_II
	) {
		return 0;
	}

	int bitrate_index = plm_buffer_read(self->buffer, 4) - 1;
	if (bitrate_index > 13) {
		return 0;
	}

	int samplerate_index = plm_buffer_read(self->buffer, 2);
	if (samplerate_index == 3) {
		return 0;
	}

	int padding = plm_buffer_read(self->buffer, 1);
	plm_buffer_skip(self->buffer, 1); // f_private
	int mode = plm_buffer_read(self->buffer, 2);

	// If we already have a header, make sure the samplerate, bitrate and mode
	// are still the same, otherwise we might have missed sync.
	if (
		self->has_header && (
			self->bitrate_index != bitrate_index ||
			self->samplerate_index != samplerate_index ||
			self->mode != mode
		)
	) {
		return 0;
	}

	self->bitrate_index = bitrate_index;
	self->samplerate_index = samplerate_index;
	self->mode = mode;
	self->has_header = TRUE;

	// Parse the mode_extension, set up the stereo bound
	if (mode == PLM_AUDIO_MODE_JOINT_STEREO) {
		self->bound = (plm_buffer_read(self->buffer, 2) + 1) << 2;
	}
	else {
		plm_buffer_skip(self->buffer, 2);
		self->bound = (mode == PLM_AUDIO_MODE_MONO) ? 0 : 32;
	}

	// Discard the last 4 bits of the header and the CRC value, if present
	plm_buffer_skip(self->buffer, 4); // copyright(1), original(1), emphasis(2)
	if (hasCRC) {
		plm_buffer_skip(self->buffer, 16);
	}

	// Compute frame size, check if we have enough data to decode the whole
	// frame.
	int bitrate = PLM_AUDIO_BIT_RATE[self->bitrate_index];
	int samplerate = PLM_AUDIO_SAMPLE_RATE[self->samplerate_index];
	int frame_size = (144000 * bitrate / samplerate) + padding;
	return frame_size - (hasCRC ? 6 : 4);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq 0x30(%rdi), %rdi
movl $0x30, %esi
callq 0x41a8
testl %eax, %eax
je 0x71e5
movq 0x30(%rbx), %rdi
xorl %ebp, %ebp
xorl %esi, %esi
callq 0x42c7
movq 0x30(%rbx), %rdi
movl $0xb, %esi
callq 0x4215
cmpl $0x7ff, %eax            # imm = 0x7FF
je 0x70e1
movq %rbx, %rdi
callq 0x7944
testl %eax, %eax
je 0x71e7
movq 0x30(%rbx), %rdi
movl $0x2, %esi
callq 0x4215
movl %eax, 0x14(%rbx)
movq 0x30(%rbx), %rdi
movl $0x2, %esi
callq 0x4215
movl %eax, 0x18(%rbx)
movq 0x30(%rbx), %rdi
movl $0x1, %esi
callq 0x4215
cmpl $0x3, 0x14(%rbx)
jne 0x71e7
cmpl $0x2, 0x18(%rbx)
jne 0x71e7
movl %eax, %r15d
movq 0x30(%rbx), %rdi
movl $0x4, %esi
callq 0x4215
cmpl $0xe, %eax
jg 0x71e7
movl %eax, %r12d
movq 0x30(%rbx), %rdi
movl $0x2, %esi
callq 0x4215
cmpl $0x3, %eax
je 0x71e7
movl %eax, %r13d
movq 0x30(%rbx), %rdi
movl $0x1, %esi
callq 0x4215
movl %eax, 0x4(%rsp)
movq 0x30(%rbx), %r14
movl $0x1, %esi
movq %r14, %rdi
callq 0x41a8
testl %eax, %eax
je 0x7186
incq (%r14)
decl %r12d
movq 0x30(%rbx), %rdi
movl $0x2, %esi
callq 0x4215
movl %eax, %r14d
cmpl $0x0, 0x2c(%rbx)
je 0x71b2
cmpl %r12d, 0x10(%rbx)
jne 0x71e7
cmpl %r13d, 0xc(%rbx)
jne 0x71e7
cmpl %r14d, 0x1c(%rbx)
jne 0x71e7
movl %r12d, 0x10(%rbx)
movl %r13d, 0xc(%rbx)
movl %r14d, 0x1c(%rbx)
movl $0x1, 0x2c(%rbx)
movq 0x30(%rbx), %r12
cmpl $0x1, %r14d
jne 0x71f8
movq %r12, %rdi
movl $0x2, %esi
callq 0x4215
leal 0x4(,%rax,4), %eax
jmp 0x721a
xorl %ebp, %ebp
movl %ebp, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x2, %esi
movq %r12, %rdi
callq 0x41a8
testl %eax, %eax
je 0x720e
addq $0x2, (%r12)
xorl %eax, %eax
cmpl $0x3, %r14d
setne %al
shll $0x5, %eax
movl %eax, 0x20(%rbx)
movq 0x30(%rbx), %r14
movl $0x4, %esi
movq %r14, %rdi
callq 0x41a8
testl %eax, %eax
je 0x7236
addq $0x4, (%r14)
movl $0xfffffffc, %ebp       # imm = 0xFFFFFFFC
testl %r15d, %r15d
jne 0x725e
movq 0x30(%rbx), %r14
movl $0x10, %esi
movq %r14, %rdi
callq 0x41a8
movl $0xfffffffa, %ebp       # imm = 0xFFFFFFFA
testl %eax, %eax
je 0x725e
addq $0x10, (%r14)
movslq 0x10(%rbx), %rax
leaq 0x3187(%rip), %rcx      # 0xa3f0
movswl (%rcx,%rax,2), %eax
movslq 0xc(%rbx), %rcx
leaq 0x1fa8(%rip), %rdx      # 0x9220
movzwl (%rdx,%rcx,2), %ecx
imull $0x23280, %eax, %eax    # imm = 0x23280
cltd
idivl %ecx
addl 0x4(%rsp), %ebp
addl %eax, %ebp
jmp 0x71e7