inside

decompiled_code:
_BOOL8 __fastcall inside(float *a1, double a2, float a3)
{
_BOOL8 result; // rax

result = 0LL;
if ( *a1 < *(float *)&a2 )
result = *(float *)&a2 < a1[1];
if ( a1[2] >= *((float *)&a2 + 1) )
{
result = 0LL;
}
else if ( *((float *)&a2 + 1) >= a1[3] )
{
result = 0LL;
}
if ( a1[4] >= a3 )
return 0LL;
if ( a3 >= a1[5] )
result = 0LL;
return result;
}

canonical_decompiled_code:
_BOOL8 __fastcall func6(float *a1, double a2, float a3)
{
_BOOL8 result; // rax

result = 0LL;
if ( *a1 < *(float *)&a2 )
result = *(float *)&a2 < a1[1];
if ( a1[2] >= *((float *)&a2 + 1) )
{
result = 0LL;
}
else if ( *((float *)&a2 + 1) >= a1[3] )
{
result = 0LL;
}
if ( a1[4] >= a3 )
return 0LL;
if ( a3 >= a1[5] )
result = 0LL;
return result;
}

original_code:
int inside(Coord pos, Ranges* r){
  int i = 1;
  if(pos.x <= r->xmin || pos.x >= r->xmax){
    i = 0;
  }
  if(pos.y <= r->ymin || pos.y >= r->ymax){
    i = 0;
  }
  if(pos.z <= r->zmin || pos.z >= r->zmax){
    i = 0;
  }
  return i;
}

canonical_original_code:
int inside(struct Coord pos, struct Ranges *r){
  int i = 1;
  if(pos.x <= r->xmin || pos.x >= r->xmax){
    i = 0;
  }
  if(pos.y <= r->ymin || pos.y >= r->ymax){
    i = 0;
  }
  if(pos.z <= r->zmin || pos.z >= r->zmax){
    i = 0;
  }
  return i;
}

variable_types: struct Ranges { float xmin; float xmax; float ymin; float ymax; float zmin; float zmax; float imin; float imax; } *

variable_types: i int


repo: acelster/scatter-pt-viz

decompiled_code:
float __fastcall angle_between_Coords(double a1, float a2, double a3, float a4)
{
float v4; // ebx
float v5; // xmm0_4
float v6; // xmm1_4
float v7; // xmm0_4
float v9; // [rsp+8h] [rbp-50h]

v4 = *(float *)&a1;
v5 = (float)((float)(*(float *)&a1 * *(float *)&a1) + (float)(*((float *)&a1 + 1) * *((float *)&a1 + 1)))
+ (float)(a2 * a2);
if ( v5 < 0.0 )
v9 = sqrtf(v5);
else
v9 = fsqrt(v5);
v6 = (float)(a4 * a4)
+ (float)((float)(*(float *)&a3 * *(float *)&a3) + (float)(*((float *)&a3 + 1) * *((float *)&a3 + 1)));
if ( v6 < 0.0 )
sqrtf(v6);
else
v6 = fsqrt(v6);
v7 = (float)((float)((float)(v4 * *(float *)&a3) + (float)(*((float *)&a1 + 1) * *((float *)&a3 + 1)))
+ (float)(a2 * a4))
/ (float)(v6 * v9);
if ( v7 > 1.0 )
v7 = *(float *)&LC1;
return acos(v7);
}

canonical_decompiled_code:
float __fastcall func7(double a1, float a2, double a3, float a4)
{
float v4; // ebx
float v5; // xmm0_4
float v6; // xmm1_4
float v7; // xmm0_4
float v9; // [rsp+8h] [rbp-50h]

v4 = *(float *)&a1;
v5 = (float)((float)(*(float *)&a1 * *(float *)&a1) + (float)(*((float *)&a1 + 1) * *((float *)&a1 + 1)))
+ (float)(a2 * a2);
if ( v5 < 0.0 )
v9 = sqrtf(v5);
else
v9 = fsqrt(v5);
v6 = (float)(a4 * a4)
+ (float)((float)(*(float *)&a3 * *(float *)&a3) + (float)(*((float *)&a3 + 1) * *((float *)&a3 + 1)));
if ( v6 < 0.0 )
sqrtf(v6);
else
v6 = fsqrt(v6);
v7 = (float)((float)((float)(v4 * *(float *)&a3) + (float)(*((float *)&a1 + 1) * *((float *)&a3 + 1)))
+ (float)(a2 * a4))
/ (float)(v6 * v9);
if ( v7 > 1.0 )
v7 = *(float *)&LC1;
return acos(v7);
}

original_code:
float angle_between_Coords(Coord a, Coord b){
  float abs_a = sqrt(a.x*a.x + a.y*a.y + a.z*a.z);
  float abs_b = sqrt(b.x*b.x + b.y*b.y + b.z*b.z);
  float dot_p = a.x*b.x + a.y*b.y + a.z*b.z;
  float temp = dot_p/(abs_a * abs_b);
  temp = (temp > 1.0) ? 1.0 : temp;
  float angle = acos(temp);
  return angle;
}

canonical_original_code:
float angle_between_Coords(struct Coord a, struct Coord b){
  float abs_a = sqrt(a.x*a.x + a.y*a.y + a.z*a.z);
  float abs_b = sqrt(b.x*b.x + b.y*b.y + b.z*b.z);
  float dot_p = a.x*b.x + a.y*b.y + a.z*b.z;
  float temp = dot_p/(abs_a * abs_b);
  temp = (temp > 1.0) ? 1.0 : temp;
  float angle = acos(temp);
  return angle;
}

variable_types: struct Coord { float x; float y; float z; }

variable_types:
b
struct Coord

variable_types: temp float

variable_types: angle float

return_type: float


decompiled_code:
float __fastcall length_Coord(double a1, float a2)
{
float v2; // xmm0_4
float result; // xmm0_4

v2 = (float)((float)(*(float *)&a1 * *(float *)&a1) + (float)(*((float *)&a1 + 1) * *((float *)&a1 + 1)))
+ (float)(a2 * a2);
if ( v2 < 0.0 )
result = sqrtf(v2);
else
result = fsqrt(v2);
return result;
}

canonical_decompiled_code:
float __fastcall func8(double a1, float a2)
{
float v2; // xmm0_4
float result; // xmm0_4

v2 = (float)((float)(*(float *)&a1 * *(float *)&a1) + (float)(*((float *)&a1 + 1) * *((float *)&a1 + 1)))
+ (float)(a2 * a2);
if ( v2 < 0.0 )
result = sqrtf(v2);
else
result = fsqrt(v2);
return result;
}

original_code:
float length_Coord(Coord c){
  return sqrt(c.x*c.x + c.y*c.y + c.z*c.z);
}

canonical_original_code:
float length_Coord(struct Coord c){
  return sqrt(c.x*c.x + c.y*c.y + c.z*c.z);
}

user_defined_types: struct Coord { float x; float y; float z; }


decompiled_code:
__m128i __fastcall cross_product(double a1, float a2, double a3, float a4)
{
__m128i v5; // [rsp+24h] [rbp-14h] BYREF

*(float *)v5.m128i_i32 = (float)(*((float *)&a1 + 1) * a4) - (float)(a2 * *((float *)&a3 + 1));
*(float *)&v5.m128i_i32[1] = (float)(a2 * *(float *)&a3) - (float)(a4 * *(float *)&a1);
return _mm_loadl_epi64(&v5);
}

canonical_decompiled_code:
__m128i __fastcall func9(double a1, float a2, double a3, float a4)
{
__m128i v5; // [rsp+24h] [rbp-14h] BYREF

*(float *)v5.m128i_i32 = (float)(*((float *)&a1 + 1) * a4) - (float)(a2 * *((float *)&a3 + 1));
*(float *)&v5.m128i_i32[1] = (float)(a2 * *(float *)&a3) - (float)(a4 * *(float *)&a1);
return _mm_loadl_epi64(&v5);
}

original_code:
Coord cross_product(Coord a, Coord b){
  Coord r;
  r.x = a.y*b.z - a.z*b.y;
  r.y = a.z*b.x - a.x*b.z;
  r.z = a.x*b.y - a.y*b.x;
  return r;
}

canonical_original_code:
struct Coord cross_product(struct Coord a, struct Coord b){
  struct Coord r;
  r.x = a.y*b.z - a.z*b.y;
  r.y = a.z*b.x - a.x*b.z;
  r.z = a.x*b.y - a.y*b.x;
  return r;
}

variable_types:
a
struct Coord

return_type: struct Coord { float x; float y; float z; }


decompiled_code:
float __fastcall distance_Coord(double a1, float a2, double a3, float a4)
{
float v4; // xmm0_4
float result; // xmm0_4

v4 = (float)((float)((float)(*(float *)&a1 - *(float *)&a3) * (float)(*(float *)&a1 - *(float *)&a3))
+ (float)((float)(*((float *)&a1 + 1) - *((float *)&a3 + 1))
* (float)(*((float *)&a1 + 1) - *((float *)&a3 + 1))))
+ (float)((float)(a2 - a4) * (float)(a2 - a4));
if ( v4 < 0.0 )
result = sqrtf(v4);
else
result = fsqrt(v4);
return result;
}

canonical_decompiled_code:
float __fastcall func10(double a1, float a2, double a3, float a4)
{
float v4; // xmm0_4
float result; // xmm0_4

v4 = (float)((float)((float)(*(float *)&a1 - *(float *)&a3) * (float)(*(float *)&a1 - *(float *)&a3))
+ (float)((float)(*((float *)&a1 + 1) - *((float *)&a3 + 1))
* (float)(*((float *)&a1 + 1) - *((float *)&a3 + 1))))
+ (float)((float)(a2 - a4) * (float)(a2 - a4));
if ( v4 < 0.0 )
result = sqrtf(v4);
else
result = fsqrt(v4);
return result;
}

original_code:
float distance_Coord(Coord a, Coord b){
  float dx = a.x - b.x;
  float dy = a.y - b.y;
  float dz = a.z - b.z;
  return sqrt(dx*dx + dy*dy + dz*dz);
}

canonical_original_code:
float distance_Coord(struct Coord a, struct Coord b){
  float dx = a.x - b.x;
  float dy = a.y - b.y;
  float dz = a.z - b.z;
  return sqrt(dx*dx + dy*dy + dz*dz);
}

variable_types: dx float

variable_types: dy float

variable_types: dz float


decompiled_code:
int __fastcall print_point(__m128i a1, double a2)
{
printf("x: %f\n", COERCE_FLOAT(_mm_cvtsi128_si32(a1)));
printf("y: %f\n", *(float *)&a1.m128i_i32[1]);
printf("z: %f\n", *(float *)&a2);
return printf("intensity: %f\n", *((float *)&a2 + 1));
}

canonical_decompiled_code:
int __fastcall func11(__m128i a1, double a2)
{
printf("x: %f\n", COERCE_FLOAT(_mm_cvtsi128_si32(a1)));
printf("y: %f\n", *(float *)&a1.m128i_i32[1]);
printf("z: %f\n", *(float *)&a2);
return printf("intensity: %f\n", *((float *)&a2 + 1));
}

original_code:
void print_point(Point p){
  printf("x: %f\n", p.x);
  printf("y: %f\n", p.y);
  printf("z: %f\n", p.z);
  printf("intensity: %f\n", p.intensity);
}

canonical_original_code:
void print_point(struct Point p){
  printf("x: %f\n", p.x);
  printf("y: %f\n", p.y);
  printf("z: %f\n", p.z);
  printf("intensity: %f\n", p.intensity);
}

variable_types: struct Point { float x; float y; float z; float intensity; }

return_type: void


decompiled_code:
int __fastcall print_coord(double a1, float a2)
{
printf("x: %f\n", *(float *)&a1);
printf("y: %f\n", *((float *)&a1 + 1));
return printf("z: %f\n", a2);
}

canonical_decompiled_code:
int __fastcall func12(double a1, float a2)
{
printf("x: %f\n", *(float *)&a1);
printf("y: %f\n", *((float *)&a1 + 1));
return printf("z: %f\n", a2);
}

original_code:
void print_coord(Coord p){
  printf("x: %f\n", p.x);
  printf("y: %f\n", p.y);
  printf("z: %f\n", p.z);
}

canonical_original_code:
void print_coord(struct Coord p){
  printf("x: %f\n", p.x);
  printf("y: %f\n", p.y);
  printf("z: %f\n", p.z);
}


decompiled_code:
int __fastcall print_ranges(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, __int64 a7, __int64 a8, __int64 a9, __int64 a10)
{
printf("xmin: %f\n", *(float *)&a7);
printf("xmax: %f\n", *((float *)&a7 + 1));
printf("ymin: %f\n", *(float *)&a8);
printf("ymax: %f\n", *((float *)&a8 + 1));
printf("zmin: %f\n", *(float *)&a9);
printf("zmax: %f\n", *((float *)&a9 + 1));
printf("imin: %f\n", *(float *)&a10);
return printf("imax: %f\n", *((float *)&a10 + 1));
}

original_code:
void print_ranges(Ranges r){
  printf("xmin: %f\n", r.xmin);
  printf("xmax: %f\n", r.xmax);
  printf("ymin: %f\n", r.ymin);
  printf("ymax: %f\n", r.ymax);
  printf("zmin: %f\n", r.zmin);
  printf("zmax: %f\n", r.zmax);
  printf("imin: %f\n", r.imin);
  printf("imax: %f\n", r.imax);
}

canonical_original_code:
void print_ranges(struct Ranges r){
  printf("xmin: %f\n", r.xmin);
  printf("xmax: %f\n", r.xmax);
  printf("ymin: %f\n", r.ymin);
  printf("ymax: %f\n", r.ymax);
  printf("zmin: %f\n", r.zmin);
  printf("zmax: %f\n", r.zmax);
  printf("imin: %f\n", r.imin);
  printf("imax: %f\n", r.imax);
}

variable_types: struct Ranges { float xmin; float xmax; float ymin; float ymax; float zmin; float zmax; float imin; float imax; }


original_code:
void print_histogram(PointList* pl, Ranges* r, int no_buckets){
  int* buckets = (int*)calloc(no_buckets, sizeof(int));
  for(int c = 0; c < pl->index; c++){
    int i = floor(no_buckets * (pl->points[c].intensity - r->imin)/(r->imax - r->imin));
    if(i == no_buckets){
      i--;
    }
    buckets[i]++;
  }
  float cum_pct = 0;
  for(int c = 0; c < no_buckets; c++){
    float pct = (float)buckets[c]/(float)pl->index;
    cum_pct += pct;
    printf("%d\t\t%10.2f - %.2f\t\t%d\t%0.4f\t%0.4f\n",
        c,
        ((r->imax -r->imin)/no_buckets) * c + r->imin,
        ((r->imax -r->imin)/no_buckets) * (c + 1) + r->imin,
        buckets[c],
        pct,
        cum_pct);
    if(cum_pct >= 0.999){
      break;
    }
  }
}

canonical_original_code:
void print_histogram(struct PointList *pl, struct Ranges *r, int no_buckets){
  int *buckets = (int*)calloc(no_buckets, sizeof(int));
  for(int c = 0; c < pl->index; c++){
    int i = floor(no_buckets * (pl->points[c].intensity - r->imin)/(r->imax - r->imin));
    if(i == no_buckets){
      i--;
    }
    buckets[i]++;
  }
  float cum_pct = 0;
  for(int c = 0; c < no_buckets; c++){
    float pct = (float)buckets[c]/(float)pl->index;
    cum_pct += pct;
    printf("%d\t\t%10.2f - %.2f\t\t%d\t%0.4f\t%0.4f\n",
        c,
        ((r->imax -r->imin)/no_buckets) * c + r->imin,
        ((r->imax -r->imin)/no_buckets) * (c + 1) + r->imin,
        buckets[c],
        pct,
        cum_pct);
    if(cum_pct >= 0.999){
      break;
    }
  }
}

variable_types: struct PointList { struct Point { float x; float y; float z; float intensity; } *points; int index; } *

variable_types:
buckets
int *

variable_types: c int

variable_types: pct float

user_defined_types: struct PointList { struct Point *points; int index; }

user_defined_types: struct Ranges { float xmin; float xmax; float ymin; float ymax; float zmin; float zmax; float imin; float imax; }


decompiled_code:
__int64 set_default_values()
{
int *v0; // rax
__int64 result; // rax

v0 = ANISO_MATRIX;
do
*v0++ = 0;
while ( v0 != (int *)(unsigned int)((_DWORD)ANISO_MATRIX + 36) );
ANISO_MATRIX[0] = LC1;
ANISO_MATRIX[4] = LC1;
ANISO_MATRIX[8] = LC1;
INTERPOLATION_RADIUS = 990057071;
RESOLUTION = 512;
NEIGHBOUR_MODE = 1;
INTERPOLATION_MODE = 1;
STEP_SIZE = 1028443341;
NUMBERS = 1;
GRID_ON = 1;
EYE_INITIAL = sqrtf(-1.0);
FORWARD_INITIAL = sqrtf(-1.0);
strcpy(DEFAULT_FOLDER, "/home/data");
GRID_BASE = 1;
GRID_SPACING = -1082130432;
result = sysconf(84);
NUM_THREADS = result;
VERBOSE = 1;
FILTERING_THRESHOLD = 0;
MEDIAN_FILTERING = 0;
ANISOTROPIC = 0;
COLOR_BANDS = 11;
DATA_STRUCTURE = 0;
STEP_LIMIT = 1025758986;
STEP_FACTOR = 0x40000000;
OPACITY_THRESHOLD = 1065185444;
THRESHOLD_MEDIAN_FILTER = 1097859072;
VARIOGRAM_RADIUS = 925353388;
BATCH_SIZE = 1315859240;
return result;
}

canonical_decompiled_code:
__int64 func0()
{
int *v0; // rax
__int64 result; // rax

v0 = ANISO_MATRIX;
do
*v0++ = 0;
while ( v0 != (int *)(unsigned int)((_DWORD)ANISO_MATRIX + 36) );
ANISO_MATRIX[0] = LC1;
ANISO_MATRIX[4] = LC1;
ANISO_MATRIX[8] = LC1;
INTERPOLATION_RADIUS = 990057071;
RESOLUTION = 512;
NEIGHBOUR_MODE = 1;
INTERPOLATION_MODE = 1;
STEP_SIZE = 1028443341;
NUMBERS = 1;
GRID_ON = 1;
EYE_INITIAL = sqrtf(-1.0);
FORWARD_INITIAL = sqrtf(-1.0);
strcpy(DEFAULT_FOLDER, "/home/data");
GRID_BASE = 1;
GRID_SPACING = -1082130432;
result = sysconf(84);
NUM_THREADS = result;
VERBOSE = 1;
FILTERING_THRESHOLD = 0;
MEDIAN_FILTERING = 0;
ANISOTROPIC = 0;
COLOR_BANDS = 11;
DATA_STRUCTURE = 0;
STEP_LIMIT = 1025758986;
STEP_FACTOR = 0x40000000;
OPACITY_THRESHOLD = 1065185444;
THRESHOLD_MEDIAN_FILTER = 1097859072;
VARIOGRAM_RADIUS = 925353388;
BATCH_SIZE = 1315859240;
return result;
}

original_code:
void set_default_values(){
  for(int c = 0; c < 9; c++){
    ANISO_MATRIX[c] = 0.0;
  }
  ANISO_MATRIX[0] = 1.0;
  ANISO_MATRIX[4] = 1.0;
  ANISO_MATRIX[8] = 1.0;
  INTERPOLATION_RADIUS = 0.002;
  RESOLUTION = 512;
  NEIGHBOUR_MODE = 1;
  INTERPOLATION_MODE = 1;
  STEP_SIZE = 0.05;
  NUMBERS = 1;
  GRID_ON = 1;
  EYE_INITIAL.x = sqrt(-1);
  FORWARD_INITIAL.x = sqrt(-1);
  char* temp_default_folder = "/home/data";
  strcpy(DEFAULT_FOLDER, temp_default_folder);
  GRID_BASE = 1;
  GRID_SPACING = -1;
  NUM_THREADS = sysconf(_SC_NPROCESSORS_ONLN);
  VERBOSE = 1;
  FILTERING_THRESHOLD = 0;
  MEDIAN_FILTERING = 0;
  ANISOTROPIC = 0;
  COLOR_BANDS=11;
  DATA_STRUCTURE=0;
  STEP_LIMIT = 0.04;
  STEP_FACTOR = 2.0;
  OPACITY_THRESHOLD = 0.99;
  THRESHOLD_MEDIAN_FILTER = 15;
  VARIOGRAM_RADIUS = 0.00001;
  BATCH_SIZE = 1e9;
}

canonical_original_code:
void set_default_values(){
  for(int c = 0; c < 9; c++){
    ANISO_MATRIX[c] = 0.0;
  }
  ANISO_MATRIX[0] = 1.0;
  ANISO_MATRIX[4] = 1.0;
  ANISO_MATRIX[8] = 1.0;
  INTERPOLATION_RADIUS = 0.002;
  RESOLUTION = 512;
  NEIGHBOUR_MODE = 1;
  INTERPOLATION_MODE = 1;
  STEP_SIZE = 0.05;
  NUMBERS = 1;
  GRID_ON = 1;
  EYE_INITIAL.x = sqrt(-1);
  FORWARD_INITIAL.x = sqrt(-1);
  char *temp_default_folder = "/home/data";
  strcpy(DEFAULT_FOLDER, temp_default_folder);
  GRID_BASE = 1;
  GRID_SPACING = -1;
  NUM_THREADS = sysconf(_SC_NPROCESSORS_ONLN);
  VERBOSE = 1;
  FILTERING_THRESHOLD = 0;
  MEDIAN_FILTERING = 0;
  ANISOTROPIC = 0;
  COLOR_BANDS=11;
  DATA_STRUCTURE=0;
  STEP_LIMIT = 0.04;
  STEP_FACTOR = 2.0;
  OPACITY_THRESHOLD = 0.99;
  THRESHOLD_MEDIAN_FILTER = 15;
  VARIOGRAM_RADIUS = 0.00001;
  BATCH_SIZE = 1e9;
}


decompiled_code:
__int64 __fastcall parse_args(unsigned int a1, __int64 a2)
{
__int64 result; // rax
unsigned int v3; // er12

BATCH = 0;
FILEARG = 0;
SINGLE = 0;
opterr = 0;
while ( 1 )
{
result = _posix_getopt(a1, a2, "sbf:");
if ( (_DWORD)result == -1 )
return result;
if ( (_DWORD)result == 102 )
{
FILEARG = 1;
FILENAME = (__int64)optarg;
}
else if ( (int)result > 102 )
{
if ( (_DWORD)result != 115 )
goto LABEL_16;
SINGLE = 1;
}
else if ( (_DWORD)result == 63 )
{
v3 = optopt;
if ( optopt == 102 )
{
fwrite("ERROR: Option -f requires an argument. Exiting.\n", 1uLL, 0x30uLL, stderr);
exit(-1);
}
if ( ((*_ctype_b_loc())[v3] & 0x4000) != 0 )
fprintf(stderr, "ERROR: Unknown option '-%c'.\n", v3);
else
fprintf(stderr, "ERROR: Unknown option character '\\x%x.\n", v3);
}
else
{
if ( (_DWORD)result != 98 )
LABEL_16:
exit(-1);
BATCH = 1;
}
}
}

canonical_decompiled_code:
__int64 __fastcall func2(unsigned int a1, __int64 a2)
{
__int64 result; // rax
unsigned int v3; // er12

BATCH = 0;
FILEARG = 0;
SINGLE = 0;
opterr = 0;
while ( 1 )
{
result = _posix_getopt(a1, a2, "sbf:");
if ( (_DWORD)result == -1 )
return result;
if ( (_DWORD)result == 102 )
{
FILEARG = 1;
FILENAME = (__int64)optarg;
}
else if ( (int)result > 102 )
{
if ( (_DWORD)result != 115 )
goto LABEL_16;
SINGLE = 1;
}
else if ( (_DWORD)result == 63 )
{
v3 = optopt;
if ( optopt == 102 )
{
fwrite("ERROR: Option -f requires an argument. Exiting.\n", 1uLL, 0x30uLL, stderr);
exit(-1);
}
if ( ((*_ctype_b_loc())[v3] & 0x4000) != 0 )
fprintf(stderr, "ERROR: Unknown option '-%c'.\n", v3);
else
fprintf(stderr, "ERROR: Unknown option character '\\x%x.\n", v3);
}
else
{
if ( (_DWORD)result != 98 )
LABEL_16:
exit(-1);
BATCH = 1;
}
}
}

original_code:
void parse_args(int argc, char** argv){
  BATCH = 0;
  FILEARG = 0;
  SINGLE = 0;
  opterr = 0;
  int c;
  while((c = getopt(argc, argv, "sbf:")) != -1){
    switch(c){
      case 's':
        SINGLE = 1;
        break;
      case 'b':
        BATCH = 1;
        break;
      case 'f':
        FILEARG = 1;
        FILENAME = optarg;
        break;
      case '?':
        if(optopt == 'f'){
          fprintf(stderr, "ERROR: Option -f requires an argument. Exiting.\n");
          exit(-1);
        }
        else if(((*__ctype_b_loc ())[(int) ((optopt))] & (unsigned short int) _ISprint))
          fprintf(stderr, "ERROR: Unknown option '-%c'.\n", optopt);
        else
          fprintf(stderr, "ERROR: Unknown option character '\\x%x.\n", optopt);
        break;
      default:
        exit(-1);
    }
  }
}

canonical_original_code:
void parse_args(int argc, char **argv){
  BATCH = 0;
  FILEARG = 0;
  SINGLE = 0;
  opterr = 0;
  int c;
  while((c = getopt(argc, argv, "sbf:")) != -1){
    switch(c){
      case 's':
        SINGLE = 1;
        break;
      case 'b':
        BATCH = 1;
        break;
      case 'f':
        FILEARG = 1;
        FILENAME = optarg;
        break;
      case '?':
        if(optopt == 'f'){
          fprintf(stderr, "ERROR: Option -f requires an argument. Exiting.\n");
          exit(-1);
        }
        else if(((*__ctype_b_loc ())[(int) ((optopt))] & (unsigned short) _ISprint))
          fprintf(stderr, "ERROR: Unknown option '-%c'.\n", optopt);
        else
          fprintf(stderr, "ERROR: Unknown option character '\\x%x.\n", optopt);
        break;
      default:
        exit(-1);
    }
  }
}

variable_types: argc int

variable_types:
argv
char **


decompiled_code:
int __fastcall timer_start(const char *a1)
{
printf("%s", a1);
return clock_gettime(1, &start);
}

canonical_decompiled_code:
int __fastcall func0(const char *a1)
{
printf("%s", a1);
return clock_gettime(1, &start);
}

original_code:
void timer_start(char* message){
  printf("%s", message);
  clock_gettime(1, &start);
}

canonical_original_code:
void timer_start(char *message){
  printf("%s", message);
  clock_gettime(1, &start);
}

variable_types:
message
char *


decompiled_code:
double timer_end()
{
double v0; // rbx

clock_gettime(1, &end);
v0 = (double)(int)((double)(LODWORD(end.tv_sec) - LODWORD(start.tv_sec)) * 1000000000.0
+ (double)(LODWORD(end.tv_nsec) - LODWORD(start.tv_nsec)))
/ 1000000000.0;
printf("DONE in %f s\n\n", v0);
return v0;
}

canonical_decompiled_code:
double func1()
{
double v0; // rbx

clock_gettime(1, &end);
v0 = (double)(int)((double)(LODWORD(end.tv_sec) - LODWORD(start.tv_sec)) * 1000000000.0
+ (double)(LODWORD(end.tv_nsec) - LODWORD(start.tv_nsec)))
/ 1000000000.0;
printf("DONE in %f s\n\n", v0);
return v0;
}

original_code:
double timer_end(){
  clock_gettime(1, &end);
  long nsec = (end.tv_sec - start.tv_sec)*1e9 + (end.tv_nsec - start.tv_nsec);
  double sec = (double)nsec/1e9;
  printf("DONE in %f s\n\n", sec);
  return sec;
}

variable_types: nsec long

variable_types: sec double

return_type: double


decompiled_code:
void __fastcall init_lasso(__int64 a1)
{
*(_DWORD *)(a1 + 16) = 0;
}

canonical_decompiled_code:
void __fastcall func0(__int64 a1)
{
*(_DWORD *)(a1 + 16) = 0;
}

original_code:
void init_lasso(Lasso* l){
  l->active = 0;
}

canonical_original_code:
void init_lasso(struct Lasso *l){
  l->active = 0;
}

variable_types: struct Lasso { int start_x; int start_y; int end_x; int end_y; int active; struct Quad { float x; float y; float w; float h; struct Color { float a; float b; float g; float r; } c; } quad; } *

user_defined_types: struct Lasso { int start_x; int start_y; int end_x; int end_y; int active; struct Quad quad; }

user_defined_types: struct Quad { float x; float y; float w; float h; struct Color c; }


decompiled_code:
__int64 __fastcall render_lasso(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, __int64 a7, __int64 a8, __int64 a9, __int64 a10, __int64 a11, __int64 a12, int a13)
{
float v13; // xmm0_4
float v14; // xmm0_4
float v15; // xmm0_4
unsigned int v16; // xmm0_4

v13 = (double)(int)a7 / (double)RESOLUTION;
*((float *)&a9 + 1) = v13;
v14 = 1.0 - (double)SHIDWORD(a7) / (double)RESOLUTION;
*(float *)&a10 = v14;
v15 = (double)((int)a8 - (int)a7) / (double)RESOLUTION;
*((float *)&a10 + 1) = v15;
*(float *)&v16 = COERCE_DOUBLE(COERCE_UNSIGNED_INT64((double)(HIDWORD(a8) - HIDWORD(a7))) ^ LC1) / (double)RESOLUTION;
a11 = v16 | 0x3E99999A00000000LL;
LODWORD(a12) = LC3;
HIDWORD(a12) = LC3;
a13 = LC3;
return render((char *)&a9 + 4);
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, __int64 a7, __int64 a8, __int64 a9, __int64 a10, __int64 a11, __int64 a12, int a13)
{
float v13; // xmm0_4
float v14; // xmm0_4
float v15; // xmm0_4
unsigned int v16; // xmm0_4

v13 = (double)(int)a7 / (double)RESOLUTION;
*((float *)&a9 + 1) = v13;
v14 = 1.0 - (double)SHIDWORD(a7) / (double)RESOLUTION;
*(float *)&a10 = v14;
v15 = (double)((int)a8 - (int)a7) / (double)RESOLUTION;
*((float *)&a10 + 1) = v15;
*(float *)&v16 = COERCE_DOUBLE(COERCE_UNSIGNED_INT64((double)(HIDWORD(a8) - HIDWORD(a7))) ^ LC1) / (double)RESOLUTION;
a11 = v16 | 0x3E99999A00000000LL;
LODWORD(a12) = LC3;
HIDWORD(a12) = LC3;
a13 = LC3;
return render((char *)&a9 + 4);
}

original_code:
void render_lasso(Lasso l){
  l.quad.x = ((double)l.start_x)/RESOLUTION;
  l.quad.y = 1.0 - ((double)l.start_y)/RESOLUTION;
  l.quad.w = ((double)(l.end_x - l.start_x))/RESOLUTION;
  l.quad.h = -((double)(l.end_y - l.start_y))/RESOLUTION;
  Color color = {0.3,1.0,1.0,1.0};
  l.quad.c = color;
  render(&l.quad);
}

canonical_original_code:
void render_lasso(struct Lasso l){
  l.quad.x = ((double)l.start_x)/RESOLUTION;
  l.quad.y = 1.0 - ((double)l.start_y)/RESOLUTION;
  l.quad.w = ((double)(l.end_x - l.start_x))/RESOLUTION;
  l.quad.h = -((double)(l.end_y - l.start_y))/RESOLUTION;
  struct Color color = {0.3,1.0,1.0,1.0};
  l.quad.c = color;
  render(&l.quad);
}

variable_types: struct Lasso { int start_x; int start_y; int end_x; int end_y; int active; struct Quad { float x; float y; float w; float h; struct Color { float a; float b; float g; float r; } c; } quad; }


decompiled_code:
unsigned __int64 __fastcall create_bin_tree(__int64 a1, int a2, int a3)
{
unsigned __int64 result; // rax
__int64 v5; // rdx
_QWORD *v6; // rcx
__int64 v7; // rdx

result = (unsigned int)(a2 - 1);
if ( (unsigned int)result <= 1 )
{
result = (unsigned __int64)malloc(0x20uLL);
*(_BYTE *)result = 1;
v5 = a3 % 3;
v6 = *(_QWORD **)(a1 + 8 * v5);
*(_QWORD *)(result + 8) = *(_QWORD *)(*v6 + 8 * v5);
*(_QWORD *)(result + 16) = *v6;
v7 = 0LL;
if ( a2 == 2 )
v7 = v6[1];
*(_QWORD *)(result + 24) = v7;
}
return result;
}

canonical_decompiled_code:
unsigned __int64 __fastcall func0(__int64 a1, int a2, int a3)
{
unsigned __int64 result; // rax
__int64 v5; // rdx
_QWORD *v6; // rcx
__int64 v7; // rdx

result = (unsigned int)(a2 - 1);
if ( (unsigned int)result <= 1 )
{
result = (unsigned __int64)malloc(0x20uLL);
*(_BYTE *)result = 1;
v5 = a3 % 3;
v6 = *(_QWORD **)(a1 + 8 * v5);
*(_QWORD *)(result + 8) = *(_QWORD *)(*v6 + 8 * v5);
*(_QWORD *)(result + 16) = *v6;
v7 = 0LL;
if ( a2 == 2 )
v7 = v6[1];
*(_QWORD *)(result + 24) = v7;
}
return result;
}

original_code:
Bin_node* create_bin_tree(Point*** points, int num_points, int depth){
  int level = depth % 3;
  if(num_points == 1 || num_points == 2){
    Bin_node* n = (Bin_node*)malloc(sizeof(Bin_node));
    n->is_leaf = 1;
    n->value = ((double*)points[level][0])[level];
    n->left = (void*)points[level][0];
    if(num_points == 2){
      n->right = (void*)points[level][1];
    }
    else{
      n->right = ((void *)0);
    }
    return n;
  }
}

canonical_original_code:
struct Bin_node *create_bin_tree(struct Point ***points, int num_points, int depth){
  int level = depth % 3;
  if(num_points == 1 || num_points == 2){
    struct Bin_node *n = (Bin_node*)malloc(sizeof(Bin_node));
    n->is_leaf = 1;
    n->value = ((double *)points[level][0])[level];
    n->left = (void *)points[level][0];
    if(num_points == 2){
      n->right = (void *)points[level][1];
    }
    else{
      n->right = ((void *)0);
    }
    return n;
  }
}

variable_types: struct Point { float x; float y; float z; float intensity; } ***

variable_types: depth int

variable_types: level int

variable_types: struct Bin_node { char is_leaf; double value; void *left; void *right; } *


decompiled_code:
int __fastcall print_bin_node(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, double a7, double a8, double a9, double a10, double a11, double a12, double a13, double a14, char a15, double a16)
{
printf("is leaf: %d\n", (unsigned int)a15);
return printf("value: %f\n", a16);
}

canonical_decompiled_code:
int __fastcall func1(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, double a7, double a8, double a9, double a10, double a11, double a12, double a13, double a14, char a15, double a16)
{
printf("is leaf: %d\n", (unsigned int)a15);
return printf("value: %f\n", a16);
}

original_code:
void print_bin_node(Bin_node n){
  printf("is leaf: %d\n", n.is_leaf);
  printf("value: %f\n", n.value);
}

canonical_original_code:
void print_bin_node(struct Bin_node n){
  printf("is leaf: %d\n", n.is_leaf);
  printf("value: %f\n", n.value);
}

variable_types: struct Bin_node { char is_leaf; double value; void *left; void *right; }


comparator

decompiled_code:
__int64 __fastcall comparator(const void *a1, const void *a2)
{
float v2; // xmm0_4
float v3; // xmm1_4
__int64 result; // rax

LODWORD(v2) = *(_DWORD *)(*(_QWORD *)a1 + 12LL) & LC0;
LODWORD(v3) = *(_DWORD *)(*(_QWORD *)a2 + 12LL) & LC0;
result = 1LL;
if ( v2 <= v3 )
result = (unsigned int)-(v3 > v2);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(const void *a1, const void *a2)
{
float v2; // xmm0_4
float v3; // xmm1_4
__int64 result; // rax

LODWORD(v2) = *(_DWORD *)(*(_QWORD *)a1 + 12LL) & LC0;
LODWORD(v3) = *(_DWORD *)(*(_QWORD *)a2 + 12LL) & LC0;
result = 1LL;
if ( v2 <= v3 )
result = (unsigned int)-(v3 > v2);
return result;
}

original_code:
int comparator(const void* p, const void* n){
  Point** pp = (Point**)p;
  Point** pn = (Point**)n;
  if( fabs((*pp)->intensity) > fabs((*pn)->intensity)){
    return 1;
  }
  else if (fabs((*pp)->intensity) < fabs((*pn)->intensity)){
    return -1;
  }
  else{
    return 0;
  }
}

canonical_original_code:
int comparator(void *p, void *n){
  struct Point **pp = (Point**)p;
  struct Point **pn = (Point**)n;
  if( fabs((*pp)->intensity) > fabs((*pn)->intensity)){
    return 1;
  }
  else if (fabs((*pp)->intensity) < fabs((*pn)->intensity)){
    return -1;
  }
  else{
    return 0;
  }
}

variable_types:
p
void *

variable_types:
n
void *

variable_types: struct Point { float x; float y; float z; float intensity; } **

return_type: int


sort

decompiled_code:
void __fastcall sort(void *a1, int a2)
{
qsort(a1, a2, 8uLL, (__compar_fn_t)comparator);
}

canonical_decompiled_code:
void __fastcall func1(void *a1, int a2)
{
qsort(a1, a2, 8uLL, (__compar_fn_t)comparator);
}

original_code:
void sort(Point** p, int num_points){
  qsort(p, num_points, sizeof(Point*), comparator);
}

canonical_original_code:
void sort(struct Point **p, int num_points){
  qsort(p, num_points, sizeof(struct Point *), comparator);
}

user_defined_types: struct Point { float x; float y; float z; float intensity; }


original_code:
void mark_for_removal(Node* node){
  if(node->is_leaf){
    int num_neighbours = 0;
    PointList* neighbours = (PointList*)malloc(sizeof(PointList) * 8*512);
    for(int c = 0; c < node->num_children; c++){
      Coord pos;
      pos.x = ((Point**)node->pointer)[c]->x;
      pos.y = ((Point**)node->pointer)[c]->y;
      pos.z = ((Point**)node->pointer)[c]->z;
      Ranges search_ranges;
      search_ranges.xmin = pos.x -INTERPOLATION_RADIUS/2.0;
      search_ranges.ymin = pos.y -INTERPOLATION_RADIUS/2.0;
      search_ranges.zmin = pos.z -INTERPOLATION_RADIUS/2.0;
      search_ranges.xmax = pos.x + INTERPOLATION_RADIUS/2.0;
      search_ranges.ymax = pos.y + INTERPOLATION_RADIUS/2.0;
      search_ranges.zmax = pos.z + INTERPOLATION_RADIUS/2.0;
      range_search(g_root, &search_ranges, neighbours, &num_neighbours);
      int num_points = 0;
      for(int n = 0; n < num_neighbours; n++){
        num_points += neighbours[n].index;
      }
      Point** points = (Point**)malloc(sizeof(Point*)*num_points);
      int i = 0;
      for(int n = 0; n < num_neighbours; n++){
        for(int p = 0; p < neighbours[n].index; p++){
          points[i] = ((Point**)neighbours[n].points)[p];
          i++;
        }
      }
      int keep = 0;
      for(int all = 0; all < num_points; all++){
        double dx = points[all]->x - pos.x;
        double dy = points[all]->y - pos.y;
        double dz = points[all]->z - pos.z;
        if(sqrt(dx*dx + dy*dy + dz*dz) < INTERPOLATION_RADIUS/2.0){
          points[keep] = points[all];
          keep++;
        }
      }
      sort(points, keep);
      double median = fabs(points[keep/2]->intensity);
      double threshold = THRESHOLD_MEDIAN_FILTER*sqrt(median);
      if( fabs(((Point**)node->pointer)[c]->intensity - median) > threshold){
          ((Point**)node->pointer)[c]->intensity *= -1;
          num_removed++;
      }
      free(points);
    }
    free(neighbours);
  }
  else{
    for(int c = 0; c < 8; c++){
      mark_for_removal(&((Node*)node->pointer)[c]);
    }
  }
}

canonical_original_code:
void mark_for_removal(struct Node *node){
  if(node->is_leaf){
    int num_neighbours = 0;
    struct PointList *neighbours = (PointList*)malloc(sizeof(PointList) * 8*512);
    for(int c = 0; c < node->num_children; c++){
      struct Coord pos;
      pos.x = ((struct Point **)node->pointer)[c]->x;
      pos.y = ((struct Point **)node->pointer)[c]->y;
      pos.z = ((struct Point **)node->pointer)[c]->z;
      struct Ranges search_ranges;
      search_ranges.xmin = pos.x -INTERPOLATION_RADIUS/2.0;
      search_ranges.ymin = pos.y -INTERPOLATION_RADIUS/2.0;
      search_ranges.zmin = pos.z -INTERPOLATION_RADIUS/2.0;
      search_ranges.xmax = pos.x + INTERPOLATION_RADIUS/2.0;
      search_ranges.ymax = pos.y + INTERPOLATION_RADIUS/2.0;
      search_ranges.zmax = pos.z + INTERPOLATION_RADIUS/2.0;
      range_search(g_root, &search_ranges, neighbours, &num_neighbours);
      int num_points = 0;
      for(int n = 0; n < num_neighbours; n++){
        num_points += neighbours[n].index;
      }
      struct Point **points = (Point**)malloc(sizeof(Point*)*num_points);
      int i = 0;
      for(int n = 0; n < num_neighbours; n++){
        for(int p = 0; p < neighbours[n].index; p++){
          points[i] = ((struct Point **)neighbours[n].points)[p];
          i++;
        }
      }
      int keep = 0;
      for(int all = 0; all < num_points; all++){
        double dx = points[all]->x - pos.x;
        double dy = points[all]->y - pos.y;
        double dz = points[all]->z - pos.z;
        if(sqrt(dx*dx + dy*dy + dz*dz) < INTERPOLATION_RADIUS/2.0){
          points[keep] = points[all];
          keep++;
        }
      }
      sort(points, keep);
      double median = fabs(points[keep/2]->intensity);
      double threshold = THRESHOLD_MEDIAN_FILTER*sqrt(median);
      if( fabs(((struct Point **)node->pointer)[c]->intensity - median) > threshold){
          ((struct Point **)node->pointer)[c]->intensity *= -1;
          num_removed++;
      }
      free(points);
    }
    free(neighbours);
  }
  else{
    for(int c = 0; c < 8; c++){
      mark_for_removal(&((struct Node *)node->pointer)[c]);
    }
  }
}

variable_types: struct Node { int is_leaf; int num_children; void **pointer; float x; float y; float z; } *

variable_types: struct PointList { struct Point { float x; float y; float z; float intensity; } *points; int index; } *

variable_types: c int

variable_types: struct Coord { float x; float y; float z; }

variable_types: struct Ranges { float xmin; float xmax; float ymin; float ymax; float zmin; float zmax; float imin; float imax; }

variable_types: n int

variable_types: i int

variable_types: p int

variable_types: keep int

variable_types: all int

variable_types: dx double

variable_types: dy double

variable_types: dz double

variable_types: median double

variable_types: threshold double


filter

decompiled_code:
void __fastcall filter(__int64 a1)
{
g_root = a1;
num_removed = 0;
num_collapsed = 0;
mark_for_removal(a1);
if ( VERBOSE )
{
printf("\tRemoved %d points\n", (unsigned int)num_removed);
printf("\tCollapsed %d points\n", (unsigned int)num_collapsed);
}
}

canonical_decompiled_code:
void __fastcall func3(__int64 a1)
{
g_root = a1;
num_removed = 0;
num_collapsed = 0;
func2(a1);
if ( VERBOSE )
{
printf("\tRemoved %d points\n", (unsigned int)num_removed);
printf("\tCollapsed %d points\n", (unsigned int)num_collapsed);
}
}

original_code:
void filter(Node* root, Ranges* ranges){
  g_root = root;
  g_ranges = ranges;
  num_removed = 0;
  num_collapsed = 0;
  mark_for_removal(root);
  if(VERBOSE){
    printf("\tRemoved %d points\n", num_removed);
    printf("\tCollapsed %d points\n", num_collapsed);
  }
}

canonical_original_code:
void filter(struct Node *root, struct Ranges *ranges){
  g_root = root;
  g_ranges = ranges;
  num_removed = 0;
  num_collapsed = 0;
  mark_for_removal(root);
  if(VERBOSE){
    printf("\tRemoved %d points\n", num_removed);
    printf("\tCollapsed %d points\n", num_collapsed);
  }
}

variable_types: struct Ranges { float xmin; float xmax; float ymin; float ymax; float zmin; float zmax; float imin; float imax; } *

user_defined_types: struct Node { int is_leaf; int num_children; void **pointer; float x; float y; float z; }


decompiled_code:
__int64 __fastcall point_comparator(const void *a1, const void *a2)
{
return (unsigned int)(*((_DWORD *)a1 + 4) - *((_DWORD *)a2 + 4));
}

canonical_decompiled_code:
__int64 __fastcall func0(const void *a1, const void *a2)
{
return (unsigned int)(*((_DWORD *)a1 + 4) - *((_DWORD *)a2 + 4));
}

original_code:
int point_comparator(const void* p, const void* n){
  return ((Grid_point*)p)->grid_index - ((Grid_point*)n)->grid_index;
}

canonical_original_code:
int point_comparator(void *p, void *n){
  return ((struct Grid_point *)p)->grid_index - ((struct Grid_point *)n)->grid_index;
}

variable_types:
p
void *

variable_types:
n
void *

user_defined_types: struct Grid_point { float x; float y; float z; float intensity; int grid_index; }


decompiled_code:
int __fastcall finalize_grid(__int64 a1)
{
int result; // eax

if ( VERBOSE > 0 )
result = printf("Total number of points: %d\n", *(unsigned int *)(a1 + 60));
return result;
}

canonical_decompiled_code:
int __fastcall func1(__int64 a1)
{
int result; // eax

if ( VERBOSE > 0 )
result = printf("Total number of points: %d\n", *(unsigned int *)(a1 + 60));
return result;
}

original_code:
void finalize_grid(void* v){
  Grid* g = (Grid*)v;
  if(VERBOSE >= 1){
    printf("Total number of points: %d\n", g->num_points);
  }
}

canonical_original_code:
void finalize_grid(void *v){
  struct Grid *g = (Grid*)v;
  if(VERBOSE >= 1){
    printf("Total number of points: %d\n", g->num_points);
  }
}

variable_types:
v
void *

variable_types: struct Grid { struct Point { float x; float y; float z; float intensity; } *points; struct Grid_cell { int index; int length; } *indices; struct Ranges { float xmin; float xmax; float ymin; float ymax; float zmin; float zmax; float imin; float imax; } ranges; int x_size; int y_size; int z_size; int num_points; } *

user_defined_types: struct Grid { struct Point *points; struct Grid_cell *indices; struct Ranges ranges; int x_size; int y_size; int z_size; int num_points; }


original_code:
float get_intensity_for_pos_grid(void *v, Coord pos){
  Grid* g = (Grid*)v;
  int x = g->x_size * ((pos.x - g->ranges.xmin)/(g->ranges.xmax - g->ranges.xmin));
  int y = g->y_size * ((pos.y - g->ranges.ymin)/(g->ranges.ymax - g->ranges.ymin));
  int z = g->z_size * ((pos.z - g->ranges.zmin)/(g->ranges.zmax - g->ranges.zmin));
  int sub_x = (2*g->x_size) * ((pos.x - g->ranges.xmin)/(g->ranges.xmax - g->ranges.xmin));
  int sub_y = (2*g->y_size) * ((pos.y - g->ranges.ymin)/(g->ranges.ymax - g->ranges.ymin));
  int sub_z = (2*g->z_size) * ((pos.z - g->ranges.zmin)/(g->ranges.zmax - g->ranges.zmin));
  sub_x = sub_x - (x*2);
  sub_y = sub_y - (y*2);
  sub_z = sub_z - (z*2);
  PointList pls[27];
  int i = 0;
  int ue,uc,ud,le,ld,lc;
  if(NEIGHBOUR_MODE == 1){
    if(sub_x == 1){
      ue = 2; le = 0;
    }
    else{
      ue = 1; le = -1;
    }
    if(sub_y == 1){
      ud = 2; ld = 0;
    }
    else{
      ud = 1; ld = -1;
    }
    if(sub_z == 1){
      uc = 2; lc = 0;
    }
    else{
      uc = 1; lc = -1;
    }
  }
  if(NEIGHBOUR_MODE == 0){
    uc = 1; lc = 0;
    ud = 1; ld = 0;
    ue = 1; le = 0;
  }
  for(int c = lc; c < uc; c++){
    for(int d = ld; d < ud; d++){
      for(int e = le; e < ue; e++){
        int index = (z+c)*g->x_size*g->y_size + (y+d)*g->x_size + (x+e);
        if(index < 0 || (x+e) >= g->x_size || (y+d) >= g->y_size || (z+c) >= g->z_size){
          continue;
        }
        if( g->indices[index].index == -1){
          continue;
        }
        pls[i].index = g->indices[index].length;
        pls[i].points = &g->points[g->indices[index].index];
        i++;
      }
    }
  }
  return i/1000.0;
}

canonical_original_code:
float get_intensity_for_pos_grid(void *v, struct Coord pos){
  struct Grid *g = (Grid*)v;
  int x = g->x_size * ((pos.x - g->ranges.xmin)/(g->ranges.xmax - g->ranges.xmin));
  int y = g->y_size * ((pos.y - g->ranges.ymin)/(g->ranges.ymax - g->ranges.ymin));
  int z = g->z_size * ((pos.z - g->ranges.zmin)/(g->ranges.zmax - g->ranges.zmin));
  int sub_x = (2*g->x_size) * ((pos.x - g->ranges.xmin)/(g->ranges.xmax - g->ranges.xmin));
  int sub_y = (2*g->y_size) * ((pos.y - g->ranges.ymin)/(g->ranges.ymax - g->ranges.ymin));
  int sub_z = (2*g->z_size) * ((pos.z - g->ranges.zmin)/(g->ranges.zmax - g->ranges.zmin));
  sub_x = sub_x - (x*2);
  sub_y = sub_y - (y*2);
  sub_z = sub_z - (z*2);
  struct PointList pls[27];
  int i = 0;
  int ue; int uc; int ud; int le; int ld; int lc;
  if(NEIGHBOUR_MODE == 1){
    if(sub_x == 1){
      ue = 2; le = 0;
    }
    else{
      ue = 1; le = -1;
    }
    if(sub_y == 1){
      ud = 2; ld = 0;
    }
    else{
      ud = 1; ld = -1;
    }
    if(sub_z == 1){
      uc = 2; lc = 0;
    }
    else{
      uc = 1; lc = -1;
    }
  }
  if(NEIGHBOUR_MODE == 0){
    uc = 1; lc = 0;
    ud = 1; ld = 0;
    ue = 1; le = 0;
  }
  for(int c = lc; c < uc; c++){
    for(int d = ld; d < ud; d++){
      for(int e = le; e < ue; e++){
        int index = (z+c)*g->x_size*g->y_size + (y+d)*g->x_size + (x+e);
        if(index < 0 || (x+e) >= g->x_size || (y+d) >= g->y_size || (z+c) >= g->z_size){
          continue;
        }
        if( g->indices[index].index == -1){
          continue;
        }
        pls[i].index = g->indices[index].length;
        pls[i].points = &g->points[g->indices[index].index];
        i++;
      }
    }
  }
  return i/1000.0;
}

variable_types: struct Coord { float x; float y; float z; }

variable_types: x int

variable_types: y int

variable_types: z int

variable_types: struct PointList { struct Point { float x; float y; float z; float intensity; } *points; int index; } [27]

variable_types: ue int

variable_types: uc int

variable_types: ud int

variable_types: le int

variable_types: ld int

variable_types: lc int

variable_types: c int

variable_types: d int

variable_types: e int

variable_types: index int

user_defined_types: struct Grid_cell { int index; int length; }


original_code:
void set_grid_index(Grid_point* p, Grid* g){
  int x = g->x_size * ((p->x - g->ranges.xmin)/(g->ranges.xmax - g->ranges.xmin));
  int y = g->y_size * ((p->y - g->ranges.ymin)/(g->ranges.ymax - g->ranges.ymin));
  int z = g->z_size * ((p->z - g->ranges.zmin)/(g->ranges.zmax - g->ranges.zmin));
  p->grid_index = z*g->x_size*g->y_size + y*g->x_size + x;
}

canonical_original_code:
void set_grid_index(struct Grid_point *p, struct Grid *g){
  int x = g->x_size * ((p->x - g->ranges.xmin)/(g->ranges.xmax - g->ranges.xmin));
  int y = g->y_size * ((p->y - g->ranges.ymin)/(g->ranges.ymax - g->ranges.ymin));
  int z = g->z_size * ((p->z - g->ranges.zmin)/(g->ranges.zmax - g->ranges.zmin));
  p->grid_index = z*g->x_size*g->y_size + y*g->x_size + x;
}

variable_types: struct Grid_point { float x; float y; float z; float intensity; int grid_index; } *


original_code:
void insert_points_grid(void* v, PointList* pl){
  Grid* g = (Grid*) v;
  g->num_points = pl->index;
  g->x_size = (int)((g->ranges.xmax - g->ranges.xmin)/(2*INTERPOLATION_RADIUS));
  g->y_size = (int)((g->ranges.ymax - g->ranges.ymin)/(2*INTERPOLATION_RADIUS));
  g->z_size = (int)((g->ranges.zmax - g->ranges.zmin)/(2*INTERPOLATION_RADIUS));
  long int grid_size = (long int)g->x_size * (long int)g->y_size * (long int)g->z_size;
  if(grid_size > 0x7fffffff){
    fprintf(stderr, "Grid is too big. Exiting.\n");
    exit(-1);
  }
  if(VERBOSE >= 1){
    printf("Grid size: %dx%dx%d, %ld bytes\n",g->x_size, g->y_size, g->z_size, sizeof(Grid_cell) * grid_size);
  }
  g->indices = (Grid_cell*)malloc(sizeof(Grid_cell) * grid_size);
  for(int c= 0; c < grid_size; c++){
    g->indices[c].index = -1;
  }
  Grid_point* grid_points = (Grid_point*)malloc(sizeof(Grid_point) * pl->index);
  for(int c = 0; c < pl->index; c++){
    grid_points[c].x = pl->points[c].x;
    grid_points[c].y = pl->points[c].y;
    grid_points[c].z = pl->points[c].z;
    grid_points[c].intensity = pl->points[c].intensity;
    set_grid_index(&grid_points[c], g);
  }
  qsort(grid_points, pl->index, sizeof(Grid_point), point_comparator);
  int prev = -1;
  for(int c = 0; c < pl->index; c++){
    if(grid_points[c].grid_index != prev){
      g->indices[grid_points[c].grid_index].index = c;
      prev = grid_points[c].grid_index;
    }
  }
  for(int c = 0; c < grid_size; c++){
    if(g->indices[c].index != -1){
      int i = g->indices[c].index;
      while(grid_points[i].grid_index == c && i < pl->index){
        i++;
      }
      g->indices[c].length = i - g->indices[c].index;
    }
  }
  for(int c = 0; c < pl->index; c++){
    pl->points[c].x = grid_points[c].x;
    pl->points[c].y = grid_points[c].y;
    pl->points[c].z = grid_points[c].z;
    pl->points[c].intensity = grid_points[c].intensity;
  }
  g->points = pl->points;
}

canonical_original_code:
void insert_points_grid(void *v, struct PointList *pl){
  struct Grid *g = (Grid*) v;
  g->num_points = pl->index;
  g->x_size = (int)((g->ranges.xmax - g->ranges.xmin)/(2*INTERPOLATION_RADIUS));
  g->y_size = (int)((g->ranges.ymax - g->ranges.ymin)/(2*INTERPOLATION_RADIUS));
  g->z_size = (int)((g->ranges.zmax - g->ranges.zmin)/(2*INTERPOLATION_RADIUS));
  long grid_size = (long int)g->x_size * (long int)g->y_size * (long int)g->z_size;
  if(grid_size > 0x7fffffff){
    fprintf(stderr, "Grid is too big. Exiting.\n");
    exit(-1);
  }
  if(VERBOSE >= 1){
    printf("Grid size: %dx%dx%d, %ld bytes\n",g->x_size, g->y_size, g->z_size, sizeof(Grid_cell) * grid_size);
  }
  g->indices = (struct Grid_cell *)malloc(sizeof(Grid_cell) * grid_size);
  for(int c = 0; c < grid_size; c++){
    g->indices[c].index = -1;
  }
  struct Grid_point *grid_points = (Grid_point*)malloc(sizeof(Grid_point) * pl->index);
  for(int c = 0; c < pl->index; c++){
    grid_points[c].x = pl->points[c].x;
    grid_points[c].y = pl->points[c].y;
    grid_points[c].z = pl->points[c].z;
    grid_points[c].intensity = pl->points[c].intensity;
    set_grid_index(&grid_points[c], g);
  }
  qsort(grid_points, pl->index, sizeof(Grid_point), point_comparator);
  int prev = -1;
  for(int c = 0; c < pl->index; c++){
    if(grid_points[c].grid_index != prev){
      g->indices[grid_points[c].grid_index].index = c;
      prev = grid_points[c].grid_index;
    }
  }
  for(int c = 0; c < grid_size; c++){
    if(g->indices[c].index != -1){
      int i = g->indices[c].index;
      while(grid_points[i].grid_index == c && i < pl->index){
        i++;
      }
      g->indices[c].length = i - g->indices[c].index;
    }
  }
  for(int c = 0; c < pl->index; c++){
    pl->points[c].x = grid_points[c].x;
    pl->points[c].y = grid_points[c].y;
    pl->points[c].z = grid_points[c].z;
    pl->points[c].intensity = grid_points[c].intensity;
  }
  g->points = pl->points;
}

variable_types:
v
void *

variable_types: struct PointList { struct Point { float x; float y; float z; float intensity; } *points; int index; } *

variable_types: struct Grid { struct Point { float x; float y; float z; float intensity; } *points; struct Grid_cell { int index; int length; } *indices; struct Ranges { float xmin; float xmax; float ymin; float ymax; float zmin; float zmax; float imin; float imax; } ranges; int x_size; int y_size; int z_size; int num_points; } *

variable_types: prev int

variable_types: i int


original_code:
long get_memory_usage_grid(void * v){
  Grid* g = (Grid*)v;
  long grid = sizeof(Grid_cell)*g->x_size * g->y_size * g->z_size;
  long points = sizeof(Point)*g->num_points;
  if(VERBOSE >= 1){
    printf("sizeof grid: %ld, sizeof points: %ld\n", grid, points);
  }
  return grid + points;
}

canonical_original_code:
long get_memory_usage_grid(void *v){
  struct Grid *g = (Grid*)v;
  long grid = sizeof(Grid_cell)*g->x_size * g->y_size * g->z_size;
  long points = sizeof(Point)*g->num_points;
  if(VERBOSE >= 1){
    printf("sizeof grid: %ld, sizeof points: %ld\n", grid, points);
  }
  return grid + points;
}

variable_types: grid long

variable_types: points long

return_type: long


original_code:
void print_grid(Grid* g){
  for(int c= 0; c < g->num_points; c++){
    print_point(g->points[c]);
  }
  printf("\n\n\n");
  int grid_size = g->x_size * g->y_size * g->z_size;
  for(int c= 0; c < grid_size; c++){
    printf("%d %d\n", g->indices[c].index, g->indices[c].length);
  }
}

canonical_original_code:
void print_grid(struct Grid *g){
  for(int c = 0; c < g->num_points; c++){
    print_point(g->points[c]);
  }
  printf("\n\n\n");
  int grid_size = g->x_size * g->y_size * g->z_size;
  for(int c = 0; c < grid_size; c++){
    printf("%d %d\n", g->indices[c].index, g->indices[c].length);
  }
}


decompiled_code:
char *__fastcall new_thread_pool(int a1)
{
char *v1; // rbp
size_t v2; // r12
__int64 v3; // rbx

v1 = (char *)malloc(0x70uLL);
*(_DWORD *)v1 = 0;
pthread_mutex_init((pthread_mutex_t *)(v1 + 8), 0LL);
*((_DWORD *)v1 + 12) = a1;
*((_QWORD *)v1 + 7) = malloc(8LL * a1);
v2 = 4LL * a1;
*((_QWORD *)v1 + 8) = malloc(40LL * a1);
*((_QWORD *)v1 + 9) = malloc(40LL * a1);
*((_QWORD *)v1 + 10) = malloc(48LL * a1);
*((_QWORD *)v1 + 11) = malloc(48LL * a1);
*((_QWORD *)v1 + 12) = malloc(v2);
*((_QWORD *)v1 + 13) = malloc(v2);
if ( a1 > 0 )
{
v3 = 0LL;
do
{
pthread_mutex_init((pthread_mutex_t *)(*((_QWORD *)v1 + 8) + 10 * v3), 0LL);
pthread_mutex_init((pthread_mutex_t *)(*((_QWORD *)v1 + 9) + 10 * v3), 0LL);
pthread_cond_init((pthread_cond_t *)(*((_QWORD *)v1 + 10) + 12 * v3), 0LL);
pthread_cond_init((pthread_cond_t *)(*((_QWORD *)v1 + 11) + 12 * v3), 0LL);
*(_DWORD *)(*((_QWORD *)v1 + 12) + v3) = 0;
*(_DWORD *)(*((_QWORD *)v1 + 13) + v3) = 0;
v3 += 4LL;
}
while ( v3 != 4LL * (unsigned int)a1 );
}
return v1;
}

canonical_decompiled_code:
char *__fastcall func0(int a1)
{
char *v1; // rbp
size_t v2; // r12
__int64 v3; // rbx

v1 = (char *)malloc(0x70uLL);
*(_DWORD *)v1 = 0;
pthread_mutex_init((pthread_mutex_t *)(v1 + 8), 0LL);
*((_DWORD *)v1 + 12) = a1;
*((_QWORD *)v1 + 7) = malloc(8LL * a1);
v2 = 4LL * a1;
*((_QWORD *)v1 + 8) = malloc(40LL * a1);
*((_QWORD *)v1 + 9) = malloc(40LL * a1);
*((_QWORD *)v1 + 10) = malloc(48LL * a1);
*((_QWORD *)v1 + 11) = malloc(48LL * a1);
*((_QWORD *)v1 + 12) = malloc(v2);
*((_QWORD *)v1 + 13) = malloc(v2);
if ( a1 > 0 )
{
v3 = 0LL;
do
{
pthread_mutex_init((pthread_mutex_t *)(*((_QWORD *)v1 + 8) + 10 * v3), 0LL);
pthread_mutex_init((pthread_mutex_t *)(*((_QWORD *)v1 + 9) + 10 * v3), 0LL);
pthread_cond_init((pthread_cond_t *)(*((_QWORD *)v1 + 10) + 12 * v3), 0LL);
pthread_cond_init((pthread_cond_t *)(*((_QWORD *)v1 + 11) + 12 * v3), 0LL);
*(_DWORD *)(*((_QWORD *)v1 + 12) + v3) = 0;
*(_DWORD *)(*((_QWORD *)v1 + 13) + v3) = 0;
v3 += 4LL;
}
while ( v3 != 4LL * (unsigned int)a1 );
}
return v1;
}

original_code:
Thread_pool * new_thread_pool(int no_of_threads){
  Thread_pool * tp = (Thread_pool*)malloc(sizeof(Thread_pool));
  tp->work_queue = 0;
  pthread_mutex_init(&tp->work_queue_mutex, ((void *)0));
  tp->no_of_threads = no_of_threads;
  tp->thread_ids = (pthread_t*)malloc(sizeof(pthread_t) * no_of_threads);
  tp->work_mutexes = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t) * no_of_threads);
  tp->finished_mutexes = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t) * no_of_threads);
  tp->work_conds = (pthread_cond_t*)malloc(sizeof(pthread_cond_t) * no_of_threads);
  tp->finished_conds = (pthread_cond_t*)malloc(sizeof(pthread_cond_t) * no_of_threads);
  tp->work = (int*)malloc(sizeof(int) * no_of_threads);
  tp->finished = (int*)malloc(sizeof(int) * no_of_threads);
  for(int i = 0; i < no_of_threads; i++){
    pthread_mutex_init(&tp->work_mutexes[i], ((void *)0));
    pthread_mutex_init(&tp->finished_mutexes[i], ((void *)0));
    pthread_cond_init(&tp->work_conds[i], ((void *)0));
    pthread_cond_init(&tp->finished_conds[i], ((void *)0));
    tp->work[i] = 0;
    tp->finished[i] = 0;
  }
  return tp;
}

canonical_original_code:
struct Thread_pool *new_thread_pool(int no_of_threads){
  struct Thread_pool *tp = (Thread_pool*)malloc(sizeof(Thread_pool));
  tp->work_queue = 0;
  pthread_mutex_init(&tp->work_queue_mutex, ((void *)0));
  tp->no_of_threads = no_of_threads;
  tp->thread_ids = (unsigned long *)malloc(sizeof(pthread_t) * no_of_threads);
  tp->work_mutexes = (union pthread_mutex_t *)malloc(sizeof(pthread_mutex_t) * no_of_threads);
  tp->finished_mutexes = (union pthread_mutex_t *)malloc(sizeof(pthread_mutex_t) * no_of_threads);
  tp->work_conds = (union pthread_cond_t *)malloc(sizeof(pthread_cond_t) * no_of_threads);
  tp->finished_conds = (union pthread_cond_t *)malloc(sizeof(pthread_cond_t) * no_of_threads);
  tp->work = (int *)malloc(sizeof(int) * no_of_threads);
  tp->finished = (int *)malloc(sizeof(int) * no_of_threads);
  for(int i = 0; i < no_of_threads; i++){
    pthread_mutex_init(&tp->work_mutexes[i], ((void *)0));
    pthread_mutex_init(&tp->finished_mutexes[i], ((void *)0));
    pthread_cond_init(&tp->work_conds[i], ((void *)0));
    pthread_cond_init(&tp->finished_conds[i], ((void *)0));
    tp->work[i] = 0;
    tp->finished[i] = 0;
  }
  return tp;
}

variable_types: struct Thread_pool { int work_queue; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } work_queue_mutex; int no_of_threads; unsigned long *thread_ids; union pthread_mutex_t *work_mutexes; union pthread_mutex_t *finished_mutexes; union pthread_cond_t { struct __pthread_cond_s { union { unsigned long long __wseq; struct { unsigned int __low; unsigned int __high; } __wseq32; }; union { unsigned long long __g1_start; struct { unsigned int __low; unsigned int __high; } __g1_start32; }; unsigned int __g_refs[2]; unsigned int __g_size[2]; unsigned int __g1_orig_size; unsigned int __wrefs; unsigned int __g_signals[2]; } __data; char __size[48]; long long __align; } *work_conds; union pthread_cond_t *finished_conds; int *work; int *finished; } *

user_defined_types: struct Thread_pool { int work_queue; union pthread_mutex_t work_queue_mutex; int no_of_threads; unsigned long *thread_ids; union pthread_mutex_t *work_mutexes; union pthread_mutex_t *finished_mutexes; union pthread_cond_t *work_conds; union pthread_cond_t *finished_conds; int *work; int *finished; }

user_defined_types: union pthread_mutex_t { struct __pthread_mutex_s __data; char __size[40]; long __align; }

user_defined_types: union pthread_cond_t { struct __pthread_cond_s __data; char __size[48]; long long __align; }

user_defined_types: struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list __list; }


decompiled_code:
int __fastcall create_threads(__int64 a1, __int64 a2)
{
__int64 v2; // rbx
int result; // eax

if ( *(int *)(a1 + 48) > 0 )
{
v2 = 0LL;
do
{
*(_DWORD *)(*(_QWORD *)(a2 + 8 * v2) + 8LL) = v2;
**(_QWORD **)(a2 + 8 * v2) = a1;
result = pthread_create((pthread_t *)(*(_QWORD *)(a1 + 56) + 8 * v2), 0LL, do_work, *(void **)(a2 + 8 * v2));
++v2;
}
while ( *(_DWORD *)(a1 + 48) > (int)v2 );
}
return result;
}

original_code:
void create_threads(Thread_pool * tp, Thread_args ** tas){
  for(int i = 0; i < tp->no_of_threads; i++){
    tas[i]->id = i;
    tas[i]->tp = tp;
    pthread_create(&tp->thread_ids[i], ((void *)0), do_work, (void*)tas[i]);
  }
}

canonical_original_code:
void create_threads(struct Thread_pool *tp, struct Thread_args **tas){
  for(int i = 0; i < tp->no_of_threads; i++){
    tas[i]->id = i;
    tas[i]->tp = tp;
    pthread_create(&tp->thread_ids[i], ((void *)0), do_work, (void *)tas[i]);
  }
}

variable_types: struct Thread_args { struct Thread_pool *tp; int id; } **

user_defined_types: struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; }

user_defined_types: struct __pthread_cond_s { union { unsigned long long __wseq; struct { unsigned int __low; unsigned int __high; } __wseq32; }; union { unsigned long long __g1_start; struct { unsigned int __low; unsigned int __high; } __g1_start32; }; unsigned int __g_refs[2]; unsigned int __g_size[2]; unsigned int __g1_orig_size; unsigned int __wrefs; unsigned int __g_signals[2]; }


original_code:
void thread_pool_exec(Thread_pool * tp, int work_id, int work_amount){
  tp->work_queue = work_amount;
  for(int i = 0; i < tp->no_of_threads; i++){
    pthread_mutex_lock(&tp->work_mutexes[i]);
    tp->work[i] = work_id;
    pthread_cond_signal(&tp->work_conds[i]);
    int succ = pthread_mutex_unlock(&tp->work_mutexes[i]);
  }
  for(int i = 0; i < tp->no_of_threads; i++){
    pthread_mutex_lock(&tp->finished_mutexes[i]);
    while(tp->finished[i] == 0){
      pthread_cond_wait(&tp->finished_conds[i], &tp->finished_mutexes[i]);
    }
    tp->finished[i] = 0;
    pthread_mutex_unlock(&tp->finished_mutexes[i]);
  }
}

canonical_original_code:
void thread_pool_exec(struct Thread_pool *tp, int work_id, int work_amount){
  tp->work_queue = work_amount;
  for(int i = 0; i < tp->no_of_threads; i++){
    pthread_mutex_lock(&tp->work_mutexes[i]);
    tp->work[i] = work_id;
    pthread_cond_signal(&tp->work_conds[i]);
    int succ = pthread_mutex_unlock(&tp->work_mutexes[i]);
  }
  for(int i = 0; i < tp->no_of_threads; i++){
    pthread_mutex_lock(&tp->finished_mutexes[i]);
    while(tp->finished[i] == 0){
      pthread_cond_wait(&tp->finished_conds[i], &tp->finished_mutexes[i]);
    }
    tp->finished[i] = 0;
    pthread_mutex_unlock(&tp->finished_mutexes[i]);
  }
}

variable_types: succ int


decompiled_code:
int __fastcall thread_pool_stop(__int64 a1)
{
pthread_mutex_lock((pthread_mutex_t *)(a1 + 8));
*(_DWORD *)a1 = 0;
return pthread_mutex_unlock((pthread_mutex_t *)(a1 + 8));
}

canonical_decompiled_code:
int __fastcall func3(__int64 a1)
{
pthread_mutex_lock((pthread_mutex_t *)(a1 + 8));
*(_DWORD *)a1 = 0;
return pthread_mutex_unlock((pthread_mutex_t *)(a1 + 8));
}

original_code:
void thread_pool_stop(Thread_pool* tp){
  pthread_mutex_lock(&tp->work_queue_mutex);
  tp->work_queue = 0;
  pthread_mutex_unlock(&tp->work_queue_mutex);
}

canonical_original_code:
void thread_pool_stop(struct Thread_pool *tp){
  pthread_mutex_lock(&tp->work_queue_mutex);
  tp->work_queue = 0;
  pthread_mutex_unlock(&tp->work_queue_mutex);
}


decompiled_code:
unsigned __int64 __fastcall get_work(unsigned int *a1, int a2)
{
int v2; // er13
unsigned int v3; // er12
int v4; // er14

v2 = 64;
if ( a2 )
v2 = 128;
pthread_mutex_lock((pthread_mutex_t *)(a1 + 2));
v3 = *a1;
v4 = *a1 - v2;
if ( v4 < 0 )
{
*a1 = 0;
v4 = 0;
}
else
{
*a1 = v4;
}
pthread_mutex_unlock((pthread_mutex_t *)(a1 + 2));
return __PAIR64__(v3, v4);
}

canonical_decompiled_code:
unsigned __int64 __fastcall func4(unsigned int *a1, int a2)
{
int v2; // er13
unsigned int v3; // er12
int v4; // er14

v2 = 64;
if ( a2 )
v2 = 128;
pthread_mutex_lock((pthread_mutex_t *)(a1 + 2));
v3 = *a1;
v4 = *a1 - v2;
if ( v4 < 0 )
{
*a1 = 0;
v4 = 0;
}
else
{
*a1 = v4;
}
pthread_mutex_unlock((pthread_mutex_t *)(a1 + 2));
return __PAIR64__(v3, v4);
}

original_code:
Work_item get_work(Thread_pool * tp, int first){
  Work_item new_work_item;
  int size = 64;
  new_work_item.first = 0;
  if(first){
    size = 128;
    new_work_item.first = 1;
  }
  pthread_mutex_lock(&tp->work_queue_mutex);
  new_work_item.stop = tp->work_queue;
  tp->work_queue -= size;
  new_work_item.start = tp->work_queue;
  if(new_work_item.start < 0){
    new_work_item.start = 0;
    tp->work_queue = 0;
  }
  pthread_mutex_unlock(&tp->work_queue_mutex);
  return new_work_item;
}

canonical_original_code:
struct Work_item get_work(struct Thread_pool *tp, int first){
  struct Work_item new_work_item;
  int size = 64;
  new_work_item.first = 0;
  if(first){
    size = 128;
    new_work_item.first = 1;
  }
  pthread_mutex_lock(&tp->work_queue_mutex);
  new_work_item.stop = tp->work_queue;
  tp->work_queue -= size;
  new_work_item.start = tp->work_queue;
  if(new_work_item.start < 0){
    new_work_item.start = 0;
    tp->work_queue = 0;
  }
  pthread_mutex_unlock(&tp->work_queue_mutex);
  return new_work_item;
}

variable_types: first int

variable_types: struct Work_item { int start; int stop; int first; }

variable_types: size int


decompiled_code:
void __fastcall __noreturn do_work(void *a1)
{
__int64 v1; // rax
__int64 v2; // r13
__int64 v3; // r12
__int64 v4; // r14
int j; // esi
__int64 v6; // rax
unsigned int i; // ebx

v1 = *((int *)a1 + 2);
v2 = 4 * v1;
v3 = 40 * v1;
v4 = 48 * v1;
while ( 1 )
{
pthread_mutex_lock((pthread_mutex_t *)(*(_QWORD *)(*(_QWORD *)a1 + 64LL) + v3));
v6 = *(_QWORD *)a1;
for ( i = *(_DWORD *)(*(_QWORD *)(*(_QWORD *)a1 + 96LL) + v2);
!i;
i = *(_DWORD *)(*(_QWORD *)(*(_QWORD *)a1 + 96LL) + v2) )
{
pthread_cond_wait((pthread_cond_t *)(*(_QWORD *)(v6 + 80) + v4), (pthread_mutex_t *)(*(_QWORD *)(v6 + 64) + v3));
v6 = *(_QWORD *)a1;
}
pthread_mutex_unlock((pthread_mutex_t *)(*(_QWORD *)(v6 + 64) + v3));
for ( j = 1; get_work(*(unsigned int **)a1, j); j = 0 )
trace_rays(i);
pthread_mutex_lock((pthread_mutex_t *)(*(_QWORD *)(*(_QWORD *)a1 + 64LL) + v3));
*(_DWORD *)(*(_QWORD *)(*(_QWORD *)a1 + 96LL) + v2) = 0;
pthread_mutex_unlock((pthread_mutex_t *)(*(_QWORD *)(*(_QWORD *)a1 + 64LL) + v3));
pthread_mutex_lock((pthread_mutex_t *)(*(_QWORD *)(*(_QWORD *)a1 + 72LL) + v3));
*(_DWORD *)(*(_QWORD *)(*(_QWORD *)a1 + 104LL) + v2) = 1;
pthread_cond_signal((pthread_cond_t *)(*(_QWORD *)(*(_QWORD *)a1 + 88LL) + v4));
pthread_mutex_unlock((pthread_mutex_t *)(*(_QWORD *)(*(_QWORD *)a1 + 72LL) + v3));
}
}

canonical_decompiled_code:
void __fastcall __noreturn func5(void *a1)
{
__int64 v1; // rax
__int64 v2; // r13
__int64 v3; // r12
__int64 v4; // r14
int j; // esi
__int64 v6; // rax
unsigned int i; // ebx

v1 = *((int *)a1 + 2);
v2 = 4 * v1;
v3 = 40 * v1;
v4 = 48 * v1;
while ( 1 )
{
pthread_mutex_lock((pthread_mutex_t *)(*(_QWORD *)(*(_QWORD *)a1 + 64LL) + v3));
v6 = *(_QWORD *)a1;
for ( i = *(_DWORD *)(*(_QWORD *)(*(_QWORD *)a1 + 96LL) + v2);
!i;
i = *(_DWORD *)(*(_QWORD *)(*(_QWORD *)a1 + 96LL) + v2) )
{
pthread_cond_wait((pthread_cond_t *)(*(_QWORD *)(v6 + 80) + v4), (pthread_mutex_t *)(*(_QWORD *)(v6 + 64) + v3));
v6 = *(_QWORD *)a1;
}
pthread_mutex_unlock((pthread_mutex_t *)(*(_QWORD *)(v6 + 64) + v3));
for ( j = 1; func4(*(unsigned int **)a1, j); j = 0 )
trace_rays(i);
pthread_mutex_lock((pthread_mutex_t *)(*(_QWORD *)(*(_QWORD *)a1 + 64LL) + v3));
*(_DWORD *)(*(_QWORD *)(*(_QWORD *)a1 + 96LL) + v2) = 0;
pthread_mutex_unlock((pthread_mutex_t *)(*(_QWORD *)(*(_QWORD *)a1 + 64LL) + v3));
pthread_mutex_lock((pthread_mutex_t *)(*(_QWORD *)(*(_QWORD *)a1 + 72LL) + v3));
*(_DWORD *)(*(_QWORD *)(*(_QWORD *)a1 + 104LL) + v2) = 1;
pthread_cond_signal((pthread_cond_t *)(*(_QWORD *)(*(_QWORD *)a1 + 88LL) + v4));
pthread_mutex_unlock((pthread_mutex_t *)(*(_QWORD *)(*(_QWORD *)a1 + 72LL) + v3));
}
}

original_code:
void * do_work(void * args){
  Thread_args * ta = (Thread_args*)args;
  int id = ta->id;
  int local_work;
  while(1){
    pthread_mutex_lock(&ta->tp->work_mutexes[id]);
    while(ta->tp->work[id] == 0){
      pthread_cond_wait(&ta->tp->work_conds[id], &ta->tp->work_mutexes[id]);
    }
    local_work = ta->tp->work[id];
    pthread_mutex_unlock(&ta->tp->work_mutexes[id]);
    int first = 1;
    while(1){
      Work_item item = get_work(ta->tp, first);
      first = 0;
      if(item.start == 0 && item.stop == 0){
        break;
      }
      trace_rays(local_work, item.start, item.stop);
    }
    pthread_mutex_lock(&ta->tp->work_mutexes[id]);
    ta->tp->work[id] = 0;
    pthread_mutex_unlock(&ta->tp->work_mutexes[id]);
    pthread_mutex_lock(&ta->tp->finished_mutexes[id]);
    ta->tp->finished[id] = 1;
    pthread_cond_signal(&ta->tp->finished_conds[id]);
    pthread_mutex_unlock(&ta->tp->finished_mutexes[id]);
  }
}

canonical_original_code:
void *do_work(void *args){
  struct Thread_args *ta = (Thread_args*)args;
  int id = ta->id;
  int local_work;
  while(1){
    pthread_mutex_lock(&ta->tp->work_mutexes[id]);
    while(ta->tp->work[id] == 0){
      pthread_cond_wait(&ta->tp->work_conds[id], &ta->tp->work_mutexes[id]);
    }
    local_work = ta->tp->work[id];
    pthread_mutex_unlock(&ta->tp->work_mutexes[id]);
    int first = 1;
    while(1){
      struct Work_item item = get_work(ta->tp, first);
      first = 0;
      if(item.start == 0 && item.stop == 0){
        break;
      }
      trace_rays(local_work, item.start, item.stop);
    }
    pthread_mutex_lock(&ta->tp->work_mutexes[id]);
    ta->tp->work[id] = 0;
    pthread_mutex_unlock(&ta->tp->work_mutexes[id]);
    pthread_mutex_lock(&ta->tp->finished_mutexes[id]);
    ta->tp->finished[id] = 1;
    pthread_cond_signal(&ta->tp->finished_conds[id]);
    pthread_mutex_unlock(&ta->tp->finished_mutexes[id]);
  }
}

variable_types:
args
void *

variable_types: struct Thread_args { struct Thread_pool { int work_queue; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } work_queue_mutex; int no_of_threads; unsigned long *thread_ids; union pthread_mutex_t *work_mutexes; union pthread_mutex_t *finished_mutexes; union pthread_cond_t { struct __pthread_cond_s { union { unsigned long long __wseq; struct { unsigned int __low; unsigned int __high; } __wseq32; }; union { unsigned long long __g1_start; struct { unsigned int __low; unsigned int __high; } __g1_start32; }; unsigned int __g_refs[2]; unsigned int __g_size[2]; unsigned int __g1_orig_size; unsigned int __wrefs; unsigned int __g_signals[2]; } __data; char __size[48]; long long __align; } *work_conds; union pthread_cond_t *finished_conds; int *work; int *finished; } *tp; int id; } *

variable_types: id int

return_type: void *

user_defined_types: struct Work_item { int start; int stop; int first; }

user_defined_types: struct Thread_args { struct Thread_pool *tp; int id; }


decompiled_code:
void __fastcall free_thread_pool(void *ptr, int a2)
{
__int64 v2; // r12
__int64 v3; // rbp

free(*((void **)ptr + 7));
pthread_mutex_destroy((pthread_mutex_t *)((char *)ptr + 8));
if ( a2 > 0 )
{
v2 = 0LL;
v3 = 0LL;
do
{
pthread_cond_destroy((pthread_cond_t *)(*((_QWORD *)ptr + 10) + v3));
pthread_cond_destroy((pthread_cond_t *)(*((_QWORD *)ptr + 11) + v3));
pthread_mutex_destroy((pthread_mutex_t *)(*((_QWORD *)ptr + 8) + v2));
pthread_mutex_destroy((pthread_mutex_t *)(*((_QWORD *)ptr + 9) + v2));
v3 += 48LL;
v2 += 40LL;
}
while ( v3 != 48LL * (unsigned int)a2 );
}
free(*((void **)ptr + 8));
free(*((void **)ptr + 9));
free(*((void **)ptr + 10));
free(*((void **)ptr + 11));
free(*((void **)ptr + 12));
free(*((void **)ptr + 13));
free(ptr);
}

canonical_decompiled_code:
void __fastcall func6(void *ptr, int a2)
{
__int64 v2; // r12
__int64 v3; // rbp

free(*((void **)ptr + 7));
pthread_mutex_destroy((pthread_mutex_t *)((char *)ptr + 8));
if ( a2 > 0 )
{
v2 = 0LL;
v3 = 0LL;
do
{
pthread_cond_destroy((pthread_cond_t *)(*((_QWORD *)ptr + 10) + v3));
pthread_cond_destroy((pthread_cond_t *)(*((_QWORD *)ptr + 11) + v3));
pthread_mutex_destroy((pthread_mutex_t *)(*((_QWORD *)ptr + 8) + v2));
pthread_mutex_destroy((pthread_mutex_t *)(*((_QWORD *)ptr + 9) + v2));
v3 += 48LL;
v2 += 40LL;
}
while ( v3 != 48LL * (unsigned int)a2 );
}
free(*((void **)ptr + 8));
free(*((void **)ptr + 9));
free(*((void **)ptr + 10));
free(*((void **)ptr + 11));
free(*((void **)ptr + 12));
free(*((void **)ptr + 13));
free(ptr);
}

original_code:
void free_thread_pool(Thread_pool * tp, int no_of_threads){
  free(tp->thread_ids);
  pthread_mutex_destroy(&tp->work_queue_mutex);
  for(int i = 0; i < no_of_threads; i++){
    pthread_cond_destroy(&tp->work_conds[i]);
    pthread_cond_destroy(&tp->finished_conds[i]);
    pthread_mutex_destroy(&tp->work_mutexes[i]);
    pthread_mutex_destroy(&tp->finished_mutexes[i]);
  }
  free(tp->work_mutexes);
  free(tp->finished_mutexes);
  free(tp->work_conds);
  free(tp->finished_conds);
  free(tp->work);
  free(tp->finished);
  free(tp);
}

canonical_original_code:
void free_thread_pool(struct Thread_pool *tp, int no_of_threads){
  free(tp->thread_ids);
  pthread_mutex_destroy(&tp->work_queue_mutex);
  for(int i = 0; i < no_of_threads; i++){
    pthread_cond_destroy(&tp->work_conds[i]);
    pthread_cond_destroy(&tp->finished_conds[i]);
    pthread_mutex_destroy(&tp->work_mutexes[i]);
    pthread_mutex_destroy(&tp->finished_mutexes[i]);
  }
  free(tp->work_mutexes);
  free(tp->finished_mutexes);
  free(tp->work_conds);
  free(tp->finished_conds);
  free(tp->work);
  free(tp->finished);
  free(tp);
}


decompiled_code:
void __fastcall free_thread_arg(void *a1)
{
free(a1);
}

canonical_decompiled_code:
void __fastcall func7(void *a1)
{
free(a1);
}

original_code:
void free_thread_arg(Thread_args * ta){
  free(ta);
}

canonical_original_code:
void free_thread_arg(struct Thread_args *ta){
  free(ta);
}


decompiled_code:
void __fastcall free_thread_args(void *ptr, int a2)
{
void **v2; // rbx

if ( a2 > 0 )
{
v2 = (void **)ptr;
do
free_thread_arg(*v2++);
while ( v2 != (void **)((char *)ptr + 8 * (unsigned int)(a2 - 1) + 8) );
}
free(ptr);
}

canonical_decompiled_code:
void __fastcall func8(void *ptr, int a2)
{
void **v2; // rbx

if ( a2 > 0 )
{
v2 = (void **)ptr;
do
func7(*v2++);
while ( v2 != (void **)((char *)ptr + 8 * (unsigned int)(a2 - 1) + 8) );
}
free(ptr);
}

original_code:
void free_thread_args(Thread_args ** tas, int no_of_threads){
  for(int i = 0; i < no_of_threads; i++){
    free_thread_arg(tas[i]);
  }
  free(tas);
}

canonical_original_code:
void free_thread_args(struct Thread_args **tas, int no_of_threads){
  for(int i = 0; i < no_of_threads; i++){
    free_thread_arg(tas[i]);
  }
  free(tas);
}

variable_types: struct Thread_args { struct Thread_pool { int work_queue; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } work_queue_mutex; int no_of_threads; unsigned long *thread_ids; union pthread_mutex_t *work_mutexes; union pthread_mutex_t *finished_mutexes; union pthread_cond_t { struct __pthread_cond_s { union { unsigned long long __wseq; struct { unsigned int __low; unsigned int __high; } __wseq32; }; union { unsigned long long __g1_start; struct { unsigned int __low; unsigned int __high; } __g1_start32; }; unsigned int __g_refs[2]; unsigned int __g_size[2]; unsigned int __g1_orig_size; unsigned int __wrefs; unsigned int __g_signals[2]; } __data; char __size[48]; long long __align; } *work_conds; union pthread_cond_t *finished_conds; int *work; int *finished; } *tp; int id; } **


decompiled_code:
float __fastcall anisotropic_distance(float *a1, float *a2, float result)
{
float v3; // xmm1_4
float v4; // xmm8_4
float v5; // xmm9_4
float v6; // xmm0_4

v3 = *a1 - *a2;
v4 = a1[1] - a2[1];
v5 = a1[2] - a2[2];
switch ( ANISOTROPIC )
{
case 0:
v6 = (float)((float)(v4 * v4) + (float)(v3 * v3)) + (float)(v5 * v5);
if ( v6 >= 0.0 )
return fsqrt(v6);
goto LABEL_12;
case 1:
v6 = (float)((float)(v5 * ANISO_MATRIX[8]) * v5)
+ (float)((float)(v3 * (float)(v3 * ANISO_MATRIX[0])) + (float)((float)(v4 * ANISO_MATRIX[4]) * v4));
if ( v6 >= 0.0 )
return fsqrt(v6);
goto LABEL_12;
case 2:
v6 = (float)((float)(v5 * ANISO_MATRIX[8]) * v5)
+ (float)((float)((float)((float)((float)((float)((float)((float)((float)(v3 * ANISO_MATRIX[0]) * v3)
+ (float)((float)(v4 * ANISO_MATRIX[1]) * v3))
+ (float)((float)(v5 * ANISO_MATRIX[2]) * v3))
+ (float)((float)(v3 * ANISO_MATRIX[3]) * v4))
+ (float)((float)(v4 * ANISO_MATRIX[4]) * v4))
+ (float)((float)(v5 * ANISO_MATRIX[5]) * v4))
+ (float)((float)(v3 * ANISO_MATRIX[6]) * v5))
+ (float)((float)(v4 * ANISO_MATRIX[7]) * v5));
if ( v6 >= 0.0 )
return fsqrt(v6);
LABEL_12:
result = sqrtf(v6);
break;
}
return result;
}

canonical_decompiled_code:
float __fastcall func0(float *a1, float *a2, float result)
{
float v3; // xmm1_4
float v4; // xmm8_4
float v5; // xmm9_4
float v6; // xmm0_4

v3 = *a1 - *a2;
v4 = a1[1] - a2[1];
v5 = a1[2] - a2[2];
switch ( ANISOTROPIC )
{
case 0:
v6 = (float)((float)(v4 * v4) + (float)(v3 * v3)) + (float)(v5 * v5);
if ( v6 >= 0.0 )
return fsqrt(v6);
goto LABEL_12;
case 1:
v6 = (float)((float)(v5 * ANISO_MATRIX[8]) * v5)
+ (float)((float)(v3 * (float)(v3 * ANISO_MATRIX[0])) + (float)((float)(v4 * ANISO_MATRIX[4]) * v4));
if ( v6 >= 0.0 )
return fsqrt(v6);
goto LABEL_12;
case 2:
v6 = (float)((float)(v5 * ANISO_MATRIX[8]) * v5)
+ (float)((float)((float)((float)((float)((float)((float)((float)((float)(v3 * ANISO_MATRIX[0]) * v3)
+ (float)((float)(v4 * ANISO_MATRIX[1]) * v3))
+ (float)((float)(v5 * ANISO_MATRIX[2]) * v3))
+ (float)((float)(v3 * ANISO_MATRIX[3]) * v4))
+ (float)((float)(v4 * ANISO_MATRIX[4]) * v4))
+ (float)((float)(v5 * ANISO_MATRIX[5]) * v4))
+ (float)((float)(v3 * ANISO_MATRIX[6]) * v5))
+ (float)((float)(v4 * ANISO_MATRIX[7]) * v5));
if ( v6 >= 0.0 )
return fsqrt(v6);
LABEL_12:
result = sqrtf(v6);
break;
}
return result;
}

original_code:
float anisotropic_distance(Point* a, Point* b){
  float dx = a->x - b->x;
  float dy = a->y - b->y;
  float dz = a->z - b->z;
  if(ANISOTROPIC == 0){
    return sqrt(dx*dx + dy*dy + dz*dz);
  }
  else if(ANISOTROPIC == 1){
    return sqrt( ANISO_MATRIX[0]*dx*dx + ANISO_MATRIX[4]*dy*dy + ANISO_MATRIX[8]*dz*dz);
  }
  else if(ANISOTROPIC == 2){
    return sqrt(ANISO_MATRIX[0]*dx*dx + ANISO_MATRIX[1]*dy*dx + ANISO_MATRIX[2]*dz*dx +
        ANISO_MATRIX[3]*dx*dy + ANISO_MATRIX[4]*dy*dy + ANISO_MATRIX[5]*dz*dy +
        ANISO_MATRIX[6]*dx*dz + ANISO_MATRIX[7]*dy*dz + ANISO_MATRIX[8]*dz*dz);
  }
}

canonical_original_code:
float anisotropic_distance(struct Point *a, struct Point *b){
  float dx = a->x - b->x;
  float dy = a->y - b->y;
  float dz = a->z - b->z;
  if(ANISOTROPIC == 0){
    return sqrt(dx*dx + dy*dy + dz*dz);
  }
  else if(ANISOTROPIC == 1){
    return sqrt( ANISO_MATRIX[0]*dx*dx + ANISO_MATRIX[4]*dy*dy + ANISO_MATRIX[8]*dz*dz);
  }
  else if(ANISOTROPIC == 2){
    return sqrt(ANISO_MATRIX[0]*dx*dx + ANISO_MATRIX[1]*dy*dx + ANISO_MATRIX[2]*dz*dx +
        ANISO_MATRIX[3]*dx*dy + ANISO_MATRIX[4]*dy*dy + ANISO_MATRIX[5]*dz*dy +
        ANISO_MATRIX[6]*dx*dz + ANISO_MATRIX[7]*dy*dz + ANISO_MATRIX[8]*dz*dz);
  }
}

variable_types: struct Point { float x; float y; float z; float intensity; } *

variable_types:
b
struct Point *

variable_types: dx float

variable_types: dy float

variable_types: dz float


variogram

decompiled_code:
float __fastcall variogram(float *a1, float *a2, float a3)
{
float v3; // xmm0_4

v3 = anisotropic_distance(a1, a2, a3);
return 1.0 - exp(COERCE_FLOAT(COERCE_UNSIGNED_INT(v3 / VARIOGRAM_RADIUS) ^ LC1));
}

canonical_decompiled_code:
float __fastcall func1(float *a1, float *a2, float a3)
{
float v3; // xmm0_4

v3 = func0(a1, a2, a3);
return 1.0 - exp(COERCE_FLOAT(COERCE_UNSIGNED_INT(v3 / VARIOGRAM_RADIUS) ^ LC1));
}

original_code:
float variogram(Point* a, Point* b){
  float d = anisotropic_distance(a, b);
  float r = (1 - exp(-(d/VARIOGRAM_RADIUS)));
  return r;
}

canonical_original_code:
float variogram(struct Point *a, struct Point *b){
  float d = anisotropic_distance(a, b);
  float r = (1 - exp(-(d/VARIOGRAM_RADIUS)));
  return r;
}

variable_types: d float

variable_types: r float


original_code:
void update_camera(Raycreator* rc, Lasso lasso){
  float dx1 = ((float)lasso.start_x)/RESOLUTION - 0.5;
  float dx2 = ((float)lasso.end_x)/RESOLUTION - 0.5;
  float dy1 = ((float)lasso.end_y)/RESOLUTION - 0.5;
  float dy2 = ((float)lasso.start_y)/RESOLUTION - 0.5;
  float screen_width = 2*0.1*tan(rc->fov);
  dx1 = dx1*screen_width;
  dx2 = dx2*screen_width;
  dy1 = dy1*screen_width;
  dy2 = dy2*screen_width;
  float ax1 = atan(dx1/0.1);
  float ax2 = atan(dx2/0.1);
  float ay1 = atan(dy1/0.1);
  float ay2 = atan(dy2/0.1);
  float angle_x = fabs(ax2 - ax1);
  float angle_y = fabs(ay2 - ay1);
  float angle = (angle_x > angle_y) ? angle_x : angle_y;
  float acx = (ax1 + ax2)/2.0;
  float acy = (ay1 + ay2)/2.0;
  float dcx = 0.1 * tan(acx);
  float dcy = 0.1 * tan(acy);
  Coord new_center = add_scaled_Coord(rc->eye, rc->forward, 0.1);
  new_center = add_scaled_Coord(new_center, rc->right, dcx);
  new_center = add_scaled_Coord(new_center, rc->up, -dcy);
  rc->forward = sub_Coord(new_center, rc->eye);
  rc->fov = angle/2.0;
}

canonical_original_code:
void update_camera(struct rcstruct *rc, struct Lasso lasso){
  float dx1 = ((float)lasso.start_x)/RESOLUTION - 0.5;
  float dx2 = ((float)lasso.end_x)/RESOLUTION - 0.5;
  float dy1 = ((float)lasso.end_y)/RESOLUTION - 0.5;
  float dy2 = ((float)lasso.start_y)/RESOLUTION - 0.5;
  float screen_width = 2*0.1*tan(rc->fov);
  dx1 = dx1*screen_width;
  dx2 = dx2*screen_width;
  dy1 = dy1*screen_width;
  dy2 = dy2*screen_width;
  float ax1 = atan(dx1/0.1);
  float ax2 = atan(dx2/0.1);
  float ay1 = atan(dy1/0.1);
  float ay2 = atan(dy2/0.1);
  float angle_x = fabs(ax2 - ax1);
  float angle_y = fabs(ay2 - ay1);
  float angle = (angle_x > angle_y) ? angle_x : angle_y;
  float acx = (ax1 + ax2)/2.0;
  float acy = (ay1 + ay2)/2.0;
  float dcx = 0.1 * tan(acx);
  float dcy = 0.1 * tan(acy);
  struct Coord new_center = add_scaled_Coord(rc->eye, rc->forward, 0.1);
  new_center = add_scaled_Coord(new_center, rc->right, dcx);
  new_center = add_scaled_Coord(new_center, rc->up, -dcy);
  rc->forward = sub_Coord(new_center, rc->eye);
  rc->fov = angle/2.0;
}

variable_types: struct rcstruct { int resolution; struct Ranges { float xmin; float xmax; float ymin; float ymax; float zmin; float zmax; float imin; float imax; } *ranges; float fov; struct Coord { float x; float y; float z; } eye; struct Coord forward; struct Coord right; struct Coord up; struct Coord screen_center; float pixel_width; } *

variable_types: struct Lasso { int start_x; int start_y; int end_x; int end_y; int active; struct Quad { float x; float y; float w; float h; struct Color { float a; float b; float g; float r; } c; } quad; }

variable_types: angle float

variable_types: acx float

variable_types: acy float

variable_types: dcx float

variable_types: dcy float

user_defined_types: struct rcstruct { int resolution; struct Ranges *ranges; float fov; struct Coord eye; struct Coord forward; struct Coord right; struct Coord up; struct Coord screen_center; float pixel_width; }


original_code:
void update_raycreator(Raycreator* rc){
  Coord eye = rc->eye;
  float eye_screen_d = 0.1;
  rc->pixel_width = 2*eye_screen_d*tan(rc->fov)/((float)rc->resolution);
  Coord forward = rc->forward;
  Coord right;
  Coord up;
  if(forward.x == 0 && forward.y == 0){
    right.x = 1; right.y = 0; right.z = 0;
    up.x = 0; up.y = 1; up.z = 0;
  }
  else{
    right.x = forward.y;
    right.y = -forward.x;
    right.z = 0;
    up.x = right.y*forward.z - right.z*forward.y;
    up.y = right.z*forward.x - right.x*forward.z;
    up.z = right.x*forward.y - right.y*forward.x;
  }
  normalize_Coord(&right);
  normalize_Coord(&up);
  normalize_Coord(&forward);
  rc->eye = eye;
  rc->forward = forward;
  rc->right = right;
  rc->up = up;
  rc->screen_center = add_scaled_Coord(eye, forward, eye_screen_d);
}

canonical_original_code:
void update_raycreator(struct rcstruct *rc){
  struct Coord eye = rc->eye;
  float eye_screen_d = 0.1;
  rc->pixel_width = 2*eye_screen_d*tan(rc->fov)/((float)rc->resolution);
  struct Coord forward = rc->forward;
  struct Coord right;
  struct Coord up;
  if(forward.x == 0 && forward.y == 0){
    right.x = 1; right.y = 0; right.z = 0;
    up.x = 0; up.y = 1; up.z = 0;
  }
  else{
    right.x = forward.y;
    right.y = -forward.x;
    right.z = 0;
    up.x = right.y*forward.z - right.z*forward.y;
    up.y = right.z*forward.x - right.x*forward.z;
    up.z = right.x*forward.y - right.y*forward.x;
  }
  normalize_Coord(&right);
  normalize_Coord(&up);
  normalize_Coord(&forward);
  rc->eye = eye;
  rc->forward = forward;
  rc->right = right;
  rc->up = up;
  rc->screen_center = add_scaled_Coord(eye, forward, eye_screen_d);
}

variable_types: struct Coord { float x; float y; float z; }

user_defined_types: struct Ranges { float xmin; float xmax; float ymin; float ymax; float zmin; float zmax; float imin; float imax; }


original_code:
void create_rays(Raycreator* rc, Ray* rays){
 Coord screen_center = rc->screen_center;
 Coord up = rc->up;
 Coord right = rc->right;
 Coord eye = rc->eye;
 float pixel_width = rc->pixel_width;
  Color color = {-1,-1,-1,-1};
  int half_res = rc->resolution/2;

#pragma omp parallel for
  for(int c = -half_res; c < half_res; c++){
    for(int d = -half_res; d < half_res; d++){
      int i = (c+half_res)*rc->resolution + (d + half_res);
      Coord end;
      end.x = screen_center.x + c*pixel_width*up.x + d*pixel_width*right.x;
      end.y = screen_center.y + c*pixel_width*up.y + d*pixel_width*right.y;
      end.z = screen_center.z + c*pixel_width*up.z + d*pixel_width*right.z;
      rays[i].start = end;
      rays[i].dir = sub_Coord(end, eye);
      rays[i].color = color;
      find_intersections(&rays[i], rc->ranges);
    }
  }
}

canonical_original_code:
void create_rays(struct rcstruct *rc, struct Ray *rays){
 struct Coord screen_center = rc->screen_center;
 struct Coord up = rc->up;
 struct Coord right = rc->right;
 struct Coord eye = rc->eye;
 float pixel_width = rc->pixel_width;
  struct Color color = {-1,-1,-1,-1};
  int half_res = rc->resolution/2;

#pragma omp parallel for
  for(int c = -half_res; c < half_res; c++){
    for(int d = -half_res; d < half_res; d++){
      int i = (c+half_res)*rc->resolution + (d + half_res);
      struct Coord end;
      end.x = screen_center.x + c*pixel_width*up.x + d*pixel_width*right.x;
      end.y = screen_center.y + c*pixel_width*up.y + d*pixel_width*right.y;
      end.z = screen_center.z + c*pixel_width*up.z + d*pixel_width*right.z;
      rays[i].start = end;
      rays[i].dir = sub_Coord(end, eye);
      rays[i].color = color;
      find_intersections(&rays[i], rc->ranges);
    }
  }
}

variable_types: struct Ray { struct Coord start; struct Coord dir; float distance; struct Color { float a; float b; float g; float r; } color; } *

variable_types: c int

variable_types: d int

variable_types: i int

user_defined_types: struct Coord { float x; float y; float z; }

user_defined_types: struct Ray { struct Coord start; struct Coord dir; float distance; struct Color color; }


original_code:
void find_intersections(Ray* ray, Ranges* ranges){
  Coord top = {ranges->xmax, ranges->ymax, ranges->zmax};
  Coord bottom = {ranges->xmin, ranges->ymin, ranges->zmin};
  Coord t1 = div_Coord(sub_Coord(top, ray->start), ray->dir, 1);
  Coord t2 = div_Coord(sub_Coord(bottom, ray->start), ray->dir, -1);
  Coord tmin = min_Coord(t1, t2);
  Coord tmax = max_Coord(t1, t2);
  float tnear = fmax(fmax(tmin.x, tmin.y), fmax(tmin.x, tmin.z));
  float tfar = fmin(fmin(tmax.x, tmax.y), fmin(tmax.x, tmax.z));
  if(tfar <= tnear){
    ray->distance = 0;
    return;
  }
  if(tfar <=0){
    ray->distance = -1;
    return;
  }
  Coord far = add_scaled_Coord(ray->start, ray->dir, tfar);
  tnear = fmax(0, tnear);
  ray->start = add_scaled_Coord(ray->start, ray->dir, tnear);
  ray->distance = distance_Coord(ray->start, far);
}

canonical_original_code:
void find_intersections(struct Ray *ray, struct Ranges *ranges){
  struct Coord top = {ranges->xmax, ranges->ymax, ranges->zmax};
  struct Coord bottom = {ranges->xmin, ranges->ymin, ranges->zmin};
  struct Coord t1 = div_Coord(sub_Coord(top, ray->start), ray->dir, 1);
  struct Coord t2 = div_Coord(sub_Coord(bottom, ray->start), ray->dir, -1);
  struct Coord tmin = min_Coord(t1, t2);
  struct Coord tmax = max_Coord(t1, t2);
  float tnear = fmax(fmax(tmin.x, tmin.y), fmax(tmin.x, tmin.z));
  float tfar = fmin(fmin(tmax.x, tmax.y), fmin(tmax.x, tmax.z));
  if(tfar <= tnear){
    ray->distance = 0;
    return;
  }
  if(tfar <=0){
    ray->distance = -1;
    return;
  }
  struct Coord far = add_scaled_Coord(ray->start, ray->dir, tfar);
  tnear = fmax(0, tnear);
  ray->start = add_scaled_Coord(ray->start, ray->dir, tnear);
  ray->distance = distance_Coord(ray->start, far);
}

variable_types: struct Ray { struct Coord { float x; float y; float z; } start; struct Coord dir; float distance; struct Color { float a; float b; float g; float r; } color; } *

variable_types: struct Ranges { float xmin; float xmax; float ymin; float ymax; float zmin; float zmax; float imin; float imax; } *

variable_types: tnear float

variable_types: tfar float


original_code:
void normalize_ray(Ray* r){
  float length = sqrt(r->dir.x*r->dir.x + r->dir.y*r->dir.y + r->dir.z*r->dir.z);
  r->dir.x = r->dir.x/length;
  r->dir.y = r->dir.y/length;
  r->dir.z = r->dir.z/length;
}

canonical_original_code:
void normalize_ray(struct Ray *r){
  float length = sqrt(r->dir.x*r->dir.x + r->dir.y*r->dir.y + r->dir.z*r->dir.z);
  r->dir.x = r->dir.x/length;
  r->dir.y = r->dir.y/length;
  r->dir.z = r->dir.z/length;
}

variable_types: length float

user_defined_types: struct Color { float a; float b; float g; float r; }


decompiled_code:
__int64 __fastcall trace_rays(int a1, int a2, int a3, double a4, double a5, double a6)
{
int v6; // ebx
__int64 v8; // rbp
double v9; // xmm0_8
__int64 result; // rax
int v11; // er13
_DWORD *v12; // rbp

v6 = a2;
v8 = images;
v9 = log2((double)a1);
result = (unsigned int)(RESOLUTION / a1);
if ( a2 < a3 )
{
v11 = RESOLUTION / a1;
v12 = (_DWORD *)(*(_QWORD *)(v8 + 8LL * (int)v9 - 32) + 4LL * a2);
do
{
result = trace_ray(rays + 44LL * (v11 * (v6 % a1) + RESOLUTION * v11 * (v6 / a1)), root, 0, v9, a5, a6);
*v12 = result;
++v6;
++v12;
}
while ( a3 != v6 );
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(int a1, int a2, int a3, double a4, double a5, double a6)
{
int v6; // ebx
__int64 v8; // rbp
double v9; // xmm0_8
__int64 result; // rax
int v11; // er13
_DWORD *v12; // rbp

v6 = a2;
v8 = images;
v9 = log2((double)a1);
result = (unsigned int)(RESOLUTION / a1);
if ( a2 < a3 )
{
v11 = RESOLUTION / a1;
v12 = (_DWORD *)(*(_QWORD *)(v8 + 8LL * (int)v9 - 32) + 4LL * a2);
do
{
result = func1(rays + 44LL * (v11 * (v6 % a1) + RESOLUTION * v11 * (v6 / a1)), root, 0, v9, a5, a6);
*v12 = result;
++v6;
++v12;
}
while ( a3 != v6 );
}
return result;
}

original_code:
void* trace_rays(int resolution, int start, int stop){
  Display_color* image = images[(int)log2(resolution) - 4];
  int limit = resolution*resolution/64;
  int factor = RESOLUTION/resolution;
  for(int c = start; c < stop; c++){
    int row = c/resolution;
    int col = c%resolution;
    row *= factor;
    col *= factor;
    image[c] = trace_ray(&rays[row*RESOLUTION + col], root, 0);
  }
}

canonical_original_code:
void *trace_rays(int resolution, int start, int stop){
  struct Display_color *image = images[(int)log2(resolution) - 4];
  int limit = resolution*resolution/64;
  int factor = RESOLUTION/resolution;
  for(int c = start; c < stop; c++){
    int row = c/resolution;
    int col = c%resolution;
    row *= factor;
    col *= factor;
    image[c] = trace_ray(&rays[row*RESOLUTION + col], root, 0);
  }
}

variable_types: resolution int

variable_types: start int

variable_types: stop int

variable_types: struct Display_color { unsigned char a; unsigned char b; unsigned char g; unsigned char r; } *

variable_types: limit int

variable_types: factor int

variable_types: row int

variable_types: col int


decompiled_code:
int __fastcall print_ray(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, double a7, double a8, double a9, double a10, double a11, double a12, double a13, double a14, __int64 a15, __int64 a16, __int64 a17, float a18)
{
printf("Start: ");
printf("%f,%f,%f\n", *(float *)&a15, *((float *)&a15 + 1), *(float *)&a16);
printf("Dir: ");
printf("%f,%f,%f\n", *((float *)&a16 + 1), *(float *)&a17, *((float *)&a17 + 1));
printf("Dist: ");
return printf("%f\n", a18);
}

canonical_decompiled_code:
int __fastcall func3(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, double a7, double a8, double a9, double a10, double a11, double a12, double a13, double a14, __int64 a15, __int64 a16, __int64 a17, float a18)
{
printf("Start: ");
printf("%f,%f,%f\n", *(float *)&a15, *((float *)&a15 + 1), *(float *)&a16);
printf("Dir: ");
printf("%f,%f,%f\n", *((float *)&a16 + 1), *(float *)&a17, *((float *)&a17 + 1));
printf("Dist: ");
return printf("%f\n", a18);
}

original_code:
void print_ray(Ray r){
  printf("Start: ");
  printf("%f,%f,%f\n", r.start.x, r.start.y, r.start.z);
  printf("Dir: ");
  printf("%f,%f,%f\n", r.dir.x, r.dir.y, r.dir.z);
  printf("Dist: ");
  printf("%f\n", r.distance);
}

canonical_original_code:
void print_ray(struct Ray r){
  printf("Start: ");
  printf("%f,%f,%f\n", r.start.x, r.start.y, r.start.z);
  printf("Dir: ");
  printf("%f,%f,%f\n", r.dir.x, r.dir.y, r.dir.z);
  printf("Dist: ");
  printf("%f\n", r.distance);
}

variable_types: struct Ray { struct Coord { float x; float y; float z; } start; struct Coord dir; float distance; struct Color { float a; float b; float g; float r; } color; }


decompiled_code:
_BOOL8 __fastcall batch_has_next(__int64 a1)
{
return *(_DWORD *)(a1 + 20) < *(_DWORD *)(a1 + 16);
}

canonical_decompiled_code:
_BOOL8 __fastcall func1(__int64 a1)
{
return *(_DWORD *)(a1 + 20) < *(_DWORD *)(a1 + 16);
}

original_code:
int batch_has_next(Batch* b){
  if(b->current_pos < b->num_positions){
    return 1;
  }
  else{
    return 0;
  }
}

canonical_original_code:
int batch_has_next(struct Batch *b){
  if(b->current_pos < b->num_positions){
    return 1;
  }
  else{
    return 0;
  }
}

variable_types: struct Batch { struct Coord { float x; float y; float z; } *positions; int *transitions; int num_positions; int current_pos; int current_pos_progress; int pic_number; } *

user_defined_types: struct Batch { struct Coord *positions; int *transitions; int num_positions; int current_pos; int current_pos_progress; int pic_number; }


rotate

original_code:
Coord rotate(Coord v1, Coord v2, double fraction){
  double angle = angle_between_Coords(v1,v2);
  angle = angle*fraction;
  Coord axis = cross_product(v1,v2);
  if(length_Coord(axis) == 0){
    fprintf(stderr, "ERROR: Plane undefined. Exiting\n");
    exit(-1);
  }
  normalize_Coord(&axis);
  Coord r;
  double u = axis.x; double v = axis.y; double w = axis.z;
  double x = v1.x; double y = v1.y; double z = v1.z;
  r.x = u*(u*x+v*y+w*z)*(1-cos(angle)) + x*cos(angle) + (-w*y+v*z)*sin(angle);
  r.y = v*(u*x+v*y+w*z)*(1-cos(angle)) + y*cos(angle) + (w*x-u*z)*sin(angle);
  r.z = w*(u*x+v*y+w*z)*(1-cos(angle)) + z*cos(angle) + (-v*x+u*y)*sin(angle);
  return r;
}

canonical_original_code:
struct Coord rotate(struct Coord v1, struct Coord v2, double fraction){
  double angle = angle_between_Coords(v1,v2);
  angle = angle*fraction;
  struct Coord axis = cross_product(v1,v2);
  if(length_Coord(axis) == 0){
    fprintf(stderr, "ERROR: Plane undefined. Exiting\n");
    exit(-1);
  }
  normalize_Coord(&axis);
  struct Coord r;
  double u = axis.x; double v = axis.y; double w = axis.z;
  double x = v1.x; double y = v1.y; double z = v1.z;
  r.x = u*(u*x+v*y+w*z)*(1-cos(angle)) + x*cos(angle) + (-w*y+v*z)*sin(angle);
  r.y = v*(u*x+v*y+w*z)*(1-cos(angle)) + y*cos(angle) + (w*x-u*z)*sin(angle);
  r.z = w*(u*x+v*y+w*z)*(1-cos(angle)) + z*cos(angle) + (-v*x+u*y)*sin(angle);
  return r;
}

variable_types: fraction double

variable_types: angle double

variable_types: struct Coord { float x; float y; float z; }

variable_types: u double

variable_types: v double

variable_types: w double

variable_types: x double

variable_types: y double

variable_types: z double


original_code:
void batch_next(Batch* b, Raycreator* rc){
  b->pic_number++;
  if(b->current_pos == b->num_positions -1){
    rc->eye = b->positions[b->current_pos * 2];
    rc->forward = b->positions[b->current_pos* 2 + 1];
    b->current_pos++;
  }
  else{
    Coord pos;
    Coord dir;
    double aaa = (double)(b->current_pos_progress);
    double bbb = (double)(b->transitions[b->current_pos]);
    double weight = aaa / bbb;
    pos.x = (1-weight)*b->positions[b->current_pos*2].x + weight*b->positions[(b->current_pos + 1)*2].x;
    pos.y = (1-weight)*b->positions[b->current_pos*2].y + weight*b->positions[(b->current_pos + 1)*2].y;
    pos.z = (1-weight)*b->positions[b->current_pos*2].z + weight*b->positions[(b->current_pos + 1)*2].z;
    dir = rotate(b->positions[b->current_pos*2 + 1],b->positions[(b->current_pos+1)*2 + 1], weight);
    rc->eye = pos;
    rc->forward = dir;
    print_coord(dir);
    b->current_pos_progress++;
    if(b->current_pos_progress == b->transitions[b->current_pos]){
      b->current_pos_progress = 0;
      b->current_pos++;
    }
  }
}

canonical_original_code:
void batch_next(struct Batch *b, struct rcstruct *rc){
  b->pic_number++;
  if(b->current_pos == b->num_positions -1){
    rc->eye = b->positions[b->current_pos * 2];
    rc->forward = b->positions[b->current_pos* 2 + 1];
    b->current_pos++;
  }
  else{
    struct Coord pos;
    struct Coord dir;
    double aaa = (double)(b->current_pos_progress);
    double bbb = (double)(b->transitions[b->current_pos]);
    double weight = aaa / bbb;
    pos.x = (1-weight)*b->positions[b->current_pos*2].x + weight*b->positions[(b->current_pos + 1)*2].x;
    pos.y = (1-weight)*b->positions[b->current_pos*2].y + weight*b->positions[(b->current_pos + 1)*2].y;
    pos.z = (1-weight)*b->positions[b->current_pos*2].z + weight*b->positions[(b->current_pos + 1)*2].z;
    dir = rotate(b->positions[b->current_pos*2 + 1],b->positions[(b->current_pos+1)*2 + 1], weight);
    rc->eye = pos;
    rc->forward = dir;
    print_coord(dir);
    b->current_pos_progress++;
    if(b->current_pos_progress == b->transitions[b->current_pos]){
      b->current_pos_progress = 0;
      b->current_pos++;
    }
  }
}

variable_types: struct rcstruct { int resolution; struct Ranges { float xmin; float xmax; float ymin; float ymax; float zmin; float zmax; float imin; float imax; } *ranges; float fov; struct Coord eye; struct Coord forward; struct Coord right; struct Coord up; struct Coord screen_center; float pixel_width; } *

variable_types: aaa double

variable_types: bbb double

variable_types: weight double


decompiled_code:
int __fastcall print_batch(__int64 a1)
{
__int64 v1; // rbx
int v2; // er12
int result; // eax
__int64 v4; // rbx

if ( *(int *)(a1 + 16) > 0 )
{
v1 = 0LL;
v2 = 0;
do
{
print_coord(*(double *)(*(_QWORD *)a1 + v1), *(float *)(*(_QWORD *)a1 + v1 + 8));
print_coord(*(double *)(*(_QWORD *)a1 + v1 + 12), *(float *)(*(_QWORD *)a1 + v1 + 20));
result = putchar(10);
++v2;
v1 += 24LL;
}
while ( *(_DWORD *)(a1 + 16) > v2 );
}
if ( *(int *)(a1 + 16) > 1 )
{
v4 = 0LL;
do
{
printf("%d\n", *(unsigned int *)(*(_QWORD *)(a1 + 8) + 4 * v4++));
result = *(_DWORD *)(a1 + 16) - 1;
}
while ( result > (int)v4 );
}
return result;
}

original_code:
void print_batch(Batch* b){
  for(int c = 0; c < b->num_positions; c++){
    print_coord(b->positions[2*c]);
    print_coord(b->positions[2*c+1]);
    printf("\n");
  }
  for(int c = 0; c < b->num_positions -1; c++){
    printf("%d\n", b->transitions[c]);
  }
}

canonical_original_code:
void print_batch(struct Batch *b){
  for(int c = 0; c < b->num_positions; c++){
    print_coord(b->positions[2*c]);
    print_coord(b->positions[2*c+1]);
    printf("\n");
  }
  for(int c = 0; c < b->num_positions -1; c++){
    printf("%d\n", b->transitions[c]);
  }
}

variable_types: c int


decompiled_code:
__int64 __fastcall to_display_color(double a1, double a2)
{
float v2; // edx
__int64 v3; // xmm0_8
float v4; // xmm3_4
float v5; // xmm1_4
unsigned __int16 v6; // ax

v2 = *(float *)&a1;
v3 = HIDWORD(*(_QWORD *)&a1);
v4 = *(float *)&a2;
LODWORD(a2) = HIDWORD(a2);
if ( *((float *)&a2 + 1) > 1.0 )
v5 = *(float *)&LC0;
if ( *(float *)&v3 > 1.0 )
LODWORD(v3) = LC0;
if ( v4 > 1.0 )
v4 = *(float *)&LC0;
LOBYTE(v6) = (int)(float)(v2 * 255.0);
HIBYTE(v6) = (int)(float)(*(float *)&v3 * 255.0);
return ((int)(float)(v5 * 255.0) << 24) | ((unsigned __int8)(int)(float)(v4 * 255.0) << 16) | (unsigned int)v6;
}

canonical_decompiled_code:
__int64 __fastcall func0(double a1, double a2)
{
float v2; // edx
__int64 v3; // xmm0_8
float v4; // xmm3_4
float v5; // xmm1_4
unsigned __int16 v6; // ax

v2 = *(float *)&a1;
v3 = HIDWORD(*(_QWORD *)&a1);
v4 = *(float *)&a2;
LODWORD(a2) = HIDWORD(a2);
if ( *((float *)&a2 + 1) > 1.0 )
v5 = *(float *)&LC0;
if ( *(float *)&v3 > 1.0 )
LODWORD(v3) = LC0;
if ( v4 > 1.0 )
v4 = *(float *)&LC0;
LOBYTE(v6) = (int)(float)(v2 * 255.0);
HIBYTE(v6) = (int)(float)(*(float *)&v3 * 255.0);
return ((int)(float)(v5 * 255.0) << 24) | ((unsigned __int8)(int)(float)(v4 * 255.0) << 16) | (unsigned int)v6;
}

original_code:
Display_color to_display_color(Color c){
  Display_color dc;
  if(c.r > 1.0){
    c.r = 1.0;
  }
  if(c.b > 1.0){
    c.b = 1.0;
  }
  if(c.g > 1.0){
    c.g = 1.0;
  }
  dc.a = (unsigned char)(c.a*255);
  dc.r = (unsigned char)(c.r*255);
  dc.g = (unsigned char)(c.g*255);
  dc.b = (unsigned char)(c.b*255);
  return dc;
}

canonical_original_code:
struct Display_color to_display_color(struct Color c){
  struct Display_color dc;
  if(c.r > 1.0){
    c.r = 1.0;
  }
  if(c.b > 1.0){
    c.b = 1.0;
  }
  if(c.g > 1.0){
    c.g = 1.0;
  }
  dc.a = (unsigned char)(c.a*255);
  dc.r = (unsigned char)(c.r*255);
  dc.g = (unsigned char)(c.g*255);
  dc.b = (unsigned char)(c.b*255);
  return dc;
}

variable_types: struct Color { float a; float b; float g; float r; }

variable_types: struct Display_color { unsigned char a; unsigned char b; unsigned char g; unsigned char r; }


blend

decompiled_code:
__int64 __fastcall blend(float *a1, float a2)
{
__int64 result; // rax
float v3; // xmm1_4
float v4; // xmm0_4
int v5[6]; // [rsp+0h] [rbp-18h] BYREF

result = set_color_from_table(transfer_overlay, v5, a2 / *(float *)(transfer_overlay + 40LL));
v3 = *a1;
v4 = (float)(1.0 - *a1) * *(float *)v5;
a1[3] = (float)(v4 * *(float *)&v5[3]) + a1[3];
a1[2] = (float)(v4 * *(float *)&v5[2]) + a1[2];
a1[1] = (float)(v4 * *(float *)&v5[1]) + a1[1];
*a1 = v4 + v3;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(float *a1, float a2)
{
__int64 result; // rax
float v3; // xmm1_4
float v4; // xmm0_4
int v5[6]; // [rsp+0h] [rbp-18h] BYREF

result = set_color_from_table(transfer_overlay, v5, a2 / *(float *)(transfer_overlay + 40LL));
v3 = *a1;
v4 = (float)(1.0 - *a1) * *(float *)v5;
a1[3] = (float)(v4 * *(float *)&v5[3]) + a1[3];
a1[2] = (float)(v4 * *(float *)&v5[2]) + a1[2];
a1[1] = (float)(v4 * *(float *)&v5[1]) + a1[1];
*a1 = v4 + v3;
return result;
}

original_code:
void blend(Color* output, float intensity){
  Color new_color;
  set_color_from_table(transfer_overlay, intensity/transfer_overlay->max_intensity, &new_color);
  output->r = output->r + (1-output->a)*new_color.a*new_color.r;
  output->g = output->g + (1-output->a)*new_color.a*new_color.g;
  output->b = output->b + (1-output->a)*new_color.a*new_color.b;
  output->a = output->a + (1-output->a)*new_color.a;
}

canonical_original_code:
void blend(struct Color *output, float intensity){
  struct Color new_color;
  set_color_from_table(transfer_overlay, intensity/transfer_overlay->max_intensity, &new_color);
  output->r = output->r + (1-output->a)*new_color.a*new_color.r;
  output->g = output->g + (1-output->a)*new_color.a*new_color.g;
  output->b = output->b + (1-output->a)*new_color.a*new_color.b;
  output->a = output->a + (1-output->a)*new_color.a;
}

variable_types: struct Color { float a; float b; float g; float r; } *

variable_types: intensity float


decompiled_code:
int __fastcall print_color(__m128i a1, __m128i a2)
{
return printf(
"%f, %f, %f, %f\n",
*(float *)&a2.m128i_i32[1],
COERCE_FLOAT(_mm_cvtsi128_si32(a2)),
*(float *)&a1.m128i_i32[1],
COERCE_FLOAT(_mm_cvtsi128_si32(a1)));
}

canonical_decompiled_code:
int __fastcall func2(__m128i a1, __m128i a2)
{
return printf(
"%f, %f, %f, %f\n",
*(float *)&a2.m128i_i32[1],
COERCE_FLOAT(_mm_cvtsi128_si32(a2)),
*(float *)&a1.m128i_i32[1],
COERCE_FLOAT(_mm_cvtsi128_si32(a1)));
}

original_code:
void print_color(Color c){
  printf("%f, %f, %f, %f\n", c.r, c.g, c.b, c.a);
}

canonical_original_code:
void print_color(struct Color c){
  printf("%f, %f, %f, %f\n", c.r, c.g, c.b, c.a);
}