// File: /workspace/github_c_makefile_star2_O0/jsummers[P]deark/modules/bmp.c
// Function: de_run_picjpeg
static void de_run_picjpeg(deark *c, de_module_params *mparams)
{
	i64 bits_offset;
	i64 jpeg_data_len;
	UI lum_setting;
	UI chr_setting;
	int need_errmsg = 0;
	i64 srcpos;
	dbuf *outf = NULL;
	i64 i;
	u32 hdr[7];
	struct de_bmpinfo bi;
	struct de_scan_jpeg_data_ctx sd;

	de_declare_fmt(c, "Pegasus JPEG or KQP");

	(void)fmtutil_get_bmpinfo(c, c->infile, &bi, 0, c->infile->len,
		DE_BMPINFO_HAS_FILEHEADER|DE_BMPINFO_CMPR_IS_4CC|DE_BMPINFO_NOERR);
	// TODO?: Read the palette (for dbg info)

	bits_offset = de_getu32le(10);
	jpeg_data_len = c->infile->len - bits_offset;
	if(jpeg_data_len<2) {
		need_errmsg = 1;
		goto done;
	}

	// Extended BMP header fields
	for(i=0; i<7; i++) {
		hdr[i] = (u32)de_getu32le(54+4*i);
		de_dbg(c, "bmp ext hdr[%u]: %u", (UI)i, (UI)hdr[i]);
	}

	// Validate the extra BMP fields.
	// Not sure what all these are.
	// [5] & [6] are related to sampling factors.
	if(hdr[0]!=44 || hdr[1]!=24 || hdr[2]!=0 || hdr[3]!=2 ||
		hdr[4]!=8)
	{
		need_errmsg = 1;
		goto done;
	}

	de_zeromem(&sd, sizeof(struct de_scan_jpeg_data_ctx));
	de_scan_jpeg_data(c, c->infile, bits_offset, c->infile->len-bits_offset, &sd);
	if(sd.error_flag) {
		need_errmsg = 1;
		goto done;
	}
	if(!sd.found_pic || !sd.found_sof || !sd.found_sos) {
		need_errmsg = 1;
		goto done;
	}
	if(sd.pic_pos >= sd.sof_pos) {
		need_errmsg = 1;
		goto done;
	}

	// Read from "PIC" segment.
	lum_setting = (UI)de_getbyte(sd.pic_pos+9);
	chr_setting = (UI)de_getbyte(sd.pic_pos+10);
	de_dbg(c, "luminance: %u", lum_setting);
	de_dbg(c, "chrominance: %u", chr_setting);

	de_dbg(c, "has DHT: %u", (UI)sd.found_dht);

	outf = dbuf_create_output_file(c, "jpg", NULL, 0);

	srcpos = sd.soi_pos;
	dbuf_copy(c->infile, srcpos, 2, outf);
	srcpos += 2;

	if(sd.found_jfif && sd.jfif_pos==srcpos) {
		// Copy everything before the JFIF version number
		dbuf_copy(c->infile, srcpos, 9, outf);
		// Sometimes the JFIF version number is wrong, so we correct it.
		dbuf_writebyte(outf, 1);
		dbuf_writebyte(outf, 2);
		srcpos += 11;
	}

	// Copy everything up to the PIC segment
	dbuf_copy(c->infile, srcpos, sd.pic_pos-srcpos, outf);

	srcpos = sd.pic_pos + sd.pic_len; // Skip the PIC segment

	// Convert the Photoshop Resources segment to a more standard format
	if(sd.found_8bim && sd._8bim_pos>=srcpos && sd._8bim_pos<sd.sof_pos) {
		// Copy everything up to 8BIM
		dbuf_copy(c->infile, srcpos, sd._8bim_pos-srcpos, outf);

		dbuf_writeu16be(outf, 0xffed);
		dbuf_writeu16be(outf, 2 + 14 + (sd._8bim_len-4));
		dbuf_write(outf, (const u8*)"Photoshop 3.0\0", 14);
		dbuf_copy(c->infile, sd._8bim_pos+4, sd._8bim_len-4, outf);
		srcpos = sd._8bim_pos + sd._8bim_len;
	}

	// Copy everything up to SOF
	dbuf_copy(c->infile, srcpos, sd.sof_pos-srcpos, outf);
	srcpos = sd.sof_pos;

	// Insert DQT segments
	if(!sd.found_dqt) {
		u8 tmptbl[64];

		dbuf_write(outf, (const u8*)"\xff\xdb\x00\x43\x00", 5);
		fmtutil_get_std_jpeg_qtable(0, tmptbl);
		picjpeg_scale_qtable(tmptbl, lum_setting);
		dbuf_write(outf, tmptbl, 64);

		dbuf_write(outf, (const u8*)"\xff\xdb\x00\x43\x01", 5);
		fmtutil_get_std_jpeg_qtable(1, tmptbl);
		picjpeg_scale_qtable(tmptbl, chr_setting);
		dbuf_write(outf, tmptbl, 64);
	}

	// Copy everything up to SOS
	dbuf_copy(c->infile, srcpos, sd.sos_pos-srcpos, outf);
	srcpos = sd.sos_pos;

	// Insert DHT segment
	if(!sd.found_dht) {
		dbuf_write(outf, (const u8*)"\xff\xc4\x01\xa2\x00", 5);
		fmtutil_write_std_jpeg_dht(outf, 0);
		dbuf_writebyte(outf, 0x10);
		fmtutil_write_std_jpeg_dht(outf, 1);
		dbuf_writebyte(outf, 0x01);
		fmtutil_write_std_jpeg_dht(outf, 2);
		dbuf_writebyte(outf, 0x11);
		fmtutil_write_std_jpeg_dht(outf, 3);
	}

	// Copy the rest of the file
	dbuf_copy(c->infile, srcpos, c->infile->len-srcpos, outf);

done:
	if(need_errmsg) {
		de_err(c, "Can't convert this Pegasus JPEG file");
	}
	dbuf_close(outf);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1a0, %rsp            # imm = 0x1A0
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0x0, -0x2c(%rbp)
movq $0x0, -0x40(%rbp)
movq -0x8(%rbp), %rdi
leaq 0x160a7f(%rip), %rsi    # 0x1a3acc
callq 0x15e380
movq -0x8(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rsi
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x18(%rax), %r8
leaq -0x110(%rbp), %rdx
xorl %eax, %eax
movl %eax, %ecx
movl $0x19, %r9d
callq 0x172d70
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
movl $0xa, %esi
callq 0x165540
movq %rax, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x18(%rax), %rax
subq -0x18(%rbp), %rax
movq %rax, -0x20(%rbp)
cmpq $0x2, -0x20(%rbp)
jge 0x430bd
movl $0x1, -0x2c(%rbp)
jmp 0x43594
movq $0x0, -0x48(%rbp)
cmpq $0x7, -0x48(%rbp)
jge 0x4311d
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x48(%rbp), %rsi
shlq $0x2, %rsi
addq $0x36, %rsi
callq 0x165540
movl %eax, %ecx
movq -0x48(%rbp), %rax
movl %ecx, -0x70(%rbp,%rax,4)
movq -0x8(%rbp), %rdi
movq -0x48(%rbp), %rax
movl %eax, %edx
movq -0x48(%rbp), %rax
movl -0x70(%rbp,%rax,4), %ecx
leaq 0x1609d8(%rip), %rsi    # 0x1a3ae0
movb $0x0, %al
callq 0x15b0d0
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
jmp 0x430c5
cmpl $0x2c, -0x70(%rbp)
jne 0x4313b
cmpl $0x18, -0x6c(%rbp)
jne 0x4313b
cmpl $0x0, -0x68(%rbp)
jne 0x4313b
cmpl $0x2, -0x64(%rbp)
jne 0x4313b
cmpl $0x8, -0x60(%rbp)
je 0x43147
movl $0x1, -0x2c(%rbp)
jmp 0x43594
leaq -0x158(%rbp), %rdi
xorl %esi, %esi
movl $0x48, %edx
callq 0x19140
movq -0x8(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rsi
movq -0x18(%rbp), %rdx
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x18(%rax), %rcx
subq -0x18(%rbp), %rcx
leaq -0x158(%rbp), %r8
callq 0x46a30
cmpb $0x0, -0x158(%rbp)
je 0x4319b
movl $0x1, -0x2c(%rbp)
jmp 0x43594
cmpb $0x0, -0x152(%rbp)
je 0x431b6
cmpb $0x0, -0x154(%rbp)
je 0x431b6
cmpb $0x0, -0x157(%rbp)
jne 0x431c2
movl $0x1, -0x2c(%rbp)
jmp 0x43594
movq -0x130(%rbp), %rax
cmpq -0x140(%rbp), %rax
jl 0x431de
movl $0x1, -0x2c(%rbp)
jmp 0x43594
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x130(%rbp), %rsi
addq $0x9, %rsi
callq 0x165060
movzbl %al, %eax
movl %eax, -0x24(%rbp)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x130(%rbp), %rsi
addq $0xa, %rsi
callq 0x165060
movzbl %al, %eax
movl %eax, -0x28(%rbp)
movq -0x8(%rbp), %rdi
movl -0x24(%rbp), %edx
leaq 0x1608cc(%rip), %rsi    # 0x1a3af4
movb $0x0, %al
callq 0x15b0d0
movq -0x8(%rbp), %rdi
movl -0x28(%rbp), %edx
leaq 0x1608c5(%rip), %rsi    # 0x1a3b02
movb $0x0, %al
callq 0x15b0d0
movq -0x8(%rbp), %rdi
movzbl -0x156(%rbp), %edx
leaq 0x1608bc(%rip), %rsi    # 0x1a3b12
movb $0x0, %al
callq 0x15b0d0
movq -0x8(%rbp), %rdi
leaq 0x17c091(%rip), %rsi    # 0x1bf2f9
xorl %eax, %eax
movl %eax, %edx
xorl %ecx, %ecx
callq 0x166c60
movq %rax, -0x40(%rbp)
movq -0x150(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x38(%rbp), %rsi
movq -0x40(%rbp), %rcx
movl $0x2, %edx
callq 0x166070
movq -0x38(%rbp), %rax
addq $0x2, %rax
movq %rax, -0x38(%rbp)
movzbl -0x153(%rbp), %eax
cmpl $0x0, %eax
je 0x43303
movq -0x138(%rbp), %rax
cmpq -0x38(%rbp), %rax
jne 0x43303
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x38(%rbp), %rsi
movq -0x40(%rbp), %rcx
movl $0x9, %edx
callq 0x166070
movq -0x40(%rbp), %rdi
movl $0x1, %esi
callq 0x168380
movq -0x40(%rbp), %rdi
movl $0x2, %esi
callq 0x168380
movq -0x38(%rbp), %rax
addq $0xb, %rax
movq %rax, -0x38(%rbp)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x38(%rbp), %rsi
movq -0x130(%rbp), %rdx
subq -0x38(%rbp), %rdx
movq -0x40(%rbp), %rcx
callq 0x166070
movq -0x130(%rbp), %rax
addq -0x128(%rbp), %rax
movq %rax, -0x38(%rbp)
movzbl -0x151(%rbp), %eax
cmpl $0x0, %eax
je 0x433fe
movq -0x120(%rbp), %rax
cmpq -0x38(%rbp), %rax
jl 0x433fe
movq -0x120(%rbp), %rax
cmpq -0x140(%rbp), %rax
jge 0x433fe
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x38(%rbp), %rsi
movq -0x120(%rbp), %rdx
subq -0x38(%rbp), %rdx
movq -0x40(%rbp), %rcx
callq 0x166070
movq -0x40(%rbp), %rdi
movl $0xffed, %esi           # imm = 0xFFED
callq 0x168a50
movq -0x40(%rbp), %rdi
movq -0x118(%rbp), %rsi
subq $0x4, %rsi
addq $0x10, %rsi
callq 0x168a50
movq -0x40(%rbp), %rdi
leaq 0x160225(%rip), %rsi    # 0x1a35e0
movl $0xe, %edx
callq 0x166170
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x120(%rbp), %rsi
addq $0x4, %rsi
movq -0x118(%rbp), %rdx
subq $0x4, %rdx
movq -0x40(%rbp), %rcx
callq 0x166070
movq -0x120(%rbp), %rax
addq -0x118(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x38(%rbp), %rsi
movq -0x140(%rbp), %rdx
subq -0x38(%rbp), %rdx
movq -0x40(%rbp), %rcx
callq 0x166070
movq -0x140(%rbp), %rax
movq %rax, -0x38(%rbp)
cmpb $0x0, -0x155(%rbp)
jne 0x434c7
movq -0x40(%rbp), %rdi
leaq 0x1601ae(%rip), %rsi    # 0x1a35ef
movl $0x5, %edx
callq 0x166170
leaq -0x1a0(%rbp), %rsi
xorl %edi, %edi
callq 0x176500
leaq -0x1a0(%rbp), %rdi
movl -0x24(%rbp), %esi
callq 0x46cb0
movq -0x40(%rbp), %rdi
leaq -0x1a0(%rbp), %rsi
movl $0x40, %edx
callq 0x166170
movq -0x40(%rbp), %rdi
leaq 0x16016d(%rip), %rsi    # 0x1a35f5
movl $0x5, %edx
callq 0x166170
leaq -0x1a0(%rbp), %rsi
movl $0x1, %edi
callq 0x176500
leaq -0x1a0(%rbp), %rdi
movl -0x28(%rbp), %esi
callq 0x46cb0
movq -0x40(%rbp), %rdi
leaq -0x1a0(%rbp), %rsi
movl $0x40, %edx
callq 0x166170
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x38(%rbp), %rsi
movq -0x148(%rbp), %rdx
subq -0x38(%rbp), %rdx
movq -0x40(%rbp), %rcx
callq 0x166070
movq -0x148(%rbp), %rax
movq %rax, -0x38(%rbp)
cmpb $0x0, -0x156(%rbp)
jne 0x4356f
movq -0x40(%rbp), %rdi
leaq 0x1600f5(%rip), %rsi    # 0x1a35fb
movl $0x5, %edx
callq 0x166170
movq -0x40(%rbp), %rdi
xorl %esi, %esi
callq 0x176570
movq -0x40(%rbp), %rdi
movl $0x10, %esi
callq 0x168380
movq -0x40(%rbp), %rdi
movl $0x1, %esi
callq 0x176570
movq -0x40(%rbp), %rdi
movl $0x1, %esi
callq 0x168380
movq -0x40(%rbp), %rdi
movl $0x2, %esi
callq 0x176570
movq -0x40(%rbp), %rdi
movl $0x11, %esi
callq 0x168380
movq -0x40(%rbp), %rdi
movl $0x3, %esi
callq 0x176570
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x38(%rbp), %rsi
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x18(%rax), %rdx
subq -0x38(%rbp), %rdx
movq -0x40(%rbp), %rcx
callq 0x166070
cmpl $0x0, -0x2c(%rbp)
je 0x435ac
movq -0x8(%rbp), %rdi
leaq 0x160579(%rip), %rsi    # 0x1a3b1e
movb $0x0, %al
callq 0x15bfb0
movq -0x40(%rbp), %rdi
callq 0x1676a0
addq $0x1a0, %rsp            # imm = 0x1A0
popq %rbp
retq
nop