Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenloader/intern/readblenentry.c
| Show First 20 Lines • Show All 210 Lines • ▼ Show 20 Lines | else if (bhead->code == ENDB) { | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| *r_tot_info_items = tot; | *r_tot_info_items = tot; | ||||
| return infos; | return infos; | ||||
| } | } | ||||
| static BHead *blo_blendhandle_read_preview_rect(FileData *fd, | |||||
| BHead *bhead, | |||||
| PreviewImage *result, | |||||
| const PreviewImage *preview_from_file, | |||||
| const int preview_index) | |||||
| { | |||||
| if (preview_from_file->rect[preview_index] && preview_from_file->w[preview_index] && | |||||
| preview_from_file->h[preview_index]) { | |||||
| bhead = blo_bhead_next(fd, bhead); | |||||
| BLI_assert((preview_from_file->w[preview_index] * preview_from_file->h[preview_index] * | |||||
| sizeof(uint)) == bhead->len); | |||||
| result->rect[preview_index] = BLO_library_read_struct(fd, bhead, "PreviewImage Icon Rect"); | |||||
| } | |||||
mont29: This is very confusing, and a nice source of bugs, since signature of the function hints that… | |||||
| else { | |||||
| /* This should not be needed, but can happen in 'broken' .blend files, | |||||
| * better handle this gracefully than crashing. */ | |||||
| BLI_assert(preview_from_file->rect[preview_index] == NULL && | |||||
| preview_from_file->w[preview_index] == 0 && | |||||
| preview_from_file->h[preview_index] == 0); | |||||
| result->rect[preview_index] = NULL; | |||||
| result->w[preview_index] = result->h[preview_index] = 0; | |||||
| } | |||||
| BKE_previewimg_finish(result, preview_index); | |||||
| return bhead; | |||||
| } | |||||
| /** | /** | ||||
| * Gets the previews of all the data-blocks in a file of a certain type | * Get the PreviewImage of a single data block in a file. | ||||
| * (e.g. all the scene previews in a file). | * (e.g. all the scene previews in a file). | ||||
| * | * | ||||
| * \param bh: The blendhandle to access. | * \param bh: The blendhandle to access. | ||||
| * \param ofblocktype: The type of names to get. | * \param ofblocktype: The type of names to get. | ||||
| * \param r_tot_prev: The length of the returned list. | * \param r_tot_prev: The length of the returned list. | ||||
| * \return A BLI_linklist of PreviewImage. The PreviewImage links should be freed with malloc. | * \return A BLI_linklist of PreviewImage. The PreviewImage links should be freed with malloc. | ||||
| */ | */ | ||||
| LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *r_tot_prev) | PreviewImage *BLO_blendhandle_get_preview(BlendHandle *bh, int ofblocktype, const char *name) | ||||
| { | { | ||||
| FileData *fd = (FileData *)bh; | FileData *fd = (FileData *)bh; | ||||
| LinkNode *previews = NULL; | bool looking = false; | ||||
| BHead *bhead; | const int sdna_preview_image = DNA_struct_find_nr(fd->filesdna, "PreviewImage"); | ||||
| int looking = 0; | |||||
| PreviewImage *prv = NULL; | |||||
| PreviewImage *new_prv = NULL; | |||||
| int tot = 0; | |||||
| for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) { | for (BHead *bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) { | ||||
| if (bhead->code == ofblocktype) { | if (bhead->code == ofblocktype) { | ||||
| const char *idname = blo_bhead_id_name(fd, bhead); | const char *idname = blo_bhead_id_name(fd, bhead); | ||||
| switch (GS(idname)) { | if (STREQ(&idname[2], name)) { | ||||
| case ID_MA: /* fall through */ | looking = true; | ||||
| case ID_TE: /* fall through */ | |||||
| case ID_IM: /* fall through */ | |||||
| case ID_WO: /* fall through */ | |||||
| case ID_LA: /* fall through */ | |||||
| case ID_OB: /* fall through */ | |||||
| case ID_GR: /* fall through */ | |||||
| case ID_SCE: /* fall through */ | |||||
| case ID_AC: /* fall through */ | |||||
| new_prv = MEM_callocN(sizeof(PreviewImage), "newpreview"); | |||||
| BLI_linklist_prepend(&previews, new_prv); | |||||
| tot++; | |||||
| looking = 1; | |||||
| break; | |||||
| default: | |||||
| break; | |||||
| } | } | ||||
| } | } | ||||
| else if (bhead->code == DATA) { | else if (bhead->code == DATA) { | ||||
Done Inline Actionspreview_from_file == NULL mont29: `preview_from_file == NULL` | |||||
| if (looking) { | if (looking && bhead->SDNAnr == sdna_preview_image) { | ||||
| if (bhead->SDNAnr == DNA_struct_find_nr(fd->filesdna, "PreviewImage")) { | PreviewImage *preview_from_file = BLO_library_read_struct(fd, bhead, "PreviewImage"); | ||||
| prv = BLO_library_read_struct(fd, bhead, "PreviewImage"); | |||||
| if (prv) { | |||||
| memcpy(new_prv, prv, sizeof(PreviewImage)); | |||||
| if (prv->rect[0] && prv->w[0] && prv->h[0]) { | |||||
| bhead = blo_bhead_next(fd, bhead); | |||||
| BLI_assert((new_prv->w[0] * new_prv->h[0] * sizeof(uint)) == bhead->len); | |||||
| new_prv->rect[0] = BLO_library_read_struct(fd, bhead, "PreviewImage Icon Rect"); | |||||
| } | |||||
| else { | |||||
| /* This should not be needed, but can happen in 'broken' .blend files, | |||||
| * better handle this gracefully than crashing. */ | |||||
| BLI_assert(prv->rect[0] == NULL && prv->w[0] == 0 && prv->h[0] == 0); | |||||
| new_prv->rect[0] = NULL; | |||||
| new_prv->w[0] = new_prv->h[0] = 0; | |||||
| } | |||||
| BKE_previewimg_finish(new_prv, 0); | |||||
| if (prv->rect[1] && prv->w[1] && prv->h[1]) { | if (!preview_from_file) { | ||||
| bhead = blo_bhead_next(fd, bhead); | return NULL; | ||||
| BLI_assert((new_prv->w[1] * new_prv->h[1] * sizeof(uint)) == bhead->len); | |||||
| new_prv->rect[1] = BLO_library_read_struct(fd, bhead, "PreviewImage Image Rect"); | |||||
| } | |||||
| else { | |||||
| /* This should not be needed, but can happen in 'broken' .blend files, | |||||
| * better handle this gracefully than crashing. */ | |||||
| BLI_assert(prv->rect[1] == NULL && prv->w[1] == 0 && prv->h[1] == 0); | |||||
| new_prv->rect[1] = NULL; | |||||
| new_prv->w[1] = new_prv->h[1] = 0; | |||||
| } | |||||
| BKE_previewimg_finish(new_prv, 1); | |||||
| MEM_freeN(prv); | |||||
| } | } | ||||
| PreviewImage *result = MEM_dupallocN(preview_from_file); | |||||
| for (int preview_index = 0; preview_index < NUM_ICON_SIZES; preview_index++) { | |||||
| bhead = blo_blendhandle_read_preview_rect( | |||||
| fd, bhead, result, preview_from_file, preview_index); | |||||
| } | } | ||||
| MEM_freeN(preview_from_file); | |||||
| return result; | |||||
| } | } | ||||
| } | } | ||||
| else if (bhead->code == ENDB) { | else if (bhead->code == ENDB) { | ||||
| break; | break; | ||||
| } | } | ||||
| else { | else { | ||||
| looking = 0; | looking = 0; | ||||
| new_prv = NULL; | |||||
| prv = NULL; | |||||
| } | } | ||||
| } | } | ||||
| *r_tot_prev = tot; | return NULL; | ||||
| return previews; | |||||
| } | } | ||||
| /** | /** | ||||
| * Gets the names of all the linkable data-block types available in a file. | * Gets the names of all the linkable data-block types available in a file. | ||||
| * (e.g. "Scene", "Mesh", "Light", etc.). | * (e.g. "Scene", "Mesh", "Light", etc.). | ||||
| * | * | ||||
| * \param bh: The blendhandle to access. | * \param bh: The blendhandle to access. | ||||
| * \return A BLI_linklist of strings. The string links should be freed with #MEM_freeN(). | * \return A BLI_linklist of strings. The string links should be freed with #MEM_freeN(). | ||||
| ▲ Show 20 Lines • Show All 176 Lines • Show Last 20 Lines | |||||
This is very confusing, and a nice source of bugs, since signature of the function hints that it can randomly access a given preview_index, when this code can only even work once and with proper sequential preview_index.
The loop over preview_index values should be done in this helper. And comment should make it clears that the bhead is 'consumed' too.