// File: /workspace/github_c_makefile_star2_O0/jsummers[P]deark/modules/cfb.c
// Function: do_extract_stream_to_file_thumbsdb
static void do_extract_stream_to_file_thumbsdb(deark *c, lctx *d, struct dir_entry_info *dei,
	de_finfo *fi, de_ucstring *tmpfn, dbuf *firstpart)
{
	i64 hdrsize;
	i64 catalog_idx;
	dbuf *outf = NULL;
	i64 ver;
	i64 reported_size;
	i64 startpos;
	i64 final_streamsize;
	int is_msrgba = 0;
	struct fmtutil_fmtid_ctx *idctx = NULL;

	if(dei->is_thumbsdb_catalog) {
		// We've already read the catalog.
		goto done;
	}

	de_dbg(c, "reading Thumbs.db stream");
	de_dbg_indent(c, 1);

	startpos = 0;
	final_streamsize = dei->stream_size;

	// A Thumbs.db stream typically has a header, followed by an embedded JPEG
	// (or something) file.

	catalog_idx = lookup_thumbsdb_catalog_entry(c, d, dei);

	if(catalog_idx>=0) {
		if(d->thumbsdb_catalog[catalog_idx].mod_time.is_valid) {
			fi->timestamp[DE_TIMESTAMPIDX_MODIFY] = d->thumbsdb_catalog[catalog_idx].mod_time; // struct copy
		}
	}

	hdrsize = dbuf_getu32le(firstpart, 0);
	de_dbg(c, "header size: %d", (int)hdrsize);

	ver = dbuf_getu32le(firstpart, 4);
	de_dbg(c, "version: %d", (int)ver);

	// 0x0c = "Original format" Thumbs.db
	// 0x18 = "Windows 7 format"

	if((hdrsize==0x0c || hdrsize==0x18) && dei->stream_size>hdrsize) {
		const char *ext;

		reported_size = dbuf_getu32le(firstpart, 8);
		de_dbg(c, "reported size: %d", (int)reported_size);

		startpos = hdrsize;
		final_streamsize -= hdrsize;
		de_dbg(c, "calculated size: %d", (int)final_streamsize);

		if(catalog_idx>=0 && c->filenames_from_file) {
			de_dbg(c, "name from catalog: \"%s\"",
				ucstring_getpsz(d->thumbsdb_catalog[catalog_idx].fname_srd->str));

			// Replace the default name with the name from the catalog.
			ucstring_empty(tmpfn);

			if(!de_strcasecmp(d->thumbsdb_catalog[catalog_idx].fname_srd->sz_utf8,
				"{A42CD7B6-E9B9-4D02-B7A6-288B71AD28BA}"))
			{
				ucstring_append_sz(tmpfn, "_folder", DE_ENCODING_LATIN1);
			}
			else {
				ucstring_append_ucstring(tmpfn, d->thumbsdb_catalog[catalog_idx].fname_srd->str);
			}
		}

		idctx = de_malloc(c, sizeof(struct fmtutil_fmtid_ctx));
		dbuf_read(firstpart, idctx->bof64bytes, hdrsize, sizeof(idctx->bof64bytes));
		idctx->have_bof64bytes = 1;
		// Expecting JPEG, PNG, or special MS-JPEG.
		idctx->mode = FMTUTIL_FMTIDMODE_ALL_IMG;
		fmtutil_fmtid(c, idctx);
		ext = idctx->ext_sz;

		if(idctx->fmtid==0 &&
			idctx->bof64bytes[0]==0x01 && idctx->bof64bytes[1]==0x00 &&
			idctx->bof64bytes[16]==0xff && idctx->bof64bytes[17]==0xd8)
		{
			// Looks like a nonstandard Microsoft RGBA JPEG.
			ext = "msrgbajpg";
			is_msrgba = 1;
		}

		ucstring_printf(tmpfn, DE_ENCODING_LATIN1, ".thumb.%s", ext);
	}
	else {
		de_warn(c, "Unidentified Thumbs.db stream \"%s\"",
			ucstring_getpsz(dei->fname_srd->str));
	}

	de_dbg_indent(c, -1);

	de_finfo_set_name_from_ucstring(c, fi, tmpfn, 0);
	fi->original_filename_flag = 1;

	outf = dbuf_create_output_file(c, NULL, fi, 0);

	if(is_msrgba) {
		if(d->thumbsdb_msrgba_mode) {
			int ok = 0;
			ok = thumbsdb_msrgba_special_extract(c, d, dei, hdrsize, outf);
			if(ok) goto done;
		}

		// "MSRGBA" thumbnails seem to have an additional 16-byte header,
		// before the JPEG data starts. In this mode, we just ignore it.
		startpos += 16;
		final_streamsize -= 16;
	}

	copy_any_stream_to_dbuf(c, d, dei, startpos, final_streamsize, outf);

done:
	dbuf_close(outf);
	de_free(c, idctx);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq %r9, -0x30(%rbp)
movq $0x0, -0x48(%rbp)
movl $0x0, -0x6c(%rbp)
movq $0x0, -0x78(%rbp)
movq -0x18(%rbp), %rax
cmpb $0x0, 0x80(%rax)
je 0x5477c
jmp 0x54b75
movq -0x8(%rbp), %rdi
leaq 0x151449(%rip), %rsi    # 0x1a5bd0
movb $0x0, %al
callq 0x15b0d0
movq -0x8(%rbp), %rdi
movl $0x1, %esi
callq 0x15b560
movq $0x0, -0x60(%rbp)
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x68(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
callq 0x54ea0
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
jl 0x54814
movq -0x10(%rbp), %rax
movq 0xb0(%rax), %rax
movq -0x40(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
cmpb $0x0, 0x10(%rax)
je 0x54812
movq -0x20(%rbp), %rax
movq -0x10(%rbp), %rcx
movq 0xb0(%rcx), %rcx
movq -0x40(%rbp), %rdx
shlq $0x5, %rdx
addq %rdx, %rcx
movq 0x10(%rcx), %rdx
movq %rdx, 0x18(%rax)
movq 0x18(%rcx), %rcx
movq %rcx, 0x20(%rax)
jmp 0x54814
movq -0x30(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x165540
movq %rax, -0x38(%rbp)
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rax
movl %eax, %edx
leaq 0x15e8d8(%rip), %rsi    # 0x1b310e
movb $0x0, %al
callq 0x15b0d0
movq -0x30(%rbp), %rdi
movl $0x4, %esi
callq 0x165540
movq %rax, -0x50(%rbp)
movq -0x8(%rbp), %rdi
movq -0x50(%rbp), %rax
movl %eax, %edx
leaq 0x16b9b0(%rip), %rsi    # 0x1c0210
movb $0x0, %al
callq 0x15b0d0
cmpq $0xc, -0x38(%rbp)
je 0x54879
cmpq $0x18, -0x38(%rbp)
jne 0x54a86
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rax
cmpq -0x38(%rbp), %rax
jle 0x54a86
movq -0x30(%rbp), %rdi
movl $0x8, %esi
callq 0x165540
movq %rax, -0x58(%rbp)
movq -0x8(%rbp), %rdi
movq -0x58(%rbp), %rax
movl %eax, %edx
leaq 0x15133b(%rip), %rsi    # 0x1a5be9
movb $0x0, %al
callq 0x15b0d0
movq -0x38(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x38(%rbp), %rcx
movq -0x68(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x68(%rbp)
movq -0x8(%rbp), %rdi
movq -0x68(%rbp), %rax
movl %eax, %edx
leaq 0x15131e(%rip), %rsi    # 0x1a5bfb
movb $0x0, %al
callq 0x15b0d0
cmpq $0x0, -0x40(%rbp)
jl 0x549c1
movq -0x8(%rbp), %rax
movzbl 0xd0(%rax), %eax
cmpl $0x0, %eax
je 0x549c1
movq -0x8(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x10(%rbp), %rax
movq 0xb0(%rax), %rax
movq -0x40(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rax
movq 0x18(%rax), %rdi
callq 0x172500
movq -0x90(%rbp), %rdi
movq %rax, %rdx
leaq 0x1512cd(%rip), %rsi    # 0x1a5c0f
movb $0x0, %al
callq 0x15b0d0
movq -0x28(%rbp), %rdi
callq 0x171210
movq -0x10(%rbp), %rax
movq 0xb0(%rax), %rax
movq -0x40(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rax
movq 0x20(%rax), %rdi
leaq 0x1512b0(%rip), %rsi    # 0x1a5c27
callq 0x15aaa0
cmpl $0x0, %eax
jne 0x54998
movq -0x28(%rbp), %rdi
leaq 0x1512c2(%rip), %rsi    # 0x1a5c4e
movl $0x5, %edx
callq 0x1715e0
jmp 0x549bf
movq -0x28(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0xb0(%rax), %rax
movq -0x40(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rax
movq 0x18(%rax), %rsi
callq 0x171460
jmp 0x549c1
movq -0x8(%rbp), %rdi
movl $0x78, %esi
callq 0x15b780
movq %rax, -0x78(%rbp)
movq -0x30(%rbp), %rdi
movq -0x78(%rbp), %rsi
addq $0x28, %rsi
movq -0x38(%rbp), %rdx
movl $0x40, %ecx
callq 0x164d10
movq -0x78(%rbp), %rax
movb $0x1, 0x1(%rax)
movq -0x78(%rbp), %rax
movb $0x1, (%rax)
movq -0x8(%rbp), %rdi
movq -0x78(%rbp), %rsi
callq 0x176960
movq -0x78(%rbp), %rax
addq $0x6c, %rax
movq %rax, -0x80(%rbp)
movq -0x78(%rbp), %rax
cmpl $0x0, 0x68(%rax)
jne 0x54a69
movq -0x78(%rbp), %rax
movzbl 0x28(%rax), %eax
cmpl $0x1, %eax
jne 0x54a69
movq -0x78(%rbp), %rax
movzbl 0x29(%rax), %eax
cmpl $0x0, %eax
jne 0x54a69
movq -0x78(%rbp), %rax
movzbl 0x38(%rax), %eax
cmpl $0xff, %eax
jne 0x54a69
movq -0x78(%rbp), %rax
movzbl 0x39(%rax), %eax
cmpl $0xd8, %eax
jne 0x54a69
leaq 0x1511f8(%rip), %rax    # 0x1a5c56
movq %rax, -0x80(%rbp)
movl $0x1, -0x6c(%rbp)
movq -0x28(%rbp), %rdi
movq -0x80(%rbp), %rcx
movl $0x5, %esi
leaq 0x1511e3(%rip), %rdx    # 0x1a5c60
movb $0x0, %al
callq 0x171660
jmp 0x54aba
movq -0x8(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x18(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x18(%rax), %rdi
callq 0x172500
movq -0x98(%rbp), %rdi
movq %rax, %rdx
leaq 0x1511b7(%rip), %rsi    # 0x1a5c6a
movb $0x0, %al
callq 0x15bc10
movq -0x8(%rbp), %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x15b560
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
xorl %ecx, %ecx
callq 0x15d2c0
movq -0x20(%rbp), %rax
movb $0x1, 0x8(%rax)
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rdx
xorl %eax, %eax
movl %eax, %esi
xorl %ecx, %ecx
callq 0x166c60
movq %rax, -0x48(%rbp)
cmpl $0x0, -0x6c(%rbp)
je 0x54b58
movq -0x10(%rbp), %rax
cmpl $0x0, 0x8(%rax)
je 0x54b40
movl $0x0, -0x84(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x38(%rbp), %rcx
movq -0x48(%rbp), %r8
callq 0x54f90
movl %eax, -0x84(%rbp)
cmpl $0x0, -0x84(%rbp)
je 0x54b3e
jmp 0x54b75
jmp 0x54b40
movq -0x60(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x60(%rbp)
movq -0x68(%rbp), %rax
subq $0x10, %rax
movq %rax, -0x68(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x60(%rbp), %rcx
movq -0x68(%rbp), %r8
movq -0x48(%rbp), %r9
callq 0x543d0
movq -0x48(%rbp), %rdi
callq 0x1676a0
movq -0x8(%rbp), %rdi
movq -0x78(%rbp), %rsi
callq 0x15b820
addq $0xa0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)