// File: /workspace/github_cpp_makefile_star2_O1/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, %rbp
leaq 0x99e91(%rip), %rsi     # 0xe1379
movq %r14, %rdi
callq 0x21aa0
testq %rax, %rax
je 0x479c9
movq %rax, %rbx
leaq 0x28(%rsp), %rdi
movl $0x1, %esi
movl $0x6, %edx
movq %rax, %rcx
callq 0x21e30
cmpq $0x6, %rax
jne 0x479e8
cmpl $0x4d554e93, 0x28(%rsp) # imm = 0x4D554E93
jne 0x479f2
cmpb $0x50, 0x2c(%rsp)
jne 0x479f2
cmpb $0x59, 0x2d(%rsp)
jne 0x479f2
leaq 0x3e(%rsp), %rdi
movl $0x1, %esi
movl $0x2, %edx
movq %rbx, %rcx
callq 0x21e30
cmpq $0x2, %rax
jne 0x479fc
leaq 0x1e(%rsp), %rdi
movl $0x2, %esi
movl $0x1, %edx
movq %rbx, %rcx
callq 0x21e30
cmpq $0x1, %rax
jne 0x47a06
movzwl 0x1e(%rsp), %r14d
testq %r14, %r14
je 0x47a10
leaq 0x1(%r14), %rdi
callq 0x21040
movq %rax, %r12
movl $0x1, %esi
movq %rax, %rdi
movq %r14, %rdx
movq %rbx, %rcx
callq 0x21e30
cmpq %r14, %rax
jne 0x47a1a
movb $0x0, (%r12,%r14)
leaq 0x9badf(%rip), %rsi     # 0xe30a5
movq %r12, %rdi
callq 0x21170
movq $0x0, 0x20(%rsp)
testq %rax, %rax
movq %r12, 0x10(%rsp)
je 0x4763a
movq %rax, %rdi
movl $0x3c, %esi
callq 0x21320
testq %rax, %rax
movq %rbx, %r14
je 0x47642
movq %rax, %r15
incq %r15
movsbl (%r15), %r13d
incq %r15
cmpl $0x20, %r13d
je 0x475fc
movq %r15, %rdi
movl $0x27, %esi
callq 0x21320
cmpq %rax, %r15
jae 0x47633
movq %rax, %r12
movb $0x0, (%rax)
movq %r15, %rdi
callq 0x21ed0
movq %rax, 0x20(%rsp)
movb $0x27, (%r12)
movq 0x10(%rsp), %r12
jmp 0x47645
xorl %r13d, %r13d
movq %rbx, %r14
jmp 0x47645
xorl %r13d, %r13d
leaq 0x9ba61(%rip), %rsi     # 0xe30ad
movq %r12, %rdi
callq 0x21170
movb $0x1, %bl
testq %rax, %rax
je 0x476c4
movq %rax, %rdi
movl $0x3a, %esi
callq 0x21320
testq %rax, %rax
je 0x476c4
movq %rax, %r15
cmpb $0x20, 0x1(%r15)
leaq 0x1(%r15), %r15
je 0x47670
movq %r15, %rdi
movl $0x2c, %esi
callq 0x21320
cmpq %rax, %r15
jae 0x476c4
movq %rax, %r12
movb $0x0, (%rax)
leaq 0x9ba23(%rip), %rsi     # 0xe30bd
movq %r15, %rdi
callq 0x21cf0
testl %eax, %eax
setne %bl
leaq 0x9ba14(%rip), %rsi     # 0xe30c2
movq %r15, %rdi
callq 0x21cf0
testl %eax, %eax
setne %al
andb %bl, %al
movl %eax, %ebx
movb $0x2c, (%r12)
leaq 0x9b9fc(%rip), %rsi     # 0xe30c7
movq 0x10(%rsp), %rdi
callq 0x21170
movl $0x1, 0xc(%rsp)
movl $0x1, %ecx
testq %rax, %rax
je 0x47738
movq %rax, %rdi
movl $0x28, %esi
callq 0x21320
movl $0x1, %ecx
testq %rax, %rax
je 0x47738
movq %rax, %r15
cmpb $0x20, 0x1(%r15)
leaq 0x1(%r15), %r15
je 0x47701
movq %r15, %rdi
movl $0x2c, %esi
callq 0x21320
movl $0x1, %ecx
cmpq %rax, %r15
jae 0x47738
movq %rax, %r12
movb $0x0, (%rax)
movq %r15, %rdi
callq 0x21ed0
movl %eax, %ecx
movb $0x2c, (%r12)
movl %ecx, 0x18(%rsp)
leaq 0x9b984(%rip), %rsi     # 0xe30c7
movq 0x10(%rsp), %rdi
callq 0x21170
testq %rax, %rax
movb %bl, 0xb(%rsp)
je 0x477b8
movq %rax, %rdi
movl $0x2c, %esi
callq 0x21320
testq %rax, %rax
je 0x477b8
movq %rax, %r15
cmpb $0x20, 0x1(%r15)
leaq 0x1(%r15), %r15
je 0x4776b
movq %r15, %rdi
movl $0x2c, %esi
callq 0x21320
movq %rax, %rbx
movq %r15, %rdi
movl $0x29, %esi
callq 0x21320
movq %rax, %r12
cmpq %rax, %rbx
cmovbq %rbx, %r12
cmpq %r12, %r15
jae 0x477b8
movb $0x0, (%r12)
movq %r15, %rdi
callq 0x21ed0
movl %eax, 0xc(%rsp)
movb $0x29, (%r12)
movq 0x10(%rsp), %rdi
callq 0x21c10
movq 0x20(%rsp), %rcx
leal (,%rcx,4), %eax
cmpl $0x55, %r13d
cmovnel %ecx, %eax
movl 0x18(%rsp), %ecx
movl %ecx, %r15d
imull 0xc(%rsp), %r15d
imull %eax, %r15d
movq %r15, %rdi
callq 0x21040
movq %rax, 0x10(%rsp)
testl %r15d, %r15d
je 0x4784a
movq 0xfe7a9(%rip), %rbx     # 0x145fa8
xorl %r12d, %r12d
movl %r12d, %edi
addq 0x10(%rsp), %rdi
movl %r15d, %edx
subl %r12d, %edx
movl $0x1, %esi
movq %r14, %rcx
callq 0x21e30
movq %rax, %r13
testq %rax, %rax
je 0x4782f
addl %r13d, %r12d
cmpl %r15d, %r12d
jb 0x47802
jmp 0x4784a
movq (%rbx), %rdi
leaq 0x9b896(%rip), %rsi     # 0xe30cf
xorl %edx, %edx
movl %r12d, %ecx
movl %r15d, %r8d
xorl %eax, %eax
callq 0x21d70
jmp 0x47825
movq %r14, %rdi
callq 0x218a0
movl 0xc(%rsp), %r14d
testl %r14d, %r14d
movl 0x18(%rsp), %ebx
jle 0x478bb
leaq 0x8(%rbp), %rax
movq %rax, 0x30(%rsp)
leaq 0x40(%rsp), %r12
xorl %r13d, %r13d
movq %r12, %rdi
leaq 0x9b882(%rip), %rsi     # 0xe30fd
movl %r13d, %edx
xorl %eax, %eax
callq 0x21130
movl $0x448, %edi            # imm = 0x448
callq 0x218b0
movq %rax, %r15
movq (%rbp), %rsi
movq %rax, %rdi
movq %r12, %rdx
xorl %ecx, %ecx
callq 0x487c8
movl 0x14(%rbp), %edx
movq 0x30(%rsp), %rdi
movq %r15, %rsi
callq 0x8cf92
incl %r13d
cmpl %r13d, %r14d
jne 0x47871
cmpb $0x0, 0xb(%rsp)
je 0x4793d
testl %ebx, %ebx
movq 0x20(%rsp), %rax
jle 0x479b8
movl 0xc(%rsp), %r12d
xorl %r15d, %r15d
movq 0x10(%rsp), %r13
movq %rbp, %r14
cmpl $0x0, 0xc(%rsp)
jle 0x47931
xorl %ebx, %ebx
cmpl $0x8, %eax
je 0x478ff
cmpl $0x4, %eax
jne 0x47929
movss (%r13), %xmm0
movl $0x4, %ebp
jmp 0x4790d
xorps %xmm0, %xmm0
cvtsd2ss (%r13), %xmm0
movl $0x8, %ebp
movq 0x8(%r14), %rax
movq (%rax,%rbx,8), %rdi
cvtss2sd %xmm0, %xmm0
movl %r15d, %esi
callq 0x4a20c
addq %rbp, %r13
movq 0x20(%rsp), %rax
incq %rbx
cmpq %rbx, %r12
jne 0x478e8
incl %r15d
cmpl 0x18(%rsp), %r15d
jne 0x478df
jmp 0x479b8
testl %r14d, %r14d
movq 0x20(%rsp), %rax
jle 0x479b8
movl 0xc(%rsp), %ecx
movq %rcx, 0x30(%rsp)
xorl %r13d, %r13d
movq 0x10(%rsp), %r12
movl 0x18(%rsp), %r14d
testl %r14d, %r14d
jle 0x479ae
xorl %r15d, %r15d
cmpl $0x8, %eax
je 0x4797c
cmpl $0x4, %eax
jne 0x479a6
movss (%r12), %xmm0
movl $0x4, %ebx
jmp 0x4798a
xorps %xmm0, %xmm0
cvtsd2ss (%r12), %xmm0
movl $0x8, %ebx
movq 0x8(%rbp), %rax
movq (%rax,%r13,8), %rdi
cvtss2sd %xmm0, %xmm0
movl %r15d, %esi
callq 0x4a20c
addq %rbx, %r12
movq 0x20(%rsp), %rax
incl %r15d
cmpl %r15d, %r14d
jne 0x47965
incq %r13
cmpq 0x30(%rsp), %r13
jne 0x4795d
movq 0x10(%rsp), %rdi
callq 0x21c10
movl $0x1, %ebx
jmp 0x47a27
movq 0xfe5d8(%rip), %rax     # 0x145fa8
movq (%rax), %rdi
leaq 0x9b5cc(%rip), %rsi     # 0xe2fa6
xorl %ebx, %ebx
movq %r14, %rdx
xorl %eax, %eax
callq 0x21d70
jmp 0x47a27
movq %rbx, %rdi
callq 0x22310
jmp 0x47a25
movq %rbx, %rdi
callq 0x223f1
jmp 0x47a25
movq %rbx, %rdi
callq 0x22339
jmp 0x47a25
movq %rbx, %rdi
callq 0x22362
jmp 0x47a25
movq %rbx, %rdi
callq 0x223c8
jmp 0x47a25
movq %r12, %rdi
movq %rbx, %rsi
callq 0x2238b
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 0x220b0
nop