// File: /workspace/github_c_makefile_star2_O0/jsummers[P]deark/src/fmtutil-lzh.c
// Function: deflate_block_type2_read_trees
static int deflate_block_type2_read_trees(deark *c, struct lzh_ctx *cctx)
{
	UI n;
	UI i;
	UI num_total_codes;
	UI num_literal_codes;
	UI num_dist_codes;
	UI num_bit_length_codes;
	int retval = 0;
	int ret;
	static const u8 cll_order[19] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11,
		4, 12, 3, 13, 2, 14, 1, 15};
	UI cll[19]; // sorted code length lengths
	UI prev_code = 0;
	UI num_rle_codes_left = 0;
	u8 stop_code_defined = 0;
	int saved_indent_level;

	de_dbg_indent_save(c, &saved_indent_level);
	lzh_destroy_trees(cctx);
	de_zeromem(cll, sizeof(cll));

	n = (UI)lzh_getbits(cctx, 5);
	num_literal_codes = n + 257;
	de_dbg2(c, "num lit/len codes: %u", num_literal_codes);

	n = (UI)lzh_getbits(cctx, 5);
	num_dist_codes = n + 1;
	de_dbg2(c, "num dist codes: %u", num_dist_codes);

	n = (UI)lzh_getbits(cctx, 4);
	num_bit_length_codes = n + 4;
	de_dbg2(c, "num bit-length codes: %u", num_bit_length_codes);

	// "Meta" tree - An unencoded sequence of Huffman code lengths, used
	// to construct a Huffman tree containing the code values (which
	// themselves are usually code lengths) used in the rest of the tree
	// definition section.

	cctx->meta_tree.ht = fmtutil_huffman_create_decoder(c, 19, 19);
	for(i=0; i<num_bit_length_codes; i++) {
		n = (UI)lzh_getbits(cctx, 3);
		cll[(UI)cll_order[i]] = n;
		if(c->debug_level>=3) {
			de_dbg3(c, "%u. length[%u] = %u", i, (UI)cll_order[i], n);
		}
	}
	for(i=0; i<19; i++) {
		if(cll[i]>0) {
			fmtutil_huffman_record_a_code_length(c, cctx->meta_tree.ht->builder,
				(fmtutil_huffman_valtype)i, cll[i]);
		}
	}
	if(fmtutil_huffman_hcb_get_num_codes(cctx->meta_tree.ht->builder) < 1) {
		// There must be at least 1, if only because it will ultimately be
		// needed to define the mandatory "stop" code.
		// (Actually, I think there must be at least two, for complicated reasons.)
		de_dfilter_set_errorf(cctx->c, cctx->dres, cctx->modname,
			"Bad \"code length codes\" table");
		goto done;
	}

	if(!fmtutil_huffman_make_canonical_code(c, cctx->meta_tree.ht->bk,
		cctx->meta_tree.ht->builder, 0, "derived codelengths codebook"))
	{
		goto done;
	}

	cctx->literals_tree.ht = fmtutil_huffman_create_decoder(c, num_literal_codes, 286);
	cctx->offsets_tree.ht = fmtutil_huffman_create_decoder(c, num_dist_codes, 32);

	de_dbg3(c, "[main lit/len/offsets definition table]");
	de_dbg_indent(c, 1);
	num_total_codes = num_literal_codes + num_dist_codes;
	for(i=0; i<num_total_codes; i++) {
		UI x;
		const char *tblname;
		UI code_bias;

		if(i<num_literal_codes) {
			tblname = "lit/len";
			code_bias = 0;
		}
		else {
			tblname = "offset";
			code_bias = num_literal_codes;
		}

		if(num_rle_codes_left>0) {
			x = prev_code;
			num_rle_codes_left--;
		}
		else {
			x = read_next_code_using_tree(cctx, &cctx->meta_tree);
			if(cctx->err_flag) goto done;

			if(x<=15) {
				prev_code = x;
				de_dbg3(c, "%s %u codelen: %u", tblname, i-code_bias, x);
			}
			else if(x==16) { // Read next 2 bits, copy prev code 3-6 times
				x = prev_code;
				n = (UI)lzh_getbits(cctx, 2);
				num_rle_codes_left = n + 3 - 1;
				de_dbg3(c, "[next %u codes same as prev]", n+3);
			}
			else if(x==17) { // Read next 3 bits, next 3-10 codes are 0
				x = 0;
				prev_code = 0;
				n = (UI)lzh_getbits(cctx, 3);
				num_rle_codes_left = n + 3 - 1;
				de_dbg3(c, "[next %u codes = 0]", n+3);
			}
			else if(x==18) { // Read next 7 bits, next 11-138 codes are 0
				x = 0;
				prev_code = 0;
				n = (UI)lzh_getbits(cctx, 7);
				num_rle_codes_left = n + 11 - 1;
				de_dbg3(c, "[next %u codes = 0]", n+11);
			}
			else {
				goto done;
			}
		}

		if(x==0) {
			ret = 1;
		}
		else if(i<num_literal_codes) {
			ret = fmtutil_huffman_record_a_code_length(c, cctx->literals_tree.ht->builder,
				(fmtutil_huffman_valtype)i, x);
			if(ret) {
				if(i==256) {
					stop_code_defined = 1;
				}
			}
		}
		else {
			ret = fmtutil_huffman_record_a_code_length(c, cctx->offsets_tree.ht->builder,
				(fmtutil_huffman_valtype)(i-code_bias), x);
		}
		if(!ret) goto done;

	}

	if(!stop_code_defined) {
		de_dfilter_set_errorf(cctx->c, cctx->dres, cctx->modname,
			"No \"end of block\" code definition found");
		goto done;
	}

	de_dbg_indent(c, -1);

	if(!fmtutil_huffman_make_canonical_code(c, cctx->literals_tree.ht->bk,
		cctx->literals_tree.ht->builder, 0, "derived lit/len codebook"))
	{
		goto done;
	}

	if(!fmtutil_huffman_make_canonical_code(c, cctx->offsets_tree.ht->bk,
		cctx->offsets_tree.ht->builder, 0, "derived offsets codebook"))
	{
		goto done;
	}

	retval = 1;
done:
	de_dbg_indent_restore(c, saved_indent_level);
	return retval;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0x0, -0x2c(%rbp)
movl $0x0, -0x84(%rbp)
movl $0x0, -0x88(%rbp)
movb $0x0, -0x89(%rbp)
movq -0x8(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x15b580
movq -0x10(%rbp), %rdi
callq 0x181bd0
leaq -0x80(%rbp), %rdi
xorl %esi, %esi
movl $0x4c, %edx
callq 0x19140
movq -0x10(%rbp), %rdi
movl $0x5, %esi
callq 0x181a10
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %eax
addl $0x101, %eax            # imm = 0x101
movl %eax, -0x20(%rbp)
movq -0x8(%rbp), %rdi
movl -0x20(%rbp), %edx
leaq 0x542a4(%rip), %rsi     # 0x1d705c
movb $0x0, %al
callq 0x15b350
movq -0x10(%rbp), %rdi
movl $0x5, %esi
callq 0x181a10
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
movq -0x8(%rbp), %rdi
movl -0x24(%rbp), %edx
leaq 0x5428b(%rip), %rsi     # 0x1d7072
movb $0x0, %al
callq 0x15b350
movq -0x10(%rbp), %rdi
movl $0x4, %esi
callq 0x181a10
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %eax
addl $0x4, %eax
movl %eax, -0x28(%rbp)
movq -0x8(%rbp), %rdi
movl -0x28(%rbp), %edx
leaq 0x5426f(%rip), %rsi     # 0x1d7085
movb $0x0, %al
callq 0x15b350
movq -0x8(%rbp), %rdi
movl $0x13, %edx
movq %rdx, %rsi
callq 0x188560
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x90(%rax)
movl $0x0, -0x18(%rbp)
movl -0x18(%rbp), %eax
cmpl -0x28(%rbp), %eax
jae 0x182eb4
movq -0x10(%rbp), %rdi
movl $0x3, %esi
callq 0x181a10
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %ecx
movl -0x18(%rbp), %eax
movl %eax, %edx
leaq 0x545b5(%rip), %rax     # 0x1d7420
movzbl (%rax,%rdx), %eax
movl %eax, %eax
movl %ecx, -0x80(%rbp,%rax,4)
movq -0x8(%rbp), %rax
cmpl $0x3, (%rax)
jl 0x182ea7
movq -0x8(%rbp), %rdi
movl -0x18(%rbp), %edx
movl -0x18(%rbp), %eax
movl %eax, %ecx
leaq 0x5458f(%rip), %rax     # 0x1d7420
movzbl (%rax,%rcx), %ecx
movl -0x14(%rbp), %r8d
leaq 0x541fe(%rip), %rsi     # 0x1d709e
movb $0x0, %al
callq 0x15b400
jmp 0x182ea9
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0x182e43
movl $0x0, -0x18(%rbp)
cmpl $0x13, -0x18(%rbp)
jae 0x182efa
movl -0x18(%rbp), %eax
cmpl $0x0, -0x80(%rbp,%rax,4)
jbe 0x182eed
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x90(%rax), %rax
movq 0x10(%rax), %rsi
movl -0x18(%rbp), %edx
movl -0x18(%rbp), %eax
movl -0x80(%rbp,%rax,4), %ecx
callq 0x187f20
jmp 0x182eef
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0x182ebb
movq -0x10(%rbp), %rax
movq 0x90(%rax), %rax
movq 0x10(%rax), %rdi
callq 0x187f00
cmpq $0x1, %rax
jge 0x182f3e
movq -0x10(%rbp), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rsi
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdx
leaq 0x54180(%rip), %rcx     # 0x1d70b2
movb $0x0, %al
callq 0x177450
jmp 0x183326
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x90(%rax), %rax
movq 0x8(%rax), %rsi
movq -0x10(%rbp), %rax
movq 0x90(%rax), %rax
movq 0x10(%rax), %rdx
xorl %ecx, %ecx
leaq 0x54167(%rip), %r8      # 0x1d70d0
callq 0x188020
cmpl $0x0, %eax
jne 0x182f78
jmp 0x183326
movq -0x8(%rbp), %rdi
movl -0x20(%rbp), %eax
movl %eax, %esi
movl $0x11e, %edx            # imm = 0x11E
callq 0x188560
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x98(%rax)
movq -0x8(%rbp), %rdi
movl -0x24(%rbp), %eax
movl %eax, %esi
movl $0x20, %edx
callq 0x188560
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0xa0(%rax)
movq -0x8(%rbp), %rdi
leaq 0x54128(%rip), %rsi     # 0x1d70ed
movb $0x0, %al
callq 0x15b400
movq -0x8(%rbp), %rdi
movl $0x1, %esi
callq 0x15b560
movl -0x20(%rbp), %eax
addl -0x24(%rbp), %eax
movl %eax, -0x1c(%rbp)
movl $0x0, -0x18(%rbp)
movl -0x18(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jae 0x183270
movl -0x18(%rbp), %eax
cmpl -0x20(%rbp), %eax
jae 0x183018
leaq 0x54110(%rip), %rax     # 0x1d7115
movq %rax, -0xa0(%rbp)
movl $0x0, -0xa4(%rbp)
jmp 0x18302f
leaq 0x54368(%rip), %rax     # 0x1d7387
movq %rax, -0xa0(%rbp)
movl -0x20(%rbp), %eax
movl %eax, -0xa4(%rbp)
cmpl $0x0, -0x88(%rbp)
jbe 0x183058
movl -0x84(%rbp), %eax
movl %eax, -0x94(%rbp)
movl -0x88(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x88(%rbp)
jmp 0x1831d1
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq $0x90, %rsi
callq 0x181ae0
movl %eax, -0x94(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x0, 0x30(%rax)
je 0x183081
jmp 0x183326
cmpl $0xf, -0x94(%rbp)
ja 0x1830c4
movl -0x94(%rbp), %eax
movl %eax, -0x84(%rbp)
movq -0x8(%rbp), %rdi
movq -0xa0(%rbp), %rdx
movl -0x18(%rbp), %ecx
subl -0xa4(%rbp), %ecx
movl -0x94(%rbp), %r8d
leaq 0x54065(%rip), %rsi     # 0x1d711d
movb $0x0, %al
callq 0x15b400
jmp 0x1831cf
cmpl $0x10, -0x94(%rbp)
jne 0x183116
movl -0x84(%rbp), %eax
movl %eax, -0x94(%rbp)
movq -0x10(%rbp), %rdi
movl $0x2, %esi
callq 0x181a10
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %eax
addl $0x3, %eax
subl $0x1, %eax
movl %eax, -0x88(%rbp)
movq -0x8(%rbp), %rdi
movl -0x14(%rbp), %edx
addl $0x3, %edx
leaq 0x54025(%rip), %rsi     # 0x1d712f
movb $0x0, %al
callq 0x15b400
jmp 0x1831cd
cmpl $0x11, -0x94(%rbp)
jne 0x18316d
movl $0x0, -0x94(%rbp)
movl $0x0, -0x84(%rbp)
movq -0x10(%rbp), %rdi
movl $0x3, %esi
callq 0x181a10
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %eax
addl $0x3, %eax
subl $0x1, %eax
movl %eax, -0x88(%rbp)
movq -0x8(%rbp), %rdi
movl -0x14(%rbp), %edx
addl $0x3, %edx
leaq 0x53fe8(%rip), %rsi     # 0x1d714c
movb $0x0, %al
callq 0x15b400
jmp 0x1831cb
cmpl $0x12, -0x94(%rbp)
jne 0x1831c4
movl $0x0, -0x94(%rbp)
movl $0x0, -0x84(%rbp)
movq -0x10(%rbp), %rdi
movl $0x7, %esi
callq 0x181a10
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %eax
addl $0xb, %eax
subl $0x1, %eax
movl %eax, -0x88(%rbp)
movq -0x8(%rbp), %rdi
movl -0x14(%rbp), %edx
addl $0xb, %edx
leaq 0x53f91(%rip), %rsi     # 0x1d714c
movb $0x0, %al
callq 0x15b400
jmp 0x1831c9
jmp 0x183326
jmp 0x1831cb
jmp 0x1831cd
jmp 0x1831cf
jmp 0x1831d1
cmpl $0x0, -0x94(%rbp)
jne 0x1831e3
movl $0x1, -0x30(%rbp)
jmp 0x183255
movl -0x18(%rbp), %eax
cmpl -0x20(%rbp), %eax
jae 0x183229
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x98(%rax), %rax
movq 0x10(%rax), %rsi
movl -0x18(%rbp), %edx
movl -0x94(%rbp), %ecx
callq 0x187f20
movl %eax, -0x30(%rbp)
cmpl $0x0, -0x30(%rbp)
je 0x183227
cmpl $0x100, -0x18(%rbp)     # imm = 0x100
jne 0x183225
movb $0x1, -0x89(%rbp)
jmp 0x183227
jmp 0x183253
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0xa0(%rax), %rax
movq 0x10(%rax), %rsi
movl -0x18(%rbp), %edx
subl -0xa4(%rbp), %edx
movl -0x94(%rbp), %ecx
callq 0x187f20
movl %eax, -0x30(%rbp)
jmp 0x183255
cmpl $0x0, -0x30(%rbp)
jne 0x183260
jmp 0x183326
jmp 0x183262
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0x182fea
cmpb $0x0, -0x89(%rbp)
jne 0x1832a3
movq -0x10(%rbp), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rsi
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rdx
leaq 0x53ec9(%rip), %rcx     # 0x1d7160
movb $0x0, %al
callq 0x177450
jmp 0x183326
movq -0x8(%rbp), %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x15b560
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x98(%rax), %rax
movq 0x8(%rax), %rsi
movq -0x10(%rbp), %rax
movq 0x98(%rax), %rax
movq 0x10(%rax), %rdx
xorl %ecx, %ecx
leaq 0x53eac(%rip), %r8      # 0x1d7188
callq 0x188020
cmpl $0x0, %eax
jne 0x1832e8
jmp 0x183326
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0xa0(%rax), %rax
movq 0x8(%rax), %rsi
movq -0x10(%rbp), %rax
movq 0xa0(%rax), %rax
movq 0x10(%rax), %rdx
xorl %ecx, %ecx
leaq 0x53e8e(%rip), %r8      # 0x1d71a1
callq 0x188020
cmpl $0x0, %eax
jne 0x18331f
jmp 0x183326
movl $0x1, -0x2c(%rbp)
movq -0x8(%rbp), %rdi
movl -0x90(%rbp), %esi
callq 0x15b5a0
movl -0x2c(%rbp), %eax
addq $0xb0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)