X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Fbin%2Fjp2%2Fopj_decompress.c;h=088f3a29b5d6b69692a8be396b9c8409f0af9222;hb=4841292b5df8f5ed3c92f1760769428ad7500b7a;hp=397e637080d48e2683cd808afc62363d308a8051;hpb=563bd8499e63db976ca8358216138647593354bc;p=openjpeg.git diff --git a/src/bin/jp2/opj_decompress.c b/src/bin/jp2/opj_decompress.c index 397e6370..088f3a29 100644 --- a/src/bin/jp2/opj_decompress.c +++ b/src/bin/jp2/opj_decompress.c @@ -150,6 +150,12 @@ typedef struct opj_decompress_params { int split_pnm; /** number of threads */ int num_threads; + /* Quiet */ + int quiet; + /** number of components to decode */ + OPJ_UINT32 numcomps; + /** indices of components to decode */ + OPJ_UINT32* comps_indices; } opj_decompress_parameters; /* -------------------------------------------------------------------------- */ @@ -225,6 +231,10 @@ static void decode_help_display(void) " If 'C' is specified (default), values are clipped.\n" " If 'S' is specified, values are scaled.\n" " A 0 value can be specified (meaning original bit depth).\n"); + fprintf(stdout, " -c first_comp_index[,second_comp_index][,...]\n" + " OPTIONAL\n" + " To limit the number of components to decoded.\n" + " Component indices are numbered starting at 0.\n"); fprintf(stdout, " -force-rgb\n" " Force output image colorspace to RGB\n" " -upsample\n" @@ -232,9 +242,11 @@ static void decode_help_display(void) " -split-pnm\n" " Split output components to different files when writing to PNM\n"); if (opj_has_thread_support()) { - fprintf(stdout, " -threads \n" - " Number of threads to use for decoding.\n"); + fprintf(stdout, " -threads \n" + " Number of threads to use for decoding or ALL_CPUS for all available cores.\n"); } + fprintf(stdout, " -quiet\n" + " Disable output from the library and other output.\n"); /* UniPG>> */ #ifdef USE_JPWL fprintf(stdout, " -W \n" @@ -552,10 +564,11 @@ int parse_cmdline_decoder(int argc, char **argv, {"force-rgb", NO_ARG, NULL, 1}, {"upsample", NO_ARG, NULL, 1}, {"split-pnm", NO_ARG, NULL, 1}, - {"threads", REQ_ARG, NULL, 'T'} + {"threads", REQ_ARG, NULL, 'T'}, + {"quiet", NO_ARG, NULL, 1}, }; - const char optlist[] = "i:o:r:l:x:d:t:p:" + const char optlist[] = "i:o:r:l:x:d:t:p:c:" /* UniPG>> */ #ifdef USE_JPWL @@ -567,6 +580,7 @@ int parse_cmdline_decoder(int argc, char **argv, long_option[2].flag = &(parameters->force_rgb); long_option[3].flag = &(parameters->upsample); long_option[4].flag = &(parameters->split_pnm); + long_option[6].flag = &(parameters->quiet); totlen = sizeof(long_option); opj_reset_options_reading(); img_fol->set_out_format = 0; @@ -764,6 +778,25 @@ int parse_cmdline_decoder(int argc, char **argv, return 1; } } + break; + + /* ----------------------------------------------------- */ + case 'c': { /* Componenets */ + const char* iter = opj_optarg; + while (1) { + parameters->numcomps ++; + parameters->comps_indices = (OPJ_UINT32*) realloc( + parameters->comps_indices, + parameters->numcomps * sizeof(OPJ_UINT32)); + parameters->comps_indices[parameters->numcomps - 1] = + (OPJ_UINT32) atoi(iter); + iter = strchr(iter, ','); + if (iter == NULL) { + break; + } + iter ++; + } + } break; /* ----------------------------------------------------- */ @@ -830,8 +863,10 @@ int parse_cmdline_decoder(int argc, char **argv, token = strtok(NULL, ","); }; parameters->jpwl_correct = OPJ_TRUE; - fprintf(stdout, "JPWL correction capability activated\n"); - fprintf(stdout, "- expecting %d components\n", parameters->jpwl_exp_comps); + if (!(parameter->quiet)) { + fprintf(stdout, "JPWL correction capability activated\n"); + fprintf(stdout, "- expecting %d components\n", parameters->jpwl_exp_comps); + } } break; #endif /* USE_JPWL */ @@ -929,7 +964,8 @@ OPJ_FLOAT64 opj_clock(void) /* cout << "freq = " << ((double) freq.QuadPart) << endl; */ /* t is the high resolution performance counter (see MSDN) */ QueryPerformanceCounter(& t) ; - return freq.QuadPart ? (t.QuadPart / (OPJ_FLOAT64)freq.QuadPart) : 0; + return freq.QuadPart ? ((OPJ_FLOAT64)t.QuadPart / (OPJ_FLOAT64)freq.QuadPart) : + 0; #elif defined(__linux) struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); @@ -976,6 +1012,14 @@ static void info_callback(const char *msg, void *client_data) (void)client_data; fprintf(stdout, "[INFO] %s", msg); } +/** +sample quiet callback expecting no client object +*/ +static void quiet_callback(const char *msg, void *client_data) +{ + (void)msg; + (void)client_data; +} static void set_default_parameters(opj_decompress_parameters* parameters) { @@ -998,6 +1042,9 @@ static void destroy_parameters(opj_decompress_parameters* parameters) free(parameters->precision); parameters->precision = NULL; } + + free(parameters->comps_indices); + parameters->comps_indices = NULL; } } @@ -1280,6 +1327,7 @@ int main(int argc, char **argv) int failed = 0; OPJ_FLOAT64 t, tCumulative = 0; OPJ_UINT32 numDecompressedImages = 0; + OPJ_UINT32 cp_reduce; /* set decoding parameters to default values */ set_default_parameters(¶meters); @@ -1293,6 +1341,15 @@ int main(int argc, char **argv) goto fin; } + cp_reduce = parameters.core.cp_reduce; + if (getenv("USE_OPJ_SET_DECODED_RESOLUTION_FACTOR") != NULL) { + /* For debugging/testing purposes, do not set the cp_reduce member */ + /* if USE_OPJ_SET_DECODED_RESOLUTION_FACTOR is defined, but used */ + /* the opj_set_decoded_resolution_factor() API instead */ + parameters.core.cp_reduce = 0; + } + + /* Initialize reading of directory */ if (img_fol.set_imgdir == 1) { int it_image; @@ -1325,7 +1382,7 @@ int main(int argc, char **argv) goto fin; } if (num_images == 0) { - fprintf(stdout, "Folder is empty\n"); + fprintf(stderr, "Folder is empty\n"); failed = 1; goto fin; } @@ -1336,7 +1393,9 @@ int main(int argc, char **argv) /*Decoding image one by one*/ for (imageno = 0; imageno < num_images ; imageno++) { - fprintf(stderr, "\n"); + if (!parameters.quiet) { + fprintf(stderr, "\n"); + } if (img_fol.set_imgdir == 1) { if (get_next_file(imageno, dirptr, &img_fol, ¶meters)) { @@ -1383,10 +1442,18 @@ int main(int argc, char **argv) continue; } - /* catch events using our callbacks and give a local context */ - opj_set_info_handler(l_codec, info_callback, 00); - opj_set_warning_handler(l_codec, warning_callback, 00); - opj_set_error_handler(l_codec, error_callback, 00); + if (parameters.quiet) { + /* Set all callbacks to quiet */ + opj_set_info_handler(l_codec, quiet_callback, 00); + opj_set_warning_handler(l_codec, quiet_callback, 00); + opj_set_error_handler(l_codec, quiet_callback, 00); + } else { + /* catch events using our callbacks and give a local context */ + opj_set_info_handler(l_codec, info_callback, 00); + opj_set_warning_handler(l_codec, warning_callback, 00); + opj_set_error_handler(l_codec, error_callback, 00); + } + t = opj_clock(); @@ -1418,11 +1485,50 @@ int main(int argc, char **argv) goto fin; } + if (parameters.numcomps) { + if (! opj_set_decoded_components(l_codec, + parameters.numcomps, + parameters.comps_indices, + OPJ_FALSE)) { + fprintf(stderr, + "ERROR -> opj_decompress: failed to set the component indices!\n"); + opj_destroy_codec(l_codec); + opj_stream_destroy(l_stream); + opj_image_destroy(image); + failed = 1; + goto fin; + } + } + + if (getenv("USE_OPJ_SET_DECODED_RESOLUTION_FACTOR") != NULL) { + /* For debugging/testing purposes, and also an illustration on how to */ + /* use the alternative API opj_set_decoded_resolution_factor() instead */ + /* of setting parameters.cp_reduce */ + if (! opj_set_decoded_resolution_factor(l_codec, cp_reduce)) { + fprintf(stderr, + "ERROR -> opj_decompress: failed to set the resolution factor tile!\n"); + opj_destroy_codec(l_codec); + opj_stream_destroy(l_stream); + opj_image_destroy(image); + failed = 1; + goto fin; + } + } + if (!parameters.nb_tile_to_decode) { + if (getenv("SKIP_OPJ_SET_DECODE_AREA") != NULL && + parameters.DA_x0 == 0 && + parameters.DA_y0 == 0 && + parameters.DA_x1 == 0 && + parameters.DA_y1 == 0) { + /* For debugging/testing purposes, */ + /* do nothing if SKIP_OPJ_SET_DECODE_AREA env variable */ + /* is defined and no decoded area has been set */ + } /* Optional if you want decode the entire image */ - if (!opj_set_decode_area(l_codec, image, (OPJ_INT32)parameters.DA_x0, - (OPJ_INT32)parameters.DA_y0, (OPJ_INT32)parameters.DA_x1, - (OPJ_INT32)parameters.DA_y1)) { + else if (!opj_set_decode_area(l_codec, image, (OPJ_INT32)parameters.DA_x0, + (OPJ_INT32)parameters.DA_y0, (OPJ_INT32)parameters.DA_x1, + (OPJ_INT32)parameters.DA_y1)) { fprintf(stderr, "ERROR -> opj_decompress: failed to set the decoded area\n"); opj_stream_destroy(l_stream); opj_destroy_codec(l_codec); @@ -1442,15 +1548,14 @@ int main(int argc, char **argv) goto fin; } } else { - - /* It is just here to illustrate how to use the resolution after set parameters */ - /*if (!opj_set_decoded_resolution_factor(l_codec, 5)) { - fprintf(stderr, "ERROR -> opj_decompress: failed to set the resolution factor tile!\n"); - opj_destroy_codec(l_codec); - opj_stream_destroy(l_stream); - opj_image_destroy(image); - failed = 1; goto fin; - }*/ + if (!(parameters.DA_x0 == 0 && + parameters.DA_y0 == 0 && + parameters.DA_x1 == 0 && + parameters.DA_y1 == 0)) { + if (!(parameters.quiet)) { + fprintf(stderr, "WARNING: -d option ignored when used together with -t\n"); + } + } if (!opj_get_decoded_tile(l_codec, l_stream, image, parameters.tile_index)) { fprintf(stderr, "ERROR -> opj_decompress: failed to decode tile!\n"); @@ -1460,7 +1565,20 @@ int main(int argc, char **argv) failed = 1; goto fin; } - fprintf(stdout, "tile %d is decoded!\n\n", parameters.tile_index); + if (!(parameters.quiet)) { + fprintf(stdout, "tile %d is decoded!\n\n", parameters.tile_index); + } + } + + /* FIXME? Shouldn't that situation be considered as an error of */ + /* opj_decode() / opj_get_decoded_tile() ? */ + if (image->comps[0].data == NULL) { + fprintf(stderr, "ERROR -> opj_decompress: no image data!\n"); + opj_destroy_codec(l_codec); + opj_stream_destroy(l_stream); + opj_image_destroy(image); + failed = 1; + goto fin; } tCumulative += opj_clock() - t; @@ -1574,7 +1692,7 @@ int main(int argc, char **argv) if (imagetopnm(image, parameters.outfile, parameters.split_pnm)) { fprintf(stderr, "[ERROR] Outfile %s not generated\n", parameters.outfile); failed = 1; - } else { + } else if (!(parameters.quiet)) { fprintf(stdout, "[INFO] Generated Outfile %s\n", parameters.outfile); } break; @@ -1583,7 +1701,7 @@ int main(int argc, char **argv) if (imagetopgx(image, parameters.outfile)) { fprintf(stderr, "[ERROR] Outfile %s not generated\n", parameters.outfile); failed = 1; - } else { + } else if (!(parameters.quiet)) { fprintf(stdout, "[INFO] Generated Outfile %s\n", parameters.outfile); } break; @@ -1592,7 +1710,7 @@ int main(int argc, char **argv) if (imagetobmp(image, parameters.outfile)) { fprintf(stderr, "[ERROR] Outfile %s not generated\n", parameters.outfile); failed = 1; - } else { + } else if (!(parameters.quiet)) { fprintf(stdout, "[INFO] Generated Outfile %s\n", parameters.outfile); } break; @@ -1601,7 +1719,7 @@ int main(int argc, char **argv) if (imagetotif(image, parameters.outfile)) { fprintf(stderr, "[ERROR] Outfile %s not generated\n", parameters.outfile); failed = 1; - } else { + } else if (!(parameters.quiet)) { fprintf(stdout, "[INFO] Generated Outfile %s\n", parameters.outfile); } break; @@ -1611,7 +1729,7 @@ int main(int argc, char **argv) fprintf(stderr, "[ERROR] Error generating raw file. Outfile %s not generated\n", parameters.outfile); failed = 1; - } else { + } else if (!(parameters.quiet)) { fprintf(stdout, "[INFO] Generated Outfile %s\n", parameters.outfile); } break; @@ -1622,7 +1740,7 @@ int main(int argc, char **argv) "[ERROR] Error generating rawl file. Outfile %s not generated\n", parameters.outfile); failed = 1; - } else { + } else if (!(parameters.quiet)) { fprintf(stdout, "[INFO] Generated Outfile %s\n", parameters.outfile); } break; @@ -1632,7 +1750,7 @@ int main(int argc, char **argv) fprintf(stderr, "[ERROR] Error generating tga file. Outfile %s not generated\n", parameters.outfile); failed = 1; - } else { + } else if (!(parameters.quiet)) { fprintf(stdout, "[INFO] Generated Outfile %s\n", parameters.outfile); } break; @@ -1642,7 +1760,7 @@ int main(int argc, char **argv) fprintf(stderr, "[ERROR] Error generating png file. Outfile %s not generated\n", parameters.outfile); failed = 1; - } else { + } else if (!(parameters.quiet)) { fprintf(stdout, "[INFO] Generated Outfile %s\n", parameters.outfile); } break; @@ -1685,7 +1803,7 @@ fin: } free(dirptr); } - if (numDecompressedImages) { + if (numDecompressedImages && !failed && !(parameters.quiet)) { fprintf(stdout, "decode time: %d ms\n", (int)((tCumulative * 1000.0) / (OPJ_FLOAT64)numDecompressedImages)); }