// File: /workspace/github_c_makefile_star2_O0/jsummers[P]deark/src/fmtutil-iff.c
// Function: do_iff_chunk
static int do_iff_chunk(deark *c, struct de_iffctx *ictx,
	struct de_iffchunkctx *parent,
	i64 pos, i64 bytes_avail, int level, i64 *pbytes_consumed)
{
	int ret;
	i64 chunk_dlen_raw;
	i64 chunk_dlen_padded;
	i64 data_bytes_avail;
	i64 hdrsize;
	struct de_iffchunkctx chunkctx;
	int saved_indent_level;
	int retval = 0;
	struct iff_parser_data *pctx = (struct iff_parser_data*)ictx->private_data;

	de_dbg_indent_save(c, &saved_indent_level);
	de_zeromem(&chunkctx, sizeof(struct de_iffchunkctx));
	chunkctx.parent = parent;

	hdrsize = 4+ictx->sizeof_len;
	if(bytes_avail<hdrsize) {
		de_warn(c, "Ignoring %"I64_FMT" bytes at %"I64_FMT"; too small "
			"to be a chunk", bytes_avail, pos);
		goto done;
	}
	data_bytes_avail = bytes_avail-hdrsize;

	dbuf_read_fourcc(ictx->f, pos, &chunkctx.chunk4cc, 4,
		ictx->reversed_4cc ? DE_4CCFLAG_REVERSED : 0x0);
	if(chunkctx.chunk4cc.id==0 && level==0) {
		de_warn(c, "Chunk ID not found at %"I64_FMT"; assuming the data ends "
			"here", pos);
		goto done;
	}

	if(ictx->sizeof_len==2) {
		chunk_dlen_raw = dbuf_getu16x(ictx->f, pos+4, ictx->is_le);
	}
	else {
		chunk_dlen_raw = dbuf_getu32x(ictx->f, pos+4, ictx->is_le);
	}
	chunkctx.dlen = chunk_dlen_raw;
	chunkctx.dpos = pos+hdrsize;

	// TODO: Setting these fields (prior to the identify function) is enough
	// for now, but we should also set the other fields here if we can.
	ictx->level = level;
	ictx->chunkctx = &chunkctx;

	if(ictx->preprocess_chunk_fn) {
		ictx->preprocess_chunk_fn(ictx);
	}

	if(!chunkctx.chunk_name && ictx->has_standard_iff_chunks) {
		fmtutil_default_iff_chunk_identify(ictx);
	}

	if(chunkctx.chunk_name) {
		de_snprintf(pctx->name_str, sizeof(pctx->name_str), " (%s)", chunkctx.chunk_name);
	}
	else {
		pctx->name_str[0] = '\0';
	}

	de_dbg(c, "chunk '%s'%s at %"I64_FMT", dpos=%"I64_FMT", dlen=%"I64_FMT,
		chunkctx.chunk4cc.id_dbgstr, pctx->name_str, pos,
		chunkctx.dpos, chunkctx.dlen);
	de_dbg_indent(c, 1);

	if(chunkctx.dlen > data_bytes_avail) {
		int should_warn = 1;

		if(chunkctx.chunk4cc.id==CODE_RIFF && pos==0 && bytes_avail==ictx->f->len) {
			// Hack:
			// This apparent error, in which the RIFF chunk's length field gives the
			// length of the entire file, is too common (particularly in .ani files)
			// to warn about.
			should_warn = 0;
		}

		if(should_warn) {
			de_warn(c, "Invalid oversized chunk, or unexpected end of file "
				"(chunk at %d ends at %" I64_FMT ", "
				"parent ends at %" I64_FMT ")",
				(int)pos, chunkctx.dlen+chunkctx.dpos, pos+bytes_avail);
		}

		chunkctx.dlen = data_bytes_avail; // Try to continue
		de_dbg(c, "adjusting chunk data len to %"I64_FMT, chunkctx.dlen);
	}

	chunk_dlen_padded = de_pad_to_n(chunkctx.dlen, ictx->alignment);
	*pbytes_consumed = hdrsize + chunk_dlen_padded;

	// We've set *pbytes_consumed, so we can return "success"
	retval = 1;

	// Set ictx fields, prior to calling the handler
	chunkctx.pos = pos;
	chunkctx.len = bytes_avail;
	ictx->handled = 0;
	ictx->is_std_container = 0;
	ictx->is_raw_container = 0;

	ret = ictx->handle_chunk_fn(ictx);
	if(!ret) {
		retval = 0;
		goto done;
	}

	if(ictx->is_std_container || ictx->is_raw_container) {
		i64 contents_dpos, contents_dlen;

		ictx->chunkctx = NULL;
		ictx->curr_container_fmt4cc = chunkctx.chunk4cc;
		fourcc_clear(&ictx->curr_container_contentstype4cc);

		if(ictx->is_std_container) {
			contents_dpos = chunkctx.dpos+4;
			contents_dlen = chunkctx.dlen-4;

			// First 4 bytes of payload are the "contents type" or "FORM type"
			dbuf_read_fourcc(ictx->f, chunkctx.dpos, &ictx->curr_container_contentstype4cc, 4,
				ictx->reversed_4cc ? DE_4CCFLAG_REVERSED : 0);

			if(level==0) {
				ictx->main_fmt4cc = ictx->curr_container_fmt4cc;
				ictx->main_contentstype4cc = ictx->curr_container_contentstype4cc; // struct copy
			}
			de_dbg(c, "contents type: '%s'", ictx->curr_container_contentstype4cc.id_dbgstr);

			if(ictx->on_std_container_start_fn) {
				// Call only for standard-format containers.
				ictx->chunkctx = &chunkctx;
				ret = ictx->on_std_container_start_fn(ictx);
				ictx->chunkctx = NULL;
				if(!ret) goto done;
			}
		}
		else { // ictx->is_raw_container
			contents_dpos = chunkctx.dpos;
			contents_dlen = chunkctx.dlen;
		}

		ret = do_iff_chunk_sequence(c, ictx, &chunkctx, contents_dpos, contents_dlen, level+1);
		if(!ret) {
			retval = 0;
			goto done;
		}

		if(ictx->on_container_end_fn) {
			// Call for all containers (not just standard-format containers).

			// TODO: Decide exactly what ictx->* fields to set here.
			ictx->level = level;

			ictx->chunkctx = &chunkctx;
			ret = ictx->on_container_end_fn(ictx);
			ictx->chunkctx = NULL;
			if(!ret) {
				retval = 0;
				goto done;
			}
		}
	}
	else if(!ictx->handled) {
		de_fmtutil_default_iff_chunk_handler(ictx);
	}

done:
	fourcc_clear(&ictx->curr_container_fmt4cc);
	fourcc_clear(&ictx->curr_container_contentstype4cc);

	de_dbg_indent_restore(c, saved_indent_level);
	return retval;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xf0, %rsp
movq 0x10(%rbp), %rax
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movl %r9d, -0x2c(%rbp)
movl $0x0, -0xc0(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0xc8(%rbp)
movq -0x8(%rbp), %rdi
leaq -0xbc(%rbp), %rsi
callq 0x15b580
leaq -0xb8(%rbp), %rdi
xorl %esi, %esi
movl $0x68, %edx
callq 0x19140
movq -0x18(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x10(%rbp), %rax
movq 0x50(%rax), %rax
addq $0x4, %rax
movq %rax, -0x50(%rbp)
movq -0x28(%rbp), %rax
cmpq -0x50(%rbp), %rax
jge 0x18ccf4
movq -0x8(%rbp), %rdi
movq -0x28(%rbp), %rdx
movq -0x20(%rbp), %rcx
leaq 0x4af72(%rip), %rsi     # 0x1d7c5a
movb $0x0, %al
callq 0x15bc10
jmp 0x18d1e7
movq -0x28(%rbp), %rax
subq -0x50(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x20(%rbp), %rsi
leaq -0xb8(%rbp), %rdx
movq -0x10(%rbp), %rax
movzbl 0x5c(%rax), %ecx
xorl %r8d, %r8d
movl $0x1, %eax
cmpl $0x0, %ecx
cmovnel %eax, %r8d
movl $0x4, %ecx
callq 0x169860
cmpl $0x0, -0xb4(%rbp)
jne 0x18cd5e
cmpl $0x0, -0x2c(%rbp)
jne 0x18cd5e
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rdx
leaq 0x4af3b(%rip), %rsi     # 0x1d7c8d
movb $0x0, %al
callq 0x15bc10
jmp 0x18d1e7
movq -0x10(%rbp), %rax
cmpq $0x2, 0x50(%rax)
jne 0x18cd8b
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x20(%rbp), %rsi
addq $0x4, %rsi
movq -0x10(%rbp), %rax
movl 0x58(%rax), %edx
callq 0x165820
movq %rax, -0x38(%rbp)
jmp 0x18cdab
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x20(%rbp), %rsi
addq $0x4, %rsi
movq -0x10(%rbp), %rax
movl 0x58(%rax), %edx
callq 0x1658c0
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x20(%rbp), %rax
addq -0x50(%rbp), %rax
movq %rax, -0x78(%rbp)
movl -0x2c(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x64(%rax)
movq -0x10(%rbp), %rax
leaq -0xb8(%rbp), %rcx
movq %rcx, 0x128(%rax)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x28(%rax)
je 0x18cdf4
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movq -0x10(%rbp), %rdi
callq *%rax
cmpq $0x0, -0x60(%rbp)
jne 0x18ce11
movq -0x10(%rbp), %rax
movzbl 0x5d(%rax), %eax
cmpl $0x0, %eax
je 0x18ce11
movq -0x10(%rbp), %rdi
callq 0x18d230
cmpq $0x0, -0x60(%rbp)
je 0x18ce38
movq -0xc8(%rbp), %rdi
movq -0x60(%rbp), %rcx
movl $0x50, %esi
leaq 0x2aabb(%rip), %rdx     # 0x1b78ea
movb $0x0, %al
callq 0x15a980
jmp 0x18ce42
movq -0xc8(%rbp), %rax
movb $0x0, (%rax)
movq -0x8(%rbp), %rdi
leaq -0xb8(%rbp), %rdx
addq $0x10, %rdx
movq -0xc8(%rbp), %rcx
movq -0x20(%rbp), %r8
movq -0x78(%rbp), %r9
movq -0x70(%rbp), %rax
leaq 0x4ae59(%rip), %rsi     # 0x1d7cc4
movq %rax, (%rsp)
movb $0x0, %al
callq 0x15b0d0
movq -0x8(%rbp), %rdi
movl $0x1, %esi
callq 0x15b560
movq -0x70(%rbp), %rax
cmpq -0x48(%rbp), %rax
jle 0x18cf1a
movl $0x1, -0xcc(%rbp)
cmpl $0x52494646, -0xb4(%rbp) # imm = 0x52494646
jne 0x18cecb
cmpq $0x0, -0x20(%rbp)
jne 0x18cecb
movq -0x28(%rbp), %rax
movq -0x10(%rbp), %rcx
movq 0x18(%rcx), %rcx
cmpq 0x18(%rcx), %rax
jne 0x18cecb
movl $0x0, -0xcc(%rbp)
cmpl $0x0, -0xcc(%rbp)
je 0x18cefc
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rax
movl %eax, %edx
movq -0x70(%rbp), %rcx
addq -0x78(%rbp), %rcx
movq -0x20(%rbp), %r8
addq -0x28(%rbp), %r8
leaq 0x4adf7(%rip), %rsi     # 0x1d7cec
movb $0x0, %al
callq 0x15bc10
movq -0x48(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x8(%rbp), %rdi
movq -0x70(%rbp), %rdx
leaq 0x4ae3a(%rip), %rsi     # 0x1d7d4d
movb $0x0, %al
callq 0x15b0d0
movq -0x70(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x48(%rax), %rsi
callq 0x15ce90
movq %rax, -0x40(%rbp)
movq -0x50(%rbp), %rcx
addq -0x40(%rbp), %rcx
movq 0x10(%rbp), %rax
movq %rcx, (%rax)
movl $0x1, -0xc0(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x10(%rbp), %rax
movl $0x0, 0x130(%rax)
movq -0x10(%rbp), %rax
movl $0x0, 0x134(%rax)
movq -0x10(%rbp), %rax
movl $0x0, 0x138(%rax)
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rax
movq -0x10(%rbp), %rdi
callq *%rax
movl %eax, -0x30(%rbp)
cmpl $0x0, -0x30(%rbp)
jne 0x18cfab
movl $0x0, -0xc0(%rbp)
jmp 0x18d1e7
movq -0x10(%rbp), %rax
cmpl $0x0, 0x134(%rax)
jne 0x18cfc9
movq -0x10(%rbp), %rax
cmpl $0x0, 0x138(%rax)
je 0x18d1cd
movq -0x10(%rbp), %rax
movq $0x0, 0x128(%rax)
movq -0x10(%rbp), %rdi
addq $0xc8, %rdi
leaq -0xb8(%rbp), %rsi
movl $0x30, %edx
callq 0x191e0
movq -0x10(%rbp), %rdi
addq $0xf8, %rdi
callq 0x18ca50
movq -0x10(%rbp), %rax
cmpl $0x0, 0x134(%rax)
je 0x18d11b
movq -0x78(%rbp), %rax
addq $0x4, %rax
movq %rax, -0xd8(%rbp)
movq -0x70(%rbp), %rax
subq $0x4, %rax
movq %rax, -0xe0(%rbp)
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x78(%rbp), %rsi
movq -0x10(%rbp), %rdx
addq $0xf8, %rdx
movq -0x10(%rbp), %rax
movzbl 0x5c(%rax), %ecx
xorl %r8d, %r8d
movl $0x1, %eax
cmpl $0x0, %ecx
cmovnel %eax, %r8d
movl $0x4, %ecx
callq 0x169860
cmpl $0x0, -0x2c(%rbp)
jne 0x18d0ae
movq -0x10(%rbp), %rdi
addq $0x68, %rdi
movq -0x10(%rbp), %rsi
addq $0xc8, %rsi
movl $0x30, %edx
callq 0x191e0
movq -0x10(%rbp), %rdi
addq $0x98, %rdi
movq -0x10(%rbp), %rsi
addq $0xf8, %rsi
movl $0x30, %edx
callq 0x191e0
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rdx
addq $0xf8, %rdx
addq $0x10, %rdx
leaq 0x4aca5(%rip), %rsi     # 0x1d7d6d
movb $0x0, %al
callq 0x15b0d0
movq -0x10(%rbp), %rax
cmpq $0x0, 0x30(%rax)
je 0x18d119
movq -0x10(%rbp), %rax
leaq -0xb8(%rbp), %rcx
movq %rcx, 0x128(%rax)
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movq -0x10(%rbp), %rdi
callq *%rax
movl %eax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movq $0x0, 0x128(%rax)
cmpl $0x0, -0x30(%rbp)
jne 0x18d117
jmp 0x18d1e7
jmp 0x18d119
jmp 0x18d131
movq -0x78(%rbp), %rax
movq %rax, -0xd8(%rbp)
movq -0x70(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0xd8(%rbp), %rcx
movq -0xe0(%rbp), %r8
movl -0x2c(%rbp), %r9d
addl $0x1, %r9d
leaq -0xb8(%rbp), %rdx
callq 0x18ca80
movl %eax, -0x30(%rbp)
cmpl $0x0, -0x30(%rbp)
jne 0x18d170
movl $0x0, -0xc0(%rbp)
jmp 0x18d1e7
movq -0x10(%rbp), %rax
cmpq $0x0, 0x38(%rax)
je 0x18d1cb
movl -0x2c(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x64(%rax)
movq -0x10(%rbp), %rax
leaq -0xb8(%rbp), %rcx
movq %rcx, 0x128(%rax)
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movq -0x10(%rbp), %rdi
callq *%rax
movl %eax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movq $0x0, 0x128(%rax)
cmpl $0x0, -0x30(%rbp)
jne 0x18d1c9
movl $0x0, -0xc0(%rbp)
jmp 0x18d1e7
jmp 0x18d1cb
jmp 0x18d1e5
movq -0x10(%rbp), %rax
cmpl $0x0, 0x130(%rax)
jne 0x18d1e3
movq -0x10(%rbp), %rdi
callq 0x18d2c0
jmp 0x18d1e5
jmp 0x18d1e7
movq -0x10(%rbp), %rdi
addq $0xc8, %rdi
callq 0x18ca50
movq -0x10(%rbp), %rdi
addq $0xf8, %rdi
callq 0x18ca50
movq -0x8(%rbp), %rdi
movl -0xbc(%rbp), %esi
callq 0x15b5a0
movl -0xc0(%rbp), %eax
addq $0xf0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)