Skip to content

Commit 4de5bc9

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

1 file changed

Lines changed: 80 additions & 67 deletions

File tree

examples/core/core_simple.cpp

Lines changed: 80 additions & 67 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,15 +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;
130113

131-
// 6. decompress
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_object* codec = nullptr; // compression/decompression codec object
131+
grk_header_info headerInfo = {}; // compressed image header info
132+
int32_t rc = EXIT_FAILURE;
133+
bool images_equal = true;
134+
135+
grk_stream_params decCompressedStream = {};
136+
decCompressedStream.buf = compressedData.data();
137+
decCompressedStream.buf_len = compressedData.size();
138+
139+
grk_decompress_parameters decompressParams = {};
140+
grk_image* decOutputImage = nullptr; // uncompressed image created by decompressor
141+
142+
// 1. decompress
132143
codec = grk_decompress_init(&decCompressedStream, &decompressParams);
133144
if(!grk_decompress_read_header(codec, &headerInfo))
134145
{
@@ -141,7 +152,7 @@ int core_simple(uint32_t dimX, uint32_t dimY, uint8_t precision,
141152
goto beach;
142153
}
143154

144-
// 7. retrieve decompressed image
155+
// 2. retrieve decompressed image
145156
decOutputImage = grk_decompress_get_image(codec);
146157
if(!decOutputImage)
147158
{
@@ -150,36 +161,31 @@ int core_simple(uint32_t dimX, uint32_t dimY, uint8_t precision,
150161
}
151162
printf("Decompression succeeded\n");
152163

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)
164+
// 3. compare original uncompressedData to decompressed decOutputImage
165+
if(numComps != decOutputImage->numcomps || colourSpace != decOutputImage->color_space)
158166
{
159167
images_equal = false;
160168
}
161169
else
162170
{
163-
for(uint32_t compno = 0; compno < encInputImage->numcomps; ++compno)
171+
for(uint32_t compno = 0; compno < numComps; ++compno)
164172
{
165-
auto encImageComp = encInputImage->comps + compno;
166173
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)
174+
if(1 != decImageComp->dx || 1 != decImageComp->dy || dimX != decImageComp->w ||
175+
dimY != decImageComp->h || precision != decImageComp->prec || false != decImageComp->sgnd)
170176
{
171177
images_equal = false;
172178
break;
173179
}
174180
auto in_data = uncompressedData[compno].get();
175-
auto in_stride = encImageComp->w;
181+
auto in_stride = dimX;
176182
auto out_data = (int32_t*)decImageComp->data;
177183
auto out_stride = decImageComp->stride;
178184
bool comp_equal = true;
179-
for(uint32_t j = 0; j < encImageComp->h; ++j)
185+
for(uint32_t j = 0; j < dimY; ++j)
180186
{
181187
bool row_equal = true;
182-
for(uint32_t i = 0; i < encImageComp->w; ++i)
188+
for(uint32_t i = 0; i < dimX; ++i)
183189
{
184190
if((int32_t)in_data[i] != out_data[i])
185191
{
@@ -205,39 +211,46 @@ int core_simple(uint32_t dimX, uint32_t dimY, uint8_t precision,
205211
if(images_equal)
206212
printf("Input and output data buffers are identical\n");
207213
else
208-
printf("Input and output data bufffers differ\n");
214+
printf("Input and output data buffers differ\n");
209215

210216
rc = EXIT_SUCCESS;
211217

212218
beach:
213-
// cleanup
214219
grk_object_unref(codec);
215-
if(encInputImage)
216-
grk_object_unref(&encInputImage->obj);
217220
// note: since decImage was allocated by library, it will be cleaned up by library
218221

219222
return rc;
220223
}
221224

222225
int main([[maybe_unused]] int argc, [[maybe_unused]] const char** argv)
223226
{
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)
227+
const uint16_t numComps = 1U;
228+
const auto dimX = 640U;
229+
const auto dimY = 480U;
230+
const uint8_t precision = 16;
231+
232+
// 1. allocate and fill uncompressedData buffer with grid pattern
233+
std::vector<std::unique_ptr<uint16_t[]>> uncompressedData(numComps);
234+
for(uint16_t comp = 0; comp < numComps; ++comp)
235235
{
236-
for(uint32_t i = 0; i < compWidth; ++i)
237-
srcPtr[i] = (i % 32 == 0 || j % 32 == 0) ? white : 0;
238-
srcPtr += compWidth;
236+
uncompressedData[comp] = std::make_unique<uint16_t[]>((size_t)dimX * dimY);
237+
auto srcPtr = uncompressedData[comp].get();
238+
const auto white = (uint16_t)((1 << precision) - 1);
239+
for(uint32_t j = 0; j < dimY; ++j)
240+
{
241+
for(uint32_t i = 0; i < dimX; ++i)
242+
srcPtr[i] = (i % 32 == 0 || j % 32 == 0) ? white : 0;
243+
srcPtr += dimX;
244+
}
239245
}
240246

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

0 commit comments

Comments
 (0)