// File: srajangarg[P]raytracer/src/core/stb_image.hpp
// Function: stbi__psd_load(stbi__context*, int*, int*, int*, int)
static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp)
{
   int   pixelCount;
   int channelCount, compression;
   int channel, i, count, len;
   int bitdepth;
   int w,h;
   stbi_uc *out;

   // Check identifier
   if (stbi__get32be(s) != 0x38425053)   // "8BPS"
      return stbi__errpuc("not PSD", "Corrupt PSD image");

   // Check file type version.
   if (stbi__get16be(s) != 1)
      return stbi__errpuc("wrong version", "Unsupported version of PSD image");

   // Skip 6 reserved bytes.
   stbi__skip(s, 6 );

   // Read the number of channels (R, G, B, A, etc).
   channelCount = stbi__get16be(s);
   if (channelCount < 0 || channelCount > 16)
      return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image");

   // Read the rows and columns of the image.
   h = stbi__get32be(s);
   w = stbi__get32be(s);

   // Make sure the depth is 8 bits.
   bitdepth = stbi__get16be(s);
   if (bitdepth != 8 && bitdepth != 16)
      return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit");

   // Make sure the color mode is RGB.
   // Valid options are:
   //   0: Bitmap
   //   1: Grayscale
   //   2: Indexed color
   //   3: RGB color
   //   4: CMYK color
   //   7: Multichannel
   //   8: Duotone
   //   9: Lab color
   if (stbi__get16be(s) != 3)
      return stbi__errpuc("wrong color format", "PSD is not in RGB color format");

   // Skip the Mode Data.  (It's the palette for indexed color; other info for other modes.)
   stbi__skip(s,stbi__get32be(s) );

   // Skip the image resources.  (resolution, pen tool paths, etc)
   stbi__skip(s, stbi__get32be(s) );

   // Skip the reserved data.
   stbi__skip(s, stbi__get32be(s) );

   // Find out if the data is compressed.
   // Known values:
   //   0: no compression
   //   1: RLE compressed
   compression = stbi__get16be(s);
   if (compression > 1)
      return stbi__errpuc("bad compression", "PSD has an unknown compression format");

   // Create the destination image.
   out = (stbi_uc *) stbi__malloc(4 * w*h);
   if (!out) return stbi__errpuc("outofmem", "Out of memory");
   pixelCount = w*h;

   // Initialize the data to zero.
   //memset( out, 0, pixelCount * 4 );

   // Finally, the image data.
   if (compression) {
      // RLE as used by .PSD and .TIFF
      // Loop until you get the number of unpacked bytes you are expecting:
      //     Read the next source byte into n.
      //     If n is between 0 and 127 inclusive, copy the next n+1 bytes literally.
      //     Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times.
      //     Else if n is 128, noop.
      // Endloop

      // The RLE-compressed data is preceeded by a 2-byte data count for each row in the data,
      // which we're going to just skip.
      stbi__skip(s, h * channelCount * 2 );

      // Read the RLE data by channel.
      for (channel = 0; channel < 4; channel++) {
         stbi_uc *p;

         p = out+channel;
         if (channel >= channelCount) {
            // Fill this channel with default data.
            for (i = 0; i < pixelCount; i++, p += 4)
               *p = (channel == 3 ? 255 : 0);
         } else {
            // Read the RLE data.
            count = 0;
            while (count < pixelCount) {
               len = stbi__get8(s);
               if (len == 128) {
                  // No-op.
               } else if (len < 128) {
                  // Copy next len+1 bytes literally.
                  len++;
                  count += len;
                  while (len) {
                     *p = stbi__get8(s);
                     p += 4;
                     len--;
                  }
               } else if (len > 128) {
                  stbi_uc   val;
                  // Next -len+1 bytes in the dest are replicated from next source byte.
                  // (Interpret len as a negative 8-bit int.)
                  len ^= 0x0FF;
                  len += 2;
                  val = stbi__get8(s);
                  count += len;
                  while (len) {
                     *p = val;
                     p += 4;
                     len--;
                  }
               }
            }
         }
      }

   } else {
      // We're at the raw image data.  It's each channel in order (Red, Green, Blue, Alpha, ...)
      // where each channel consists of an 8-bit value for each pixel in the image.

      // Read the data by channel.
      for (channel = 0; channel < 4; channel++) {
         stbi_uc *p;

         p = out + channel;
         if (channel >= channelCount) {
            // Fill this channel with default data.
            stbi_uc val = channel == 3 ? 255 : 0;
            for (i = 0; i < pixelCount; i++, p += 4)
               *p = val;
         } else {
            // Read the data.
            if (bitdepth == 16) {
               for (i = 0; i < pixelCount; i++, p += 4)
                  *p = (stbi_uc) (stbi__get16be(s) >> 8);
            } else {
               for (i = 0; i < pixelCount; i++, p += 4)
                  *p = stbi__get8(s);
            }
         }
      }
   }

   if (req_comp && req_comp != 4) {
      out = stbi__convert_format(out, 4, req_comp, w, h);
      if (out == NULL) return out; // stbi__convert_format frees input on failure
   }

   if (comp) *comp = 4;
   *y = h;
   *x = w;

   return out;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movl %r8d, -0x2c(%rbp)
movq -0x10(%rbp), %rdi
callq 0x31510
cmpl $0x38425053, %eax       # imm = 0x38425053
je 0x2990f
leaq 0x1ec35(%rip), %rdi     # 0x4852b
callq 0x275b0
movl %eax, %ecx
xorl %eax, %eax
cmpl $0x0, %ecx
cmovneq %rax, %rax
movq %rax, -0x8(%rbp)
jmp 0x29dbd
movq -0x10(%rbp), %rdi
callq 0x2cf90
cmpl $0x1, %eax
je 0x2993d
leaq 0x1ec0f(%rip), %rdi     # 0x48533
callq 0x275b0
movl %eax, %ecx
xorl %eax, %eax
cmpl $0x0, %ecx
cmovneq %rax, %rax
movq %rax, -0x8(%rbp)
jmp 0x29dbd
movq -0x10(%rbp), %rdi
movl $0x6, %esi
callq 0x2d340
movq -0x10(%rbp), %rdi
callq 0x2cf90
movl %eax, -0x34(%rbp)
cmpl $0x0, -0x34(%rbp)
jl 0x29963
cmpl $0x10, -0x34(%rbp)
jle 0x29983
leaq 0x1ebd7(%rip), %rdi     # 0x48541
callq 0x275b0
movl %eax, %ecx
xorl %eax, %eax
cmpl $0x0, %ecx
cmovneq %rax, %rax
movq %rax, -0x8(%rbp)
jmp 0x29dbd
movq -0x10(%rbp), %rdi
callq 0x31510
movl %eax, -0x54(%rbp)
movq -0x10(%rbp), %rdi
callq 0x31510
movl %eax, -0x50(%rbp)
movq -0x10(%rbp), %rdi
callq 0x2cf90
movl %eax, -0x4c(%rbp)
cmpl $0x8, -0x4c(%rbp)
je 0x299d3
cmpl $0x10, -0x4c(%rbp)
je 0x299d3
leaq 0x1eb9b(%rip), %rdi     # 0x48555
callq 0x275b0
movl %eax, %ecx
xorl %eax, %eax
cmpl $0x0, %ecx
cmovneq %rax, %rax
movq %rax, -0x8(%rbp)
jmp 0x29dbd
movq -0x10(%rbp), %rdi
callq 0x2cf90
cmpl $0x3, %eax
je 0x29a01
leaq 0x1eb83(%rip), %rdi     # 0x4856b
callq 0x275b0
movl %eax, %ecx
xorl %eax, %eax
cmpl $0x0, %ecx
cmovneq %rax, %rax
movq %rax, -0x8(%rbp)
jmp 0x29dbd
movq -0x10(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x10(%rbp), %rdi
callq 0x31510
movq -0x98(%rbp), %rdi
movl %eax, %esi
callq 0x2d340
movq -0x10(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x10(%rbp), %rdi
callq 0x31510
movq -0x90(%rbp), %rdi
movl %eax, %esi
callq 0x2d340
movq -0x10(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x10(%rbp), %rdi
callq 0x31510
movq -0x88(%rbp), %rdi
movl %eax, %esi
callq 0x2d340
movq -0x10(%rbp), %rdi
callq 0x2cf90
movl %eax, -0x38(%rbp)
cmpl $0x1, -0x38(%rbp)
jle 0x29a99
leaq 0x1eafe(%rip), %rdi     # 0x4857e
callq 0x275b0
movl %eax, %ecx
xorl %eax, %eax
cmpl $0x0, %ecx
cmovneq %rax, %rax
movq %rax, -0x8(%rbp)
jmp 0x29dbd
movl -0x50(%rbp), %eax
shll $0x2, %eax
imull -0x54(%rbp), %eax
movslq %eax, %rdi
callq 0x27f20
movq %rax, -0x60(%rbp)
cmpq $0x0, -0x60(%rbp)
jne 0x29ad6
leaq 0x1e528(%rip), %rdi     # 0x47fe5
callq 0x275b0
movl %eax, %ecx
xorl %eax, %eax
cmpl $0x0, %ecx
cmovneq %rax, %rax
movq %rax, -0x8(%rbp)
jmp 0x29dbd
movl -0x50(%rbp), %eax
imull -0x54(%rbp), %eax
movl %eax, -0x30(%rbp)
cmpl $0x0, -0x38(%rbp)
je 0x29c5c
movq -0x10(%rbp), %rdi
movl -0x54(%rbp), %esi
imull -0x34(%rbp), %esi
shll %esi
callq 0x2d340
movl $0x0, -0x3c(%rbp)
cmpl $0x4, -0x3c(%rbp)
jge 0x29c57
movq -0x60(%rbp), %rax
movslq -0x3c(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x68(%rbp)
movl -0x3c(%rbp), %eax
cmpl -0x34(%rbp), %eax
jl 0x29b67
movl $0x0, -0x40(%rbp)
movl -0x40(%rbp), %eax
cmpl -0x30(%rbp), %eax
jge 0x29b62
movl -0x3c(%rbp), %edx
xorl %eax, %eax
movl $0xff, %ecx
cmpl $0x3, %edx
cmovel %ecx, %eax
movb %al, %cl
movq -0x68(%rbp), %rax
movb %cl, (%rax)
movl -0x40(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
movq -0x68(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x68(%rbp)
jmp 0x29b2b
jmp 0x29c47
movl $0x0, -0x44(%rbp)
movl -0x44(%rbp), %eax
cmpl -0x30(%rbp), %eax
jge 0x29c45
movq -0x10(%rbp), %rdi
callq 0x2ce50
movzbl %al, %eax
movl %eax, -0x48(%rbp)
cmpl $0x80, -0x48(%rbp)
jne 0x29b97
jmp 0x29c40
cmpl $0x80, -0x48(%rbp)
jge 0x29be2
movl -0x48(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x48(%rbp)
movl -0x48(%rbp), %eax
addl -0x44(%rbp), %eax
movl %eax, -0x44(%rbp)
cmpl $0x0, -0x48(%rbp)
je 0x29be0
movq -0x10(%rbp), %rdi
callq 0x2ce50
movb %al, %cl
movq -0x68(%rbp), %rax
movb %cl, (%rax)
movq -0x68(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x68(%rbp)
movl -0x48(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x48(%rbp)
jmp 0x29bb2
jmp 0x29c3e
cmpl $0x80, -0x48(%rbp)
jle 0x29c3c
movl -0x48(%rbp), %eax
xorl $0xff, %eax
movl %eax, -0x48(%rbp)
movl -0x48(%rbp), %eax
addl $0x2, %eax
movl %eax, -0x48(%rbp)
movq -0x10(%rbp), %rdi
callq 0x2ce50
movb %al, -0x69(%rbp)
movl -0x48(%rbp), %eax
addl -0x44(%rbp), %eax
movl %eax, -0x44(%rbp)
cmpl $0x0, -0x48(%rbp)
je 0x29c3a
movb -0x69(%rbp), %cl
movq -0x68(%rbp), %rax
movb %cl, (%rax)
movq -0x68(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x68(%rbp)
movl -0x48(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x48(%rbp)
jmp 0x29c14
jmp 0x29c3c
jmp 0x29c3e
jmp 0x29c40
jmp 0x29b6e
jmp 0x29c47
jmp 0x29c49
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x29b03
jmp 0x29d57
movl $0x0, -0x3c(%rbp)
cmpl $0x4, -0x3c(%rbp)
jge 0x29d55
movq -0x60(%rbp), %rax
movslq -0x3c(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x78(%rbp)
movl -0x3c(%rbp), %eax
cmpl -0x34(%rbp), %eax
jl 0x29cc8
movl -0x3c(%rbp), %edx
xorl %eax, %eax
movl $0xff, %ecx
cmpl $0x3, %edx
cmovel %ecx, %eax
movb %al, -0x79(%rbp)
movl $0x0, -0x40(%rbp)
movl -0x40(%rbp), %eax
cmpl -0x30(%rbp), %eax
jge 0x29cc6
movb -0x79(%rbp), %cl
movq -0x78(%rbp), %rax
movb %cl, (%rax)
movl -0x40(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
movq -0x78(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x78(%rbp)
jmp 0x29c9e
jmp 0x29d45
cmpl $0x10, -0x4c(%rbp)
jne 0x29d0a
movl $0x0, -0x40(%rbp)
movl -0x40(%rbp), %eax
cmpl -0x30(%rbp), %eax
jge 0x29d08
movq -0x10(%rbp), %rdi
callq 0x2cf90
sarl $0x8, %eax
movb %al, %cl
movq -0x78(%rbp), %rax
movb %cl, (%rax)
movl -0x40(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
movq -0x78(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x78(%rbp)
jmp 0x29cd5
jmp 0x29d43
movl $0x0, -0x40(%rbp)
movl -0x40(%rbp), %eax
cmpl -0x30(%rbp), %eax
jge 0x29d41
movq -0x10(%rbp), %rdi
callq 0x2ce50
movb %al, %cl
movq -0x78(%rbp), %rax
movb %cl, (%rax)
movl -0x40(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
movq -0x78(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x78(%rbp)
jmp 0x29d11
jmp 0x29d43
jmp 0x29d45
jmp 0x29d47
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x29c63
jmp 0x29d57
cmpl $0x0, -0x2c(%rbp)
je 0x29d92
cmpl $0x4, -0x2c(%rbp)
je 0x29d92
movq -0x60(%rbp), %rdi
movl -0x2c(%rbp), %edx
movl -0x50(%rbp), %ecx
movl -0x54(%rbp), %r8d
movl $0x4, %esi
callq 0x30f30
movq %rax, -0x60(%rbp)
cmpq $0x0, -0x60(%rbp)
jne 0x29d90
movq -0x60(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x29dbd
jmp 0x29d92
cmpq $0x0, -0x28(%rbp)
je 0x29da3
movq -0x28(%rbp), %rax
movl $0x4, (%rax)
movl -0x54(%rbp), %ecx
movq -0x20(%rbp), %rax
movl %ecx, (%rax)
movl -0x50(%rbp), %ecx
movq -0x18(%rbp), %rax
movl %ecx, (%rax)
movq -0x60(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0xa0, %rsp
popq %rbp
retq
nopw (%rax,%rax)