// File: /workspace/github_c_makefile_star2_O3/enzo1982[P]smooth/classes/graphics/imageloader/jpeg.cpp
// Function: smooth::GUI::ImageLoaderJPEG::Load()
const S::GUI::Bitmap &S::GUI::ImageLoaderJPEG::Load()
{
	/* Make sure bitmap is initialized.
	 */
	bitmap = NIL;

	/* Check magic number.
	 */
	if	( gotBuffer && (buffer[0] != 0xFF || buffer[1] != 0xD8))			     return bitmap;
	else if (!gotBuffer && InStream(STREAM_FILE, fileName, IS_READ).InputNumberRaw(2) != 0xFFD8) return bitmap;

	/* Open stream.
	 */
	FILE	 *stream = NIL;

	if (!gotBuffer)
	{
#ifdef __WIN32__
		stream = _wfopen(fileName, L"rb");
#else
		stream = fopen(fileName.ConvertTo("UTF-8"), "rb");
#endif

		if (stream == NIL) return bitmap;
	}

	/* This struct contains the JPEG decompression parameters and pointers to
	 * working space (which is allocated as needed by the JPEG library).
	 */
	jpeg_decompress_struct	 cinfo;

	/* We set up the normal JPEG error routines, then override error_exit.
	 */
	jpeg_error_mgr	 jerr;

	cinfo.err = jpeg_std_error(&jerr);
	cinfo.err->error_exit = my_error_exit;

	/* Now we can initialize the JPEG decompression object.
	 */
	jpeg_create_decompress(&cinfo);

	/* Specify data source (eg, a file)
	 */
	if (gotBuffer) jpeg_mem_src(&cinfo, buffer, buffer.Size());
	else	       jpeg_stdio_src(&cinfo, stream);

	/* Read file parameters with jpeg_read_header()
	 */
	if (jpeg_read_header(&cinfo, TRUE) != JPEG_HEADER_OK)
	{
		jpeg_destroy_decompress(&cinfo);

		if (!gotBuffer) fclose(stream);

		return bitmap;
	}

	/* We can ignore the return value from jpeg_read_header since
	 *   (a) suspension is not possible with the stdio data source, and
	 *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
	 * See libjpeg.doc for more info.
	 */

	/* Start decompressor
	 */
	jpeg_start_decompress(&cinfo);

	/* We can ignore the return value since suspension is not possible
	 * with the stdio data source.
	 */

	/* We may need to do some setup of our own at this point before reading
	 * the data.  After jpeg_start_decompress() we have the correct scaled
	 * output image dimensions available, as well as the output colormap
	 * if we asked for color quantization.
	 * In this example, we need to make an output work buffer of the right size.
	 */

	/* JSAMPLEs per row in output buffer
	 */
	int		 row_stride = cinfo.output_width * cinfo.output_components;

	/* Make a one-row-high sample array that will go away when done with image
	 */
	JSAMPARRAY	 buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);

	bitmap.CreateBitmap(Size(cinfo.output_width, cinfo.output_height));

	/* Here we use the library's state variable cinfo.output_scanline as the
	 * loop counter, so that we don't have to keep track ourselves.
	 */
	while (cinfo.output_scanline < cinfo.output_height)
	{
		/* jpeg_read_scanlines expects an array of pointers to scanlines.
		 * Here the array is only one element long, but you could ask for
		 * more than one scanline at a time if that's more convenient.
		 */
		jpeg_read_scanlines(&cinfo, buffer, 1);

		/* TODO: The copying step needs lots of optimization
		 */
		for (Int x = 0; x < (signed) cinfo.output_width; x++)
		{
			bitmap.SetPixel(Point(x, cinfo.output_scanline - 1), Color(buffer[0][3 * x], buffer[0][3 * x + 1], buffer[0][3 * x + 2], Color::RGB));
		}
	}

	/* We can ignore the return value since suspension is not possible
	 * with the stdio data source.
	 */
	jpeg_finish_decompress(&cinfo);

	/* This is an important step since it will release a good deal of memory.
	 */
	jpeg_destroy_decompress(&cinfo);

	/* After finish_decompress, we can close the input file.
	 * Here we postpone it until after no more JPEG errors are possible,
	 * so as to simplify the setjmp error logic above.  (Actually, I don't
	 * think that jpeg_destroy can do an error exit, but why assume anything...)
	 */
	if (!gotBuffer) fclose(stream);

	/* At this point you may want to check to see whether any corrupt-data
	 * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
	 */

	/* And we're done!
	 */
	return bitmap;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x368, %rsp            # imm = 0x368
movq %rdi, %r14
leaq 0x40(%rdi), %rbx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x56740
movb 0x39(%r14), %al
cmpb $0x1, %al
jne 0x62203
movq 0x28(%r14), %rcx
movq (%rcx), %rcx
cmpb $-0x1, (%rcx)
jne 0x6243d
cmpb $-0x28, 0x1(%rcx)
je 0x62249
jmp 0x6243d
leaq 0x8(%r14), %rdx
leaq 0x30(%rsp), %r15
movq %r15, %rdi
movl $0x3, %esi
movl $0x2, %ecx
callq 0x58730
movq %r15, %rdi
movl $0x2, %esi
callq 0x55d40
movq %rax, %r15
leaq 0x30(%rsp), %rdi
callq 0x555b0
cmpq $0xffd8, %r15           # imm = 0xFFD8
jne 0x6243d
movb 0x39(%r14), %al
testb $0x1, %al
je 0x62252
xorl %r15d, %r15d
jmp 0x6227d
leaq 0x8(%r14), %rdi
leaq 0xb0079(%rip), %rsi     # 0x1122d6
callq 0x57940
leaq 0x910f4(%rip), %rsi     # 0xf335d
movq %rax, %rdi
callq 0x58e70
movq %rax, %r15
testq %rax, %rax
je 0x6243d
leaq 0x2c0(%rsp), %rdi
callq 0x55a70
leaq 0x30(%rsp), %rdi
movq %rax, (%rdi)
leaq -0xdc(%rip), %rcx       # 0x621bd
movq %rcx, (%rax)
movl $0x290, %edx            # imm = 0x290
movl $0x50, %esi
callq 0x569c0
cmpb $0x1, 0x39(%r14)
jne 0x622c0
movq 0x28(%r14), %rax
testq %rax, %rax
je 0x622cf
movq (%rax), %rsi
jmp 0x622d1
leaq 0x30(%rsp), %rdi
movq %r15, %rsi
callq 0x572c0
jmp 0x622df
xorl %esi, %esi
movslq 0x30(%r14), %rdx
leaq 0x30(%rsp), %rdi
callq 0x575a0
leaq 0x30(%rsp), %rdi
movl $0x1, %esi
callq 0x55390
cmpl $0x1, %eax
jne 0x62424
movq %r15, 0x10(%rsp)
movq %r14, 0x18(%rsp)
leaq 0x30(%rsp), %r15
movq %r15, %rdi
callq 0x565b0
movl 0x94(%r15), %edx
imull 0x88(%r15), %edx
movq 0x8(%r15), %rax
movq %r15, %rdi
movl $0x1, %esi
movl $0x1, %ecx
callq *0x10(%rax)
movq %rax, %r12
movq 0x88(%r15), %rax
leaq 0x20(%rsp), %rsi
movq %rax, (%rsi)
movq %rbx, %rdi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x57c20
movl 0xa8(%r15), %eax
cmpl 0x8c(%r15), %eax
jae 0x623fd
leaq 0x8(%rsp), %rbp
leaq 0x20(%rsp), %r15
leaq 0x30(%rsp), %rdi
movq %r12, %rsi
movl $0x1, %edx
callq 0x57da0
cmpl $0x0, 0xb8(%rsp)
jle 0x623e9
movl $0x2, %r13d
xorl %r14d, %r14d
movl 0xd8(%rsp), %eax
decl %eax
movl %r14d, 0x8(%rsp)
movl %eax, 0xc(%rsp)
movq (%r12), %rax
movzwl -0x2(%rax,%r13), %ecx
movzbl (%rax,%r13), %eax
shll $0x10, %eax
orq %rcx, %rax
movq %rax, 0x28(%rsp)
movl $0x0, 0x20(%rsp)
movq %rbx, %rdi
movq %rbp, %rsi
movq %r15, %rdx
callq 0x56080
incq %r14
movslq 0xb8(%rsp), %rax
addq $0x3, %r13
cmpq %rax, %r14
jl 0x62393
movl 0xd8(%rsp), %eax
cmpl 0xbc(%rsp), %eax
jb 0x6236e
leaq 0x30(%rsp), %r15
movq %r15, %rdi
callq 0x57dc0
movq %r15, %rdi
callq 0x554d0
movq 0x18(%rsp), %rax
cmpb $0x0, 0x39(%rax)
movq 0x10(%rsp), %r15
je 0x62435
jmp 0x6243d
leaq 0x30(%rsp), %rdi
callq 0x554d0
cmpb $0x0, 0x39(%r14)
jne 0x6243d
movq %r15, %rdi
callq 0x564b0
movq %rbx, %rax
addq $0x368, %rsp            # imm = 0x368
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x555b0
movq %rbx, %rdi
callq 0x57090
nop