File indexing completed on 2025-01-05 03:56:49
0001 /* -*- C++ -*- 0002 * File: identify.cpp 0003 * Copyright 2008-2021 LibRaw LLC (info@libraw.org) 0004 * Created: Sat Mar 8, 2008 0005 * 0006 * LibRaw C++ demo: emulates dcraw -i [-v] 0007 * 0008 0009 LibRaw is free software; you can redistribute it and/or modify 0010 it under the terms of the one of two licenses as you choose: 0011 0012 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 0013 (See file LICENSE.LGPL provided in LibRaw distribution archive for details). 0014 0015 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 0016 (See file LICENSE.CDDL provided in LibRaw distribution archive for details). 0017 0018 0019 */ 0020 0021 #include <stdio.h> 0022 #include <string.h> 0023 #include <math.h> 0024 #include <time.h> 0025 #include <string> 0026 #include <list> 0027 0028 #include "libraw/libraw.h" 0029 0030 #ifdef LIBRAW_WIN32_CALLS 0031 #define snprintf _snprintf 0032 #define strcasecmp stricmp 0033 #define strncasecmp strnicmp 0034 #endif 0035 0036 #ifndef LIBRAW_WIN32_CALLS 0037 #include <sys/stat.h> 0038 #include <fcntl.h> 0039 #include <unistd.h> 0040 #include <sys/mman.h> 0041 #include <sys/time.h> 0042 #ifndef MAX_PATH 0043 #ifdef PATH_MAX 0044 #define MAX_PATH PATH_MAX 0045 #else 0046 #define MAX_PATH 4096 0047 #endif 0048 #endif 0049 #endif 0050 0051 #ifdef _MSC_VER 0052 #if _MSC_VER < 1800 /* below MSVC 2013 */ 0053 float roundf(float f) { return floorf(f + 0.5); } 0054 0055 #endif 0056 #endif 0057 0058 #define P1 MyCoolRawProcessor.imgdata.idata 0059 #define P2 MyCoolRawProcessor.imgdata.other 0060 #define P3 MyCoolRawProcessor.imgdata.makernotes.common 0061 0062 #define mnLens MyCoolRawProcessor.imgdata.lens.makernotes 0063 #define exifLens MyCoolRawProcessor.imgdata.lens 0064 #define ShootingInfo MyCoolRawProcessor.imgdata.shootinginfo 0065 0066 #define S MyCoolRawProcessor.imgdata.sizes 0067 #define O MyCoolRawProcessor.imgdata.params 0068 #define C MyCoolRawProcessor.imgdata.color 0069 #define T MyCoolRawProcessor.imgdata.thumbnail 0070 0071 void print_verbose(FILE *, LibRaw &MyCoolRawProcessor, std::string &fn); 0072 void print_wbfun(FILE *, LibRaw &MyCoolRawProcessor, std::string &fn); 0073 void print_szfun(FILE *, LibRaw &MyCoolRawProcessor, std::string &fn); 0074 void print_unpackfun(FILE *, LibRaw &MyCoolRawProcessor, int print_frame, std::string &fn); 0075 0076 /* 0077 table of fluorescents: 0078 12 = FL-D; Daylight fluorescent (D 5700K – 7100K) (F1,F5) 0079 13 = FL-N; Day white fluorescent (N 4600K – 5400K) (F7,F8) 0080 14 = FL-W; Cool white fluorescent (W 3900K – 4500K) (F2,F6, office, 0081 store,warehouse) 15 = FL-WW; White fluorescent (WW 3200K – 3700K) (F3, 0082 residential) 16 = FL-L; Soft/Warm white fluorescent (L 2600K - 3250K) (F4, 0083 kitchen, bath) 0084 */ 0085 0086 static const struct 0087 { 0088 const int NumId; 0089 const char *StrId; 0090 const char *hrStrId; // human-readable 0091 const int aux_setting; 0092 } WBToStr[] = { 0093 {LIBRAW_WBI_Unknown, "WBI_Unknown", "Unknown", 0}, 0094 {LIBRAW_WBI_Daylight, "WBI_Daylight", "Daylight", 0}, 0095 {LIBRAW_WBI_Fluorescent, "WBI_Fluorescent", "Fluorescent", 0}, 0096 {LIBRAW_WBI_Tungsten, "WBI_Tungsten", "Tungsten (Incandescent)", 0}, 0097 {LIBRAW_WBI_Flash, "WBI_Flash", "Flash", 0}, 0098 {LIBRAW_WBI_FineWeather, "WBI_FineWeather", "Fine Weather", 0}, 0099 {LIBRAW_WBI_Cloudy, "WBI_Cloudy", "Cloudy", 0}, 0100 {LIBRAW_WBI_Shade, "WBI_Shade", "Shade", 0}, 0101 {LIBRAW_WBI_FL_D, "WBI_FL_D", "Daylight Fluorescent", 0}, 0102 {LIBRAW_WBI_FL_N, "WBI_FL_N", "Day White Fluorescent", 0}, 0103 {LIBRAW_WBI_FL_W, "WBI_FL_W", "Cool White Fluorescent", 0}, 0104 {LIBRAW_WBI_FL_WW, "WBI_FL_WW", "White Fluorescent", 0}, 0105 {LIBRAW_WBI_FL_L, "WBI_FL_L", "Warm White Fluorescent", 0}, 0106 {LIBRAW_WBI_Ill_A, "WBI_Ill_A", "Illuminant A", 0}, 0107 {LIBRAW_WBI_Ill_B, "WBI_Ill_B", "Illuminant B", 0}, 0108 {LIBRAW_WBI_Ill_C, "WBI_Ill_C", "Illuminant C", 0}, 0109 {LIBRAW_WBI_D55, "WBI_D55", "D55", 0}, 0110 {LIBRAW_WBI_D65, "WBI_D65", "D65", 0}, 0111 {LIBRAW_WBI_D75, "WBI_D75", "D75", 0}, 0112 {LIBRAW_WBI_D50, "WBI_D50", "D50", 0}, 0113 {LIBRAW_WBI_StudioTungsten, "WBI_StudioTungsten", "ISO Studio Tungsten", 0}, 0114 {LIBRAW_WBI_BW, "WBI_BW", "BW", 0}, 0115 {LIBRAW_WBI_Other, "WBI_Other", "Other", 0}, 0116 {LIBRAW_WBI_Sunset, "WBI_Sunset", "Sunset", 1}, 0117 {LIBRAW_WBI_Underwater, "WBI_Underwater", "Underwater", 1}, 0118 {LIBRAW_WBI_FluorescentHigh, "WBI_FluorescentHigh", "Fluorescent High", 1}, 0119 {LIBRAW_WBI_HT_Mercury, "WBI_HT_Mercury", "HT Mercury", 1}, 0120 {LIBRAW_WBI_AsShot, "WBI_AsShot", "As Shot", 1}, 0121 {LIBRAW_WBI_Measured, "WBI_Measured", "Camera Measured", 1}, 0122 {LIBRAW_WBI_Auto, "WBI_Auto", "Camera Auto", 1}, 0123 {LIBRAW_WBI_Auto1, "WBI_Auto1", "Camera Auto 1", 1}, 0124 {LIBRAW_WBI_Auto2, "WBI_Auto2", "Camera Auto 2", 1}, 0125 {LIBRAW_WBI_Auto3, "WBI_Auto3", "Camera Auto 3", 1}, 0126 {LIBRAW_WBI_Auto4, "WBI_Auto4", "Camera Auto 4", 1}, 0127 {LIBRAW_WBI_Custom, "WBI_Custom", "Custom", 1}, 0128 {LIBRAW_WBI_Custom1, "WBI_Custom1", "Custom 1", 1}, 0129 {LIBRAW_WBI_Custom2, "WBI_Custom2", "Custom 2", 1}, 0130 {LIBRAW_WBI_Custom3, "WBI_Custom3", "Custom 3", 1}, 0131 {LIBRAW_WBI_Custom4, "WBI_Custom4", "Custom 4", 1}, 0132 {LIBRAW_WBI_Custom5, "WBI_Custom5", "Custom 5", 1}, 0133 {LIBRAW_WBI_Custom6, "WBI_Custom6", "Custom 6", 1}, 0134 {LIBRAW_WBI_PC_Set1, "WBI_PC_Set1", "PC Set 1", 1}, 0135 {LIBRAW_WBI_PC_Set2, "WBI_PC_Set2", "PC Set 2", 1}, 0136 {LIBRAW_WBI_PC_Set3, "WBI_PC_Set3", "PC Set 3", 1}, 0137 {LIBRAW_WBI_PC_Set4, "WBI_PC_Set4", "PC Set 4", 1}, 0138 {LIBRAW_WBI_PC_Set5, "WBI_PC_Set5", "PC Set 5", 1}, 0139 {LIBRAW_WBI_Kelvin, "WBI_Kelvin", "Kelvin", 1}, 0140 }; 0141 0142 const char *WB_idx2str(unsigned WBi) 0143 { 0144 for (int i = 0; i < int(sizeof WBToStr / sizeof *WBToStr); i++) 0145 if (WBToStr[i].NumId == (int)WBi) 0146 return WBToStr[i].StrId; 0147 return 0; 0148 } 0149 0150 const char *WB_idx2hrstr(unsigned WBi) 0151 { 0152 for (int i = 0; i < int(sizeof WBToStr / sizeof *WBToStr); i++) 0153 if (WBToStr[i].NumId == (int)WBi) 0154 return WBToStr[i].hrStrId; 0155 return 0; 0156 } 0157 0158 double _log2(double a) 0159 { 0160 if(a > 0.00000000001) return log(a)/log(2.0); 0161 return -1000; 0162 } 0163 0164 void trimSpaces(char *s) 0165 { 0166 char *p = s; 0167 if (!strncasecmp(p, "NO=", 3)) 0168 p = p + 3; /* fix for Nikon D70, D70s */ 0169 int l = strlen(p); 0170 if (!l) 0171 return; 0172 while (isspace(p[l - 1])) 0173 p[--l] = 0; /* trim trailing spaces */ 0174 while (*p && isspace(*p)) 0175 ++p, --l; /* trim leading spaces */ 0176 memmove(s, p, l + 1); 0177 } 0178 0179 void print_usage(const char *pname) 0180 { 0181 printf("Usage: %s [options] inputfiles\n", pname); 0182 printf("Options:\n" 0183 "\t-v\tverbose output\n" 0184 "\t-w\tprint white balance\n" 0185 "\t-u\tprint unpack function\n" 0186 "\t-f\tprint frame size (only w/ -u)\n" 0187 "\t-s\tprint output image size\n" 0188 "\t-h\tforce half-size mode (only for -s)\n" 0189 "\t-M\tdisable use of raw-embedded color data\n" 0190 "\t+M\tforce use of raw-embedded color data\n" 0191 "\t-L filename\tread input files list from filename\n" 0192 "\t-o filename\toutput to filename\n"); 0193 } 0194 0195 int main(int ac, char *av[]) 0196 { 0197 int ret; 0198 int verbose = 0, print_sz = 0, print_unpack = 0, print_frame = 0, print_wb = 0; 0199 LibRaw MyCoolRawProcessor; 0200 char *filelistfile = NULL; 0201 char *outputfilename = NULL; 0202 FILE *outfile = stdout; 0203 std::vector<std::string> filelist; 0204 0205 filelist.reserve(ac - 1); 0206 0207 for (int i = 1; i < ac; i++) 0208 { 0209 if (av[i][0] == '-') 0210 { 0211 if (!strcmp(av[i], "-v")) 0212 verbose++; 0213 if (!strcmp(av[i], "-w")) 0214 print_wb++; 0215 if (!strcmp(av[i], "-u")) 0216 print_unpack++; 0217 if (!strcmp(av[i], "-s")) 0218 print_sz++; 0219 if (!strcmp(av[i], "-h")) 0220 O.half_size = 1; 0221 if (!strcmp(av[i], "-f")) 0222 print_frame++; 0223 if (!strcmp(av[i], "-M")) 0224 MyCoolRawProcessor.imgdata.params.use_camera_matrix = 0; 0225 if (!strcmp(av[i], "-L") && i < ac - 1) 0226 { 0227 filelistfile = av[i + 1]; 0228 i++; 0229 } 0230 if (!strcmp(av[i], "-o") && i < ac - 1) 0231 { 0232 outputfilename = av[i + 1]; 0233 i++; 0234 } 0235 continue; 0236 } 0237 else if (!strcmp(av[i], "+M")) 0238 { 0239 MyCoolRawProcessor.imgdata.params.use_camera_matrix = 3; 0240 continue; 0241 } 0242 filelist.push_back(av[i]); 0243 } 0244 if (filelistfile) 0245 { 0246 char *p; 0247 char path[MAX_PATH + 1]; 0248 FILE *f = fopen(filelistfile, "r"); 0249 if (f) 0250 { 0251 while (fgets(path, MAX_PATH, f)) 0252 { 0253 if ((p = strchr(path, '\n'))) 0254 *p = 0; 0255 if ((p = strchr(path, '\r'))) 0256 *p = 0; 0257 filelist.push_back(path); 0258 } 0259 fclose(f); 0260 } 0261 } 0262 if (filelist.size() < 1) 0263 { 0264 print_usage(av[0]); 0265 return 1; 0266 } 0267 if (outputfilename) 0268 outfile = fopen(outputfilename, "wt"); 0269 0270 for (int i = 0; i < (int)filelist.size(); i++) 0271 { 0272 if ((ret = MyCoolRawProcessor.open_file(filelist[i].c_str())) != LIBRAW_SUCCESS) 0273 { 0274 fprintf(stderr, "Cannot decode %s: %s\n", filelist[i].c_str(), libraw_strerror(ret)); 0275 continue; // no recycle, open_file will recycle 0276 } 0277 0278 if (print_sz) 0279 print_szfun(outfile, MyCoolRawProcessor, filelist[i]); 0280 else if (verbose) 0281 print_verbose(outfile, MyCoolRawProcessor, filelist[i]); 0282 else if (print_unpack) 0283 print_unpackfun(outfile, MyCoolRawProcessor, print_frame, filelist[i]); 0284 else if (print_wb) 0285 print_wbfun(outfile, MyCoolRawProcessor, filelist[i]); 0286 else 0287 fprintf(outfile, "%s is a %s %s image.\n", filelist[i].c_str(), P1.make, P1.model); 0288 0289 MyCoolRawProcessor.recycle(); 0290 } // endfor 0291 return 0; 0292 } 0293 0294 #define PRINTMATRIX3x4(of, mat, clrs) \ 0295 do \ 0296 { \ 0297 for (int r = 0; r < 3; r++) \ 0298 if (clrs == 4) \ 0299 fprintf(of, "%6.4f\t%6.4f\t%6.4f\t%6.4f\n", mat[r][0], mat[r][1], mat[r][2], mat[r][3]); \ 0300 else \ 0301 fprintf(of, "%6.4f\t%6.4f\t%6.4f\n", mat[r][0], mat[r][1], mat[r][2]); \ 0302 } while (0) 0303 0304 #define PRINTMATRIX4x3(of, mat, clrs) \ 0305 do \ 0306 { \ 0307 for (int r = 0; r < clrs && r < 4; r++) \ 0308 fprintf(of, "%6.4f\t%6.4f\t%6.4f\n", mat[r][0], mat[r][1], mat[r][2]); \ 0309 } while (0) 0310 0311 void print_verbose(FILE *outfile, LibRaw &MyCoolRawProcessor, std::string &fn) 0312 { 0313 int WBi; 0314 float denom; 0315 int ret; 0316 0317 if ((ret = MyCoolRawProcessor.adjust_sizes_info_only())) 0318 { 0319 fprintf(outfile, "Cannot decode %s: %s\n", fn.c_str(), libraw_strerror(ret)); 0320 return; // no recycle, open_file will recycle 0321 } 0322 0323 fprintf(outfile, "\nFilename: %s\n", fn.c_str()); 0324 if (C.OriginalRawFileName[0]) 0325 fprintf(outfile, "OriginalRawFileName: =%s=\n", C.OriginalRawFileName); 0326 fprintf(outfile, "Timestamp: %s", ctime(&(P2.timestamp))); 0327 fprintf(outfile, "Camera: %s %s ID: 0x%llx\n", P1.make, P1.model, mnLens.CamID); 0328 fprintf(outfile, "Normalized Make/Model: =%s/%s= ", P1.normalized_make, P1.normalized_model); 0329 fprintf(outfile, "CamMaker ID: %d\n", P1.maker_index); 0330 0331 { 0332 int i = 0; 0333 char sep[] = ", "; 0334 if (C.UniqueCameraModel[0]) 0335 { 0336 i++; 0337 fprintf(outfile, "UniqueCameraModel: =%s=", C.UniqueCameraModel); 0338 } 0339 if (C.LocalizedCameraModel[0]) 0340 { 0341 if (i) 0342 { 0343 fprintf(outfile, "%s", sep); 0344 i++; 0345 } 0346 fprintf(outfile, "LocalizedCameraModel: =%s=", C.LocalizedCameraModel); 0347 } 0348 if (i) 0349 { 0350 fprintf(outfile, "\n"); 0351 i = 0; 0352 } 0353 if (C.ImageUniqueID[0]) 0354 { 0355 if (i) 0356 fprintf(outfile, "%s", sep); 0357 i++; 0358 fprintf(outfile, "ImageUniqueID: =%s=", C.ImageUniqueID); 0359 } 0360 if (C.RawDataUniqueID[0]) 0361 { 0362 if (i) 0363 fprintf(outfile, "%s", sep); 0364 i++; 0365 fprintf(outfile, "RawDataUniqueID: =%s=", C.RawDataUniqueID); 0366 } 0367 if (i) 0368 fprintf(outfile, "\n"); 0369 } 0370 0371 if (ShootingInfo.BodySerial[0] && strcmp(ShootingInfo.BodySerial, "0")) 0372 { 0373 trimSpaces(ShootingInfo.BodySerial); 0374 fprintf(outfile, "Body#: %s", ShootingInfo.BodySerial); 0375 } 0376 else if (C.model2[0] && (!strncasecmp(P1.normalized_make, "Kodak", 5))) 0377 { 0378 trimSpaces(C.model2); 0379 fprintf(outfile, "Body#: %s", C.model2); 0380 } 0381 if (ShootingInfo.InternalBodySerial[0]) 0382 { 0383 trimSpaces(ShootingInfo.InternalBodySerial); 0384 fprintf(outfile, " BodyAssy#: %s", ShootingInfo.InternalBodySerial); 0385 } 0386 if (exifLens.LensSerial[0]) 0387 { 0388 trimSpaces(exifLens.LensSerial); 0389 fprintf(outfile, " Lens#: %s", exifLens.LensSerial); 0390 } 0391 if (exifLens.InternalLensSerial[0]) 0392 { 0393 trimSpaces(exifLens.InternalLensSerial); 0394 fprintf(outfile, " LensAssy#: %s", exifLens.InternalLensSerial); 0395 } 0396 if (P2.artist[0]) 0397 fprintf(outfile, " Owner: %s\n", P2.artist); 0398 if (P1.dng_version) 0399 { 0400 fprintf(outfile, " DNG Version: "); 0401 for (int i = 24; i >= 0; i -= 8) 0402 fprintf(outfile, "%d%c", P1.dng_version >> i & 255, i ? '.' : '\n'); 0403 } 0404 fprintf(outfile, "\nEXIF:\n"); 0405 fprintf(outfile, "\tMinFocal: %0.1f mm\n", exifLens.MinFocal); 0406 fprintf(outfile, "\tMaxFocal: %0.1f mm\n", exifLens.MaxFocal); 0407 fprintf(outfile, "\tMaxAp @MinFocal: f/%0.1f\n", exifLens.MaxAp4MinFocal); 0408 fprintf(outfile, "\tMaxAp @MaxFocal: f/%0.1f\n", exifLens.MaxAp4MaxFocal); 0409 fprintf(outfile, "\tCurFocal: %0.1f mm\n", P2.focal_len); 0410 fprintf(outfile, "\tMaxAperture @CurFocal: f/%0.1f\n", exifLens.EXIF_MaxAp); 0411 fprintf(outfile, "\tFocalLengthIn35mmFormat: %d mm\n", exifLens.FocalLengthIn35mmFormat); 0412 fprintf(outfile, "\tLensMake: %s\n", exifLens.LensMake); 0413 fprintf(outfile, "\tLens: %s\n", exifLens.Lens); 0414 fprintf(outfile, "\n"); 0415 0416 fprintf(outfile, "\nMakernotes:\n"); 0417 fprintf(outfile, "\tDriveMode: %d\n", ShootingInfo.DriveMode); 0418 fprintf(outfile, "\tFocusMode: %d\n", ShootingInfo.FocusMode); 0419 fprintf(outfile, "\tMeteringMode: %d\n", ShootingInfo.MeteringMode); 0420 fprintf(outfile, "\tAFPoint: %d\n", ShootingInfo.AFPoint); 0421 fprintf(outfile, "\tExposureMode: %d\n", ShootingInfo.ExposureMode); 0422 fprintf(outfile, "\tExposureProgram: %d\n", ShootingInfo.ExposureProgram); 0423 fprintf(outfile, "\tImageStabilization: %d\n", ShootingInfo.ImageStabilization); 0424 0425 fprintf(outfile, "\tLens: %s\n", mnLens.Lens); 0426 fprintf(outfile, "\tLensFormat: %d, ", mnLens.LensFormat); 0427 0428 fprintf(outfile, "\tLensMount: %d, ", mnLens.LensMount); 0429 fprintf(outfile, "\tFocalType: %d, ", mnLens.FocalType); 0430 switch (mnLens.FocalType) 0431 { 0432 case LIBRAW_FT_UNDEFINED: 0433 fprintf(outfile, "Undefined\n"); 0434 break; 0435 case LIBRAW_FT_PRIME_LENS: 0436 fprintf(outfile, "Prime lens\n"); 0437 break; 0438 case LIBRAW_FT_ZOOM_LENS: 0439 fprintf(outfile, "Zoom lens\n"); 0440 break; 0441 default: 0442 fprintf(outfile, "Unknown\n"); 0443 break; 0444 } 0445 fprintf(outfile, "\tLensFeatures_pre: %s\n", mnLens.LensFeatures_pre); 0446 fprintf(outfile, "\tLensFeatures_suf: %s\n", mnLens.LensFeatures_suf); 0447 fprintf(outfile, "\tMinFocal: %0.1f mm\n", mnLens.MinFocal); 0448 fprintf(outfile, "\tMaxFocal: %0.1f mm\n", mnLens.MaxFocal); 0449 fprintf(outfile, "\tMaxAp @MinFocal: f/%0.1f\n", mnLens.MaxAp4MinFocal); 0450 fprintf(outfile, "\tMaxAp @MaxFocal: f/%0.1f\n", mnLens.MaxAp4MaxFocal); 0451 fprintf(outfile, "\tMinAp @MinFocal: f/%0.1f\n", mnLens.MinAp4MinFocal); 0452 fprintf(outfile, "\tMinAp @MaxFocal: f/%0.1f\n", mnLens.MinAp4MaxFocal); 0453 fprintf(outfile, "\tMaxAp: f/%0.1f\n", mnLens.MaxAp); 0454 fprintf(outfile, "\tMinAp: f/%0.1f\n", mnLens.MinAp); 0455 fprintf(outfile, "\tCurFocal: %0.1f mm\n", mnLens.CurFocal); 0456 fprintf(outfile, "\tCurAp: f/%0.1f\n", mnLens.CurAp); 0457 fprintf(outfile, "\tMaxAp @CurFocal: f/%0.1f\n", mnLens.MaxAp4CurFocal); 0458 fprintf(outfile, "\tMinAp @CurFocal: f/%0.1f\n", mnLens.MinAp4CurFocal); 0459 0460 if (exifLens.makernotes.FocalLengthIn35mmFormat > 1.0f) 0461 fprintf(outfile, "\tFocalLengthIn35mmFormat: %0.1f mm\n", exifLens.makernotes.FocalLengthIn35mmFormat); 0462 0463 if (exifLens.nikon.EffectiveMaxAp > 0.1f) 0464 fprintf(outfile, "\tEffectiveMaxAp: f/%0.1f\n", exifLens.nikon.EffectiveMaxAp); 0465 0466 if (exifLens.makernotes.LensFStops > 0.1f) 0467 fprintf(outfile, "\tLensFStops @CurFocal: %0.2f\n", exifLens.makernotes.LensFStops); 0468 0469 fprintf(outfile, "\tTeleconverterID: %lld\n", mnLens.TeleconverterID); 0470 fprintf(outfile, "\tTeleconverter: %s\n", mnLens.Teleconverter); 0471 fprintf(outfile, "\tAdapterID: %lld\n", mnLens.AdapterID); 0472 fprintf(outfile, "\tAdapter: %s\n", mnLens.Adapter); 0473 fprintf(outfile, "\tAttachmentID: %lld\n", mnLens.AttachmentID); 0474 fprintf(outfile, "\tAttachment: %s\n", mnLens.Attachment); 0475 fprintf(outfile, "\n"); 0476 0477 fprintf(outfile, "ISO speed: %d\n", (int)P2.iso_speed); 0478 if (P3.real_ISO > 0.1f) 0479 fprintf(outfile, "real ISO speed: %d\n", (int)P3.real_ISO); 0480 fprintf(outfile, "Shutter: "); 0481 if (P2.shutter > 0 && P2.shutter < 1) 0482 P2.shutter = fprintf(outfile, "1/%0.1f\n", 1.0f / P2.shutter); 0483 else if (P2.shutter >= 1) 0484 fprintf(outfile, "%0.1f sec\n", P2.shutter); 0485 else /* negative*/ 0486 fprintf(outfile, " negative value\n"); 0487 fprintf(outfile, "Aperture: f/%0.1f\n", P2.aperture); 0488 fprintf(outfile, "Focal length: %0.1f mm\n", P2.focal_len); 0489 if (P3.exifAmbientTemperature > -273.15f) 0490 fprintf(outfile, "Ambient temperature (exif data): %6.2f° C\n", P3.exifAmbientTemperature); 0491 if (P3.CameraTemperature > -273.15f) 0492 fprintf(outfile, "Camera temperature: %6.2f° C\n", P3.CameraTemperature); 0493 if (P3.SensorTemperature > -273.15f) 0494 fprintf(outfile, "Sensor temperature: %6.2f° C\n", P3.SensorTemperature); 0495 if (P3.SensorTemperature2 > -273.15f) 0496 fprintf(outfile, "Sensor temperature2: %6.2f° C\n", P3.SensorTemperature2); 0497 if (P3.LensTemperature > -273.15f) 0498 fprintf(outfile, "Lens temperature: %6.2f° C\n", P3.LensTemperature); 0499 if (P3.AmbientTemperature > -273.15f) 0500 fprintf(outfile, "Ambient temperature: %6.2f° C\n", P3.AmbientTemperature); 0501 if (P3.BatteryTemperature > -273.15f) 0502 fprintf(outfile, "Battery temperature: %6.2f° C\n", P3.BatteryTemperature); 0503 if (P3.FlashGN > 1.0f) 0504 fprintf(outfile, "Flash Guide Number: %6.2f\n", P3.FlashGN); 0505 fprintf(outfile, "Flash exposure compensation: %0.2f EV\n", P3.FlashEC); 0506 if (C.profile) 0507 fprintf(outfile, "Embedded ICC profile: yes, %d bytes\n", C.profile_length); 0508 else 0509 fprintf(outfile, "Embedded ICC profile: no\n"); 0510 0511 if (C.dng_levels.baseline_exposure > -999.f) 0512 fprintf(outfile, "Baseline exposure: %04.3f\n", C.dng_levels.baseline_exposure); 0513 0514 fprintf(outfile, "Number of raw images: %d\n", P1.raw_count); 0515 0516 if (S.pixel_aspect != 1) 0517 fprintf(outfile, "Pixel Aspect Ratio: %0.6f\n", S.pixel_aspect); 0518 if (T.tlength) 0519 fprintf(outfile, "Thumb size: %4d x %d\n", T.twidth, T.theight); 0520 fprintf(outfile, "Full size: %4d x %d\n", S.raw_width, S.raw_height); 0521 0522 if (S.raw_inset_crops[0].cwidth) 0523 { 0524 fprintf(outfile, "Raw inset, width x height: %4d x %d ", S.raw_inset_crops[0].cwidth, S.raw_inset_crops[0].cheight); 0525 if (S.raw_inset_crops[0].cleft != 0xffff) 0526 fprintf(outfile, "left: %d ", S.raw_inset_crops[0].cleft); 0527 if (S.raw_inset_crops[0].ctop != 0xffff) 0528 fprintf(outfile, "top: %d", S.raw_inset_crops[0].ctop); 0529 fprintf(outfile, "\n"); 0530 } 0531 0532 fprintf(outfile, "Image size: %4d x %d\n", S.width, S.height); 0533 fprintf(outfile, "Output size: %4d x %d\n", S.iwidth, S.iheight); 0534 fprintf(outfile, "Image flip: %d\n", S.flip); 0535 0536 fprintf(outfile, "Raw colors: %d", P1.colors); 0537 if (P1.filters) 0538 { 0539 fprintf(outfile, "\nFilter pattern: "); 0540 if (!P1.cdesc[3]) 0541 P1.cdesc[3] = 'G'; 0542 for (int i = 0; i < 16; i++) 0543 putchar(P1.cdesc[MyCoolRawProcessor.fcol(i >> 1, i & 1)]); 0544 } 0545 0546 if (C.black) 0547 { 0548 fprintf(outfile, "\nblack: %d", C.black); 0549 } 0550 if (C.cblack[0] != 0) 0551 { 0552 fprintf(outfile, "\ncblack[0 .. 3]:"); 0553 for (int c = 0; c < 4; c++) 0554 fprintf(outfile, " %d", C.cblack[c]); 0555 } 0556 if ((C.cblack[4] * C.cblack[5]) > 0) 0557 { 0558 fprintf(outfile, "\nBlackLevelRepeatDim: %d x %d\n", C.cblack[4], C.cblack[5]); 0559 int n = C.cblack[4] * C.cblack[5]; 0560 fprintf(outfile, "cblack[6 .. %d]:", 6 + n - 1); 0561 for (int c = 6; c < 6 + n; c++) 0562 fprintf(outfile, " %d", C.cblack[c]); 0563 } 0564 0565 if (C.linear_max[0] != 0) 0566 { 0567 fprintf(outfile, "\nHighlight linearity limits:"); 0568 for (int c = 0; c < 4; c++) 0569 fprintf(outfile, " %ld", C.linear_max[c]); 0570 } 0571 0572 if (P1.colors > 1) 0573 { 0574 fprintf(outfile, "\nMakernotes WB data: coeffs EVs"); 0575 if ((C.cam_mul[0] > 0) && (C.cam_mul[1] > 0)) 0576 { 0577 fprintf(outfile, "\n %-23s %g %g %g %g %5.2f %5.2f %5.2f %5.2f", "As shot", C.cam_mul[0], C.cam_mul[1], 0578 C.cam_mul[2], C.cam_mul[3], roundf(_log2(C.cam_mul[0] / C.cam_mul[1]) * 100.0f) / 100.0f, 0.0f, 0579 roundf(_log2(C.cam_mul[2] / C.cam_mul[1]) * 100.0f) / 100.0f, 0580 C.cam_mul[3] ? roundf(_log2(C.cam_mul[3] / C.cam_mul[1]) * 100.0f) / 100.0f : 0.0f); 0581 } 0582 0583 for (int cnt = 0; cnt < int(sizeof WBToStr / sizeof *WBToStr); cnt++) 0584 { 0585 WBi = WBToStr[cnt].NumId; 0586 if ((C.WB_Coeffs[WBi][0] > 0) && (C.WB_Coeffs[WBi][1] > 0)) 0587 { 0588 denom = (float)C.WB_Coeffs[WBi][1]; 0589 fprintf(outfile, "\n %-23s %4d %4d %4d %4d %5.2f %5.2f %5.2f %5.2f", WBToStr[cnt].hrStrId, 0590 C.WB_Coeffs[WBi][0], C.WB_Coeffs[WBi][1], C.WB_Coeffs[WBi][2], C.WB_Coeffs[WBi][3], 0591 roundf(_log2((float)C.WB_Coeffs[WBi][0] / denom) * 100.0f) / 100.0f, 0.0f, 0592 roundf(_log2((float)C.WB_Coeffs[WBi][2] / denom) * 100.0f) / 100.0f, 0593 C.WB_Coeffs[3] ? roundf(_log2((float)C.WB_Coeffs[WBi][3] / denom) * 100.0f) / 100.0f : 0.0f); 0594 } 0595 } 0596 0597 if (C.rgb_cam[0][0] > 0.0001) 0598 { 0599 fprintf(outfile, "\n\nCamera2RGB matrix (mode: %d):\n", MyCoolRawProcessor.imgdata.params.use_camera_matrix); 0600 PRINTMATRIX3x4(outfile, C.rgb_cam, P1.colors); 0601 } 0602 0603 fprintf(outfile, "\nXYZ->CamRGB matrix:\n"); 0604 PRINTMATRIX4x3(outfile, C.cam_xyz, P1.colors); 0605 0606 for (int cnt = 0; cnt < 2; cnt++) 0607 { 0608 if (fabsf(C.P1_color[cnt].romm_cam[0]) > 0) 0609 { 0610 fprintf(outfile, "\nPhaseOne Matrix %d:\n", cnt + 1); 0611 for (int i = 0; i < 3; i++) 0612 fprintf(outfile, "%6.4f\t%6.4f\t%6.4f\n", C.P1_color[cnt].romm_cam[i * 3], 0613 C.P1_color[cnt].romm_cam[i * 3 + 1], C.P1_color[cnt].romm_cam[i * 3 + 2]); 0614 } 0615 } 0616 0617 if (fabsf(C.cmatrix[0][0]) > 0) 0618 { 0619 fprintf(outfile, "\ncamRGB -> sRGB Matrix:\n"); 0620 PRINTMATRIX3x4(outfile, C.cmatrix, P1.colors); 0621 } 0622 0623 if (fabsf(C.ccm[0][0]) > 0) 0624 { 0625 fprintf(outfile, "\nColor Correction Matrix:\n"); 0626 PRINTMATRIX3x4(outfile, C.ccm, P1.colors); 0627 } 0628 0629 for (int cnt = 0; cnt < 2; cnt++) 0630 { 0631 if (C.dng_color[cnt].illuminant != LIBRAW_WBI_None) 0632 { 0633 if (C.dng_color[cnt].illuminant <= LIBRAW_WBI_StudioTungsten) 0634 { 0635 fprintf(outfile, "\nDNG Illuminant %d: %s", cnt + 1, WB_idx2hrstr(C.dng_color[cnt].illuminant)); 0636 } 0637 else if (C.dng_color[cnt].illuminant == LIBRAW_WBI_Other) 0638 { 0639 fprintf(outfile, "\nDNG Illuminant %d: Other", cnt + 1); 0640 } 0641 else 0642 { 0643 fprintf(outfile, 0644 "\nDNG Illuminant %d is out of EXIF LightSources range " 0645 "[0:24, 255]: %d", 0646 cnt + 1, C.dng_color[cnt].illuminant); 0647 } 0648 } 0649 } 0650 0651 for (int n = 0; n < 2; n++) 0652 { 0653 if (fabsf(C.dng_color[n].colormatrix[0][0]) > 0) 0654 { 0655 fprintf(outfile, "\nDNG color matrix %d:\n", n + 1); 0656 PRINTMATRIX4x3(outfile, C.dng_color[n].colormatrix, P1.colors); 0657 } 0658 } 0659 0660 for (int n = 0; n < 2; n++) 0661 { 0662 if (fabsf(C.dng_color[n].calibration[0][0]) > 0) 0663 { 0664 fprintf(outfile, "\nDNG calibration matrix %d:\n", n + 1); 0665 for (int i = 0; i < P1.colors && i < 4; i++) 0666 { 0667 for (int j = 0; j < P1.colors && j < 4; j++) 0668 fprintf(outfile, "%6.4f\t", C.dng_color[n].calibration[j][i]); 0669 fprintf(outfile, "\n"); 0670 } 0671 } 0672 } 0673 0674 for (int n = 0; n < 2; n++) 0675 { 0676 if (fabsf(C.dng_color[n].forwardmatrix[0][0]) > 0) 0677 { 0678 fprintf(outfile, "\nDNG forward matrix %d:\n", n + 1); 0679 PRINTMATRIX3x4(outfile, C.dng_color[n].forwardmatrix, P1.colors); 0680 } 0681 } 0682 0683 fprintf(outfile, "\nDerived D65 multipliers:"); 0684 for (int c = 0; c < P1.colors; c++) 0685 fprintf(outfile, " %f", C.pre_mul[c]); 0686 fprintf(outfile, "\n"); 0687 } 0688 } 0689 0690 void print_wbfun(FILE *outfile, LibRaw &MyCoolRawProcessor, std::string &fn) 0691 { 0692 int WBi; 0693 float denom; 0694 fprintf(outfile, "// %s %s\n", P1.make, P1.model); 0695 for (int cnt = 0; cnt < int(sizeof WBToStr / sizeof *WBToStr); cnt++) 0696 { 0697 WBi = WBToStr[cnt].NumId; 0698 if (C.WB_Coeffs[WBi][0] && C.WB_Coeffs[WBi][1] && !WBToStr[cnt].aux_setting) 0699 { 0700 denom = (float)C.WB_Coeffs[WBi][1]; 0701 fprintf(outfile, "{\"%s\", \"%s\", %s, {%6.5ff, 1.0f, %6.5ff, ", P1.normalized_make, P1.normalized_model, 0702 WBToStr[cnt].StrId, C.WB_Coeffs[WBi][0] / denom, C.WB_Coeffs[WBi][2] / denom); 0703 if (C.WB_Coeffs[WBi][1] == C.WB_Coeffs[WBi][3]) 0704 fprintf(outfile, "1.0f}},\n"); 0705 else 0706 fprintf(outfile, "%6.5ff}},\n", C.WB_Coeffs[WBi][3] / denom); 0707 } 0708 } 0709 0710 for (int cnt = 0; cnt < 64; cnt++) 0711 if (C.WBCT_Coeffs[cnt][0]) 0712 { 0713 fprintf(outfile, "{\"%s\", \"%s\", %d, {%6.5ff, 1.0f, %6.5ff, ", P1.normalized_make, P1.normalized_model, 0714 (int)C.WBCT_Coeffs[cnt][0], C.WBCT_Coeffs[cnt][1] / C.WBCT_Coeffs[cnt][2], 0715 C.WBCT_Coeffs[cnt][3] / C.WBCT_Coeffs[cnt][2]); 0716 if (C.WBCT_Coeffs[cnt][2] == C.WBCT_Coeffs[cnt][4]) 0717 fprintf(outfile, "1.0f}},\n"); 0718 else 0719 fprintf(outfile, "%6.5ff}},\n", C.WBCT_Coeffs[cnt][4] / C.WBCT_Coeffs[cnt][2]); 0720 } 0721 else 0722 break; 0723 fprintf(outfile, "\n"); 0724 } 0725 0726 void print_szfun(FILE *outfile, LibRaw &MyCoolRawProcessor, std::string &fn) 0727 { 0728 fprintf(outfile, "%s\t%s\t%s\t%d\t%d\n", fn.c_str(), P1.make, P1.model, S.width, S.height); 0729 } 0730 0731 void print_unpackfun(FILE *outfile, LibRaw &MyCoolRawProcessor, int print_frame, std::string &fn) 0732 { 0733 char frame[48] = ""; 0734 if (print_frame) 0735 { 0736 ushort right_margin = S.raw_width - S.width - S.left_margin; 0737 ushort bottom_margin = S.raw_height - S.height - S.top_margin; 0738 snprintf(frame, 48, "F=%dx%dx%dx%d RS=%dx%d", S.left_margin, S.top_margin, right_margin, bottom_margin, S.raw_width, 0739 S.raw_height); 0740 } 0741 fprintf(outfile, "%s\t%s\t%s\t%s/%s\n", fn.c_str(), MyCoolRawProcessor.unpack_function_name(), frame, P1.make, 0742 P1.model); 0743 }