2 * Copyright (c) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes@c-s.fr>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
32 #include "opj_config.h"
36 /* -------------------------------------------------------------------------- */
39 sample error debug callback expecting no client object
41 static void error_callback(const char *msg, void *client_data)
44 fprintf(stdout, "[ERROR] %s", msg);
47 sample warning debug callback expecting no client object
49 static void warning_callback(const char *msg, void *client_data)
52 fprintf(stdout, "[WARNING] %s", msg);
55 sample debug callback expecting no client object
57 static void info_callback(const char *msg, void *client_data)
60 fprintf(stdout, "[INFO] %s", msg);
63 static INLINE OPJ_UINT32 opj_uint_max(OPJ_UINT32 a, OPJ_UINT32 b)
65 return (a > b) ? a : b;
68 static INLINE OPJ_UINT32 opj_uint_min(OPJ_UINT32 a, OPJ_UINT32 b)
70 return (a < b) ? a : b;
73 /* -------------------------------------------------------------------------- */
75 #define NUM_COMPS_MAX 4
76 int main(int argc, char *argv[])
78 opj_cparameters_t l_param;
79 opj_codec_t * l_codec;
80 opj_image_t * l_image;
81 opj_image_cmptparm_t l_params [NUM_COMPS_MAX];
82 opj_stream_t * l_stream;
83 OPJ_UINT32 l_nb_tiles_width, l_nb_tiles_height, l_nb_tiles;
84 OPJ_UINT32 l_data_size;
88 const OPJ_FLOAT32 l_mct [] = {
94 const OPJ_INT32 l_offsets [] = {
99 opj_image_cmptparm_t * l_current_param_ptr;
103 OPJ_UINT32 num_comps;
110 const char *output_file;
111 int cblockw_init = 64;
112 int cblockh_init = 64;
113 int numresolution = 6;
114 OPJ_UINT32 offsetx = 0;
115 OPJ_UINT32 offsety = 0;
116 int quality_loss = 1;
119 opj_set_default_encoder_parameters(&l_param);
121 /* should be test_tile_encoder 3 2000 2000 1000 1000 8 tte1.j2k [64 64] [6] [0 0] [0] [256 256] */
123 num_comps = (OPJ_UINT32)atoi(argv[1]);
124 image_width = atoi(argv[2]);
125 image_height = atoi(argv[3]);
126 tile_width = atoi(argv[4]);
127 tile_height = atoi(argv[5]);
128 comp_prec = atoi(argv[6]);
129 irreversible = atoi(argv[7]);
130 output_file = argv[8];
133 cblockw_init = atoi(argv[9]);
134 cblockh_init = atoi(argv[10]);
137 numresolution = atoi(argv[11]);
140 offsetx = (OPJ_UINT32)atoi(argv[12]);
141 offsety = (OPJ_UINT32)atoi(argv[13]);
144 is_rand = atoi(argv[14]);
146 for (i = 15; i + 1 < (OPJ_UINT32)argc &&
147 l_param.res_spec < OPJ_J2K_MAXRLVLS; i += 2) {
148 l_param.csty |= 0x01;
149 l_param.prcw_init[l_param.res_spec] = atoi(argv[i]);
150 l_param.prch_init[l_param.res_spec] = atoi(argv[i + 1]);
161 output_file = "test.j2k";
163 if (num_comps > NUM_COMPS_MAX) {
166 l_nb_tiles_width = (offsetx + (OPJ_UINT32)image_width +
167 (OPJ_UINT32)tile_width - 1) / (OPJ_UINT32)tile_width;
168 l_nb_tiles_height = (offsety + (OPJ_UINT32)image_height +
169 (OPJ_UINT32)tile_height - 1) / (OPJ_UINT32)tile_height;
170 l_nb_tiles = l_nb_tiles_width * l_nb_tiles_height;
171 l_data_size = (OPJ_UINT32)tile_width * (OPJ_UINT32)tile_height *
172 (OPJ_UINT32)num_comps * (OPJ_UINT32)(comp_prec / 8);
174 l_data = (OPJ_BYTE*) malloc(l_data_size * sizeof(OPJ_BYTE));
175 if (l_data == NULL) {
179 "Encoding random values -> keep in mind that this is very hard to compress\n");
180 for (i = 0; i < l_data_size; ++i) {
182 l_data[i] = (OPJ_BYTE)rand();
184 l_data[i] = (OPJ_BYTE)i;
188 /** you may here add custom encoding parameters */
189 /* rate specifications */
190 /** number of quality layers in the stream */
192 l_param.tcp_numlayers = 1;
193 l_param.cp_fixed_quality = 1;
194 l_param.tcp_distoratio[0] = 20;
196 /* is using others way of calculation */
197 /* l_param.cp_disto_alloc = 1 or l_param.cp_fixed_alloc = 1 */
198 /* l_param.tcp_rates[0] = ... */
201 /* tile definitions parameters */
202 /* position of the tile grid aligned with the image */
205 /* tile size, we are using tile based encoding */
206 l_param.tile_size_on = OPJ_TRUE;
207 l_param.cp_tdx = tile_width;
208 l_param.cp_tdy = tile_height;
210 /* code block size */
211 l_param.cblockw_init = cblockw_init;
212 l_param.cblockh_init = cblockh_init;
214 /* use irreversible encoding ?*/
215 l_param.irreversible = irreversible;
217 /* do not bother with mct, the rsiz is set when calling opj_set_MCT*/
218 /*l_param.cp_rsiz = OPJ_STD_RSIZ;*/
221 /*l_param.cp_cinema = 0;*/
223 /* no not bother using SOP or EPH markers, do not use custom size precinct */
224 /* number of precincts to specify */
225 /* l_param.csty = 0;*/
226 /* l_param.res_spec = ... */
227 /* l_param.prch_init[i] = .. */
228 /* l_param.prcw_init[i] = .. */
231 /* do not use progression order changes */
232 /*l_param.numpocs = 0;*/
233 /* l_param.POC[i].... */
235 /* do not restrain the size for a component.*/
236 /* l_param.max_comp_size = 0; */
238 /** block encoding style for each component, do not use at the moment */
239 /** J2K_CCP_CBLKSTY_TERMALL, J2K_CCP_CBLKSTY_LAZY, J2K_CCP_CBLKSTY_VSC, J2K_CCP_CBLKSTY_SEGSYM, J2K_CCP_CBLKSTY_RESET */
240 /* l_param.mode = 0;*/
242 /** number of resolutions */
243 l_param.numresolution = numresolution;
245 /** progression order to use*/
246 /** OPJ_LRCP, OPJ_RLCP, OPJ_RPCL, PCRL, CPRL */
247 l_param.prog_order = OPJ_LRCP;
249 /** no "region" of interest, more precisally component */
250 /* l_param.roi_compno = -1; */
251 /* l_param.roi_shift = 0; */
253 /* we are not using multiple tile parts for a tile. */
254 /* l_param.tp_on = 0; */
255 /* l_param.tp_flag = 0; */
257 /* if we are using mct */
259 opj_set_MCT(&l_param, l_mct, l_offsets, NUM_COMPS);
263 /* image definition */
264 l_current_param_ptr = l_params;
265 for (i = 0; i < num_comps; ++i) {
266 /* do not bother bpp useless */
267 /*l_current_param_ptr->bpp = COMP_PREC;*/
268 l_current_param_ptr->dx = 1;
269 l_current_param_ptr->dy = 1;
271 l_current_param_ptr->h = (OPJ_UINT32)image_height;
272 l_current_param_ptr->w = (OPJ_UINT32)image_width;
274 l_current_param_ptr->sgnd = 0;
275 l_current_param_ptr->prec = (OPJ_UINT32)comp_prec;
277 l_current_param_ptr->x0 = offsetx;
278 l_current_param_ptr->y0 = offsety;
280 ++l_current_param_ptr;
283 /* should we do j2k or jp2 ?*/
284 len = strlen(output_file);
285 if (strcmp(output_file + len - 4, ".jp2") == 0) {
286 l_codec = opj_create_compress(OPJ_CODEC_JP2);
288 l_codec = opj_create_compress(OPJ_CODEC_J2K);
295 /* catch events using our callbacks and give a local context */
296 opj_set_info_handler(l_codec, info_callback, 00);
297 opj_set_warning_handler(l_codec, warning_callback, 00);
298 opj_set_error_handler(l_codec, error_callback, 00);
300 l_image = opj_image_tile_create(num_comps, l_params, OPJ_CLRSPC_SRGB);
303 opj_destroy_codec(l_codec);
307 l_image->x0 = offsetx;
308 l_image->y0 = offsety;
309 l_image->x1 = offsetx + (OPJ_UINT32)image_width;
310 l_image->y1 = offsety + (OPJ_UINT32)image_height;
311 l_image->color_space = OPJ_CLRSPC_SRGB;
313 if (! opj_setup_encoder(l_codec, &l_param, l_image)) {
314 fprintf(stderr, "ERROR -> test_tile_encoder: failed to setup the codec!\n");
315 opj_destroy_codec(l_codec);
316 opj_image_destroy(l_image);
321 l_stream = opj_stream_create_default_file_stream(output_file, OPJ_FALSE);
324 "ERROR -> test_tile_encoder: failed to create the stream from the output file %s !\n",
326 opj_destroy_codec(l_codec);
327 opj_image_destroy(l_image);
332 if (! opj_start_compress(l_codec, l_image, l_stream)) {
333 fprintf(stderr, "ERROR -> test_tile_encoder: failed to start compress!\n");
334 opj_stream_destroy(l_stream);
335 opj_destroy_codec(l_codec);
336 opj_image_destroy(l_image);
341 for (i = 0; i < l_nb_tiles; ++i) {
342 OPJ_UINT32 tile_y = i / l_nb_tiles_width;
343 OPJ_UINT32 tile_x = i % l_nb_tiles_width;
344 OPJ_UINT32 tile_x0 = opj_uint_max(l_image->x0, tile_x * (OPJ_UINT32)tile_width);
345 OPJ_UINT32 tile_y0 = opj_uint_max(l_image->y0,
346 tile_y * (OPJ_UINT32)tile_height);
347 OPJ_UINT32 tile_x1 = opj_uint_min(l_image->x1,
348 (tile_x + 1) * (OPJ_UINT32)tile_width);
349 OPJ_UINT32 tile_y1 = opj_uint_min(l_image->y1,
350 (tile_y + 1) * (OPJ_UINT32)tile_height);
351 OPJ_UINT32 tilesize = (tile_x1 - tile_x0) * (tile_y1 - tile_y0) *
352 (OPJ_UINT32)num_comps * (OPJ_UINT32)(comp_prec / 8);
353 if (! opj_write_tile(l_codec, i, l_data, tilesize, l_stream)) {
354 fprintf(stderr, "ERROR -> test_tile_encoder: failed to write the tile %d!\n",
356 opj_stream_destroy(l_stream);
357 opj_destroy_codec(l_codec);
358 opj_image_destroy(l_image);
364 if (! opj_end_compress(l_codec, l_stream)) {
365 fprintf(stderr, "ERROR -> test_tile_encoder: failed to end compress!\n");
366 opj_stream_destroy(l_stream);
367 opj_destroy_codec(l_codec);
368 opj_image_destroy(l_image);
373 opj_stream_destroy(l_stream);
374 opj_destroy_codec(l_codec);
375 opj_image_destroy(l_image);