bool rarch_task_push_image_load(const char *fullpath, const char *type, retro_task_callback_t cb, void *user_data) { #if defined(HAVE_RPNG) && defined(HAVE_MENU) nbio_handle_t *nbio = NULL; retro_task_t *t = NULL; uint32_t cb_type_hash = 0; struct nbio_t* handle = NULL; cb_type_hash = djb2_calculate(type); handle = nbio_open(fullpath, NBIO_READ); if (!handle) { RARCH_ERR("[image load] Failed to open '%s': %s.\n", fullpath, strerror(errno)); return false; } nbio = (nbio_handle_t*)calloc(1, sizeof(*nbio)); if (!nbio) return false; nbio->handle = handle; nbio->is_finished = false; nbio->cb = &cb_nbio_default; nbio->status = NBIO_STATUS_TRANSFER; nbio->image.status = NBIO_IMAGE_STATUS_TRANSFER; if (cb_type_hash == CB_MENU_WALLPAPER) nbio->cb = &cb_nbio_image_menu_wallpaper; else if (cb_type_hash == CB_MENU_THUMBNAIL) nbio->cb = &cb_nbio_image_menu_thumbnail; nbio_begin_read(handle); t = (retro_task_t*)calloc(1, sizeof(*t)); if (!t) { free(nbio); return false; } t->state = nbio; t->handler = rarch_task_file_load_handler; t->callback = cb; t->user_data = user_data; task_queue_ctl(TASK_QUEUE_CTL_PUSH, t); #endif return true; }
static bool rpng_nbio_load_image_argb(const char *path, uint32_t **data, unsigned *width, unsigned *height) { int retval; size_t file_len; bool ret = true; struct rpng_t *rpng = NULL; void *ptr = NULL; unsigned val = 0; struct nbio_t* handle = (void*)nbio_open(path, NBIO_READ); if (!handle) goto end; ptr = nbio_get_ptr(handle, &file_len); nbio_begin_read(handle); while (!nbio_iterate(handle)); ptr = nbio_get_ptr(handle, &file_len); if (!ptr) { ret = false; goto end; } rpng = (struct rpng_t*)calloc(1, sizeof(struct rpng_t)); if (!rpng) { ret = false; goto end; } rpng->buff_data = (uint8_t*)ptr; if (!rpng->buff_data) { ret = false; goto end; } if (!rpng_nbio_load_image_argb_start(rpng)) { ret = false; goto end; } while (rpng_nbio_load_image_argb_iterate( rpng->buff_data, rpng, &val)) { rpng->buff_data += val; } #if 0 fprintf(stderr, "has_ihdr: %d\n", rpng->has_ihdr); fprintf(stderr, "has_idat: %d\n", rpng->has_idat); fprintf(stderr, "has_iend: %d\n", rpng->has_iend); #endif if (!rpng->has_ihdr || !rpng->has_idat || !rpng->has_iend) { ret = false; goto end; } do { retval = rpng_nbio_load_image_argb_process(rpng, data, width, height); }while(retval == IMAGE_PROCESS_NEXT); if (retval == IMAGE_PROCESS_ERROR || retval == IMAGE_PROCESS_ERROR_END) ret = false; end: if (handle) nbio_free(handle); if (rpng) rpng_nbio_load_image_free(rpng); rpng = NULL; if (!ret) free(*data); return ret; }
static int rarch_main_data_nbio_iterate_poll(nbio_handle_t *nbio) { char elem0[PATH_MAX_LENGTH]; unsigned elem0_hash = 0; uint32_t cb_type_hash = 0; struct nbio_t* handle = NULL; struct string_list *str_list = NULL; const char *path = NULL; if (!nbio) return -1; path = msg_queue_pull(nbio->msg_queue); if (!path) return -1; /* Can only deal with one NBIO transfer at a time for now */ if (nbio->handle) return -1; str_list = string_split(path, "|"); if (!str_list || (str_list->size < 1)) goto error; strlcpy(elem0, str_list->elems[0].data, sizeof(elem0)); elem0_hash = djb2_calculate(elem0); /* TODO/FIXME - should be able to deal with this * in a better way. */ switch(elem0_hash) { case CB_MENU_WALLPAPER: case CB_MENU_BOXART: goto error; default: break; } if (str_list->size > 1) cb_type_hash = djb2_calculate(str_list->elems[1].data); handle = nbio_open(elem0, NBIO_READ); if (!handle) { RARCH_ERR("Could not create new file loading handle.\n"); goto error; } nbio->handle = handle; nbio->is_finished = false; nbio->cb = &cb_nbio_default; switch (cb_type_hash) { #if defined(HAVE_MENU) && defined(HAVE_RPNG) case CB_MENU_WALLPAPER: nbio->cb = &cb_nbio_image_menu_wallpaper; break; case CB_MENU_BOXART: nbio->cb = &cb_nbio_image_menu_boxart; break; #endif } nbio_begin_read(handle); string_list_free(str_list); return 0; error: if (str_list) string_list_free(str_list); return -1; }
static int rarch_main_data_nbio_iterate_poll(nbio_handle_t *nbio) { struct nbio_t* handle; char elem0[PATH_MAX_LENGTH], elem1[PATH_MAX_LENGTH]; struct string_list *str_list = NULL; const char *path = NULL; if (!nbio) return -1; path = msg_queue_pull(nbio->msg_queue); if (!path) return -1; /* Can only deal with one NBIO transfer at a time for now */ if (nbio->handle) return -1; str_list = string_split(path, "|"); if (!str_list) goto error; if (str_list->size > 0) strlcpy(elem0, str_list->elems[0].data, sizeof(elem0)); if (str_list->size > 1) strlcpy(elem1, str_list->elems[1].data, sizeof(elem1)); handle = nbio_open(elem0, NBIO_READ); if (!handle) { RARCH_ERR("Could not create new file loading handle.\n"); goto error; } nbio->handle = handle; nbio->is_blocking = false; nbio->is_finished = false; nbio->cb = &cb_nbio_default; if (elem1[0] != '\0') { #ifdef HAVE_MENU if (!strcmp(elem1, "cb_menu_wallpaper")) nbio->cb = &cb_nbio_image_menu_wallpaper; #endif } nbio_begin_read(handle); string_list_free(str_list); return 0; error: if (str_list) string_list_free(str_list); return -1; }
static bool rpng_load_image_argb(const char *path, uint32_t **data, unsigned *width, unsigned *height) { int retval; size_t file_len; bool ret = true; rpng_t *rpng = NULL; void *ptr = NULL; struct nbio_t* handle = (struct nbio_t*)nbio_open(path, NBIO_READ); if (!handle) goto end; nbio_begin_read(handle); while (!nbio_iterate(handle)); ptr = nbio_get_ptr(handle, &file_len); if (!ptr) { ret = false; goto end; } rpng = rpng_alloc(); if (!rpng) { ret = false; goto end; } if (!rpng_set_buf_ptr(rpng, (uint8_t*)ptr)) { ret = false; goto end; } if (!rpng_start(rpng)) { ret = false; goto end; } while (rpng_iterate_image(rpng)); if (!rpng_is_valid(rpng)) { ret = false; goto end; } do { retval = rpng_process_image(rpng, (void**)data, file_len, width, height); }while(retval == IMAGE_PROCESS_NEXT); if (retval == IMAGE_PROCESS_ERROR || retval == IMAGE_PROCESS_ERROR_END) ret = false; end: if (handle) nbio_free(handle); if (rpng) rpng_free(rpng); rpng = NULL; if (!ret) free(*data); return ret; }
void task_file_load_handler(retro_task_t *task) { nbio_handle_t *nbio = (nbio_handle_t*)task->state; if (nbio) { switch (nbio->status) { case NBIO_STATUS_INIT: if (nbio && !string_is_empty(nbio->path)) { struct nbio_t *handle = (struct nbio_t*)nbio_open(nbio->path, NBIO_READ); if (handle) { nbio->handle = handle; nbio->status = NBIO_STATUS_TRANSFER; nbio_begin_read(handle); return; } else task_set_cancelled(task, true); } break; case NBIO_STATUS_TRANSFER_PARSE: if (!nbio || task_file_transfer_iterate_parse(nbio) == -1) task_set_cancelled(task, true); nbio->status = NBIO_STATUS_TRANSFER_FINISHED; break; case NBIO_STATUS_TRANSFER: if (!nbio || task_file_transfer_iterate_transfer(nbio) == -1) nbio->status = NBIO_STATUS_TRANSFER_PARSE; break; case NBIO_STATUS_TRANSFER_FINISHED: break; } switch (nbio->type) { case NBIO_TYPE_PNG: case NBIO_TYPE_JPEG: case NBIO_TYPE_TGA: case NBIO_TYPE_BMP: if (!task_image_load_handler(task)) task_set_finished(task, true); break; case NBIO_TYPE_MP3: case NBIO_TYPE_FLAC: case NBIO_TYPE_OGG: case NBIO_TYPE_MOD: case NBIO_TYPE_WAV: if (!task_audio_mixer_load_handler(task)) task_set_finished(task, true); break; case NBIO_TYPE_NONE: default: if (nbio->is_finished) task_set_finished(task, true); break; } } if (task_get_cancelled(task)) { task_set_error(task, strdup("Task canceled.")); task_set_finished(task, true); } }
void task_file_load_handler(retro_task_t *task) { nbio_handle_t *nbio = (nbio_handle_t*)task->state; if (nbio) { switch (nbio->status) { case NBIO_STATUS_INIT: if (nbio && !string_is_empty(nbio->path)) { const char *fullpath = nbio->path; struct nbio_t *handle = nbio_open(fullpath, NBIO_READ); if (handle) { nbio->handle = handle; nbio->status = NBIO_STATUS_TRANSFER; if (strstr(fullpath, file_path_str(FILE_PATH_PNG_EXTENSION))) nbio->image_type = IMAGE_TYPE_PNG; else if (strstr(fullpath, file_path_str(FILE_PATH_JPEG_EXTENSION)) || strstr(fullpath, file_path_str(FILE_PATH_JPG_EXTENSION))) nbio->image_type = IMAGE_TYPE_JPEG; else if (strstr(fullpath, file_path_str(FILE_PATH_BMP_EXTENSION))) nbio->image_type = IMAGE_TYPE_BMP; else if (strstr(fullpath, file_path_str(FILE_PATH_TGA_EXTENSION))) nbio->image_type = IMAGE_TYPE_TGA; nbio_begin_read(handle); return; } else task_set_cancelled(task, true); } break; case NBIO_STATUS_TRANSFER_PARSE: if (task_file_transfer_iterate_parse(nbio) == -1) task_set_cancelled(task, true); nbio->status = NBIO_STATUS_TRANSFER_PARSE_FREE; break; case NBIO_STATUS_TRANSFER: if (task_file_transfer_iterate_transfer(nbio) == -1) nbio->status = NBIO_STATUS_TRANSFER_PARSE; break; case NBIO_STATUS_TRANSFER_PARSE_FREE: case NBIO_STATUS_POLL: default: break; } switch (nbio->image_type) { case IMAGE_TYPE_PNG: case IMAGE_TYPE_JPEG: case IMAGE_TYPE_TGA: case IMAGE_TYPE_BMP: if (!task_image_load_handler(task)) task_set_finished(task, true); break; case 0: if (nbio->is_finished) task_set_finished(task, true); break; } } if (task_get_cancelled(task)) { task_set_error(task, strdup("Task canceled.")); task_set_finished(task, true); } }