// File: /workspace/github_cpp_makefile_star2_O2/brianwu02[P]ImageProcessing/briansFunctions.cpp
// Function: padImage(imageS*, int, imageS*)
void padImage(imageP I1, int sz, imageP paddedImg) {
    /* PIXEL REPLICATION PADDING
     * takes I1 as input image, I1 and applies pixel replication technique
     * to paddedImg using kernel size sz * sz.
     *   Pixel Replcation Example:
     *                             leftIdx         rightIdx
     *   AA|ABCDEFGH|HH                    x x x x
     *   AA|ABCDEFGH|HH        region0  |  region1  |  region2   y
     *   --------------        -------------------------------  topIdx
     *   AA|ABCDEFGH|HH        region3  |           |  region5   y
     *   II|IJKLMNOP|PP        region3  |  region4  |  region5   y
     *   QQ|QRSTUVWX|XX        region3  |  orig img |  region5   y
     *   YY|YZabcdef|ff        region3  |           |  region5   y
     *   gg|ghijklmn|nn        -------------------------------  botIdx
     *   oo|opqrstuv|vv        region6  | region 7  | region 8   y
     *   --------------
     *   oo|opqrstuv|vv       
     *   oo|opqrstuv|vv
     *   
     *   region0 = x <  leftIdx  and y <  topIdx
     *   region1 = x >= leftIdx  and x <  rightIdx and y <  topIdx 
     *   region2 = x >= rightIdx and y <  topIdx
     *   region3 = x <  leftIdx  and y >= topIdx   and y <  botIdx
     *   region4 = x >= leftIdx  and x <  rightIdx and y >= topIdx and y < botIdx
     *   region5 = x >= rightIdx and y >= topIdx   and y <  botIdx
     *   region6 = x <  leftIdx  and y >= botIdx
     *   region7 = x >= leftIdx  and x <  rightIdx and y >= botIdx
     *   region8 = x >= rightIdx and y >= botIdx
     *
     */

    int n = (sz - 1) / 2;
    int m = (sz - 1) / 2;
    unsigned char *in, *paddedOut;

    int total = I1->width * I1->height;
    int w = I1->width;
    int h = I1->height;

    paddedImg->width = (w + 2*m);
    paddedImg->height = (h + 2*n);

    int paddedTotal = paddedImg->height * paddedImg->width;
    paddedImg->image = (unsigned char*) malloc(paddedTotal);
    paddedOut = paddedImg->image;
    in = I1->image;

    int paddedHeight = paddedImg->height;
    int paddedWidth = paddedImg->width;

    // vertical indices that represent padding columns
    int leftIdx = n;
    int rightIdx = w + n;

    // horizontal indices that represent padding rows
    int topIdx = m;
    int botIdx = h + m;


    for (int y=0; y < paddedHeight; y++) {
        for (int x=0; x < paddedWidth; x++) {

            // this condition comes first since it will occur most frequent.
            // dont need the branch predictor working so hard.
            if (x >= leftIdx and x < rightIdx and y >= topIdx and y < botIdx) {
                // we are in region 4.
                paddedOut[y*paddedWidth+x] = in[(y-n) * w + (x-m)];

            } else if (x < leftIdx and y < topIdx) {
                // we are in region 0.
                // assign padded pixel as upper left original pixel value.
                paddedOut[y*paddedWidth+x] = in[0]; 

            } else if (x >= leftIdx and x < rightIdx and y < topIdx) {
                // we are in region 1.
                // assign pixel values to be top row of original image.
                paddedOut[y*paddedWidth+x] = in[(x-m)]; 
                
            } else if (x >= rightIdx and y < topIdx) {
                // we are in region 2.
                // assign padded pixels as upper right original pixel value.
                paddedOut[y*paddedWidth+x] = in[w-1];

            } else if (x < leftIdx and y >= topIdx and y < botIdx) {
                // we are in region 3.
                // assigned padded pixel as left most pixel of current row.
                paddedOut[y*paddedWidth+x] = in[(y - n) * w];

            } else if (x >= rightIdx and y >= topIdx and y < botIdx) {
                // we are in region 5
                // assign padded pixel as right most pixel of current row
                paddedOut[y*paddedWidth+x] = in[(y - n) * w + (w-1) ];

            } else if (x < leftIdx and y >= botIdx) {
                // we are in region 6
                // assign padded pixel as bottom left original pixel value.
                paddedOut[y*paddedWidth+x] = in[w*(h-1)];
            
            } else if (x >= leftIdx and x < rightIdx and y >= botIdx) {
                // we are in region 7
                // assign padded pixel to be bottom-most row of original input img.
                paddedOut[y*paddedWidth+x] = in[(h-1) * w + (x-m)];
            
            } else if (x >= rightIdx and y >= botIdx) {
                // we are in region 8
                // assign padded pixel as bottom right original pixel value.
                paddedOut[y*paddedWidth+x] = in[w*h-1];
            
            } else {
                // this should never happen since this will only occur if we have
                // not handled a certain x,y coordinate.
                cerr << "unhandled condition, something bad" << endl;
                cerr << "x is: " << x << " y is: " << y << endl;
            }
        }
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movq %rdx, %r8
movq %rdi, %r12
leal -0x1(%rsi), %eax
pushq $0x2
popq %rcx
cltd
idivl %ecx
movl %eax, %r14d
movl (%rdi), %ebp
movl 0x4(%rdi), %r13d
leal (%rbp,%r14,2), %ebx
movq %r8, 0x10(%rsp)
movl %ebx, (%r8)
leal (%r13,%r14,2), %r15d
movl %r15d, 0x4(%r8)
movl %r15d, %eax
imull %ebx, %eax
movslq %eax, %rdi
callq 0x1100
movq %r15, %r8
movq %rax, %r10
movq 0x10(%rsp), %rax
movq %r10, 0x8(%rax)
movq 0x8(%r12), %r11
leal (%r14,%rbp), %eax
leal (%r14,%r13), %ecx
leal -0x1(%r13), %edx
imull %ebp, %edx
movslq %edx, %rdx
imull %ebp, %r13d
movslq %r13d, %rsi
movq %rsi, 0x28(%rsp)
movq %rbp, 0x68(%rsp)
movslq %ebp, %rdi
movslq %r14d, %rbp
movslq %eax, %r13
xorl %r14d, %r14d
testl %ebx, %ebx
movl $0x0, %r9d
cmovgl %ebx, %r9d
movslq %ebx, %rax
movq %rax, 0x60(%rsp)
movslq %ecx, %rsi
testl %r8d, %r8d
cmovlel %r14d, %r8d
leaq (%r11,%rdi), %rax
decq %rax
movq %rax, 0x58(%rsp)
movl %edi, %eax
notl %eax
imull %ebp, %eax
movq %rax, 0x10(%rsp)
movq %rdx, 0x50(%rsp)
subl %ebp, %edx
movq %rdx, 0x48(%rsp)
movq %r11, %rax
subq %rbp, %rax
movq %rax, 0x70(%rsp)
movq %r8, 0x38(%rsp)
movq %r11, 0x30(%rsp)
movq %rdi, 0x18(%rsp)
movq %r9, 0x8(%rsp)
cmpq %r8, %r14
je 0x1dc6
movq %r14, %rax
subq %rbp, %rax
setge %bl
imulq %rdi, %rax
movq %rax, 0x20(%rsp)
xorl %r12d, %r12d
cmpq %r12, %r9
je 0x1daa
cmpq %rbp, %r12
setge %cl
cmpq %r13, %r12
setl %al
andb %cl, %al
movl %eax, %edx
andb %bl, %dl
cmpb $0x1, %dl
jne 0x1c01
cmpq %rsi, %r14
jge 0x1c01
movq 0x10(%rsp), %rax
addl %r12d, %eax
cltq
movb (%r11,%rax), %al
movb %al, (%r10,%r12)
jmp 0x1c50
movq %rsi, %r15
cmpq %rbp, %r12
setge %dl
cmpq %rbp, %r14
setge %sil
orb %dl, %sil
jne 0x1c1b
movb (%r11), %al
jmp 0x1c49
xorb $0x1, %al
cmpq %rbp, %r14
setge %dl
orb %al, %dl
jne 0x1c32
movq 0x70(%rsp), %rax
movb (%rax,%r12), %al
jmp 0x1c49
cmpq %r13, %r12
setl %dl
cmpq %rbp, %r14
setge %sil
orb %dl, %sil
jne 0x1c58
movb -0x1(%r11,%rdi), %al
movb %al, (%r10,%r12)
movq %r15, %rsi
incq %r12
jmp 0x1bc8
cmpq %rbp, %r12
setl %dl
movq %r15, %r9
cmpq %r15, %r14
setl %sil
andb %bl, %dl
andb %sil, %dl
cmpb $0x1, %dl
jne 0x1c81
movq 0x20(%rsp), %rax
movb (%r11,%rax), %al
movb %al, (%r10,%r12)
jmp 0x1cb7
cmpq %r13, %r12
setge %dl
cmpq %r9, %r14
setl %sil
cmpq %rbp, %r14
setge %dil
andb %dl, %dil
andb %sil, %dil
cmpb $0x1, %dil
jne 0x1cc1
movq 0x58(%rsp), %rax
movq 0x20(%rsp), %rcx
movb (%rax,%rcx), %al
movb %al, (%r10,%r12)
movq 0x18(%rsp), %rdi
movq %r9, %rsi
movq 0x8(%rsp), %r9
jmp 0x1c50
cmpq %r9, %r14
setl %dl
orb %dl, %cl
movq 0x18(%rsp), %rdi
movq %r9, %rsi
je 0x1d7f
cmpq %rsi, %r14
setl %cl
orb %cl, %al
movq 0x8(%rsp), %r9
je 0x1d91
cmpq %r13, %r12
setl %al
cmpq %rsi, %r14
setl %cl
orb %al, %cl
je 0x1d9b
movq 0x22eb(%rip), %rdi      # 0x3ff0
leaq 0x3d8(%rip), %rsi       # 0x20e4
movq %r10, 0x40(%rsp)
callq 0x1090
movq %rax, %rdi
callq 0x1060
movq 0x22cb(%rip), %rdi      # 0x3ff0
leaq 0x3db(%rip), %rsi       # 0x2107
callq 0x1090
movq %rax, %rdi
movl %r12d, %esi
callq 0x1150
movq %rax, %rdi
leaq 0x3c8(%rip), %rsi       # 0x210e
callq 0x1090
movq %rax, %rdi
movl %r14d, %esi
callq 0x1150
movq %rax, %rdi
callq 0x1060
movq 0x8(%rsp), %r9
movq %r15, %rsi
movq 0x18(%rsp), %rdi
movq 0x30(%rsp), %r11
movq 0x40(%rsp), %r10
movq 0x38(%rsp), %r8
jmp 0x1c50
movq 0x50(%rsp), %rax
movb (%r11,%rax), %al
movb %al, (%r10,%r12)
jmp 0x1cba
movq 0x48(%rsp), %rax
jmp 0x1bf2
movq 0x28(%rsp), %rax
movb -0x1(%r11,%rax), %al
jmp 0x1bfb
incq %r14
addq 0x60(%rsp), %r10
movq 0x10(%rsp), %rax
addq 0x68(%rsp), %rax
movq %rax, 0x10(%rsp)
jmp 0x1baa
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq