/[packages]/cauldron/dcraw/current/SOURCES/parse.c
ViewVC logotype

Contents of /cauldron/dcraw/current/SOURCES/parse.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 53152 - (show annotations) (download)
Thu Feb 17 16:09:23 2011 UTC (13 years, 1 month ago) by ahmad
File MIME type: text/plain
File size: 27371 byte(s)
imported package dcraw
1 /*
2 Raw Photo Parser
3 Copyright 2004-2006 by Dave Coffin, dcoffin a cybercom o net
4
5 This program displays raw metadata for all raw photo formats.
6 It is free for all uses.
7
8 $Revision: 1.66 $
9 $Date: 2008/01/19 06:01:47 $
10 */
11
12 #include <stdio.h>
13 #include <string.h>
14 #include <stdlib.h>
15 #include <ctype.h>
16
17 #ifdef WIN32
18 #include <winsock2.h>
19 typedef __int64 INT64;
20 #else
21 #include <netinet/in.h>
22 typedef long long INT64;
23 #endif
24
25 /*
26 TIFF and CIFF data blocks can be quite large.
27 Display only the first DLEN bytes.
28 */
29 #ifndef DLEN
30 #define DLEN 768
31 #endif
32
33 #define ushort UshORt
34 typedef unsigned char uchar;
35 typedef unsigned short ushort;
36
37 FILE *ifp;
38 short order;
39 char *fname, make[128], model[128], model2[128];
40 int is_dng;
41
42 ushort sget2 (uchar *s)
43 {
44 if (order == 0x4949) /* "II" means little-endian */
45 return s[0] | s[1] << 8;
46 else /* "MM" means big-endian */
47 return s[0] << 8 | s[1];
48 }
49 #define sget2(s) sget2((uchar *)s)
50
51 ushort get2()
52 {
53 uchar str[2] = { 0xff,0xff };
54 fread (str, 1, 2, ifp);
55 return sget2(str);
56 }
57
58 int sget4 (uchar *s)
59 {
60 if (order == 0x4949)
61 return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24;
62 else
63 return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3];
64 }
65 #define sget4(s) sget4((uchar *)s)
66
67 int get4()
68 {
69 uchar str[4] = { 0xff,0xff,0xff,0xff };
70 fread (str, 1, 4, ifp);
71 return sget4(str);
72 }
73
74 float int_to_float (int i)
75 {
76 union { int i; float f; } u;
77 u.i = i;
78 return u.f;
79 }
80
81 double get_double()
82 {
83 union { char c[8]; double d; } u;
84 int i, rev;
85
86 rev = 7 * ((order == 0x4949) == (ntohs(0x1234) == 0x1234));
87 for (i=0; i < 8; i++)
88 u.c[i ^ rev] = fgetc(ifp);
89 return u.d;
90 }
91
92 void tiff_dump(int base, int tag, int type, int count, int level)
93 {
94 int save, j, num, den;
95 uchar c;
96 int size[] = { 1,1,1,2,4,8,1,1,2,4,8,4,8 };
97
98 if (count * size[type < 13 ? type:0] > 4)
99 fseek (ifp, get4()+base, SEEK_SET);
100 save = ftell(ifp);
101 printf("%*stag=0x%x %d, type=%d, count=%d, offset=%06x, data=",
102 level*2, "", tag, tag, type, count, save);
103 if (tag == 34310) goto quit;
104 if (type==2) putchar('\"');
105 for (j = 0; j < count && j < DLEN; j++)
106 switch (type) {
107 case 1: case 6: case 7: /* byte values */
108 printf ("%c%02x",(j & 31) || count < 17 ? ' ':'\n', fgetc(ifp) & 0xff);
109 break;
110 case 2: /* null-terminated ASCII strings */
111 c = fgetc(ifp);
112 putchar(isprint(c) ? c:'.');
113 break;
114 case 3: case 8: /* word values */
115 printf ("%c%04x",(j & 15) || count < 9 ? ' ':'\n', get2());
116 break;
117 case 4: case 9: /* dword values */
118 printf ("%c%08x",(j & 7) || count < 5 ? ' ':'\n', get4());
119 break;
120 case 5: case 10: /* rationals */
121 num = get4();
122 den = get4();
123 printf (" %d/%d", num, den);
124 // printf (" %lf", (double) num/den);
125 break;
126 }
127 if (type==2) putchar('\"');
128 quit:
129 putchar('\n');
130 fseek (ifp, save, SEEK_SET);
131 }
132
133 void parse_nikon_capture_note (int length)
134 {
135 unsigned sorder, offset, tag, j, size;
136
137 puts (" Nikon Capture Note:");
138 sorder = order;
139 order = 0x4949;
140 fseek (ifp, 22, SEEK_CUR);
141 for (offset=22; offset+22 < length; offset += 22+size) {
142 tag = get4();
143 fseek (ifp, 14, SEEK_CUR);
144 size = get4()-4;
145 printf(" tag=0x%08x, size=%d", tag, size);
146 for (j=0; j < size; j++)
147 printf ("%s%02x", j & 31 ? " ":"\n\t", fgetc(ifp));
148 puts("");
149 }
150 order = sorder;
151 }
152
153 void nikon_decrypt (uchar ci, uchar cj, int tag, int i, int size, uchar *buf)
154 {
155 static const uchar xlat[2][256] = {
156 { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d,
157 0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d,
158 0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f,
159 0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f,
160 0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1,
161 0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17,
162 0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89,
163 0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f,
164 0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b,
165 0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb,
166 0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3,
167 0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f,
168 0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35,
169 0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43,
170 0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5,
171 0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 },
172 { 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c,
173 0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34,
174 0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad,
175 0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05,
176 0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee,
177 0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d,
178 0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b,
179 0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b,
180 0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc,
181 0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33,
182 0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8,
183 0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6,
184 0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c,
185 0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49,
186 0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb,
187 0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } };
188 uchar ck=0x60;
189
190 if (strncmp ((char *)buf, "02", 2)) return;
191 ci = xlat[0][ci];
192 cj = xlat[1][cj];
193 printf("Decrypted tag 0x%x:\n%*s", tag, (i & 31)*3, "");
194 for (; i < size; i++)
195 printf("%02x%c", buf[i] ^ (cj += ci * ck++), (i & 31) == 31 ? '\n':' ');
196 if (size & 31) puts("");
197 }
198
199 int parse_tiff_ifd (int base, int level);
200
201 void parse_makernote (int base, int level)
202 {
203 int offset=0, entries, tag, type, count, val, save;
204 unsigned serial=0, key=0;
205 uchar buf91[630]="", buf97[608]="", buf98[31]="";
206 short sorder;
207 char buf[10];
208
209 /*
210 The MakerNote might have its own TIFF header (possibly with
211 its own byte-order!), or it might just be a table.
212 */
213 sorder = order;
214 fread (buf, 1, 10, ifp);
215 if (!strcmp (buf,"Nikon")) { /* starts with "Nikon\0\2\0\0\0" ? */
216 base = ftell(ifp);
217 order = get2(); /* might differ from file-wide byteorder */
218 val = get2(); /* should be 42 decimal */
219 offset = get4();
220 fseek (ifp, offset-8, SEEK_CUR);
221 } else if (!strcmp (buf,"OLYMPUS")) {
222 base = ftell(ifp)-10;
223 fseek (ifp, -2, SEEK_CUR);
224 order = get2();
225 val = get2();
226 } else if (!strncmp (buf,"FUJIFILM",8) ||
227 !strncmp (buf,"SONY",4) ||
228 !strcmp (buf,"Panasonic")) {
229 order = 0x4949;
230 fseek (ifp, 2, SEEK_CUR);
231 } else if (!strcmp (buf,"OLYMP") ||
232 !strcmp (buf,"LEICA") ||
233 !strcmp (buf,"Ricoh") ||
234 !strcmp (buf,"EPSON"))
235 fseek (ifp, -2, SEEK_CUR);
236 else if (!strcmp (buf,"AOC"))
237 fseek (ifp, -4, SEEK_CUR);
238 else
239 fseek (ifp, -10, SEEK_CUR);
240
241 entries = get2();
242 if (entries > 100) return;
243 puts(" MakerNote:");
244 while (entries--) {
245 save = ftell(ifp);
246 tag = get2();
247 type = get2();
248 count= get4();
249 tiff_dump (base, tag, type, count, level);
250 if ((tag == 0x11 && !strncmp(make,"NIKON",5)) || type == 13) {
251 fseek (ifp, get4()+base, SEEK_SET);
252 parse_tiff_ifd (base, level+1);
253 }
254 if (tag == 0x1d)
255 while ((val = fgetc(ifp)) && val != EOF)
256 serial = serial*10 + (isdigit(val) ? val - '0' : val % 10);
257 if (tag == 0x91)
258 fread (buf91, sizeof buf91, 1, ifp);
259 if (tag == 0x97)
260 fread (buf97, sizeof buf97, 1, ifp);
261 if (tag == 0x98)
262 fread (buf98, sizeof buf98, 1, ifp);
263 if (tag == 0xa7)
264 key = fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp);
265 if (!strcmp (buf,"OLYMP") && tag >> 8 == 0x20)
266 parse_tiff_ifd (base, level+1);
267 if (tag == 0xe01)
268 parse_nikon_capture_note (count);
269 if (tag == 0xb028) {
270 fseek (ifp, get4(), SEEK_SET);
271 parse_tiff_ifd (base, level+1);
272 }
273 fseek (ifp, save+12, SEEK_SET);
274 }
275 nikon_decrypt (serial, key, 0x91, 4, sizeof buf91, buf91);
276 if (!strncmp ((char *)buf97, "0205", 4))
277 nikon_decrypt (serial, key, 0x97, 4, 284, buf97);
278 else
279 nikon_decrypt (serial, key, 0x97, 284, sizeof buf97, buf97);
280 nikon_decrypt (serial, key, 0x98, 4, sizeof buf98, buf98);
281 order = sorder;
282 }
283
284 void parse_exif (int base, int level)
285 {
286 int entries, tag, type, count, save;
287
288 puts("EXIF table:");
289 entries = get2();
290 while (entries--) {
291 save = ftell(ifp);
292 tag = get2();
293 type = get2();
294 count= get4();
295 tiff_dump (base, tag, type, count, level);
296 if (tag == 0x927c)
297 parse_makernote (base, level+1);
298 fseek (ifp, save+12, SEEK_SET);
299 }
300 }
301
302 void parse_mos(int level);
303
304 void sony_decrypt (unsigned *data, int len, int start, int key)
305 {
306 static unsigned pad[128], p;
307
308 if (start) {
309 for (p=0; p < 4; p++)
310 pad[p] = key = key * 48828125 + 1;
311 pad[3] = pad[3] << 1 | (pad[0]^pad[2]) >> 31;
312 for (p=4; p < 127; p++)
313 pad[p] = (pad[p-4]^pad[p-2]) << 1 | (pad[p-3]^pad[p-1]) >> 31;
314 for (p=0; p < 127; p++)
315 pad[p] = htonl(pad[p]);
316 }
317 while (len--)
318 *data++ ^= pad[p++ & 127] = pad[(p+1) & 127] ^ pad[(p+65) & 127];
319 }
320
321 int parse_tiff_ifd (int base, int level)
322 {
323 int entries, tag, type, count, slen, save, save2, i;
324 unsigned *buf, sony_offset=0, sony_length=0, sony_key=0;
325 FILE *sfp;
326
327 entries = get2();
328 if (entries > 1024) return 1;
329 while (entries--) {
330 save = ftell(ifp);
331 tag = get2();
332 type = get2();
333 count= get4();
334 slen = count;
335 if (slen > 128) slen = 128;
336 tiff_dump (base, tag, type, count, level);
337 switch (tag) {
338 case 0x10f: /* Make tag */
339 fgets (make, slen, ifp);
340 break;
341 case 0x110: /* Model tag */
342 fgets (model, slen, ifp);
343 break;
344 case 33405: /* Model2 tag */
345 fgets (model2, slen, ifp);
346 break;
347 case 0x14a: /* SubIFD tag */
348 save2 = ftell(ifp);
349 for (i=0; i < count; i++) {
350 printf ("SubIFD #%d:\n", i+1);
351 fseek (ifp, save2 + i*4, SEEK_SET);
352 fseek (ifp, get4()+base, SEEK_SET);
353 parse_tiff_ifd (base, level+1);
354 }
355 break;
356 case 29184: sony_offset = get4(); break;
357 case 29185: sony_length = get4(); break;
358 case 29217: sony_key = get4(); break;
359 case 33424:
360 puts("Kodak private data:");
361 fseek (ifp, get4()+base, SEEK_SET);
362 parse_tiff_ifd (base, level+1);
363 break;
364 case 34310:
365 parse_mos(0);
366 break;
367 case 34665:
368 fseek (ifp, get4()+base, SEEK_SET);
369 parse_exif (base, level+1);
370 break;
371 case 34853:
372 puts("GPS data:");
373 fseek (ifp, get4()+base, SEEK_SET);
374 parse_tiff_ifd (base, level+1);
375 break;
376 case 50459:
377 i = order;
378 save2 = ftell(ifp);
379 order = get2();
380 fseek (ifp, save2 + (get2(),get4()), SEEK_SET);
381 parse_tiff_ifd (save2, level+1);
382 order = i;
383 break;
384 case 50706:
385 is_dng = 1;
386 break;
387 case 50740:
388 if (count != 4 || type != 1) break;
389 puts("Sony SR2 private IFD:");
390 fseek (ifp, get4()+base, SEEK_SET);
391 parse_tiff_ifd (base, level+1);
392 }
393 fseek (ifp, save+12, SEEK_SET);
394 }
395 if (sony_length && (buf = malloc(sony_length))) {
396 fseek (ifp, sony_offset, SEEK_SET);
397 fread (buf, sony_length, 1, ifp);
398 sony_decrypt (buf, sony_length/4, 1, sony_key);
399 sfp = ifp;
400 if ((ifp = tmpfile())) {
401 fwrite (buf, sony_length, 1, ifp);
402 fseek (ifp, 0, SEEK_SET);
403 puts ("Sony SR2 encrypted IFD:");
404 parse_tiff_ifd (-sony_offset, level);
405 fclose (ifp);
406 }
407 ifp = sfp;
408 free (buf);
409 }
410 return 0;
411 }
412
413 /*
414 Parse a TIFF file looking for camera model and decompress offsets.
415 */
416 void parse_tiff (int base)
417 {
418 int doff, ifd=0;
419
420 fseek (ifp, base, SEEK_SET);
421 order = get2();
422 if (order != 0x4949 && order != 0x4d4d) return;
423 get2();
424 while ((doff = get4())) {
425 fseek (ifp, doff+base, SEEK_SET);
426 printf ("IFD #%d:\n", ifd++);
427 if (parse_tiff_ifd (base, 0)) break;
428 }
429 }
430
431 void parse_minolta()
432 {
433 int data_offset, save, tag, len;
434
435 fseek (ifp, 4, SEEK_SET);
436 data_offset = get4() + 8;
437 while ((save=ftell(ifp)) < data_offset) {
438 tag = get4();
439 len = get4();
440 printf ("Tag %c%c%c offset %06x length %06x\n",
441 tag>>16, tag>>8, tag, save, len);
442 switch (tag) {
443 case 0x545457: /* TTW */
444 parse_tiff (ftell(ifp));
445 }
446 fseek (ifp, save+len+8, SEEK_SET);
447 }
448 }
449
450 /*
451 Parse the CIFF structure.
452 */
453 void parse_ciff (int offset, int length, int level)
454 {
455 int tboff, nrecs, i, j, type, len, dlen, roff, aoff=0, save;
456 char c, name[256];
457 ushort key[2];
458
459 fseek (ifp, offset+length-4, SEEK_SET);
460 tboff = get4() + offset;
461 fseek (ifp, tboff, SEEK_SET);
462 nrecs = get2();
463 if (nrecs > 100) return;
464 printf ("%*s%d records:\n", level*2, "", nrecs);
465 for (i = 0; i < nrecs; i++) {
466 save = ftell(ifp);
467 type = get2();
468 printf ("%*stype=0x%04x", level*2, "", type);
469 if (type & 0x4000) {
470 len = 8;
471 type &= 0x3fff;
472 } else {
473 len = get4();
474 roff = get4();
475 aoff = offset + roff;
476 printf (", length=%d, reloff=%d, absoff=%d",
477 len, roff, aoff);
478 fseek (ifp, aoff, SEEK_SET);
479 }
480 if ((type & 0xe700) == 0)
481 printf (", data=");
482 if (type == 0x0032) /* display as words */
483 type |= 0x1000;
484 dlen = len < DLEN ? len:DLEN;
485 switch (type >> 8) {
486 case 0x28:
487 case 0x30:
488 putchar('\n');
489 parse_ciff (aoff, len, level+1);
490 fseek (ifp, save+10, SEEK_SET);
491 continue;
492 case 0x00: /* byte values */
493 for (j = 0; j < dlen; j++)
494 printf ("%c%02x",(j & 31) || dlen < 16 ? ' ':'\n', fgetc(ifp) & 0xff);
495 break;
496 case 0x08: /* null-terminated ASCII strings */
497 putchar('\"');
498 for (j = 0; j < dlen; j++) {
499 c = fgetc(ifp);
500 putchar( isprint(c) ? c:'.');
501 }
502 putchar('\"');
503 break;
504 case 0x10: /* word values */
505 key[0] = get2();
506 fseek (ifp, -2, SEEK_CUR);
507 if (type == 0x1032 && key[0] == 1040)
508 key[1] = 17907;
509 else key[0] = key[1] = 0;
510 for (j = 0; j < dlen; j+=2)
511 printf ("%c%5u",(j & 31) || dlen < 16 ? ' ':'\n',
512 get2() ^ key[(j >> 1) & 1]);
513 break;
514 case 0x18: /* dword values */
515 for (j = 0; j < dlen; j+=4)
516 printf ("%c%08x",(j & 31) || dlen < 16 ? ' ':'\n', get4());
517 }
518 putchar('\n');
519 fseek (ifp, save+10, SEEK_SET);
520 if (type == 0x080a) { /* Get the camera name */
521 fseek (ifp, aoff, SEEK_SET);
522 fread (name, 256, 1, ifp);
523 strcpy (make, name);
524 strcpy (model, name + strlen(make)+1);
525 }
526 }
527 }
528
529 int parse_jpeg (int offset)
530 {
531 int len, save, hlen;
532
533 fseek (ifp, offset, SEEK_SET);
534 if (fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) return 0;
535
536 while (fgetc(ifp) == 0xff && fgetc(ifp) >> 4 != 0xd) {
537 order = 0x4d4d;
538 len = get2() - 2;
539 save = ftell(ifp);
540 order = get2();
541 hlen = get4();
542 if (get4() == 0x48454150) /* "HEAP" */
543 parse_ciff (save+hlen, len-hlen, 0);
544 parse_tiff (save+6);
545 fseek (ifp, save+len, SEEK_SET);
546 }
547 return 1;
548 }
549
550 void parse_riff (int level)
551 {
552 unsigned i, size, end, save;
553 char tag[4], type[4], buf[64];
554
555 order = 0x4949;
556 fread (tag, 4, 1, ifp);
557 size = get4();
558 if (isdigit(tag[0])) {
559 fseek (ifp, size, SEEK_CUR);
560 return;
561 }
562 printf ("%*.4s size %d", level*4+4, tag, size);
563 if (!memcmp(tag,"RIFF",4) || !memcmp(tag,"LIST",4)) {
564 end = ftell(ifp) + size;
565 fread (type, 4, 1, ifp);
566 printf (" type %.4s:\n", type);
567 while (ftell(ifp) < end)
568 parse_riff (level+1);
569 } else {
570 save = ftell(ifp);
571 fread (buf, 1, 40, ifp);
572 printf (": ");
573 for (i=0; i < 40 && isprint(buf[i]); i++)
574 putchar (buf[i]);
575 putchar ('\n');
576 fseek (ifp, save+size, SEEK_SET);
577 }
578 }
579
580 void parse_mos(int level)
581 {
582 char data[256];
583 int i, skip, save;
584 char *cp;
585
586 save = ftell(ifp);
587 while (1) {
588 if (get4() != 0x504b5453) break;
589 get4();
590 printf ("%*sPKTS ", level, "");
591 fread (data, 1, 40, ifp);
592 skip = get4();
593 printf ("%s %d bytes: ", data, skip);
594 if (!strcmp(data,"pattern_ratation_angle")) {
595 printf ("%d\n", get2());
596 continue;
597 }
598 if (!strcmp(data,"icc_camera_to_tone_matrix")) {
599 for (i=0; i < skip/4; i++)
600 printf ("%f ", int_to_float(get4()));
601 putchar('\n');
602 continue;
603 }
604 fread (data, 1, sizeof data, ifp);
605 fseek (ifp, -sizeof data, SEEK_CUR);
606 data[sizeof data - 1] = 0;
607 while ((cp=strchr(data,'\n')))
608 *cp = ' ';
609 printf ("%s\n",data);
610 parse_mos(level+2);
611 fseek (ifp, skip, SEEK_CUR);
612 }
613 fseek (ifp, save, SEEK_SET);
614 }
615
616 void parse_rollei()
617 {
618 char line[128], *val;
619
620 fseek (ifp, 0, SEEK_SET);
621 do {
622 fgets (line, 128, ifp);
623 fputs (line, stdout);
624 if ((val = strchr(line,'=')))
625 *val++ = 0;
626 else
627 val = line + strlen(line);
628 } while (strncmp(line,"EOHD",4));
629 strcpy (make, "Rollei");
630 strcpy (model, "d530flex");
631 }
632
633 void get_utf8 (int offset, char *buf, int len)
634 {
635 ushort c;
636 char *cp;
637
638 fseek (ifp, offset, SEEK_SET);
639 for (cp=buf; (c = get2()) && cp+3 < buf+len; ) {
640 if (c < 0x80)
641 *cp++ = c;
642 else if (c < 0x800) {
643 *cp++ = 0xc0 + (c >> 6);
644 *cp++ = 0x80 + (c & 0x3f);
645 } else {
646 *cp++ = 0xe0 + (c >> 12);
647 *cp++ = 0x80 + (c >> 6 & 0x3f);
648 *cp++ = 0x80 + (c & 0x3f);
649 }
650 }
651 *cp = 0;
652 }
653
654 void parse_foveon()
655 {
656 unsigned entries, off, len, tag, save, i, j, k, pent, poff[256][2];
657 char name[128], value[128], camf[0x20000], *pos, *cp, *dp;
658 unsigned val, key, type, num, ndim, dim[3];
659
660 order = 0x4949; /* Little-endian */
661 fseek (ifp, -4, SEEK_END);
662 fseek (ifp, get4(), SEEK_SET);
663 if (get4() != 0x64434553) { /* SECd */
664 printf ("Bad Section identifier at %6x\n", (int)ftell(ifp)-4);
665 return;
666 }
667 get4();
668 entries = get4();
669 while (entries--) {
670 off = get4();
671 len = get4();
672 tag = get4();
673 save = ftell(ifp);
674 fseek (ifp, off, SEEK_SET);
675 printf ("%c%c%c%c at offset %06x, length %06x, ",
676 tag, tag >> 8, tag >> 16, tag >> 24, off, len);
677 if (get4() != (0x20434553 | (tag << 24))) {
678 printf ("Bad Section identifier at %6x\n", off);
679 return;
680 }
681 val = get4();
682 printf ("version %d.%d, ",val >> 16, val & 0xffff);
683 switch (tag) {
684 case 0x32414d49: /* IMA2 */
685 case 0x47414d49: /* IMAG */
686 printf ("type %d, " , get4());
687 printf ("format %2d, " , get4());
688 printf ("columns %4d, " , get4());
689 printf ("rows %4d, " , get4());
690 printf ("rowsize %d\n" , get4());
691 parse_jpeg (off+28);
692 order = 0x4949;
693 break;
694 case 0x464d4143: /* CAMF */
695 printf ("type %d, ", get4());
696 get4();
697 for (i=0; i < 4; i++)
698 putchar(fgetc(ifp));
699 val = get4();
700 printf (" version %d.%d:\n",val >> 16, val & 0xffff);
701 key = get4();
702 if ((len -= 28) > 0x20000)
703 len = 0x20000;
704 fread (camf, 1, len, ifp);
705 for (i=0; i < len; i++) {
706 key = (key * 1597 + 51749) % 244944;
707 val = key * (INT64) 301593171 >> 24;
708 camf[i] ^= ((((key << 8) - val) >> 1) + val) >> 17;
709 }
710 for (pos=camf; (unsigned) (pos-camf) < len; pos += sget4(pos+8)) {
711 if (strncmp (pos, "CMb", 3)) {
712 printf("Bad CAMF tag \"%.4s\"\n", pos);
713 break;
714 }
715 val = sget4(pos+4);
716 printf (" %4.4s version %d.%d: ", pos, val >> 16, val & 0xffff);
717 switch (pos[3]) {
718 case 'M':
719 cp = pos + sget4(pos+16);
720 type = sget4(cp);
721 ndim = sget4(cp+4);
722 dim[0] = dim[1] = dim[2] = 1;
723 printf ("%d-dimensonal array %s of type %d:\n Key: (",
724 ndim, pos+sget4(pos+12), sget4(cp));
725 dp = pos + sget4(cp+8);
726 for (i=ndim; i--; ) {
727 cp += 12;
728 dim[i] = sget4(cp);
729 printf ("%s %d%s", pos+sget4(cp+4), dim[i], i ? ", ":")\n");
730 }
731 for (i=0; i < dim[2]; i++) {
732 for (j=0; j < dim[1]; j++) {
733 printf (" ");
734 for (k=0; k < dim[0]; k++)
735 switch (type) {
736 case 5:
737 printf ("%7d", *(uchar *)dp++);
738 break;
739 case 0:
740 case 6:
741 printf ("%7d", (short) sget2(dp));
742 dp += 2;
743 break;
744 case 1:
745 case 2:
746 printf (" %d", sget4(dp));
747 dp += 4;
748 break;
749 case 3:
750 val = sget4(dp);
751 printf (" %9f", int_to_float(val));
752 dp += 4;
753 }
754 printf ("\n");
755 }
756 printf ("\n");
757 }
758 break;
759 case 'P':
760 val = sget4(pos+16);
761 num = sget4(pos+val);
762 printf ("%s, %d parameters:\n", pos+sget4(pos+12), num);
763 cp = pos+val+8 + num*8;
764 for (i=0; i < num; i++) {
765 val += 8;
766 printf (" %s = %s\n", cp+sget4(pos+val), cp+sget4(pos+val+4));
767 }
768 break;
769 case 'T':
770 cp = pos + sget4(pos+16);
771 printf ("%s = %.*s\n", pos+sget4(pos+12), sget4(cp), cp+4);
772 break;
773 default:
774 printf ("\n");
775 }
776 }
777 break;
778 case 0x504f5250: /* PROP */
779 printf ("entries %d, ", pent=get4());
780 printf ("charset %d, ", get4());
781 get4();
782 printf ("nchars %d\n", get4());
783 off += pent*8 + 24;
784 if ((unsigned) pent > 256) pent=256;
785 for (i=0; i < pent*2; i++)
786 poff[0][i] = off + get4()*2;
787 for (i=0; i < pent; i++) {
788 get_utf8 (poff[i][0], name, 128);
789 get_utf8 (poff[i][1], value, 128);
790 printf (" %s = %s\n", name, value);
791 if (!strcmp (name,"CAMMANUF"))
792 strcpy (make, value);
793 if (!strcmp (name,"CAMMODEL"))
794 strcpy (model, value);
795 }
796 }
797 fseek (ifp, save, SEEK_SET);
798 }
799 }
800
801 void parse_fuji (int offset)
802 {
803 int entries, tag, len;
804
805 fseek (ifp, offset, SEEK_SET);
806 if (!(len = get4())) return;
807 printf ("Fuji table at %d:\n",len);
808 fseek (ifp, len, SEEK_SET);
809 entries = get4();
810 if (entries > 255) return;
811 while (entries--) {
812 tag = get2();
813 len = get2();
814 printf ("Fuji tag=0x%x, len=%d, data =",tag,len);
815 while (len--)
816 printf (" %02x",fgetc(ifp));
817 putchar ('\n');
818 }
819 }
820
821 void parse_phase_one (int base)
822 {
823 unsigned entries, tag, type, len, data, save;
824 unsigned meta=0, wide=0, high=0, i, j;
825 char str[256];
826
827 fseek (ifp, base, SEEK_SET);
828 order = get4() & 0xffff;
829 if (get4() >> 8 != 0x526177) return;
830 fseek (ifp, base+get4(), SEEK_SET);
831 entries = get4();
832 get4();
833 while (entries--) {
834 tag = get4();
835 type = get4();
836 len = get4();
837 data = get4();
838 save = ftell(ifp);
839 printf ("Phase One tag=0x%x, type=%d, len=%2d, data = 0x%x",
840 tag, type, len, data);
841 if (type == 4 && len == 4 && data > 0xfffffff)
842 printf (" = %f", int_to_float(data));
843 putchar ('\n');
844 if (tag == 0x110) meta = base+data;
845 if (len > 4)
846 fseek (ifp, base+data, SEEK_SET);
847 if (type == 1 && len < 256) {
848 fread (str, 256, 1, ifp);
849 puts (str);
850 }
851 if (tag != 0x21c && type == 4 && len > 4) {
852 for ( ; len > 0; len -= 4)
853 printf ("%f ", int_to_float(get4()));
854 puts ("");
855 }
856 fseek (ifp, save, SEEK_SET);
857 }
858 strcpy (make, "Phase One");
859 strcpy (model, "unknown");
860 if (!meta) return;
861 fseek (ifp, meta, SEEK_SET);
862 order = get2();
863 fseek (ifp, 6, SEEK_CUR);
864 fseek (ifp, meta+get4(), SEEK_SET);
865 entries = get4();
866 get4();
867 while (entries--) {
868 tag = get4();
869 len = get4();
870 data = get4();
871 save = ftell(ifp);
872 printf ("Phase One meta tag=0x%x, len=%2d, offset = 0x%x, data = ",
873 tag, len, data);
874 if (!((0x000801f4 >> (tag-0x400)) & 1)) putchar ('\n');
875 fseek (ifp, meta+data, SEEK_SET);
876 switch (tag) {
877 case 0x400:
878 for (i=0; i < len; i+=2)
879 printf ("%5u%c", get2(), (i & 6) == 6 || i == len-2 ? '\n':' ');
880 break;
881 case 0x401:
882 for (i=0; i < 16; i+=2)
883 printf ("%6u%c", get2(), (i & 14) == 14 || i == len-2 ? '\n':' ');
884 for (; i < len; i+=4)
885 printf ("%9.6f%c", int_to_float(get4()),
886 (i & 28) == 12 || i == len-4 ? '\n':' ');
887 break;
888 case 0x402:
889 printf ("%f\n", int_to_float (data));
890 break;
891 case 0x404: case 0x405: case 0x406: case 0x407:
892 fread (str, 256, 1, ifp);
893 puts (str);
894 break;
895 case 0x408: case 0x413:
896 printf ("%lf\n", get_double());
897 break;
898 case 0x40b: case 0x410: case 0x416:
899 for (i=0; i < len; i+=2)
900 printf ("%6u%c", get2(), (i & 14) == 14 || i == len-2 ? '\n':' ');
901 break;
902 case 0x40f: case 0x418: case 0x419: case 0x41a:
903 for (i=0; i < 4; i++)
904 printf ("%02X%c", fgetc(ifp), i == 3 ? '\n':' ');
905 for (; i < len; i+=4)
906 printf ("%e%c", int_to_float(get4()), i == len-4 ? '\n':' ');
907 break;
908 case 0x412:
909 for (i=0; i < 36; i+=4) {
910 printf ("%u ", j=get4());
911 if (i == 4) wide = j;
912 if (i == 12) high = j*2;
913 }
914 printf ("%u\n", get2());
915 for (i=0; i < wide*high; i++)
916 printf ("%9.6f%c", int_to_float(get4()),
917 i % wide == wide-1 ? '\n':' ');
918 for (i=0; i < wide*high; i++)
919 printf ("%5u%c", get2(), i % wide == wide-1 ? '\n':' ');
920 break;
921 default:
922 for (i=0; i < len; i++)
923 printf ("%02X%c", fgetc(ifp),
924 (i & 15) == 15 || i == len-1 ? '\n':' ');
925 }
926 fseek (ifp, save, SEEK_SET);
927 }
928 }
929
930 char *memmem (char *haystack, size_t haystacklen,
931 char *needle, size_t needlelen)
932 {
933 char *c;
934 for (c = haystack; c <= haystack + haystacklen - needlelen; c++)
935 if (!memcmp (c, needle, needlelen))
936 return c;
937 return NULL;
938 }
939
940 /*
941 Identify which camera created this file, and set global variables
942 accordingly. Return nonzero if the file cannot be decoded.
943 */
944 void identify()
945 {
946 char head[32], *cp;
947 unsigned hlen, fsize, toff, tlen;
948
949 make[0] = model[0] = model2[0] = is_dng = 0;
950 order = get2();
951 hlen = get4();
952 fseek (ifp, 0, SEEK_SET);
953 fread (head, 1, 32, ifp);
954 fseek (ifp, 0, SEEK_END);
955 fsize = ftell(ifp);
956 if ((cp = memmem (head, 32, "MMMM", 4)) ||
957 (cp = memmem (head, 32, "IIII", 4))) {
958 parse_phase_one (cp-head);
959 if (cp-head) parse_tiff (0);
960 } else if (order == 0x4949 || order == 0x4d4d) {
961 if (!memcmp(head+6,"HEAPCCDR",8)) {
962 parse_ciff (hlen, fsize - hlen, 0);
963 fseek (ifp, hlen, SEEK_SET);
964 } else
965 parse_tiff (0);
966 } else if (!memcmp (head,"NDF0",4)) {
967 parse_tiff (12);
968 } else if (!memcmp (head,"\0MRM",4)) {
969 parse_minolta();
970 } else if (!memcmp (head,"FUJIFILM",8)) {
971 fseek (ifp, 84, SEEK_SET);
972 toff = get4();
973 tlen = get4();
974 parse_fuji (92);
975 if (toff > 120) parse_fuji (120);
976 parse_tiff (toff+12);
977 } else if (!memcmp (head,"RIFF",4)) {
978 fseek (ifp, 0, SEEK_SET);
979 parse_riff(0);
980 } else if (!memcmp (head,"DSC-Image",9))
981 parse_rollei();
982 else if (!memcmp (head,"FOVb",4))
983 parse_foveon();
984 parse_jpeg(0);
985 }
986
987 int main(int argc, char **argv)
988 {
989 int arg;
990
991 if (argc == 1)
992 {
993 fprintf (stderr,
994 "\nRaw Photo Parser"
995 "\nby Dave Coffin, dcoffin a cybercom o net"
996 "\n\nUsage: %s file1.crw file2.crw ...\n", argv[0]);
997 return 1;
998 }
999 for (arg=1; arg < argc; arg++)
1000 {
1001 fname = argv[arg];
1002 ifp = fopen (fname,"rb");
1003 if (!ifp) {
1004 perror (fname);
1005 continue;
1006 }
1007 printf ("\nParsing %s:\n", fname);
1008 identify();
1009 fclose (ifp);
1010 }
1011 return 0;
1012 }

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.30