// File: /workspace/github_c_makefile_star2_O2/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
pushq $0x30
popq %rsi
callq 0x3b9d
testl %eax, %eax
je 0x66cd
movq 0x30(%rbx), %rdi
xorl %ebp, %ebp
xorl %esi, %esi
callq 0x3cb2
movq 0x30(%rbx), %rdi
pushq $0xb
popq %rsi
callq 0x3c08
cmpl $0x7ff, %eax            # imm = 0x7FF
je 0x65e8
movq %rbx, %rdi
callq 0x6cfd
testl %eax, %eax
je 0x66cf
movq 0x30(%rbx), %rdi
pushq $0x2
popq %r14
movl %r14d, %esi
callq 0x3c08
movl %eax, 0x14(%rbx)
movq 0x30(%rbx), %rdi
movl %r14d, %esi
callq 0x3c08
movl %eax, 0x18(%rbx)
movq 0x30(%rbx), %rdi
pushq $0x1
popq %rsi
callq 0x3c08
cmpl $0x3, 0x14(%rbx)
jne 0x66cf
cmpl $0x2, 0x18(%rbx)
jne 0x66cf
movl %eax, %r14d
movq 0x30(%rbx), %rdi
pushq $0x4
popq %rsi
callq 0x3c08
cmpl $0xe, %eax
jg 0x66cf
movl %eax, %r12d
movq 0x30(%rbx), %rdi
pushq $0x2
popq %rsi
callq 0x3c08
cmpl $0x3, %eax
je 0x66cf
movl %eax, %r13d
decl %r12d
movq 0x30(%rbx), %rdi
pushq $0x1
popq %rsi
callq 0x3c08
movl %eax, 0x4(%rsp)
movq 0x30(%rbx), %rdi
pushq $0x1
popq %rsi
callq 0x3c94
movq 0x30(%rbx), %rdi
pushq $0x2
popq %rsi
callq 0x3c08
movl %eax, %r15d
cmpl $0x0, 0x2c(%rbx)
je 0x669f
cmpl %r12d, 0x10(%rbx)
jne 0x66cf
cmpl %r13d, 0xc(%rbx)
jne 0x66cf
cmpl %r15d, 0x1c(%rbx)
jne 0x66cf
movl %r12d, 0x10(%rbx)
movl %r13d, 0xc(%rbx)
movl %r15d, 0x1c(%rbx)
movl $0x1, 0x2c(%rbx)
movq 0x30(%rbx), %rdi
cmpl $0x1, %r15d
jne 0x66e0
pushq $0x2
popq %rsi
callq 0x3c08
leal 0x4(,%rax,4), %eax
jmp 0x66f4
xorl %ebp, %ebp
movl %ebp, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $0x2
popq %rsi
callq 0x3c94
xorl %eax, %eax
cmpl $0x3, %r15d
setne %al
shll $0x5, %eax
movl %eax, 0x20(%rbx)
movq 0x30(%rbx), %rdi
pushq $0x4
popq %rsi
callq 0x3c94
testl %r14d, %r14d
je 0x670c
pushq $-0x4
jmp 0x671a
movq 0x30(%rbx), %rdi
pushq $0x10
popq %rsi
callq 0x3c94
pushq $-0x6
popq %rbp
movslq 0x10(%rbx), %rax
leaq 0x2c8a(%rip), %rcx      # 0x93b0
movswl (%rcx,%rax,2), %eax
movslq 0xc(%rbx), %rcx
leaq 0x1a9b(%rip), %rdx      # 0x81d0
movzwl (%rdx,%rcx,2), %ecx
imull $0x23280, %eax, %eax    # imm = 0x23280
cltd
idivl %ecx
addl 0x4(%rsp), %ebp
addl %eax, %ebp
jmp 0x66cf