// File: /workspace/github_c_makefile_star2_O3/Joy-Division[P]tools-mgs/zar-extract.c
// Function: main
int main( int argc, char **argv ) {
	
	char *name = NULL;
	unsigned char *comdata = NULL, *uncomdata = NULL;
	uint32_t *size;
	unsigned int memoff, len;
	
	if( argc < 2 ) {
		printf("Not enough args!\nUse: %s _zar-file\n", argv[0]);
		return 1;
	}
	
	uint32_t numfiles, workfiles, uncomsize, filesize;
	unsigned long int havebuf;
	
	FILE *f, *o;
	
	if( !(f = fopen( argv[1], "rb" ))) {
		printf("Couldnt open file %s\n", argv[1]);
		return 1;
	}
	
	fseek(f, 0, SEEK_END);
	filesize = ftell(f);
	fseek(f, 0, SEEK_SET);
	
	fread( &uncomsize, 4, 1, f );
	
	printf("Compressed size %08x (file is %08x)\n", filesize-4, filesize);
	printf("Uncompressed size: %08x\n", uncomsize );
	havebuf = uncomsize;
	
	comdata = malloc(filesize-4);
	uncomdata = malloc(uncomsize);
	
	fread(comdata, filesize-4, 1, f);
	
	if((workfiles = uncompress(uncomdata, &havebuf, comdata, filesize-4)) != Z_OK) {
		printf("=====================================couldnt decompress data\n");
		switch(workfiles) {
			case Z_MEM_ERROR: {
				printf("memory error\n");
				break;
			}
			case Z_NEED_DICT: {
				printf("need dictionary\n");
				break;
			}
			case Z_DATA_ERROR: {
				printf("input corrupted\n");
				//~ printf("%s\n", strm.msg);
				break;
			}
			case Z_STREAM_ERROR: {
				printf("broken stream\n");
				break;
			}
			case Z_BUF_ERROR: {
				printf("buffer error\n");
				break;
			}
			default: {
				printf("unknown error\n");
				break;
			}
		}
		printf("uncomsize %08x\n", uncomsize);
		return 1;
	}
	free(comdata);
	fclose(f);
	
	numfiles = *uncomdata;
	
	printf("Number of files: %u\n", numfiles);
	
	memoff = 4;
	
	for( workfiles = 0; workfiles < numfiles; workfiles++ ) {
		printf("offset %08x\n", memoff);
		name = (char *)uncomdata+memoff;
		len = strlen(name) + 1;
		if((memoff+len)%4) len+= 4-((memoff+len)%4);
		memoff += len;
		
		printf("offset %08x\n", memoff);
		size = (uint32_t *)(uncomdata+memoff);
		len = 4;
		if((memoff+len)%0x10) len += 0x10-((memoff+len)%0x10);
		memoff += len;
		
		printf("Current file: %s - Size %08x\n", name, *size);
		
		if( !(o = fopen( name, "wb" ))) {
			printf("Couldnt open output %s\n", name);
			return 1;
		}
		
		fwrite(uncomdata+memoff, *size, 1, o);
		
		fclose(o);
		
		memoff += *size + 1;
	}
	
	free(uncomdata);
	printf("Done.\n");
	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rsi, %rbx
cmpl $0x1, %edi
jg 0x12de
movq (%rbx), %rsi
leaq 0xd79(%rip), %rdi       # 0x2052
jmp 0x13e6
movq 0x8(%rbx), %rdi
leaq 0xd8d(%rip), %rsi       # 0x2076
callq 0x10d0
testq %rax, %rax
je 0x13db
movq %rax, %r14
movq %rax, %rdi
xorl %esi, %esi
movl $0x2, %edx
callq 0x10c0
movq %r14, %rdi
callq 0x10a0
movq %rax, %rbx
movq %r14, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x10c0
leaq 0xc(%rsp), %r15
movl $0x4, %esi
movl $0x1, %edx
movq %r15, %rdi
movq %r14, %rcx
callq 0x1050
leal -0x4(%rbx), %r12d
leaq 0xd4a(%rip), %rdi       # 0x208f
movl %r12d, %esi
movl %ebx, %edx
xorl %eax, %eax
callq 0x1090
movl (%r15), %r15d
leaq 0xd59(%rip), %rdi       # 0x20b4
movl %r15d, %esi
xorl %eax, %eax
callq 0x1090
leaq 0x10(%rsp), %rbp
movq %r15, (%rbp)
movq %r12, %rdi
callq 0x10b0
movq %rax, %r13
movq %r15, %rdi
callq 0x10b0
movq %rax, %rbx
movl $0x1, %edx
movq %r13, %rdi
movq %r12, %rsi
movq %r14, %rcx
callq 0x1050
movq %rbx, %rdi
movq %rbp, %rsi
movq %r13, %rdx
movq %r12, %rcx
callq 0x1070
testl %eax, %eax
je 0x13f2
movl %eax, %ebp
leaq 0xd89(%rip), %rdi       # 0x213e
callq 0x1040
addl $0x5, %ebp
cmpl $0x7, %ebp
ja 0x150b
movl %ebp, %eax
leaq 0xe05(%rip), %rcx       # 0x21d4
movslq (%rcx,%rax,4), %rdi
addq %rcx, %rdi
jmp 0x1512
movq 0x8(%rbx), %rsi
leaq 0xc93(%rip), %rdi       # 0x2079
xorl %eax, %eax
callq 0x1090
jmp 0x1528
movq %r13, %rdi
callq 0x1030
movq %r14, %rdi
callq 0x1060
movzbl (%rbx), %r14d
leaq 0xcd0(%rip), %rdi       # 0x20dd
movl %r14d, %esi
xorl %eax, %eax
callq 0x1090
testl %r14d, %r14d
je 0x14f3
movl $0x4, %r15d
leaq 0xcc5(%rip), %rbp       # 0x20f2
movq %rbp, %rdi
movl %r15d, %esi
xorl %eax, %eax
callq 0x1090
movl %r15d, %r13d
addq %rbx, %r13
movq %r13, %rdi
callq 0x1080
movq %rax, %r12
incl %eax
leal (%r12,%r15), %ecx
incl %ecx
andl $0x3, %ecx
subl %ecx, %r12d
addl $0x5, %r12d
testl %ecx, %ecx
cmovel %eax, %r12d
addl %r15d, %r12d
movq %rbp, %rdi
movl %r12d, %esi
xorl %eax, %eax
callq 0x1090
movl (%rbx,%r12), %edx
leaq 0xc81(%rip), %rdi       # 0x20ff
movq %r13, %rsi
xorl %eax, %eax
callq 0x1090
movq %r13, %rdi
leaq 0xc8b(%rip), %rsi       # 0x211d
callq 0x10d0
testq %rax, %rax
je 0x153c
movq %rax, %r15
leal 0x4(%r12), %eax
andl $0xf, %eax
movl $0x14, %r13d
subl %eax, %r13d
testl %eax, %eax
movl $0x4, %eax
cmovel %eax, %r13d
addl %r12d, %r13d
leaq (%rbx,%r13), %rdi
movl (%rbx,%r12), %esi
movl $0x1, %edx
movq %r15, %rcx
callq 0x10f0
movq %r15, %rdi
callq 0x1060
movl (%rbx,%r12), %eax
leal (%rax,%r13), %r15d
incl %r15d
decl %r14d
jne 0x1426
movq %rbx, %rdi
callq 0x1030
leaq 0xc36(%rip), %rdi       # 0x2138
callq 0x1040
xorl %eax, %eax
jmp 0x152d
leaq 0xcb1(%rip), %rdi       # 0x21c3
callq 0x1040
leaq 0xbaf(%rip), %rdi       # 0x20cd
movl %r15d, %esi
xorl %eax, %eax
callq 0x1090
movl $0x1, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xbdd(%rip), %rdi       # 0x2120
movq %r13, %rsi
jmp 0x13e6