// File: /workspace/github_c_makefile_star2_O1/zhiyb[P]png2tlg/png2tlg.cpp
// Function: SaveTLG6(std::ostream*, tTVPBaseBitmap const*, bool)
void SaveTLG6( std::ostream* stream, const tTVPBaseBitmap* bmp, bool is24 )
{
	std::ostream *out = stream;

	// DWORD medstart, medend;
#ifdef WRITE_ENTROPY_VALUES
	FILE *vs = fopen("vs.bin", "wb");
#endif

	int colors;

	TVPTLG6InitGolombTable();

	// check pixel format
	if( bmp->Is32BPP() ) {
		if( is24 ) colors = 3;
		else colors = 4;
	} else {
		colors = 1;
	}
	int stride = colors;
	if( stride == 3 ) stride = 4;

	// output stream header
	{
		out->write("TLG6.0\x00raw\x1a\x00", 11);
		out->write((const char *)&colors, 1);
		int n = 0;
		out->write((const char *)&n, 1); // data flag (0)
		out->write((const char *)&n, 1); // color type (0)
		out->write((const char *)&n, 1); // external golomb table (0)
		int width = bmp->GetWidth();
		int height = bmp->GetHeight();
		WriteInt32(width, out);
		WriteInt32(height, out);
	}

	// compress
	long max_bit_length = 0;

	unsigned char *buf[MAX_COLOR_COMPONENTS];
	for(int i = 0; i < MAX_COLOR_COMPONENTS; i++) buf[i] = NULL;
	char *block_buf[MAX_COLOR_COMPONENTS];
	for(int i = 0; i < MAX_COLOR_COMPONENTS; i++) block_buf[i] = NULL;
	unsigned char *filtertypes = NULL;
	std::stringstream *memstream = NULL;

	try
	{
		memstream = new std::stringstream();

		TLG6BitStream bs(memstream);

//		int buf_size = bmp->Width * bmp->Height;

		// allocate buffer
		for(int c = 0; c < colors; c++)
		{
			buf[c] = new unsigned char [W_BLOCK_SIZE * H_BLOCK_SIZE * 3];
			block_buf[c] = new char [H_BLOCK_SIZE * bmp->GetWidth()];
		}
		int w_block_count = (int)((bmp->GetWidth() - 1) / W_BLOCK_SIZE) + 1;
		int h_block_count = (int)((bmp->GetHeight() - 1) / H_BLOCK_SIZE) + 1;
		filtertypes = new unsigned char [w_block_count * h_block_count];

		int fc = 0;
		for(int y = 0; y < (int)bmp->GetHeight(); y += H_BLOCK_SIZE)
		{
			int ylim = y + H_BLOCK_SIZE;
			if(ylim > (int)bmp->GetHeight()) ylim = bmp->GetHeight();
			int gwp = 0;
			int xp = 0;
			for(int x = 0; x < (int)bmp->GetWidth(); x += W_BLOCK_SIZE, xp++)
			{
				int xlim = x + W_BLOCK_SIZE;
				if(xlim > (int)bmp->GetWidth()) xlim = bmp->GetWidth();
				int bw = xlim - x;

				int p0size; // size of MED method (p=0)
				int minp = 0; // most efficient method (0:MED, 1:AVG)
				int ft; // filter type
				int wp; // write point
				for(int p = 0; p < 2; p++)
				{
					int dbofs = (p+1) * (H_BLOCK_SIZE * W_BLOCK_SIZE);

					// do med(when p=0) or take average of upper and left pixel(p=1)
					for(int c = 0; c < colors; c++)
					{
						int wp = 0;
						for(int yy = y; yy < ylim; yy++)
						{
							const unsigned char * sl = x*stride +
								c + (const unsigned char *)bmp->GetScanLine(yy);
							const unsigned char * usl;
							if(yy >= 1)
								usl = x*stride + c + (const unsigned char *)bmp->GetScanLine(yy-1);
							else
								usl = NULL;
							for(int xx = x; xx < xlim; xx++)
							{
								unsigned char pa = xx > 0 ? sl[-stride] : 0;
								unsigned char pb = usl ? *usl : 0;
								unsigned char px = *sl;

								unsigned char py;

//								py = 0;
								if(p == 0)
								{
									unsigned char pc = (xx > 0 && usl) ? usl[-stride] : 0;
									unsigned char min_a_b = pa>pb?pb:pa;
									unsigned char max_a_b = pa<pb?pb:pa;

									if(pc >= max_a_b)
										py = min_a_b;
									else if(pc < min_a_b)
										py = max_a_b;
									else
										py = pa + pb - pc;
								}
								else
								{
									py = (pa+pb+1)>>1;
								}
								
								// stbi_image format is RGBA, so swap to BGRA
								int wc = c == 0 ? 2 : c == 2 ? 0 : c;
								buf[wc][wp] = (unsigned char)(px - py);

								wp++;
								sl += stride;
								if(usl) usl += stride;
							}
						}
					}

					// reordering
					// Transfer the data into block_buf (block buffer).
					// Even lines are stored forward (left to right),
					// Odd lines are stored backward (right to left).

					wp = 0;
					for(int yy = y; yy < ylim; yy++)
					{
						int ofs;
						if(!(xp&1))
							ofs = (yy - y)*bw;
						else
							ofs = (ylim - yy - 1) * bw;
						bool dir; // false for forward, true for backward
						if(!((ylim-y)&1))
						{
							// vertical line count per block is even
							dir = ((yy&1) ^ (xp&1)) ? true : false;
						}
						else
						{
							// otherwise;
							if(xp & 1)
							{
								dir = (yy&1);
							}
							else
							{
								dir = ((yy&1) ^ (xp&1)) ? true : false;
							}
						}

						if(!dir)
						{
							// forward
							for(int xx = 0; xx < bw; xx++)
							{
								for(int c = 0; c < colors; c++)
									buf[c][wp + dbofs] =
									buf[c][ofs + xx];
								wp++;
							}
						}
						else
						{
							// backward
							for(int xx = bw - 1; xx >= 0; xx--)
							{
								for(int c = 0; c < colors; c++)
									buf[c][wp + dbofs] =
									buf[c][ofs + xx];
								wp++;
							}
						}
					}
				}


				for(int p = 0; p < 2; p++)
				{
					int dbofs = (p+1) * (H_BLOCK_SIZE * W_BLOCK_SIZE);
					// detect color filter
					int size = 0;
					int ft_;
					if(colors >= 3)
						ft_ = DetectColorFilter(
							reinterpret_cast<char*>(buf[0] + dbofs),
							reinterpret_cast<char*>(buf[1] + dbofs),
							reinterpret_cast<char*>(buf[2] + dbofs), wp, size);
					else
						ft_ = 0;

					// select efficient mode of p (MED or average)
					if(p == 0)
					{
						p0size = size;
						ft = ft_;
					}
					else
					{
						if(p0size >= size)
							minp = 1, ft = ft_;
					}
				}

				// Apply most efficient color filter / prediction method
				wp = 0;
				int dbofs = (minp + 1)  * (H_BLOCK_SIZE * W_BLOCK_SIZE);
				for(int yy = y; yy < ylim; yy++)
				{
					for(int xx = 0; xx < bw; xx++)
					{
						for(int c = 0; c < colors; c++)
							block_buf[c][gwp + wp] = buf[c][wp + dbofs];
						wp++;
					}
				}

				ApplyColorFilter(block_buf[0] + gwp,
					block_buf[1] + gwp, block_buf[2] + gwp, wp, ft);

				filtertypes[fc++] = (ft<<1) + minp;
//				ftfreq[ft]++;
				gwp += wp;
			}

			// compress values (entropy coding)
			for(int c = 0; c < colors; c++)
			{
				int method;
				CompressValuesGolomb(bs, block_buf[c], gwp);
				method = 0;
#ifdef WRITE_ENTROPY_VALUES
				fwrite(block_buf[c], 1, gwp, vs);
#endif
				long bitlength = bs.GetBitLength();
				if(bitlength & 0xc0000000)
					throw std::runtime_error("TVPTlgTooLargeBitLength");
				// two most significant bits of bitlength are
				// entropy coding method;
				// 00 means Golomb method,
				// 01 means Gamma method (implemented but not used),
				// 10 means modified LZSS method (not yet implemented),
				// 11 means raw (uncompressed) data (not yet implemented).
				if(max_bit_length < bitlength) max_bit_length = bitlength;
				bitlength |= (method << 30);
				WriteInt32(bitlength, memstream);
				bs.Flush();
			}

		}


		// write max bit length
		WriteInt32(max_bit_length, out);

		// output filter types
		{
			SlideCompressor comp;
			TLG6InitializeColorFilterCompressor(comp);
			unsigned char *outbuf = new unsigned char[fc * 2];
			try
			{
				long outlen;
				comp.Encode(filtertypes, fc, outbuf, outlen);
				WriteInt32(outlen, out);
				out->write((const char *)outbuf, outlen);
			}
			catch(...)
			{
				delete [] outbuf;
				throw std::runtime_error("Encoding error");
			}
			delete [] outbuf;

		}

		// copy memory stream to output stream
		std::string str(memstream->str());
		out->write((const char *)str.data(), (tjs_uint)str.size() );
	}
	catch(...)
	{
		for(int i = 0; i < MAX_COLOR_COMPONENTS; i++)
		{
			if(buf[i]) delete [] (buf[i]);
			if(block_buf[i]) delete [] (block_buf[i]);
		}
		if(filtertypes) delete [] filtertypes;
		if(memstream) delete memstream;
		throw;
	}

	for(int i = 0; i < MAX_COLOR_COMPONENTS; i++)
	{
		if(buf[i]) delete [] (buf[i]);
		if(block_buf) delete [] (block_buf[i]);
	}
	if(filtertypes) delete [] filtertypes;
	if(memstream) delete memstream;

#ifdef WRITE_ENTROPY_VALUES
	fclose(vs);
#endif
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x943c8, %rsp          # imm = 0x943C8
movl %edx, %ebx
movq %rsi, %r13
movq %rdi, %r12
callq 0x4ae3
movl $0x4, %eax
subl %ebx, %eax
leaq 0x8(%rsp), %rbx
movl %eax, (%rbx)
leaq 0x11905(%rip), %rsi     # 0x173a8
movl $0xb, %edx
movq %r12, %rdi
callq 0x2200
movl $0x1, %edx
movq %r12, %rdi
movq %rbx, %rsi
callq 0x2200
leaq 0x190(%rsp), %rbx
movl $0x0, (%rbx)
movl $0x1, %edx
movq %r12, %rdi
movq %rbx, %rsi
callq 0x2200
movl $0x1, %edx
movq %r12, %rdi
movq %rbx, %rsi
callq 0x2200
movl $0x1, %edx
movq %r12, %rdi
movq %rbx, %rsi
callq 0x2200
movl (%r13), %eax
movl 0x4(%r13), %ebp
leaq 0x2198(%rsp), %rbx
movl %eax, (%rbx)
movl $0x4, %edx
movq %r12, %rdi
movq %rbx, %rsi
callq 0x2200
movl %ebp, (%rbx)
leaq 0x2198(%rsp), %rsi
movl $0x4, %edx
movq %r12, %rdi
callq 0x2200
xorps %xmm0, %xmm0
movaps %xmm0, 0x90(%rsp)
movaps %xmm0, 0x80(%rsp)
movaps %xmm0, 0xc0(%rsp)
movaps %xmm0, 0xb0(%rsp)
movl $0x188, %edi            # imm = 0x188
callq 0x2190
movq %rax, %r15
movq %rax, %rdi
callq 0x2120
leaq 0x10(%r15), %rax
movl $0x0, 0x160(%rsp)
movq $0x0, 0x168(%rsp)
movq %rax, 0xe8(%rsp)
movq %rax, 0x170(%rsp)
xorps %xmm0, %xmm0
movups %xmm0, 0x178(%rsp)
movslq 0x8(%rsp), %rbx
testq %rbx, %rbx
jle 0x5be0
xorl %r14d, %r14d
movl $0xc0, %edi
callq 0x2040
movq %rax, 0x80(%rsp,%r14,8)
movl (%r13), %edi
shll $0x3, %edi
callq 0x2040
movq %rax, 0xb0(%rsp,%r14,8)
incq %r14
cmpq %r14, %rbx
jne 0x5bb2
movq %r12, 0x40(%rsp)
movl (%r13), %eax
movl 0x4(%r13), %edi
decl %eax
shrl $0x3, %eax
incl %eax
decl %edi
shrl $0x3, %edi
incl %edi
imull %eax, %edi
callq 0x2040
movq %r13, %rcx
movq %rax, %r13
movq %rcx, 0x38(%rsp)
movl 0x4(%rcx), %edi
testl %edi, %edi
movq %r15, 0x28(%rsp)
movq %rax, 0x60(%rsp)
jle 0x62ee
movq 0x80(%rsp), %rax
movq 0x88(%rsp), %rcx
movq 0x90(%rsp), %rdx
movq 0xb0(%rsp), %rsi
movq %rsi, 0xe0(%rsp)
movq 0xb8(%rsp), %rsi
movq %rsi, 0xd8(%rsp)
movq 0xc0(%rsp), %rsi
movq %rsi, 0xd0(%rsp)
addq $0x40, %rdx
movq %rdx, 0x108(%rsp)
addq $0x40, %rcx
movq %rcx, 0x110(%rsp)
addq $0x40, %rax
movq %rax, 0x118(%rsp)
movq $0x0, 0x50(%rsp)
movq $0x0, 0x30(%rsp)
xorl %r14d, %r14d
xorl %ecx, %ecx
movq %rax, 0x48(%rsp)
movq 0x38(%rsp), %rax
movl %ecx, %edx
movq %rdx, 0x18(%rsp)
leal 0x8(%rdx), %ecx
cmpl %edi, %ecx
movl %edi, %r10d
movl %ecx, 0x6c(%rsp)
cmovll %ecx, %r10d
movl (%rax), %eax
testl %eax, %eax
jle 0x6234
movl %edi, 0x24(%rsp)
movslq %r14d, %r14
movl $0x8, %edx
xorl %esi, %esi
xorl %ecx, %ecx
xorl %edi, %edi
xorl %r8d, %r8d
xorl %r12d, %r12d
movl %r10d, 0x10(%rsp)
movq %r14, 0x100(%rsp)
movq %rsi, 0xf8(%rsp)
andl $-0x20, %esi
movq %rsi, 0x120(%rsp)
leaq 0x8(%rcx), %rsi
cmpl %eax, %esi
movslq %eax, %r9
movq %rsi, 0xf0(%rsp)
cmovll %esi, %eax
movl %eax, %esi
subl %ecx, %esi
testb $0x1, %r10b
movl $0x0, %r11d
movl %r8d, 0x14(%rsp)
cmovel %r8d, %r11d
movl %r11d, 0x7c(%rsp)
leal (,%rcx,4), %r8d
andl $-0x20, %r8d
movq %r8, 0x130(%rsp)
cmpl %edx, %r9d
movl %edx, 0x74(%rsp)
movq %r9, 0x158(%rsp)
cmovll %r9d, %edx
movl %esi, 0xc(%rsp)
movslq %esi, %rsi
movq %rsi, 0x138(%rsp)
movl %edi, 0x70(%rsp)
addl %edi, %edx
movslq %edx, %rdx
movq %rdx, 0x128(%rsp)
xorl %edx, %edx
movq %r12, 0xa0(%rsp)
movq %rdx, %r11
cmpl $0x0, 0x8(%rsp)
jle 0x5f65
movq 0x120(%rsp), %rdx
movq %rdx, 0xa8(%rsp)
movq $0x0, 0x58(%rsp)
movq 0x18(%rsp), %rdx
cmpl %edx, 0x24(%rsp)
jle 0x5f42
movq 0x130(%rsp), %rdx
movq 0x58(%rsp), %rsi
addq %rsi, %rdx
movq %rdx, 0x148(%rsp)
xorl %edi, %edi
cmpq $0x2, %rsi
movl %esi, %edx
movl $0x0, %r8d
cmovneq %rdx, %r8
testq %rsi, %rsi
movl $0x2, %edx
cmoveq %rdx, %r8
movq %r8, 0x140(%rsp)
movq 0x50(%rsp), %rdx
movl %edx, %ebx
movq 0x18(%rsp), %r14
cmpq 0x158(%rsp), %rcx
jge 0x5f33
movq 0x38(%rsp), %rsi
movq 0x10(%rsi), %rdx
movl (%rsi), %ebp
leal -0x4(,%r14,4), %r13d
imull %ebp, %r13d
movq 0x148(%rsp), %rsi
addq %rdx, %rsi
addq %rsi, %r13
testl %r14d, %r14d
movl $0x0, %esi
cmoveq %rsi, %r13
movq %rdi, 0x150(%rsp)
movslq %edi, %r9
movq 0x140(%rsp), %rsi
addq 0x80(%rsp,%rsi,8), %r9
addq 0xa8(%rsp), %rdx
imull %ebx, %ebp
addq %rdx, %rbp
xorl %r12d, %r12d
movl %ecx, %r10d
addl %r12d, %r10d
je 0x5e84
movb -0x4(%rbp,%r12,4), %dl
jmp 0x5e86
xorl %edx, %edx
testq %r13, %r13
je 0x5e91
movb (%r13), %sil
jmp 0x5e93
xorl %esi, %esi
movzbl %dl, %edx
movzbl %sil, %esi
testq %r11, %r11
je 0x5ea8
leal (%rdx,%rsi), %edi
incl %edi
shrl %edi
jmp 0x5ef0
testq %r13, %r13
sete %dil
testl %r10d, %r10d
sete %r15b
xorl %r10d, %r10d
orb %dil, %r15b
jne 0x5ec3
movzbl -0x4(%r13), %r10d
cmpb %sil, %dl
movl %esi, %r15d
movl %esi, %edi
cmoval %edx, %edi
cmovbl %edx, %r15d
movzbl %dil, %r8d
cmpl %r8d, %r10d
jae 0x5eed
movzbl %r15b, %r8d
cmpl %r8d, %r10d
jb 0x5ef0
addl %edx, %esi
subl %r10d, %esi
movl %esi, %edi
jmp 0x5ef0
movl %r15d, %edi
movb (%rbp,%r12,4), %dl
subb %dil, %dl
leaq 0x4(%r13), %rsi
testq %r13, %r13
cmovneq %rsi, %r13
movb %dl, (%r9,%r12)
incq %r12
leal (%r12,%rcx), %edx
cmpl %eax, %edx
jl 0x5e75
movq 0x150(%rsp), %rdi
addl %r12d, %edi
movq 0x60(%rsp), %r13
movq 0xa0(%rsp), %r12
movl 0x10(%rsp), %r10d
incl %r14d
addl $0x4, %ebx
cmpl %r10d, %r14d
jl 0x5e0a
movq 0x58(%rsp), %rdi
incq %rdi
movslq 0x8(%rsp), %rdx
incq 0xa8(%rsp)
movq %rdi, 0x58(%rsp)
cmpq %rdx, %rdi
jl 0x5db1
leaq 0x1(%r11), %rdx
xorl %r15d, %r15d
movq 0x18(%rsp), %rsi
cmpl %esi, 0x24(%rsp)
movl 0x14(%rsp), %ebx
movl 0xc(%rsp), %ebp
jle 0x607e
movq %rdx, %rdi
shlq $0x6, %rdi
xorl %r15d, %r15d
movq 0x18(%rsp), %rsi
movl %esi, %r8d
movl %r8d, %r9d
notl %r9d
addl %r10d, %r9d
movl %r8d, %esi
subl 0x18(%rsp), %esi
testb $0x1, %bl
cmovnel %r9d, %esi
imull %ebp, %esi
movl %r8d, %r9d
xorl 0x7c(%rsp), %r9d
testb $0x1, %r9b
je 0x601a
testl %ebp, %ebp
jle 0x6072
movslq %esi, %rsi
movslq %r15d, %r15
movq 0x128(%rsp), %r9
leaq -0x1(%r9), %r10
cmpl $0x0, 0x8(%rsp)
jle 0x6004
xorl %ebx, %ebx
movq 0x80(%rsp,%rbx,8), %r14
leaq (%r14,%r10), %r12
movb (%rsi,%r12), %bpl
addq %r15, %r14
movb %bpl, (%rdi,%r14)
incq %rbx
movslq 0x8(%rsp), %r14
cmpq %r14, %rbx
jl 0x5fe0
incq %r15
cmpq $0x1, %r9
movq %r10, %r9
jg 0x5fd3
movq 0xa0(%rsp), %r12
jmp 0x6065
testl %ebp, %ebp
jle 0x6072
movslq %esi, %rsi
movslq %r15d, %r15
xorl %r9d, %r9d
cmpl $0x0, 0x8(%rsp)
jle 0x6055
xorl %r10d, %r10d
movq 0x80(%rsp,%r10,8), %rbx
leaq (%rbx,%r9), %r14
movb (%rsi,%r14), %bpl
addq %r15, %rbx
movb %bpl, (%rdi,%rbx)
incq %r10
movslq 0x8(%rsp), %rbx
cmpq %rbx, %r10
jl 0x6031
incq %r15
incq %r9
cmpq 0x138(%rsp), %r9
jl 0x6027
movl 0x10(%rsp), %r10d
movl 0x14(%rsp), %ebx
movl 0xc(%rsp), %ebp
incl %r8d
cmpl %r10d, %r8d
jl 0x5f95
testq %r11, %r11
je 0x5d8a
xorl %r14d, %r14d
xorl %ebx, %ebx
movl 0x78(%rsp), %r9d
movl $0x0, 0x2198(%rsp)
cmpl $0x3, 0x8(%rsp)
movl $0x0, %eax
jl 0x60e7
movl %r9d, %ebp
movq 0x118(%rsp), %rax
leaq (%rax,%r14), %rdi
movq 0x110(%rsp), %rax
leaq (%rax,%r14), %rsi
movq 0x108(%rsp), %rax
leaq (%rax,%r14), %rdx
movl %r15d, %ecx
leaq 0x2198(%rsp), %r8
callq 0x5889
movl %ebp, %r9d
movl 0x10(%rsp), %r10d
movl 0x2198(%rsp), %ecx
cmpl %ecx, %r9d
setl %dl
movq 0x48(%rsp), %rsi
cmovgel %eax, %esi
testb $0x1, %dl
movl $0x1, %edx
cmovnel %ebx, %edx
testq %r14, %r14
cmovel %ecx, %r9d
cmovnel %edx, %ebx
cmovel %eax, %esi
movq %rsi, 0x48(%rsp)
addq $0x40, %r14
cmpq $0x40, %r14
je 0x6091
xorl %r15d, %r15d
movslq %r12d, %r12
movq 0x18(%rsp), %rax
cmpl %eax, 0x24(%rsp)
movq 0x100(%rsp), %r14
jle 0x61a1
movl %ebx, %eax
shlq $0x6, %rax
xorl %r15d, %r15d
movq 0x18(%rsp), %rcx
cmpl $0x0, 0xc(%rsp)
jle 0x619a
movslq %r15d, %r15
xorl %edx, %edx
cmpl $0x0, 0x8(%rsp)
jle 0x618f
xorl %esi, %esi
movq 0x80(%rsp,%rsi,8), %rdi
addq %r15, %rdi
movb 0x40(%rax,%rdi), %dil
movq 0xb0(%rsp,%rsi,8), %r8
addq %r15, %r8
movb %dil, (%r12,%r8)
incq %rsi
movslq 0x8(%rsp), %rdi
cmpq %rdi, %rsi
jl 0x6163
incq %r15
incl %edx
cmpl 0xc(%rsp), %edx
jl 0x615a
incl %ecx
cmpl %r10d, %ecx
jl 0x614e
movl %r9d, 0x78(%rsp)
movq 0xe0(%rsp), %rax
leaq (%rax,%r12), %rdi
movq 0xd8(%rsp), %rax
leaq (%rax,%r12), %rsi
movq 0xd0(%rsp), %rax
leaq (%rax,%r12), %rdx
movl %r15d, %ecx
movq %r12, %rbp
movq 0x48(%rsp), %r12
movl %r12d, %r8d
callq 0x4daf
movl 0x10(%rsp), %r10d
leal (%rbx,%r12,2), %eax
movq %rbp, %r12
movb %al, (%r13,%r14)
incq %r14
addl %r15d, %r12d
movl 0x14(%rsp), %r8d
incl %r8d
movq 0x38(%rsp), %rax
movl (%rax), %eax
movl 0x74(%rsp), %edx
addl $0x8, %edx
movl 0x70(%rsp), %edi
addl $-0x8, %edi
movq 0xf8(%rsp), %rsi
addq $0x20, %rsi
movq 0xf0(%rsp), %rcx
cmpl %ecx, %eax
jg 0x5cee
movq 0x28(%rsp), %r15
jmp 0x6237
xorl %r12d, %r12d
cmpl $0x0, 0x8(%rsp)
jle 0x62cb
xorl %ebx, %ebx
movq 0xb0(%rsp,%rbx,8), %rsi
leaq 0x160(%rsp), %rdi
movl %r12d, %edx
callq 0x4b4c
movq 0x168(%rsp), %rax
movslq 0x160(%rsp), %rcx
leaq (%rcx,%rax,8), %rax
testl $0xc0000000, %eax       # imm = 0xC0000000
jne 0x6498
movq 0x30(%rsp), %rcx
cmpq %rax, %rcx
cmovleq %rax, %rcx
movq %rcx, 0x30(%rsp)
movl %eax, 0x2198(%rsp)
movl $0x4, %edx
movq 0xe8(%rsp), %rdi
leaq 0x2198(%rsp), %rsi
callq 0x2200
leaq 0x160(%rsp), %rdi
callq 0x16612
incq %rbx
movslq 0x8(%rsp), %rax
cmpq %rax, %rbx
jl 0x6244
movq 0x38(%rsp), %rax
movl 0x4(%rax), %edi
movq 0x50(%rsp), %rcx
addl $0x20, %ecx
movq %rcx, 0x50(%rsp)
movl 0x6c(%rsp), %ecx
cmpl %edi, %ecx
jl 0x5cb0
jmp 0x62fa
xorl %r14d, %r14d
movq $0x0, 0x30(%rsp)
leaq 0x2198(%rsp), %rsi
movq 0x30(%rsp), %rax
movl %eax, (%rsi)
movl $0x4, %edx
movq 0x40(%rsp), %rdi
callq 0x2200
leaq 0x2198(%rsp), %rdi
callq 0x43e2
xorl %eax, %eax
leaq 0x190(%rsp), %rdi
movzbl %al, %ecx
imull $0x1010101, %ecx, %ecx  # imm = 0x1010101
xorl %edx, %edx
movl %ecx, (%rdi)
movzbl %dl, %esi
imull $0x1010101, %esi, %esi  # imm = 0x1010101
movl %esi, 0x4(%rdi)
addq $0x8, %rdi
incq %rdx
cmpl $0x10, %edx
jne 0x633a
incl %eax
cmpl $0x20, %eax
jne 0x632f
leaq 0x2198(%rsp), %rdi
leaq 0x190(%rsp), %rsi
leaq 0x1190(%rsp), %rcx
leaq 0x188(%rsp), %r8
movl $0x1000, %edx           # imm = 0x1000
callq 0x46a8
leal (%r14,%r14), %eax
movslq %eax, %rdi
callq 0x2040
movq %rax, %rbx
movslq %r14d, %rdx
leaq 0x2198(%rsp), %rdi
leaq 0x190(%rsp), %r14
movq %r13, %rsi
movq %rax, %rcx
movq %r14, %r8
callq 0x46a8
movq (%r14), %r14
leaq 0x1190(%rsp), %rsi
movl %r14d, (%rsi)
movl $0x4, %edx
movq 0x40(%rsp), %r12
movq %r12, %rdi
callq 0x2200
movq %r12, %rdi
movq %rbx, %rsi
movq %r14, %rdx
callq 0x2200
movq %rbx, %rdi
callq 0x21f0
movq %r15, %rsi
addq $0x18, %rsi
leaq 0x2198(%rsp), %rdi
callq 0x22b0
movq 0x2198(%rsp), %rsi
movl 0x21a0(%rsp), %edx
movq 0x40(%rsp), %rdi
callq 0x2200
leaq 0x21a8(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x6439
movq 0x21a8(%rsp), %rsi
incq %rsi
callq 0x21a0
leaq 0x160(%rsp), %rdi
callq 0x16612
xorl %ebx, %ebx
movq 0x80(%rsp,%rbx,8), %rdi
testq %rdi, %rdi
je 0x645a
callq 0x21f0
movq 0xb0(%rsp,%rbx,8), %rdi
testq %rdi, %rdi
je 0x646c
callq 0x21f0
incq %rbx
cmpq $0x4, %rbx
jne 0x6448
movq %r13, %rdi
callq 0x21f0
movq (%r15), %rax
movq %r15, %rdi
callq *0x8(%rax)
addq $0x943c8, %rsp          # imm = 0x943C8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x10, %edi
callq 0x20e0
movq %rax, %r14
leaq 0x11483(%rip), %rsi     # 0x1792f
movq %rax, %rdi
callq 0x20a0
movq 0x15b35(%rip), %rsi     # 0x1bff0
movq 0x15b06(%rip), %rdx     # 0x1bfc8
movq %r14, %rdi
callq 0x2300
jmp 0x6627
jmp 0x6639
movq %rax, %rbx
leaq 0x21a8(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x6591
movq 0x21a8(%rsp), %rsi
incq %rsi
callq 0x21a0
jmp 0x6591
jmp 0x6503
movq %rax, %rbx
jmp 0x6591
jmp 0x65b6
jmp 0x659d
movq %rax, %rbx
movl $0x188, %esi            # imm = 0x188
movq %r15, %rdi
callq 0x21a0
jmp 0x652a
movq %rax, %rbx
xorl %r15d, %r15d
xorl %r13d, %r13d
jmp 0x65d0
movq %rax, %rdi
callq 0x20b0
movq %rbx, %rdi
callq 0x21f0
movl $0x10, %edi
callq 0x20e0
movq %rax, %r14
leaq 0x113ee(%rip), %rsi     # 0x17947
movq %rax, %rdi
callq 0x20a0
movq 0x15a88(%rip), %rsi     # 0x1bff0
movq 0x15a59(%rip), %rdx     # 0x1bfc8
movq %r14, %rdi
callq 0x2300
jmp 0x6627
movq %rax, %rbx
jmp 0x658c
movq %rax, %rbx
movq %r14, %rdi
callq 0x2140
callq 0x22d0
movq 0x28(%rsp), %r15
movq 0x60(%rsp), %r13
jmp 0x65c3
movq %rax, %rbx
xorl %r13d, %r13d
jmp 0x65c3
jmp 0x65b6
movq %rax, %rbx
movq %r14, %rdi
callq 0x2140
jmp 0x65c3
jmp 0x65b6
movq %rax, %rbx
jmp 0x65c3
movq %rax, %rbx
movq 0x28(%rsp), %r15
leaq 0x160(%rsp), %rdi
callq 0x16612
movq %rbx, %rdi
callq 0x20b0
xorl %ebx, %ebx
movq 0x80(%rsp,%rbx,8), %rdi
testq %rdi, %rdi
je 0x65ec
callq 0x21f0
movq 0xb0(%rsp,%rbx,8), %rdi
testq %rdi, %rdi
je 0x65fe
callq 0x21f0
incq %rbx
cmpq $0x4, %rbx
jne 0x65da
testq %r13, %r13
je 0x6614
movq %r13, %rdi
callq 0x21f0
testq %r15, %r15
je 0x6622
movq (%r15), %rax
movq %r15, %rdi
callq *0x8(%rax)
callq 0x2250
jmp 0x6639
movq %rax, %rbx
callq 0x22d0
movq %rbx, %rdi
callq 0x2310
movq %rax, %rdi
callq 0x1667a