// File: /workspace/github_c_makefile_star2_O3/jsummers[P]deark/modules/tiff.c
// Function: paint_decompressed_strile_to_image
static void paint_decompressed_strile_to_image(deark *c, lctx *d, struct page_ctx *pg,
	struct decode_page_ctx *dctx, de_bitmap *img, de_bitmap *img_lo)
{
	i64 i, j;
	u32 s_idx;
	u32 sample_mask;
	u32 sample_scalefactor;
	u32 prev_sample[DE_TIFF_MAX_SAMPLES];
	u32 sample[DE_TIFF_MAX_SAMPLES];
	u8 sample_lo[DE_TIFF_MAX_SAMPLES];
	de_color clr_lo = 0;

	de_zeromem(&prev_sample, sizeof(prev_sample));
	de_zeromem(&sample, sizeof(sample));
	de_zeromem(&sample_lo, sizeof(sample_lo));

	sample_mask = (1U<<(u32)pg->bits_per_sample)-1U;
	if(pg->bits_per_sample<=8) {
		sample_scalefactor = 255/sample_mask;
	}
	else {
		sample_scalefactor = 1;
	}

	for(j=0; j<dctx->strileset_height; j++) {

		for(s_idx=0; s_idx<dctx->samples_per_pixel_to_decode; s_idx++) {
			prev_sample[s_idx] = 0;
		}

		for(i=0; i<dctx->strileset_width; i++) {
			de_color clr;

			for(s_idx=0; s_idx<dctx->samples_per_pixel_to_decode; s_idx++) {
				UI dbuf_idx;
				i64 sample_offset;
				i64 bytepos;

				if(dctx->is_separated) {
					dbuf_idx = s_idx;
					sample_offset = 0;
				}
				else {
					dbuf_idx = 0;
					sample_offset = (i64)s_idx;
				}

				switch(pg->bits_per_sample) {
				case 1: case 2: case 4:
					sample[s_idx] = de_get_bits_symbol(dctx->unc_strile_dbuf[dbuf_idx], (i64)pg->bits_per_sample,
						dctx->strileset_rowspan*j, i*(i64)dctx->samples_per_pixel_per_plane + sample_offset);
					break;
				case 8:
					bytepos = dctx->strileset_rowspan*j + i*(i64)dctx->samples_per_pixel_per_plane + sample_offset;
					sample[s_idx] = dbuf_getbyte(dctx->unc_strile_dbuf[dbuf_idx], bytepos);
					break;
				case 16:
					bytepos = dctx->strileset_rowspan*j + (i*(i64)dctx->samples_per_pixel_per_plane + sample_offset)*2;
					// Byte order for 16-bit samples is dictated by the TIFF file header -- at least
					// for uncompressed images.
					sample[s_idx] = (u32)dbuf_getu16x(dctx->unc_strile_dbuf[dbuf_idx], bytepos, d->is_le);
					break;
				default:
					sample[s_idx] = 0;
				}
			}

			if(pg->predictor==2) {
				for(s_idx=0; s_idx<dctx->samples_per_pixel_to_decode; s_idx++) {
					sample[s_idx] = (sample[s_idx] + prev_sample[s_idx]) & sample_mask;
					prev_sample[s_idx] = sample[s_idx];
				}
			}

			if(!dctx->use_pal && sample_scalefactor>1) { // Scale samples to 255
				for(s_idx=0; s_idx<dctx->samples_per_pixel_to_decode; s_idx++) {
					sample[s_idx] *= sample_scalefactor;
				}
			}

			if(dctx->grayscale_reverse_polarity) {
				if(pg->bits_per_sample==16)
					sample[0] = 0xffff - sample[0];
				else
					sample[0] = 0xff - sample[0];
			}

			if(pg->bits_per_sample==16) {
				for(s_idx=0; s_idx<dctx->samples_per_pixel_to_decode; s_idx++) {
					sample_lo[s_idx] = sample[s_idx] & 0xff;
					sample[s_idx] >>= 8;
				}
			}

			if(dctx->use_pal) {
				UI palidx;

				if(pg->is_dexxa && pg->dexxa_ncolors==16) {
					palidx = (sample[3]<<3) | (sample[2]<<2) | (sample[1]<<1) | sample[0];
					if(pg->compression==CMPR_CCITTRLE) {
						palidx = 15 - palidx;
					}
				}
				else {
					palidx = sample[0];
				}
				clr = pg->pal[palidx & 0xff];
			}
			else if(dctx->is_grayscale) {
				clr = DE_MAKE_GRAY(sample[0]);
				if(dctx->dst_flag_16bit) {
					clr_lo = DE_MAKE_GRAY(sample_lo[0]);
				}
			}
			else {
				clr = DE_MAKE_RGB(sample[0], sample[1], sample[2]);
			}

			if(dctx->has_alpha) {
				clr = DE_SET_ALPHA(clr, sample[dctx->alpha_sample_idx]);
				if(dctx->is_assoc_alpha) {
					clr = de_unpremultiply_alpha_clr(clr);
				}
			}

			de_bitmap_setpixel_rgba(img, dctx->strileset_xpos+i, dctx->strileset_ypos+j, clr);
			if(dctx->dst_flag_16bit) {
				de_bitmap_setpixel_rgba(img_lo, dctx->strileset_xpos+i, dctx->strileset_ypos+j, clr_lo);
			}
		}
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movq %r8, 0x48(%rsp)
movq %rcx, 0x50(%rsp)
movq %rdx, %r15
movq %rsi, %r12
xorps %xmm0, %xmm0
movaps %xmm0, 0x60(%rsp)
movaps %xmm0, 0x70(%rsp)
xorl %eax, %eax
movq %rax, 0x80(%rsp)
movaps %xmm0, (%rsp)
movaps %xmm0, 0x10(%rsp)
movq %rax, 0x20(%rsp)
movq %rax, 0x30(%rsp)
movw $0x0, 0x38(%rsp)
movl 0x28(%rsi), %ecx
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
shll %cl, %esi
movq %rdi, 0x58(%rsp)
notl %esi
movl $0x1, %ebp
cmpl $0x8, %ecx
ja 0xd021b
movl $0xff, %eax
xorl %edx, %edx
divl %esi
movl %eax, %ebp
movl %esi, 0x2c(%rsp)
movq 0x50(%r15), %r14
testq %r14, %r14
jle 0xd054a
movq $0x0, 0x40(%rsp)
xorl %ebx, %ebx
movl 0xc4(%r15), %edx
testq %rdx, %rdx
je 0xd0253
shlq $0x2, %rdx
leaq 0x60(%rsp), %rdi
xorl %esi, %esi
callq 0x18140
cmpq $0x0, 0x58(%r15)
jle 0xd053e
xorl %r13d, %r13d
cmpl $0x0, 0xc4(%r15)
je 0xd03a0
xorl %r14d, %r14d
xorl %eax, %eax
cmpb $0x0, 0xcd(%r15)
movq %r14, %rcx
cmoveq %rax, %rcx
movl $0x0, %r8d
cmoveq %r14, %r8
movslq 0x28(%r12), %rsi
cmpq $0x7, %rsi
jg 0xd02c4
leal -0x1(%rsi), %edx
cmpl $0x2, %edx
jb 0xd02a5
cmpl $0x4, %esi
jne 0xd031b
movq 0x70(%r15,%rcx,8), %rdi
movq 0x60(%r15), %rdx
imulq %rbx, %rdx
movl 0x30(%r15), %ecx
imulq %r13, %rcx
addq %r8, %rcx
callq 0xf26f9
jmp 0xd0318
cmpl $0x8, %esi
je 0xd02f8
cmpl $0x10, %esi
jne 0xd031b
movq 0x60(%r15), %rax
imulq %rbx, %rax
movl 0x30(%r15), %edx
imulq %r13, %rdx
addq %r8, %rdx
leaq (%rax,%rdx,2), %rsi
movq 0x70(%r15,%rcx,8), %rdi
movq 0x58(%rsp), %rax
movl (%rax), %edx
callq 0xeef43
jmp 0xd031b
movq 0x60(%r15), %rsi
imulq %rbx, %rsi
movl 0x30(%r15), %eax
imulq %r13, %rax
addq %r8, %rsi
addq %rax, %rsi
movq 0x70(%r15,%rcx,8), %rdi
callq 0xeead3
movzbl %al, %eax
movl %eax, (%rsp,%r14,4)
incq %r14
movl 0xc4(%r15), %eax
cmpq %rax, %r14
jb 0xd0272
cmpl $0x2, 0x3c(%r12)
setne %cl
testl %eax, %eax
setne %dl
sete %sil
orb %cl, %sil
movl 0x2c(%rsp), %edi
jne 0xd0367
xorl %ecx, %ecx
movl 0x60(%rsp,%rcx,4), %esi
addl (%rsp,%rcx,4), %esi
andl %edi, %esi
movl %esi, (%rsp,%rcx,4)
movl %esi, 0x60(%rsp,%rcx,4)
incq %rcx
cmpq %rcx, %rax
jne 0xd034f
testl %eax, %eax
sete %sil
cmpl $0x2, %ebp
setb %dil
cmpb $0x0, 0xd3(%r15)
sete %cl
setne %r8b
orb %sil, %dil
orb %r8b, %dil
jne 0xd03af
xorl %esi, %esi
movl (%rsp,%rsi,4), %edi
imull %ebp, %edi
movl %edi, (%rsp,%rsi,4)
incq %rsi
cmpq %rsi, %rax
jne 0xd038d
jmp 0xd03af
cmpb $0x0, 0xd3(%r15)
sete %cl
xorl %eax, %eax
xorl %edx, %edx
cmpb $0x0, 0xd0(%r15)
movl 0x28(%r12), %esi
je 0xd03d3
movl (%rsp), %edi
cmpl $0x10, %esi
jne 0xd03fe
movl $0xffff, %r8d           # imm = 0xFFFF
subl %edi, %r8d
movl %r8d, (%rsp)
cmpl $0x10, %esi
setne %sil
xorb $0x1, %dl
orb %sil, %dl
jne 0xd0408
movl %eax, %eax
xorl %edx, %edx
movl (%rsp,%rdx,4), %esi
movb %sil, 0x30(%rsp,%rdx)
shrl $0x8, %esi
movl %esi, (%rsp,%rdx,4)
incq %rdx
cmpq %rdx, %rax
jne 0xd03e6
jmp 0xd0408
movl $0xff, %eax
subl %edi, %eax
movl %eax, (%rsp)
testb %cl, %cl
je 0xd0452
movl (%rsp), %edx
movl %edx, %eax
shll $0x10, %eax
cmpb $0x0, 0xcf(%r15)
je 0xd0497
movl %edx, %ecx
shll $0x8, %ecx
orl %eax, %ecx
orl %edx, %ecx
orl $0xff000000, %ecx       # imm = 0xFF000000
cmpb $0x0, 0xce(%r15)
je 0xd04bb
movzbl 0x30(%rsp), %eax
imull $0x10101, %eax, %eax    # imm = 0x10101
orl $0xff000000, %eax       # imm = 0xFF000000
movq %rax, 0x40(%rsp)
jmp 0xd04bb
cmpb $0x0, 0x99(%r12)
je 0xd04ac
cmpb $0x10, 0x9a(%r12)
movl (%rsp), %eax
jne 0xd04b0
movl 0xc(%rsp), %ecx
shll $0x3, %ecx
movl 0x4(%rsp), %edx
movl 0x8(%rsp), %esi
shll $0x2, %esi
orl %ecx, %esi
addl %edx, %edx
orl %eax, %edx
orl %esi, %edx
movl $0xf, %eax
subl %edx, %eax
cmpl $0x2, 0x1c(%r12)
cmovnel %edx, %eax
jmp 0xd04b0
movl 0x4(%rsp), %ecx
shll $0x8, %ecx
orl 0x8(%rsp), %ecx
orl %eax, %ecx
orl $0xff000000, %ecx       # imm = 0xFF000000
jmp 0xd04bb
movzbl (%rsp), %eax
movzbl %al, %eax
movl 0xd0(%r12,%rax,4), %ecx
cmpb $0x0, 0xd4(%r15)
je 0xd04ee
movl %ecx, %eax
andl $0xffffff, %eax         # imm = 0xFFFFFF
movl 0xd8(%r15), %ecx
movl (%rsp,%rcx,4), %ecx
shll $0x18, %ecx
orl %eax, %ecx
cmpb $0x0, 0xd5(%r15)
je 0xd04ee
movl %ecx, %edi
callq 0xf3d94
movl %eax, %ecx
movq 0x40(%r15), %rsi
addq %r13, %rsi
movq 0x48(%r15), %rdx
addq %rbx, %rdx
movq 0x50(%rsp), %rdi
callq 0xf24bf
cmpb $0x0, 0xce(%r15)
je 0xd052d
movq 0x40(%r15), %rsi
addq %r13, %rsi
movq 0x48(%r15), %rdx
addq %rbx, %rdx
movq 0x48(%rsp), %rdi
movq 0x40(%rsp), %rcx
callq 0xf24bf
incq %r13
cmpq 0x58(%r15), %r13
jl 0xd0261
movq 0x50(%r15), %r14
incq %rbx
cmpq %r14, %rbx
jl 0xd0237
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq