#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
typedef int /*<<< orphan*/ FILE;

/* Variables and functions */
int /*<<< orphan*/ SEEK_SET;
int /*<<< orphan*/ fread(unsigned char *, int, long, int /*<<< orphan*/ *);
int /*<<< orphan*/ free(unsigned char *);
int /*<<< orphan*/ fseek(int /*<<< orphan*/ *, int, int /*<<< orphan*/);
int /*<<< orphan*/ fwrite(unsigned char *, int, long, int /*<<< orphan*/ *);
int get_filesize(int /*<<< orphan*/ *);
long get_uncompressed_size(int /*<<< orphan*/ *);
scalar_t__ is_valid_lzw_file(int /*<<< orphan*/ *);
int /*<<< orphan*/ lzw_decompress_b(unsigned char *, long, unsigned char *,
                                    long);
scalar_t__ malloc(int);
void lzw_decompress(FILE *input_file, FILE *output_file) {
  unsigned char *source_buffer;
  unsigned char *destination_buffer;
  long source_buffer_size;
  long destination_buffer_size;
  if (is_valid_lzw_file(input_file)) {
    source_buffer_size = get_filesize(input_file) - 4;
    destination_buffer_size = get_uncompressed_size(input_file);
    source_buffer =
        (unsigned char *)malloc(sizeof(unsigned char *) * source_buffer_size);
    destination_buffer = (unsigned char *)malloc(sizeof(unsigned char *) *
                                                 destination_buffer_size);
    fseek(input_file, 4, SEEK_SET);
    fread(source_buffer, 1, source_buffer_size, input_file);
    lzw_decompress_b(source_buffer, source_buffer_size, destination_buffer,
                     destination_buffer_size);
    fwrite(destination_buffer, 1, destination_buffer_size, output_file);
    free(source_buffer);
    free(destination_buffer);
  }
}


x86 assembly (clang, -O0):
<lzw_decompress>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    -0x8(%rbp),%rdi
call   10b0 <is_valid_lzw_file@plt>
cmp    $0x0,%rax
je     1262 <lzw_decompress+0xd2>
mov    -0x8(%rbp),%rdi
call   10a0 <get_filesize@plt>
sub    $0x4,%eax
cltq
mov    %rax,-0x28(%rbp)
mov    -0x8(%rbp),%rdi
call   1050 <get_uncompressed_size@plt>
mov    %rax,-0x30(%rbp)
mov    -0x28(%rbp),%rax
shl    $0x3,%rax
mov    %eax,%edi
call   1070 <malloc@plt>
mov    %rax,-0x18(%rbp)
mov    -0x30(%rbp),%rax
shl    $0x3,%rax
mov    %eax,%edi
call   1070 <malloc@plt>
mov    %rax,-0x20(%rbp)
mov    -0x8(%rbp),%rdi
mov    0x2ddd(%rip),%rax
mov    (%rax),%edx
mov    $0x4,%esi
call   1080 <fseek@plt>
mov    -0x18(%rbp),%rdi
mov    -0x28(%rbp),%rdx
mov    -0x8(%rbp),%rcx
mov    $0x1,%esi
call   1040 <fread@plt>
mov    -0x18(%rbp),%rdi
mov    -0x28(%rbp),%rsi
mov    -0x20(%rbp),%rdx
mov    -0x30(%rbp),%rcx
call   1060 <lzw_decompress_b@plt>
mov    -0x20(%rbp),%rdi
mov    -0x30(%rbp),%rdx
mov    -0x10(%rbp),%rcx
mov    $0x1,%esi
call   1090 <fwrite@plt>
mov    -0x18(%rbp),%rdi
call   1030 <free@plt>
mov    -0x20(%rbp),%rdi
call   1030 <free@plt>
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<lzw_decompress>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
push   %rax
mov    %rsi,%r14
mov    %rdi,%rbx
call   10b0 <is_valid_lzw_file@plt>
test   %rax,%rax
je     1254 <lzw_decompress+0xc4>
mov    %rbx,%rdi
call   10a0 <get_filesize@plt>
mov    %eax,%ebp
lea    -0x4(%rbp),%eax
movslq %eax,%r13
mov    %rbx,%rdi
call   1050 <get_uncompressed_size@plt>
mov    %rax,%r15
lea    -0x20(,%rbp,8),%edi
call   1070 <malloc@plt>
mov    %rax,%r12
lea    0x0(,%r15,8),%edi
call   1070 <malloc@plt>
mov    %rax,%rbp
mov    0x2df0(%rip),%rax
mov    (%rax),%edx
mov    %rbx,%rdi
mov    $0x4,%esi
call   1080 <fseek@plt>
mov    %r12,%rdi
mov    $0x1,%esi
mov    %r13,%rdx
mov    %rbx,%rcx
call   1040 <fread@plt>
mov    %r12,%rdi
mov    %r13,%rsi
mov    %rbp,%rdx
mov    %r15,%rcx
call   1060 <lzw_decompress_b@plt>
mov    %rbp,%rdi
mov    $0x1,%esi
mov    %r15,%rdx
mov    %r14,%rcx
call   1090 <fwrite@plt>
mov    %r12,%rdi
call   1030 <free@plt>
mov    %rbp,%rdi
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
jmp    1030 <free@plt>
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@SEEK_SET = global i32 0
define void @lzw_decompress(i32* %0, i32* %1) {
%3 = alloca i32*
%4 = alloca i32*
%5 = alloca i8*
%6 = alloca i8*
%7 = alloca i64
%8 = alloca i64
store i32* %0, i32** %3
store i32* %1, i32** %4
%9 = load i32*, i32** %3
%10 = call i64 @is_valid_lzw_file(i32* %9)
%11 = icmp ne i64 %10, 0
br i1 %11, label %12, label %49
12: ; preds = %2
%13 = load i32*, i32** %3
%14 = call i32 @get_filesize(i32* %13)
%15 = sub nsw i32 %14, 4
%16 = sext i32 %15 to i64
store i64 %16, i64* %7
%17 = load i32*, i32** %3
%18 = call i64 @get_uncompressed_size(i32* %17)
store i64 %18, i64* %8
%19 = load i64, i64* %7
%20 = mul i64 8, %19
%21 = trunc i64 %20 to i32
%22 = call i64 @malloc(i32 %21)
%23 = inttoptr i64 %22 to i8*
store i8* %23, i8** %5
%24 = load i64, i64* %8
%25 = mul i64 8, %24
%26 = trunc i64 %25 to i32
%27 = call i64 @malloc(i32 %26)
%28 = inttoptr i64 %27 to i8*
store i8* %28, i8** %6
%29 = load i32*, i32** %3
%30 = load i32, i32* @SEEK_SET
%31 = call i32 @fseek(i32* %29, i32 4, i32 %30)
%32 = load i8*, i8** %5
%33 = load i64, i64* %7
%34 = load i32*, i32** %3
%35 = call i32 @fread(i8* %32, i32 1, i64 %33, i32* %34)
%36 = load i8*, i8** %5
%37 = load i64, i64* %7
%38 = load i8*, i8** %6
%39 = load i64, i64* %8
%40 = call i32 @lzw_decompress_b(i8* %36, i64 %37, i8* %38, i64 %39)
%41 = load i8*, i8** %6
%42 = load i64, i64* %8
%43 = load i32*, i32** %4
%44 = call i32 @fwrite(i8* %41, i32 1, i64 %42, i32* %43)
%45 = load i8*, i8** %5
%46 = call i32 @free(i8* %45)
%47 = load i8*, i8** %6
%48 = call i32 @free(i8* %47)
br label %49
49: ; preds = %12, %2
ret void
}

LLVM IR (-O2):
@SEEK_SET = global i32 0
define void @lzw_decompress(i32* %0, i32* nocapture %1) {
%3 = tail call i64 @is_valid_lzw_file(i32* %0)
%4 = icmp eq i64 %3, 0
br i1 %4, label %24, label %5
5: ; preds = %2
%6 = tail call i32 @get_filesize(i32* %0)
%7 = add nsw i32 %6, -4
%8 = sext i32 %7 to i64
%9 = tail call i64 @get_uncompressed_size(i32* %0)
%10 = shl i32 %7, 3
%11 = tail call i64 @malloc(i32 %10)
%12 = inttoptr i64 %11 to i8*
%13 = trunc i64 %9 to i32
%14 = shl i32 %13, 3
%15 = tail call i64 @malloc(i32 %14)
%16 = inttoptr i64 %15 to i8*
%17 = load i32, i32* @SEEK_SET
%18 = tail call i32 @fseek(i32* %0, i32 4, i32 %17)
%19 = tail call i32 @fread(i8* %12, i32 1, i64 %8, i32* %0)
%20 = tail call i32 @lzw_decompress_b(i8* %12, i64 %8, i8* %16, i64 %9)
%21 = tail call i32 @fwrite(i8* %16, i32 1, i64 %9, i32* %1)
%22 = tail call i32 @free(i8* %12)
%23 = tail call i32 @free(i8* %16)
br label %24
24: ; preds = %5, %2
ret void
}