// File: /workspace/github_c_makefile_star2_O2/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, %r15
cmpl $0x1, %edi
jg 0x16ef
movq (%r15), %rsi
leaq 0x9ab(%rip), %rdi       # 0x2095
jmp 0x18e9
movq 0x8(%r15), %rdi
leaq 0x9be(%rip), %rsi       # 0x20b8
callq 0x10e0
movq 0x8(%r15), %rbx
testq %rax, %rax
je 0x18df
movq %rax, %rbp
movq %rbx, %rdi
callq 0x1080
leaq 0xe(%rax), %rdi
callq 0x10b0
movq %rax, %r14
leaq 0x991(%rip), %rsi       # 0x20bb
movq %rax, %rdi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x1100
leaq 0x93e(%rip), %rsi       # 0x207c
movq %r14, %rdi
callq 0x10e0
movq %rax, 0x50(%rsp)
testq %rax, %rax
je 0x18d3
movq 0x8(%r15), %rdx
leaq 0x96c(%rip), %rsi       # 0x20cb
movq %r14, %rdi
xorl %eax, %eax
callq 0x1100
leaq 0x96b(%rip), %rsi       # 0x20db
movq %r14, %rdi
callq 0x10e0
testq %rax, %rax
je 0x18d3
movq %rax, %rbx
movq 0x8(%r15), %rdx
leaq 0x950(%rip), %rsi       # 0x20df
movq %r14, %rdi
xorl %eax, %eax
callq 0x1100
leaq 0x93b(%rip), %rsi       # 0x20db
movq %r14, %rdi
callq 0x10e0
movq %rax, 0x48(%rsp)
testq %rax, %rax
je 0x18d3
movq %rbx, 0x38(%rsp)
movq %r15, 0x40(%rsp)
movq %r14, 0x68(%rsp)
leaq 0x5c(%rsp), %r15
pushq $0x4
popq %rsi
pushq $0x1
popq %r12
movq %r15, %rdi
movq %r12, %rdx
movq %rbp, %rcx
callq 0x1060
pushq $-0x4
popq %rsi
pushq $0x1
popq %rbx
movq %rbp, %rdi
movl %ebx, %edx
callq 0x10d0
movq %r15, %r14
movl (%r15), %r15d
bswapl %r15d
leaq 0x805(%rip), %r13       # 0x2004
leal -0x1b9(%r15), %eax
cmpl $0x5, %eax
ja 0x1836
movslq (%r13,%rax,4), %rax
addq %r13, %rax
jmpq *%rax
leaq 0x32(%rsp), %rdi
pushq $0x6
popq %rsi
movq %r12, %rdx
movq %rbp, %rcx
callq 0x1060
movzwl 0x36(%rsp), %eax
rolw $0x8, %ax
movzwl %ax, %esi
jmp 0x1877
cmpl $0x1e0, %r15d           # imm = 0x1E0
jne 0x1907
movq %rbp, %rdi
callq 0x10a0
movq %rbp, %rdi
movl %eax, %esi
movq 0x50(%rsp), %rdx
callq 0x12cf
jmp 0x18a8
leaq 0x72(%rsp), %rdi
pushq $0xe
popq %rsi
movq %r12, %rdx
movq %rbp, %rcx
callq 0x1060
movzbl 0x7f(%rsp), %esi
andl $0x7, %esi
movq %rbp, %rdi
movl %ebx, %edx
callq 0x10d0
jmp 0x18a8
movq %rbp, %rdi
callq 0x10a0
movq 0x40(%rsp), %rcx
movq 0x8(%rcx), %r9
movq %rbp, %rdi
movl %eax, %esi
movq 0x38(%rsp), %rdx
movq 0x48(%rsp), %r8
callq 0x1372
movq %r14, %rdi
pushq $0x4
popq %rsi
movq %r12, %rdx
movq %rbp, %rcx
callq 0x1060
movq %rbp, %rdi
pushq $-0x4
popq %rsi
movl %ebx, %edx
callq 0x10d0
movl 0x5c(%rsp), %r15d
bswapl %r15d
jmp 0x17ff
leaq 0x7a5(%rip), %rdi       # 0x207f
movq %r14, %rsi
jmp 0x18e9
leaq 0x799(%rip), %rdi       # 0x207f
movq %rbx, %rsi
xorl %eax, %eax
callq 0x1090
pushq $0x1
popq %rbx
movl %ebx, %eax
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rbp, %rdi
callq 0x10a0
leaq 0x7d9(%rip), %rdi       # 0x20ef
movl %r15d, %esi
movl %eax, %edx
xorl %eax, %eax
callq 0x1090
jmp 0x18f3
movq 0x38(%rsp), %r12
movq %r12, %rdi
callq 0x10a0
movq %rax, %r14
movq 0x50(%rsp), %rdi
callq 0x10a0
movq %rax, %rbx
movq 0x48(%rsp), %rdi
callq 0x10a0
movq %rax, %r13
movq %r12, %rdi
callq 0x10a0
testq %rax, %rax
jle 0x1a4a
movq %rbx, 0x60(%rsp)
movq %r13, %rbx
movb 0x2748(%rip), %al       # 0x40b5
xorl %ecx, %ecx
cmpb $0x2, %al
sete %cl
shll $0x6, %ecx
cmpb $0x1, %al
pushq $0x30
popq %r15
cmovneq %rcx, %r15
movq %r12, %rdi
movq %r15, %rsi
xorl %edx, %edx
callq 0x10d0
pxor %xmm0, %xmm0
leaq 0x80(%rsp), %r12
movdqa %xmm0, (%r12)
pushq $0x10
popq %r13
pushq $0x1
popq %rbp
movq %r12, %rdi
movq %r13, %rsi
movq %rbp, %rdx
movq 0x38(%rsp), %rcx
callq 0x1060
testq %rax, %rax
je 0x19db
movdqa 0x80(%rsp), %xmm0
pcmpeqb 0x26d0(%rip), %xmm0     # 0x40a0
pmovmskb %xmm0, %eax
cmpl $0xffff, %eax           # imm = 0xFFFF
jne 0x19a7
movq 0x38(%rsp), %r12
movq %r12, %rdi
callq 0x10a0
movzbl 0x26c6(%rip), %ecx      # 0x40b5
cqto
idivq %rcx
subl %r15d, %eax
movq 0x40(%rsp), %rcx
movq 0x8(%rcx), %rdx
leaq 0x98(%rsp), %r15
movq %r15, %rdi
movl %eax, %esi
callq 0x15ac
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 0x162c
movq %rbx, %r13
movq 0x60(%rsp), %rbx
movq %r12, %rdi
callq 0x1070
movq 0x50(%rsp), %rdi
callq 0x1070
movq 0x48(%rsp), %rdi
callq 0x1070
movq 0x2573(%rip), %rax      # 0x3fe0
movq (%rax), %rdi
callq 0x10c0
testl %r14d, %r14d
movq 0x68(%rsp), %r14
movq 0x40(%rsp), %r15
jne 0x1ab6
movq 0x8(%r15), %rdx
leaq 0x63c(%rip), %rsi       # 0x20cb
movq %r14, %rdi
xorl %eax, %eax
callq 0x1100
movq %r14, %rdi
callq 0x1050
testl %eax, %eax
je 0x1ab6
leaq 0x675(%rip), %rdi       # 0x2121
movq %r14, %rsi
xorl %eax, %eax
callq 0x1090
testl %ebx, %ebx
jne 0x1aec
movq 0x8(%r15), %rdx
leaq 0x5f6(%rip), %rsi       # 0x20bb
movq %r14, %rdi
xorl %eax, %eax
callq 0x1100
movq %r14, %rdi
callq 0x1050
testl %eax, %eax
je 0x1aec
leaq 0x666(%rip), %rdi       # 0x2148
movq %r14, %rsi
xorl %eax, %eax
callq 0x1090
testl %r13d, %r13d
jne 0x1b23
movq 0x8(%r15), %rdx
leaq 0x5e3(%rip), %rsi       # 0x20df
movq %r14, %rdi
xorl %eax, %eax
callq 0x1100
movq %r14, %rdi
callq 0x1050
testl %eax, %eax
je 0x1b23
leaq 0x654(%rip), %rdi       # 0x216d
movq %r14, %rsi
xorl %eax, %eax
callq 0x1090
movq %r14, %rdi
callq 0x1030
xorl %ebx, %ebx
jmp 0x18f3