// File: OpenFodder[P]SOS_Unpacker/capsimg/CAPSImg/CapsImageStd.cpp
// Function: CCapsImageStd::ReadSample(ImageStreamInfo*, int)
int CCapsImageStd::ReadSample(PIMAGESTREAMINFO pstr, int maxbc)
{
	// number of bits read
	int actbc=0;

	// value read
	uint32_t readvalue=0;

	// process remaining bits from stream
	while (maxbc > 0) {
		// get new sample when needed
		if (!pstr->remstreambc)
			if (ReadSampleInit(pstr))
				break;

		// restore bitstream state
		uint32_t remstreambc=pstr->remstreambc;
		uint32_t remsamplebc=pstr->remsamplebc;

		// stop on invalid sample state
		if (!remsamplebc)
			break;

		// read next sample if stream is empty, e.g. loop size has been changed
		if (!remstreambc)
			continue;

		uint32_t sampleofs=pstr->sampleofs;
		uint32_t samplemask=pstr->samplemask;
		uint32_t sampledata=pstr->samplebase[sampleofs];

		// read remaining bits from sample
		while (maxbc > 0) {
			// add new bit
			readvalue<<=1;
			if (sampledata & samplemask)
				readvalue|=1;

			// bit added
			actbc++;
			maxbc--;

			// one less sample bit to process 
			if (!--remsamplebc) {
				// reset the sample data if all sample bits have been read
				remsamplebc=pstr->samplebc;
				sampleofs=0;
				samplemask=0x80;
				sampledata=pstr->samplebase[sampleofs];
			} else {
				// set next bit position to read
				if (!(samplemask>>=1)) {
					sampleofs++;
					samplemask=0x80;
					sampledata=pstr->samplebase[sampleofs];
				}
			}

			// stop reading the current sample if complete data size has been read
			if (!--remstreambc)
				break;
		}

		// save bitstream state
		pstr->remstreambc=remstreambc;
		pstr->remsamplebc=remsamplebc;
		pstr->sampleofs=sampleofs;
		pstr->samplemask=samplemask;
	}

	// store value read
	pstr->readvalue=readvalue;

	return actbc;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x38(%rbp)
movl $0x0, -0x18(%rbp)
movl $0x0, -0x1c(%rbp)
cmpl $0x0, -0x14(%rbp)
jle 0x11c48
movq -0x10(%rbp), %rax
cmpl $0x0, 0x54(%rax)
jne 0x11b16
movq -0x38(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x119c0
cmpl $0x0, %eax
je 0x11b14
jmp 0x11c48
jmp 0x11b16
movq -0x10(%rbp), %rax
movl 0x54(%rax), %eax
movl %eax, -0x20(%rbp)
movq -0x10(%rbp), %rax
movl 0x58(%rax), %eax
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x24(%rbp)
jne 0x11b35
jmp 0x11c48
cmpl $0x0, -0x20(%rbp)
jne 0x11b3d
jmp 0x11ae9
movq -0x10(%rbp), %rax
movl 0x5c(%rax), %eax
movl %eax, -0x28(%rbp)
movq -0x10(%rbp), %rax
movl 0x60(%rax), %eax
movl %eax, -0x2c(%rbp)
movq -0x10(%rbp), %rax
movq 0x68(%rax), %rax
movl -0x28(%rbp), %ecx
movzbl (%rax,%rcx), %eax
movl %eax, -0x30(%rbp)
cmpl $0x0, -0x14(%rbp)
jle 0x11c1b
movl -0x1c(%rbp), %eax
shll %eax
movl %eax, -0x1c(%rbp)
movl -0x30(%rbp), %eax
andl -0x2c(%rbp), %eax
cmpl $0x0, %eax
je 0x11b89
movl -0x1c(%rbp), %eax
orl $0x1, %eax
movl %eax, -0x1c(%rbp)
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
movl -0x14(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x14(%rbp)
movl -0x24(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x24(%rbp)
cmpl $0x0, %eax
jne 0x11bd5
movq -0x10(%rbp), %rax
movl 0x50(%rax), %eax
movl %eax, -0x24(%rbp)
movl $0x0, -0x28(%rbp)
movl $0x80, -0x2c(%rbp)
movq -0x10(%rbp), %rax
movq 0x68(%rax), %rax
movl -0x28(%rbp), %ecx
movzbl (%rax,%rcx), %eax
movl %eax, -0x30(%rbp)
jmp 0x11c06
movl -0x2c(%rbp), %eax
shrl %eax
movl %eax, -0x2c(%rbp)
cmpl $0x0, %eax
jne 0x11c04
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
movl $0x80, -0x2c(%rbp)
movq -0x10(%rbp), %rax
movq 0x68(%rax), %rax
movl -0x28(%rbp), %ecx
movzbl (%rax,%rcx), %eax
movl %eax, -0x30(%rbp)
jmp 0x11c06
movl -0x20(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x20(%rbp)
cmpl $0x0, %eax
jne 0x11c16
jmp 0x11c1b
jmp 0x11b63
movl -0x20(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x54(%rax)
movl -0x24(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x58(%rax)
movl -0x28(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x5c(%rax)
movl -0x2c(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x60(%rax)
jmp 0x11ae9
movl -0x1c(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x40(%rax)
movl -0x18(%rbp), %eax
addq $0x40, %rsp
popq %rbp
retq
nopl (%rax,%rax)