// File: /workspace/github_c_makefile_star2_O1/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
movl $0x0, (%rax)
movq %rax, %rbp
movq 0x50(%rsp), %rdi
leaq 0xa57(%rip), %rsi       # 0x200e
callq 0x1110
testq %rax, %rax
je 0x1675
movq %rax, %r14
leaq 0xa38(%rip), %rdi       # 0x2007
xorl %eax, %eax
movl %eax, %ecx
movq %rcx, %rsi
movq %rcx, %rdx
callq 0x1190
movq %rax, 0x8(%rsp)
testq %rax, %rax
je 0x166d
movq %rax, %rdi
movl $0x9, %esi
callq 0x1090
movq 0x8(%rsp), %rdi
callq 0x1120
movq %rax, 0x10(%rsp)
testq %rax, %rax
je 0x165e
movq 0x8(%rsp), %rdi
movq 0x29cf(%rip), %rsi      # 0x3fe8
movl $0xc8, %edx
callq 0x10d0
movq %rax, %rdi
callq 0x10f0
testl %eax, %eax
jne 0x165e
movq 0x8(%rsp), %rdi
movq %r14, %rsi
callq 0x1170
movq 0x8(%rsp), %rdi
movq 0x29a0(%rip), %rsi      # 0x3fe8
movl $0xc8, %edx
callq 0x10d0
movq %rax, %rdi
callq 0x10f0
testl %eax, %eax
je 0x1687
leaq 0x8(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x1130
movq %r14, %rdi
callq 0x10b0
movl (%rbp), %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x50(%rsp), %r13
movzwl 0x38(%r13), %eax
cmpl $0x3, %eax
je 0x16a3
cmpl $0x4, %eax
jne 0x165e
movl $0x6, %r9d
jmp 0x16a9
movl $0x2, %r9d
movq 0x48(%r13), %r12
movzbl (%r12), %r8d
movq 0x8(%rsp), %rdi
movq 0x10(%rsp), %rsi
movl 0x30(%r13), %edx
movq 0x28(%r13), %r15
movl %r15d, %ecx
subq $0x8, %rsp
xorl %eax, %eax
movl %eax, %r10d
pushq %r10
pushq %r10
pushq %rax
callq 0x11d0
addq $0x20, %rsp
movq %r12, %rdi
callq 0x1040
movq 0x8(%rsp), %rdi
movq 0x10(%rsp), %rsi
callq 0x1030
movq 0x8(%rsp), %rdi
movq 0x28e7(%rip), %rsi      # 0x3fe8
movl $0xc8, %edx
callq 0x10d0
movq %rax, %rdi
callq 0x10f0
testl %eax, %eax
jne 0x165e
movq 0x8(%rsp), %rdi
movq 0x40(%r13), %r12
movq %r12, %rsi
callq 0x10c0
movq 0x8(%rsp), %rdi
movq 0x28b0(%rip), %rsi      # 0x3fe8
movl $0xc8, %edx
callq 0x10d0
movq %rax, %rdi
callq 0x10f0
testl %eax, %eax
jne 0x165e
movq 0x8(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x10e0
testq %r15, %r15
je 0x178e
xorl %eax, %eax
movl %eax, %r13d
movq (%r12,%r13,8), %rdi
callq 0x1040
testq %rbx, %rbx
je 0x1780
movq %r13, %rdi
movq %r15, %rsi
callq *%rbx
movq %r13, %rax
incq %rax
movq %rax, %r13
cmpq %rax, %r15
jne 0x176a
movq %r12, %rdi
callq 0x1040
jmp 0x165e