// File: OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsImage.cpp
// Function: CCapsImage::FindWeakBits()
void CCapsImage::FindWeakBits()
{
	PDISKTRACKINFO pti = di.pdt;

	// true if all the available revolutions should be returned
	int allrev = (pti->trackcnt == pti->rawtrackcnt);

	// process all revolutions
	for (int rev = 0; rev < pti->rawtrackcnt; rev++) {
		// get the track data buffer and the size of the buffer
		PUBYTE trackbuf = pti->trackdata[rev];
		int tracklen = allrev ? pti->rawlen : pti->tracksize[rev];

		// byte offset in track buffer for the current bitcell
		int bofs = 0;

		// number of consecutive 0 bitcells since the last 1 bit
		int zcnt = 0;

		// start position of the area containing 0s
		int lastbp = 0;

		// bitcell position in the current data byte bitcell; position#0 is bit#7
		int actbit = 0;

		// process the entire track buffer
		while (bofs < tracklen) {
			// get actual byte from track buffer
			uint8_t bval = trackbuf[bofs];
			
			while (1) {
				// first 0 bit position
				int f0b;

				// if area is empty search for area starting with 0 bit value
				if (!zcnt) {
					// find the first 0 bit from the current position in the current byte
					f0b = f0b_table[actbit][bval];
					if (f0b == 8) {
						// 0 bit not found, continue with the next byte
						break;
					} else {
						// 0 bit found, set the current bit position
						actbit = f0b;

						// set the area start position
						lastbp = bofs << 3 | actbit;
					}
				} else {
					// area not empty, start from position#0
					f0b = 0;
				}

				// find the first 1 bit from the current position in the current byte
				int f1b = f1b_table[actbit][bval];

				// add the number of bits from the last position (8 if no 1 bit found)
				zcnt += f1b - f0b;

				if (f1b == 8) {
					// 1 bit not found, continue with the next byte
					break;
				} else {
					// start the next search for 0 from the current position
					actbit = f1b;
				}

				// add the area
				if (zcnt >= MIN_CTRAW_WEAK_SIZE && zcnt <= MAX_CTRAW_WEAK_SIZE)
					AddWeakBitArea(rev, lastbp, zcnt);

				// area empty
				zcnt = 0;
			}

			// continue with the next byte
			actbit = 0;
			bofs++;
		}

		// add the last area if exists (loop ended before it was added)
		if (zcnt >= MIN_CTRAW_WEAK_SIZE && zcnt <= MAX_CTRAW_WEAK_SIZE)
			AddWeakBitArea(rev, lastbp, zcnt);
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x48(%rbp)
movq 0x210(%rax), %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
movl 0x28(%rax), %eax
movq -0x10(%rbp), %rcx
cmpl 0x2c(%rcx), %eax
sete %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x14(%rbp)
movl $0x0, -0x18(%rbp)
movl -0x18(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x2c(%rcx), %eax
jge 0xde9a
movq -0x10(%rbp), %rax
movslq -0x18(%rbp), %rcx
movq 0x58(%rax,%rcx,8), %rax
movq %rax, -0x20(%rbp)
cmpl $0x0, -0x14(%rbp)
je 0xdd62
movq -0x10(%rbp), %rax
movl 0x30(%rax), %eax
movl %eax, -0x4c(%rbp)
jmp 0xdd74
movq -0x10(%rbp), %rax
movslq -0x18(%rbp), %rcx
movl 0x80(%rax,%rcx,4), %eax
movl %eax, -0x4c(%rbp)
movl -0x4c(%rbp), %eax
movl %eax, -0x24(%rbp)
movl $0x0, -0x28(%rbp)
movl $0x0, -0x2c(%rbp)
movl $0x0, -0x30(%rbp)
movl $0x0, -0x34(%rbp)
movl -0x28(%rbp), %eax
cmpl -0x24(%rbp), %eax
jge 0xde6c
movq -0x20(%rbp), %rax
movslq -0x28(%rbp), %rcx
movb (%rax,%rcx), %al
movb %al, -0x35(%rbp)
cmpl $0x0, -0x2c(%rbp)
jne 0xddef
movslq -0x34(%rbp), %rcx
leaq 0x1a7cf(%rip), %rax     # 0x28590
shlq $0x8, %rcx
addq %rcx, %rax
movzbl -0x35(%rbp), %ecx
movsbl (%rax,%rcx), %eax
movl %eax, -0x3c(%rbp)
cmpl $0x8, -0x3c(%rbp)
jne 0xdddb
jmp 0xde57
movl -0x3c(%rbp), %eax
movl %eax, -0x34(%rbp)
movl -0x28(%rbp), %eax
shll $0x3, %eax
orl -0x34(%rbp), %eax
movl %eax, -0x30(%rbp)
jmp 0xddf6
movl $0x0, -0x3c(%rbp)
movslq -0x34(%rbp), %rcx
leaq 0x1af8f(%rip), %rax     # 0x28d90
shlq $0x8, %rcx
addq %rcx, %rax
movzbl -0x35(%rbp), %ecx
movsbl (%rax,%rcx), %eax
movl %eax, -0x40(%rbp)
movl -0x40(%rbp), %eax
subl -0x3c(%rbp), %eax
addl -0x2c(%rbp), %eax
movl %eax, -0x2c(%rbp)
cmpl $0x8, -0x40(%rbp)
jne 0xde27
jmp 0xde57
movl -0x40(%rbp), %eax
movl %eax, -0x34(%rbp)
cmpl $0x5, -0x2c(%rbp)
jl 0xde4b
cmpl $0x10, -0x2c(%rbp)
jg 0xde4b
movq -0x48(%rbp), %rdi
movl -0x18(%rbp), %esi
movl -0x30(%rbp), %edx
movl -0x2c(%rbp), %ecx
callq 0xe050
movl $0x0, -0x2c(%rbp)
jmp 0xddb0
movl $0x0, -0x34(%rbp)
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0xdd96
cmpl $0x5, -0x2c(%rbp)
jl 0xde8a
cmpl $0x10, -0x2c(%rbp)
jg 0xde8a
movq -0x48(%rbp), %rdi
movl -0x18(%rbp), %esi
movl -0x30(%rbp), %edx
movl -0x2c(%rbp), %ecx
callq 0xe050
jmp 0xde8c
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0xdd2f
addq $0x50, %rsp
popq %rbp
retq