// File: /workspace/github_c_makefile_star2_O2/albinoloverats[P]hide/src/png.c
// Function: write_png
static int write_png(image_info_t image_info, void (*progress_update)(uint64_t, uint64_t))
{
	errno = EXIT_SUCCESS;

	/* create file */
	FILE *fp = fopen(image_info.file, "wb");
	if (!fp)
		return errno;

	/* initialize stuff */
	png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	if (!png_ptr)
		goto cf;

	png_set_compression_level(png_ptr, 9/*Z_BEST_COMPRESSION*/);

	png_infop info_ptr = png_create_info_struct(png_ptr);
	if (!info_ptr)
		goto cleanup;

	if (setjmp(png_jmpbuf(png_ptr)))
		goto cleanup;

	png_init_io(png_ptr, fp);

	/* write header */
	if (setjmp(png_jmpbuf(png_ptr)))
		goto cleanup;

	png_byte color_type;
	switch (image_info.bpp)
	{
		case 3:
			color_type = PNG_COLOR_TYPE_RGB;
			break;
		case 4:
			color_type = PNG_COLOR_TYPE_RGBA;
			break;
		default:
			goto cleanup;
	}

	png_byte bit_depth;
	memcpy(&bit_depth, image_info.extra, sizeof bit_depth);
	png_set_IHDR(png_ptr, info_ptr, image_info.width, image_info.height, bit_depth,
			 color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
	free(image_info.extra);

	png_write_info(png_ptr, info_ptr);

	/* write bytes */
	if (setjmp(png_jmpbuf(png_ptr)))
		goto cleanup;

	png_write_image(png_ptr, image_info.buffer);

	/* end write */
	if (setjmp(png_jmpbuf(png_ptr)))
		goto cleanup;

	png_write_end(png_ptr, NULL);

	/* clean up heap allocation */
	for (uint64_t y = 0; y < image_info.height; y++)
	{
		free(image_info.buffer[y]);
		if (progress_update)
			progress_update(y, image_info.height);
	}
	free(image_info.buffer);

cleanup:
	png_destroy_write_struct(&png_ptr, &info_ptr);
cf:
	fclose(fp);
	return errno;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdi, %rbx
callq 0x1060
movq %rax, %r13
andl $0x0, (%rax)
movq 0x50(%rsp), %rdi
leaq 0xa65(%rip), %rsi       # 0x200e
callq 0x1110
testq %rax, %rax
je 0x165f
movq %rax, %r14
leaq 0xa46(%rip), %rdi       # 0x2007
xorl %eax, %eax
movl %eax, %ecx
movq %rcx, %rsi
movq %rcx, %rdx
callq 0x1190
movq %rax, 0x10(%rsp)
testq %rax, %rax
je 0x1657
movq %rax, %r15
pushq $0x9
popq %rsi
movq %rax, %rdi
callq 0x1090
movq %r15, %rdi
callq 0x1120
movq %rax, 0x8(%rsp)
testq %rax, %rax
je 0x1648
movq %rax, %r12
movq 0x29e4(%rip), %rsi      # 0x3fe8
movl $0xc8, %edx
movq %r15, %rdi
callq 0x10d0
movq %rax, %rdi
callq 0x10f0
testl %eax, %eax
jne 0x1648
movq %r15, %rdi
movq %r14, %rsi
callq 0x1170
movq 0x29b9(%rip), %rsi      # 0x3fe8
movl $0xc8, %edx
movq %r15, %rdi
callq 0x10d0
movq %rax, %rdi
callq 0x10f0
testl %eax, %eax
je 0x1672
leaq 0x10(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x1130
movq %r14, %rdi
callq 0x10b0
movl (%r13), %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x50(%rsp), %rcx
movzwl 0x38(%rcx), %eax
cmpl $0x3, %eax
je 0x1689
cmpl $0x4, %eax
jne 0x1648
pushq $0x6
jmp 0x168b
pushq $0x2
popq %r9
movq %r12, %rsi
movq %r12, (%rsp)
movq 0x48(%rcx), %rbp
movzbl (%rbp), %r8d
movl 0x30(%rcx), %edx
movq 0x28(%rcx), %r12
movl %r12d, %ecx
subq $0x8, %rsp
movq %r15, %rdi
pushq $0x0
pushq $0x0
pushq $0x0
callq 0x11d0
addq $0x20, %rsp
movq %rbp, %rdi
callq 0x1040
movq %r15, %rdi
movq (%rsp), %rsi
callq 0x1030
movq 0x2910(%rip), %rsi      # 0x3fe8
movl $0xc8, %edx
movq %r15, %rdi
callq 0x10d0
movq %rax, %rdi
callq 0x10f0
leaq 0x50(%rsp), %rcx
testl %eax, %eax
jne 0x1648
movq 0x40(%rcx), %rbp
movq %r15, %rdi
movq %rbp, %rsi
callq 0x10c0
movq 0x28d8(%rip), %rsi      # 0x3fe8
movl $0xc8, %edx
movq %r15, %rdi
callq 0x10d0
movq %rax, %rdi
callq 0x10f0
testl %eax, %eax
jne 0x1648
xorl %eax, %eax
movl %eax, %esi
movq %r15, %rdi
movq %rsi, %r15
callq 0x10e0
cmpq %r15, %r12
je 0x175d
movq (%rbp,%r15,8), %rdi
callq 0x1040
testq %rbx, %rbx
je 0x1758
movq %r15, %rdi
movq %r12, %rsi
callq *%rbx
incq %r15
jmp 0x173c
movq %rbp, %rdi
callq 0x1040
jmp 0x1648