// File: tomfunkhouser[P]gaps/pkgs/R2Shapes/R2Image.cpp
// Function: gaps::R2Image::ReadJPEGStream(_IO_FILE*)
int R2Image::
ReadJPEGStream(FILE *fp)
{
#ifdef RN_USE_JPEG
  // Initialize decompression info
  struct jpeg_decompress_struct cinfo;
  struct jpeg_error_mgr jerr;
  cinfo.err = jpeg_std_error(&jerr);
  jpeg_create_decompress(&cinfo);
  jpeg_stdio_src(&cinfo, fp);
  jpeg_read_header(&cinfo, TRUE);
  jpeg_start_decompress(&cinfo);

  // Remember image attributes
  width = cinfo.output_width;
  height = cinfo.output_height;
  ncomponents = cinfo.output_components;
  rowsize = ncomponents * width;
  if ((rowsize % 4) != 0) rowsize = (rowsize / 4 + 1) * 4;

  // Allocate image pixels
  int nbytes = rowsize * height;
  this->pixels = new unsigned char [nbytes];
  if (!this->pixels) {
    RNFail("Unable to allocate memory for JPEG file");
    fclose(fp);
    return 0;
  }

  // Read scan lines 
  // First jpeg pixel is top-left, so read pixels in opposite scan-line order
  while (cinfo.output_scanline < cinfo.output_height) {
    int scanline = cinfo.output_height - cinfo.output_scanline - 1;
    unsigned char *row_pointer = &pixels[scanline * rowsize];
    jpeg_read_scanlines(&cinfo, &row_pointer, 1);
  }

  // Free everything
  jpeg_finish_decompress(&cinfo);
  jpeg_destroy_decompress(&cinfo);

  // Return success
  return 1;
#else
  RNFail("JPEG not supported");
  return 0;
#endif
}

// Assembly:
subq $0x358, %rsp            # imm = 0x358
movq %rdi, 0x348(%rsp)
movq %rsi, 0x340(%rsp)
movq 0x348(%rsp), %rax
movq %rax, 0x8(%rsp)
leaq 0x20(%rsp), %rdi
callq 0xf94a0
movq %rax, 0xc8(%rsp)
leaq 0xc8(%rsp), %rdi
movl $0x3e, %esi
movl $0x278, %edx            # imm = 0x278
callq 0xe2350
movq 0x340(%rsp), %rsi
leaq 0xc8(%rsp), %rdi
callq 0xe3550
leaq 0xc8(%rsp), %rdi
movl $0x1, %esi
callq 0xe2550
leaq 0xc8(%rsp), %rdi
callq 0xe2d40
movq 0x8(%rsp), %rax
movl 0x150(%rsp), %ecx
movl %ecx, (%rax)
movl 0x154(%rsp), %ecx
movl %ecx, 0x4(%rax)
movl 0x15c(%rsp), %ecx
movl %ecx, 0x8(%rax)
movl 0x8(%rax), %ecx
imull (%rax), %ecx
movl %ecx, 0xc(%rax)
movl 0xc(%rax), %eax
movl $0x4, %ecx
cltd
idivl %ecx
cmpl $0x0, %edx
je 0xc9e6c
movq 0x8(%rsp), %rax
movl 0xc(%rax), %eax
movl $0x4, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movq 0x8(%rsp), %rax
addl $0x1, %ecx
shll $0x2, %ecx
movl %ecx, 0xc(%rax)
movq 0x8(%rsp), %rcx
movl 0xc(%rcx), %eax
imull 0x4(%rcx), %eax
movl %eax, 0x1c(%rsp)
movslq 0x1c(%rsp), %rdi
callq 0xf030
movq %rax, %rcx
movq 0x8(%rsp), %rax
movq %rcx, 0x10(%rax)
cmpq $0x0, 0x10(%rax)
jne 0xc9ec4
leaq 0x6c7e3(%rip), %rdi     # 0x136683
movb $0x0, %al
callq 0xd4f30
movq 0x340(%rsp), %rdi
callq 0xf4b0
movl $0x0, 0x354(%rsp)
jmp 0xc9f45
jmp 0xc9ec6
movl 0x170(%rsp), %eax
cmpl 0x154(%rsp), %eax
jae 0xc9f20
movq 0x8(%rsp), %rdx
movl 0x154(%rsp), %eax
subl 0x170(%rsp), %eax
subl $0x1, %eax
movl %eax, 0x18(%rsp)
movq 0x10(%rdx), %rax
movl 0x18(%rsp), %ecx
imull 0xc(%rdx), %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, 0x10(%rsp)
leaq 0xc8(%rsp), %rdi
leaq 0x10(%rsp), %rsi
movl $0x1, %edx
callq 0xe3090
jmp 0xc9ec6
leaq 0xc8(%rsp), %rdi
callq 0xe2bd0
leaq 0xc8(%rsp), %rdi
callq 0xe2530
movl $0x1, 0x354(%rsp)
movl 0x354(%rsp), %eax
addq $0x358, %rsp            # imm = 0x358
retq
nopw %cs:(%rax,%rax)