Skip to content

Commit 37a0061

Browse files
committed
Store plugins in shared_ptr, so FIMULTIBITMAP can be safely closed after plugin reset
1 parent 6b07782 commit 37a0061

3 files changed

Lines changed: 121 additions & 86 deletions

File tree

Source/FreeImage/MultiPage.cpp

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ struct MULTIBITMAPHEADER {
104104
SetDefaultIO(&io);
105105
}
106106

107-
PluginNodeBase* node{ nullptr };
107+
std::shared_ptr<PluginNodeBase> node{ nullptr };
108108
FREE_IMAGE_FORMAT fif{ FIF_UNKNOWN };
109109
FreeImageIO io;
110110
fi_handle handle{ nullptr };
@@ -227,7 +227,8 @@ FIMULTIBITMAP* OpenMultiBitmapImpl(FREE_IMAGE_FORMAT fif, std::filesystem::path
227227

228228
if (auto& plugins = PluginsRegistrySingleton::Instance()) {
229229

230-
if (auto node = plugins->FindFromFIF(fif)) {
230+
if (auto it = plugins->FindFromFIF(fif); it != plugins->NodesCEnd()) {
231+
assert(it->second != nullptr);
231232
if (!create_new) {
232233
handle = FreeImage_FOpen(filename, "rb");
233234
if (!handle) {
@@ -239,7 +240,7 @@ FIMULTIBITMAP* OpenMultiBitmapImpl(FREE_IMAGE_FORMAT fif, std::filesystem::path
239240
auto header = std::make_unique<MULTIBITMAPHEADER>();
240241
header->m_filename = filename;
241242
// io is default
242-
header->node = node;
243+
header->node = it->second; // not null
243244
header->fif = fif;
244245
header->handle = handle;
245246
header->read_only = static_cast<bool>(read_only);
@@ -250,13 +251,13 @@ FIMULTIBITMAP* OpenMultiBitmapImpl(FREE_IMAGE_FORMAT fif, std::filesystem::path
250251

251252
if (header->handle) {
252253
// open persistent data is supported
253-
if (node->SupportsOpenPersistent()) {
254-
header->persistent_data = node->OpenPersistent(&header->io, header->handle, header->read_only);
254+
if (header->node->SupportsOpenPersistent()) {
255+
header->persistent_data = header->node->OpenPersistent(&header->io, header->handle, header->read_only);
255256
// cache the page count
256-
header->page_count = node->GetPageCount(&header->io, header->handle, header->persistent_data);
257+
header->page_count = header->node->GetPageCount(&header->io, header->handle, header->persistent_data);
257258
}
258259
else {
259-
header->page_count = node->GetPageCount(&header->io, header->handle);
260+
header->page_count = header->node->GetPageCount(&header->io, header->handle);
260261
}
261262
}
262263
else {
@@ -329,11 +330,13 @@ FreeImage_OpenMultiBitmapFromHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_h
329330

330331
if (auto& plugins = PluginsRegistrySingleton::Instance()) {
331332

332-
if (auto node = plugins->FindFromFIF(fif)) {
333+
if (auto it = plugins->FindFromFIF(fif); it != plugins->NodesCEnd()) {
334+
assert(it->second != nullptr);
335+
333336
auto bitmap = std::make_unique<FIMULTIBITMAP>();
334337
auto header = std::make_unique<MULTIBITMAPHEADER>();
335338
header->io = *io;
336-
header->node = node;
339+
header->node = it->second; // not null
337340
header->fif = fif;
338341
header->handle = handle;
339342
header->read_only = read_only;
@@ -343,13 +346,13 @@ FreeImage_OpenMultiBitmapFromHandle(FREE_IMAGE_FORMAT fif, FreeImageIO *io, fi_h
343346
// store the MULTIBITMAPHEADER in the surrounding FIMULTIBITMAP structure
344347

345348
// open persistent data is supported
346-
if (node->SupportsOpenPersistent()) {
347-
header->persistent_data = node->OpenPersistent(&header->io, header->handle, header->read_only);
349+
if (header->node->SupportsOpenPersistent()) {
350+
header->persistent_data = header->node->OpenPersistent(&header->io, header->handle, header->read_only);
348351
// cache the page count
349-
header->page_count = node->GetPageCount(&header->io, header->handle, header->persistent_data);
352+
header->page_count = header->node->GetPageCount(&header->io, header->handle, header->persistent_data);
350353
}
351354
else {
352-
header->page_count = node->GetPageCount(&header->io, header->handle);
355+
header->page_count = header->node->GetPageCount(&header->io, header->handle);
353356
}
354357

355358
// allocate a continueus block to describe the bitmap
@@ -383,7 +386,10 @@ bool SaveMultiBitmapToHandleImpl(FREE_IMAGE_FORMAT fif, FIMULTIBITMAP* bitmap, F
383386

384387
if (auto& plugins = PluginsRegistrySingleton::Instance()) {
385388

386-
if (auto dst_node = plugins->FindFromFIF(fif)) {
389+
if (auto dst_it = plugins->FindFromFIF(fif); dst_it != plugins->NodesCEnd()) {
390+
const auto& dst_node = (*dst_it).second;
391+
assert(dst_node != nullptr);
392+
387393
auto *header = FreeImage_GetMultiBitmapHeader(bitmap);
388394

389395
// dst data
@@ -544,11 +550,8 @@ FreeImage_CloseMultiBitmap(FIMULTIBITMAP *bitmap, int flags) {
544550

545551
// close persistent data handle
546552

547-
if (header->persistent_data) {
548-
if (auto& plugins = PluginsRegistrySingleton::Instance()) {
549-
auto node = plugins->FindFromFIF(header->fif);
550-
node->ClosePersistent(&header->io, header->handle, header->persistent_data);
551-
}
553+
if (header->persistent_data && header->node) {
554+
header->node->ClosePersistent(&header->io, header->handle, header->persistent_data);
552555
}
553556

554557
// delete the FIMULTIBITMAPHEADER
@@ -853,15 +856,16 @@ FreeImage_LoadMultiBitmapFromMemory(FREE_IMAGE_FORMAT fif, FIMEMORY *stream, int
853856

854857
if (auto& plugins = PluginsRegistrySingleton::Instance()) {
855858

856-
if (auto node = plugins->FindFromFIF(fif)) {
859+
if (auto it = plugins->FindFromFIF(fif); it != plugins->NodesCEnd()) {
860+
assert(it->second != nullptr);
857861

858862
std::unique_ptr<FIMULTIBITMAP> bitmap(new(std::nothrow) FIMULTIBITMAP);
859863

860864
if (bitmap) {
861865
std::unique_ptr<MULTIBITMAPHEADER> header(new(std::nothrow) MULTIBITMAPHEADER);
862866

863867
if (header) {
864-
header->node = node;
868+
header->node = it->second;
865869
header->fif = fif;
866870
SetMemoryIO(&header->io);
867871
header->handle = (fi_handle)stream;
@@ -872,13 +876,13 @@ FreeImage_LoadMultiBitmapFromMemory(FREE_IMAGE_FORMAT fif, FIMEMORY *stream, int
872876
// store the MULTIBITMAPHEADER in the surrounding FIMULTIBITMAP structure
873877

874878
// open persistent data is supported
875-
if (node->SupportsOpenPersistent()) {
876-
header->persistent_data = node->OpenPersistent(&header->io, header->handle, header->read_only);
879+
if (header->node->SupportsOpenPersistent()) {
880+
header->persistent_data = header->node->OpenPersistent(&header->io, header->handle, header->read_only);
877881
// cache the page count
878-
header->page_count = node->GetPageCount(&header->io, header->handle, header->persistent_data);
882+
header->page_count = header->node->GetPageCount(&header->io, header->handle, header->persistent_data);
879883
}
880884
else {
881-
header->page_count = node->GetPageCount(&header->io, header->handle);
885+
header->page_count = header->node->GetPageCount(&header->io, header->handle);
882886
}
883887

884888
// allocate a continueus block to describe the bitmap

0 commit comments

Comments
 (0)