// File: /workspace/github_cpp_makefile_star2_O2/cloudinary[P]fuif/./import/read_jpeg.h
// Function: read_JPEG_file(char const*)
Image read_JPEG_file(const char *input_image) {

  FILE *fp = fopen(input_image,"rb");
  if (!fp) return Image();

  struct jpeg_decompress_struct cinfo;

  jpegErrorManager jerr;
  cinfo.err = jpeg_std_error(&jerr.pub);
  jerr.pub.error_exit = jpegErrorExit;
  /* Establish the setjmp return context for my_error_exit to use. */
  if (setjmp(jerr.setjmp_buffer)) {
    /* If we get here, the JPEG code has signaled an error. */
    v_printf(10, "libjpeg: %s\n",jpegLastErrorMsg);
    jpeg_destroy_decompress(&cinfo);
    fclose(fp);
    return Image();
  }

  jpeg_create_decompress(&cinfo);
  jpeg_stdio_src(&cinfo, fp);
  (void) jpeg_read_header(&cinfo, TRUE);


  jvirt_barray_ptr *coeffs_array = jpeg_read_coefficients(&cinfo);

  int nbcomp = cinfo.num_components;
  int w = cinfo.image_width;
  int h = cinfo.image_height;
  int bitdepth = cinfo.data_precision;

  Image image;
  image.w = w;
  image.h = h;
  image.nb_channels = nbcomp;
  image.real_nb_channels = nbcomp;
  image.minval = 0;
  image.maxval = (1<<bitdepth)-1;

  if (nbcomp == 4) image.colormodel = 16; // CMYK

  Transform subsampling(TRANSFORM_ChromaSubsample);
  int max_factor_h = 1;
  int max_factor_v = 1;
  for (int ci=0; ci < nbcomp; ci++) {
      jpeg_component_info* compptr = cinfo.comp_info + ci;
      int srh = compptr->h_samp_factor;
      int srv = compptr->v_samp_factor;
      if (srh > max_factor_h) max_factor_h = srh;
      if (srv > max_factor_v) max_factor_v = srv;
  }
  std::vector<int> & p = subsampling.parameters;
  for (int ci=0; ci < nbcomp; ci++) {
      jpeg_component_info* compptr = cinfo.comp_info + ci;
      int srh = compptr->h_samp_factor;
      int srv = compptr->v_samp_factor;
      if (srh < max_factor_h || srv < max_factor_v) {
         p.push_back(ci);
         p.push_back(ci);
         p.push_back(max_factor_h/srh);
         p.push_back(max_factor_v/srv);
      }
  }
  if (p.size() >= 8) {
    if (p[2] == p[6] && p[3] == p[7] && p[4] == p[1]+1) {
        p[1] = p[4];
        p.erase(p.begin()+4, p.end());
    }
    if (p.size() == 4 && p[0] == 1 && p[1] == 2) {
        if (p[2] == 2 && p[3] == 2) { p[0] = 0; p.erase(p.begin()+1, p.end()); } // 4:2:0
    }
  }

  if (cinfo.jpeg_color_space == JCS_YCbCr ||
      cinfo.jpeg_color_space == JCS_YCCK) image.transform.push_back(Transform(TRANSFORM_YCbCr));

  if (p.size()) image.transform.push_back(subsampling);

  image.transform.push_back(Transform(TRANSFORM_DCT));

  image.transform.push_back(Transform(TRANSFORM_QUANTIZE));

  std::vector<std::vector<int>> ordering;
  std::vector<int> comp;
  std::vector<int> coeff;
  default_DCT_scanscript(nbcomp,ordering,comp,coeff);

  for (int i=0; i < 64*nbcomp; i++) {
    int bi=0;
    for (; bi<64 ; bi++) if (coeff[i]==jpeg_zigzag[bi]) break;
    int ci = comp[i];
    jpeg_component_info* compptr = cinfo.comp_info + ci;
    int hib = compptr->height_in_blocks;
    int wib = compptr->width_in_blocks;
    int q = compptr->quant_table->quantval[bi];
    v_printf(5,"Quantization for component %i, coefficient %i: %i\n",comp[i],coeff[i],q);

    Channel c(wib,hib,LARGEST_VAL,SMALLEST_VAL);
    c.q = q;
    c.component = ci;
    c.hshift = 3 + (compptr->h_samp_factor < max_factor_h ? 1 : 0);
    c.vshift = 3 + (compptr->v_samp_factor < max_factor_v ? 1 : 0);
    c.hcshift = dct_cshifts[coeff[i]];
    c.vcshift = dct_cshifts[coeff[i]];
    int zeroes=0;
    int nonzeroes=0;
    for (int by=0; by < hib; by++) {
      JBLOCKARRAY buffer = (cinfo.mem->access_virt_barray)((j_common_ptr)&cinfo, coeffs_array[ci], by, (JDIMENSION) 1, FALSE);
      for (int bx=0; bx < wib; bx++) {
        JCOEFPTR blockptr = buffer[0][bx];
        c.value(by,bx) = blockptr[bi];
        if (c.value(by,bx) > c.maxval) c.maxval = c.value(by,bx);
        if (c.value(by,bx) < c.minval) c.minval = c.value(by,bx);
        if (c.value(by,bx)) nonzeroes++; else zeroes++;
      }
    }
    v_printf(10,"Comp %i, coeff %i (natural %i) : %f %% zeroes (%i zeroes, %i nonzeroes)\n",ci,coeff[i],bi,100.0*zeroes/(zeroes+nonzeroes),zeroes,nonzeroes);
    image.channel.push_back(c);
  }

  jpeg_finish_decompress( &cinfo );
  jpeg_destroy_decompress( &cinfo );
  fclose(fp);

  image.error = false;


  return image;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x548, %rsp            # imm = 0x548
movq %rsi, %rax
movq %rdi, %rbp
leaq 0x6a73(%rip), %rsi      # 0x1ea1f
movq %rax, %rdi
callq 0x33a0
testq %rax, %rax
je 0x1801e
movq %rax, %r15
leaq 0x3d8(%rsp), %rbx
movq %rbx, %rdi
callq 0x3080
movq %rax, 0x148(%rsp)
leaq -0x6d(%rip), %rax       # 0x17f6e
movq %rax, (%rbx)
leaq 0x480(%rsp), %rdi
callq 0x3460
testl %eax, %eax
je 0x1802b
leaq 0x7121(%rip), %rsi      # 0x1f117
leaq 0x16843(%rip), %rdx     # 0x2e840
xorl %eax, %eax
pushq $0xa
popq %rdi
callq 0x16c30
leaq 0x148(%rsp), %rdi
callq 0x30d0
movq %r15, %rdi
callq 0x32c0
jmp 0x1801e
movq %rbp, %rdi
callq 0xd18a
jmp 0x18717
leaq 0x148(%rsp), %r14
pushq $0x50
popq %rsi
movl $0x290, %edx            # imm = 0x290
movq %r14, %rdi
callq 0x35a0
movq %r14, %rdi
movq %r15, 0x108(%rsp)
movq %r15, %rsi
callq 0x34a0
pushq $0x1
popq %rsi
movq %r14, %rdi
callq 0x3500
movq %r14, %rdi
callq 0x30b0
movq %rax, %rbx
movl 0x38(%r14), %r12d
movb 0x128(%r14), %r15b
movq 0x30(%r14), %r14
movq %rbp, %rdi
callq 0xd18a
movq %r14, 0x30(%rbp)
movl %r12d, 0x64(%rbp)
movl %r12d, 0x68(%rbp)
andl $0x0, 0x5c(%rbp)
pushq $-0x1
popq %rax
movl %r15d, %ecx
shll %cl, %eax
notl %eax
movl %eax, 0x60(%rbp)
cmpl $0x4, %r12d
jne 0x180ad
movl $0x10, 0x70(%rbp)
movq %rbx, 0x100(%rsp)
leaq 0x30(%rsp), %rax
movl $0x3, -0x8(%rax)
andq $0x0, 0x10(%rax)
xorps %xmm0, %xmm0
movups %xmm0, (%rax)
movq 0x278(%rsp), %rax
xorl %ecx, %ecx
testl %r12d, %r12d
movl %ecx, %edx
cmovgl %r12d, %ecx
imulq $0x60, %rcx, %rcx
movdqa 0x5585(%rip), %xmm0     # 0x1d670
cmpq %rdx, %rcx
je 0x18114
movdqa %xmm0, %xmm2
movq 0x8(%rax,%rdx), %xmm0
movdqa %xmm0, %xmm1
pcmpgtd %xmm2, %xmm0
pand %xmm0, %xmm1
pandn %xmm2, %xmm0
por %xmm1, %xmm0
addq $0x60, %rdx
jmp 0x180eb
movq %rbp, (%rsp)
movd %xmm0, 0x8(%rsp)
movdqa %xmm0, 0x130(%rsp)
pshufd $0x55, %xmm0, %xmm0     # xmm0 = xmm0[1,1,1,1]
movd %xmm0, 0xc(%rsp)
xorl %eax, %eax
leaq 0x50(%rsp), %r14
leaq 0xb0(%rsp), %rbx
movl %eax, 0x50(%rsp)
cmpl %r12d, %eax
jge 0x181cf
movq 0x278(%rsp), %rcx
movslq %eax, %rdx
imulq $0x60, %rdx, %rdx
movl 0x8(%rcx,%rdx), %ebp
movl 0xc(%rcx,%rdx), %r13d
cmpl 0x8(%rsp), %ebp
jl 0x18173
cmpl 0xc(%rsp), %r13d
jge 0x181c8
leaq 0x30(%rsp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0xa60a
movq %r15, %rdi
movq %r14, %rsi
callq 0xa60a
movl 0x8(%rsp), %eax
cltd
idivl %ebp
movl %eax, 0xb0(%rsp)
movq %r15, %rdi
movq %rbx, %rbp
movq %rbx, %rsi
callq 0xb266
movl 0xc(%rsp), %eax
cltd
idivl %r13d
movl %eax, 0xb0(%rsp)
movq %r15, %rdi
movq %rbp, %rsi
callq 0xb266
movl 0x50(%rsp), %eax
incl %eax
jmp 0x18141
movq 0x30(%rsp), %rsi
movq 0x38(%rsp), %rdx
movq %rdx, %rax
subq %rsi, %rax
cmpq $0x1c, %rax
movq (%rsp), %rbp
leaq 0x30(%rsp), %r15
jbe 0x18269
movl 0x8(%rsi), %eax
cmpl 0x18(%rsi), %eax
jne 0x18234
movl 0xc(%rsi), %eax
cmpl 0x1c(%rsi), %eax
jne 0x18234
movl 0x4(%rsi), %ecx
movl 0x10(%rsi), %eax
incl %ecx
cmpl %ecx, %eax
jne 0x18234
movl %eax, 0x4(%rsi)
addq $0x10, %rsi
movq %r15, %rdi
callq 0xaa84
movq 0x30(%rsp), %rdx
movq 0x38(%rsp), %rax
movq %rax, %rcx
movq %rax, %rdi
movq %rdx, %rax
movq %rdx, %rsi
movq %rdi, %rdx
jmp 0x1823a
movq %rsi, %rax
movq %rdx, %rcx
subq %rax, %rcx
cmpq $0x10, %rcx
jne 0x18269
cmpl $0x1, (%rsi)
jne 0x18269
cmpl $0x2, 0x4(%rsi)
jne 0x18269
cmpl $0x2, 0x8(%rsi)
jne 0x18269
cmpl $0x2, 0xc(%rsi)
jne 0x18269
andl $0x0, (%rsi)
addq $0x4, %rsi
movq %r15, %rdi
callq 0xaa84
movl 0x184(%rsp), %eax
cmpl $0x5, %eax
je 0x1827a
cmpl $0x3, %eax
jne 0x182a6
leaq 0x18(%rbp), %rdi
leaq 0x58(%rsp), %rbx
andl $0x0, -0x8(%rbx)
pxor %xmm0, %xmm0
movdqu %xmm0, (%rbx)
andq $0x0, 0x10(%rbx)
leaq 0x50(%rsp), %rsi
callq 0x1c6ee
movq %rbx, %rdi
callq 0x5374
movq 0x38(%rsp), %rax
cmpq 0x30(%rsp), %rax
je 0x182c0
leaq 0x18(%rbp), %rdi
leaq 0x28(%rsp), %rsi
callq 0x52fa
leaq 0x18(%rbp), %rbx
leaq 0x58(%rsp), %r14
movl $0x4, -0x8(%r14)
pxor %xmm0, %xmm0
movdqu %xmm0, (%r14)
andq $0x0, 0x10(%r14)
leaq 0x50(%rsp), %rsi
movq %rbx, %rdi
callq 0x1c6ee
movq %r14, %rdi
callq 0x5374
leaq 0x58(%rsp), %r14
movl $0x5, -0x8(%r14)
pxor %xmm0, %xmm0
movdqu %xmm0, (%r14)
andq $0x0, 0x10(%r14)
leaq 0x50(%rsp), %rsi
movq %rbx, %rdi
callq 0x1c6ee
movq %r14, %rdi
callq 0x5374
leaq 0xb0(%rsp), %rsi
andq $0x0, 0x10(%rsi)
pxor %xmm0, %xmm0
movdqa %xmm0, (%rsi)
leaq 0x110(%rsp), %rdx
movdqa %xmm0, (%rdx)
andq $0x0, 0x10(%rdx)
leaq 0x90(%rsp), %rcx
movdqa %xmm0, (%rcx)
andq $0x0, 0x10(%rcx)
movl %r12d, %edi
callq 0x612f
shll $0x6, %r12d
xorl %ebx, %ebx
testl %r12d, %r12d
cmovlel %ebx, %r12d
movl %r12d, %eax
movq %rax, 0xf8(%rsp)
movl %ebx, %eax
leaq 0x50ec(%rip), %rdx      # 0x1d470
cmpq 0xf8(%rsp), %rax
je 0x186ba
movq %rax, %rdi
movq 0x90(%rsp), %rax
movl (%rax,%rdi,4), %ecx
movl %ebx, %eax
cmpq $0x40, %rax
je 0x183b2
cmpl (%rdx,%rax,4), %ecx
je 0x183b9
incq %rax
jmp 0x183a2
xorl %esi, %esi
pushq $0x40
popq %rax
jmp 0x183bb
xorl %esi, %esi
movq 0x110(%rsp), %rdx
movq %rdi, 0x18(%rsp)
movl (%rdx,%rdi,4), %edx
movq 0x278(%rsp), %r15
movl %edx, 0x14(%rsp)
movslq %edx, %rdi
imulq $0x60, %rdi, %r13
movl 0x1c(%r15,%r13), %r14d
movl 0x20(%r15,%r13), %ebx
movq 0x50(%r15,%r13), %rdx
movl %eax, %eax
movq %rax, 0x48(%rsp)
movzwl (%rdx,%rax,2), %r12d
movl %esi, %eax
movq %rdi, %rdx
movq %rdi, 0xf0(%rsp)
pushq $0x5
popq %rdi
leaq 0x6d14(%rip), %rsi      # 0x1f124
movl %r12d, %r8d
callq 0x16c30
leaq 0x50(%rsp), %rdi
movl %r14d, %esi
movl %ebx, %edx
movl $0x7fff, %ecx           # imm = 0x7FFF
movl $0xffff8001, %r8d       # imm = 0xFFFF8001
pushq $0x1
popq %r9
pushq $0x0
pushq $0x0
pushq $0x0
pushq $0x0
callq 0xa470
addq $0x20, %rsp
addq %r13, %r15
movl %r12d, 0x78(%rsp)
movl 0x14(%rsp), %eax
movl %eax, 0x8c(%rsp)
movq 0x8(%r15), %xmm0
movdqa 0x130(%rsp), %xmm1
pcmpgtd %xmm0, %xmm1
movdqa 0x6a40(%rip), %xmm0     # 0x1eeb0
psubd %xmm1, %xmm0
movq %xmm0, 0x7c(%rsp)
movq 0x90(%rsp), %rax
movq 0x18(%rsp), %rsi
movslq (%rax,%rsi,4), %rcx
leaq 0x50de(%rip), %rdx      # 0x1d570
movl (%rdx,%rcx,4), %ecx
movl %ecx, 0x84(%rsp)
movslq (%rax,%rsi,4), %rax
movl (%rdx,%rax,4), %eax
movl %eax, 0x88(%rsp)
xorl %eax, %eax
testl %r14d, %r14d
cmovlel %eax, %r14d
testl %ebx, %ebx
cmovlel %eax, %ebx
movl %ebx, 0x24(%rsp)
movl %r14d, %ecx
movq %rcx, 0xe8(%rsp)
movq 0x48(%rsp), %rcx
addq %rcx, %rcx
movq %rcx, 0xe0(%rsp)
movl %eax, %ebp
movl %eax, %r8d
movl %eax, %r14d
cmpl 0x24(%rsp), %r8d
leaq 0x30(%rsp), %r15
movl $0x0, %ebx
je 0x18639
movq 0x150(%rsp), %rax
movq 0x100(%rsp), %rcx
movq 0xf0(%rsp), %rdx
movq (%rcx,%rdx,8), %rsi
leaq 0x148(%rsp), %rdi
movl %r8d, 0x10(%rsp)
movl %r8d, %edx
pushq $0x1
popq %rcx
movl %ebx, %r8d
callq *0x40(%rax)
movq %rax, 0xd8(%rsp)
movl %ebx, %r15d
movq 0xe0(%rsp), %rax
movl %r14d, %r13d
movl %ebp, %r12d
cmpq %r15, 0xe8(%rsp)
je 0x18626
movq %rax, %rcx
movl %r12d, 0x20(%rsp)
movq 0xd8(%rsp), %rax
movq (%rax), %rax
movq %rcx, 0xd0(%rsp)
movzwl (%rax,%rcx), %ebx
leaq 0x50(%rsp), %r12
movq %r12, %rdi
movl 0x10(%rsp), %ebp
movl %ebp, %esi
movl %r15d, %edx
callq 0xa44a
movw %bx, (%rax)
movq %r12, %rbx
movq %r12, %rdi
movl %ebp, %esi
movl %r15d, %edx
callq 0xa44a
movzwl (%rax), %eax
cmpw 0x72(%rsp), %ax
jle 0x185b7
movl %r15d, %edx
movq %rbx, %rdi
movl %ebp, %esi
callq 0xa44a
movzwl (%rax), %eax
movw %ax, 0x72(%rsp)
movl %r15d, %edx
movq %rbx, %rdi
movl %ebp, %esi
callq 0xa44a
movzwl (%rax), %eax
cmpw 0x70(%rsp), %ax
movl 0x20(%rsp), %r12d
jge 0x185e8
movl %r15d, %edx
movq %rbx, %rdi
movl %ebp, %esi
callq 0xa44a
movzwl (%rax), %eax
movw %ax, 0x70(%rsp)
movl %r15d, %edx
movq %rbx, %rdi
movl %ebp, %esi
callq 0xa44a
xorl %ecx, %ecx
xorl %edx, %edx
cmpw $0x0, (%rax)
setne %al
sete %sil
movb %sil, %dl
addl %edx, %r13d
movb %al, %cl
addl %ecx, %r12d
incq %r15
movq 0xd0(%rsp), %rbp
subq $-0x80, %rbp
movq %rbp, %rax
jmp 0x18542
movl 0x10(%rsp), %r8d
incl %r8d
movl %r13d, %r14d
movl %r12d, %ebp
jmp 0x184df
movq 0x48(%rsp), %rax
movl %eax, %r8d
movq 0x90(%rsp), %rax
movq 0x18(%rsp), %rcx
movl (%rax,%rcx,4), %ecx
cvtsi2sd %r14d, %xmm0
mulsd 0x5d9a(%rip), %xmm0     # 0x1e3f8
movl %r14d, %eax
movl %ebp, %edx
addl %edx, %eax
cvtsi2sd %eax, %xmm1
divsd %xmm1, %xmm0
subq $0x8, %rsp
movl %ebp, %r10d
pushq $0xa
popq %rdi
leaq 0x6ad9(%rip), %rsi      # 0x1f157
movl 0x1c(%rsp), %edx
movl %r14d, %r9d
movb $0x1, %al
pushq %r10
movq 0x10(%rsp), %rbp
callq 0x16c30
popq %rax
popq %rcx
leaq 0x50(%rsp), %r14
movq %rbp, %rdi
movq %r14, %rsi
callq 0xa628
movq %r14, %rdi
callq 0xabc2
movq 0x18(%rsp), %rax
incq %rax
jmp 0x1837d
leaq 0x148(%rsp), %rdi
callq 0x3370
leaq 0x148(%rsp), %rdi
callq 0x30d0
movq 0x108(%rsp), %rdi
callq 0x32c0
movb $0x0, 0xa8(%rbp)
leaq 0x90(%rsp), %rdi
callq 0x5374
leaq 0x110(%rsp), %rdi
callq 0x5374
leaq 0xb0(%rsp), %rdi
callq 0xa654
movq %r15, %rdi
callq 0x5374
movq %rbp, %rax
addq $0x548, %rsp            # imm = 0x548
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x18730
jmp 0x18730
movq %rax, %rbx
jmp 0x187c2
movq %rax, %r14
movq %rbx, %rdi
callq 0x5374
movq %r14, %rbx
jmp 0x187c2
jmp 0x1874a
movq %rax, %rbx
movq %r14, %rdi
callq 0x5374
jmp 0x187c2
movq %rax, %rbx
jmp 0x1879b
movq %rax, %rbx
movq (%rsp), %rbp
leaq 0x30(%rsp), %r15
jmp 0x187c2
jmp 0x1877f
movq %rax, %rbx
jmp 0x18778
movq %rax, %rbx
movq (%rsp), %rbp
leaq 0x30(%rsp), %r15
jmp 0x1879b
movq %rax, %rbx
movq (%rsp), %rbp
jmp 0x187c2
jmp 0x1878a
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0xabc2
movq (%rsp), %rbp
leaq 0x90(%rsp), %rdi
callq 0x5374
leaq 0x110(%rsp), %rdi
callq 0x5374
leaq 0xb0(%rsp), %rdi
callq 0xa654
movq %r15, %rdi
callq 0x5374
movq %rbp, %rdi
callq 0xa776
movq %rbx, %rdi
callq 0x35d0