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; | |||||
| } | |||||
| /** | |||||
| * Get the PreviewImage of a single data block in a file. | |||||
| * (e.g. all the scene previews in a file). | |||||
| * | |||||
| * \param bh: The blendhandle to access. | |||||
| * \param ofblocktype: The type of names to get. | |||||
| * \param name: Name of the block without the ID_ prefix, to read the preview image from. | |||||
| * \return PreviewImage or NULL when no preview Images have been found. Caller owns the returned | |||||
| */ | |||||
| PreviewImage *BLO_blendhandle_get_preview_for_id(BlendHandle *bh, | |||||
| int ofblocktype, | |||||
| const char *name) | |||||
| { | |||||
| FileData *fd = (FileData *)bh; | |||||
| bool looking = false; | |||||
| const int sdna_preview_image = DNA_struct_find_nr(fd->filesdna, "PreviewImage"); | |||||
| for (BHead *bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) { | |||||
| if (bhead->code == DATA) { | |||||
| if (looking && bhead->SDNAnr == sdna_preview_image) { | |||||
| PreviewImage *preview_from_file = BLO_library_read_struct(fd, bhead, "PreviewImage"); | |||||
| if (!preview_from_file) { | |||||
mont29Unsubmitted Done Inline Actionspreview_from_file == NULL mont29: `preview_from_file == NULL` | |||||
| break; | |||||
| } | |||||
| 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 (looking || bhead->code == ENDB) { | |||||
| /* We were looking for a preview image, but didn't find any belonging to block. So it doesn't | |||||
| * exist. */ | |||||
| break; | |||||
| } | |||||
| else if (bhead->code == ofblocktype) { | |||||
| const char *idname = blo_bhead_id_name(fd, bhead); | |||||
| if (STREQ(&idname[2], name)) { | |||||
| looking = true; | |||||
| } | |||||
| } | |||||
| } | |||||
| return NULL; | |||||
| } | |||||
| /** | /** | ||||
| * Gets the previews of all the data-blocks in a file of a certain type | * Gets the previews of all the data-blocks in a file of a certain type | ||||
| * (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. | ||||
| Show All 32 Lines | for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) { | ||||
| } | } | ||||
| else if (bhead->code == DATA) { | else if (bhead->code == DATA) { | ||||
| if (looking) { | if (looking) { | ||||
| if (bhead->SDNAnr == DNA_struct_find_nr(fd->filesdna, "PreviewImage")) { | if (bhead->SDNAnr == DNA_struct_find_nr(fd->filesdna, "PreviewImage")) { | ||||
| prv = BLO_library_read_struct(fd, bhead, "PreviewImage"); | prv = BLO_library_read_struct(fd, bhead, "PreviewImage"); | ||||
| if (prv) { | if (prv) { | ||||
| memcpy(new_prv, prv, sizeof(PreviewImage)); | memcpy(new_prv, prv, sizeof(PreviewImage)); | ||||
| if (prv->rect[0] && prv->w[0] && prv->h[0]) { | for (int preview_index = 0; preview_index < NUM_ICON_SIZES; preview_index++) { | ||||
| bhead = blo_bhead_next(fd, bhead); | bhead = blo_blendhandle_read_preview_rect(fd, bhead, new_prv, prv, preview_index); | ||||
| 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]) { | |||||
| bhead = blo_bhead_next(fd, bhead); | |||||
| 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); | MEM_freeN(prv); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else if (bhead->code == ENDB) { | else if (bhead->code == ENDB) { | ||||
| break; | break; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 193 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.