// File: /workspace/github_c_makefile_star2_O0/jsummers[P]deark/modules/tga.c
// Function: do_decode_image
static void do_decode_image(deark *c, lctx *d, struct tgaimginfo *imginfo, dbuf *unc_pixels,
	const char *token, UI createflags1)
{
	de_bitmap *img = NULL;
	de_finfo *fi = NULL;
	i64 i, j;
	i64 pdwidth;
	u8 b;
	u32 clr;
	u8 a;
	i64 rowspan;
	int output_bypp;
	UI getrgbflags;
	i64 interleave_stride;
	i64 interleave_pass;
	i64 cur_rownum; // 0-based, does not account for bottom-up orientation
	int has_alpha_0 = 0;
	int has_alpha_partial = 0;
	int has_alpha_255 = 0;
	UI createflags = createflags1;

	fi = de_finfo_create(c);

	if(token) {
		de_finfo_set_name_from_sz(c, fi, token, 0, DE_ENCODING_LATIN1);
	}
	if(d->mod_time.is_valid) {
		fi->internal_mod_time = d->mod_time;
	}

	pdwidth = imginfo->width;
	if(d->pixel_depth==1) {
		de_warn(c, "1-bit TGA images are not portable, and may not be decoded correctly");
		pdwidth = de_pad_to_n(imginfo->width, 8);
		rowspan = pdwidth/8;
	}
	else {
		rowspan = imginfo->width*d->bytes_per_pixel;
	}

	if(d->color_type==TGA_CLRTYPE_GRAYSCALE || d->pixel_depth==1)
		output_bypp=1;
	else if(d->pixel_depth==32)
		output_bypp=4;
	else
		output_bypp=3;

	if(d->file_format==FMT_VST)
		getrgbflags = 0;
	else
		getrgbflags = DE_GETRGBFLAG_BGR;

	img = de_bitmap_create2(c, imginfo->width, pdwidth, imginfo->height, output_bypp);

	switch(d->interleave_mode) {
	case 1: interleave_stride = 2; break;
	case 2: interleave_stride = 4; break;
	default: interleave_stride = 1;
	}

	cur_rownum = 0;
	interleave_pass = 0;

	for(j=0; j<imginfo->height; j++) {
		i64 j_adj;

		j_adj = cur_rownum;

		// Update the row number for next time
		cur_rownum += interleave_stride;
		if(cur_rownum >= imginfo->height) {
			// Went past the end of the image; move back to near the start.
			interleave_pass++;
			cur_rownum = interleave_pass;
		}

		if(d->pixel_depth==1) {
			de_convert_row_bilevel(unc_pixels, j*rowspan, img, j_adj, 0);
			continue;
		}

		for(i=0; i<pdwidth; i++) {
			if(d->color_type==TGA_CLRTYPE_TRUECOLOR && (d->pixel_depth==15 || d->pixel_depth==16)) {
				clr = (u32)dbuf_getu16le(unc_pixels, j*rowspan + i*d->bytes_per_pixel);
				clr = de_rgb555_to_888(clr);
				de_bitmap_setpixel_rgb(img, i, j_adj, clr);
			}
			else if(d->color_type==TGA_CLRTYPE_TRUECOLOR) {
				clr = dbuf_getRGB(unc_pixels, j*rowspan + i*d->bytes_per_pixel, getrgbflags);
				if(d->pixel_depth==32) {
					a = dbuf_getbyte(unc_pixels, j*rowspan + i*d->bytes_per_pixel+3);
					de_bitmap_setpixel_rgba(img, i, j_adj, DE_SET_ALPHA(clr, a));

					// Collect metrics that we may need, to decide whether to keep the
					// might-be-alpha channel.
					if(a==0) {
						has_alpha_0 = 1;
					}
					else if(a==0xff) {
						has_alpha_255 = 1;
					}
					else {
						has_alpha_partial = 1;
					}
				}
				else {
					de_bitmap_setpixel_rgb(img, i, j_adj, clr);
				}
			}
			else if(d->color_type==TGA_CLRTYPE_GRAYSCALE) {
				b = dbuf_getbyte(unc_pixels, j*rowspan + i*d->bytes_per_pixel);
				de_bitmap_setpixel_gray(img, i, j_adj, b);
			}
			else if(d->color_type==TGA_CLRTYPE_PALETTE) {
				b = dbuf_getbyte(unc_pixels, j*rowspan + i*d->bytes_per_pixel);
				de_bitmap_setpixel_rgb(img, i, j_adj, d->pal[(UI)b]);
			}
		}
	}

	// TODO: 16-bit images could theoretically have a transparency bit, but I don't
	// know how to detect that.
	if(d->pixel_depth==32) {
		// TODO: The transparency logic is a bit messy. It probably ought to be
		// redesigned from scratch.

		imginfo->respect_alpha_channel = should_use_alpha_channel(c, d, imginfo,
			has_alpha_0, has_alpha_partial, has_alpha_255);

		if(!imginfo->is_thumb) {
			de_dbg(c, "using alpha channel: %s", imginfo->respect_alpha_channel?"yes":"no");
		}

		if(!imginfo->respect_alpha_channel || (!has_alpha_0 && !has_alpha_partial)) {
			de_bitmap_remove_alpha(img);
		}

		if(imginfo->respect_alpha_channel && d->alpha_is_premultiplied) {
			bitmap_unpremultiply_alpha(img);
		}
	}

	if(d->right_to_left) {
		de_bitmap_mirror(img);
	}
	if(!d->top_down) {
		createflags |= DE_CREATEFLAG_FLIP_IMAGE;
	}

	createflags |= DE_CREATEFLAG_OPT_IMAGE;
	de_bitmap_write_to_file_finfo(img, fi, createflags);

	de_bitmap_destroy(img);
	de_finfo_destroy(c, fi);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movl %r9d, -0x2c(%rbp)
movq $0x0, -0x38(%rbp)
movq $0x0, -0x40(%rbp)
movl $0x0, -0x94(%rbp)
movl $0x0, -0x98(%rbp)
movl $0x0, -0x9c(%rbp)
movl -0x2c(%rbp), %eax
movl %eax, -0xa0(%rbp)
movq -0x8(%rbp), %rdi
callq 0x15d230
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x28(%rbp)
je 0x12bf07
movq -0x8(%rbp), %rdi
movq -0x40(%rbp), %rsi
movq -0x28(%rbp), %rdx
xorl %ecx, %ecx
movl $0x5, %r8d
callq 0x15d4c0
movq -0x10(%rbp), %rax
cmpb $0x0, 0x4e8(%rax)
je 0x12bf32
movq -0x40(%rbp), %rax
movq -0x10(%rbp), %rcx
movq 0x4e8(%rcx), %rdx
movq %rdx, 0x68(%rax)
movq 0x4f0(%rcx), %rcx
movq %rcx, 0x70(%rax)
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x58(%rbp)
movq -0x10(%rbp), %rax
cmpq $0x1, 0x70(%rax)
jne 0x12bf83
movq -0x8(%rbp), %rdi
leaq 0x9bcbb(%rip), %rsi     # 0x1c7c0e
movb $0x0, %al
callq 0x15bc10
movq -0x18(%rbp), %rax
movq (%rax), %rdi
movl $0x8, %esi
callq 0x15ce90
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movl $0x8, %ecx
cqto
idivq %rcx
movq %rax, -0x70(%rbp)
jmp 0x12bf9a
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq -0x10(%rbp), %rcx
imulq 0xb8(%rcx), %rax
movq %rax, -0x70(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x3, 0xa4(%rax)
je 0x12bfb2
movq -0x10(%rbp), %rax
cmpq $0x1, 0x70(%rax)
jne 0x12bfbb
movl $0x1, -0x74(%rbp)
jmp 0x12bfd8
movq -0x10(%rbp), %rax
cmpq $0x20, 0x70(%rax)
jne 0x12bfcf
movl $0x4, -0x74(%rbp)
jmp 0x12bfd6
movl $0x3, -0x74(%rbp)
jmp 0x12bfd8
movq -0x10(%rbp), %rax
cmpl $0x1, 0xc(%rax)
jne 0x12bfeb
movl $0x0, -0x78(%rbp)
jmp 0x12bff2
movl $0x1, -0x78(%rbp)
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rax
movq -0x58(%rbp), %rdx
movq (%rax), %rsi
movq 0x8(%rax), %rcx
movl -0x74(%rbp), %r8d
callq 0x16b7f0
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rax
movzbl 0x8c(%rax), %eax
movl %eax, -0xac(%rbp)
subl $0x1, %eax
je 0x12c037
jmp 0x12c02a
movl -0xac(%rbp), %eax
subl $0x2, %eax
je 0x12c041
jmp 0x12c04b
movq $0x2, -0x80(%rbp)
jmp 0x12c053
movq $0x4, -0x80(%rbp)
jmp 0x12c053
movq $0x1, -0x80(%rbp)
movq $0x0, -0x90(%rbp)
movq $0x0, -0x88(%rbp)
movq $0x0, -0x50(%rbp)
movq -0x50(%rbp), %rax
movq -0x18(%rbp), %rcx
cmpq 0x8(%rcx), %rax
jge 0x12c354
movq -0x90(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq -0x80(%rbp), %rax
addq -0x90(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rax
movq -0x18(%rbp), %rcx
cmpq 0x8(%rcx), %rax
jl 0x12c0d4
movq -0x88(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x88(%rbp)
movq -0x88(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x10(%rbp), %rax
cmpq $0x1, 0x70(%rax)
jne 0x12c104
movq -0x20(%rbp), %rdi
movq -0x50(%rbp), %rsi
imulq -0x70(%rbp), %rsi
movq -0x38(%rbp), %rdx
movq -0xa8(%rbp), %rcx
xorl %r8d, %r8d
callq 0x16be90
jmp 0x12c343
movq $0x0, -0x48(%rbp)
movq -0x48(%rbp), %rax
cmpq -0x58(%rbp), %rax
jge 0x12c341
movq -0x10(%rbp), %rax
cmpl $0x2, 0xa4(%rax)
jne 0x12c18c
movq -0x10(%rbp), %rax
cmpq $0xf, 0x70(%rax)
je 0x12c13d
movq -0x10(%rbp), %rax
cmpq $0x10, 0x70(%rax)
jne 0x12c18c
movq -0x20(%rbp), %rdi
movq -0x50(%rbp), %rsi
imulq -0x70(%rbp), %rsi
movq -0x48(%rbp), %rax
movq -0x10(%rbp), %rcx
imulq 0xb8(%rcx), %rax
addq %rax, %rsi
callq 0x165280
movl %eax, -0x60(%rbp)
movl -0x60(%rbp), %edi
callq 0x1619e0
movl %eax, -0x60(%rbp)
movq -0x38(%rbp), %rdi
movq -0x48(%rbp), %rsi
movq -0xa8(%rbp), %rdx
movl -0x60(%rbp), %ecx
callq 0x16b310
jmp 0x12c32e
movq -0x10(%rbp), %rax
cmpl $0x2, 0xa4(%rax)
jne 0x12c27f
movq -0x20(%rbp), %rdi
movq -0x50(%rbp), %rsi
imulq -0x70(%rbp), %rsi
movq -0x48(%rbp), %rax
movq -0x10(%rbp), %rcx
imulq 0xb8(%rcx), %rax
addq %rax, %rsi
movl -0x78(%rbp), %edx
callq 0x165ff0
movl %eax, -0x60(%rbp)
movq -0x10(%rbp), %rax
cmpq $0x20, 0x70(%rax)
jne 0x12c263
movq -0x20(%rbp), %rdi
movq -0x50(%rbp), %rsi
imulq -0x70(%rbp), %rsi
movq -0x48(%rbp), %rax
movq -0x10(%rbp), %rcx
imulq 0xb8(%rcx), %rax
addq %rax, %rsi
addq $0x3, %rsi
callq 0x165060
movb %al, -0x61(%rbp)
movq -0x38(%rbp), %rdi
movq -0x48(%rbp), %rsi
movq -0xa8(%rbp), %rdx
movl -0x60(%rbp), %ecx
andl $0xffffff, %ecx         # imm = 0xFFFFFF
movzbl -0x61(%rbp), %eax
shll $0x18, %eax
orl %eax, %ecx
callq 0x16b350
movzbl -0x61(%rbp), %eax
cmpl $0x0, %eax
jne 0x12c23e
movl $0x1, -0x94(%rbp)
jmp 0x12c261
movzbl -0x61(%rbp), %eax
cmpl $0xff, %eax
jne 0x12c255
movl $0x1, -0x9c(%rbp)
jmp 0x12c25f
movl $0x1, -0x98(%rbp)
jmp 0x12c261
jmp 0x12c27a
movq -0x38(%rbp), %rdi
movq -0x48(%rbp), %rsi
movq -0xa8(%rbp), %rdx
movl -0x60(%rbp), %ecx
callq 0x16b310
jmp 0x12c32c
movq -0x10(%rbp), %rax
cmpl $0x3, 0xa4(%rax)
jne 0x12c2ce
movq -0x20(%rbp), %rdi
movq -0x50(%rbp), %rsi
imulq -0x70(%rbp), %rsi
movq -0x48(%rbp), %rax
movq -0x10(%rbp), %rcx
imulq 0xb8(%rcx), %rax
addq %rax, %rsi
callq 0x165060
movb %al, -0x59(%rbp)
movq -0x38(%rbp), %rdi
movq -0x48(%rbp), %rsi
movq -0xa8(%rbp), %rdx
movzbl -0x59(%rbp), %ecx
callq 0x16b1c0
jmp 0x12c32a
movq -0x10(%rbp), %rax
cmpl $0x1, 0xa4(%rax)
jne 0x12c328
movq -0x20(%rbp), %rdi
movq -0x50(%rbp), %rsi
imulq -0x70(%rbp), %rsi
movq -0x48(%rbp), %rax
movq -0x10(%rbp), %rcx
imulq 0xb8(%rcx), %rax
addq %rax, %rsi
callq 0x165060
movb %al, -0x59(%rbp)
movq -0x38(%rbp), %rdi
movq -0x48(%rbp), %rsi
movq -0xa8(%rbp), %rdx
movq -0x10(%rbp), %rax
movzbl -0x59(%rbp), %ecx
movl %ecx, %ecx
movl 0xe8(%rax,%rcx,4), %ecx
callq 0x16b310
jmp 0x12c32a
jmp 0x12c32c
jmp 0x12c32e
jmp 0x12c330
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
jmp 0x12c10c
jmp 0x12c343
movq -0x50(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x50(%rbp)
jmp 0x12c071
movq -0x10(%rbp), %rax
cmpq $0x20, 0x70(%rax)
jne 0x12c413
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movl -0x94(%rbp), %ecx
movl -0x98(%rbp), %r8d
movl -0x9c(%rbp), %r9d
callq 0x12d4f0
movl %eax, %ecx
movq -0x18(%rbp), %rax
movl %ecx, 0x1c(%rax)
movq -0x18(%rbp), %rax
cmpl $0x0, 0x18(%rax)
jne 0x12c3c9
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rax
movl 0x1c(%rax), %ecx
leaq 0x87651(%rip), %rdx     # 0x1b39fe
leaq 0x96686(%rip), %rax     # 0x1c2a3a
cmpl $0x0, %ecx
cmovneq %rax, %rdx
leaq 0x9b890(%rip), %rsi     # 0x1c7c52
movb $0x0, %al
callq 0x15b0d0
movq -0x18(%rbp), %rax
cmpl $0x0, 0x1c(%rax)
je 0x12c3e5
cmpl $0x0, -0x94(%rbp)
jne 0x12c3ee
cmpl $0x0, -0x98(%rbp)
jne 0x12c3ee
movq -0x38(%rbp), %rdi
callq 0x16d070
movq -0x18(%rbp), %rax
cmpl $0x0, 0x1c(%rax)
je 0x12c411
movq -0x10(%rbp), %rax
movzbl 0x89(%rax), %eax
cmpl $0x0, %eax
je 0x12c411
movq -0x38(%rbp), %rdi
callq 0x12d740
jmp 0x12c413
movq -0x10(%rbp), %rax
cmpb $0x0, 0x8b(%rax)
je 0x12c429
movq -0x38(%rbp), %rdi
callq 0x16ca60
movq -0x10(%rbp), %rax
cmpb $0x0, 0x8a(%rax)
jne 0x12c445
movl -0xa0(%rbp), %eax
orl $0x4, %eax
movl %eax, -0xa0(%rbp)
movl -0xa0(%rbp), %eax
orl $0x2, %eax
movl %eax, -0xa0(%rbp)
movq -0x38(%rbp), %rdi
movq -0x40(%rbp), %rsi
movl -0xa0(%rbp), %edx
callq 0x16afa0
movq -0x38(%rbp), %rdi
callq 0x16af60
movq -0x8(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x15d260
addq $0xb0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)