1 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
2 /* EXIFPROBE - TIFF/JPEG/EXIF image file probe */
3 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
4 /* Copyright (C) 2002,2005 by Duane H. Hesser. All rights reserved. */
5 /* */
6 /* See the file LICENSE.EXIFPROBE for terms of use. */
7 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
8
9 #ifndef lint
10 static char *ModuleId = "@(#) $Id: mrw.c,v 1.11 2005/07/24 20:27:36 alex Exp $";
11 #endif
12
13 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
14 /* Minolta MRW routines */
15 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
16 /* The information coded here is derived from information reported */
17 /* by Dalibor Jelinek at: */
18 /* http://www.dalibor.cz/minolta/raw_file_format.htm */
19 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
20
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <time.h>
25 #include <math.h>
26
27 #include "defs.h"
28 #include "datadefs.h"
29 #include "summary.h"
30 #include "maker.h"
31 #include "misc.h"
32 #include "tags.h"
33 #include "extern.h"
34 #include "mrw.h"
35
36
37 /* Print the (rather simple) MRW header information. */
38
39 int
print_mrw_header(struct fileheader * fileheader,unsigned long section_id)40 print_mrw_header(struct fileheader *fileheader,unsigned long section_id)
41 {
42 struct mrw_header mrwheader;
43 int status = -1;
44 int chpr = 0;
45
46 if(Print_options & section_id)
47 {
48 if(fileheader && (fileheader->probe_magic == PROBE_MRWMAGIC))
49 {
50 mrwheader = fileheader->mrw_header;
51 if(mrwheader.mrw_magic == PROBE_MRWMAGIC)
52 {
53 chpr += printf("MRW magic %#lx, length %u, offset to image data %lu",
54 mrwheader.mrw_magic,8,mrwheader.mrw_dataoffset + 8);
55 chpr = newline(chpr);
56 status = 0;
57 }
58 else
59 chpr += printf(" MRW HEADER MAGIC BAD");
60 }
61 else
62 chpr += printf(" NOT AN MRW HEADER");
63 }
64 chpr = newline(chpr);
65 return(status);
66 }
67
68 /* Process a Minolta (now Konica Minolta) MRW file, starting right */
69 /* after the MRM header. */
70
71 unsigned long
process_mrw(FILE * inptr,unsigned long offset,unsigned long data_offset,unsigned long data_length,struct image_summary * summary_entry,char * parent_name,int indent)72 process_mrw(FILE *inptr,unsigned long offset,unsigned long data_offset,
73 unsigned long data_length,struct image_summary *summary_entry,
74 char *parent_name,int indent)
75 {
76 char *blockname;
77 char *fulldirname = CNULL;
78 struct fileheader *header;
79 unsigned long blocklength,blockid;
80 unsigned long ifd_offset;
81 unsigned long max_offset = 0UL;
82 int chpr = 0;
83 int status = 0;
84
85 if(inptr && data_offset)
86 {
87 if((summary_entry == NULL) || summary_entry->entry_lock)
88 summary_entry = new_summary_entry(summary_entry,0,IMGFMT_MRW);
89 if(summary_entry)
90 {
91 /* This isn't strictly necessary, because we're going to */
92 /* do it again at the end, but allows the TIFF processor */
93 /* to avoid changing this stuff if it notices they're */
94 /* already set. */
95 if(summary_entry->length <= 0)
96 summary_entry->length = data_length;
97 if(summary_entry->offset <= 0)
98 summary_entry->offset = data_offset;
99 summary_entry->imageformat = IMGFMT_MRW;
100 summary_entry->imagesubformat = IMGSUBFMT_CFA;
101 /* Don't lock it here; the TIFF processor should use it */
102 /* (and lock it) */
103 }
104 chpr = newline(chpr);
105 while(offset < data_offset)
106 {
107 blockid = read_ulong(inptr,TIFF_MOTOROLA,offset);
108 blockname = read_string(inptr,offset+1,3);
109 blocklength = read_ulong(inptr,TIFF_MOTOROLA,HERE);
110 print_tag_address(SECTION,offset,indent,"@");
111 if(blockid != MRM_PAD)
112 offset += 8;
113 if((PRINT_SECTION))
114 {
115 chpr += printf("{%s} (%#lx) length %lu starting at offset %#lx/%lu",blockname,
116 blockid,blocklength,offset,offset);
117 chpr = newline(chpr);
118 }
119
120 if(Debug)
121 {
122 chpr = newline(chpr);
123 hexdump(inptr,offset,48,48,16,0,0);
124 chpr = newline(1);
125 }
126 switch(blockid)
127 {
128 case MRM_PRD:
129 max_offset = process_prd(inptr,offset,blocklength,summary_entry,indent);
130 offset += blocklength;
131 break;
132 case MRM_TTW:
133 header = read_imageheader(inptr,offset);
134 if(header && (header->probe_magic == PROBE_TIFFMAGIC))
135 {
136 ifd_offset = read_ulong(inptr,header->file_marker,HERE);
137 if(PRINT_SECTION)
138 {
139 print_tag_address(SECTION,offset,indent + 4,"@");
140 status = print_header(header,SECTION);
141 chpr += printf(" ifd offset = %#lx/%lu)",ifd_offset,ifd_offset);
142 if(offset)
143 {
144 chpr += printf(" (+ %lu = %#lx/%lu)",offset,offset + ifd_offset,
145 offset + ifd_offset);
146 }
147 chpr = newline(chpr);
148 }
149 fulldirname = splice(parent_name,".",blockname);
150 max_offset = process_tiff_ifd(inptr,header->file_marker,
151 ifd_offset,offset,offset + blocklength,summary_entry,
152 fulldirname,TIFF_IFD,0,-1,indent + 4);
153 if(max_offset > 0L)
154 status = 0;
155 max_offset = offset + blocklength;
156 fflush(stdout);
157 if(fulldirname)
158 free(fulldirname);
159 fulldirname = CNULL;
160 }
161 else
162 chpr += printf(" NOT A TIFF HEADER");
163 offset += blocklength;
164 break;
165 case MRM_WBG:
166 max_offset = process_wbg(inptr,offset,blocklength,summary_entry,indent);
167 offset += blocklength;
168 break;
169 case MRM_RIF:
170 max_offset = process_rif(inptr,offset,blocklength,summary_entry,indent);
171 offset += blocklength;
172 break;
173 case MRM_PAD:
174 offset += blocklength;
175 max_offset = offset;
176 break;
177 default:
178 offset += blocklength;
179 max_offset = offset - 8;
180 break;
181 }
182 chpr = newline(0);
183 if((PRINT_SECTION))
184 {
185 print_tag_address(SECTION,max_offset - 1,indent,"@");
186 chpr += printf("{/%s}",blockname ? blockname : "UNK");
187 }
188 chpr = newline(chpr);
189 }
190 if((PRINT_SECTION))
191 {
192 print_tag_address(SECTION,data_offset,indent,"@");
193 chpr += printf("MRW (CFA) data length %lu",data_length);
194 chpr = newline(chpr);
195 dumpsection(inptr,data_offset,data_length,indent + SMALLINDENT);
196 print_tag_address(SECTION,data_offset + data_length - 1,indent,"@");
197 chpr += printf("End of MRW data");
198 }
199 chpr = newline(chpr);
200 /* Fix up any damage done by the TIFF IFD... */
201 /* This information supercedes anything the TIFF processor */
202 /* may have done...image processing software can trash the */
203 /* TIFF structure (and some do), but this is basic */
204 /* information from the MRW header. */
205 if(summary_entry)
206 {
207 summary_entry->length = data_length;
208 summary_entry->offset = data_offset;
209 summary_entry->imageformat = IMGFMT_MRW;
210 summary_entry->imagesubformat = IMGSUBFMT_CFA;
211 /* The TIFF processor should have locked it, but make */
212 /* sure */
213 summary_entry->entry_lock = lock_number(summary_entry);
214 }
215 }
216 return(data_offset + data_length);
217 }
218
219 #define SHORTNAMEWIDTH 20
220 #define LONGNAMEWIDTH 24
221
222 unsigned long
process_prd(FILE * inptr,unsigned long offset,unsigned long blocklength,struct image_summary * summary_entry,int indent)223 process_prd(FILE *inptr,unsigned long offset,unsigned long blocklength,
224 struct image_summary *summary_entry,int indent)
225 {
226 unsigned short ccd_height,ccd_width;
227 unsigned short image_height,image_width;
228 unsigned short datasize,pixelsize,storage_method;
229 unsigned short unknown1,unknown2,unknown3;
230 char *version;
231 int chpr = 0;
232
233 blocklength += offset;
234
235
236 chpr = newline(chpr);
237 version = (char *)read_bytes(inptr,8UL,offset);
238 if((PRINT_ENTRY))
239 {
240 print_tag_address(ENTRY,offset,indent + 4,"@");
241 if((PRINT_TAGINFO))
242 {
243 if((PRINT_LONGNAMES))
244 chpr += printf("%s","MRW.PRD.");
245 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"Version");
246 }
247 if((PRINT_VALUE))
248 chpr += printf(" = %8.8s",version);
249 chpr = newline(chpr);
250 }
251 offset += 8;
252 ccd_height = read_ushort(inptr,TIFF_MOTOROLA,offset);
253 ccd_width = read_ushort(inptr,TIFF_MOTOROLA,HERE);
254 if((PRINT_ENTRY))
255 {
256 print_tag_address(ENTRY,offset,indent + 4,"@");
257 if((LIST_MODE))
258 {
259 if((PRINT_TAGINFO))
260 {
261 if((PRINT_LONGNAMES))
262 chpr += printf("%s","MRW.PRD.");
263 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"ccdWidth");
264 }
265 if((PRINT_VALUE))
266 chpr += printf(" = %u",ccd_width);
267 chpr = newline(chpr);
268 print_tag_address(ENTRY,offset + 4,indent + 4,"@");
269 if((PRINT_TAGINFO))
270 {
271 if((PRINT_LONGNAMES))
272 chpr += printf("%s","MRW.PRD.");
273 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"ccdHeight");
274 }
275 if((PRINT_VALUE))
276 chpr += printf(" = %u",ccd_height);
277 }
278 else
279 {
280 if((PRINT_TAGINFO))
281 {
282 if((PRINT_LONGNAMES))
283 chpr += printf("%s","MRW.PRD.");
284 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"CCDSize");
285 }
286 if((PRINT_VALUE))
287 chpr += printf(" = %ux%u",ccd_width,ccd_height);
288 }
289 chpr = newline(chpr);
290 }
291 offset += 4;
292 image_height = read_ushort(inptr,TIFF_MOTOROLA,offset);
293 image_width = read_ushort(inptr,TIFF_MOTOROLA,HERE);
294 if((PRINT_ENTRY))
295 {
296 print_tag_address(ENTRY,offset,indent + 4,"@");
297 if((LIST_MODE))
298 {
299 if((PRINT_TAGINFO))
300 {
301 if((PRINT_LONGNAMES))
302 chpr += printf("%s","MRW.PRD.");
303 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"ImageWidth");
304 }
305 if((PRINT_VALUE))
306 chpr += printf(" = %u",image_width);
307 chpr = newline(chpr);
308 print_tag_address(ENTRY,offset + 4,indent + 4,"@");
309 if((PRINT_TAGINFO))
310 {
311 if((PRINT_LONGNAMES))
312 chpr += printf("%s","MRW.PRD.");
313 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"ImageHeight");
314 }
315 if((PRINT_VALUE))
316 chpr += printf(" = %u",image_height);
317 }
318 else
319 {
320 if((PRINT_TAGINFO))
321 {
322 if((PRINT_LONGNAMES))
323 chpr += printf("%s","MRW.PRD.");
324 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"ImageSize");
325 }
326 if((PRINT_VALUE))
327 chpr += printf(" = %ux%u",image_width,image_height);
328 }
329 chpr = newline(chpr);
330 /* This is also in the TIFF IFD0 */
331 if(summary_entry)
332 {
333 summary_entry->pixel_width = image_width;
334 summary_entry->pixel_height = image_height;
335 }
336 }
337 offset += 4;
338 datasize = read_ubyte(inptr,offset);
339 if(summary_entry)
340 {
341 summary_entry->sample_size = datasize;
342 summary_entry->spp = 1;
343 }
344 if((PRINT_ENTRY))
345 {
346 print_tag_address(ENTRY,offset,indent + 4,"@");
347 if((PRINT_TAGINFO))
348 {
349 if((PRINT_LONGNAMES))
350 chpr += printf("%s","MRW.PRD.");
351 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"DataSize");
352 }
353 if((PRINT_VALUE))
354 chpr += printf(" = %u",datasize);
355 chpr = newline(chpr);
356 }
357 ++offset;
358 pixelsize = read_ubyte(inptr,offset);
359 if(summary_entry)
360 summary_entry->bps[0] = (int)pixelsize;
361 if((PRINT_ENTRY))
362 {
363 print_tag_address(ENTRY,offset,indent + 4,"@");
364 if((PRINT_TAGINFO))
365 {
366 if((PRINT_LONGNAMES))
367 chpr += printf("%s","MRW.PRD.");
368 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"PixelSize");
369 }
370 if((PRINT_VALUE))
371 chpr += printf(" = %u",pixelsize);
372 chpr = newline(chpr);
373 }
374 ++offset;
375 storage_method = read_ubyte(inptr,offset);
376 if((PRINT_ENTRY))
377 {
378 print_tag_address(ENTRY,offset,indent + 4,"@");
379 if((PRINT_TAGINFO))
380 {
381 if((PRINT_LONGNAMES))
382 chpr += printf("%s","MRW.PRD.");
383 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"StorageMethod");
384 }
385 if((PRINT_VALUE))
386 chpr += printf(" = %#x/%u",storage_method,storage_method);
387 chpr = newline(chpr);
388 }
389 ++offset;
390 unknown1 = read_ubyte(inptr,offset);
391 if((PRINT_ENTRY))
392 {
393 print_tag_address(ENTRY,offset,indent + 4,"@");
394 if((PRINT_TAGINFO))
395 {
396 if((PRINT_LONGNAMES))
397 chpr += printf("%s","MRW.PRD.");
398 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"unknown1");
399 }
400 if((PRINT_VALUE))
401 chpr += printf(" = %u",unknown1);
402 chpr = newline(chpr);
403 }
404 ++offset;
405 unknown2 = read_ushort(inptr,TIFF_MOTOROLA,offset);
406 if((PRINT_ENTRY))
407 {
408 print_tag_address(ENTRY,offset,indent + 4,"@");
409 if((PRINT_TAGINFO))
410 {
411 if((PRINT_LONGNAMES))
412 chpr += printf("%s","MRW.PRD.");
413 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"unknown2");
414 }
415 if((PRINT_VALUE))
416 chpr += printf(" = %u",unknown1);
417 chpr = newline(chpr);
418 }
419 offset += 2;
420 unknown3 = read_ushort(inptr,TIFF_MOTOROLA,offset);
421 if((PRINT_ENTRY))
422 {
423 print_tag_address(ENTRY,offset,indent + 4,"@");
424 if((PRINT_TAGINFO))
425 {
426 if((PRINT_LONGNAMES))
427 chpr += printf("%s","MRW.PRD.");
428 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"unknown3");
429 }
430 if((PRINT_VALUE))
431 chpr += printf(" = %u",unknown1);
432 chpr = newline(chpr);
433 }
434 offset += 2;
435 return(offset);
436 }
437
438 /* The White Balance blob. Weird stuff. */
439
440 unsigned long
process_wbg(FILE * inptr,unsigned long offset,unsigned long blocklength,struct image_summary * summary_entry,int indent)441 process_wbg(FILE *inptr,unsigned long offset,unsigned long blocklength,
442 struct image_summary *summary_entry,int indent)
443 {
444 unsigned short wbr_denom,wbg1_denom,wbg2_denom,wbb_denom;
445 unsigned short wbr_num,wbg1_num,wbg2_num,wbb_num;
446 double wbr,wbg1,wbg2,wbb;
447 int chpr = 0;
448
449 blocklength += offset;
450
451 chpr = newline(chpr);
452 wbr_denom = read_ubyte(inptr,offset);
453 if((PRINT_ENTRY))
454 {
455 print_tag_address(ENTRY,offset,indent + 4,"@");
456 if((PRINT_TAGINFO))
457 {
458 if((PRINT_LONGNAMES))
459 chpr += printf("%s","MRW.WBG.");
460 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"WbrDenominator");
461 }
462 if((PRINT_VALUE))
463 chpr += printf(" = %u",wbr_denom);
464 switch(wbr_denom)
465 {
466 case 0: wbr_denom = 64; break;
467 case 1: wbr_denom = 128; break;
468 case 2: wbr_denom = 256; break;
469 case 3: wbr_denom = 512; break;
470 case 4: wbr_denom = 1024; break;
471 default: break;
472 }
473 if((PRINT_VALUE))
474 chpr += printf(" = %u",wbr_denom);
475
476 chpr = newline(chpr);
477 }
478 offset++;
479 wbg1_denom = read_ubyte(inptr,offset);
480 if((PRINT_ENTRY))
481 {
482 print_tag_address(ENTRY,offset,indent + 4,"@");
483 if((PRINT_TAGINFO))
484 {
485 if((PRINT_LONGNAMES))
486 chpr += printf("%s","MRW.WBG.");
487 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"Wbg1Denominator");
488 }
489 if((PRINT_VALUE))
490 chpr += printf(" = %u",wbg1_denom);
491 switch(wbg1_denom)
492 {
493 case 0: wbg1_denom = 64; break;
494 case 1: wbg1_denom = 128; break;
495 case 2: wbg1_denom = 256; break;
496 case 3: wbg1_denom = 512; break;
497 case 4: wbg1_denom = 1024; break;
498 default: break;
499 }
500 if((PRINT_VALUE))
501 chpr += printf(" = %u",wbg1_denom);
502
503 chpr = newline(chpr);
504 }
505 offset++;
506 wbg2_denom = read_ubyte(inptr,offset);
507 if((PRINT_ENTRY))
508 {
509 print_tag_address(ENTRY,offset,indent + 4,"@");
510 if((PRINT_TAGINFO))
511 {
512 if((PRINT_LONGNAMES))
513 chpr += printf("%s","MRW.WBG.");
514 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"Wbg2Denominator");
515 }
516 if((PRINT_VALUE))
517 chpr += printf(" = %u",wbg2_denom);
518 switch(wbg2_denom)
519 {
520 case 0: wbg2_denom = 64; break;
521 case 1: wbg2_denom = 128; break;
522 case 2: wbg2_denom = 256; break;
523 case 3: wbg2_denom = 512; break;
524 case 4: wbg2_denom = 1024; break;
525 default: break;
526 }
527 if((PRINT_VALUE))
528 chpr += printf(" = %u",wbg2_denom);
529
530 chpr = newline(chpr);
531 }
532 offset++;
533 wbb_denom = read_ubyte(inptr,offset);
534 if((PRINT_ENTRY))
535 {
536 print_tag_address(ENTRY,offset,indent + 4,"@");
537 if((PRINT_TAGINFO))
538 {
539 if((PRINT_LONGNAMES))
540 chpr += printf("%s","MRW.WBG.");
541 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"WbbDenominator");
542 }
543 if((PRINT_VALUE))
544 chpr += printf(" = %u",wbb_denom);
545 switch(wbb_denom)
546 {
547 case 0: wbb_denom = 64; break;
548 case 1: wbb_denom = 128; break;
549 case 2: wbb_denom = 256; break;
550 case 3: wbb_denom = 512; break;
551 case 4: wbb_denom = 1024; break;
552 default: break;
553 }
554 if((PRINT_VALUE))
555 chpr += printf(" = %u",wbb_denom);
556
557 chpr = newline(chpr);
558 }
559 offset++;
560 wbr_num = read_ushort(inptr,TIFF_MOTOROLA,offset);
561 if((PRINT_ENTRY))
562 {
563 print_tag_address(ENTRY,offset,indent + 4,"@");
564 if((PRINT_TAGINFO))
565 {
566 if((PRINT_LONGNAMES))
567 chpr += printf("%s","MRW.WBG.");
568 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"WbrNumerator");
569 }
570 if((PRINT_VALUE))
571 chpr += printf(" = %u",wbr_num);
572
573 if((PRINT_SECTION))
574 {
575 if(wbr_denom)
576 {
577 wbr = (double)wbr_num / (double)wbr_denom;
578 chpr += printf(" => wbr = %.3f",wbr);
579 }
580 else
581 chpr += printf(" => wbr = inf");
582 }
583 else
584 {
585 chpr = newline(chpr);
586 print_tag_address(ENTRY,HERE,indent + 4,"*");
587 if((PRINT_TAGINFO))
588 {
589 /* pseudo-tag for result whitebalance */
590 if((PRINT_LONGNAMES))
591 chpr += printf("%s","MRW.WBG.");
592 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"WbRed");
593 }
594 if((PRINT_VALUE))
595 {
596 if(wbr_denom)
597 {
598 wbr = (double)wbr_num / (double)wbr_denom;
599 chpr += printf(" = %.3f",wbr);
600 }
601 else
602 chpr += printf(" = inf");
603 }
604 }
605
606 chpr = newline(chpr);
607 }
608 offset += 2;
609 wbg1_num = read_ushort(inptr,TIFF_MOTOROLA,offset);
610 if((PRINT_ENTRY))
611 {
612 print_tag_address(ENTRY,offset,indent + 4,"@");
613 if((PRINT_TAGINFO))
614 {
615 if((PRINT_LONGNAMES))
616 chpr += printf("%s","MRW.WBG.");
617 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"Wbg1Numerator");
618 }
619 if((PRINT_VALUE))
620 chpr += printf(" = %u",wbg1_num);
621 if((PRINT_SECTION))
622 {
623 if(wbg1_denom)
624 {
625 wbg1 = (double)wbg1_num / (double)wbg1_denom;
626 chpr += printf(" => wbg1 = %.3f",wbg1);
627 }
628 else
629 chpr += printf(" => wbg1 = inf");
630 }
631 else
632 {
633 chpr = newline(chpr);
634 print_tag_address(ENTRY,HERE,indent + 4,"*");
635 if((PRINT_TAGINFO))
636 {
637 /* pseudo-tag for result whitebalance */
638 if((PRINT_LONGNAMES))
639 chpr += printf("%s","MRW.WBG.");
640 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"WbGreen1");
641 }
642 if((PRINT_VALUE))
643 {
644 if(wbg1_denom)
645 {
646 wbg1 = (double)wbg1_num / (double)wbg1_denom;
647 chpr += printf(" = %.3f",wbg1);
648 }
649 else
650 chpr += printf(" => wbg1 = inf");
651 }
652 }
653 chpr = newline(chpr);
654 }
655 offset += 2;
656 wbg2_num = read_ushort(inptr,TIFF_MOTOROLA,offset);
657 if((PRINT_ENTRY))
658 {
659 print_tag_address(ENTRY,offset,indent + 4,"@");
660 if((PRINT_TAGINFO))
661 {
662 if((PRINT_LONGNAMES))
663 chpr += printf("%s","MRW.WBG.");
664 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"Wbg2Numerator");
665 }
666 if((PRINT_VALUE))
667 chpr += printf(" = %u",wbg2_num);
668 if((PRINT_SECTION))
669 {
670 if(wbg2_denom)
671 {
672 wbg2 = (double)wbg2_num / (double)wbg2_denom;
673 chpr += printf(" => wbg2 = %.3f",wbg2);
674 }
675 else
676 chpr += printf(" => wbg2 = inf");
677 }
678 else
679 {
680 chpr = newline(chpr);
681 print_tag_address(ENTRY,HERE,indent + 4,"*");
682 if((PRINT_TAGINFO))
683 {
684 /* pseudo-tag for result whitebalance */
685 if((PRINT_LONGNAMES))
686 chpr += printf("%s","MRW.WBG.");
687 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"WbGreen2");
688 }
689 if((PRINT_VALUE))
690 {
691 if(wbg2_denom)
692 {
693 wbg2 = (double)wbg2_num / (double)wbg2_denom;
694 chpr += printf(" = %.3f",wbg2);
695 }
696 else
697 chpr += printf(" => wbg2 = inf");
698 }
699 }
700 chpr = newline(chpr);
701 }
702 offset += 2;
703 wbb_num = read_ushort(inptr,TIFF_MOTOROLA,offset);
704 if((PRINT_ENTRY))
705 {
706 print_tag_address(ENTRY,offset,indent + 4,"@");
707 if((PRINT_TAGINFO))
708 {
709 if((PRINT_LONGNAMES))
710 chpr += printf("%s","MRW.WBG.");
711 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"WbbNumerator");
712 }
713 if((PRINT_VALUE))
714 chpr += printf(" = %u",wbb_num);
715 if((PRINT_SECTION))
716 {
717 if(wbb_denom)
718 {
719 wbb = (double)wbb_num / (double)wbb_denom;
720 chpr += printf(" => wbb = %.3f",wbb);
721 }
722 else
723 chpr += printf(" => wbb = inf");
724 }
725 else
726 {
727 chpr = newline(chpr);
728 print_tag_address(ENTRY,HERE,indent + 4,"*");
729 if((PRINT_TAGINFO))
730 {
731 /* pseudo-tag for result whitebalance */
732 if((PRINT_LONGNAMES))
733 chpr += printf("%s","MRW.WBG.");
734 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"WbBlue");
735 }
736 if((PRINT_VALUE))
737 {
738 if(wbb_denom)
739 {
740 wbb = (double)wbb_num / (double)wbb_denom;
741 chpr += printf(" = %.3f",wbb);
742 }
743 else
744 chpr += printf(" => wbb = inf");
745 }
746 }
747 chpr = newline(chpr);
748 }
749 offset += 2;
750 return(offset);
751 }
752
753 /* Requested Image Format */
754
755 unsigned long
process_rif(FILE * inptr,unsigned long offset,unsigned long blocklength,struct image_summary * summary_entry,int indent)756 process_rif(FILE *inptr,unsigned long offset,unsigned long blocklength,
757 struct image_summary *summary_entry,int indent)
758 {
759 unsigned long end_offset;
760 unsigned short saturation,contrast;
761 unsigned short sharpness,white_balance;
762 unsigned short subject_program,iso;
763 unsigned short color_mode,color_filter,bw_filter;
764 unsigned short unknown;
765 double fvalue;
766 int chpr = 0;
767
768 end_offset = offset + blocklength;
769
770 chpr = newline(chpr);
771 unknown = read_ubyte(inptr,offset);
772 if((PRINT_ENTRY))
773 {
774 print_tag_address(ENTRY,offset,indent + 4,"@");
775 if((PRINT_TAGINFO))
776 {
777 if((PRINT_LONGNAMES))
778 chpr += printf("%s","MRW.RIF.");
779 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"unknown");
780 }
781 if((PRINT_VALUE))
782 chpr += printf(" = %u",unknown);
783 chpr = newline(chpr);
784 }
785 ++offset;
786 saturation = read_ubyte(inptr,offset);
787 if((PRINT_ENTRY))
788 {
789 print_tag_address(ENTRY,offset,indent + 4,"@");
790 if((PRINT_TAGINFO))
791 {
792 if((PRINT_LONGNAMES))
793 chpr += printf("%s","MRW.RIF.");
794 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"Saturation");
795 }
796 if((PRINT_VALUE))
797 chpr += printf(" = %u",saturation);
798 chpr = newline(chpr);
799 }
800 ++offset;
801 contrast = read_ubyte(inptr,offset);
802 if((PRINT_ENTRY))
803 {
804 print_tag_address(ENTRY,offset,indent + 4,"@");
805 if((PRINT_TAGINFO))
806 {
807 if((PRINT_LONGNAMES))
808 chpr += printf("%s","MRW.RIF.");
809 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"Contrast");
810 }
811 if((PRINT_VALUE))
812 chpr += printf(" = %u",contrast);
813 chpr = newline(chpr);
814 }
815 ++offset;
816 sharpness = read_ubyte(inptr,offset);
817 if((PRINT_ENTRY))
818 {
819 print_tag_address(ENTRY,offset,indent + 4,"@");
820 if((PRINT_TAGINFO))
821 {
822 if((PRINT_LONGNAMES))
823 chpr += printf("%s","MRW.RIF.");
824 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"Sharpness");
825 }
826 if((PRINT_VALUE))
827 chpr += printf(" = %u",sharpness);
828 chpr = newline(chpr);
829 }
830 ++offset;
831 white_balance = read_ubyte(inptr,offset);
832 if((PRINT_ENTRY))
833 {
834 print_tag_address(ENTRY,offset,indent + 4,"@");
835 if((PRINT_TAGINFO))
836 {
837 if((PRINT_LONGNAMES))
838 chpr += printf("%s","MRW.RIF.");
839 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"WhiteBalance");
840 }
841 if((PRINT_VALUE))
842 chpr += printf(" = %u/%#x",white_balance,white_balance);
843 chpr = newline(chpr);
844 }
845 ++offset;
846 subject_program = read_ubyte(inptr,offset);
847 if((PRINT_ENTRY))
848 {
849 print_tag_address(ENTRY,offset,indent + 4,"@");
850 {
851 if((PRINT_LONGNAMES))
852 chpr += printf("%s","MRW.RIF.");
853 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"SubjectProgram");
854 }
855 if((PRINT_VALUE))
856 chpr += printf(" = %u",subject_program);
857 chpr = newline(chpr);
858 }
859 ++offset;
860 iso = read_ubyte(inptr,offset);
861 if((PRINT_ENTRY))
862 {
863 print_tag_address(ENTRY,offset,indent + 4,"@");
864 if((PRINT_TAGINFO))
865 {
866 if((PRINT_LONGNAMES))
867 chpr += printf("%s","MRW.RIF.");
868 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"CCDSensitivity");
869 }
870 if((PRINT_VALUE))
871 {
872 if(PRINT_RAW_VALUES)
873 chpr += printf(" = %u",iso);
874 fvalue = ((double)iso/8.0) - 1.0;
875 chpr += printf(" = %.3g APEX",fvalue);
876 fvalue = pow(2.0,fvalue) * 3.125;
877 chpr += printf(" = %.3g ISO",fvalue);
878 }
879 chpr = newline(chpr);
880 }
881 ++offset;
882 color_mode = read_ubyte(inptr,offset);
883 if((PRINT_ENTRY))
884 {
885 print_tag_address(ENTRY,offset,indent + 4,"@");
886 if((PRINT_TAGINFO))
887 {
888 if((PRINT_LONGNAMES))
889 chpr += printf("%s","MRW.RIF.");
890 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"ColorMode");
891 }
892 if((PRINT_VALUE))
893 chpr += printf(" = %u/%#x",color_mode,color_mode);
894 chpr = newline(chpr);
895 }
896 ++offset;
897 color_filter = read_ubyte(inptr,offset);
898 if((PRINT_ENTRY))
899 {
900 print_tag_address(ENTRY,offset,indent + 4,"@");
901 if((PRINT_TAGINFO))
902 {
903 if((PRINT_LONGNAMES))
904 chpr += printf("%s","MRW.RIF.");
905 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"ColorFilter");
906 }
907 if((PRINT_VALUE))
908 chpr += printf(" = %u/%#x",color_filter,color_filter);
909 chpr = newline(chpr);
910 }
911 ++offset;
912 bw_filter = read_ubyte(inptr,offset);
913 if((PRINT_ENTRY))
914 {
915 print_tag_address(ENTRY,offset,indent + 4,"@");
916 if((PRINT_TAGINFO))
917 {
918 if((PRINT_LONGNAMES))
919 chpr += printf("%s","MRW.RIF.");
920 chpr += printf("%-*.*s",SHORTNAMEWIDTH,SHORTNAMEWIDTH,"BWFilter");
921 }
922 if((PRINT_VALUE))
923 chpr += printf(" = %u/%#x",bw_filter,bw_filter);
924 chpr = newline(chpr);
925 }
926 ++offset;
927 /* Remaining values are unknown */
928 return(end_offset);
929 }
930