// File: /workspace/github_c_makefile_star2_O1/Joy-Division[P]tools-zoe/pss-demux.c
// Function: main
int main( int argc, char **argv ) {
	
	mpegPackHeader packHead;
	mpegPesHeader tempHead;
	
	uint32_t curId = 0, headSize = 0;
	unsigned char temp[4];
	FILE *pss = NULL, *pout = NULL, *sout = NULL, *aout = NULL, *vout = NULL;
	
	if( argc < 2 ) {
		printf("Not enough args!\nUse: %s PSS-file\n", argv[0]);
		return 1;
	}
	
	if( !(pss = fopen( argv[1], "rb" ))) {
		printf("Couldnt open file %s\n", argv[1]);
		return 1;
	}
	
	char *outfilename = malloc( strlen( argv[1] ) + 7 + 2 + 4 + 1 );
	
	sprintf( outfilename, "%s-stream00.m2v", argv[1] );
	if( !(vout = fopen( outfilename, "wb" ))) {
			printf("Couldnt open file %s\n", outfilename);
			return 1;
	}
	sprintf( outfilename, "%s-stream01.vag", argv[1] );
	if( !(aout = fopen( outfilename, "wb+" ))) {
			printf("Couldnt open file %s\n", outfilename);
			return 1;
	}
	sprintf( outfilename, "%s-stream05.dmx", argv[1] );
	if( !(pout = fopen( outfilename, "wb+" ))) {
			printf("Couldnt open file %s\n", outfilename);
			return 1;
	}
	
	fread( temp, 4, 1, pss );
	fseek( pss, - 4, SEEK_CUR );
	curId = temp[0] << 24 | temp[1] << 16 | temp[2] << 8 | temp[3];
	
	while( curId != MPEG_PROGRAM_END ) {
		switch (curId) {
			case MPEG_VIDEO: {
				// printf( "Encountered VIDEO header at %08x\n", (unsigned int)ftell(pss));
				mpegDumpVideoStream( pss, ftell(pss), vout );
				break;
			}
			case MPEG_PRIVATE_STREAM1: {
				// printf( "Encountered PRIVATE1 header at %08x\n", (unsigned int)ftell(pss));
				mpegDetectAndDumpPrivateStream( pss, ftell(pss), aout, sout, pout, argv[1] );
				break;
			}
			// SYSTEM, PADDING and PACKs are ignored for now
			case MPEG_SYSTEM_HEAD: {
				// printf( "Encountered SYSTEM header at %08x", (unsigned int)ftell(pss));
				fread( &tempHead, sizeof(tempHead), 1, pss );
				headSize = tempHead.size[0] << 8 | tempHead.size[1];
				// printf( " of %04x bytes\n", headSize );
				fseek( pss, headSize, SEEK_CUR );
				break;
			}
			case MPEG_PADDING: {
				// printf( "Encountered padding stream at %08x", (unsigned int)ftell(pss));
				fread( &tempHead, sizeof(tempHead), 1, pss );
				headSize = tempHead.size[0] << 8 | tempHead.size[1];
				// printf( " of %04x bytes\n", headSize );
				fseek( pss, headSize, SEEK_CUR );
				break;
			}
			case MPEG_PACK_HEAD: {
				// printf( "Encountered PACK header at %08x", (unsigned int)ftell(pss));
				fread( &packHead, sizeof(packHead), 1, pss );
				// printf( " with %1x bytes padding\n", packHead.reservedStuffing & 0x07 );
				fseek( pss, packHead.reservedStuffing & 0x07, SEEK_CUR );
				break;
			}
			default: {
				printf("Encountered unknown ID %08x at %08x, stopping...\n", curId, (unsigned int)ftell(pss));
				return 1;
			}
		}
		fread( temp, 4, 1, pss );
		fseek( pss, - 4, SEEK_CUR );
		curId = temp[0] << 24 | temp[1] << 16 | temp[2] << 8 | temp[3];
	}
	
	unsigned int haveAudio = ftell(aout), haveVideo = ftell(vout), havePoly = ftell(pout);
	
	if( ftell(aout) > 0 ) {
		unsigned int headSize;
		if( audioNumChannels == 1 ) headSize = 0x30;
		else if( audioNumChannels == 2 ) headSize = 0x40;
		fseek( aout, headSize, SEEK_SET );
		unsigned char readbuf[0x10] = {0};
		vagHeader header;
		while( fread( readbuf, 0x10, 1, aout )) {
			if( !memcmp( readbuf, vagEnd, 0x10 ) ) break;
		}
		uint32_t numBytes = ftell(aout)/audioNumChannels - headSize;
		vagPrepareHeader( &header, numBytes, argv[1] );
		fseek( aout, 0, SEEK_SET );
		vagWriteHeader( header, aout );
	}
	fclose(aout);
	fclose(vout);
	fclose(pout);
	fflush(stdout);
	if( !haveAudio ) {
		sprintf( outfilename, "%s-stream01.vag", argv[1] );
		if( remove( outfilename )) printf("Couldnt delete unused audio stream %s\n", outfilename );
	}
	if( !haveVideo ) {
		sprintf( outfilename, "%s-stream00.m2v", argv[1] );
		if( remove( outfilename )) printf("Couldnt delete unused video file %s\n", outfilename );
	}
	if( !havePoly ) {
		sprintf( outfilename, "%s-stream05.dmx", argv[1] );
		if( remove( outfilename )) printf("Couldnt delete unused poly file %s\n", outfilename );
	}
	
	free(outfilename);
	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc8, %rsp
movq %rsi, %r14
cmpl $0x1, %edi
jg 0x174b
movq (%r14), %rsi
leaq 0x94f(%rip), %rdi       # 0x2095
jmp 0x1954
movq 0x8(%r14), %rdi
leaq 0x962(%rip), %rsi       # 0x20b8
callq 0x10e0
movq 0x8(%r14), %rbx
testq %rax, %rax
je 0x194a
movq %rax, %rbp
movq %rbx, %rdi
callq 0x1080
leaq 0xe(%rax), %rdi
callq 0x10b0
movq %rax, %r15
leaq 0x935(%rip), %rsi       # 0x20bb
movq %rax, %rdi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x1100
leaq 0x8e2(%rip), %rsi       # 0x207c
movq %r15, %rdi
callq 0x10e0
movq %rax, 0x40(%rsp)
testq %rax, %rax
je 0x193e
movq 0x8(%r14), %rdx
leaq 0x910(%rip), %rsi       # 0x20cb
movq %r15, %rdi
xorl %eax, %eax
callq 0x1100
leaq 0x90f(%rip), %rsi       # 0x20db
movq %r15, %rdi
callq 0x10e0
testq %rax, %rax
je 0x193e
movq %rax, %rbx
movq 0x8(%r14), %rdx
leaq 0x8f4(%rip), %rsi       # 0x20df
movq %r15, %rdi
xorl %eax, %eax
callq 0x1100
leaq 0x8df(%rip), %rsi       # 0x20db
movq %r15, %rdi
callq 0x10e0
movq %rax, 0x38(%rsp)
testq %rax, %rax
je 0x193e
movq %rbx, 0x58(%rsp)
movq %r15, 0x68(%rsp)
leaq 0x4e(%rsp), %rbx
movl $0x4, %esi
movl $0x1, %edx
movq %rbx, %rdi
movq %rbp, %rcx
callq 0x1060
movq %rbp, %rdi
movq $-0x4, %rsi
movl $0x1, %edx
callq 0x10d0
movl (%rbx), %r15d
bswapl %r15d
leaq 0x7ad(%rip), %r12       # 0x2004
leaq 0x52(%rsp), %r13
leal -0x1b9(%r15), %eax
cmpl $0x5, %eax
ja 0x1894
movslq (%r12,%rax,4), %rax
addq %r12, %rax
jmpq *%rax
movl $0x6, %esi
movl $0x1, %edx
movq %r13, %rdi
movq %rbp, %rcx
callq 0x1060
movzwl 0x56(%rsp), %eax
rolw $0x8, %ax
movzwl %ax, %esi
jmp 0x18d9
cmpl $0x1e0, %r15d           # imm = 0x1E0
jne 0x1972
movq %rbp, %rdi
callq 0x10a0
movq %rbp, %rdi
movl %eax, %esi
movq 0x40(%rsp), %rdx
callq 0x12eb
jmp 0x1908
movl $0xe, %esi
movl $0x1, %edx
leaq 0x72(%rsp), %rdi
movq %rbp, %rcx
callq 0x1060
movzbl 0x7f(%rsp), %esi
andl $0x7, %esi
movq %rbp, %rdi
movl $0x1, %edx
callq 0x10d0
jmp 0x1908
movq %rbp, %rdi
callq 0x10a0
movq 0x8(%r14), %r9
movq %rbp, %rdi
movl %eax, %esi
movq 0x58(%rsp), %rdx
movq 0x38(%rsp), %r8
callq 0x1394
movl $0x4, %esi
movl $0x1, %edx
movq %rbx, %rdi
movq %rbp, %rcx
callq 0x1060
movq %rbp, %rdi
movq $-0x4, %rsi
movl $0x1, %edx
callq 0x10d0
movl 0x4e(%rsp), %r15d
bswapl %r15d
jmp 0x185c
leaq 0x73a(%rip), %rdi       # 0x207f
movq %r15, %rsi
jmp 0x1954
leaq 0x72e(%rip), %rdi       # 0x207f
movq %rbx, %rsi
xorl %eax, %eax
callq 0x1090
movl $0x1, %eax
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rbp, %rdi
callq 0x10a0
leaq 0x76e(%rip), %rdi       # 0x20ef
movl %r15d, %esi
movl %eax, %edx
xorl %eax, %eax
callq 0x1090
jmp 0x195b
movq 0x58(%rsp), %r12
movq %r12, %rdi
callq 0x10a0
movq %rax, %rbx
movq 0x40(%rsp), %rdi
callq 0x10a0
movq %rax, %r13
movq 0x38(%rsp), %rdi
callq 0x10a0
movq %rax, %rbp
movq %r12, %rdi
callq 0x10a0
testq %rax, %rax
jle 0x1aa1
movq %r13, 0x60(%rsp)
movb 0x26e0(%rip), %al       # 0x40b5
xorl %ecx, %ecx
cmpb $0x2, %al
sete %cl
shll $0x6, %ecx
cmpb $0x1, %al
movl $0x30, %r13d
cmovneq %rcx, %r13
movq %r12, %rdi
movq %r13, %rsi
xorl %edx, %edx
callq 0x10d0
pxor %xmm0, %xmm0
leaq 0x80(%rsp), %r15
movdqa %xmm0, (%r15)
movl $0x10, %esi
movl $0x1, %edx
movq %r15, %rdi
movq %r12, %rcx
callq 0x1060
testq %rax, %rax
je 0x1a3f
movdqa 0x80(%rsp), %xmm0
pcmpeqb 0x266c(%rip), %xmm0     # 0x40a0
pmovmskb %xmm0, %eax
cmpl $0xffff, %eax           # imm = 0xFFFF
jne 0x1a09
movq %r12, %rdi
callq 0x10a0
movzbl 0x2667(%rip), %ecx      # 0x40b5
cqto
idivq %rcx
subl %r13d, %eax
movq 0x8(%r14), %rdx
leaq 0x98(%rsp), %r15
movq %r15, %rdi
movl %eax, %esi
callq 0x15f6
movq %r12, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x10d0
movups (%r15), %xmm0
movups 0x10(%r15), %xmm1
movups 0x20(%r15), %xmm2
movups %xmm2, 0x20(%rsp)
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
movq %r12, %rdi
callq 0x167c
movq 0x60(%rsp), %r13
movq %r12, %rdi
callq 0x1070
movq 0x40(%rsp), %rdi
callq 0x1070
movq 0x38(%rsp), %rdi
callq 0x1070
movq 0x251c(%rip), %rax      # 0x3fe0
movq (%rax), %rdi
callq 0x10c0
testl %ebx, %ebx
movq 0x68(%rsp), %rbx
jne 0x1b07
movq 0x8(%r14), %rdx
leaq 0x5eb(%rip), %rsi       # 0x20cb
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1100
movq %rbx, %rdi
callq 0x1050
testl %eax, %eax
je 0x1b07
leaq 0x624(%rip), %rdi       # 0x2121
movq %rbx, %rsi
xorl %eax, %eax
callq 0x1090
testl %r13d, %r13d
jne 0x1b3e
movq 0x8(%r14), %rdx
leaq 0x5a4(%rip), %rsi       # 0x20bb
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1100
movq %rbx, %rdi
callq 0x1050
testl %eax, %eax
je 0x1b3e
leaq 0x614(%rip), %rdi       # 0x2148
movq %rbx, %rsi
xorl %eax, %eax
callq 0x1090
testl %ebp, %ebp
jne 0x1b74
movq 0x8(%r14), %rdx
leaq 0x592(%rip), %rsi       # 0x20df
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1100
movq %rbx, %rdi
callq 0x1050
testl %eax, %eax
je 0x1b74
leaq 0x603(%rip), %rdi       # 0x216d
movq %rbx, %rsi
xorl %eax, %eax
callq 0x1090
movq %rbx, %rdi
callq 0x1030
xorl %eax, %eax
jmp 0x1960