Skip to content

Commit 229bf35

Browse files
author
Grok Compression
committed
core_simple: refactor into two methods, one for compress and one for decompress
1 parent e80c315 commit 229bf35

File tree

1 file changed

+80
-68
lines changed

1 file changed

+80
-68
lines changed

examples/core/core_simple.cpp

Lines changed: 80 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -32,42 +32,27 @@ with memory buffers as source and destination
3232

3333
// template parameter T determines the type of input data: uint8_t, uint16_t etc
3434
template<typename T>
35-
int core_simple(uint32_t dimX, uint32_t dimY, uint8_t precision,
36-
std::vector<std::unique_ptr<T[]>>& uncompressedData)
35+
int core_compress(uint32_t dimX, uint32_t dimY, uint8_t precision,
36+
std::vector<std::unique_ptr<T[]>>& uncompressedData,
37+
std::vector<uint8_t>& compressedData)
3738
{
3839
const uint16_t numComps = (uint16_t)uncompressedData.size();
3940
const auto colourSpace = numComps == 3 ? GRK_CLRSPC_SRGB : GRK_CLRSPC_GRAY;
4041

41-
grk_object* codec = nullptr; // compression/decompression codec object
42-
grk_image* encInputImage = nullptr; // uncompressed image passed into compressor
43-
grk_image* decOutputImage = nullptr; // uncompressed image created by decompressor
44-
grk_header_info headerInfo = {}; // compressed image header info
42+
grk_object* codec = nullptr; // compression codec object
4543
int32_t rc = EXIT_FAILURE;
44+
size_t compressedLength = 0;
45+
grk_stream_params encCompressedStream = {};
4646

47-
uint64_t compressedLength = 0; // length of compressed stream
48-
49-
bool images_equal = true;
50-
grk_stream_params decCompressedStream = {}; // compressed stream passed to decompressor
51-
52-
// 1. initialize compress and decompress parameters
47+
// 1. initialize compress parameters
5348
grk_cparameters compressParams;
5449
grk_compress_set_default_params(&compressParams);
5550
compressParams.cod_format = GRK_FMT_JP2;
5651
compressParams.verbose = true;
5752
compressParams.irreversible = false; // Enable reversible (lossless) compression
5853

59-
grk_decompress_parameters decompressParams = {};
60-
61-
// 2.initialize struct holding encoder compressed stream
62-
std::unique_ptr<uint8_t[]> compressedData;
63-
// allocate size of input image, assuming that compressed stream
64-
// is smaller than input
65-
size_t bufLen = (size_t)numComps * ((precision + 7) / 8) * dimX * dimY;
66-
compressedData = std::make_unique<uint8_t[]>(bufLen);
67-
68-
grk_stream_params encCompressedStream = {};
69-
encCompressedStream.buf = compressedData.get();
70-
encCompressedStream.buf_len = bufLen;
54+
encCompressedStream.buf = compressedData.data();
55+
encCompressedStream.buf_len = compressedData.size();
7156

7257
// 3. create image that will be passed to encoder
7358
auto components = std::make_unique<grk_image_comp[]>(numComps);
@@ -79,9 +64,9 @@ int core_simple(uint32_t dimX, uint32_t dimY, uint8_t precision,
7964
c->h = dimY;
8065
c->prec = precision;
8166
}
82-
encInputImage = grk_image_new(numComps, components.get(), colourSpace, true);
67+
auto encInputImage = grk_image_new(numComps, components.get(), colourSpace, true);
8368

84-
// fill in component data: see grok.h header for full details of image structure
69+
// 4. fill in component data: see grok.h header for full details of image structure
8570
for(uint16_t compno = 0; compno < encInputImage->numcomps; ++compno)
8671
{
8772
auto comp = encInputImage->comps + compno;
@@ -107,7 +92,7 @@ int core_simple(uint32_t dimX, uint32_t dimY, uint8_t precision,
10792
}
10893
}
10994

110-
// 4. compress
95+
// 5. compress
11196
codec = grk_compress_init(&encCompressedStream, &compressParams, encInputImage);
11297
if(!codec)
11398
{
@@ -120,16 +105,41 @@ int core_simple(uint32_t dimX, uint32_t dimY, uint8_t precision,
120105
fprintf(stderr, "Failed to compress\n");
121106
goto beach;
122107
}
123-
// destroy compression codec
124-
grk_object_unref(codec);
108+
compressedData.resize(compressedLength);
109+
125110
printf("Compression succeeded: %" PRIu64 " bytes used\n", compressedLength);
126111

127-
// 5. copy encCompressedStream to decCompressedStream to prepare for decompression
128-
decCompressedStream.buf = encCompressedStream.buf;
129-
decCompressedStream.buf_len = compressedLength;
112+
rc = EXIT_SUCCESS;
113+
114+
beach:
115+
grk_object_unref(codec);
116+
if(encInputImage)
117+
grk_object_unref(&encInputImage->obj);
118+
return rc;
119+
}
120+
121+
// template parameter T determines the type of input data: uint8_t, uint16_t etc
122+
template<typename T>
123+
int core_decompress(uint32_t dimX, uint32_t dimY, uint8_t precision,
124+
std::vector<std::unique_ptr<T[]>>& uncompressedData,
125+
std::vector<uint8_t>& compressedData)
126+
{
127+
const uint16_t numComps = (uint16_t)uncompressedData.size();
128+
const auto colourSpace = numComps == 3 ? GRK_CLRSPC_SRGB : GRK_CLRSPC_GRAY;
129+
130+
grk_header_info headerInfo = {}; // compressed image header info
131+
int32_t rc = EXIT_FAILURE;
132+
bool images_equal = true;
133+
134+
grk_stream_params decCompressedStream = {};
135+
decCompressedStream.buf = compressedData.data();
136+
decCompressedStream.buf_len = compressedData.size();
130137

131-
// 6. decompress
132-
codec = grk_decompress_init(&decCompressedStream, &decompressParams);
138+
grk_decompress_parameters decompressParams = {};
139+
grk_image* decOutputImage = nullptr; // uncompressed image created by decompressor
140+
141+
// 1. decompress
142+
auto codec = grk_decompress_init(&decCompressedStream, &decompressParams);
133143
if(!grk_decompress_read_header(codec, &headerInfo))
134144
{
135145
fprintf(stderr, "Failed to read the header\n");
@@ -141,7 +151,7 @@ int core_simple(uint32_t dimX, uint32_t dimY, uint8_t precision,
141151
goto beach;
142152
}
143153

144-
// 7. retrieve decompressed image
154+
// 2. retrieve decompressed image
145155
decOutputImage = grk_decompress_get_image(codec);
146156
if(!decOutputImage)
147157
{
@@ -150,36 +160,31 @@ int core_simple(uint32_t dimX, uint32_t dimY, uint8_t precision,
150160
}
151161
printf("Decompression succeeded\n");
152162

153-
// 8. compare original uncompressedData to decompressed decInputmage
154-
if(encInputImage->numcomps != decOutputImage->numcomps ||
155-
encInputImage->x0 != decOutputImage->x0 || encInputImage->y0 != decOutputImage->y0 ||
156-
encInputImage->x1 != decOutputImage->x1 || encInputImage->y1 != decOutputImage->y1 ||
157-
encInputImage->color_space != decOutputImage->color_space)
163+
// 3. compare original uncompressedData to decompressed decOutputImage
164+
if(numComps != decOutputImage->numcomps || colourSpace != decOutputImage->color_space)
158165
{
159166
images_equal = false;
160167
}
161168
else
162169
{
163-
for(uint32_t compno = 0; compno < encInputImage->numcomps; ++compno)
170+
for(uint32_t compno = 0; compno < numComps; ++compno)
164171
{
165-
auto encImageComp = encInputImage->comps + compno;
166172
auto decImageComp = decOutputImage->comps + compno;
167-
if(encImageComp->dx != decImageComp->dx || encImageComp->dy != decImageComp->dy ||
168-
encImageComp->w != decImageComp->w || encImageComp->h != decImageComp->h ||
169-
encImageComp->prec != decImageComp->prec || encImageComp->sgnd != decImageComp->sgnd)
173+
if(1 != decImageComp->dx || 1 != decImageComp->dy || dimX != decImageComp->w ||
174+
dimY != decImageComp->h || precision != decImageComp->prec || false != decImageComp->sgnd)
170175
{
171176
images_equal = false;
172177
break;
173178
}
174179
auto in_data = uncompressedData[compno].get();
175-
auto in_stride = encImageComp->w;
180+
auto in_stride = dimX;
176181
auto out_data = (int32_t*)decImageComp->data;
177182
auto out_stride = decImageComp->stride;
178183
bool comp_equal = true;
179-
for(uint32_t j = 0; j < encImageComp->h; ++j)
184+
for(uint32_t j = 0; j < dimY; ++j)
180185
{
181186
bool row_equal = true;
182-
for(uint32_t i = 0; i < encImageComp->w; ++i)
187+
for(uint32_t i = 0; i < dimX; ++i)
183188
{
184189
if((int32_t)in_data[i] != out_data[i])
185190
{
@@ -205,39 +210,46 @@ int core_simple(uint32_t dimX, uint32_t dimY, uint8_t precision,
205210
if(images_equal)
206211
printf("Input and output data buffers are identical\n");
207212
else
208-
printf("Input and output data bufffers differ\n");
213+
printf("Input and output data buffers differ\n");
209214

210215
rc = EXIT_SUCCESS;
211216

212217
beach:
213-
// cleanup
214218
grk_object_unref(codec);
215-
if(encInputImage)
216-
grk_object_unref(&encInputImage->obj);
217219
// note: since decImage was allocated by library, it will be cleaned up by library
218220

219221
return rc;
220222
}
221223

222224
int main([[maybe_unused]] int argc, [[maybe_unused]] const char** argv)
223225
{
224-
// 1. create uncompressed buffer
225-
auto compWidth = 640U;
226-
auto compHeight = 480U;
227-
uint32_t precision = sizeof(uint16_t) * 8;
228-
229-
std::vector<std::unique_ptr<uint16_t[]>> uncompressedData(1);
230-
// allocate and fill uncompressedData buffer with grid pattern (contiguous)
231-
uncompressedData[0] = std::make_unique<uint16_t[]>((size_t)compWidth * compHeight);
232-
auto srcPtr = uncompressedData[0].get();
233-
const uint16_t white = (uint16_t)((1 << precision) - 1);
234-
for(uint32_t j = 0; j < compHeight; ++j)
226+
const uint16_t numComps = 1U;
227+
const auto dimX = 640U;
228+
const auto dimY = 480U;
229+
const uint8_t precision = 16;
230+
231+
// 1. allocate and fill uncompressedData buffer with grid pattern
232+
std::vector<std::unique_ptr<uint16_t[]>> uncompressedData(numComps);
233+
for(uint16_t comp = 0; comp < numComps; ++comp)
235234
{
236-
for(uint32_t i = 0; i < compWidth; ++i)
237-
srcPtr[i] = (i % 32 == 0 || j % 32 == 0) ? white : 0;
238-
srcPtr += compWidth;
235+
uncompressedData[comp] = std::make_unique<uint16_t[]>((size_t)dimX * dimY);
236+
auto srcPtr = uncompressedData[comp].get();
237+
const auto white = (uint16_t)((1 << precision) - 1);
238+
for(uint32_t j = 0; j < dimY; ++j)
239+
{
240+
for(uint32_t i = 0; i < dimX; ++i)
241+
srcPtr[i] = (i % 32 == 0 || j % 32 == 0) ? white : 0;
242+
srcPtr += dimX;
243+
}
239244
}
240245

241-
// run compress and the decompress and compare output with original
242-
return core_simple<uint16_t>(compWidth, compHeight, precision, uncompressedData);
246+
// 2. run compress and then decompress and compare output with original
247+
std::vector<uint8_t> compressedData;
248+
size_t bufLen = (size_t)numComps * ((precision + 7) / 8) * dimX * dimY;
249+
compressedData.resize(bufLen);
250+
int rc = core_compress<uint16_t>(dimX, dimY, precision, uncompressedData, compressedData);
251+
if(rc == 0)
252+
rc = core_decompress<uint16_t>(dimX, dimY, precision, uncompressedData, compressedData);
253+
254+
return rc;
243255
}

0 commit comments

Comments
 (0)