- Timestamp:
- 2021-02-26T19:39:51+13:00 (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Samsung.pm
r24107 r34921 8 8 # References: 1) Tae-Sun Park private communication 9 9 # 2) http://www.cybercom.net/~dcoffin/dcraw/ 10 # 3) Pascal de Bruijn private communication (NX100) 11 # 4) Jaroslav Stepanek via rt.cpan.org 12 # 5) Nick Livchits private communication 13 # 6) Sreerag Raghavan private communication (SM-C200) 14 # IB) Iliah Borg private communication (LibRaw) 15 # NJ) Niels Kristian Bech Jensen private communication 10 16 #------------------------------------------------------------------------------ 11 17 … … 13 19 14 20 use strict; 15 use vars qw($VERSION );21 use vars qw($VERSION %samsungLensTypes); 16 22 use Image::ExifTool qw(:DataAccess :Utils); 17 23 use Image::ExifTool::Exif; 18 24 19 $VERSION = '1. 08';25 $VERSION = '1.48'; 20 26 21 27 sub WriteSTMN($$$); 22 28 sub ProcessINFO($$$); 29 sub ProcessSamsungMeta($$$); 30 sub ProcessSamsungIFD($$$); 31 32 # Samsung LensType lookup 33 %samsungLensTypes = ( 34 # (added "Samsung NX" in all of these lens names - ref 4) 35 0 => 'Built-in or Manual Lens', #PH (EX1, WB2000) 36 1 => 'Samsung NX 30mm F2 Pancake', 37 2 => 'Samsung NX 18-55mm F3.5-5.6 OIS', # (also version II, ref 1) 38 3 => 'Samsung NX 50-200mm F4-5.6 ED OIS', 39 # what about the non-OIS version of the 18-55, 40 # which was supposed to be available before the 20-50? - PH 41 4 => 'Samsung NX 20-50mm F3.5-5.6 ED', #PH/4 42 5 => 'Samsung NX 20mm F2.8 Pancake', #PH 43 6 => 'Samsung NX 18-200mm F3.5-6.3 ED OIS', #4 44 7 => 'Samsung NX 60mm F2.8 Macro ED OIS SSA', #1 45 8 => 'Samsung NX 16mm F2.4 Pancake', #1/4 46 9 => 'Samsung NX 85mm F1.4 ED SSA', #4 47 10 => 'Samsung NX 45mm F1.8', #3 48 11 => 'Samsung NX 45mm F1.8 2D/3D', #3 49 12 => 'Samsung NX 12-24mm F4-5.6 ED', #4 50 13 => 'Samsung NX 16-50mm F2-2.8 S ED OIS', #forum3833 51 14 => 'Samsung NX 10mm F3.5 Fisheye', #NJ 52 15 => 'Samsung NX 16-50mm F3.5-5.6 Power Zoom ED OIS', #5 53 20 => 'Samsung NX 50-150mm F2.8 S ED OIS', #PH 54 21 => 'Samsung NX 300mm F2.8 ED OIS', #IB 55 ); 23 56 24 57 # range of values for Formats used in encrypted information … … 31 64 32 65 # Samsung "STMN" maker notes (ref PH) 33 %Image::ExifTool::Samsung:: Type1= (66 %Image::ExifTool::Samsung::Main = ( 34 67 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 35 68 WRITE_PROC => \&WriteSTMN, … … 39 72 FIRST_ENTRY => 0, 40 73 IS_OFFSET => [ 2 ], # tag 2 is 'IsOffset' 74 IS_SUBDIR => [ 11 ], 41 75 GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, 42 76 NOTES => q{ … … 54 88 IsOffset => 3, 55 89 Protected => 2, 90 WriteGroup => 'MakerNotes', 56 91 }, 57 92 3 => { … … 60 95 DataTag => 'PreviewImage', 61 96 Protected => 2, 62 }, 97 WriteGroup => 'MakerNotes', 98 }, 99 11 => { 100 Name => 'SamsungIFD', 101 # Note: this is not always an IFD. In many models the string 102 # "Park Byeongchan" is found at this location 103 Condition => '$$valPt =~ /^[^\0]\0\0\0/', 104 Format => 'undef[$size - 44]', 105 SubDirectory => { TagTable => 'Image::ExifTool::Samsung::IFD' }, 106 }, 107 ); 108 109 %Image::ExifTool::Samsung::IFD = ( 110 PROCESS_PROC => \&ProcessSamsungIFD, 111 NOTES => q{ 112 This is a standard-format IFD found in the maker notes of some Samsung 113 models, except that the entry count is a 4-byte integer and the offsets are 114 relative to the end of the IFD. Currently, no tags in this IFD are known, 115 so the L<Unknown|../ExifTool.html#Unknown> (-u) or L<Verbose|../ExifTool.html#Verbose> (-v) option must be used to see this 116 information. 117 }, 118 GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, 119 # 0x0001 - undef[4000|4100]: starts with "MN_PRV" (or all zeros) 120 # 0x0002 - undef[7000] : starts with "Kim Miae" 121 # 0x0003 - undef[5000] : starts with "Lee BK" 122 # 0x0004 - undef[500|2000] : starts with "IPCD" (or all zeros) 123 # 0x0006 - undef[100|200] : starts with "MN_ADS" (or all zeros) 63 124 ); 64 125 … … 75 136 Count => 4, 76 137 }, 138 0x0002 => { 139 Name => 'DeviceType', 140 Groups => { 2 => 'Camera' }, 141 Writable => 'int32u', 142 PrintHex => 1, 143 PrintConv => { 144 0x1000 => 'Compact Digital Camera', 145 0x2000 => 'High-end NX Camera', 146 0x3000 => 'HXM Video Camera', 147 0x12000 => 'Cell Phone', 148 0x300000 => 'SMX Video Camera', 149 }, 150 }, 151 0x0003 => { 152 Name => 'SamsungModelID', 153 Groups => { 2 => 'Camera' }, 154 Writable => 'int32u', 155 PrintHex => 1, 156 PrintConv => { 157 0x100101c => 'NX10', 158 0x1001226 => 'HMX-S10BP', 159 0x1001226 => 'HMX-S15BP', 160 0x1001233 => 'HMX-Q10', 161 0x1001234 => 'HMX-H300', 162 0x1001234 => 'HMX-H304', 163 0x100130c => 'NX100', 164 0x1001327 => 'NX11', 165 0x170104b => 'ES65, ES67 / VLUU ES65, ES67 / SL50', 166 0x170104e => 'ES70, ES71 / VLUU ES70, ES71 / SL600', 167 0x1701052 => 'ES73 / VLUU ES73 / SL605', 168 0x1701055 => 'ES25, ES27 / VLUU ES25, ES27 / SL45', 169 0x1701300 => 'ES28 / VLUU ES28', 170 0x1701303 => 'ES74,ES75,ES78 / VLUU ES75,ES78', 171 0x2001046 => 'PL150 / VLUU PL150 / TL210 / PL151', 172 0x2001048 => 'PL100 / TL205 / VLUU PL100 / PL101', 173 0x2001311 => 'PL120,PL121 / VLUU PL120,PL121', 174 0x2001315 => 'PL170,PL171 / VLUUPL170,PL171', 175 0x200131e => 'PL210, PL211 / VLUU PL210, PL211', 176 0x2701317 => 'PL20,PL21 / VLUU PL20,PL21', 177 0x2a0001b => 'WP10 / VLUU WP10 / AQ100', 178 0x3000000 => 'Various Models (0x3000000)', 179 #0x3000000 => 'DV150F / DV151F / DV155F', 180 #0x3000000 => 'NX mini', 181 #0x3000000 => 'NX3000', 182 #0x3000000 => 'NX3300', 183 #0x3000000 => 'ST150F / ST151F / ST152F', 184 #0x3000000 => 'WB200F / WB201F / WB202F', 185 #0x3000000 => 'WB250F / WB251F / WB252F', 186 #0x3000000 => 'WB30F / WB31F / WB32F', 187 #0x3000000 => 'WB350F / WB351F / WB352F', 188 #0x3000000 => 'WB800F', 189 0x3a00018 => 'Various Models (0x3a00018)', 190 #0x3a00018 => 'ES30 / VLUU ES30', 191 #0x3a00018 => 'ES80 / ES81', 192 #0x3a00018 => 'ES9 / ES8', 193 #0x3a00018 => 'PL200 / VLUU PL200', 194 #0x3a00018 => 'PL80 / VLUU PL80 / SL630 / PL81', 195 #0x3a00018 => 'PL90 / VLUU PL90', 196 #0x3a00018 => 'WB1100F / WB1101F / WB1102F', 197 #0x3a00018 => 'WB2200F', 198 0x400101f => 'ST1000 / ST1100 / VLUU ST1000 / CL65', 199 0x4001022 => 'ST550 / VLUU ST550 / TL225', 200 0x4001025 => 'Various Models (0x4001025)', 201 #0x4001025 => 'DV300 / DV300F / DV305F', 202 #0x4001025 => 'ST500 / VLUU ST500 / TL220', 203 #0x4001025 => 'ST200 / ST200F / ST201 / ST201F / ST205F', 204 0x400103e => 'VLUU ST5500, ST5500, CL80', 205 0x4001041 => 'VLUU ST5000, ST5000, TL240', 206 0x4001043 => 'ST70 / VLUU ST70 / ST71', 207 0x400130a => 'Various Models (0x400130a)', 208 #0x400130a => 'VLUU ST100, ST100', 209 #0x400130a => 'VLUU ST600, ST600', 210 #0x400130a => 'VLUU ST80, ST80', 211 0x400130e => 'ST90,ST91 / VLUU ST90,ST91', 212 0x4001313 => 'VLUU ST95, ST95', 213 0x4a00015 => 'VLUU ST60', 214 0x4a0135b => 'ST30, ST65 / VLUU ST65 / ST67', 215 0x5000000 => 'Various Models (0x5000000)', 216 #0x5000000 => 'EX2F', 217 #0x5000000 => 'NX1000', 218 #0x5000000 => 'NX20', 219 #0x5000000 => 'NX200', 220 #0x5000000 => 'NX210', 221 #0x5000000 => 'ST96', 222 #0x5000000 => 'WB750', 223 #0x5000000 => 'ST700', 224 0x5001038 => 'Various Models (0x5001038)', 225 #0x5001038 => 'EK-GN120', 226 #0x5001038 => 'HMX-E10', 227 #0x5001038 => 'NX1', 228 #0x5001038 => 'NX2000', 229 #0x5001038 => 'NX30', 230 #0x5001038 => 'NX300', 231 #0x5001038 => 'NX500', 232 #0x5001038 => 'SM-C200', 233 #0x5001038 => 'WB2000', 234 0x500103a => 'WB650 / VLUU WB650 / WB660', 235 0x500103c => 'WB600 / VLUU WB600 / WB610', 236 0x500133e => 'WB150 / WB150F / WB152 / WB152F / WB151', 237 0x5a0000f => 'WB5000 / HZ25W', 238 0x5a0001e => 'WB5500 / VLUU WB5500 / HZ50W', 239 0x6001036 => 'EX1', 240 0x700131c => 'VLUU SH100, SH100', 241 0x27127002 => 'SMX-C20N', 242 }, 243 }, 244 # 0x0004 - undef[x] (SamsungContentsID?) 245 # 0x000a - int32u (ContinuousShotMode?) 246 # 0x000b - int16u (BestPhotoMode?) 247 # 0x000c - int32u ? values: 0,1 248 # 0x000e - int32u[2] (SoundMultiPicture?) 249 # 0x0010 - rational64u ? values: undef,inf 250 0x0011 => { #6 251 Name => 'OrientationInfo', 252 SubDirectory => { TagTable => 'Image::ExifTool::Samsung::OrientationInfo' }, 253 }, 254 0x0020 => [{ #forum7685 255 Name => 'SmartAlbumColor', 256 Condition => '$$valPt =~ /^\0{4}/', 257 Writable => 'int16u', 258 Count => 2, 259 PrintConv => { 260 '0 0' => 'n/a', 261 }, 262 },{ 263 Name => 'SmartAlbumColor', 264 Writable => 'int16u', 265 Count => 2, 266 PrintConv => [{ 267 0 => 'Red', 268 1 => 'Yellow', 269 2 => 'Green', 270 3 => 'Blue', 271 4 => 'Magenta', 272 5 => 'Black', 273 6 => 'White', 274 7 => 'Various', 275 }], 276 }], 77 277 0x0021 => { #1 78 278 Name => 'PictureWizard', 79 279 Writable => 'int16u', 80 Count => 5, 81 PrintConv => q{ 82 my @a = split ' ', $val; 83 return $val unless @a == 5; 84 sprintf("Mode: %d, Col: %d, Sat: %d, Sha: %d, Con: %d", 85 $a[0], $a[1], $a[2]-4, $a[3]-4, $a[4]-4); 86 }, 87 PrintConvInv => q{ 88 my @a = ($val =~ /[+-]?\d+/g); 89 return $val unless @a >= 5; 90 sprintf("%d %d %d %d %d", $a[0], $a[1], $a[2]+4, $a[3]+4, $a[4]+4); 91 }, 92 }, 93 # 0x0023 - string: "0123456789" (PH) 280 SubDirectory => { TagTable => 'Image::ExifTool::Samsung::PictureWizard' }, 281 }, 282 # 0x0022 - int32u (CaptureMode?) (Gamma? eg. 65538 = 1.2, ref forum7720) 283 # 0x0023 - string: "0123456789" (PH) (placeholder for SerialNumber?) 284 # 0x0025 - int32u (ImageCount?) 285 # 0x002a - undef[4] (SNSDirectShare?) 286 # 0x002f - string (GPSInfo01?) 94 287 0x0030 => { #1 (NX100 with GPS) 95 288 Name => 'LocalLocationName', 289 Groups => { 2 => 'Location' }, 96 290 Writable => 'string', 97 291 Format => 'undef', … … 103 297 0x0031 => { #1 (NX100 with GPS) 104 298 Name => 'LocationName', 299 Groups => { 2 => 'Location' }, 105 300 Writable => 'string', 106 301 }, 107 0x0035 => { 302 # 0x0032 - string (GPSInfo03) 303 # 0x0033 - string (GPSInfo04) 304 # 0x0034 - string (GPSInfo05) 305 0x0035 => [{ 306 Name => 'PreviewIFD', 307 Condition => '$$self{TIFF_TYPE} eq "SRW" and $$self{Model} ne "EK-GN120"', # (not an IFD in JPEG images) 308 Groups => { 1 => 'PreviewIFD' }, 309 Flags => 'SubIFD', 310 SubDirectory => { 311 TagTable => 'Image::ExifTool::Nikon::PreviewIFD', 312 ByteOrder => 'Unknown', 313 Start => '$val', 314 }, 315 },{ 108 316 Name => 'PreviewIFD', 109 317 Condition => '$$self{TIFF_TYPE} eq "SRW"', # (not an IFD in JPEG images) … … 113 321 TagTable => 'Image::ExifTool::Nikon::PreviewIFD', 114 322 ByteOrder => 'Unknown', 115 Start => '$val', 323 Start => '$val - 36', 324 }, 325 }], 326 # 0x003a - int16u[2] (SmartLensInfo?) 327 # 0x003b - int16u[2] (PhotoStyleSelectInfo?) 328 # 0x003c - int16u (SmartRange?) 329 # 0x003d - int16u[5] (SmartCropInfo?) 330 # 0x003e - int32u (DualCapture?) 331 # 0x003f - int16u[2] (SGIFInfo?) 332 0x0040 => { #forum7432 333 Name => 'RawDataByteOrder', 334 PrintConv => { 335 0 => 'Little-endian (Intel, II)', 336 1 => 'Big-endian (Motorola, MM)', #(NC) 337 }, 338 }, 339 0x0041 => { #forum7684 340 Name => 'WhiteBalanceSetup', 341 Writable => 'int32u', 342 PrintConv => { 343 0 => 'Auto', 344 1 => 'Manual', 116 345 }, 117 346 }, … … 121 350 Writable => 'rational64s', 122 351 # (DPreview samples all 0.2 C --> pre-production model) 123 PrintConv => ' "$val C"',352 PrintConv => '$val =~ /\d/ ? "$val C" : $val', 124 353 PrintConvInv => '$val=~s/ ?C//; $val', 125 354 }, 126 # 0x00a0 - undef[8192]: white balance information (ref 1): 355 # 0x0045 => { Name => 'RawCompressionMode', Writable => 'int32u' }, # (related to ExposureMode, not raw compresison? ref forum7432) 356 # 0x004a - int32u[7] (ImageVerification?) 357 # 0x004b - int32u[2] (RewindInfo?) 358 # 0x0050 - int32u (ColorSpace? - inconsistent) values: 1 (related to compression mode, ref forum7432) 359 0x0050 => { #forum7432 360 Name => 'RawDataCFAPattern', 361 PrintConv => { 362 0 => 'Unchanged', 363 1 => 'Swap', 364 65535 => 'Roll', 365 }, 366 }, 367 # 0x0054 - int16u[2] (WeatherInfo?) 368 # 0x0060 - undef (AEInfo?) 369 # 0x0080 - undef (AFInfo?) 370 # 0x00a0 - undef[8192] (AWBInfo1): white balance information (ref 1): 127 371 # At byte 5788, the WBAdjust: "Adjust\0\X\0\Y\0\Z\xee\xea\xce\xab", where 128 372 # Y = BA adjust (0=Blue7, 7=0, 14=Amber7), Z = MG (0=Magenta7, 7=0, 14=Green7) 373 # 0x00a1 - undef (AWBInfo2?) 374 # 0x00c0 - undef (IPCInfo?) 375 # 0x00c7 - undef (SmartFunctionInfo?) 376 # 0x00e0 - int16u (SceneResult?) 377 # 0x00e1 - int16u[8] (SADebugInfo01?) 378 # 0x00e1 - int16u[x] (SADebugInfo02?) 379 0x0100 => { 380 Name => 'FaceDetect', 381 Writable => 'int16u', 382 PrintConv => { 0 => 'Off', 1 => 'On' }, #(NC) 383 }, 384 # 0x0101 - int16u[6] (FaceDetectInfo?) 385 # 0x0102 - int16u[x] (FaceDetectInfo?) 386 0x0120 => { 387 Name => 'FaceRecognition', 388 Writable => 'int32u', 389 PrintConv => { 0 => 'Off', 1 => 'On' }, #(NC) 390 }, 391 0x0123 => { Name => 'FaceName', Writable => 'string' }, 392 # 0x140 - undef (LensInfo?) 129 393 # 130 394 # the following tags found only in SRW images 131 395 # 132 # 0xa000 - rational64u: 1 or 1.1 (ref PH) 396 # 0xa000 - rational64u: 1 or 1.1 (ref PH) (MakerNoteVersion?) 133 397 0xa001 => { #1 134 398 Name => 'FirmwareName', … … 136 400 Writable => 'string', 137 401 }, 138 # 0xa002 - string[30]: '0' or 'DY049P000000' (ref PH) 402 0xa002 => { #PH/IB 403 Name => 'SerialNumber', 404 Condition => '$$valPt =~ /^\w{5}/', # should be at least 5 characters long 405 Groups => { 2 => 'Camera' }, 406 Writable => 'string', 407 }, 139 408 0xa003 => { #1 (SRW images only) 140 409 Name => 'LensType', 141 410 Groups => { 2 => 'Camera' }, 142 411 Writable => 'int16u', 143 PrintConv => { 144 0 => 'Built-in', #PH (EX1, WB2000) 145 1 => 'Samsung 30mm F2 Pancake', 146 2 => 'Samsung Zoom 18-55mm F3.5-5.6 OIS', 147 3 => 'Samsung Zoom 50-200mm F4-5.6 ED OIS', 148 # what about the non-OIS version of the 18-55, 149 # which was supposed to be available before the 20-50? 150 4 => 'Samsung 20-50mm F3.5-5.6 Compact Zoom', #PH 151 5 => 'Samsung 20mm F2.8 Pancake', #PH (guess) 152 }, 412 Count => -1, 413 PrintConv => [ \%samsungLensTypes ], 153 414 }, 154 415 0xa004 => { #1 … … 157 418 Writable => 'string', 158 419 }, 159 # 0xa005 - string[30]: constant for a given lens? Not the printed serial number (ref 1) 420 0xa005 => { 421 Name => 'InternalLensSerialNumber', # Not the printed serial number (ref 1) 422 Groups => { 2 => 'Camera' }, 423 Writable => 'string', 424 }, 160 425 0xa010 => { #1 161 426 Name => 'SensorAreas', … … 190 455 Writable => 'rational64u', 191 456 PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', 192 PrintConvInv => ' Image::ExifTool::Exif::ConvertFraction($val)',457 PrintConvInv => '$val', 193 458 }, 194 459 0xa019 => { #1 195 460 Name => 'FNumber', 461 Priority => 0, 196 462 Writable => 'rational64u', 197 463 PrintConv => 'sprintf("%.1f",$val)', … … 201 467 Name => 'FocalLengthIn35mmFormat', 202 468 Groups => { 2 => 'Camera' }, 469 Priority => 0, 203 470 Format => 'int32u', 204 471 ValueConv => '$val / 10', … … 207 474 PrintConvInv => '$val=~s/\s*mm$//;$val', 208 475 }, 476 # 0xa01b - int32u (ImageCount?) 477 # 0xa01b - int16u (LDCLens?) 209 478 0xa020 => { #1 210 479 Name => 'EncryptionKey', … … 246 515 RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,1)', 247 516 }, 248 #this doesn't seem correct 249 #0xa025 => { #PH/1 250 # Name => 'ColorTemperatureAuto', 251 # Writable => 'int32u', 252 # RawConv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,6)', 253 # RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,-6)', 254 #}, 517 0xa025 => { # (PostAEGain?) 518 Name => 'DigitalGain', #IB 519 Writable => 'int32u', 520 RawConv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,6)', 521 RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,-6)', 522 }, 523 0xa025 => { #IB 524 Name => 'HighlightLinearityLimit', 525 Writable => 'int32u', 526 }, 255 527 0xa028 => { #2/PH 256 528 Name => 'WB_RGGBLevelsBlack', … … 282 554 }, 283 555 0xa033 => { #1 284 Name => 'Samsung_Type2_0xa033', 285 Unknown => 1, 286 Hidden => 1, 556 Name => 'CbCrMatrixDefault', 287 557 Writable => 'int32s', 288 558 Count => 4, … … 291 561 }, 292 562 0xa034 => { #1 293 Name => 'Samsung_Type2_0xa034', 294 Unknown => 1, 295 Hidden => 1, 563 Name => 'CbCrMatrix', 296 564 Writable => 'int32s', 297 565 Count => 4, … … 300 568 }, 301 569 0xa035 => { #1 302 Name => 'Samsung_Type2_0xa035', 303 Unknown => 1, 304 Hidden => 1, 570 Name => 'CbCrGainDefault', 305 571 Writable => 'int32u', 306 572 Count => 2, … … 309 575 }, 310 576 0xa036 => { #1 311 Name => 'Samsung_Type2_0xa036', 312 Unknown => 1, 313 Hidden => 1, 577 Name => 'CbCrGain', 314 578 Writable => 'int32u', 315 579 Count => 2, … … 318 582 }, 319 583 0xa040 => { #1 320 Name => 'ToneCurve 1',584 Name => 'ToneCurveSRGBDefault', 321 585 Writable => 'int32u', 322 586 Count => 23, … … 329 593 }, 330 594 0xa041 => { #1 331 Name => 'ToneCurve 2',595 Name => 'ToneCurveAdobeRGBDefault', 332 596 Writable => 'int32u', 333 597 Count => 23, … … 336 600 }, 337 601 0xa042 => { #1 338 Name => 'ToneCurve 3',602 Name => 'ToneCurveSRGB', 339 603 Writable => 'int32u', 340 604 Count => 23, … … 343 607 }, 344 608 0xa043 => { #1 345 Name => 'ToneCurve 4',609 Name => 'ToneCurveAdobeRGB', 346 610 Writable => 'int32u', 347 611 Count => 23, … … 350 614 }, 351 615 0xa048 => { #1 352 Name => ' Samsung_Type2_0xa048',616 Name => 'RawData', 353 617 Unknown => 1, 354 Hidden => 1,355 618 Writable => 'int32s', 356 619 Count => 12, … … 358 621 RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,"-0")', 359 622 }, 360 0xa050 => { #1 (vignette curve?)361 Name => ' Samsung_Type2_0xa050',623 0xa050 => { #1 624 Name => 'Distortion', 362 625 Unknown => 1, 363 Hidden => 1,364 626 Writable => 'int32s', 365 627 Count => 8, … … 368 630 }, 369 631 0xa051 => { #1 370 Name => ' Samsung_Type2_0xa051',632 Name => 'ChromaticAberration', 371 633 Unknown => 1, 372 Hidden => 1,373 634 Writable => 'int16u', 374 635 Count => 22, … … 376 637 RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,0,7,3)', 377 638 }, 378 0xa052 => { #1 (vignette curve?)379 Name => ' Samsung_Type2_0xa052',639 0xa052 => { #1 640 Name => 'Vignetting', 380 641 Unknown => 1, 381 Hidden => 1,382 642 Writable => 'int16u', 383 643 Count => 15, … … 386 646 }, 387 647 0xa053 => { #1 388 Name => ' Samsung_Type2_0xa053',648 Name => 'VignettingCorrection', 389 649 Unknown => 1, 390 Hidden => 1,391 650 Writable => 'int16u', 392 651 Count => 15, … … 395 654 }, 396 655 0xa054 => { #1 397 Name => ' Samsung_Type2_0xa054',656 Name => 'VignettingSetting', 398 657 Unknown => 1, 399 Hidden => 1,400 658 Writable => 'int16u', 401 659 Count => 15, … … 404 662 }, 405 663 0xa055 => { #1 406 Name => 'Samsung_Type2_0xa055', 664 Name => 'Samsung_Type2_0xa055', # (DistortionCamera1st?) 407 665 Unknown => 1, 408 666 Hidden => 1, … … 413 671 }, 414 672 0xa056 => { #1 415 Name => 'Samsung_Type2_0xa056', 673 Name => 'Samsung_Type2_0xa056', # (DistortionCamera2nd?) 416 674 Unknown => 1, 417 675 Hidden => 1, … … 422 680 }, 423 681 0xa057 => { #1 424 Name => 'Samsung_Type2_0xa057', 682 Name => 'Samsung_Type2_0xa057', # (DistortionCameraSetting?) 425 683 Unknown => 1, 426 684 Hidden => 1, … … 429 687 RawConv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,2)', 430 688 RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,-2)', 689 }, 690 # 0xa060 - rational64u (CISTemperature?) 691 # 0xa061 - int16u (Compression?) 692 ); 693 694 # orientation information (ref 6) 695 %Image::ExifTool::Samsung::OrientationInfo = ( 696 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 697 WRITE_PROC => \&Image::ExifTool::WriteBinaryData, 698 CHECK_PROC => \&Image::ExifTool::CheckBinaryData, 699 WRITABLE => 1, 700 FORMAT => 'rational64s', 701 FIRST_ENTRY => 0, 702 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, 703 NOTES => 'Camera orientation information written by the Gear 360 (SM-C200).', 704 0 => { 705 Name => 'YawAngle', #(NC) 706 Unknown => 1, 707 Notes => 'always zero', 708 }, 709 1 => { 710 Name => 'PitchAngle', 711 Notes => 'upward tilt of rear camera in degrees', 712 }, 713 2 => { 714 Name => 'RollAngle', 715 Notes => 'clockwise rotation of rear camera in degrees', 716 }, 717 ); 718 719 # Picture Wizard information (ref 1) 720 %Image::ExifTool::Samsung::PictureWizard = ( 721 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 722 WRITE_PROC => \&Image::ExifTool::WriteBinaryData, 723 CHECK_PROC => \&Image::ExifTool::CheckBinaryData, 724 WRITABLE => 1, 725 FORMAT => 'int16u', 726 FIRST_ENTRY => 0, 727 GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, 728 0 => { 729 Name => 'PictureWizardMode', 730 PrintConvColumns => 3, 731 PrintConv => { #3 732 0 => 'Standard', 733 1 => 'Vivid', 734 2 => 'Portrait', 735 3 => 'Landscape', 736 4 => 'Forest', 737 5 => 'Retro', 738 6 => 'Cool', 739 7 => 'Calm', 740 8 => 'Classic', 741 9 => 'Custom1', 742 10 => 'Custom2', 743 11 => 'Custom3', 744 255 => 'n/a', #PH 745 }, 746 }, 747 1 => 'PictureWizardColor', 748 2 => { 749 Name => 'PictureWizardSaturation', 750 ValueConv => '$val - 4', 751 ValueConvInv => '$val + 4', 752 }, 753 3 => { 754 Name => 'PictureWizardSharpness', 755 ValueConv => '$val - 4', 756 ValueConvInv => '$val + 4', 757 }, 758 4 => { 759 Name => 'PictureWizardContrast', 760 ValueConv => '$val - 4', 761 ValueConvInv => '$val + 4', 431 762 }, 432 763 ); … … 465 796 Format => 'string[16]', 466 797 }, 467 0x2e => { # 798 0x2e => { #(NC) 468 799 Name => 'ExposureTime', 469 800 Format => 'int32u', … … 476 807 PrintConv => 'sprintf("%.1f",$val)', 477 808 }, 478 0x3a => { # 809 0x3a => { #(NC) 479 810 Name => 'ExposureCompensation', 480 811 Format => 'rational64s', … … 488 819 Name => 'Software', 489 820 Format => 'string[32]', 490 # (these tags are not at a constant offset for Sanyo videos,821 # (these tags are not at a constant offset for Olympus/Sanyo videos, 491 822 # so just to be safe use this to validate subsequent tags) 492 823 RawConv => q{ … … 496 827 }, 497 828 }, 498 0xf 8=> {499 Name => 'Thumbnail Width',829 0xf4 => { 830 Name => 'Thumbnail', 500 831 Condition => '$$self{SamsungMP4}', 501 Format => 'int32u', 502 }, 503 0xfc => { 504 Name => 'ThumbnailHeight', 505 Condition => '$$self{SamsungMP4}', 506 Format => 'int32u', 507 }, 508 0x100 => { 509 Name => 'ThumbnailLength', 510 Condition => '$$self{SamsungMP4}', 511 Format => 'int32u', 512 }, 513 0x104 => { 514 Name => 'ThumbnailOffset', 515 Condition => '$$self{SamsungMP4}', 516 IsOffset => 1, 517 Format => 'int32u', 518 RawConv => '$val + 0xf4', 519 }, 832 SubDirectory => { 833 TagTable => 'Image::ExifTool::Samsung::Thumbnail', 834 Base => '$start', 835 }, 836 }, 837 ); 838 839 # thumbnail image information found in MP4 videos (similar in Olympus,Samsung,Sanyo) 840 %Image::ExifTool::Samsung::Thumbnail = ( 841 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 842 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, 843 FIRST_ENTRY => 0, 844 FORMAT => 'int32u', 845 1 => 'ThumbnailWidth', 846 2 => 'ThumbnailHeight', 847 3 => 'ThumbnailLength', 848 4 => { Name => 'ThumbnailOffset', IsOffset => 1 }, 849 ); 850 851 # Samsung MP4 @sec information (PH - from WB30F sample) 852 %Image::ExifTool::Samsung::sec = ( 853 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 854 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, 855 NOTES => q{ 856 This information is found in the @sec atom of Samsung MP4 videos from models 857 such as the WB30F. 858 }, 859 0x00 => { 860 Name => 'Make', 861 Format => 'string[32]', 862 PrintConv => 'ucfirst(lc($val))', 863 }, 864 0x20 => { 865 Name => 'Model', 866 Description => 'Camera Model Name', 867 Format => 'string[32]', 868 }, 869 0x200 => { Name => 'ThumbnailWidth', Format => 'int32u' }, 870 0x204 => { Name => 'ThumbnailHeight', Format => 'int32u' }, 871 0x208 => { Name => 'ThumbnailLength', Format => 'int32u' }, # (2 bytes too long in my sample) 872 0x20c => { 873 Name => 'ThumbnailImage', 874 Groups => { 2 => 'Preview' }, 875 Format => 'undef[$val{0x208}]', 876 Notes => 'the THM image, embedded metadata is extracted as the first sub-document', 877 SetBase => 1, 878 RawConv => q{ 879 my $pt = $self->ValidateImage(\$val, $tag); 880 if ($pt) { 881 $$self{BASE} += 0x20c; 882 $$self{DOC_NUM} = ++$$self{DOC_COUNT}; 883 $self->ExtractInfo($pt, { ReEntry => 1 }); 884 $$self{DOC_NUM} = 0; 885 } 886 return $pt; 887 }, 888 }, 889 ); 890 891 # Samsung MP4 smta information (PH - from SM-C101 sample) 892 %Image::ExifTool::Samsung::smta = ( 893 GROUPS => { 0 => 'MakerNotes', 2 => 'Video' }, 894 NOTES => q{ 895 This information is found in the smta atom of Samsung MP4 videos from models 896 such as the Galaxy S4. 897 }, 898 svss => { 899 Name => 'SamsungSvss', 900 SubDirectory => { TagTable => 'Image::ExifTool::Samsung::svss' }, 901 }, 902 # swtr - 4 bytes, all zero 903 # scid - 8 bytes, all zero 904 # saut - 4 bytes, all zero 905 ); 906 907 # Samsung MP4 svss information (PH - from SM-C101 sample) 908 %Image::ExifTool::Samsung::svss = ( 909 GROUPS => { 0 => 'MakerNotes', 2 => 'Video' }, 910 NOTES => q{ 911 This information is found in the svss atom of Samsung MP4 videos from models 912 such as the Galaxy S4. 913 }, 914 # junk - 10240 bytes, all zero 915 ); 916 917 # thumbnail image information found in some MP4 videos 918 %Image::ExifTool::Samsung::Thumbnail2 = ( 919 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 920 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, 921 FIRST_ENTRY => 0, 922 FORMAT => 'int32u', 923 1 => 'ThumbnailWidth', 924 2 => 'ThumbnailHeight', 925 3 => 'ThumbnailLength', 926 4 => { Name => 'ThumbnailOffset', IsOffset => 1 }, 927 ); 928 929 # information extracted from "ssuniqueid\0" APP5 (ref PH) 930 %Image::ExifTool::Samsung::APP5 = ( 931 GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, 932 ssuniqueid => { 933 Name => 'UniqueID', 934 # 32 bytes - some sort of serial number? 935 ValueConv => 'unpack("H*",$val)', 936 }, 937 ); 938 939 # information extracted from Samsung trailer (ie. Samsung SM-T805 "Sound & Shot" JPEG) (ref PH) 940 %Image::ExifTool::Samsung::Trailer = ( 941 GROUPS => { 0 => 'MakerNotes', 2 => 'Other' }, 942 VARS => { NO_ID => 1, HEX_ID => 0 }, 943 NOTES => q{ 944 Tags extracted from the trailer of JPEG images written when using certain 945 features (such as "Sound & Shot" or "Shot & More") from Samsung models such 946 as the Galaxy S4 and Tab S. 947 }, 948 '0x0001-name' => 'EmbeddedImageName', # ("DualShot_1","DualShot_2") 949 '0x0001' => { Name => 'EmbeddedImage', Groups => { 2 => 'Preview' }, Binary => 1 }, 950 '0x0100-name' => 'EmbeddedAudioFileName', # ("SoundShot_000") 951 '0x0100' => { Name => 'EmbeddedAudioFile', Groups => { 2 => 'Audio' }, Binary => 1 }, 952 '0x0201-name' => 'SurroundShotVideoName', # ("Interactive_Panorama_000") 953 '0x0201' => { Name => 'SurroundShotVideo', Groups => { 2 => 'Video' }, Binary => 1 }, 954 # 0x0800-name - seen 'SoundShot_Meta_Info' 955 # 0x0800 - unknown (29 bytes) (contains already-extracted EmbeddedAudioFileName) 956 # 0x0830-name - seen '1165724808.pre' 957 # 0x0830 - unknown (164004 bytes) 958 # 0x08d0-name - seen 'Interactive_Panorama_Info' 959 # 0x08d0 - unknown (7984 bytes) 960 # 0x08e0-name - seen 'Panorama_Shot_Info' 961 # 0x08e0 - string, seen 'PanoramaShot' 962 # 0x08e1-name - seen 'Motion_Panorama_Info' 963 # 0x0910-name - seen 'Front_Cam_Selfie_Info' 964 # 0x0910 - string, seen 'Front_Cam_Selfie_Info' 965 # 0x09e0-name - seen 'Burst_Shot_Info' 966 # 0x09e0 - string, seen '489489125' 967 # 0x0a01-name - seen 'Image_UTC_Data' 968 '0x0a01' => { #forum7161 969 Name => 'TimeStamp', 970 Groups => { 2 => 'Time' }, 971 ValueConv => 'ConvertUnixTime($val / 1e3, 1)', 972 PrintConv => '$self->ConvertDateTime($val)', 973 }, 974 '0x0a20-name' => 'DualCameraImageName', # ("FlipPhoto_002") 975 '0x0a20' => { Name => 'DualCameraImage', Groups => { 2 => 'Preview' }, Binary => 1 }, 976 '0x0a30-name' => 'EmbeddedVideoType', # ("MotionPhoto_Data") 977 '0x0a30' => { Name => 'EmbeddedVideoFile', Groups => { 2 => 'Video' }, Binary => 1 }, #forum7161 978 # 0x0aa1-name - seen 'MCC_Data' 979 # 0x0aa1 - seen '234','222','429' 980 # 0x0ab0-name - seen 'DualShot_Meta_Info' 981 '0x0ab1-name' => 'DepthMapName', # seen 'DualShot_DepthMap_1' (SM-N950U) 982 '0x0ab1' => { Name => 'DepthMapData', Binary => 1 }, 983 # 0x0ab3-name - seen 'DualShot_Extra_Info' (SM-N950U) 984 '0x0ab3' => { # (SM-N950U) 985 Name => 'DualShotExtra', 986 SubDirectory => { TagTable => 'Image::ExifTool::Samsung::DualShotExtra' }, 987 }, 988 # 0x0ac0-name - seen 'ZoomInOut_Info' (SM-N950U) 989 # 0x0ac0 - 2048 bytes of interesting stuff including firmware version? (SM-N950U) 990 '0x0b40' => { # (SM-N975X front camera) 991 Name => 'SingleShotMeta', 992 SubDirectory => { TagTable => 'Image::ExifTool::Samsung::SingleShotMeta' }, 993 }, 994 # 0x0b41-name - seen 'SingeShot_DepthMap_1' (Yes, "Singe") (SM-N975X front camera) 995 '0x0b41' => { Name => 'SingleShotDepthMap', Binary => 1 }, 996 # 0xa050-name - seen 'Jpeg360_2D_Info' (Samsung Gear 360) 997 # 0xa050 - seen 'Jpeg3602D' (Samsung Gear 360) 998 ); 999 1000 # DualShot Extra Info (ref PH) 1001 %Image::ExifTool::Samsung::DualShotExtra = ( 1002 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, 1003 GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, 1004 FIRST_ENTRY => 0, 1005 FORMAT => 'int32u', 1006 # This is a pain, but the DepthMapWidth/Height move around in this record. 1007 # In all of my samples so far, the bytes "01 00 ff ff" precede these tags. 1008 # I have seen this byte sequence at offsets 32, 60, 64 and 68, so look for 1009 # it in bytes 32-95, and use its location to adjust the tag positions 1010 8 => { 1011 Name => 'DualShotDummy', 1012 Format => 'undef[64]', 1013 Hidden => 1, 1014 Hook => q{ 1015 if ($size >= 96) { 1016 my $tmp = substr($$dataPt, $pos, 64); 1017 if ($tmp =~ /\x01\0\xff\xff/g and not pos($tmp) % 4) { 1018 $$self{DepthMapTagPos} = pos($tmp); 1019 $varSize += $$self{DepthMapTagPos} - 32; 1020 } 1021 } 1022 }, 1023 RawConv => 'undef', # not a real tag 1024 }, 1025 16 => { 1026 Name => 'DepthMapWidth', 1027 Condition => '$$self{DepthMapTagPos}', 1028 Notes => 'index varies depending on model', 1029 }, 1030 17 => { 1031 Name => 'DepthMapHeight', 1032 Condition => '$$self{DepthMapTagPos}', 1033 Notes => 'index varies depending on model', 1034 }, 1035 ); 1036 1037 # SingleShot Meta Info (ref PH) (SM-N975X front camera) 1038 %Image::ExifTool::Samsung::SingleShotMeta = ( 1039 PROCESS_PROC => \&ProcessSamsungMeta, 1040 GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, 1041 inputWidth => { }, 1042 inputHeight => { }, 1043 outputWidth => { }, 1044 outputHeight => { }, 1045 segWidth => { }, 1046 segHeight => { }, 1047 depthSWWidth => { }, 1048 depthSWHeight => { }, 1049 depthHWWidth => { }, 1050 depthHWHeight => { }, 1051 flipStatus => { }, 1052 lensFacing => { }, 1053 deviceOrientation => { }, 1054 objectOrientation => { }, 1055 isArtBokeh => { }, 1056 beautyRetouchLevel => { }, 1057 beautyColorLevel => { }, 1058 effectType => { }, 1059 effectStrength => { }, 1060 blurStrength => { }, 1061 spinStrength => { }, 1062 zoomStrength => { }, 1063 colorpopStrength => { }, 1064 monoStrength => { }, 1065 sidelightStrength => { }, 1066 vintageStrength => { }, 1067 bokehShape => { }, 1068 perfMode => { }, 520 1069 ); 521 1070 … … 533 1082 $a[$_] -= $b[$_] foreach 0..$#a; 534 1083 return "@a"; 1084 }, 1085 }, 1086 DepthMapTiff => { 1087 Require => { 1088 0 => 'DepthMapData', 1089 1 => 'DepthMapWidth', 1090 2 => 'DepthMapHeight', 1091 }, 1092 ValueConv => q{ 1093 return undef unless length ${$val[0]} == $val[1] * $val[2]; 1094 my $tiff = MakeTiffHeader($val[1],$val[2],1,8) . ${$val[0]}; 1095 return \$tiff; 1096 }, 1097 }, 1098 SingleShotDepthMapTiff => { 1099 Require => { 1100 0 => 'SingleShotDepthMap', 1101 1 => 'SegWidth', 1102 2 => 'SegHeight', 1103 }, 1104 ValueConv => q{ 1105 return undef unless length ${$val[0]} == $val[1] * $val[2]; 1106 my $tiff = MakeTiffHeader($val[1],$val[2],1,8) . ${$val[0]}; 1107 return \$tiff; 535 1108 }, 536 1109 }, … … 551 1124 sub Crypt($$$@) 552 1125 { 553 my ($e xifTool, $val, $tagInfo, @salt) = @_;554 my $key = $$e xifTool{EncryptionKey} or return undef;1126 my ($et, $val, $tagInfo, @salt) = @_; 1127 my $key = $$et{EncryptionKey} or return undef; 555 1128 my $format = $$tagInfo{Writable} || $$tagInfo{Format} or return undef; 556 1129 return undef unless $formatMinMax{$format}; … … 583 1156 sub ProcessINFO($$$) 584 1157 { 585 my ($e xifTool, $dirInfo, $tagTablePtr) = @_;1158 my ($et, $dirInfo, $tagTablePtr) = @_; 586 1159 my $dataPt = $$dirInfo{DataPt}; 587 1160 my $pos = $$dirInfo{DirStart}; 588 1161 my $len = $$dirInfo{DirLen}; 589 1162 my $end = $pos + $len; 590 $e xifTool->VerboseDir('INFO', undef, $len);1163 $et->VerboseDir('INFO', undef, $len); 591 1164 while ($pos + 8 <= $end) { 592 1165 my $tag = substr($$dataPt, $pos, 4); … … 595 1168 my $name = "Samsung_INFO_$tag"; 596 1169 $name =~ tr/-_0-9a-zA-Z//dc; 597 Image::ExifTool::AddTagToTable($tagTablePtr, $tag, { Name => $name }) if $name;1170 AddTagToTable($tagTablePtr, $tag, { Name => $name }) if $name; 598 1171 } 599 $e xifTool->HandleTag($tagTablePtr, $tag, $val);1172 $et->HandleTag($tagTablePtr, $tag, $val); 600 1173 $pos += 8; 601 1174 } 602 1175 return 1; 1176 } 1177 1178 #------------------------------------------------------------------------------ 1179 # Read Samsung Meta Info from trailer 1180 # Inputs: 0) ExifTool object ref, 1) source dirInfo ref, 2) tag table ref 1181 # Returns: true on success 1182 sub ProcessSamsungMeta($$$) 1183 { 1184 my ($et, $dirInfo, $tagTablePtr) = @_; 1185 my $dirName = $$dirInfo{DirName}; 1186 my $dataPt = $$dirInfo{DataPt}; 1187 my $pos = $$dirInfo{DirStart}; 1188 my $end = $$dirInfo{DirLen} + $pos; 1189 unless ($pos + 8 <= $end and substr($$dataPt, $pos, 4) eq 'DOFS') { 1190 $et->Warn("Unrecognized $dirName data"); 1191 return 0; 1192 } 1193 my $ver = Get32u($dataPt, $pos + 4); 1194 if ($ver == 3) { 1195 unless ($pos + 18 <= $end and Get32u($dataPt, $pos + 12) == $$dirInfo{DirLen}) { 1196 $et->Warn("Unrecognized $dirName version $ver data"); 1197 return 0; 1198 } 1199 my $num = Get16u($dataPt, $pos + 16); 1200 $et->VerboseDir("$dirName version $ver", $num); 1201 $pos += 18; 1202 my ($i, $val); 1203 for ($i=0; $i<$num; ++$i) { 1204 last if $pos + 2 > $end; 1205 my ($x, $n) = unpack("x${pos}CC", $$dataPt); 1206 $pos += 2; 1207 last if $pos + $n + 2 > $end; 1208 my $tag = substr($$dataPt, $pos, $n); 1209 my $len = Get16u($dataPt, $pos + $n); 1210 $pos += $n + 2; 1211 last if $pos + $len > $end; 1212 if ($len == 4) { 1213 $val = Get32u($dataPt, $pos); 1214 } else { 1215 my $tmp = substr($$dataPt, $pos, $len); 1216 $val = \$pos; 1217 } 1218 $et->HandleTag($tagTablePtr, $tag, $val); 1219 $pos += $len; 1220 } 1221 $et->Warn("Unexpected end of $dirName version $ver $i $num data") if $i < $num; 1222 } 1223 return 1; 1224 } 1225 1226 #------------------------------------------------------------------------------ 1227 # Inputs: 0) ExifTool object ref, 1) source dirInfo ref, 2) tag table ref 1228 # Returns: true on success 1229 sub ProcessSamsungIFD($$$) 1230 { 1231 my ($et, $dirInfo, $tagTablePtr) = @_; 1232 my $len = $$dirInfo{DataLen}; 1233 my $pos = $$dirInfo{DirStart}; 1234 return 0 unless $pos + 4 < $len; 1235 my $dataPt = $$dirInfo{DataPt}; 1236 my $buff = substr($$dataPt, $pos, 4); 1237 # this is not an IFD for many models 1238 # (the string "Park Byeongchan" is often found here) 1239 return 0 unless $buff =~ s/^([^\0])\0\0\0/$1\0$1\0/s; 1240 my $numEntries = ord $1; 1241 if ($$et{HTML_DUMP}) { 1242 my $pt = $$dirInfo{DirStart} + $$dirInfo{DataPos} + $$dirInfo{Base}; 1243 $et->HDump($pt-44, 44, "MakerNotes header", 'Samsung'); 1244 $et->HDump($pt, 4, "MakerNotes entries", "Format: int32u\nEntry count: $numEntries"); 1245 $$dirInfo{NoDumpEntryCount} = 1; 1246 } 1247 substr($$dataPt, $pos, 4) = $buff; # insert bogus 2-byte entry count 1248 # offset base is at end of IFD 1249 my $shift = $$dirInfo{DirStart} + 4 + $numEntries * 12 + 4; 1250 $$dirInfo{Base} += $shift; 1251 $$dirInfo{DataPos} -= $shift; 1252 $$dirInfo{DirStart} += 2; # start at bogus entry count 1253 $$dirInfo{ZeroOffsetOK} = 1; # disable check for zero offset 1254 delete $$et{NO_UNKNOWN}; # (set for BinaryData, but not for EXIF IFD's) 1255 my $rtn = Image::ExifTool::Exif::ProcessExif($et, $dirInfo, $tagTablePtr); 1256 substr($$dataPt, $pos + 2, 1) = "\0"; # remove bogus count 1257 return $rtn; 1258 } 1259 1260 #------------------------------------------------------------------------------ 1261 # Read/write Samsung trailer (ie. "Sound & Shot" written by Galaxy Tab S (SM-T805)) 1262 # Inputs: 0) ExifTool object reference, 1) dirInfo reference 1263 # Returns: 1 on success, 0 not valid Samsung trailer, or -1 error writing 1264 # - updates DataPos to point to start of Samsung trailer 1265 # - updates DirLen to existing trailer length 1266 sub ProcessSamsung($$$) 1267 { 1268 my ($et, $dirInfo) = @_; 1269 my $raf = $$dirInfo{RAF}; 1270 my $offset = $$dirInfo{Offset} || 0; 1271 my $outfile = $$dirInfo{OutFile}; 1272 my $verbose = $et->Options('Verbose'); 1273 my $unknown = $et->Options('Unknown'); 1274 my ($buff, $buf2, $index, $offsetPos, $audioNOff, $audioSize); 1275 1276 return 0 unless $raf->Seek(-6-$offset, 2) and $raf->Read($buff, 6) == 6 and 1277 ($buff eq 'QDIOBS' or $buff eq "\0\0SEFT"); 1278 my $endPos = $raf->Tell(); 1279 $raf->Seek(-2, 1) or return 0 if $buff eq 'QDIOBS'; # rewind to before 'BS' 1280 my $blockEnd = $raf->Tell(); 1281 SetByteOrder('II'); 1282 1283 # read blocks backward until we find the SEFH/SEFT block 1284 # (the only other block I have seen is QDIO/QDIO) 1285 SamBlock: 1286 for (;;) { 1287 last unless $raf->Seek($blockEnd-8, 0) and $raf->Read($buff, 8) == 8; 1288 my $type = substr($buff, 4); 1289 last unless $type =~ /^\w+$/; 1290 my $len = Get32u(\$buff, 0); 1291 last unless $len < 0x10000 and $len >= 4 and $len + 8 < $blockEnd; 1292 last unless $raf->Seek(-8-$len, 1) and $raf->Read($buff, $len) == $len; 1293 $blockEnd -= $len + 8; 1294 unless ($type eq 'SEFT') { # look for directory block (ends with "SEFT") 1295 next unless $outfile and $type eq 'QDIO'; 1296 # QDIO block format: 1297 # 0 - 'QDIO' 1298 # 4 - int32u: 101 (version) 1299 # 8 - int32u: 1 1300 # 12 - int32u: absolute offset of audio file start (augh!!) 1301 # 16 - int32u: absolute offset of audio file end (augh!!) 1302 # 20 - int32u: 20 (QDIO block length minus 8) 1303 # 24 - 'QDIO' 1304 if ($len == 20) { 1305 # save position of audio file offset in QDIO block 1306 $offsetPos = $endPos - $raf->Tell() + $len - 12; 1307 } else { 1308 $et->Error('Unsupported Samsung trailer QDIO block', 1); 1309 } 1310 next; 1311 } 1312 last unless $buff =~ /^SEFH/ and $len >= 12; # validate SEFH header 1313 my $dirPos = $raf->Tell() - $len; 1314 # my $ver = Get32u(\$buff, 0x04); # version (=101) 1315 my $count = Get32u(\$buff, 0x08); 1316 last if 12 + 12 * $count > $len; 1317 my $tagTablePtr = GetTagTable('Image::ExifTool::Samsung::Trailer'); 1318 1319 # scan ahead quickly to look for the block where the data comes first 1320 # (have only seen this to be the first in the directory, but just in case) 1321 my $firstBlock = 0; 1322 for ($index=0; $index<$count; ++$index) { 1323 my $entry = 12 + 12 * $index; 1324 my $noff = Get32u(\$buff, $entry + 4); # negative offset 1325 $firstBlock = $noff if $firstBlock < $noff; 1326 } 1327 # save trailer position and length 1328 my $dataPos = $$dirInfo{DataPos} = $dirPos - $firstBlock; 1329 my $dirLen = $$dirInfo{DirLen} = $endPos - $dataPos; 1330 if (($verbose or $$et{HTML_DUMP}) and not $outfile) { 1331 $et->DumpTrailer($dirInfo); 1332 return 1 if $$et{HTML_DUMP}; 1333 } 1334 # read through the SEFH/SEFT directory entries 1335 for ($index=0; $index<$count; ++$index) { 1336 my $entry = 12 + 12 * $index; 1337 # first 2 bytes always 0 (may be part of block type) 1338 my $type = Get16u(\$buff, $entry + 2); # block type 1339 my $noff = Get32u(\$buff, $entry + 4); # negative offset 1340 my $size = Get32u(\$buff, $entry + 8); # block size 1341 last SamBlock if $noff > $dirPos or $size > $noff or $size < 8; 1342 $firstBlock = $noff if $firstBlock < $noff; 1343 if ($outfile) { 1344 next unless $type == 0x0100 and not $audioNOff; 1345 # save offset and length of first audio file for QDIO block 1346 last unless $raf->Seek($dirPos-$noff, 0) and $raf->Read($buf2, 8) == 8; 1347 $len = Get32u(\$buf2, 4); 1348 $audioNOff = $noff - 8 - $len; # negative offset to start of audio data 1349 $audioSize = $size - 8 - $len; 1350 next; 1351 } 1352 # add unknown tags if necessary 1353 my $tag = sprintf("0x%.4x", $type); 1354 unless ($$tagTablePtr{$tag}) { 1355 next unless $unknown or $verbose; 1356 my %tagInfo = ( 1357 Name => "SamsungTrailer_$tag", 1358 Description => "Samsung Trailer $tag", 1359 Unknown => 1, 1360 Binary => 1, 1361 ); 1362 AddTagToTable($tagTablePtr, $tag, \%tagInfo); 1363 } 1364 unless ($$tagTablePtr{"$tag-name"}) { 1365 my %tagInfo2 = ( 1366 Name => "SamsungTrailer_${tag}Name", 1367 Description => "Samsung Trailer $tag Name", 1368 Unknown => 1, 1369 ); 1370 AddTagToTable($tagTablePtr, "$tag-name", \%tagInfo2); 1371 } 1372 last unless $raf->Seek($dirPos-$noff, 0) and $raf->Read($buf2, $size) == $size; 1373 # (could validate the first 4 bytes of the block because they 1374 # are the same as the first 4 bytes of the directory entry) 1375 $len = Get32u(\$buf2, 4); 1376 last if $len + 8 > $size; 1377 # extract tag name and value 1378 $et->HandleTag($tagTablePtr, "$tag-name", undef, 1379 DataPt => \$buf2, 1380 DataPos => $dirPos - $noff, 1381 Start => 8, 1382 Size => $len, 1383 ); 1384 $et->HandleTag($tagTablePtr, $tag, undef, 1385 DataPt => \$buf2, 1386 DataPos => $dirPos - $noff, 1387 Start => 8 + $len, 1388 Size => $size - (8 + $len), 1389 ); 1390 } 1391 if ($outfile) { 1392 last unless $raf->Seek($dataPos, 0) and $raf->Read($buff, $dirLen) == $dirLen; 1393 # adjust the absolute offset in the QDIO block if necessary 1394 if ($offsetPos and $audioNOff) { 1395 # initialize the audio file start/end position in the QDIO block 1396 my $newPos = Tell($outfile) + $dirPos - $audioNOff - $dataPos; 1397 Set32u($newPos, \$buff, length($buff) - $offsetPos); 1398 Set32u($newPos + $audioSize, \$buff, length($buff) - $offsetPos + 4); 1399 # add a fixup so the calling routine can apply further shifts if necessary 1400 require Image::ExifTool::Fixup; 1401 my $fixup = $$dirInfo{Fixup}; 1402 $fixup or $fixup = $$dirInfo{Fixup} = new Image::ExifTool::Fixup; 1403 $fixup->AddFixup(length($buff) - $offsetPos); 1404 $fixup->AddFixup(length($buff) - $offsetPos + 4); 1405 } 1406 $et->VPrint(0, "Writing Samsung trailer ($dirLen bytes)\n") if $verbose; 1407 Write($$dirInfo{OutFile}, $buff) or return -1; 1408 return 1; 1409 } 1410 return 1; 1411 } 1412 $et->Warn('Error processing Samsung trailer',1); 1413 return 0; 603 1414 } 604 1415 … … 609 1420 sub WriteSTMN($$$) 610 1421 { 611 my ($e xifTool, $dirInfo, $tagTablePtr) = @_;1422 my ($et, $dirInfo, $tagTablePtr) = @_; 612 1423 # create a Fixup for the PreviewImage 613 1424 $$dirInfo{Fixup} = new Image::ExifTool::Fixup; 614 my $val = Image::ExifTool::WriteBinaryData($e xifTool, $dirInfo, $tagTablePtr);1425 my $val = Image::ExifTool::WriteBinaryData($et, $dirInfo, $tagTablePtr); 615 1426 # force PreviewImage into the trailer even if it fits in EXIF segment 616 $$e xifTool{PREVIEW_INFO}{IsTrailer} = 1 if $$exifTool{PREVIEW_INFO};1427 $$et{PREVIEW_INFO}{IsTrailer} = 1 if $$et{PREVIEW_INFO}; 617 1428 return $val; 618 1429 } … … 637 1448 =head1 AUTHOR 638 1449 639 Copyright 2003-20 11, Phil Harvey (phil at owl.phy.queensu.ca)1450 Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com) 640 1451 641 1452 This library is free software; you can redistribute it and/or modify it 642 1453 under the same terms as Perl itself. 643 1454 1455 =head1 REFERENCES 1456 1457 =over 4 1458 1459 =item L<http://www.cybercom.net/~dcoffin/dcraw/> 1460 1461 =back 1462 644 1463 =head1 ACKNOWLEDGEMENTS 645 1464 646 Thanks to Tae-Sun Park for decoding a number of tags. 1465 Thanks to Tae-Sun Park for decoding a number of tags, Pascal de Bruijn for 1466 the PictureWizard values, and everyone else who helped by discovering new 1467 Samsung information. 647 1468 648 1469 =head1 SEE ALSO
Note:
See TracChangeset
for help on using the changeset viewer.