// File: Alcaro[P]bridges/obj/resources.cpp
// Function: resources::decomp_images(image*, unsigned char*, unsigned char*, unsigned char const*, unsigned long)
static void decomp_images(image * imgs, uint8_t * inflate_buf, uint8_t * inflate_buf_end, const uint8_t * deflated, size_t deflated_size)
{
	__asm__("" : "+r"(imgs)); // iterating a pointer to a single object is undefined behavior, force gcc to forget it's not an array
	uint32_t palette[(IMG_8F || IMG_87) ? 256 : 16];
	inflator::inflate(bytesw(inflate_buf, inflate_buf_end-inflate_buf), bytesr(deflated, deflated_size));
	while (inflate_buf != inflate_buf_end)
	{
		uint8_t head = *inflate_buf++;
		
		uint32_t transp = 0;
		
		// these IMG_ constants allow dead code elimination of unused image formats
		// they're also why this function is in a Python string rather than a normal cpp - can't DCE across files
		if (head&0x80)
		{
			if (IMG_8F && head == 0x8F) // grayscale
			{
				for (int i=0;i<256;i++) palette[i] = 0xFF000000 + i*0x010101;
			}
			else if (IMG_80 || IMG_81 || IMG_83 || IMG_87)
			{
				int len;
				if (IMG_87 && head == 0x87) len = *inflate_buf++;
				else if (IMG_80 || IMG_81 || IMG_83) len = (head&0x7F)>>3;
				else __builtin_unreachable();
				
				for (int i=0;i<=len;i++)
				{
					palette[i] = readu_le32(inflate_buf);
					inflate_buf += 4;
				}
			}
			else __builtin_unreachable();
			head &= 0x87; // mask out palette length
		}
		else if (IMG_BARGB && imgs->fmt == ifmt_bargb8888)
		{
			transp = readu_le32(inflate_buf);
			inflate_buf += 4;
		}
		else if (IMG_NOT_BARGB) {}
		else __builtin_unreachable();
		
		size_t line_size_raw = (((head&0x1F)+1) * imgs->width + 7) >> 3;
		size_t filtered_size = (line_size_raw+1) * imgs->height;
		size_t defiltered_line_size = line_size_raw+4;
		size_t defiltered_size = defiltered_line_size * imgs->height;
		
		uint8_t * defilter_start = inflate_buf + filtered_size - defiltered_size;
		
		image::png_defilter(defilter_start, defiltered_line_size, inflate_buf, ((head&0x1F)+7)>>3, line_size_raw, imgs->height);
		defilter_start += 4;
		
		if(0);
		else if (IMG_0F && head == 0x0F) imgs->png_unpack_rgb<4>(defilter_start, defiltered_line_size);
		else if (IMG_17 && head == 0x17) imgs->png_unpack_rgb<2>(defilter_start, defiltered_line_size);
		else if (IMG_1F && head == 0x1F) imgs->png_unpack_rgb<6>(defilter_start, defiltered_line_size);
		else if (IMG_80 && head == 0x80) imgs->png_unpack_plte<1>(defilter_start, defiltered_line_size, palette, -1);
		else if (IMG_81 && head == 0x81) imgs->png_unpack_plte<2>(defilter_start, defiltered_line_size, palette, -1);
		else if (IMG_83 && head == 0x83) imgs->png_unpack_plte<4>(defilter_start, defiltered_line_size, palette, -1);
		else if ((IMG_87 || IMG_8F) && head == 0x87) imgs->png_unpack_plte<8>(defilter_start, defiltered_line_size, palette, -1);
		else __builtin_unreachable();
		
		if (transp != 0)
		{
			uint32_t * px = imgs->pixels32;
			size_t n = imgs->width * imgs->height;
			while (n--)
			{
				if (px[n] == transp) px[n] &= 0x00FFFFFF;
			}
		}
		
		inflate_buf += filtered_size;
		imgs++;
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x4c0, %rsp            # imm = 0x4C0
movq %rdi, -0x28(%rbp)
movq %rsi, -0x30(%rbp)
movq %rdx, -0x38(%rbp)
movq %rcx, -0x40(%rbp)
movq %r8, -0x48(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x30(%rbp), %rsi
movq -0x38(%rbp), %rdx
movq -0x30(%rbp), %rax
subq %rax, %rdx
leaq -0x460(%rbp), %rdi
callq 0x5ed0
movq -0x40(%rbp), %rsi
movq -0x48(%rbp), %rdx
leaq -0x470(%rbp), %rdi
callq 0x5d70
movq -0x470(%rbp), %rsi
movq -0x468(%rbp), %rdx
leaq -0x460(%rbp), %rdi
callq 0xfe80
movq -0x30(%rbp), %rax
cmpq -0x38(%rbp), %rax
je 0x46f31
movq -0x30(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x30(%rbp)
movb (%rax), %al
movb %al, -0x471(%rbp)
movl $0x0, -0x478(%rbp)
movzbl -0x471(%rbp), %eax
andl $0x80, %eax
cmpl $0x0, %eax
je 0x46c69
movzbl -0x471(%rbp), %eax
cmpl $0x8f, %eax
jne 0x46be9
movl $0x0, -0x47c(%rbp)
cmpl $0x100, -0x47c(%rbp)    # imm = 0x100
jge 0x46be7
imull $0x10101, -0x47c(%rbp), %ecx # imm = 0x10101
addl $0xff000000, %ecx       # imm = 0xFF000000
movslq -0x47c(%rbp), %rax
movl %ecx, -0x450(%rbp,%rax,4)
movl -0x47c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x47c(%rbp)
jmp 0x46bac
jmp 0x46c55
movzbl -0x471(%rbp), %eax
andl $0x7f, %eax
sarl $0x3, %eax
movl %eax, -0x480(%rbp)
movl $0x0, -0x484(%rbp)
movl -0x484(%rbp), %eax
cmpl -0x480(%rbp), %eax
jg 0x46c53
movq -0x30(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
movl (%rax), %eax
movl %eax, -0xc(%rbp)
movl -0xc(%rbp), %ecx
movslq -0x484(%rbp), %rax
movl %ecx, -0x450(%rbp,%rax,4)
movq -0x30(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x30(%rbp)
movl -0x484(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x484(%rbp)
jmp 0x46c06
jmp 0x46c55
movzbl -0x471(%rbp), %eax
andl $0x87, %eax
movb %al, -0x471(%rbp)
jmp 0x46c9f
movq -0x28(%rbp), %rax
cmpl $0x8, 0x8(%rax)
jne 0x46c9b
movq -0x30(%rbp), %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
movl %eax, -0x478(%rbp)
movq -0x30(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x30(%rbp)
jmp 0x46c9d
jmp 0x46c9d
jmp 0x46c9f
movzbl -0x471(%rbp), %eax
andl $0x1f, %eax
addl $0x1, %eax
movq -0x28(%rbp), %rcx
imull (%rcx), %eax
addl $0x7, %eax
shrl $0x3, %eax
movl %eax, %eax
movq %rax, -0x490(%rbp)
movq -0x490(%rbp), %rax
addq $0x1, %rax
movq -0x28(%rbp), %rcx
movl 0x4(%rcx), %ecx
imulq %rcx, %rax
movq %rax, -0x498(%rbp)
movq -0x490(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x4a0(%rbp)
movq -0x4a0(%rbp), %rax
movq -0x28(%rbp), %rcx
movl 0x4(%rcx), %ecx
imulq %rcx, %rax
movq %rax, -0x4a8(%rbp)
movq -0x30(%rbp), %rax
addq -0x498(%rbp), %rax
xorl %ecx, %ecx
subq -0x4a8(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x4b0(%rbp)
movq -0x4b0(%rbp), %rdi
movq -0x4a0(%rbp), %rsi
movq -0x30(%rbp), %rdx
movzbl -0x471(%rbp), %ecx
andl $0x1f, %ecx
addl $0x7, %ecx
sarl $0x3, %ecx
movq -0x490(%rbp), %r8
movq -0x28(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, %r9d
callq 0x15fa0
movq -0x4b0(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x4b0(%rbp)
movzbl -0x471(%rbp), %eax
cmpl $0xf, %eax
jne 0x46d9a
movq -0x28(%rbp), %rdi
movq -0x4b0(%rbp), %rsi
movq -0x4a0(%rbp), %rdx
callq 0x17e20
jmp 0x46e90
movzbl -0x471(%rbp), %eax
cmpl $0x17, %eax
jne 0x46dc2
movq -0x28(%rbp), %rdi
movq -0x4b0(%rbp), %rsi
movq -0x4a0(%rbp), %rdx
callq 0x17b80
jmp 0x46e8e
movzbl -0x471(%rbp), %eax
cmpl $0x1f, %eax
jne 0x46dea
movq -0x28(%rbp), %rdi
movq -0x4b0(%rbp), %rsi
movq -0x4a0(%rbp), %rdx
callq 0x17ee0
jmp 0x46e8c
movzbl -0x471(%rbp), %eax
cmpl $0x80, %eax
jne 0x46e1e
movq -0x28(%rbp), %rdi
movq -0x4b0(%rbp), %rsi
movq -0x4a0(%rbp), %rdx
leaq -0x450(%rbp), %rcx
movl $0xffffffff, %r8d       # imm = 0xFFFFFFFF
callq 0x171a0
jmp 0x46e8a
movzbl -0x471(%rbp), %eax
cmpl $0x83, %eax
jne 0x46e52
movq -0x28(%rbp), %rdi
movq -0x4b0(%rbp), %rsi
movq -0x4a0(%rbp), %rdx
leaq -0x450(%rbp), %rcx
movl $0xffffffff, %r8d       # imm = 0xFFFFFFFF
callq 0x17870
jmp 0x46e88
movzbl -0x471(%rbp), %eax
cmpl $0x87, %eax
jne 0x46e86
movq -0x28(%rbp), %rdi
movq -0x4b0(%rbp), %rsi
movq -0x4a0(%rbp), %rdx
leaq -0x450(%rbp), %rcx
movl $0xffffffff, %r8d       # imm = 0xFFFFFFFF
callq 0x17c40
jmp 0x46e86
jmp 0x46e88
jmp 0x46e8a
jmp 0x46e8c
jmp 0x46e8e
jmp 0x46e90
cmpl $0x0, -0x478(%rbp)
je 0x46f11
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x4b8(%rbp)
movq -0x28(%rbp), %rax
movl (%rax), %eax
movq -0x28(%rbp), %rcx
imull 0x4(%rcx), %eax
movl %eax, %eax
movq %rax, -0x4c0(%rbp)
movq -0x4c0(%rbp), %rax
movq %rax, %rcx
addq $-0x1, %rcx
movq %rcx, -0x4c0(%rbp)
cmpq $0x0, %rax
je 0x46f0f
movq -0x4b8(%rbp), %rax
movq -0x4c0(%rbp), %rcx
movl (%rax,%rcx,4), %eax
cmpl -0x478(%rbp), %eax
jne 0x46f0d
movq -0x4b8(%rbp), %rax
movq -0x4c0(%rbp), %rcx
movl (%rax,%rcx,4), %edx
andl $0xffffff, %edx         # imm = 0xFFFFFF
movl %edx, (%rax,%rcx,4)
jmp 0x46ebf
jmp 0x46f11
movq -0x498(%rbp), %rax
addq -0x30(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x28(%rbp), %rax
addq $0x18, %rax
movq %rax, -0x28(%rbp)
jmp 0x46b50
addq $0x4c0, %rsp            # imm = 0x4C0
popq %rbp
retq
nopw (%rax,%rax)