// File: /workspace/github_c_makefile_star2_O0/jsummers[P]deark/modules/ico.c
// Function: do_image_data
static void do_image_data(deark *c, lctx *d, struct page_ctx *pg)
{
	de_finfo *fi = NULL;
	char filename_token[32];
	i64 pos1 = pg->data_offset;
	i64 len = pg->data_size;

	if(pos1+len > c->infile->len) goto done;

	if(!fmtutil_get_bmpinfo(c, c->infile, &pg->bi, pos1, len, DE_BMPINFO_ICO_FORMAT)) {
		de_err(c, "Invalid bitmap");
		goto done;
	}

	if(pg->bi.file_format == DE_BMPINFO_FMT_PNG) {
		do_extract_png(c, d, pos1, len);
		goto done;
	}

	switch(pg->bi.bitcount) {
	case 1: case 2: case 4: case 8: case 24: case 32:
		break;
	case 16:
		de_err(c, "(image #%d) Unsupported bit count (%d)", (int)pg->img_num, (int)pg->bi.bitcount);
		goto done;
	default:
		de_err(c, "(image #%d) Invalid bit count (%d)", (int)pg->img_num, (int)pg->bi.bitcount);
		goto done;
	}

	if(pg->bi.compression_field!=0) {
		// TODO: Support BITFIELDS
		de_err(c, "Compression / BITFIELDS not supported");
		goto done;
	}

	if(pg->bi.bitcount==32) {
		// 32bpp images have both an alpha channel, and a 1bpp "mask".
		// We never use a 32bpp image's mask (although we may extract it
		// separately).
		// I'm not sure that's necessarily the best thing to do. I think that
		// in theory the mask could be used to get inverted-background-color
		// pixels, though I don't know if Windows allows that.
		pg->use_mask = 0;
		pg->has_alpha_channel = 1;
	}
	else {
		pg->use_mask = 1;
	}

	de_snprintf(filename_token, sizeof(filename_token), "%dx%dx%d",
		(int)pg->bi.width, (int)pg->bi.height, (int)pg->bi.bitcount);

	pg->pdwidth = (pg->bi.rowspan * 8)/pg->bi.bitcount;
	pg->mask_pdwidth = pg->bi.mask_rowspan * 8;

	pg->img = de_bitmap_create2(c, pg->bi.width, pg->pdwidth, pg->bi.height, 4);

	// Read palette
	if (pg->bi.pal_entries > 0) {
		if(pg->bi.pal_entries>256) goto done;

		de_read_palette_rgb(c->infile,
			pos1+pg->bi.infohdrsize, pg->bi.pal_entries, pg->bi.bytes_per_pal_entry,
			pg->pal, 256, DE_GETRGBFLAG_BGR);
	}

	pg->fg_start = pos1 + pg->bi.size_of_headers_and_pal;
	pg->bg_start = pos1 + pg->bi.size_of_headers_and_pal + pg->bi.foreground_size;

	de_dbg(c, "foreground at %d, mask at %d", (int)pg->fg_start, (int)pg->bg_start);

	// Foreground padding pixels exist if the width times the bitcount is not a
	// multiple of 32. This is rare.
	// Mask padding pixels exist if the width is not a multiple of 32. This is
	// common (when width=16 or 48).

	// Note: For the -padpix feature, we never combine the mask image's padding
	// pixels with the foreground image's padding pixels.
	// Issues:
	//   (1) There may be more mask padding pixels than image padding pixels.
	//   (2) Inverse background pixels, and the warning about them.
	// The mask's padding will be normally be ignored, but the padded mask will
	// be written to a separate file if d->extract_unused_masks is enabled.

	pg->mask_img = de_bitmap_create2(c, pg->bi.width, pg->mask_pdwidth, pg->bi.height, 1);
	de_convert_image_bilevel(c->infile, pg->bg_start, pg->bi.mask_rowspan, pg->mask_img, 0);

	if(pg->bi.bitcount==32) {
		decode_fg_image_32(c, d, pg);
	}
	else {
		decode_fg_image_default(c, d, pg);
	}

	if(pg->has_inv_bkgd) {
		warn_inv_bkgd(c);
	}

	de_bitmap_optimize_alpha(pg->img, (pg->bi.bitcount==32)?0x1:0x0);

	fi = de_finfo_create(c);

	de_finfo_set_name_from_sz(c, fi, filename_token, 0, DE_ENCODING_ASCII);

	if(d->is_cur) {
		fi->has_hotspot = 1;
		fi->hotspot_x = pg->hotspot_x;
		fi->hotspot_y = pg->hotspot_y;
	}

	de_bitmap_write_to_file_finfo(pg->img, fi, DE_CREATEFLAG_FLIP_IMAGE);

	if(d->extract_unused_masks && (!pg->use_mask || (c->padpix && pg->mask_pdwidth>pg->bi.width))) {
		char maskname_token[32];

		de_snprintf(maskname_token, sizeof(maskname_token), "%dx%dx%dmask",
			(int)pg->bi.width, (int)pg->bi.height, (int)pg->bi.bitcount);
		de_bitmap_write_to_file(pg->mask_img, maskname_token, DE_CREATEFLAG_IS_AUX | DE_CREATEFLAG_FLIP_IMAGE);
	}

done:
	if(pg) {
		de_bitmap_destroy(pg->img);
		pg->img = NULL;
		de_bitmap_destroy(pg->mask_img);
		pg->mask_img = NULL;
	}
	de_finfo_destroy(c, fi);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq $0x0, -0x20(%rbp)
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x48(%rbp)
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x48(%rbp), %rax
addq -0x50(%rbp), %rax
movq -0x8(%rbp), %rcx
movq 0x18(%rcx), %rcx
cmpq 0x18(%rcx), %rax
jle 0xac4a2
jmp 0xac955
movq -0x8(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rsi
movq -0x18(%rbp), %rdx
addq $0x50, %rdx
movq -0x48(%rbp), %rcx
movq -0x50(%rbp), %r8
movl $0x2, %r9d
callq 0x172d70
cmpl $0x0, %eax
jne 0xac4e5
movq -0x8(%rbp), %rdi
leaq 0xfb623(%rip), %rsi     # 0x1a7afc
movb $0x0, %al
callq 0x15bfb0
jmp 0xac955
movq -0x18(%rbp), %rax
cmpl $0x1, 0x50(%rax)
jne 0xac509
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x48(%rbp), %rdx
movq -0x50(%rbp), %rcx
callq 0xac9b0
jmp 0xac955
movq -0x18(%rbp), %rax
movq 0x80(%rax), %rax
movq %rax, -0x78(%rbp)
decq %rax
subq $0x2, %rax
jb 0xac55f
jmp 0xac523
movq -0x78(%rbp), %rax
subq $0x4, %rax
je 0xac55f
jmp 0xac52f
movq -0x78(%rbp), %rax
subq $0x8, %rax
je 0xac55f
jmp 0xac53b
movq -0x78(%rbp), %rax
subq $0x10, %rax
je 0xac561
jmp 0xac547
movq -0x78(%rbp), %rax
subq $0x18, %rax
je 0xac55f
jmp 0xac553
movq -0x78(%rbp), %rax
subq $0x20, %rax
jne 0xac58e
jmp 0xac55f
jmp 0xac5bb
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rax
movq (%rax), %rax
movl %eax, %edx
movq -0x18(%rbp), %rax
movq 0x80(%rax), %rax
movl %eax, %ecx
leaq 0x1078b6(%rip), %rsi    # 0x1b3e38
movb $0x0, %al
callq 0x15bfb0
jmp 0xac955
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rax
movq (%rax), %rax
movl %eax, %edx
movq -0x18(%rbp), %rax
movq 0x80(%rax), %rax
movl %eax, %ecx
leaq 0x1078b0(%rip), %rsi    # 0x1b3e5f
movb $0x0, %al
callq 0x15bfb0
jmp 0xac955
movq -0x18(%rbp), %rax
cmpl $0x0, 0x88(%rax)
je 0xac5df
movq -0x8(%rbp), %rdi
leaq 0x1078af(%rip), %rsi    # 0x1b3e82
movb $0x0, %al
callq 0x15bfb0
jmp 0xac955
movq -0x18(%rbp), %rax
cmpq $0x20, 0x80(%rax)
jne 0xac605
movq -0x18(%rbp), %rax
movl $0x0, 0x40(%rax)
movq -0x18(%rbp), %rax
movl $0x1, 0x44(%rax)
jmp 0xac610
movq -0x18(%rbp), %rax
movl $0x1, 0x40(%rax)
leaq -0x40(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x70(%rax), %rax
movl %eax, %ecx
movq -0x18(%rbp), %rax
movq 0x78(%rax), %rax
movl %eax, %r8d
movq -0x18(%rbp), %rax
movq 0x80(%rax), %rax
movl %eax, %r9d
movl $0x20, %esi
leaq 0x1064df(%rip), %rdx    # 0x1b2b22
movb $0x0, %al
callq 0x15a980
movq -0x18(%rbp), %rax
movq 0xb0(%rax), %rax
shlq $0x3, %rax
movq -0x18(%rbp), %rcx
cqto
idivq 0x80(%rcx)
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x18(%rbp), %rax
movq 0xc0(%rax), %rcx
shlq $0x3, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x38(%rax)
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x70(%rax), %rsi
movq -0x18(%rbp), %rax
movq 0x30(%rax), %rdx
movq -0x18(%rbp), %rax
movq 0x78(%rax), %rcx
movl $0x4, %r8d
callq 0x16b7f0
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0xf0(%rax)
movq -0x18(%rbp), %rax
cmpq $0x0, 0xa0(%rax)
jle 0xac728
movq -0x18(%rbp), %rax
cmpq $0x100, 0xa0(%rax) # imm = 0x100
jle 0xac6e1
jmp 0xac955
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x48(%rbp), %rsi
movq -0x18(%rbp), %rax
addq 0x68(%rax), %rsi
movq -0x18(%rbp), %rax
movq 0xa0(%rax), %rdx
movq -0x18(%rbp), %rax
movq 0x98(%rax), %rcx
movq -0x18(%rbp), %r8
addq $0x100, %r8             # imm = 0x100
movl $0x100, %r9d            # imm = 0x100
movl $0x1, (%rsp)
callq 0x16c0c0
movq -0x48(%rbp), %rcx
movq -0x18(%rbp), %rax
addq 0xd8(%rax), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x48(%rbp), %rcx
movq -0x18(%rbp), %rax
addq 0xd8(%rax), %rcx
movq -0x18(%rbp), %rax
addq 0xb8(%rax), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movl %eax, %edx
movq -0x18(%rbp), %rax
movq 0x28(%rax), %rax
movl %eax, %ecx
leaq 0x107728(%rip), %rsi    # 0x1b3ea8
movb $0x0, %al
callq 0x15b0d0
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x70(%rax), %rsi
movq -0x18(%rbp), %rax
movq 0x38(%rax), %rdx
movq -0x18(%rbp), %rax
movq 0x78(%rax), %rcx
movl $0x1, %r8d
callq 0x16b7f0
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0xf8(%rax)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x18(%rbp), %rax
movq 0x28(%rax), %rsi
movq -0x18(%rbp), %rax
movq 0xc0(%rax), %rdx
movq -0x18(%rbp), %rax
movq 0xf8(%rax), %rcx
xorl %r8d, %r8d
callq 0x16bee0
movq -0x18(%rbp), %rax
cmpq $0x20, 0x80(%rax)
jne 0xac80b
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
callq 0xaca50
jmp 0xac81c
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
callq 0xacb70
movq -0x18(%rbp), %rax
cmpl $0x0, 0x48(%rax)
je 0xac82f
movq -0x8(%rbp), %rdi
callq 0xacd40
movq -0x18(%rbp), %rax
movq 0xf0(%rax), %rdi
movq -0x18(%rbp), %rax
movq 0x80(%rax), %rcx
xorl %esi, %esi
movl $0x1, %eax
cmpq $0x20, %rcx
cmovel %eax, %esi
callq 0x16d190
movq -0x8(%rbp), %rdi
callq 0x15d230
movq %rax, -0x20(%rbp)
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
leaq -0x40(%rbp), %rdx
xorl %ecx, %ecx
movl $0x1, %r8d
callq 0x15d4c0
movq -0x10(%rbp), %rax
cmpl $0x0, (%rax)
je 0xac8b1
movq -0x20(%rbp), %rax
movb $0x1, 0xe(%rax)
movq -0x18(%rbp), %rax
movl 0x18(%rax), %ecx
movq -0x20(%rbp), %rax
movl %ecx, 0x98(%rax)
movq -0x18(%rbp), %rax
movl 0x1c(%rax), %ecx
movq -0x20(%rbp), %rax
movl %ecx, 0x9c(%rax)
movq -0x18(%rbp), %rax
movq 0xf0(%rax), %rdi
movq -0x20(%rbp), %rsi
movl $0x4, %edx
callq 0x16afa0
movq -0x10(%rbp), %rax
cmpl $0x0, 0x4(%rax)
je 0xac953
movq -0x18(%rbp), %rax
cmpl $0x0, 0x40(%rax)
je 0xac900
movq -0x8(%rbp), %rax
movzbl 0xd5(%rax), %eax
cmpl $0x0, %eax
je 0xac953
movq -0x18(%rbp), %rax
movq 0x38(%rax), %rax
movq -0x18(%rbp), %rcx
cmpq 0x70(%rcx), %rax
jle 0xac953
leaq -0x70(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x70(%rax), %rax
movl %eax, %ecx
movq -0x18(%rbp), %rax
movq 0x78(%rax), %rax
movl %eax, %r8d
movq -0x18(%rbp), %rax
movq 0x80(%rax), %rax
movl %eax, %r9d
movl $0x20, %esi
leaq 0x107592(%rip), %rdx    # 0x1b3ec5
movb $0x0, %al
callq 0x15a980
movq -0x18(%rbp), %rax
movq 0xf8(%rax), %rdi
leaq -0x70(%rbp), %rsi
movl $0x5, %edx
callq 0x16afd0
jmp 0xac955
cmpq $0x0, -0x18(%rbp)
je 0xac99a
movq -0x18(%rbp), %rax
movq 0xf0(%rax), %rdi
callq 0x16af60
movq -0x18(%rbp), %rax
movq $0x0, 0xf0(%rax)
movq -0x18(%rbp), %rax
movq 0xf8(%rax), %rdi
callq 0x16af60
movq -0x18(%rbp), %rax
movq $0x0, 0xf8(%rax)
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x15d260
addq $0x80, %rsp
popq %rbp
retq