// File: /workspace/github_c_makefile_star2_O2/enzo1982[P]smooth/misc/codecs.cpp
// Function: PCIIO::ReadLine(smooth::IO::InStream*, int)
bool PCIIO::ReadLine(PCIIn in, int y)
{
	/* Check compression type.
	 */
	if (compression != PCI	 &&
	    compression != RLE	 &&
	    compression != BZIP2 &&
	    compression != UNCOMPRESSED) return false;

	/* Read image line.
	 */
	int	*line = new int [sizex];
	int	 ctsize;
	int	 maxpalentries;

	switch (colorspace)
	{
		case Color::RGB:
		case Color::YUV:
		case Color::HSV:
		case Color::CMY:
			ctsize = 3;
			maxpalentries = 338;

			break;
		case Color::CMYK:
			ctsize = 4;
			maxpalentries = 338;

			break;
		case Color::GRAY:
			ctsize = 1;
			maxpalentries = 338;

			break;
		default:
			ctsize = 3;
			maxpalentries = 338;

			break;
	}

	switch (compression)
	{
		case BZIP2:
		case UNCOMPRESSED:
			for (int x = 0; x < sizex; x++)
			{
				line[x] = in->InputBits(ctsize * bpcc);
			}

			break;
		case RLE:
			for (int x = 0; x < sizex; x++)
			{
				int	 col = in->InputBits(ctsize * bpcc);
				int	 rle = in->InputBits(rlebits);

				for (int i = x; i <= x + rle; i++) line[i] = col;

				x += rle;
			}

			break;
		case PCI:
			if (in->InputBits(1) == 1)
			{
				DecompressSLAL(line, previousLine, sizex);
			}
			else
			{
				int	 allinpal = 0;
				int	 gallinpal = 0;
				int	 mod04 = 0;
				int	 mod16 = 0;

				int	 dosaa = in->InputBits(1);
				int	 dorle = in->InputBits(1);

				for (int x = 0; x < sizex; x++)
				{
					int	 previousColor = (x > 0 ? line[x - 1] : 0);

					if ( (x % 16) == mod16		     ) gallinpal = in->InputBits(1);
					if (((x %  4) == mod04) && !gallinpal) allinpal	 = in->InputBits(1);

					int	 col = 0;
					int	 inpal = 1;

					if (!allinpal && !gallinpal) inpal = in->InputBits(1);

					if (inpal == 0)
					{
						if (in->InputBits(1)) col = DecompressDelta(line, previousLine, x, ctsize, in);
						else		      col = in->InputBits(ctsize * bpcc);

						if (palentries < maxpalentries)
						{
							palette[palentries] = col;
							palentries++;
						}
						else
						{
							RotatePalette(col);
						}
					}
					else
					{
						int	 saa = 0;

						if (dosaa) saa = in->InputBits(1);

						if (saa)
						{
							col = previousLine[x];
						}
						else
						{
							if (in->InputBits(1) == 1)
							{
								col = palette[(palentries - 1) - in->InputBits(1)];
							}
							else
							{
								if (in->InputBits(1) == 1)
								{
									int	 lbits = Math::Min(GetMinimumBits(palentries - 2), 4);

									col = palette[(palentries - 1) - in->InputBits(lbits) - 2];
								}
								else
								{
									if (in->InputBits(1) == 1)
									{
										int	 lbits = Math::Min(GetMinimumBits(palentries - 18), 6);

										col = palette[(palentries - 1) - in->InputBits(lbits) - 18];
									}
									else
									{
										col = palette[(palentries - 1) - in->InputBits(GetMinimumBits(palentries - 83)) - 82];
									}
								}
							}
						}

						int	 paletteEntry = GetPaletteEntry(col);

						if (paletteEntry >= 0) RotatePaletteEntry(paletteEntry);
					}

					line[x] = col;

					if (col == previousColor)
					{
						if (in->InputBits(1) == 1)
						{
							int	 pcirle;

							if (in->InputBits(1) == 1) pcirle = in->InputBits(8) + 2;
							else			   pcirle = in->InputBits(3) + 2;

							for (int i = x + 1; i <= x + pcirle; i++) line[i] = line[x];

							x = x + pcirle;

							allinpal = 0;
							gallinpal = 0;

							mod04 = (x + 1) %  4;
							mod16 = (x + 1) % 16;
						}
					}
					else if ((col == previousLine[x]) && dorle)
					{
						if (in->InputBits(1) == 1)
						{
							int	 pcirle;

							if (in->InputBits(1) == 1) pcirle = in->InputBits(8) + 2;
							else			   pcirle = in->InputBits(3) + 2;

							for (int i = x + 1; i <= x + pcirle; i++) line[i] = previousLine[i];

							x = x + pcirle;

							allinpal = 0;
							gallinpal = 0;

							mod04 = (x + 1) %  4;
							mod16 = (x + 1) % 16;
						}
					}
				}
			}

			for (int x = 0; x < sizex; x++) previousLine[x] = line[x];

			break;
	}

	for (int x = 0; x < sizex; x++) bmp.SetPixel(Point(x, y), Color(line[x], colorspace).Upsample(bpcc).ConvertTo(Color::RGB));

	delete [] line;

	return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movl %edx, 0x2c(%rsp)
movq %rdi, (%rsp)
movl 0x50(%rdi), %ebx
xorl %eax, %eax
cmpl $0x4, %ebx
ja 0xb24a5
cmpl $0x2, %ebx
je 0xb24a5
movq %rsi, %r12
movq (%rsp), %r14
movslq 0x10(%r14), %rbp
leaq (,%rbp,4), %rax
testq %rbp, %rbp
pushq $-0x1
popq %rdi
cmovnsq %rax, %rdi
callq 0x577a0
movq %rax, %r15
movl 0x58(%r14), %eax
xorl %ecx, %ecx
cmpl $0x5, %eax
sete %cl
addl $0x3, %ecx
cmpl $0x6, %eax
pushq $0x1
popq %rax
cmovnel %ecx, %eax
movl %eax, 0xc(%rsp)
cmpl $0x4, %ebx
ja 0xb242a
movl %ebx, %eax
leaq 0x50c56(%rip), %rcx     # 0x102c30
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
xorl %ebx, %ebx
movq (%rsp), %r14
movslq %ebp, %rax
cmpq %rax, %rbx
jge 0xb242a
movl 0x54(%r14), %esi
imull 0xc(%rsp), %esi
movq %r12, %rdi
callq 0x584c0
movl %eax, (%r15,%rbx,4)
incq %rbx
movl 0x10(%r14), %ebp
jmp 0xb1fe9
xorl %r14d, %r14d
movq (%rsp), %r13
cmpl %ebp, %r14d
jge 0xb242a
movl 0x54(%r13), %esi
imull 0xc(%rsp), %esi
movq %r12, %rdi
callq 0x584c0
movq %rax, %rbx
movl 0x60(%r13), %esi
movq %r12, %rdi
callq 0x584c0
addl %r14d, %eax
movslq %r14d, %rcx
movslq %eax, %rdx
cmpq %rdx, %rcx
jg 0xb205a
movl %ebx, (%r15,%rcx,4)
incq %rcx
jmp 0xb204c
incl %eax
movq (%rsp), %rcx
movl 0x10(%rcx), %ebp
movl %eax, %r14d
jmp 0xb201a
pushq $0x1
popq %rsi
movq %r12, %rdi
callq 0x584c0
cmpq $0x1, %rax
jne 0xb2099
movq 0xba390(%rip), %rbx     # 0x16c410
movq (%rsp), %rax
movl 0x10(%rax), %ebp
movq %r15, %rdi
movq %rbx, %rsi
movl %ebp, %edx
callq 0xb3600
jmp 0xb240d
pushq $0x1
popq %rbx
movq %r12, %rdi
movl %ebx, %esi
callq 0x584c0
movq %rax, 0x40(%rsp)
movq %r12, %rdi
movl %ebx, %esi
callq 0x584c0
movq %rax, 0x38(%rsp)
movq $0x0, 0x20(%rsp)
xorl %ebx, %ebx
movl $0x0, 0x14(%rsp)
movl $0x0, 0x10(%rsp)
xorl %r13d, %r13d
movq (%rsp), %rax
movl 0x10(%rax), %ebp
cmpl %ebp, %r13d
jge 0xb2406
testl %r13d, %r13d
jle 0xb20f7
movl %r13d, %eax
movl -0x4(%r15,%rax,4), %r14d
jmp 0xb20fa
xorl %r14d, %r14d
pushq $0x1
popq %rbp
movl %r13d, %eax
cltd
pushq $0x10
popq %rcx
idivl %ecx
cmpl 0x10(%rsp), %edx
jne 0xb2119
movq %r12, %rdi
movl %ebp, %esi
callq 0x584c0
movq %rax, %rbx
movl %r13d, %eax
cltd
pushq $0x4
popq %rcx
idivl %ecx
xorl 0x14(%rsp), %edx
orl %ebx, %edx
jne 0xb2139
movq %r12, %rdi
movl %ebp, %esi
callq 0x584c0
movq %rax, 0x20(%rsp)
movq 0x20(%rsp), %rax
orl %ebx, %eax
movq %rbx, 0x18(%rsp)
jne 0xb2159
movq %r12, %rdi
movl %ebp, %esi
callq 0x584c0
testl %eax, %eax
je 0xb220a
cmpl $0x0, 0x40(%rsp)
je 0xb2181
movq %r12, %rdi
movl %ebp, %esi
callq 0x584c0
testl %eax, %eax
je 0xb2181
movslq %r13d, %rax
shlq $0x2, %rax
addq 0xba294(%rip), %rax     # 0x16c410
jmp 0xb22f4
movq %r12, %rdi
movl %ebp, %esi
callq 0x584c0
cmpq $0x1, %rax
jne 0xb21b8
movslq 0xba898(%rip), %rbx     # 0x16ca30
movq %r12, %rdi
movl %ebp, %esi
callq 0x584c0
notq %rax
addq %rbx, %rax
leaq 0xba271(%rip), %rcx     # 0x16c420
leaq (%rcx,%rax,4), %rax
jmp 0xb22f4
movq %r12, %rdi
movl %ebp, %esi
callq 0x584c0
cmpq $0x1, %rax
jne 0xb2236
movl 0xba862(%rip), %edi     # 0x16ca30
addl $-0x2, %edi
callq 0xb34ff
cmpl $0x4, %eax
pushq $0x4
popq %rcx
cmovgel %ecx, %eax
movslq 0xba84a(%rip), %rbx     # 0x16ca30
movq %r12, %rdi
movl %eax, %esi
callq 0x584c0
notq %rax
addq %rbx, %rax
leaq 0xba223(%rip), %rcx     # 0x16c420
leaq (%rcx,%rax,4), %rax
addq $-0x8, %rax
jmp 0xb22f4
movq %r12, %rdi
movl %ebp, %esi
callq 0x584c0
testq %rax, %rax
je 0xb2288
movq 0xba1f0(%rip), %rsi     # 0x16c410
movq %r15, %rdi
movl %r13d, %edx
movl 0xc(%rsp), %ecx
movq %r12, %r8
callq 0xb361b
movl %eax, %ebp
jmp 0xb229f
movq %r12, %rdi
movl %ebp, %esi
callq 0x584c0
movslq 0xba7e9(%rip), %rbx     # 0x16ca30
cmpq $0x1, %rax
jne 0xb22cb
addl $-0x12, %ebx
movl %ebx, %edi
callq 0xb34ff
cmpl $0x6, %eax
pushq $0x6
popq %rcx
cmovgel %ecx, %eax
movslq 0xba7c9(%rip), %rbx     # 0x16ca30
movq %r12, %rdi
movl %eax, %esi
callq 0x584c0
notq %rax
addq %rbx, %rax
leaq 0xba1a2(%rip), %rcx     # 0x16c420
leaq (%rcx,%rax,4), %rax
addq $-0x48, %rax
jmp 0xb22f4
movq (%rsp), %rax
movl 0x54(%rax), %esi
imull 0xc(%rsp), %esi
movq %r12, %rdi
callq 0x584c0
movq %rax, %rbp
movslq 0xba78a(%rip), %rax     # 0x16ca30
cmpq $0x151, %rax            # imm = 0x151
jg 0xb22c2
leaq 0xba16b(%rip), %rcx     # 0x16c420
movl %ebp, (%rcx,%rax,4)
incl %eax
movl %eax, 0xba770(%rip)     # 0x16ca30
jmp 0xb2308
movl %ebp, %edi
callq 0xb34bd
jmp 0xb2308
leal -0x53(%rbx), %edi
callq 0xb34ff
movq %r12, %rdi
movl %eax, %esi
callq 0x584c0
notq %rax
addq %rbx, %rax
leaq 0xba136(%rip), %rcx     # 0x16c420
leaq (%rcx,%rax,4), %rax
addq $-0x148, %rax           # imm = 0xFEB8
movl (%rax), %ebp
movl %ebp, %edi
callq 0xb294f
testl %eax, %eax
js 0xb2308
movl %eax, %edi
callq 0xb3541
movslq %r13d, %rbx
movl %ebp, (%r15,%rbx,4)
cmpl %r14d, %ebp
jne 0xb2365
movq %r12, %rdi
pushq $0x1
popq %rbp
movl %ebp, %esi
callq 0x584c0
cmpq $0x1, %rax
jne 0xb23d0
movq %r12, %rdi
movl %ebp, %esi
callq 0x584c0
xorl %ecx, %ecx
cmpq $0x1, %rax
sete %cl
leal (%rcx,%rcx,4), %esi
addl $0x3, %esi
movq %r12, %rdi
callq 0x584c0
addl %eax, %r13d
addl $0x2, %r13d
movslq %r13d, %rax
cmpq %rax, %rbx
jge 0xb23d7
movl %r14d, 0x4(%r15,%rbx,4)
incq %rbx
jmp 0xb2356
cmpl $0x0, 0x38(%rsp)
je 0xb23d0
movq 0xba09d(%rip), %rax     # 0x16c410
cmpl (%rax,%rbx,4), %ebp
jne 0xb23d0
movq %r12, %rdi
pushq $0x1
popq %rbp
movl %ebp, %esi
callq 0x584c0
cmpq $0x1, %rax
jne 0xb23d0
movq %r12, %rdi
movl %ebp, %esi
callq 0x584c0
xorl %ecx, %ecx
cmpq $0x1, %rax
sete %cl
leal (%rcx,%rcx,4), %esi
addl $0x3, %esi
movq %r12, %rdi
callq 0x584c0
addl %eax, %r13d
addl $0x2, %r13d
movq 0xba056(%rip), %rax     # 0x16c410
movslq %r13d, %rcx
cmpq %rcx, %rbx
jge 0xb23d7
movl 0x4(%rax,%rbx,4), %edx
movl %edx, 0x4(%r15,%rbx,4)
incq %rbx
jmp 0xb23bd
movq 0x18(%rsp), %rbx
jmp 0xb23fe
leal 0x1(%r13), %ecx
movl %ecx, %eax
cltd
pushq $0x4
popq %rsi
idivl %esi
movl %edx, 0x14(%rsp)
movl %ecx, %eax
cltd
pushq $0x10
popq %rcx
idivl %ecx
movl %edx, 0x10(%rsp)
movq $0x0, 0x20(%rsp)
xorl %ebx, %ebx
incl %r13d
jmp 0xb20d8
movq 0xba003(%rip), %rbx     # 0x16c410
xorl %eax, %eax
movslq %ebp, %rcx
cmpq %rcx, %rax
jge 0xb242a
movl (%r15,%rax,4), %ecx
movl %ecx, (%rbx,%rax,4)
incq %rax
movq (%rsp), %rcx
movl 0x10(%rcx), %ebp
jmp 0xb240f
movq (%rsp), %rax
leaq 0x8(%rax), %r12
xorl %ebx, %ebx
leaq 0x58(%rsp), %r13
leaq 0x68(%rsp), %r14
movslq %ebp, %rax
cmpq %rax, %rbx
jge 0xb249b
movl %ebx, 0x30(%rsp)
movl 0x2c(%rsp), %eax
movl %eax, 0x34(%rsp)
movslq (%r15,%rbx,4), %rax
movq (%rsp), %rbp
movl 0x58(%rbp), %ecx
movq %rax, 0x50(%rsp)
movl %ecx, 0x48(%rsp)
movl 0x54(%rbp), %edx
movq %r13, %rdi
leaq 0x48(%rsp), %rsi
callq 0x58a80
movq %r14, %rdi
movq %r13, %rsi
xorl %edx, %edx
callq 0x58f90
movq %r12, %rdi
leaq 0x30(%rsp), %rsi
movq %r14, %rdx
callq 0x57160
incq %rbx
movl 0x10(%rbp), %ebp
jmp 0xb243e
movq %r15, %rdi
callq 0x572d0
movb $0x1, %al
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq