1 /* mj2_to_metadata.c */
2 /* Dump MJ2, JP2 metadata (partial so far) to xml file */
3 /* Contributed to Open JPEG by Glenn Pearson, contract software developer, U.S. National Library of Medicine.
5 The base code in this file was developed by the author as part of a video archiving
6 project for the U.S. National Library of Medicine, Bethesda, MD.
7 It is the policy of NLM (and U.S. government) to not assert copyright.
9 A non-exclusive copy of this code has been contributed to the Open JPEG project.
10 Except for copyright, inclusion of the code within Open JPEG for distribution and use
11 can be bound by the Open JPEG open-source license and disclaimer, expressed elsewhere.
22 #define _CRTDBG_MAP_ALLOC
23 #include <stdlib.h> // Must be included first
28 #include "mj2_to_metadata.h"
30 #ifndef DONT_HAVE_GETOPT
33 #include "compat/getopt.h"
40 /* "1234567890123456789012345678901234567890123456789012345678901234567890123456789" */
41 fprintf(stdout," Help for the 'mj2_to_metadata' Program\n");
42 fprintf(stdout," ======================================\n");
43 fprintf(stdout,"The -h option displays this information on screen.\n\n");
45 fprintf(stdout,"mj2_to_metadata generates an XML file from a Motion JPEG 2000 file.\n");
46 fprintf(stdout,"The generated XML shows the structural, but not (yet) curatorial,\n");
47 fprintf(stdout,"metadata from the movie header and from the JPEG 2000 image and tile\n");
48 fprintf(stdout,"headers of a sample frame. Excluded: low-level packed-bits image data.\n\n");
50 fprintf(stdout,"By Default\n");
51 fprintf(stdout,"----------\n");
52 fprintf(stdout,"The metadata includes the jp2 image and tile headers of the first frame.\n");
54 fprintf(stdout,"Metadata values are shown in 'raw' form (e.g., hexidecimal) as stored in the\n");
55 fprintf(stdout,"file, and, if apt, in a 'derived' form that is more quickly grasped.\n");
57 fprintf(stdout,"Notes explaining the XML are embedded as terse comments. These include\n");
58 fprintf(stdout," meaning of non-obvious tag abbreviations;\n");
59 fprintf(stdout," range and precision of valid values;\n");
60 fprintf(stdout," interpretations of values, such as enumerations; and\n");
61 fprintf(stdout," current implementation limitations.\n");
63 fprintf(stdout,"The sample-size and chunk-offset tables, each with 1 row per frame, are not reported.\n");
65 fprintf(stdout,"The file is self-contained and no verification (e.g., against a DTD) is requested.\n");
67 fprintf(stdout,"Required Parameters (except with -h)\n");
68 fprintf(stdout,"------------------------------------\n");
69 fprintf(stdout,"[Caution: file strings that contain spaces should be wrapped with quotes.]\n");
70 fprintf(stdout,"-i input.mj2 : where 'input' is any source file name or path.\n");
71 fprintf(stdout," MJ2 files created with 'frames_to_mj2' are supported so far.\n");
72 fprintf(stdout," These are silent, single-track, 'MJ2 Simple Profile' videos.\n");
73 fprintf(stdout,"-o output.xml : where 'output' is any destination file name or path.\n");
75 fprintf(stdout,"Optional Parameters\n");
76 fprintf(stdout,"-------------------\n");
77 fprintf(stdout,"-h : Display this help information.\n");
78 fprintf(stdout,"-n : Suppress all mj2_to_metadata notes.\n");
79 fprintf(stdout,"-t : Include sample-size and chunk-offset tables.\n");
80 fprintf(stdout,"-f n : where n > 0. Include jp2 header info for frame n [default=1].\n");
81 fprintf(stdout,"-f 0 : No jp2 header info.\n");
82 fprintf(stdout,"-r : Suppress all 'raw' data for which a 'derived' form exists.\n");
83 fprintf(stdout,"-d : Suppress all 'derived' data.\n");
84 fprintf(stdout," (If both -r and -d given, -r will be ignored.)\n");
85 fprintf(stdout,"-v string : Verify against the DTD file located by the string.\n");
86 fprintf(stdout," Prepend quoted 'string' with either SYSTEM or PUBLIC keyword.\n");
87 fprintf(stdout," Thus, for the distributed DTD placed in the same directory as\n");
88 fprintf(stdout," the output file: -v \"SYSTEM mj2_to_metadata.dtd\"\n");
89 fprintf(stdout," \"PUBLIC\" is used with an access protocol (e.g., http:) + URL.\n");
92 /* "1234567890123456789012345678901234567890123456789012345678901234567890123456789" */
97 int main(int argc, char *argv[]) {
100 /* char xmloutname[50]; */
107 unsigned int sampleframe = 1; /* First frame */
108 char* stringDTD = NULL;
110 BOOL sampletables = FALSE;
114 #ifndef NO_PACKETS_DECODING
115 fprintf(stdout,"WARNING: For best performance, define NO_PACKETS_DECODING in preprocessing.\n");
119 /* ':' after letter means it takes an argument */
120 int c = getopt(argc, argv, "i:o:f:v:hntrd");
121 /* FUTURE: Reserve 'p' for pruning file (which will probably make -t redundant) */
125 case 'i': /* IN file */
128 while (*s) { s++; } /* Run to filename end */
136 if ((S1 == 'm' && S2 == 'j' && S3 == '2')
137 || (S1 == 'M' && S2 == 'J' && S3 == '2')) {
140 fprintf(stderr, "Input file name must have .mj2 extension, not .%c%c%c.\n", S1, S2, S3);
143 /* ----------------------------------------------------- */
144 case 'o': /* OUT file */
146 while (*outfile) { outfile++; } /* Run to filename end */
156 if ((S1 == 'x' && S2 == 'm' && S3 == 'l')
157 || (S1 == 'X' && S2 == 'M' && S3 == 'L'))
161 "Output file name must have .xml extension, not .%c%c%c\n", S1, S2, S3);
164 /* ----------------------------------------------------- */
165 case 'f': /* Choose sample frame. 0 = none */
166 sscanf(optarg, "%u", &sampleframe);
169 /* ----------------------------------------------------- */
170 case 'v': /* Verification by DTD. */
172 /* We will not insist upon last 3 chars being "dtd", since non-file
173 access protocol may be used. */
174 if(strchr(stringDTD,'"') != NULL) {
175 fprintf(stderr, "-D's string must not contain any embedded double-quote characters.\n");
179 if (strncmp(stringDTD,"PUBLIC ",7) == 0 || strncmp(stringDTD,"SYSTEM ",7) == 0)
182 fprintf(stderr, "-D's string must start with \"PUBLIC \" or \"SYSTEM \"\n");
185 /* ----------------------------------------------------- */
186 case 'n': /* Suppress comments */
190 /* ----------------------------------------------------- */
191 case 't': /* Show sample size and chunk offset tables */
195 /* ----------------------------------------------------- */
196 case 'h': /* Display an help description */
200 /* ----------------------------------------------------- */
201 case 'r': /* Suppress raw data */
205 /* ----------------------------------------------------- */
206 case 'd': /* Suppress derived data */
210 /* ----------------------------------------------------- */
217 raw = TRUE; /* At least one of 'raw' and 'derived' must be true */
221 if (!infile || !outfile) {
222 fprintf(stderr,"Correct usage: mj2_to_metadata -i mj2-file -o xml-file (plus options)\n");
228 printf("Bad syntax: Usage: MJ2_to_metadata inputfile.mj2 outputfile.xml\n");
229 printf("Example: MJ2_to_metadata foreman.mj2 foreman.xml\n");
233 len = strlen(infile);
236 infile++; /* There may be a leading blank if user put space after -i */
239 file = fopen(infile, "rb"); /* was: argv[1] */
242 fprintf(stderr, "Failed to open %s for reading.\n", infile); /* was: argv[1] */
246 len = strlen(outfile);
247 if(outfile[0] == ' ')
249 outfile++; /* There may be a leading blank if user put space after -o */
252 // Checking output file
253 xmlout = fopen(outfile, "w"); /* was: argv[2] */
255 fprintf(stderr, "Failed to open %s for writing.\n", outfile); /* was: argv[2] */
260 if (mj2_read_struct(file, &movie)) // Creating the movie structure
266 xml_write_init(notes, sampletables, raw, derived);
267 xml_write_struct(file, xmlout, &movie, sampleframe, stringDTD);
270 mj2_memory_free(&movie);
274 _CrtDumpMemoryLeaks();