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