// File: /workspace/github_c_makefile_star2_O0/OnionIoT[P]lv_example/lvgl/src/lv_draw/lv_img_cache.c
// Function: lv_img_cache_open
lv_img_cache_entry_t * lv_img_cache_open(const void * src, const lv_style_t * style)
{
    if(entry_cnt == 0) {
        LV_LOG_WARN("lv_img_cache_open: the cache size is 0");
        return NULL;
    }

    lv_img_cache_entry_t * cache = LV_GC_ROOT(_lv_img_cache_array);

    /*Decrement all lifes. Make the entries older*/
    uint16_t i;
    for(i = 0; i < entry_cnt; i++) {
        if(cache[i].life > INT32_MIN + LV_IMG_CACHE_AGING) {
            cache[i].life -= LV_IMG_CACHE_AGING;
        }
    }

    /*Is the image cached?*/
    lv_img_cache_entry_t * cached_src = NULL;
    for(i = 0; i < entry_cnt; i++) {
        bool match = false;
        lv_img_src_t src_type = lv_img_src_get_type(cache[i].dec_dsc.src);
        if(src_type == LV_IMG_SRC_VARIABLE) {
            if(cache[i].dec_dsc.src == src) match = true;
        } else if(src_type == LV_IMG_SRC_FILE) {
            if(strcmp(cache[i].dec_dsc.src, src) == 0) match = true;
        }

        if(match) {
            /* If opened increment its life.
             * Image difficult to open should live longer to keep avoid frequent their recaching.
             * Therefore increase `life` with `time_to_open`*/
            cached_src = &cache[i];
            cached_src->life += cached_src->dec_dsc.time_to_open * LV_IMG_CACHE_LIFE_GAIN;
            if(cached_src->life > LV_IMG_CACHE_LIFE_LIMIT) cached_src->life = LV_IMG_CACHE_LIFE_LIMIT;
            LV_LOG_TRACE("image draw: image found in the cache");
            break;
        }
    }

    /*The image is not cached then cache it now*/
    if(cached_src == NULL) {
        /*Find an entry to reuse. Select the entry with the least life*/
        cached_src = &cache[0];
        for(i = 1; i < entry_cnt; i++) {
            if(cache[i].life < cached_src->life) {
                cached_src = &cache[i];
            }
        }

        /*Close the decoder to reuse if it was opened (has a valid source)*/
        if(cached_src->dec_dsc.src) {
            lv_img_decoder_close(&cached_src->dec_dsc);
            LV_LOG_INFO("image draw: cache miss, close and reuse an entry");
        } else {
            LV_LOG_INFO("image draw: cache miss, cached to an empty entry");
        }

        /*Open the image and measure the time to open*/
        uint32_t t_start;
        t_start                          = lv_tick_get();
        cached_src->dec_dsc.time_to_open = 0;
        lv_res_t open_res                = lv_img_decoder_open(&cached_src->dec_dsc, src, style);
        if(open_res == LV_RES_INV) {
            LV_LOG_WARN("Image draw cannot open the image resource");
            lv_img_decoder_close(&cached_src->dec_dsc);
            memset(&cached_src->dec_dsc, 0, sizeof(lv_img_decoder_dsc_t));
            memset(cached_src, 0, sizeof(lv_img_cache_entry_t));
            cached_src->life = INT32_MIN; /*Make the empty entry very "weak" to force its use  */
            return NULL;
        }

        cached_src->life = 0;

        /*If `time_to_open` was not set in the open function set it here*/
        if(cached_src->dec_dsc.time_to_open == 0) {
            cached_src->dec_dsc.time_to_open = lv_tick_elaps(t_start);
        }

        if(cached_src->dec_dsc.time_to_open == 0) cached_src->dec_dsc.time_to_open = 1;
    }

    return cached_src;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movzwl 0x34535(%rip), %eax     # 0x9abcc
cmpl $0x0, %eax
jne 0x666a9
movq $0x0, -0x8(%rbp)
jmp 0x66931
leaq 0x2afc0(%rip), %rax     # 0x91670
movq (%rax), %rax
movq %rax, -0x20(%rbp)
movw $0x0, -0x22(%rbp)
movzwl -0x22(%rbp), %eax
movzwl 0x34504(%rip), %ecx     # 0x9abcc
cmpl %ecx, %eax
jge 0x6670c
movq -0x20(%rbp), %rax
movzwl -0x22(%rbp), %ecx
imulq $0x48, %rcx, %rcx
addq %rcx, %rax
cmpl $0x80000001, 0x40(%rax) # imm = 0x80000001
jle 0x666fc
movq -0x20(%rbp), %rax
movzwl -0x22(%rbp), %ecx
imulq $0x48, %rcx, %rcx
addq %rcx, %rax
movl 0x40(%rax), %ecx
subl $0x1, %ecx
movl %ecx, 0x40(%rax)
jmp 0x666fe
movw -0x22(%rbp), %ax
addw $0x1, %ax
movw %ax, -0x22(%rbp)
jmp 0x666bd
movq $0x0, -0x30(%rbp)
movw $0x0, -0x22(%rbp)
movzwl -0x22(%rbp), %eax
movzwl 0x344a7(%rip), %ecx     # 0x9abcc
cmpl %ecx, %eax
jge 0x66800
movb $0x0, -0x31(%rbp)
movq -0x20(%rbp), %rax
movzwl -0x22(%rbp), %ecx
imulq $0x48, %rcx, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rdi
callq 0x63110
movb %al, -0x32(%rbp)
movzbl -0x32(%rbp), %eax
cmpl $0x0, %eax
jne 0x66774
movq -0x20(%rbp), %rax
movzwl -0x22(%rbp), %ecx
imulq $0x48, %rcx, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rax
cmpq -0x10(%rbp), %rax
jne 0x66772
movb $0x1, -0x31(%rbp)
jmp 0x667a6
movzbl -0x32(%rbp), %eax
cmpl $0x1, %eax
jne 0x667a4
movq -0x20(%rbp), %rax
movzwl -0x22(%rbp), %ecx
imulq $0x48, %rcx, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x20d0
cmpl $0x0, %eax
jne 0x667a2
movb $0x1, -0x31(%rbp)
jmp 0x667a4
jmp 0x667a6
testb $0x1, -0x31(%rbp)
je 0x667ed
movq -0x20(%rbp), %rax
movzwl -0x22(%rbp), %ecx
imulq $0x48, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movl 0x28(%rax), %ecx
shll $0x0, %ecx
movq -0x30(%rbp), %rax
addl 0x40(%rax), %ecx
movl %ecx, 0x40(%rax)
movq -0x30(%rbp), %rax
cmpl $0x3e8, 0x40(%rax)      # imm = 0x3E8
jle 0x667eb
movq -0x30(%rbp), %rax
movl $0x3e8, 0x40(%rax)      # imm = 0x3E8
jmp 0x66800
jmp 0x667ef
movw -0x22(%rbp), %ax
addw $0x1, %ax
movw %ax, -0x22(%rbp)
jmp 0x6671a
cmpq $0x0, -0x30(%rbp)
jne 0x66929
movq -0x20(%rbp), %rax
movq %rax, -0x30(%rbp)
movw $0x1, -0x22(%rbp)
movzwl -0x22(%rbp), %eax
movzwl 0x343a8(%rip), %ecx     # 0x9abcc
cmpl %ecx, %eax
jge 0x66866
movq -0x20(%rbp), %rax
movzwl -0x22(%rbp), %ecx
imulq $0x48, %rcx, %rcx
addq %rcx, %rax
movl 0x40(%rax), %eax
movq -0x30(%rbp), %rcx
cmpl 0x40(%rcx), %eax
jge 0x66856
movq -0x20(%rbp), %rax
movzwl -0x22(%rbp), %ecx
imulq $0x48, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x30(%rbp)
jmp 0x66858
movw -0x22(%rbp), %ax
addw $0x1, %ax
movw %ax, -0x22(%rbp)
jmp 0x66819
movq -0x30(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x6687c
movq -0x30(%rbp), %rdi
callq 0x65c60
jmp 0x6687e
jmp 0x6687e
callq 0xdfe0
movl %eax, -0x38(%rbp)
movq -0x30(%rbp), %rax
movl $0x0, 0x28(%rax)
movq -0x30(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
callq 0x65a70
movb %al, -0x39(%rbp)
movzbl -0x39(%rbp), %eax
cmpl $0x0, %eax
jne 0x668ec
movq -0x30(%rbp), %rdi
callq 0x65c60
movq -0x30(%rbp), %rdi
xorl %esi, %esi
movl $0x40, %edx
callq 0x2090
movq -0x30(%rbp), %rdi
xorl %esi, %esi
movl $0x48, %edx
callq 0x2090
movq -0x30(%rbp), %rax
movl $0x80000000, 0x40(%rax) # imm = 0x80000000
movq $0x0, -0x8(%rbp)
jmp 0x66931
movq -0x30(%rbp), %rax
movl $0x0, 0x40(%rax)
movq -0x30(%rbp), %rax
cmpl $0x0, 0x28(%rax)
jne 0x66912
movl -0x38(%rbp), %edi
callq 0xe010
movl %eax, %ecx
movq -0x30(%rbp), %rax
movl %ecx, 0x28(%rax)
movq -0x30(%rbp), %rax
cmpl $0x0, 0x28(%rax)
jne 0x66927
movq -0x30(%rbp), %rax
movl $0x1, 0x28(%rax)
jmp 0x66929
movq -0x30(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x40, %rsp
popq %rbp
retq
nopl (%rax,%rax)