Change video content scaling so that it either:
[dcpomatic.git] / hacks / jpegdump.c
1 /*
2    avidump.c
3
4    simple format info and dump utility for jpeg codestreams
5
6    Copyright (C) 2006 Ralph Giles. All rights reserved.
7
8    Distributed under the terms of the GNU GPL.
9    See http://www.gnu.org/ for details.
10 */
11
12 #include <stdint.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <stdio.h>
16
17 /* JPEG marker codes
18    - these are the second bytes; a marker consistes of 0xff
19      followed by the type codes given below. */
20 typedef enum {
21
22     /* 0xFF00, 0xFF01, 0xFFFE, 0xFFC0-0xFFDF(?) ITU T.81/IEC 10918-1 */
23     /* 0xFFF0 - 0xFFF6 ITU T.84/IEC 10918-3 JPEG extensions */
24     /* 0xFFF7 - 0xFFF8 ITU T.87/IEC 14495-1 JPEG LS */
25     /* 0xFF4F - 0xFF6f, 0xFF90 - 0xFF93 JPEG 2000 IEC 15444-1 */
26     /* 0xFF30 - 0xFF3F reserved JP2 (markers only--no marker segments */
27
28     /* JPEG 1994 - defined in ITU T.81 | ISO IEC 10918-1 */
29     SOF0  = 0xc0,       /* start of frame - baseline jpeg */
30     SOF1  = 0xc1,       /* extended sequential, huffman */
31     SOF2  = 0xc2,       /* progressive, huffman */
32     SOF3  = 0xc3,       /* lossless, huffman */
33
34     SOF5  = 0xc5,       /* differential sequential, huffman */
35     SOF6  = 0xc6,       /* differential progressive, huffman */
36     SOF7  = 0xc7,       /* differential lossless, huffman */
37     JPG   = 0xc8,       /* reserved for JPEG extension */
38     SOF9  = 0xc9,       /* extended sequential, arithmetic */
39     SOF10 = 0xca,       /* progressive, arithmetic */
40     SOF11 = 0xcb,       /* lossless, arithmetic */
41
42     SOF13 = 0xcd,       /* differential sequential, arithmetic */
43     SOF14 = 0xce,       /* differential progressive, arithmetic */
44     SOF15 = 0xcf,       /* differential lossless, arithmetic */
45
46     DHT   = 0xc4,       /* define huffman tables */
47
48     DAC   = 0xcc,       /* define arithmetic-coding conditioning */
49
50       /* restart markers */
51     RST0  = 0xd0,
52     RST1  = 0xd1,
53     RST2  = 0xd2,
54     RST3  = 0xd3,
55     RST4  = 0xd4,
56     RST5  = 0xd5,
57     RST6  = 0xd6,
58     RST7  = 0xd7,
59       /* delimeters */
60     SOI   = 0xd8,       /* start of image */
61     EOI   = 0xd9,       /* end of image */
62     SOS   = 0xda,       /* start of scan */
63     DQT   = 0xdb,       /* define quantization tables */
64     DNL   = 0xdc,       /* define number of lines */
65     DRI   = 0xdd,       /* define restart interval */
66     DHP   = 0xde,       /* define hierarchical progression */
67     EXP   = 0xdf,       /* expand reference components */
68
69     /* JPEG 1997 extensions ITU T.84 | ISO IEC 10918-3 */
70       /* application data sections */
71     APP0  = 0xe0,
72     APP1  = 0xe1,
73     APP2  = 0xe2,
74     APP3  = 0xe3,
75     APP4  = 0xe4,
76     APP5  = 0xe5,
77     APP6  = 0xe6,
78     APP7  = 0xe7,
79     APP8  = 0xe8,
80     APP9  = 0xe9,
81     APP10 = 0xea,
82     APP11 = 0xeb,
83     APP12 = 0xec,
84     APP13 = 0xed,
85     APP14 = 0xee,
86     APP15 = 0xef,
87       /* extention data sections */
88     JPG0  = 0xf0,
89     JPG1  = 0xf1,
90     JPG2  = 0xf2,
91     JPG3  = 0xf3,
92     JPG4  = 0xf4,
93     JPG5  = 0xf5,
94     JPG6  = 0xf6,
95     SOF48 = 0xf7,       /* JPEG-LS */
96     LSE   = 0xf8,       /* JPEG-LS extension parameters */
97     JPG9  = 0xf9,
98     JPG10 = 0xfa,
99     JPG11 = 0xfb,
100     JPG12 = 0xfc,
101     JPG13 = 0xfd,
102     JCOM  = 0xfe,       /* comment */
103
104     TEM   = 0x01,       /* temporary private use for arithmetic coding */
105
106     /* 0x02 -> 0xbf reserved in JPEG 94/97*/
107
108     /* JPEG 2000 - defined in IEC 15444-1 "JPEG 2000 Core (part 1)" */
109       /* delimiters */
110     SOC   = 0x4f,       /* start of codestream */
111     SOT   = 0x90,       /* start of tile */
112     SOD   = 0x93,       /* start of data */
113     EOC   = 0xd9,       /* end of codestream */
114       /* fixed information segment */
115     SIZ   = 0x51,       /* image and tile size */
116       /* functional segments */
117     COD   = 0x52,       /* coding style default */
118     COC   = 0x53,       /* coding style component */
119     RGN   = 0x5e,       /* region of interest */
120     QCD   = 0x5c,       /* quantization default */
121     QCC   = 0x5d,       /* quantization component */
122     POC   = 0x5f,       /* progression order change */
123       /* pointer segments */
124     TLM   = 0x55,       /* tile-part lengths */
125     PLM   = 0x57,       /* packet length (main header) */
126     PLT   = 0x58,       /* packet length (tile-part header) */
127     PPM   = 0x60,       /* packed packet headers (main header) */
128     PPT   = 0x61,       /* packet packet headers (tile-part header) */
129       /* bitstream internal markers and segments */
130     SOP   = 0x91,       /* start of packet */
131     EPH   = 0x92,       /* end of packet header */
132       /* informational segments */
133     CRG   = 0x63,       /* component registration */
134     COM   = 0x64,       /* comment */
135
136 } marker;
137
138 typedef struct {
139   char *mark;   /* marker mnemonic string */
140   char *name;   /* longer name */
141   char *spec;   /* defining specification */
142 } marker_info;
143
144 marker_info *markers;
145
146 /* helper for structure initialization */
147 marker_info init_marker(char *mark, char *name, char *spec)
148 {
149   marker_info marker;
150
151   marker.mark = mark;
152   marker.name = name;
153   marker.spec = spec;
154
155   return marker;
156 }
157
158 marker_info *init_markers(void)
159 {
160   int i;
161   marker_info *marker;
162   char name[256];
163   int namelen;
164
165   /* allocate marker info array */
166   marker = malloc(256 * sizeof(*marker));
167   if (marker == NULL) return marker;
168
169   /* set default values for all marker code values */
170   namelen = strlen("reserved XX");
171   for (i = 0; i < 256; i++) {
172     snprintf(name, 256, "reserved %02x", i);
173     marker[i].mark = "---";
174     marker[i].name = malloc(namelen+1);
175     if (marker[i].name) memcpy(marker[i].name, name, namelen+1);
176     marker[i].spec = strdup("JPEG");
177   }
178
179   /* set defined marks */
180   marker[0x00] = init_marker( "nul", "reserved 00", "JPEG" );
181   marker[0x01] = init_marker( "TEM", "reserved 01", "JPEG" );
182
183   /* JPEG 1994 - defined in ITU T.81 | ISO IEC 10918-1 */
184     /* frame types */
185   marker[0xc0] = init_marker( "SOF0", "start of frame (baseline jpeg)", "JPEG 1994" );
186   marker[0xc1] = init_marker( "SOF1", "start of frame (extended sequential, huffman)", "JPEG 1994" );
187   marker[0xc2] = init_marker( "SOF2", "start of frame (progressive, huffman)", "JPEG 1994" );
188   marker[0xc3] = init_marker( "SOF3", "start of frame (lossless, huffman)", "JPEG 1994" );
189
190   marker[0xc5] = init_marker( "SOF5", "start of frame (differential sequential, huffman)", "JPEG 1994" );
191   marker[0xc6] = init_marker( "SOF6", "start of frame (differential progressive, huffman)", "JPEG 1994" );
192   marker[0xc7] = init_marker( "SOF7", "start of frame (differential lossless, huffman)", "JPEG 1994" );
193   marker[0xc8] = init_marker( "JPG", "reserved for JPEG extension", "JPEG 1994" );
194   marker[0xc9] = init_marker( "SOF9", "start of frame (extended sequential, arithmetic)", "JPEG 1994" );
195   marker[0xca] = init_marker( "SOF10", "start of frame (progressive, arithmetic)", "JPEG 1994" );
196   marker[0xcb] = init_marker( "SOF11", "start of frame (lossless, arithmetic)", "JPEG 1994" );
197
198   marker[0xcd] = init_marker( "SOF13", "start of frame (differential sequential, arithmetic)", "JPEG 1994" );
199   marker[0xce] = init_marker( "SOF14", "start of frame (differential progressive, arithmetic)", "JPEG 1994" );
200   marker[0xcf] = init_marker( "SOF15", "start of frame (differential lossless, arithmetic)", "JPEG 1994" );
201
202   marker[0xc4] = init_marker( "DHT", "define huffman tables", "JPEG 1994" );
203   marker[0xcc] = init_marker( "DAC", "define arithmetic coding conditioning", "JPEG 1994" );
204
205       /* restart markers */
206   marker[0xd0] = init_marker( "RST0", "restart marker 0", "JPEG 1994" );
207   marker[0xd1] = init_marker( "RST1", "restart marker 1", "JPEG 1994" );
208   marker[0xd2] = init_marker( "RST2", "restart marker 2", "JPEG 1994" );
209   marker[0xd3] = init_marker( "RST3", "restart marker 3", "JPEG 1994" );
210   marker[0xd4] = init_marker( "RST4", "restart marker 4", "JPEG 1994" );
211   marker[0xd5] = init_marker( "RST5", "restart marker 5", "JPEG 1994" );
212   marker[0xd6] = init_marker( "RST6", "restart marker 6", "JPEG 1994" );
213   marker[0xd7] = init_marker( "RST7", "restart marker 7", "JPEG 1994" );
214       /* delimeters */
215   marker[0xd8] = init_marker( "SOI", "start of image", "JPEG 1994" );
216   marker[0xd9] = init_marker( "EOI", "end of image", "JPEG 1994" );
217   marker[0xda] = init_marker( "SOS", "start of scan", "JPEG 1994" );
218   marker[0xdb] = init_marker( "DQT", "define quantization tables", "JPEG 1994" );
219   marker[0xdc] = init_marker( "DNL", "define number of lines", "JPEG 1994" );
220   marker[0xdd] = init_marker( "DRI", "define restart interval", "JPEG 1994" );
221   marker[0xde] = init_marker( "DHP", "define hierarchical progression", "JPEG 1994" );
222   marker[0xdf] = init_marker( "EXP", "expand reference components", "JPEG 1994" );
223
224     /* JPEG 1997 extensions ITU T.84 | ISO IEC 10918-3 */
225       /* application data sections */
226   marker[0xe0] = init_marker( "APP0", "application data section  0", "JPEG 1997" );
227   marker[0xe1] = init_marker( "APP1", "application data section  1", "JPEG 1997" );
228   marker[0xe2] = init_marker( "APP2", "application data section  2", "JPEG 1997" );
229   marker[0xe3] = init_marker( "APP3", "application data section  3", "JPEG 1997" );
230   marker[0xe4] = init_marker( "APP4", "application data section  4", "JPEG 1997" );
231   marker[0xe5] = init_marker( "APP5", "application data section  5", "JPEG 1997" );
232   marker[0xe6] = init_marker( "APP6", "application data section  6", "JPEG 1997" );
233   marker[0xe7] = init_marker( "APP7", "application data section  7", "JPEG 1997" );
234   marker[0xe8] = init_marker( "APP8", "application data section  8", "JPEG 1997" );
235   marker[0xe9] = init_marker( "APP9", "application data section  9", "JPEG 1997" );
236   marker[0xea] = init_marker( "APP10", "application data section 10", "JPEG 1997" );
237   marker[0xeb] = init_marker( "APP11", "application data section 11", "JPEG 1997" );
238   marker[0xec] = init_marker( "APP12", "application data section 12", "JPEG 1997" );
239   marker[0xed] = init_marker( "APP13", "application data section 13", "JPEG 1997" );
240   marker[0xee] = init_marker( "APP14", "application data section 14", "JPEG 1997" );
241   marker[0xef] = init_marker( "APP15", "application data section 15", "JPEG 1997" );
242       /* extention data sections */
243   marker[0xf0] = init_marker( "JPG0", "extension data 00", "JPEG 1997" );
244   marker[0xf1] = init_marker( "JPG1", "extension data 01", "JPEG 1997" );
245   marker[0xf2] = init_marker( "JPG2", "extension data 02", "JPEG 1997" );
246   marker[0xf3] = init_marker( "JPG3", "extension data 03", "JPEG 1997" );
247   marker[0xf4] = init_marker( "JPG4", "extension data 04", "JPEG 1997" );
248   marker[0xf5] = init_marker( "JPG5", "extension data 05", "JPEG 1997" );
249   marker[0xf6] = init_marker( "JPG6", "extension data 06", "JPEG 1997" );
250   marker[0xf7] = init_marker( "SOF48", "start of frame (JPEG-LS)", "JPEG-LS" );
251   marker[0xf8] = init_marker( "LSE", "extension parameters (JPEG-LS)", "JPEG-LS" );
252   marker[0xf9] = init_marker( "JPG9", "extension data 09", "JPEG 1997" );
253   marker[0xfa] = init_marker( "JPG10", "extension data 10", "JPEG 1997" );
254   marker[0xfb] = init_marker( "JPG11", "extension data 11", "JPEG 1997" );
255   marker[0xfc] = init_marker( "JPG12", "extension data 12", "JPEG 1997" );
256   marker[0xfd] = init_marker( "JPG13", "extension data 13", "JPEG 1997" );
257   marker[0xfe] = init_marker( "JCOM", "extension data (comment)", "JPEG 1997" );
258
259   /* JPEG 2000 - defined in IEC 15444-1 "JPEG 2000 Core (part 1)" */
260     /* delimiters */
261   marker[0x4f] = init_marker( "SOC", "start of codestream", "JPEG 2000" );
262   marker[0x90] = init_marker( "SOT", "start of tile", "JPEG 2000" );
263   marker[0xd9] = init_marker( "EOC", "end of codestream", "JPEG 2000" );
264       /* fixed information segment */
265   marker[0x51] = init_marker( "SIZ", "image and tile size", "JPEG 2000" );
266       /* functional segments */
267   marker[0x52] = init_marker( "COD", "coding style default", "JPEG 2000" );
268   marker[0x53] = init_marker( "COC", "coding style component", "JPEG 2000" );
269   marker[0x5e] = init_marker( "RGN", "region of interest", "JPEG 2000" );
270   marker[0x5c] = init_marker( "QCD", "quantization default", "JPEG 2000" );
271   marker[0x5d] = init_marker( "QCC", "quantization component", "JPEG 2000" );
272   marker[0x5f] = init_marker( "POC", "progression order change", "JPEG 2000" );
273       /* pointer segments */
274   marker[0x55] = init_marker( "TLM", "tile-part lengths", "JPEG 2000" );
275   marker[0x57] = init_marker( "PLM", "packet length (main header)", "JPEG 2000" );
276   marker[0x58] = init_marker( "PLT", "packet length (tile-part header)", "JPEG 2000" );
277   marker[0x60] = init_marker( "PPM", "packed packet headers (main header)", "JPEG 2000" );
278   marker[0x61] = init_marker( "PPT", "packed packet headers (tile-part header)", "JPEG 2000" );
279       /* bitstream internal markers and segments */
280   marker[0x91] = init_marker( "SOP", "start of packet", "JPEG 2000" );
281   marker[0x92] = init_marker( "EPH", "end of packet header", "JPEG 2000" );
282   marker[0x93] = init_marker( "SOD", "start of data", "JPEG 2000" );
283       /* informational segments */
284   marker[0x63] = init_marker( "CRG", "component registration", "JPEG 2000" );
285   marker[0x64] = init_marker( "COM", "comment", "JPEG 2000" );
286
287   return marker;
288 }
289
290 int read8(FILE* in)
291 {
292         unsigned char q[1];
293         fread(q, 1, 1, in);
294         return q[0];
295 }
296
297 /* read a 16 bit little-endian integer */
298 int read16(FILE *in)
299 {
300         unsigned char q[2];
301         fread(q, 1, 2, in);
302         return q[0] << 8 | q[1] << 0;
303 }
304
305 /* read a 32 bit little-endian integer */
306 int read32(FILE *in)
307 {
308         unsigned char q[4];
309         fread(q, 1, 4, in);
310         return q[0] << 24 | q[1] << 16 | q[2] << 8 | q[3] << 0;
311 }
312
313 /* write a 16 bit little-endian integer */
314 void write16(FILE *out, uint16_t p)
315 {
316         unsigned char q[2];
317         q[0] = p & 0xFF;
318         q[1] = (p >> 8) & 0xFF;
319         fwrite(q, 1, 2, out);
320         return;
321 }
322
323 /* write an 8 bit integer */
324 void write8(FILE *out, unsigned char p)
325 {
326         fwrite(&p, 1, 1, out);
327         return;
328 }
329
330 /* write a 32 bit little-endian integer */
331 void write32(FILE *out, uint32_t p)
332 {
333         unsigned char q[4];
334         q[0] = p & 0xFF;
335         q[1] = (p >> 8) & 0xFF;
336         q[2] = (p >> 16) & 0xFF;
337         q[3] = (p >> 24) & 0xFF;
338         fwrite(q, 1, 4, out);
339         return;
340 }
341
342 /* write a 32 bit big-endian integer */
343 void write_be32(FILE *out, uint32_t p)
344 {
345         unsigned char q[4];
346         q[0] = (p >> 24) & 0xFF;
347         q[1] = (p >> 16) & 0xFF;
348         q[2] = (p >> 8) & 0xFF;
349         q[3] = p & 0xFF;
350         fwrite(q, 1, 4, out);
351         return;
352 }
353
354 /* insert a 32 bit big-endian integer into a buffer */
355 void put_be32(unsigned char *p, uint32_t q)
356 {
357         p[0] = (q >> 24) & 0xFF;
358         p[1] = (q >> 16) & 0xFF;
359         p[2] = (q >> 8) & 0xFF;
360         p[3] = q & 0xFF;
361         return;
362 }
363
364 /* dump an abstract of a jpeg stream */
365 int dump_stream(FILE *out, FILE *in)
366 {
367     int c;
368     long offset = 0;
369     while (!feof(in)) {
370         c = fgetc(in);
371         if (c == 0xFF) {
372             int code = fgetc(in);
373             if (code > 0) {
374                 fprintf(out, "marker 0xff%02x %s at offset %ld", code, markers[code].mark, offset);
375                 fprintf(out, "\t(%s)\n", markers[code].name);
376                 if (strcmp (markers[code].mark, "SOT") == 0) {
377                         int const header_length = read16(in);
378                         printf("\tlength %d\n", header_length);
379                         printf("\ttile index %d\n", read16(in));
380                         int const tile_part_length = read32(in);
381                         printf("\ttile-part length %d\n", tile_part_length);
382                         printf("\ttile-part index %d\n", read8(in));
383                         printf("\tnumber of tile-parts %d\n", read8(in));
384                         printf("\t(skipping %d)\n", tile_part_length - header_length - 2);
385                         if (fseek (in, tile_part_length - header_length, SEEK_CUR) == -1) {
386                                 fprintf(stderr, "seek failed\n");
387                         }
388                 }
389             }
390             offset++;
391         }
392         offset++;
393     }
394
395     return 0;
396 }
397
398 void usage(const char *name, FILE *out)
399 {
400         fprintf(out, "usage: %s <file1.jpg> [<file2.jp2> ...]\n", name);
401         fprintf(out, "  dumps the structure of a JPEG codestream for inspection.\n");
402         return;
403 }
404
405 int main(int argc, char *argv[])
406 {
407         int i;
408         FILE *in;
409
410         if (argc < 2) usage(argv[0], stderr);
411
412         markers = init_markers();
413
414         /* treat the filename "-" as stdin */
415         if (argv[1][0] == '-' && argv[1][1] == 0)
416                 in = stdin;
417
418         for (i = 1; i < argc; i++) {
419                 const char *fn = argv[i];
420                 if (fn[0] == '-' && fn[1] == 0)
421                         in = stdin;
422                 else
423                         in = fopen(fn, "rb");
424                 if (in != NULL) {
425                         /* do something */
426                         dump_stream(stdout, in);
427                         if (in != stdin)
428                                 fclose(in);
429                 } else {
430                         fprintf(stderr, "could not open '%s'\n", argv[i]);
431                         return 1;
432                 }
433         }
434
435         return 0;
436 }