// File: /workspace/github_c_makefile_star2_O1/phoboslab[P]pl_mpeg/./pl_mpeg.h
// Function: plm_video_decode_block
void plm_video_decode_block(plm_video_t *self, int block) {

	int n = 0;
	uint8_t *quant_matrix;

	// Decode DC coefficient of intra-coded blocks
	if (self->macroblock_intra) {
		int predictor;
		int dct_size;

		// DC prediction
		int plane_index = block > 3 ? block - 3 : 0;
		predictor = self->dc_predictor[plane_index];
		dct_size = plm_buffer_read_vlc(self->buffer, PLM_VIDEO_DCT_SIZE[plane_index]);

		// Read DC coeff
		if (dct_size > 0) {
			int differential = plm_buffer_read(self->buffer, dct_size);
			if ((differential & (1 << (dct_size - 1))) != 0) {
				self->block_data[0] = predictor + differential;
			}
			else {
				self->block_data[0] = predictor + (-(1 << dct_size) | (differential + 1));
			}
		}
		else {
			self->block_data[0] = predictor;
		}

		// Save predictor value
		self->dc_predictor[plane_index] = self->block_data[0];

		// Dequantize + premultiply
		self->block_data[0] <<= (3 + 5);

		quant_matrix = self->intra_quant_matrix;
		n = 1;
	}
	else {
		quant_matrix = self->non_intra_quant_matrix;
	}

	// Decode AC coefficients (+DC for non-intra)
	int level = 0;
	while (TRUE) {
		int run = 0;
		uint16_t coeff = plm_buffer_read_vlc_uint(self->buffer, PLM_VIDEO_DCT_COEFF);

		if ((coeff == 0x0001) && (n > 0) && (plm_buffer_read(self->buffer, 1) == 0)) {
			// end_of_block
			break;
		}
		if (coeff == 0xffff) {
			// escape
			run = plm_buffer_read(self->buffer, 6);
			level = plm_buffer_read(self->buffer, 8);
			if (level == 0) {
				level = plm_buffer_read(self->buffer, 8);
			}
			else if (level == 128) {
				level = plm_buffer_read(self->buffer, 8) - 256;
			}
			else if (level > 128) {
				level = level - 256;
			}
		}
		else {
			run = coeff >> 8;
			level = coeff & 0xff;
			if (plm_buffer_read(self->buffer, 1)) {
				level = -level;
			}
		}

		n += run;
		if (n < 0 || n >= 64) {
			return; // invalid
		}

		int de_zig_zagged = PLM_VIDEO_ZIG_ZAG[n];
		n++;

		// Dequantize, oddify, clip
		level = (unsigned)level << 1;
		if (!self->macroblock_intra) {
			level += (level < 0 ? -1 : 1);
		}
		level = (level * self->quantizer_scale * quant_matrix[de_zig_zagged]) >> 4;
		if ((level & 1) == 0) {
			level -= level > 0 ? 1 : -1;
		}
		if (level > 2047) {
			level = 2047;
		}
		else if (level < -2048) {
			level = -2048;
		}

		// Save premultiplied coefficient
		self->block_data[de_zig_zagged] = level * PLM_VIDEO_PREMULTIPLIER_MATRIX[de_zig_zagged];
	}

	// Move block to its place
	uint8_t *d;
	int dw;
	int di;

	if (block < 4) {
		d = self->frame_current.y.data;
		dw = self->luma_width;
		di = (self->mb_row * self->luma_width + self->mb_col) << 4;
		if ((block & 1) != 0) {
			di += 8;
		}
		if ((block & 2) != 0) {
			di += self->luma_width << 3;
		}
	}
	else {
		d = (block == 4) ? self->frame_current.cb.data : self->frame_current.cr.data;
		dw = self->chroma_width;
		di = ((self->mb_row * self->luma_width) << 2) + (self->mb_col << 3);
	}

	int *s = self->block_data;
	int si = 0;
	if (self->macroblock_intra) {
		// Overwrite (no prediction)
		if (n == 1) {
			int clamped = plm_clamp((s[0] + 128) >> 8);
			PLM_BLOCK_SET(d, di, dw, si, 8, 8, clamped);
			s[0] = 0;
		}
		else {
			plm_video_idct(s);
			PLM_BLOCK_SET(d, di, dw, si, 8, 8, plm_clamp(s[si]));
			memset(self->block_data, 0, sizeof(self->block_data));
		}
	}
	else {
		// Add data to the predicted macroblock
		if (n == 1) {
			int value = (s[0] + 128) >> 8;
			PLM_BLOCK_SET(d, di, dw, si, 8, 8, plm_clamp(d[di] + value));
			s[0] = 0;
		}
		else {
			plm_video_idct(s);
			PLM_BLOCK_SET(d, di, dw, si, 8, 8, plm_clamp(d[di] + s[si]));
			memset(self->block_data, 0, sizeof(self->block_data));
		}
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
cmpl $0x0, 0x8c(%rdi)
movq %rsi, (%rsp)
je 0x53bb
leal -0x3(%rsi), %ecx
xorl %eax, %eax
cmpl $0x4, %esi
cmovll %eax, %ecx
movslq %ecx, %r14
movl 0x90(%rbx,%r14,4), %ebp
movq 0xa0(%rbx), %r15
leaq 0x8a93(%rip), %rcx      # 0xddd0
movq (%rcx,%r14,8), %r12
movzwl %ax, %r13d
movq %r15, %rdi
movl $0x1, %esi
callq 0x43f5
addl %r13d, %eax
movslq %eax, %rcx
movzwl (%r12,%rcx,4), %eax
testw %ax, %ax
jg 0x5341
movswl 0x2(%r12,%rcx,4), %r15d
testl %r15d, %r15d
jle 0x5398
movq 0xa0(%rbx), %rdi
movl %r15d, %esi
callq 0x43f5
leal -0x1(%r15), %ecx
movzbl %cl, %ecx
btl %ecx, %eax
jb 0x5396
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movl %r15d, %ecx
shll %cl, %edx
incl %eax
orl %edx, %eax
addl %eax, %ebp
movl %ebp, 0x178(%rbx)
movl %ebp, 0x90(%rbx,%r14,4)
shll $0x8, 0x178(%rbx)
movl $0x1, %r12d
movl $0x278, %r13d           # imm = 0x278
jmp 0x53c4
xorl %r12d, %r12d
movl $0x2b8, %r13d           # imm = 0x2B8
addq %rbx, %r13
leaq 0x4262(%rip), %r14      # 0x9630
movq 0xa0(%rbx), %r15
xorl %eax, %eax
movzwl %ax, %ebp
movq %r15, %rdi
movl $0x1, %esi
callq 0x43f5
addl %ebp, %eax
movslq %eax, %rcx
movzwl (%r14,%rcx,4), %eax
testw %ax, %ax
jg 0x53d7
movzwl 0x2(%r14,%rcx,4), %r15d
cmpl $0x1, %r15d
jne 0x5420
testl %r12d, %r12d
jle 0x5420
movq 0xa0(%rbx), %rdi
movl $0x1, %esi
callq 0x43f5
testl %eax, %eax
je 0x552c
cmpl $0xffff, %r15d          # imm = 0xFFFF
je 0x54e5
movl %r15d, %ebp
shrl $0x8, %ebp
movzbl %r15b, %r15d
movq 0xa0(%rbx), %rdi
movl $0x1, %esi
callq 0x43f5
movl %eax, %ecx
movl %r15d, %eax
negl %eax
testl %ecx, %ecx
cmovel %r15d, %eax
addl %ebp, %r12d
movl $0x1, %ecx
cmpl $0x3f, %r12d
ja 0x5531
movl %r12d, %edx
incl %r12d
leal (%rax,%rax), %esi
sarl $0x1f, %esi
orl $0x1, %esi
xorl %ecx, %ecx
cmpl %ecx, 0x8c(%rbx)
cmovnel %ecx, %esi
leal (%rsi,%rax,2), %eax
imull 0x74(%rbx), %eax
leaq 0x3cd1(%rip), %rsi      # 0x9160
movzbl (%rdx,%rsi), %edx
movzbl (%r13,%rdx), %esi
imull %eax, %esi
movl %esi, %eax
sarl $0x4, %eax
xorl %edi, %edi
testl %eax, %eax
setle %dil
testb $0x10, %sil
leal -0x1(%rdi,%rdi), %esi
cmovnel %ecx, %esi
addl %eax, %esi
cmpl $0xfffff801, %esi       # imm = 0xFFFFF801
movl $0xfffff800, %eax       # imm = 0xFFFFF800
cmovll %eax, %esi
movl $0x7ff, %eax            # imm = 0x7FF
cmpl %eax, %esi
cmovgel %eax, %esi
leaq 0x44db(%rip), %rax      # 0x99b0
movzbl (%rdx,%rax), %eax
imull %esi, %eax
movl %eax, 0x178(%rbx,%rdx,4)
jmp 0x5531
movq 0xa0(%rbx), %rdi
movl $0x6, %esi
callq 0x43f5
movl %eax, %ebp
movq 0xa0(%rbx), %rdi
movl $0x8, %esi
callq 0x43f5
cmpl $0x80, %eax
je 0x553b
movl %eax, %ecx
testl %eax, %eax
jne 0x5556
movq 0xa0(%rbx), %rdi
movl $0x8, %esi
callq 0x43f5
jmp 0x5455
movl $0x3, %ecx
testl %ecx, %ecx
je 0x53ce
jmp 0x556a
movq 0xa0(%rbx), %rdi
movl $0x8, %esi
callq 0x43f5
addl $0xffffff00, %eax       # imm = 0xFFFFFF00
jmp 0x5455
leal -0x100(%rcx), %eax
cmpl $0x81, %ecx
cmovll %ecx, %eax
jmp 0x5455
cmpl $0x3, %ecx
jne 0x5694
movq (%rsp), %rdx
cmpl $0x3, %edx
jg 0x55ae
movq 0xc8(%rbx), %r15
movl 0x30(%rbx), %r13d
movl 0x80(%rbx), %eax
imull %r13d, %eax
addl 0x84(%rbx), %eax
shll $0x4, %eax
movl %edx, %ecx
andl $0x1, %ecx
leal (%rax,%rcx,8), %ebp
testb $0x2, %dl
je 0x55db
leal (%rbp,%r13,8), %ebp
jmp 0x55db
xorl %eax, %eax
cmpl $0x4, %edx
sete %al
shll $0x4, %eax
movq 0xd8(%rax,%rbx), %r15
movl 0x80(%rbx), %eax
imull 0x30(%rbx), %eax
movl 0x38(%rbx), %r13d
shll $0x2, %eax
movl 0x84(%rbx), %ecx
leal (%rax,%rcx,8), %ebp
leaq 0x178(%rbx), %r14
cmpl $0x0, 0x8c(%rbx)
je 0x5635
cmpl $0x1, %r12d
jne 0x56a3
movl (%r14), %eax
subl $-0x80, %eax
sarl $0x8, %eax
xorl %ecx, %ecx
testl %eax, %eax
cmovgl %eax, %ecx
movl $0xff, %eax
cmpl %eax, %ecx
cmovgel %eax, %ecx
movl $0x8, %eax
movzbl %cl, %edx
movabsq $0x101010101010101, %rcx # imm = 0x101010101010101
imulq %rdx, %rcx
movslq %ebp, %rbp
movq %rcx, (%r15,%rbp)
addl %r13d, %ebp
decl %eax
jne 0x5625
jmp 0x568d
cmpl $0x1, %r12d
jne 0x56f7
movl (%r14), %eax
subl $-0x80, %eax
sarl $0x8, %eax
addl $-0x8, %r13d
xorl %ecx, %ecx
movl $0xff, %edx
xorl %esi, %esi
movslq %ebp, %r8
addq %r15, %r8
xorl %edi, %edi
movzbl (%r8,%rdi), %r9d
addl %eax, %r9d
testl %r9d, %r9d
cmovlel %ecx, %r9d
cmpl %edx, %r9d
cmovgel %edx, %r9d
movb %r9b, (%r8,%rdi)
incq %rdi
cmpl $0x8, %edi
jne 0x565d
addl %r13d, %ebp
addl %ebp, %edi
incl %esi
movl %edi, %ebp
cmpl $0x8, %esi
jne 0x5655
movl $0x0, (%r14)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r14, %rdi
callq 0x5ced
addl $-0x8, %r13d
xorl %eax, %eax
movl $0xff, %ecx
xorl %edx, %edx
xorl %esi, %esi
movslq %ebp, %r8
movslq %esi, %rdi
leaq (%r14,%rdi,4), %r9
addq %r15, %r8
xorl %edi, %edi
movl (%r9,%rdi,4), %r10d
testl %r10d, %r10d
cmovlel %eax, %r10d
cmpl %ecx, %r10d
cmovgel %ecx, %r10d
movb %r10b, (%r8,%rdi)
incq %rdi
cmpl $0x8, %edi
jne 0x56c9
addl %edi, %esi
addl %r13d, %ebp
addl %edi, %ebp
incl %edx
cmpl $0x8, %edx
jne 0x56ba
jmp 0x5753
movq %r14, %rdi
callq 0x5ced
addl $-0x8, %r13d
xorl %eax, %eax
xorl %ecx, %ecx
xorl %edx, %edx
movl $0xff, %r10d
movslq %ebp, %rdi
movslq %edx, %rsi
leaq (%r14,%rsi,4), %r8
addq %r15, %rdi
xorl %esi, %esi
movzbl (%rdi,%rsi), %r9d
addl (%r8,%rsi,4), %r9d
testl %r9d, %r9d
cmovlel %eax, %r9d
cmpl %r10d, %r9d
jl 0x5739
movl $0xff, %r9d
movb %r9b, (%rdi,%rsi)
incq %rsi
cmpl $0x8, %esi
jne 0x571e
addl %esi, %edx
addl %r13d, %ebp
addl %esi, %ebp
incl %ecx
cmpl $0x8, %ecx
jne 0x570f
movl $0x100, %edx            # imm = 0x100
movq %r14, %rdi
xorl %esi, %esi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x20e0