// File: /workspace/github_cpp_makefile_star2_O3/tomfunkhouser[P]gaps/pkgs/R3Shapes/R3MeshPropertySet.cpp
// Function: gaps::R3MeshPropertySet::ReadNumpy(char const*)
int R3MeshPropertySet::
ReadNumpy(const char *filename)
{
  // Open file
  FILE *fp = fopen(filename, "rb");
  if (!fp) {
    fprintf(stderr, "Unable to open npy file %s\n", filename);
    return 0;
  }
  
  // Read magic string
  unsigned char magic[6];
  if (fread(magic, sizeof(unsigned char), 6, fp) != (unsigned int) 6) {
    fprintf(stderr, "Unable to read first character from npy file\n");
    fclose(fp);
    return 0;
  }

  // Check magic string
  if ((magic[0] != 0x93) || (magic[1] != 'N') || (magic[2] != 'U') ||
      (magic[3] != 'M')  || (magic[4] != 'P') || (magic[5] != 'Y')) {
    fprintf(stderr, "Unrecognized format in npy file\n");
    fclose(fp);
    return 0;
  }

  // Read version info
  unsigned char version[2];
  if (fread(version, sizeof(unsigned char), 2, fp) != (unsigned int) 2) {
    fprintf(stderr, "Unable to read version in npy file\n");
    fclose(fp);
    return 0;
  }
  
  // Read header length
  unsigned short int header_length;
  if (fread(&header_length, sizeof(unsigned short), 1, fp) != (unsigned int) 1) {
    fprintf(stderr, "Unable to read header length in npy file\n");
    fclose(fp);
    return 0;
  }

  // Check header length
  if (header_length <= 0) {
    fprintf(stderr, "Invalid header length in npy file\n");
    fclose(fp);
    return 0;
  }

  // Read header
  char *header = new char [ header_length + 1 ];
  if (fread(header, sizeof(char), header_length, fp) != (unsigned int) header_length) {
    fprintf(stderr, "Unable to read header in npy file\n");
    delete [] header;
    fclose(fp);
    return 0;
  }
  header[header_length] = '\0';

  // Extract data type and size
  int data_type = 0;
  int data_size = 0;
  char *start = strstr(header, "'descr'");
  if (start) {
    start = strchr(start, '<');
    if (start) {
      start++;
      while (*start == ' ') start++;
      data_type = *start;
      start++;
      char *end = strchr(start, '\'');
      if (end && (start < end)) {
        *end = '\0';
        data_size = atoi(start);
        *end = '\'';
      }
    }
  }

  // Extract fortrain order
  int fortran_order = 0;
  start = strstr(header, "'fortran_order'");
  if (start) {
    start = strchr(start, ':');
    if (start) {
      start++;
      while (*start == ' ') start++;
      char *end = strchr(start, ',');
      if (end && (start < end)) {
        *end = '\0';
        if (!strcmp(start, "True")) fortran_order = 1;
        if (!strcmp(start, "true")) fortran_order = 1;
        *end = ',';
      }
    }
  }

  // Extract width
  int width = 1;
  start = strstr(header, "'shape'");
  if (start) {
    start = strchr(start, '(');
    if (start) {
      start++;
      while (*start == ' ') start++;
      char *end = strchr(start, ',');
      if (end && (start < end)) {
        *end = '\0';
        width = atoi(start);
        *end = ',';
      }
    }
  }

  // Extract height
  int height = 1;
  start = strstr(header, "'shape'");
  if (start) {
    start = strchr(start, ',');
    if (start) {
      start++;
      while (*start == ' ') start++;
      char *end1 = strchr(start, ',');
      char *end2 = strchr(start, ')');
      char *end = (end1 < end2) ? end1 : end2;
      if (end && (start < end)) {
        *end = '\0';
        height = atoi(start);
        *end = ')';
      }
    }
  }

  // Delete header
  delete [] header;

  // Read values
  unsigned int nbytes = width * height * NumpyDataTypeSize(data_type, data_size);
  unsigned char *array = new unsigned char [ nbytes ];
  unsigned int read_nbytes = 0;
  while (read_nbytes < nbytes) {
    size_t k = fread(&array[read_nbytes], sizeof(unsigned char), nbytes - read_nbytes, fp);
    if (k <= 0) {
      fprintf(stderr, "Unable to read array in npy file (%lu %u %u)\n", k, read_nbytes, nbytes);
      if (k < 0) {
        delete [] array;
        fclose(fp);
        return 0;
      }
    }
    read_nbytes += k;
  }

  // Close file
  fclose(fp);

  // Create properties
  for (int j = 0; j < height; j++) {
    char property_name[128];
    sprintf(property_name, "P%d", j);
    Insert(new R3MeshProperty(mesh, property_name));
  }

  // Fill property values
  unsigned char *arrayp = array;
  if (fortran_order) {
    // Fortran order
    for (int j = 0; j < height; j++) {
      for (int i = 0; i < width; i++) {
        if (data_size == 4) {
          float *a = (float *) arrayp;
          Property(j)->SetVertexValue(i, (float) *a);
          arrayp += 4;
        }
        else if (data_size == 8) {
          double *a = (double *) arrayp;
          Property(j)->SetVertexValue(i, (float) *a);
          arrayp += 8;
        }
      }
    }
  }
  else {
    // C order
    for (int i = 0; i < width; i++) {
      for (int j = 0; j < height; j++) {
        if (data_size == 4) {
          float *a = (float *) arrayp;
          Property(j)->SetVertexValue(i, (float) *a);
          arrayp += 4;
        }
        else if (data_size == 8) {
          double *a = (double *) arrayp;
          Property(j)->SetVertexValue(i, (float) *a);
          arrayp += 8;
        }
      }
    }
  }

  // Delete array
  delete [] array;
  
  // Return success
  return 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc8, %rsp
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x984de(%rip), %rsi     # 0xdf376
movq %r14, %rdi
callq 0x21a90
testq %rax, %rax
je 0x4738a
leaq 0x20(%rsp), %rdi
movl $0x1, %esi
movl $0x6, %edx
movq %rax, %rbp
movq %rax, %rcx
callq 0x21e20
cmpq $0x6, %rax
jne 0x473a9
cmpl $0x4d554e93, 0x20(%rsp) # imm = 0x4D554E93
jne 0x473b3
cmpb $0x50, 0x24(%rsp)
jne 0x473b3
cmpb $0x59, 0x25(%rsp)
jne 0x473b3
leaq 0x36(%rsp), %rdi
movl $0x1, %esi
movl $0x2, %edx
movq %rbp, %r14
movq %rbp, %rcx
callq 0x21e20
cmpq $0x2, %rax
jne 0x473bd
leaq 0x16(%rsp), %rdi
movl $0x2, %esi
movl $0x1, %edx
movq %r14, %rcx
callq 0x21e20
cmpq $0x1, %rax
jne 0x473c7
movzwl 0x16(%rsp), %r14d
testq %r14, %r14
je 0x473d1
leaq 0x1(%r14), %rdi
callq 0x21040
movq %rax, %r12
movl $0x1, %esi
movq %rax, %rdi
movq %r14, %rdx
movq %rbp, %rcx
callq 0x21e20
cmpq %r14, %rax
jne 0x473db
movb $0x0, (%r12,%r14)
leaq 0x9a11c(%rip), %rsi     # 0xe1095
movq %r12, %rdi
callq 0x21170
xorl %r14d, %r14d
testq %rax, %rax
movq %r12, 0x8(%rsp)
movq %rbx, 0x28(%rsp)
je 0x46fea
movq %rax, %rdi
movl $0x3c, %esi
callq 0x21320
testq %rax, %rax
je 0x46fea
movq %rax, %r15
incq %r15
movq %rbp, %rbx
movsbl (%r15), %r13d
incq %r15
cmpl $0x20, %r13d
je 0x46fae
movq %r15, %rdi
movl $0x27, %esi
callq 0x21320
cmpq %rax, %r15
jae 0x46fe3
movq %rax, %r12
movb $0x0, (%rax)
movq %r15, %rdi
callq 0x21ec0
movl %eax, %r14d
movb $0x27, (%r12)
movq 0x8(%rsp), %r12
jmp 0x46ff0
xorl %r13d, %r13d
movq %rbp, %rbx
leaq 0x9a0a6(%rip), %rsi     # 0xe109d
movq %r12, %rdi
callq 0x21170
testq %rax, %rax
je 0x47079
movq %rax, %rdi
movl $0x3a, %esi
callq 0x21320
testq %rax, %rax
je 0x47079
movq %rax, %r15
movb $0x1, 0x3(%rsp)
cmpb $0x20, 0x1(%r15)
leaq 0x1(%r15), %r15
je 0x4701e
movq %r15, %rdi
movl $0x2c, %esi
callq 0x21320
cmpq %rax, %r15
jae 0x4707e
movq %rax, %r12
movb $0x0, (%rax)
leaq 0x9a065(%rip), %rsi     # 0xe10ad
movq %r15, %rdi
callq 0x21ce0
testl %eax, %eax
setne %bl
leaq 0x9a056(%rip), %rsi     # 0xe10b2
movq %r15, %rdi
callq 0x21ce0
testl %eax, %eax
setne %al
andb %bl, %al
movb %al, 0x3(%rsp)
movq %rbp, %rbx
movb $0x2c, (%r12)
jmp 0x4707e
movb $0x1, 0x3(%rsp)
leaq 0x9a032(%rip), %rsi     # 0xe10b7
movq 0x8(%rsp), %rdi
callq 0x21170
movl $0x1, 0x4(%rsp)
movl $0x1, %ebp
testq %rax, %rax
je 0x470f2
movq %rax, %rdi
movl $0x28, %esi
callq 0x21320
movl $0x1, %ebp
testq %rax, %rax
je 0x470f2
movq %rax, %r15
cmpb $0x20, 0x1(%r15)
leaq 0x1(%r15), %r15
je 0x470bb
movq %r15, %rdi
movl $0x2c, %esi
callq 0x21320
movl $0x1, %ebp
cmpq %rax, %r15
jae 0x470f2
movq %rax, %r12
movb $0x0, (%rax)
movq %r15, %rdi
callq 0x21ec0
movl %eax, %ebp
movb $0x2c, (%r12)
leaq 0x99fbe(%rip), %rsi     # 0xe10b7
movq 0x8(%rsp), %rdi
callq 0x21170
testq %rax, %rax
je 0x47171
movq %rax, %rdi
movl $0x2c, %esi
callq 0x21320
testq %rax, %rax
je 0x47171
movq %rax, %r15
cmpb $0x20, 0x1(%r15)
leaq 0x1(%r15), %r15
je 0x4711d
movq %r15, %rdi
movl $0x2c, %esi
callq 0x21320
movq %rax, 0x18(%rsp)
movq %r15, %rdi
movl $0x29, %esi
callq 0x21320
movq %rax, %r12
movq 0x18(%rsp), %rax
cmpq %r12, %rax
cmovbq %rax, %r12
cmpq %r12, %r15
jae 0x47171
movb $0x0, (%r12)
movq %r15, %rdi
callq 0x21ec0
movl %eax, 0x4(%rsp)
movb $0x29, (%r12)
movq 0x8(%rsp), %rdi
callq 0x21c00
leal (,%r14,4), %eax
cmpl $0x55, %r13d
cmovnel %r14d, %eax
movl %ebp, 0x8(%rsp)
movl %ebp, %r15d
imull 0x4(%rsp), %r15d
imull %eax, %r15d
movq %r15, %rdi
callq 0x21040
movq %rax, 0x18(%rsp)
testl %r15d, %r15d
je 0x47201
movq 0xfcdf3(%rip), %rbp     # 0x143fa8
xorl %r12d, %r12d
movl %r12d, %edi
addq 0x18(%rsp), %rdi
movl %r15d, %edx
subl %r12d, %edx
movl $0x1, %esi
movq %rbx, %rcx
callq 0x21e20
movq %rax, %r13
testq %rax, %rax
je 0x471e5
addl %r13d, %r12d
cmpl %r15d, %r12d
jb 0x471b8
jmp 0x47201
movq (%rbp), %rdi
leaq 0x99ecf(%rip), %rsi     # 0xe10bf
xorl %edx, %edx
movl %r12d, %ecx
movl %r15d, %r8d
xorl %eax, %eax
callq 0x21d60
jmp 0x471db
movq %rbx, %rdi
callq 0x218a0
cmpl $0x0, 0x4(%rsp)
jle 0x47289
movq 0x28(%rsp), %rbx
leaq 0x8(%rbx), %rax
movq %rax, 0x38(%rsp)
leaq 0x40(%rsp), %r12
xorl %r13d, %r13d
movl 0x8(%rsp), %ebp
movq %r12, %rdi
leaq 0x99eb9(%rip), %rsi     # 0xe10ed
movl %r13d, %edx
xorl %eax, %eax
callq 0x21130
movl $0x448, %edi            # imm = 0x448
callq 0x218b0
movq %rax, %r15
movq (%rbx), %rsi
movq %rax, %rdi
movq %r12, %rdx
xorl %ecx, %ecx
callq 0x48134
movl 0x14(%rbx), %edx
movq 0x38(%rsp), %rdi
movq %r15, %rsi
callq 0x8bdb2
incl %r13d
cmpl %r13d, 0x4(%rsp)
jne 0x4722a
cmpb $0x0, 0x3(%rsp)
je 0x47308
testl %ebp, %ebp
jg 0x4729b
jmp 0x47379
cmpl $0x0, 0x8(%rsp)
setg %al
testb %al, 0x3(%rsp)
je 0x47379
movl 0x4(%rsp), %r12d
xorl %r15d, %r15d
movq 0x18(%rsp), %r13
cmpl $0x0, 0x4(%rsp)
jle 0x472fc
xorl %ebp, %ebp
cmpl $0x8, %r14d
je 0x472ca
cmpl $0x4, %r14d
jne 0x472f4
movss (%r13), %xmm0
movl $0x4, %ebx
jmp 0x472d8
xorps %xmm0, %xmm0
cvtsd2ss (%r13), %xmm0
movl $0x8, %ebx
movq 0x28(%rsp), %rax
movq 0x8(%rax), %rax
movq (%rax,%rbp,8), %rdi
cvtss2sd %xmm0, %xmm0
movl %r15d, %esi
callq 0x49b8e
addq %rbx, %r13
incq %rbp
cmpq %rbp, %r12
jne 0x472b1
incl %r15d
cmpl 0x8(%rsp), %r15d
jne 0x472a8
jmp 0x47379
cmpl $0x0, 0x4(%rsp)
jle 0x47379
movl 0x4(%rsp), %ebx
xorl %r13d, %r13d
movq 0x18(%rsp), %r12
testl %ebp, %ebp
jle 0x47371
xorl %r15d, %r15d
cmpl $0x8, %r14d
je 0x4733b
cmpl $0x4, %r14d
jne 0x47369
movss (%r12), %xmm0
movl $0x4, %ebp
jmp 0x47349
xorps %xmm0, %xmm0
cvtsd2ss (%r12), %xmm0
movl $0x8, %ebp
movq 0x28(%rsp), %rax
movq 0x8(%rax), %rax
movq (%rax,%r13,8), %rdi
cvtss2sd %xmm0, %xmm0
movl %r15d, %esi
callq 0x49b8e
addq %rbp, %r12
movl 0x8(%rsp), %ebp
incl %r15d
cmpl %r15d, %ebp
jne 0x47322
incq %r13
cmpq %rbx, %r13
jne 0x4731b
movq 0x18(%rsp), %rdi
callq 0x21c00
movl $0x1, %ebx
jmp 0x473e8
movq 0xfcc17(%rip), %rax     # 0x143fa8
movq (%rax), %rdi
leaq 0x99bfb(%rip), %rsi     # 0xe0f96
xorl %ebx, %ebx
movq %r14, %rdx
xorl %eax, %eax
callq 0x21d60
jmp 0x473e8
movq %rbp, %rdi
callq 0x22300
jmp 0x473e6
movq %rbp, %rdi
callq 0x223e1
jmp 0x473e6
movq %r14, %rdi
callq 0x22329
jmp 0x473e6
movq %rbp, %rdi
callq 0x22352
jmp 0x473e6
movq %rbp, %rdi
callq 0x223b8
jmp 0x473e6
movq %r12, %rdi
movq %rbp, %rsi
callq 0x2237b
xorl %ebx, %ebx
movl %ebx, %eax
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
movl $0x448, %esi            # imm = 0x448
movq %r15, %rdi
callq 0x218d0
movq %rbx, %rdi
callq 0x220a0