Skip to content

Commit 8b4150e

Browse files
author
Grok Compression
committed
grk_initialize: make thread safe and optional for API
grk_deinitialize is still needed for API
1 parent fc8f0f4 commit 8b4150e

File tree

4 files changed

+73
-60
lines changed

4 files changed

+73
-60
lines changed

examples/core/core_compress.cpp

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,16 +99,13 @@ int main([[maybe_unused]] int argc, [[maybe_unused]] const char** argv)
9999

100100
uint64_t compressedLength = 0;
101101

102-
// 1. initialize library
103-
grk_initialize(nullptr, 0, nullptr);
104-
105-
// 2. initialize compress parameters
102+
// 1. initialize compress parameters
106103
grk_cparameters compressParams;
107104
grk_compress_set_default_params(&compressParams);
108105
compressParams.cod_format = GRK_FMT_JP2;
109106
compressParams.verbose = true;
110107

111-
// 3.initialize output stream
108+
// 2.initialize output stream
112109
enum eStreamOutput
113110
{
114111
STREAM_OUTPUT_BUFFER, // output to buffer
@@ -144,7 +141,7 @@ int main([[maybe_unused]] int argc, [[maybe_unused]] const char** argv)
144141
safe_strcpy(outputStreamParams.file, outFile);
145142
}
146143

147-
// 4. create input image (blank)
144+
// 3. create input image (blank)
148145
auto components = std::make_unique<grk_image_comp[]>(numComps);
149146
for(uint32_t i = 0; i < numComps; ++i)
150147
{
@@ -184,15 +181,15 @@ int main([[maybe_unused]] int argc, [[maybe_unused]] const char** argv)
184181
delete[] srcData;
185182
}
186183

187-
// 5. initialize compressor
184+
// 4. initialize compressor
188185
codec = grk_compress_init(&outputStreamParams, &compressParams, inputImage);
189186
if(!codec)
190187
{
191188
fprintf(stderr, "Failed to initialize compressor\n");
192189
goto beach;
193190
}
194191

195-
// 6. compress
192+
// 5. compress
196193
compressedLength = grk_compress(codec, nullptr);
197194
if(compressedLength == 0)
198195
{
@@ -201,7 +198,7 @@ int main([[maybe_unused]] int argc, [[maybe_unused]] const char** argv)
201198
}
202199
printf("Compression succeeded: %" PRIu64 " bytes used.\n", compressedLength);
203200

204-
// 7. write buffer to file if needed
201+
// 6. write buffer to file if needed
205202
if(output == STREAM_OUTPUT_FILE)
206203
{
207204
auto fp = fopen(outFile, "wb");

examples/core/core_decompress.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -707,8 +707,6 @@ int main([[maybe_unused]] int argc, [[maybe_unused]] const char** argv)
707707
stream_params.buf = buf;
708708
stream_params.buf_len = len;
709709

710-
grk_initialize(nullptr, 0, nullptr);
711-
712710
// Proceed with decompression
713711
codec = grk_decompress_init(&stream_params, &parameters);
714712
if(!codec)

examples/core/core_simple.cpp

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,7 @@ int main([[maybe_unused]] int argc, [[maybe_unused]] const char** argv)
4949
bool images_equal = true;
5050
grk_stream_params decCompressedStream = {}; // compressed stream passed to decompressor
5151

52-
// 1. initialize library
53-
grk_initialize(nullptr, 0, nullptr);
54-
55-
// 2. initialize compress and decompress parameters
52+
// 1. initialize compress and decompress parameters
5653
grk_cparameters compressParams;
5754
grk_compress_set_default_params(&compressParams);
5855
compressParams.cod_format = GRK_FMT_JP2;
@@ -61,7 +58,7 @@ int main([[maybe_unused]] int argc, [[maybe_unused]] const char** argv)
6158

6259
grk_decompress_parameters decompressParams = {};
6360

64-
// 3.initialize struct holding encoder compressed stream
61+
// 2.initialize struct holding encoder compressed stream
6562
std::unique_ptr<uint8_t[]> compressedData;
6663
// allocate size of input image, assuming that compressed stream
6764
// is smaller than input
@@ -72,7 +69,7 @@ int main([[maybe_unused]] int argc, [[maybe_unused]] const char** argv)
7269
encCompressedStream.buf = compressedData.get();
7370
encCompressedStream.buf_len = bufLen;
7471

75-
// 4. create image that will be passed to encoder
72+
// 3. create image that will be passed to encoder
7673
auto components = std::make_unique<grk_image_comp[]>(numComps);
7774
for(uint32_t i = 0; i < numComps; ++i)
7875
{
@@ -124,7 +121,7 @@ int main([[maybe_unused]] int argc, [[maybe_unused]] const char** argv)
124121
}
125122
}
126123

127-
// 5. compress
124+
// 4. compress
128125
codec = grk_compress_init(&encCompressedStream, &compressParams, encInputImage);
129126
if(!codec)
130127
{
@@ -141,11 +138,11 @@ int main([[maybe_unused]] int argc, [[maybe_unused]] const char** argv)
141138
grk_object_unref(codec);
142139
printf("Compression succeeded: %" PRIu64 " bytes used\n", compressedLength);
143140

144-
// 6. copy encCompressedStream to decCompressedStream to prepare for decompression
141+
// 5. copy encCompressedStream to decCompressedStream to prepare for decompression
145142
decCompressedStream.buf = encCompressedStream.buf;
146143
decCompressedStream.buf_len = compressedLength;
147144

148-
// 7. decompress
145+
// 6. decompress
149146
codec = grk_decompress_init(&decCompressedStream, &decompressParams);
150147
if(!grk_decompress_read_header(codec, &headerInfo))
151148
{
@@ -158,7 +155,7 @@ int main([[maybe_unused]] int argc, [[maybe_unused]] const char** argv)
158155
goto beach;
159156
}
160157

161-
// 8. retrieve decompressed image
158+
// 7. retrieve decompressed image
162159
decOutputImage = grk_decompress_get_image(codec);
163160
if(!decOutputImage)
164161
{
@@ -167,7 +164,7 @@ int main([[maybe_unused]] int argc, [[maybe_unused]] const char** argv)
167164
}
168165
printf("Decompression succeeded\n");
169166

170-
// 9. compare original uncompressedData to decompressed decInputmage
167+
// 8. compare original uncompressedData to decompressed decInputmage
171168
if(encInputImage->numcomps != decOutputImage->numcomps ||
172169
encInputImage->x0 != decOutputImage->x0 || encInputImage->y0 != decOutputImage->y0 ||
173170
encInputImage->x1 != decOutputImage->x1 || encInputImage->y1 != decOutputImage->y1 ||

src/lib/core/grok.cpp

Lines changed: 59 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
#include <sys/mman.h>
2525
#endif
2626
#include <fcntl.h>
27-
2827
#include <filesystem>
28+
#include <mutex>
2929

3030
#include "grk_includes.h"
3131

@@ -108,6 +108,19 @@ static grk_object* grkDecompressCreate(grk::IStream* stream)
108108
return &codec->obj;
109109
}
110110

111+
static inline bool areStringsEqual(const char* lhs, const char* rhs)
112+
{
113+
if(lhs == nullptr && rhs == nullptr)
114+
{
115+
return true;
116+
}
117+
if(lhs == nullptr || rhs == nullptr)
118+
{
119+
return false;
120+
}
121+
return std::strcmp(lhs, rhs) == 0;
122+
}
123+
111124
struct InitState
112125
{
113126
InitState(const char* pluginPath, uint32_t numThreads)
@@ -117,7 +130,7 @@ struct InitState
117130
InitState(void) : InitState(nullptr, 0) {}
118131
bool operator==(const InitState& rhs) const
119132
{
120-
return pluginPath_ == rhs.pluginPath_ && numThreads_ == rhs.numThreads_;
133+
return areStringsEqual(pluginPath_, rhs.pluginPath_) && numThreads_ == rhs.numThreads_;
121134
}
122135
const char* pluginPath_;
123136
uint32_t numThreads_;
@@ -126,6 +139,8 @@ struct InitState
126139
};
127140

128141
static InitState initState_;
142+
static std::mutex initMutex;
143+
129144
void grk_initialize(const char* pluginPath, uint32_t numThreads, bool* plugin_initialized)
130145
{
131146
const char* singleThreadEnv = std::getenv("GRK_TEST_SINGLE");
@@ -134,50 +149,54 @@ void grk_initialize(const char* pluginPath, uint32_t numThreads, bool* plugin_in
134149
numThreads = 1; // Force single-threaded execution
135150
}
136151
InitState newState(pluginPath, numThreads);
137-
if(initState_.initialized_ && newState == initState_)
138152
{
139-
if(plugin_initialized)
140-
*plugin_initialized = initState_.pluginInitialized_;
141-
return;
142-
}
143-
// 1. set up executor
144-
ExecSingleton::create(numThreads);
153+
std::lock_guard<std::mutex> guard(initMutex);
154+
if(initState_.initialized_ && newState == initState_)
155+
{
156+
if(plugin_initialized)
157+
*plugin_initialized = initState_.pluginInitialized_;
158+
return;
159+
}
160+
// 1. set up executor
161+
ExecSingleton::create(numThreads);
145162

146-
if(!Logger::logger_.info_handler)
147-
{
148-
grk_msg_handlers handlers = {};
149-
const char* debug_env = std::getenv("GRK_DEBUG");
150-
if(debug_env)
163+
if(!Logger::logger_.info_handler)
151164
{
152-
int level = std::atoi(debug_env);
153-
if(level >= 1)
154-
handlers.error_callback = errorCallback;
155-
if(level >= 2)
156-
handlers.warn_callback = warningCallback;
157-
if(level >= 3)
158-
handlers.info_callback = infoCallback;
159-
if(level >= 4)
160-
handlers.debug_callback = debugCallback;
161-
if(level >= 5)
162-
handlers.trace_callback = traceCallback;
165+
grk_msg_handlers handlers = {};
166+
const char* debug_env = std::getenv("GRK_DEBUG");
167+
if(debug_env)
168+
{
169+
int level = std::atoi(debug_env);
170+
if(level >= 1)
171+
handlers.error_callback = errorCallback;
172+
if(level >= 2)
173+
handlers.warn_callback = warningCallback;
174+
if(level >= 3)
175+
handlers.info_callback = infoCallback;
176+
if(level >= 4)
177+
handlers.debug_callback = debugCallback;
178+
if(level >= 5)
179+
handlers.trace_callback = traceCallback;
180+
}
181+
grk_set_msg_handlers(handlers);
163182
}
164-
grk_set_msg_handlers(handlers);
165-
}
166183

167-
initState_ = newState;
184+
initState_ = newState;
168185

169-
// 2. try to load plugin
170-
if(!initState_.pluginInitialized_)
171-
{
172-
grk_plugin_load_info info;
173-
info.pluginPath = pluginPath;
174-
initState_.pluginInitialized_ = grk_plugin_load(info);
175-
if(initState_.pluginInitialized_)
186+
// 2. try to load plugin
187+
if(!initState_.pluginInitialized_)
176188
{
177-
grklog.info("Plugin loaded");
178-
if(plugin_initialized)
179-
*plugin_initialized = true;
189+
grk_plugin_load_info info;
190+
info.pluginPath = pluginPath;
191+
initState_.pluginInitialized_ = grk_plugin_load(info);
192+
if(initState_.pluginInitialized_)
193+
{
194+
grklog.info("Plugin loaded");
195+
if(plugin_initialized)
196+
*plugin_initialized = true;
197+
}
180198
}
199+
initState_.initialized_ = true;
181200
}
182201
}
183202

@@ -353,6 +372,7 @@ void grk_decompress_wait(grk_object* codecWrapper, grk_wait_swath* swath)
353372
}
354373
bool grk_decompress(grk_object* codecWrapper, grk_plugin_tile* tile)
355374
{
375+
grk_initialize(nullptr, 0, nullptr);
356376
if(codecWrapper)
357377
{
358378
auto codec = Codec::getImpl(codecWrapper);
@@ -546,6 +566,7 @@ grk_object* grk_compress_init(grk_stream_params* streamParams, grk_cparameters*
546566

547567
uint64_t grk_compress(grk_object* codecWrapper, grk_plugin_tile* tile)
548568
{
569+
grk_initialize(nullptr, 0, nullptr);
549570
if(codecWrapper)
550571
{
551572
auto codec = Codec::getImpl(codecWrapper);

0 commit comments

Comments
 (0)