1/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */ 2/* EXIFPROBE - TIFF/JPEG/EXIF image file probe */ 3/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */ 4/* Copyright (C) 2002 by Duane H. Hesser. All rights reserved. */ 5/* */ 6/* See the file LICENSE.EXIFPROBE for terms of use. */ 7/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */ 8 9#ifndef WALL 10static char *ModuleId = "@(#) $Id: maker_template,v 1.4 2005/01/27 02:27:32 alex Exp $"; 11#endif 12 13/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */ 14/* THIS_MAKE camera maker-specific routines. */ 15/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */ 16/* Template file for maker-specific routines. */ 17/* 1. Copy this to a file maker_XXX.c and edit as necessary. */ 18/* a. Replace the string "THIS_MAKE" with the maker name. */ 19/* b. assign numbers to make and model names as reqd in maker.h */ 20/* (required iff more than one style of MakerNote exists across */ 21/* models) 22/* c. edit THIS_MAKE_model_number to decode the MODEL, using the */ 23/* SOFTWARE name as well if necessary. The returned number */ 24/* will be used to select the print and interpret routines for */ 25/* the model. */ 26/* d. Edit print_THIS_MAKE_value() and */ 27/* print_THIS_MAKE_value_at_offset() to select the correct */ 28/* print and interpret routines for each note style */ 29/* e. code the specific print and interpret routines. */ 30/* f. remove any unnecessary template material. */ 31/* 2. Move the function prototypes to extern.h */ 32/* 3. Edit print_maker.c to add a case for THIS_MAKER to */ 33/* print_makervalue() and print_offset_makervalue(). */ 34/* 4. Edit maker_generic.c to add a case for THIS_MAKER to */ 35/* maker_number() and model_number(). */ 36/* 5. Edit maker_tagnames.c to add a case for THIS_MAKER to */ 37/* maker_tagname(). */ 38/* 6. Replace this comment with something appropriate. */ 39/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */ 40 41#include <stdio.h> 42#include <string.h> 43#include "defs.h" 44#include "extern.h" 45#include "misc.h" 46#include "maker.h" 47 48/* Find the id number assigned to known THIS_MAKE camera models. */ 49/* This number is used to dispatch print and interpret routines */ 50/* apporopriate to the current image. */ 51 52int 53THIS_MAKE_model_number(char *model,char *software) 54{ 55 int number = GENERIC; 56 57 switch(*model) 58 { 59 default: 60 number = GENERIC; 61 break; 62 } 63 return(number); 64} 65 66/* Dispatch a print routine based upon model */ 67 68void 69print_THIS_MAKE_makervalue(struct ifd_entry *entry_ptr,int make, int model, 70 char *prefix) 71{ 72 73 switch(model) 74 { 75 case MODEL1: 76 print_THIS_MAKE1_makervalue(entry_ptr,make,model,prefix); 77 THIS_MAKE1_interpret_value(entry_ptr); 78 break; 79 case MODEL2: 80 case MODEL3: 81 print_THIS_MAKE2_makervalue(entry_ptr,make,model,prefix); 82 THIS_MAKE2_interpret_value(entry_ptr); 83 break; 84 case GENERIC: 85 default: 86 print_THIS_MAKE1_makervalue(entry_ptr,make,model,prefix); 87 THIS_MAKE2_interpret_value(entry_ptr); 88 break; 89 } 90} 91 92/* Model-specific print routine for THIS_MAKE cameras. This routine is */ 93/* responsible for picking off any direct entry tags which are */ 94/* peculiar and will not be handled properly by print_value() */ 95/* (usually UNDEFINED values which fit in the 4-byte entry value). If */ 96/* there are no such entries, this function simply calls */ 97/* print_value(). */ 98 99void 100print_THIS_MAKE1_makervalue(struct ifd_entry *entry_ptr,int make, int model, 101 char *prefix) 102{ 103 if(entry_ptr) 104 { 105 switch(entry_ptr->tag) 106 { 107 /* pick off values that need special handling in cases */ 108 /* here */ 109 default: 110 print_value(entry_ptr,PREFIX); 111 break; 112 } 113 } 114} 115 116/* Dispatch a routine to decode and print offset values for THIS_MAKE */ 117/* cameras. */ 118 119void 120print_THIS_MAKE_offset_makervalue(FILE *inptr,unsigned short byteorder, 121 struct ifd_entry *entry_ptr,unsigned long offset_ref,char *prefix, 122 int indent,int addrwidth,int make,int model,int at_offset) 123{ 124 125 switch(model) 126 { 127 case MODEL1: 128 THIS_MAKE1_offset_makervalue(inptr,byteorder,entry_ptr, 129 offset_ref,prefix,indent, 130 addrwidth,make,model,int at_offset); 131 break; 132 case MODEL2: 133 default: 134 THIS_MAKE2_offset_makervalue(inptr,byteorder,entry_ptr, 135 offset_ref,prefix,indent, 136 addrwidth,make,model,int at_offset); 137 break; 138 } 139} 140 141/* Model-specific routine to print values found at an offset from the */ 142/* IFD entry in THIS_MAKE makernotes. */ 143 144/* One of these may be supplied for each model if necessary */ 145 146void 147THIS_MAKE1_offset_makervalue(FILE *inptr,unsigned short byteorder, 148 struct ifd_entry *entry_ptr,unsigned long offset_ref,char *prefix, 149 int indent,int addrwidth,int make,int model,int at_offset) 150{ 151 unsigned long value_offset; 152 unsigned long dumplength; 153 unsigned short marker; 154 char *nameoftag; 155 156 if(entry_ptr) 157 { 158 nameoftag = maker_tagname(entry_ptr->tag,make,model); 159 value_offset = offset_ref + entry_ptr->value; 160 161 /* Pick off UNDEFINED tag types. The rest can be handled by */ 162 /* the generic routine. */ 163 switch(entry_ptr->tag) 164 { 165 case 0x0100: /* JPEG Thumbnail in TIFF MakerNote */ 166 print_tag_address(value_offset,indent,prefix,addrwidth); 167 putindent(SUBINDENT); 168 printf("Start of %s length %ld\n",nameoftag,entry_ptr->count); 169 marker = read_imagemarker(inptr,value_offset); 170 (void)process_jpeg_segments(inptr,value_offset, 171 marker,entry_ptr->count,indent+2, 172 addrwidth); 173 STARTCOLOR(MAKER_COLOR); 174 print_tag_address(value_offset + entry_ptr->count,indent,"-", 175 addrwidth); 176 putindent(SUBINDENT); 177 printf("End of %s",nameoftag); 178 /* make certain we're at the end unless 'inptr' bad */ 179 fseek(inptr,value_offset + entry_ptr->count,0); 180 break; 181 case 0x0e00: /* PrintIM (Epson Print Image matching) */ 182 case 0x0f00: /* Data */ 183 print_tag_address(value_offset,indent,prefix,addrwidth); 184 putindent(SUBINDENT); 185 printf("%s: length %lu",nameoftag,entry_ptr->count); 186 if(Max_undefined == 0) 187 printf(" (not dumped, use -U)"); 188 else 189 { 190 if((Max_undefined == DUMPALL) 191 || (Max_undefined > entry_ptr->count)) 192 dumplength = entry_ptr->count; 193 else 194 dumplength = Max_undefined; 195 putchar('\n'); 196 hexdump(inptr,value_offset,entry_ptr->count,dumplength,12, 197 indent,SUBINDENT,addrwidth); 198 } 199 /* make certain we're at the end unless 'inptr' bad */ 200 fseek(inptr,value_offset + entry_ptr->count,0); 201 break; 202 default: 203 print_generic_offset_makervalue(inptr,byteorder,entry_ptr, 204 offset_ref,prefix,indent, 205 addrwidth,make,model,at_offset); 206 break; 207 } 208 } 209} 210 211void 212THIS_MAKE2_offset_makervalue(FILE *inptr,unsigned short byteorder, 213 struct ifd_entry *entry_ptr,unsigned long offset_ref,char *prefix, 214 int indent,int addrwidth,int make,int model,int at_offset) 215{ 216 unsigned long value_offset; 217 unsigned long dumplength; 218 unsigned short marker; 219 char *nameoftag; 220 221 if(entry_ptr) 222 { 223 nameoftag = maker_tagname(entry_ptr->tag,make,model); 224 value_offset = offset_ref + entry_ptr->value; 225 switch(entry_ptr->tag) 226 { 227 case 0x0100: /* JPEG Thumbnail in TIFF MakerNote, for */ 228 print_tag_address(value_offset,indent,prefix,addrwidth); 229 putindent(SUBINDENT); 230 printf("Start of %s length %ld\n",nameoftag,entry_ptr->count); 231 marker = read_imagemarker(inptr,value_offset); 232 (void)process_jpeg_segments(inptr,value_offset, 233 marker,entry_ptr->count,indent+2, 234 addrwidth); 235 STARTCOLOR(MAKER_COLOR); 236 print_tag_address(value_offset + entry_ptr->count,indent,"-", 237 addrwidth); 238 putindent(SUBINDENT); 239 printf("End of %s",nameoftag); 240 /* make certain we're at the end unless 'inptr' bad */ 241 fseek(inptr,value_offset + entry_ptr->count,0); 242 break; 243 case 0x0010: /* Data */ 244 print_tag_address(value_offset,indent,prefix,addrwidth); 245 putindent(SUBINDENT); 246 printf("%s: length %lu",nameoftag,entry_ptr->count); 247 if(Max_undefined == 0) 248 printf(" (not dumped, use -U)"); 249 else 250 { 251 if((Max_undefined == DUMPALL) 252 || (Max_undefined > entry_ptr->count)) 253 dumplength = entry_ptr->count; 254 else 255 dumplength = Max_undefined; 256 putchar('\n'); 257 hexdump(inptr,value_offset,entry_ptr->count,dumplength,12, 258 indent,SUBINDENT,addrwidth); 259 } 260 /* make certain we're at the end */ 261 fseek(inptr,value_offset + entry_ptr->count,0); 262 break; 263 default: 264 print_generic_offset_makervalue(inptr,byteorder,entry_ptr, 265 offset_ref,prefix,indent, 266 addrwidth,make,model,int at_offset); 267 break; 268 } 269 } 270} 271 272char * 273maker_THIS_MAKE_tagname(unsigned short tag,int model) 274{ 275 char *tagname = (char *)0; 276 277 /* Check specific models first */ 278 switch(model) 279 { 280 case MODEL1: 281 tagname = maker_THIS_MAKE1_tagname(tag,model); 282 break; 283 case MODEL2: 284 tagname = maker_THIS_MAKE2_tagname(tag,model); 285 break; 286 default: 287 /* Call a specific routine here, or leave it blank to */ 288 /* just call the generic tag maker. */ 289 break; 290 } 291 return(tagname); 292} 293 294/* Tags for the older cameras. */ 295 296char * 297maker_THIS_MAKE1_tagname(unsigned short tag,int model) 298{ 299 char *tagname = (char *)0; 300 301 switch(tag) 302 { 303 /* ###%%% be sure to change these */ 304 case 0x0003: tagname = "Quality"; break; 305 case 0x0004: tagname = "Color Mode"; break; 306 case 0x0005: tagname = "Image Adjustment"; break; 307 case 0x0006: tagname = "ISO Setting"; break; 308 case 0x0007: tagname = "White Balance"; break; 309 case 0x0008: tagname = "Focus"; break; 310 case 0x000a: tagname = "Digital Zoom"; break; 311 case 0x000b: tagname = "LensConverter"; break; 312 case 0x0f00: tagname = "Data"; break; 313 case 0x0100: tagname = "JPEG Thumbnail"; break; 314 default: break; 315 } 316 return(tagname); 317} 318 319 320char * 321maker_THIS_MAKE2_tagname(unsigned short tag,int model) 322{ 323 char *tagname = (char *)0; 324 325 switch(tag) 326 { 327 /* ###%%% be sure to change these */ 328 case 0x0001: tagname = "Version"; break; 329 case 0x0002: tagname = "ISO Setting"; break; 330 case 0x0003: tagname = "Color Mode"; break; 331 case 0x0004: tagname = "Quality"; break; 332 case 0x0005: tagname = "White Balance"; break; 333 case 0x0006: tagname = "Image Sharpening"; break; 334 case 0x0007: tagname = "Focus Mode"; break; 335 case 0x0008: tagname = "Flash Setting"; break; 336 case 0x000f: tagname = "ISO Selection"; break; 337 case 0x0010: tagname = "Data"; break; 338 case 0x0080: tagname = "Image Adjustment"; break; 339 case 0x0082: tagname = "Adapter"; break; 340 case 0x0085: tagname = "Manual Focus Distance"; break; 341 case 0x0086: tagname = "Digital Zoom"; break; 342 case 0x0088: tagname = "Auto Focus Position"; break; 343 case 0x0e00: tagname = "PrintIM Data"; break; 344 case 0x0100: tagname = "JPEG Thumbnail"; break; 345 default: break; 346 } 347 return(tagname); 348} 349 350void 351THIS_MAKE1_interpret_value(struct ifd_entry *entry_ptr) 352{ 353 switch(entry_ptr->tag) 354 { 355 case 0xQUALITY: /* Quality */ 356 switch(entry_ptr->value) 357 { 358 default: printred(" [???]",MAKER_COLOR); break; 359 } 360 break; 361 case 0xCOLOR: /* Color Mode */ 362 if(entry_ptr->value == COLOR) 363 printf(" [color]"); 364 else if(entry_ptr->value == MONOCHROME) 365 printf(" [monochrome]"); 366 else 367 printred(" [???]",MAKER_COLOR); 368 break; 369 case 0xADJUST: /* Image Adjustment */ 370 switch(entry_ptr->value) 371 { 372 default: 373 printred(" [???]",MAKER_COLOR); 374 break; 375 } 376 break; 377 default: 378 break; 379 } 380} 381 382void 383THIS_MAKE2_interpret_value(struct ifd_entry *entry_ptr) 384{ 385 386 switch(entry_ptr->tag) 387 { 388 case 0x000b: 389 case 0x000d: 390 case 0x000e: 391 case 0x0011: 392 case 0x0083: 393 case 0x0087: 394 case 0x0089: 395 case 0x008a: 396 case 0x008b: 397 case 0x0092: 398 case 0x0094: 399 printred(" [???]",MAKER_COLOR); 400 break; 401 default: 402 printred(" [???]",MAKER_COLOR); 403 break; 404 } 405} 406