// File: OpenFodder[P]SOS_Unpacker/capsimg/Codec/DiskEncoding.cpp
// Function: CDiskEncoding::FindViolation(unsigned char*, int, int, int, int, int)
int CDiskEncoding::FindViolation(uint8_t *buffer, int bitpos, int bitcnt, int max0, int max1, int mode)
{
	int vcnt=0;

	// no violation if any of the parameters is incorrect or nothing to check
	if (!buffer || bitpos < 0 || bitcnt <= 0 || (max0 < 0 && max1 < 0))
		return mode ? vcnt : -1;

	// calculate the buffer position and bit mask for the first bit to check
	uint32_t bitmask=1 << ((bitpos & 7) ^ 7);
	uint32_t pos=bitpos >> 3;
	uint32_t sval=buffer[pos++];

	// reset bit counter
	int lbv=-1;
	int bc=0;

	// process all bits
	while (bitcnt-- > 0) {
		// if mask underflowed, reset the mask to b7 and read the next buffer value
		if (!bitmask) {
			bitmask=0x80;
			sval=buffer[pos++];
		}

		// current bit value
		int bitval=(sval & bitmask) ? 1 : 0;

		if (lbv != bitval) {
			// if different from previous bit, restart counting
			lbv=bitval;
			bc=1;
		} else {
			// same as previous bit, count it in
			bc++;

			// violation found if the stream contains max1 consecutive 1 bits or max0 consecutive 0 bits
			if ((!lbv && max0 >= 0 && bc >= max0) || (lbv && max1 >= 0 && bc >= max1)) {
				// count violations or return on first violation found depending on mode
				if (mode)
					vcnt++;
				else
					return bitpos;
			}
		}

		// move to next bit
		bitpos++;
		bitmask >>= 1;
	}

	// return violation count or no violation found depending on mode
	return mode ? vcnt : -1;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
movl %r8d, -0x20(%rbp)
movl %r9d, -0x24(%rbp)
movl $0x0, -0x28(%rbp)
cmpq $0x0, -0x10(%rbp)
je 0x16d7f
cmpl $0x0, -0x14(%rbp)
jl 0x16d7f
cmpl $0x0, -0x18(%rbp)
jle 0x16d7f
cmpl $0x0, -0x1c(%rbp)
jge 0x16da2
cmpl $0x0, -0x20(%rbp)
jge 0x16da2
cmpl $0x0, -0x24(%rbp)
je 0x16d8d
movl -0x28(%rbp), %eax
movl %eax, -0x44(%rbp)
jmp 0x16d97
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movl %eax, -0x44(%rbp)
jmp 0x16d97
movl -0x44(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x16ecc
movl -0x14(%rbp), %ecx
andl $0x7, %ecx
xorl $0x7, %ecx
movl $0x1, %eax
shll %cl, %eax
movl %eax, -0x2c(%rbp)
movl -0x14(%rbp), %eax
sarl $0x3, %eax
movl %eax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movl -0x30(%rbp), %ecx
movl %ecx, %edx
addl $0x1, %edx
movl %edx, -0x30(%rbp)
movl %ecx, %ecx
movzbl (%rax,%rcx), %eax
movl %eax, -0x34(%rbp)
movl $0xffffffff, -0x38(%rbp) # imm = 0xFFFFFFFF
movl $0x0, -0x3c(%rbp)
movl -0x18(%rbp), %eax
movl %eax, %ecx
addl $-0x1, %ecx
movl %ecx, -0x18(%rbp)
cmpl $0x0, %eax
jle 0x16eae
cmpl $0x0, -0x2c(%rbp)
jne 0x16e1d
movl $0x80, -0x2c(%rbp)
movq -0x10(%rbp), %rax
movl -0x30(%rbp), %ecx
movl %ecx, %edx
addl $0x1, %edx
movl %edx, -0x30(%rbp)
movl %ecx, %ecx
movzbl (%rax,%rcx), %eax
movl %eax, -0x34(%rbp)
movl -0x34(%rbp), %edx
andl -0x2c(%rbp), %edx
xorl %eax, %eax
movl $0x1, %ecx
cmpl $0x0, %edx
cmovnel %ecx, %eax
movl %eax, -0x40(%rbp)
movl -0x38(%rbp), %eax
cmpl -0x40(%rbp), %eax
je 0x16e4a
movl -0x40(%rbp), %eax
movl %eax, -0x38(%rbp)
movl $0x1, -0x3c(%rbp)
jmp 0x16e98
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
cmpl $0x0, -0x38(%rbp)
jne 0x16e67
cmpl $0x0, -0x1c(%rbp)
jl 0x16e67
movl -0x3c(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jge 0x16e7b
cmpl $0x0, -0x38(%rbp)
je 0x16e96
cmpl $0x0, -0x20(%rbp)
jl 0x16e96
movl -0x3c(%rbp), %eax
cmpl -0x20(%rbp), %eax
jl 0x16e96
cmpl $0x0, -0x24(%rbp)
je 0x16e8c
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x16e94
movl -0x14(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x16ecc
jmp 0x16e96
jmp 0x16e98
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x14(%rbp)
movl -0x2c(%rbp), %eax
shrl %eax
movl %eax, -0x2c(%rbp)
jmp 0x16de4
cmpl $0x0, -0x24(%rbp)
je 0x16ebc
movl -0x28(%rbp), %eax
movl %eax, -0x48(%rbp)
jmp 0x16ec6
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movl %eax, -0x48(%rbp)
jmp 0x16ec6
movl -0x48(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
popq %rbp
retq
nopw %cs:(%rax,%rax)
nopl (%rax,%rax)