// File: /workspace/github_c_makefile_star2_O0/jsummers[P]deark/src/fmtutil-cmpr.c
// Function: my_packbits_codec_addbuf
static void my_packbits_codec_addbuf(struct de_dfilter_ctx *dfctx,
	const u8 *buf, i64 buf_len)
{
	int i;
	u8 b;
	struct packbitsctx *rctx = (struct packbitsctx*)dfctx->codec_private;

	if(!rctx) return;
	if(dfctx->dres->errcode) return;
	if(dfctx->finished_flag) return;

	for(i=0; i<buf_len; i++) {
		if(dfctx->dcmpro->len_known &&
			(rctx->nbytes_written >= dfctx->dcmpro->expected_len))
		{
			dfctx->finished_flag = 1;
			break;
		}

		b = buf[i];
		rctx->total_nbytes_processed++;

		switch(rctx->state) {
		case PACKBITS_STATE_NEUTRAL: // this is a code byte
			if(b>128) { // A compressed run
				rctx->repeat_count = 257 - (i64)b;
				rctx->state = PACKBITS_STATE_READING_UNIT_TO_REPEAT;
			}
			else if(b<128) { // An uncompressed run
				rctx->nliteral_bytes_remaining = (1 + (i64)b) * (i64)rctx->nbytes_per_unit;
				rctx->state = PACKBITS_STATE_COPYING_LITERAL;
			}
			// Else b==128. No-op.
			// TODO: Some (but not most) ILBM specs say that code 128 is used to
			// mark the end of compressed data, so maybe there should be options to
			// tell us what to do when code 128 is encountered.
			break;
		case PACKBITS_STATE_COPYING_LITERAL: // This byte is uncompressed
			dbuf_writebyte(dfctx->dcmpro->f, b);
			rctx->nbytes_written++;
			rctx->nliteral_bytes_remaining--;
			if(rctx->nliteral_bytes_remaining<=0) {
				rctx->state = PACKBITS_STATE_NEUTRAL;
			}
			break;
		case PACKBITS_STATE_READING_UNIT_TO_REPEAT:
			if(rctx->nbytes_per_unit==1) { // Optimization for standard PackBits
				dbuf_write_run(dfctx->dcmpro->f, b, rctx->repeat_count);
				rctx->nbytes_written += rctx->repeat_count;
				rctx->state = PACKBITS_STATE_NEUTRAL;
			}
			else {
				rctx->unitbuf[rctx->nbytes_in_unitbuf++] = b;
				if(rctx->nbytes_in_unitbuf >= rctx->nbytes_per_unit) {
					i64 k;

					for(k=0; k<rctx->repeat_count; k++) {
						dbuf_write(dfctx->dcmpro->f, rctx->unitbuf, (i64)rctx->nbytes_per_unit);
					}
					rctx->nbytes_in_unitbuf = 0;
					rctx->nbytes_written += rctx->repeat_count * (i64)rctx->nbytes_per_unit;
					rctx->state = PACKBITS_STATE_NEUTRAL;
				}
			}
			break;
		}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
jne 0x177a8c
jmp 0x177cf5
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
cmpl $0x0, (%rax)
je 0x177a9e
jmp 0x177cf5
movq -0x8(%rbp), %rax
cmpb $0x0, 0x20(%rax)
je 0x177aad
jmp 0x177cf5
movl $0x0, -0x1c(%rbp)
movslq -0x1c(%rbp), %rax
cmpq -0x18(%rbp), %rax
jge 0x177cf5
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rax
movzbl 0x8(%rax), %eax
cmpl $0x0, %eax
je 0x177af6
movq -0x28(%rbp), %rax
movq 0x20(%rax), %rax
movq -0x8(%rbp), %rcx
movq 0x10(%rcx), %rcx
cmpq 0x10(%rcx), %rax
jl 0x177af6
movq -0x8(%rbp), %rax
movb $0x1, 0x20(%rax)
jmp 0x177cf5
movq -0x10(%rbp), %rax
movslq -0x1c(%rbp), %rcx
movb (%rax,%rcx), %al
movb %al, -0x1d(%rbp)
movq -0x28(%rbp), %rax
movq 0x18(%rax), %rcx
incq %rcx
movq %rcx, 0x18(%rax)
movq -0x28(%rbp), %rax
movl 0x28(%rax), %eax
movl %eax, -0x34(%rbp)
testl %eax, %eax
je 0x177b3e
jmp 0x177b23
movl -0x34(%rbp), %eax
subl $0x1, %eax
je 0x177ba1
jmp 0x177b2d
movl -0x34(%rbp), %eax
subl $0x2, %eax
je 0x177bf0
jmp 0x177ce5
movzbl -0x1d(%rbp), %eax
cmpl $0x80, %eax
jle 0x177b6a
movzbl -0x1d(%rbp), %eax
movl $0x101, %ecx            # imm = 0x101
subq %rax, %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x38(%rax)
movq -0x28(%rbp), %rax
movl $0x2, 0x28(%rax)
jmp 0x177b9c
movzbl -0x1d(%rbp), %eax
cmpl $0x80, %eax
jge 0x177b9a
movzbl -0x1d(%rbp), %eax
movl %eax, %ecx
addq $0x1, %rcx
movq -0x28(%rbp), %rax
imulq (%rax), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x28(%rbp), %rax
movl $0x1, 0x28(%rax)
jmp 0x177b9c
jmp 0x177ce5
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rax
movq (%rax), %rdi
movzbl -0x1d(%rbp), %esi
callq 0x168380
movq -0x28(%rbp), %rax
movq 0x20(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x20(%rax)
movq -0x28(%rbp), %rax
movq 0x30(%rax), %rcx
addq $-0x1, %rcx
movq %rcx, 0x30(%rax)
movq -0x28(%rbp), %rax
cmpq $0x0, 0x30(%rax)
jg 0x177beb
movq -0x28(%rbp), %rax
movl $0x0, 0x28(%rax)
jmp 0x177ce5
movq -0x28(%rbp), %rax
cmpq $0x1, (%rax)
jne 0x177c3c
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rax
movq (%rax), %rdi
movb -0x1d(%rbp), %al
movq -0x28(%rbp), %rcx
movq 0x38(%rcx), %rdx
movzbl %al, %esi
callq 0x168800
movq -0x28(%rbp), %rax
movq 0x38(%rax), %rcx
movq -0x28(%rbp), %rax
addq 0x20(%rax), %rcx
movq %rcx, 0x20(%rax)
movq -0x28(%rbp), %rax
movl $0x0, 0x28(%rax)
jmp 0x177ce3
movb -0x1d(%rbp), %dl
movq -0x28(%rbp), %rax
movq -0x28(%rbp), %rsi
movq 0x8(%rsi), %rcx
movq %rcx, %rdi
addq $0x1, %rdi
movq %rdi, 0x8(%rsi)
movb %dl, 0x10(%rax,%rcx)
movq -0x28(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x28(%rbp), %rcx
cmpq (%rcx), %rax
jb 0x177ce1
movq $0x0, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq -0x28(%rbp), %rcx
cmpq 0x38(%rcx), %rax
jge 0x177cae
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rax
movq (%rax), %rdi
movq -0x28(%rbp), %rsi
addq $0x10, %rsi
movq -0x28(%rbp), %rax
movq (%rax), %rdx
callq 0x166170
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0x177c73
movq -0x28(%rbp), %rax
movq $0x0, 0x8(%rax)
movq -0x28(%rbp), %rax
movq 0x38(%rax), %rcx
movq -0x28(%rbp), %rax
imulq (%rax), %rcx
movq -0x28(%rbp), %rax
addq 0x20(%rax), %rcx
movq %rcx, 0x20(%rax)
movq -0x28(%rbp), %rax
movl $0x0, 0x28(%rax)
jmp 0x177ce3
jmp 0x177ce5
jmp 0x177ce7
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x177ab4
addq $0x40, %rsp
popq %rbp
retq
nopl (%rax,%rax)