// File: dsharlet[P]array/include/array/image.h
// Function: nda::array_ref<int, nda::shape<nda::dim<-9l, -9l, 1l>, nda::dim<-9l, -9l, -9l>, nda::dim<-9l, -9l, -9l>>> nda::crop<int, nda::shape<nda::dim<-9l, -9l, 1l>, nda::dim<-9l, -9l, -9l>, nda::dim<-9l, -9l, -9l>>>(nda::array_ref<int, nda::shape<nda::dim<-9l, -9l, 1l>, nda::dim<-9l, -9l, -9l>, nda::dim<-9l, -9l, -9l>>> const&, long, long, long, long, nda::crop_origin)
array_ref<T, Shape> crop(const array_ref<T, Shape>& im, index_t x0, index_t y0, index_t x1,
    index_t y1, crop_origin origin = crop_origin::crop) {
  x0 = internal::max(x0, im.x().min());
  y0 = internal::max(y0, im.y().min());
  x1 = internal::min(x1, im.x().max() + 1);
  y1 = internal::min(y1, im.y().max() + 1);
  Shape cropped_shape = crop_image_shape(im.shape(), x0, y0, x1, y1, origin);
  index_t c0 = im.c().min();
  T* base = im.base() != nullptr ? &im(x0, y0, c0) : nullptr;
  if (origin == crop_origin::crop) {
    base = internal::pointer_add(base, -cropped_shape(x0, y0, c0));
  }
  return array_ref<T, Shape>(base, cropped_shape);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x180, %rsp            # imm = 0x180
movq %rdi, -0x160(%rbp)
movq %rdi, %rax
movq %rax, -0x158(%rbp)
movl 0x10(%rbp), %eax
movq %rdi, -0x68(%rbp)
movq %rsi, -0x70(%rbp)
movq %rdx, -0x78(%rbp)
movq %rcx, -0x80(%rbp)
movq %r8, -0x88(%rbp)
movq %r9, -0x90(%rbp)
movq -0x70(%rbp), %rdi
callq 0x10cc30
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x98(%rbp)
leaq -0x78(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x12b00
movq (%rax), %rax
movq %rax, -0x78(%rbp)
movq -0x70(%rbp), %rdi
callq 0x10cc50
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0xa0(%rbp)
leaq -0x80(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x12b00
movq (%rax), %rax
movq %rax, -0x80(%rbp)
movq -0x70(%rbp), %rdi
callq 0x10cc30
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rcx
movq %rcx, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq (%rax), %rax
addq $0x8, %rcx
movq %rcx, -0x38(%rbp)
movq -0x38(%rbp), %rcx
addq (%rcx), %rax
subq $0x1, %rax
addq $0x1, %rax
movq %rax, -0xa8(%rbp)
leaq -0x88(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x124b0
movq (%rax), %rax
movq %rax, -0x88(%rbp)
movq -0x70(%rbp), %rdi
callq 0x10cc50
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rcx
movq %rcx, -0x20(%rbp)
movq -0x20(%rbp), %rax
movq (%rax), %rax
addq $0x8, %rcx
movq %rcx, -0x28(%rbp)
movq -0x28(%rbp), %rcx
addq (%rcx), %rax
subq $0x1, %rax
addq $0x1, %rax
movq %rax, -0xb0(%rbp)
leaq -0x90(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0x124b0
movq (%rax), %rax
movq %rax, -0x90(%rbp)
movq -0x70(%rbp), %rdi
callq 0x14ba0
movq %rax, %rsi
leaq -0x140(%rbp), %rdi
movl $0x48, %edx
callq 0x31c0
movq -0x78(%rbp), %rdx
movq -0x80(%rbp), %rcx
movq -0x88(%rbp), %r8
movq -0x90(%rbp), %r9
movl 0x10(%rbp), %eax
leaq -0xf8(%rbp), %rdi
leaq -0x140(%rbp), %rsi
movl %eax, (%rsp)
callq 0x10cc70
movq -0x70(%rbp), %rdi
callq 0x10ce10
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x148(%rbp)
movq -0x70(%rbp), %rdi
callq 0x14d00
cmpq $0x0, %rax
je 0x10c2be
movq -0x70(%rbp), %rdi
movq -0x78(%rbp), %rsi
movq -0x80(%rbp), %rdx
movq -0x148(%rbp), %rcx
callq 0x10ce30
movq %rax, -0x168(%rbp)
jmp 0x10c2c9
xorl %eax, %eax
movq %rax, -0x168(%rbp)
jmp 0x10c2c9
movq -0x168(%rbp), %rax
movq %rax, -0x150(%rbp)
cmpl $0x1, 0x10(%rbp)
jne 0x10c320
movq -0x150(%rbp), %rax
movq %rax, -0x170(%rbp)
movq -0x78(%rbp), %rsi
movq -0x80(%rbp), %rdx
movq -0x148(%rbp), %rcx
leaq -0xf8(%rbp), %rdi
callq 0x10ce80
movq -0x170(%rbp), %rdi
xorl %ecx, %ecx
movl %ecx, %esi
subq %rax, %rsi
callq 0x17b00
movq %rax, -0x150(%rbp)
movq -0x160(%rbp), %rdi
movq -0x150(%rbp), %rsi
leaq -0xf8(%rbp), %rdx
callq 0x97470
movq -0x158(%rbp), %rax
addq $0x180, %rsp            # imm = 0x180
popq %rbp
retq
nopw (%rax,%rax)