// File: /workspace/github_cpp_makefile_star2_O3/OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsImage.cpp
// Function: CCapsImage::CompareBlock(unsigned int)
int CCapsImage::CompareBlock(unsigned blk)
{
	PDISKTRACKINFO pti=di.pdt;
	uint8_t *buf=di.data;

	// check block number requested
	if (blk>=pti->ci.blkcnt || !buf || !di.datacount)
		return imgeGeneric;

	UDWORD maxofs=pti->datasize;

	// check buffer overrun
	if ((blk+1)*sizeof(CapsBlock) > maxofs)
		return imgeShort;

	// read block data in native format
	CapsBlock cb;
	memcpy(&cb, buf+blk*sizeof(CapsBlock), sizeof(CapsBlock));
	CCapsLoader::Swap((PUDWORD)&cb, sizeof(CapsBlock));

	// check buffer overrun
	if (cb.dataoffset >= maxofs)
		return imgeShort;

	// block stream limit is either the next block or buffer end
	if (blk != pti->ci.blkcnt-1)
		maxofs=ReadValue(buf+(blk+1)*sizeof(CapsBlock)+offsetof(CapsBlock, dataoffset), sizeof(UDWORD));

	// check buffer overrun
	if (cb.dataoffset >= maxofs)
		return imgeShort;

	// check encoder type
	switch (cb.enctype) {
		case cpencMFM:
			break;

		default:
			return imgeIncompatible;
	}

	// decode stream
	int end=false;
	int pos=pti->comppos;
	for (UDWORD ofs=cb.dataoffset; ofs < maxofs; ) {
		int code=buf[ofs++];

		// read count
		int vc=code>>CAPS_SIZE_S;
		code&=CAPS_DATAMASK;
		UDWORD count;

		if (vc) {
			if (ofs+vc > maxofs)
				return imgeTrackData;

			count=ReadValue(buf+ofs, vc);
			ofs+=vc;
		} else
			count=0;

		// process data
		switch (code) {
			// stream end
			case cpdatEnd:
				// safety checks
				if (count)
					return imgeTrackData;
				end=true;
				break;

			case cpdatData:
				// safety checks
				if (!count)
					return imgeTrackData;
				if (ofs+count > maxofs)
					return imgeTrackData;

				// copy data if requested
				if (di.flag & DI_COMP_DATA) {
					memcpy(pti->trackbuf+pos, buf+ofs, count);
					pos+=count;
				}
				ofs+=count;
				break;

			case cpdatGap:
				// safety checks
				if (!count)
					return imgeTrackData;
				if (ofs+count > maxofs)
					return imgeTrackData;

				// skip gap data
				ofs+=count;
				break;

			case cpdatMark:
				// safety checks
				if (!count)
					return imgeTrackData;
				if (ofs+count > maxofs)
					return imgeTrackData;

				// copy raw data if requested
				if (di.flag & DI_COMP_MARK) {
					memcpy(pti->trackbuf+pos, buf+ofs, count);
					pos+=count;
				}
				ofs+=count;
				break;

			case cpdatRaw:
				// safety checks
				if (!count)
					return imgeTrackData;
				if (ofs+count > maxofs)
					return imgeTrackData;

				// copy raw data if requested
				if (di.flag & DI_COMP_RAW) {
					memcpy(pti->trackbuf+pos, buf+ofs, count);
					pos+=count;
				}
				ofs+=count;
				break;

			case cpdatFData:
				// safety checks
				if (!count)
					return imgeTrackData;

				// set flakey data to 0 (memory already cleared) if requested
				if (di.flag & DI_COMP_FDATA)
					pos+=count;
				break;

			default:
				return imgeTrackStream;
		}
	}

	// no cpdatEnd encountered, definitely a problem
	if (!end)
		return imgeTrackData;

	pti->comppos=pos;
	return imgeOk;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq 0x210(%rdi), %rcx
movl $0x2, %ebp
cmpl %esi, 0x128(%rcx)
jbe 0x8f8e
movq %rdi, %rbx
movq 0x1e8(%rdi), %r14
testq %r14, %r14
je 0x8f8e
cmpl $0x0, 0x1f4(%rbx)
je 0x8f8e
movl %esi, %r15d
movl 0x24(%rcx), %edx
movl %esi, %eax
movq %rax, %r13
shlq $0x5, %r13
addq $0x20, %r13
movl $0x7, %ebp
cmpq %rdx, %r13
ja 0x8f8e
movq %rcx, 0x10(%rsp)
shlq $0x5, %rax
movups (%r14,%rax), %xmm0
movups 0x10(%r14,%rax), %xmm1
leaq 0x20(%rsp), %r12
movaps %xmm1, 0x10(%r12)
movaps %xmm0, (%r12)
movq %r12, %rdi
movl $0x20, %esi
movq %rdx, %rbp
callq 0xd1bc
movq %rbp, %rdx
movl 0x1c(%r12), %r12d
movl $0x7, %ebp
cmpl %edx, %r12d
jae 0x8f8e
movq 0x10(%rsp), %rax
movl 0x128(%rax), %eax
decl %eax
cmpl %r15d, %eax
je 0x8dd8
leaq (%r14,%r13), %rdi
addq $0x1c, %rdi
movl $0x4, %esi
callq 0xf1c0
movl %eax, %edx
movl 0x3c(%rsp), %r12d
cmpl %edx, %r12d
jae 0x8f8e
movl $0xe, %ebp
cmpl $0x1, 0x30(%rsp)
jne 0x8f8e
movq 0x10(%rsp), %rax
movl 0xbc(%rax), %eax
movl %eax, 0xc(%rsp)
xorl %r13d, %r13d
movq %rdx, 0x18(%rsp)
movl %r12d, %r15d
movl %r15d, %ecx
movl %r15d, %eax
incl %eax
movzbl (%r14,%rcx), %r12d
xorl %r8d, %r8d
cmpl $0x20, %r12d
jae 0x8e26
movl %eax, %r15d
jmp 0x8e4b
movl %r12d, %esi
shrl $0x5, %esi
leal (%rsi,%rax), %r15d
cmpl %edx, %r15d
ja 0x8f89
movl %eax, %edi
addq %r14, %rdi
callq 0xf1c0
movq 0x18(%rsp), %rdx
movl %eax, %r8d
andl $0x1f, %r12d
jne 0x8e6a
testl %r8d, %r8d
jne 0x8f89
movl $0x1, %r13d
cmpl %edx, %r15d
jb 0x8e0b
jmp 0x8f76
decl %r12d
cmpl $0x4, %r12d
ja 0x8f6a
leaq 0x9362(%rip), %rcx      # 0x121e0
movslq (%rcx,%r12,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0xa, %ebp
testl %r8d, %r8d
je 0x8f8e
leal (%r8,%r15), %r12d
cmpl %edx, %r12d
ja 0x8f8e
testb $0x1, 0x208(%rbx)
jne 0x8f13
jmp 0x8f41
testl %r8d, %r8d
je 0x8f89
movl 0x208(%rbx), %eax
shll $0x1c, %eax
sarl $0x1f, %eax
andl %r8d, %eax
addl %eax, 0xc(%rsp)
movl %r15d, %r12d
jmp 0x8f41
movl $0xa, %ebp
testl %r8d, %r8d
je 0x8f8e
addl %r15d, %r8d
movl %r8d, %r12d
cmpl %edx, %r8d
jbe 0x8f41
jmp 0x8f8e
movl $0xa, %ebp
testl %r8d, %r8d
je 0x8f8e
leal (%r8,%r15), %r12d
cmpl %edx, %r12d
ja 0x8f8e
testb $0x4, 0x208(%rbx)
je 0x8f41
movl 0xc(%rsp), %ebp
movslq %ebp, %rdi
movq 0x10(%rsp), %rax
addq 0x48(%rax), %rdi
movl %r15d, %esi
addq %r14, %rsi
movl %r8d, %edx
movq %r8, %r15
callq 0x4190
movq 0x18(%rsp), %rdx
addl %ebp, %r15d
movl %r15d, 0xc(%rsp)
cmpl %edx, %r12d
jb 0x8e08
jmp 0x8f71
movl $0xa, %ebp
testl %r8d, %r8d
je 0x8f8e
leal (%r8,%r15), %r12d
cmpl %edx, %r12d
ja 0x8f8e
testb $0x2, 0x208(%rbx)
jne 0x8f13
jmp 0x8f41
movl $0x9, %ebp
jmp 0x8f8e
testl %r13d, %r13d
je 0x8f89
movq 0x10(%rsp), %rax
movl 0xc(%rsp), %ecx
movl %ecx, 0xbc(%rax)
xorl %ebp, %ebp
jmp 0x8f8e
movl $0xa, %ebp
movl %ebp, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop