@@ -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
3434template <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
212217beach:
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
222224int 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