X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=applications%2Fcodec%2Fj2k_dump.c;h=d1c1fb694bbf4aba41cc2352dcdb8f6a172f13c3;hb=d44375aece5dea2af83ffb8c9de4ade2ad35c593;hp=02f8316c0d43724d5b237d44c742bf9c4f0f549c;hpb=676f8f189f338ababaf67fe652c708e82770d524;p=openjpeg.git diff --git a/applications/codec/j2k_dump.c b/applications/codec/j2k_dump.c index 02f8316c..d1c1fb69 100644 --- a/applications/codec/j2k_dump.c +++ b/applications/codec/j2k_dump.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 20010, Mathieu Malaterre, GDCM + * Copyright (c) 2010, Mathieu Malaterre, GDCM + * Copyright (c) 2011, Mickael Savinaud, Communications & Systemes * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -47,7 +48,7 @@ #include "openjpeg.h" #include "j2k.h" #include "jp2.h" -#include "getopt.h" +#include "opj_getopt.h" #include "convert.h" #include "index.h" @@ -93,15 +94,15 @@ void decode_help_display(void) { fprintf(stdout," Currently accepts J2K-files, JP2-files and JPT-files. The file type\n"); fprintf(stdout," is identified based on its suffix.\n"); fprintf(stdout," -o \n"); - fprintf(stdout," OPTIONAL\n"); - fprintf(stdout," Output file where file info will be dump.\n"); - fprintf(stdout," By default it will be in the stdout.\n"); + fprintf(stdout," OPTIONAL\n"); + fprintf(stdout," Output file where file info will be dump.\n"); + fprintf(stdout," By default it will be in the stdout.\n"); fprintf(stdout,"\n"); } /* -------------------------------------------------------------------------- */ -static void j2k_dump_image(FILE *fd, opj_image_t * img); -static void j2k_dump_cp(FILE *fd, opj_image_t * img, opj_cp_t * cp); +static void j2k_dump_image(FILE *fd, opj_image_header_t * img); +static void j2k_dump_cp(FILE *fd, opj_image_t * img, opj_cp_v2_t * cp); int get_num_images(char *imgdirpath){ DIR *dir; @@ -180,7 +181,7 @@ char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_dparamet sprintf(infilename,"%s/%s",img_fol->imgdirpath,image_filename); strncpy(parameters->infile, infilename, sizeof(infilename)); - //Set output file + /* Set output file */ strcpy(temp_ofname,strtok(image_filename,".")); while((temp_p = strtok(NULL,".")) != NULL){ strcat(temp_ofname,temp1); @@ -194,30 +195,30 @@ char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_dparamet } /* -------------------------------------------------------------------------- */ -int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,img_fol_t *img_fol, char *indexfilename) { +int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,img_fol_t *img_fol) { /* parse the command line */ int totlen, c; - option_t long_option[]={ + opj_option_t long_option[]={ {"ImgDir",REQ_ARG, NULL ,'y'}, }; - const char optlist[] = "i:o:h"; - - OPJ_ARG_NOT_USED(indexfilename); + const char optlist[] = "i:o:d:h"; totlen=sizeof(long_option); img_fol->set_out_format = 0; do { - c = getopt_long(argc, argv,optlist,long_option,totlen); + c = opj_getopt_long(argc, argv,optlist,long_option,totlen); if (c == -1) break; switch (c) { case 'i': /* input file */ { - char *infile = optarg; + char *infile = opj_optarg; parameters->decod_format = get_file_format(infile); switch(parameters->decod_format) { case J2K_CFMT: + break; case JP2_CFMT: + break; case JPT_CFMT: break; default: @@ -234,7 +235,7 @@ int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,i case 'o': /* output file */ { - char *outfile = optarg; + char *outfile = opj_optarg; strncpy(parameters->outfile, outfile, sizeof(parameters->outfile)-1); } break; @@ -249,16 +250,28 @@ int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,i case 'y': /* Image Directory path */ { - img_fol->imgdirpath = (char*)malloc(strlen(optarg) + 1); - strcpy(img_fol->imgdirpath,optarg); + img_fol->imgdirpath = (char*)malloc(strlen(opj_optarg) + 1); + strcpy(img_fol->imgdirpath,opj_optarg); img_fol->set_imgdir=1; } break; /* ----------------------------------------------------- */ + case 'd': /* Input decode ROI */ + { + int size_optarg = (int)strlen(optarg) + 1; + char *ROI_values = (char*) malloc(size_optarg); + ROI_values[0] = '\0'; + strncpy(ROI_values, optarg, strlen(optarg)); + ROI_values[strlen(optarg)] = '\0'; + printf("ROI_values = %s [%d / %d]\n", ROI_values, strlen(ROI_values), size_optarg ); + parse_ROI_values( ROI_values, ¶meters->ROI_x0, ¶meters->ROI_y0, ¶meters->ROI_x1, ¶meters->ROI_y1); + } + break; + /* ----------------------------------------------------- */ default: - fprintf(stderr,"WARNING -> this option is not valid \"-%c %s\"\n",c, optarg); + fprintf(stderr,"WARNING -> this option is not valid \"-%c %s\"\n",c, opj_optarg); break; } }while(c != -1); @@ -289,6 +302,34 @@ int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,i return 0; } +/******************************************************************************* + * Parse ROI input values + * separator = "," + *******************************************************************************/ +int parse_ROI_values( char* inArg, unsigned int *ROI_x0, unsigned int *ROI_y0, unsigned int *ROI_x1, unsigned int *ROI_y1) +{ + int it = 0; + int values[4]; + char delims[] = ","; + char *result = NULL; + result = strtok( inArg, delims ); + + while( (result != NULL) && (it < 4 ) ) { + values[it] = atoi(result); + result = strtok( NULL, delims ); + it++; + } + + if (it != 4) { + return EXIT_FAILURE; + } + else{ + *ROI_x0 = values[0]; *ROI_y0 = values[1]; + *ROI_x1 = values[2]; *ROI_y1 = values[3]; + return EXIT_SUCCESS; + } +} + /* -------------------------------------------------------------------------- */ /** @@ -317,37 +358,39 @@ void info_callback(const char *msg, void *client_data) { int main(int argc, char *argv[]) { + int ret; opj_dparameters_t parameters; /* decompression parameters */ img_fol_t img_fol; opj_event_mgr_t event_mgr; /* event manager */ - opj_image_t *image = NULL; + opj_image_header_t* image = NULL; + opj_file_info_t file_info; FILE *fsrc = NULL, *fout = NULL; - unsigned char *src = NULL; - int file_length; int num_images; int i,imageno; dircnt_t *dirptr = NULL; - opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */ - opj_cio_t *cio = NULL; - opj_codestream_info_t cstr_info; /* Codestream information structure */ - char indexfilename[OPJ_PATH_LEN]; /* index file name */ + opj_codec_t* dinfo = NULL; /* handle to a decompressor */ + opj_stream_t *cio = NULL; + opj_codestream_info_t* cstr_info =NULL; /* Codestream information structure */ + /* OPJ_INT32 l_tile_x0,l_tile_y0; */ + /* OPJ_UINT32 l_tile_width,l_tile_height,l_nb_tiles_x,l_nb_tiles_y; */ - /* configure the event callbacks (not required) */ + + /* FIXME configure the event callbacks (not required) */ memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); event_mgr.error_handler = error_callback; event_mgr.warning_handler = warning_callback; event_mgr.info_handler = info_callback; + event_mgr.client_data = stderr; /* set decoding parameters to default values */ opj_set_default_decoder_parameters(¶meters); - /* Initialize indexfilename and img_fol */ - *indexfilename = 0; + /* Initialize img_fol */ memset(&img_fol,0,sizeof(img_fol_t)); /* parse input and get user encoding parameters */ - if(parse_cmdline_decoder(argc, argv, ¶meters,&img_fol, indexfilename) == 1) { - return 1; + if(parse_cmdline_decoder(argc, argv, ¶meters,&img_fol) == 1) { + return EXIT_FAILURE; } /* Initialize reading of directory */ @@ -356,44 +399,43 @@ int main(int argc, char *argv[]) dirptr=(dircnt_t*)malloc(sizeof(dircnt_t)); if(dirptr){ - dirptr->filename_buf = (char*)malloc(num_images*OPJ_PATH_LEN*sizeof(char)); // Stores at max 10 image file names + dirptr->filename_buf = (char*)malloc(num_images*OPJ_PATH_LEN*sizeof(char)); /* Stores at max 10 image file names */ dirptr->filename = (char**) malloc(num_images*sizeof(char*)); if(!dirptr->filename_buf){ - return 1; + return EXIT_FAILURE; } + for(i=0;ifilename[i] = dirptr->filename_buf + i*OPJ_PATH_LEN; } } if(load_images(dirptr,img_fol.imgdirpath)==1){ - return 1; + return EXIT_FAILURE; } + if (num_images==0){ fprintf(stdout,"Folder is empty\n"); - return 1; + return EXIT_FAILURE; } }else{ num_images=1; } - // - if (parameters.outfile[0] != 0) - { - fout = fopen(parameters.outfile,"w"); - if (!fout) - { - fprintf(stderr, "ERROR -> failed to open %s for reading\n", parameters.outfile); - return 1; - } - } + /* Try to open for writing the output file if necessary */ + if (parameters.outfile[0] != 0){ + fout = fopen(parameters.outfile,"w"); + if (!fout){ + fprintf(stderr, "ERROR -> failed to open %s for writing\n", parameters.outfile); + return EXIT_FAILURE; + } + } else - fout = stdout; + fout = stdout; + + /* Read the header of each image one by one */ + for(imageno = 0; imageno < num_images ; imageno++){ - /*Encoding image one by one*/ - for(imageno = 0; imageno < num_images ; imageno++) - { - image = NULL; fprintf(stderr,"\n"); if(img_fol.set_imgdir==1){ @@ -408,217 +450,116 @@ int main(int argc, char *argv[]) fsrc = fopen(parameters.infile, "rb"); if (!fsrc) { fprintf(stderr, "ERROR -> failed to open %s for reading\n", parameters.infile); - return 1; + return EXIT_FAILURE; } - fseek(fsrc, 0, SEEK_END); - file_length = ftell(fsrc); - fseek(fsrc, 0, SEEK_SET); - src = (unsigned char *) malloc(file_length); - if (fread(src, 1, file_length, fsrc) != (size_t)file_length) - { - free(src); - fclose(fsrc); - fprintf(stderr, "\nERROR: fread return a number of element different from the expected.\n"); - return 1; + + cio = opj_stream_create_default_file_stream(fsrc,1); + if (!cio){ + fprintf(stderr, "ERROR -> failed to create the stream from the file\n"); + return EXIT_FAILURE; } - fclose(fsrc); /* decode the code-stream */ /* ---------------------- */ switch(parameters.decod_format) { - case J2K_CFMT: - { - /* JPEG-2000 codestream */ - - /* get a decoder handle */ - dinfo = opj_create_decompress(CODEC_J2K); - - /* catch events using our callbacks and give a local context */ - opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); - - /* setup the decoder decoding parameters using user parameters */ - opj_setup_decoder(dinfo, ¶meters); - - /* open a byte stream */ - cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); - - /* decode the stream and fill the image structure */ - if (*indexfilename) // If need to extract codestream information - image = opj_decode_with_info(dinfo, cio, &cstr_info); - else - image = opj_decode(dinfo, cio); - if(!image) { - fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); - opj_destroy_decompress(dinfo); - opj_cio_close(cio); - return 1; - } - /* dump image */ - j2k_dump_image(fout, image); - - /* dump cp */ - j2k_dump_cp(fout, image, ((opj_j2k_t*)dinfo->j2k_handle)->cp); - - /* close the byte stream */ - opj_cio_close(cio); + case J2K_CFMT: + { /* JPEG-2000 codestream */ - /* Write the index to disk */ - if (*indexfilename) { - opj_bool bSuccess; - bSuccess = write_index_file(&cstr_info, indexfilename); - if (bSuccess) { - fprintf(stderr, "Failed to output index file\n"); - } + /* get a decoder handle */ + dinfo = opj_create_decompress_v2(CODEC_J2K); + break; } - } - break; - - case JP2_CFMT: - { - /* JPEG 2000 compressed image data */ - - /* get a decoder handle */ - dinfo = opj_create_decompress(CODEC_JP2); - - /* catch events using our callbacks and give a local context */ - opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); - - /* setup the decoder decoding parameters using the current image and user parameters */ - opj_setup_decoder(dinfo, ¶meters); - - /* open a byte stream */ - cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); - - /* decode the stream and fill the image structure */ - if (*indexfilename) // If need to extract codestream information - image = opj_decode_with_info(dinfo, cio, &cstr_info); - else - image = opj_decode(dinfo, cio); - if(!image) { - fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); - opj_destroy_decompress(dinfo); - opj_cio_close(cio); - return 1; + case JP2_CFMT: + { /* JPEG 2000 compressed image data */ + + /* get a decoder handle */ + dinfo = opj_create_decompress_v2(CODEC_JP2); + break; } - /* dump image */ - if(image->icc_profile_buf) - { - free(image->icc_profile_buf); image->icc_profile_buf = NULL; - } - j2k_dump_image(fout, image); - - /* dump cp */ - j2k_dump_cp(fout, image, ((opj_jp2_t*)dinfo->jp2_handle)->j2k->cp); - - /* close the byte stream */ - opj_cio_close(cio); - - /* Write the index to disk */ - if (*indexfilename) { - opj_bool bSuccess; - bSuccess = write_index_file(&cstr_info, indexfilename); - if (bSuccess) { - fprintf(stderr, "Failed to output index file\n"); - } + case JPT_CFMT: + { /* JPEG 2000, JPIP */ + + /* get a decoder handle */ + dinfo = opj_create_decompress_v2(CODEC_JPT); + break; } + default: + fprintf(stderr, "skipping file..\n"); + opj_stream_destroy(cio); + continue; } - break; - - case JPT_CFMT: - { - /* JPEG 2000, JPIP */ - - /* get a decoder handle */ - dinfo = opj_create_decompress(CODEC_JPT); - - /* catch events using our callbacks and give a local context */ - opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); - - /* setup the decoder decoding parameters using user parameters */ - opj_setup_decoder(dinfo, ¶meters); - - /* open a byte stream */ - cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); - - /* decode the stream and fill the image structure */ - if (*indexfilename) // If need to extract codestream information - image = opj_decode_with_info(dinfo, cio, &cstr_info); - else - image = opj_decode(dinfo, cio); - if(!image) { - fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); - opj_destroy_decompress(dinfo); - opj_cio_close(cio); - return 1; - } - /* close the byte stream */ - opj_cio_close(cio); + /* setup the decoder decoding parameters using user parameters */ + opj_setup_decoder_v2(dinfo, ¶meters, &event_mgr); - /* Write the index to disk */ - if (*indexfilename) { - opj_bool bSuccess; - bSuccess = write_index_file(&cstr_info, indexfilename); - if (bSuccess) { - fprintf(stderr, "Failed to output index file\n"); - } - } + if(! opj_read_header(cio, dinfo, &file_info, OPJ_IMG_INFO | OPJ_J2K_INFO)){ + fprintf(stderr, "ERROR -> j2k_dump: failed to read the header\n"); + opj_stream_destroy(cio); + fclose(fsrc); + opj_destroy_codec(dinfo); + return EXIT_FAILURE; } - break; - default: - fprintf(stderr, "skipping file..\n"); - continue; - } + printf("Setting decoding area to %d,%d,%d,%d\n", + parameters.ROI_x0, parameters.ROI_y0, parameters.ROI_x1, parameters.ROI_x1); + opj_set_decode_area(dinfo, + parameters.ROI_x0, parameters.ROI_y0, + parameters.ROI_x1, parameters.ROI_x1); - /* free the memory containing the code-stream */ - free(src); - src = NULL; + /* Dump file informations from header */ + dump_file_info(fout, &file_info); + + /* close the byte stream */ + opj_stream_destroy(cio); + fclose(fsrc); /* free remaining structures */ - if(dinfo) { - opj_destroy_decompress(dinfo); + if (dinfo) { + opj_destroy_codec(dinfo); } - /* free codestream information structure */ - if (*indexfilename) - opj_destroy_cstr_info(&cstr_info); - /* free image data structure */ - opj_image_destroy(image); + + + opj_image_header_destroy(image); + //FIXME opj_file_info_destroy(file_info); } + + /* Close the output file */ fclose(fout); return EXIT_SUCCESS; } -static void j2k_dump_image(FILE *fd, opj_image_t * img) { +static void j2k_dump_image(FILE *fd, opj_image_header_t * img) { int compno; fprintf(fd, "image {\n"); fprintf(fd, " x0=%d, y0=%d, x1=%d, y1=%d\n", img->x0, img->y0, img->x1, img->y1); fprintf(fd, " numcomps=%d\n", img->numcomps); for (compno = 0; compno < img->numcomps; compno++) { - opj_image_comp_t *comp = &img->comps[compno]; + opj_image_comp_header_t *comp = &img->comps[compno]; fprintf(fd, " comp %d {\n", compno); fprintf(fd, " dx=%d, dy=%d\n", comp->dx, comp->dy); fprintf(fd, " prec=%d\n", comp->prec); - //fprintf(fd, " bpp=%d\n", comp->bpp); + /* fprintf(fd, " bpp=%d\n", comp->bpp); */ fprintf(fd, " sgnd=%d\n", comp->sgnd); fprintf(fd, " }\n"); } + //fprintf(fd, " XTOsiz=%d, YTOsiz=%d, XTsiz=%d, YTsiz=%d\n", img->tile_x0, img->tile_y0, img->tile_width, img->tile_height); + //fprintf(fd, " Nb of tiles in x direction=%d, Nb of tiles in y direction=%d\n", img->nb_tiles_x, img->nb_tiles_y); fprintf(fd, "}\n"); } -static void j2k_dump_cp(FILE *fd, opj_image_t * img, opj_cp_t * cp) { +static void j2k_dump_cp(FILE *fd, opj_image_t * img, opj_cp_v2_t * cp) { int tileno, compno, layno, bandno, resno, numbands; fprintf(fd, "coding parameters {\n"); fprintf(fd, " tx0=%d, ty0=%d\n", cp->tx0, cp->ty0); fprintf(fd, " tdx=%d, tdy=%d\n", cp->tdx, cp->tdy); fprintf(fd, " tw=%d, th=%d\n", cp->tw, cp->th); for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { - opj_tcp_t *tcp = &cp->tcps[tileno]; + opj_tcp_v2_t *tcp = &cp->tcps[tileno]; fprintf(fd, " tile %d {\n", tileno); fprintf(fd, " csty=%x\n", tcp->csty); fprintf(fd, " prg=%d\n", tcp->prg); @@ -662,9 +603,9 @@ static void j2k_dump_cp(FILE *fd, opj_image_t * img, opj_cp_t * cp) { fprintf(fd, "\n"); } fprintf(fd, " }\n"); - } + } /*end of component*/ fprintf(fd, " }\n"); - } + } /*end of tile */ fprintf(fd, "}\n"); }