SonyIDC.pm 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. #------------------------------------------------------------------------------
  2. # File: SonyIDC.pm
  3. #
  4. # Description: Read/write Sony IDC information
  5. #
  6. # Revisions: 2010/01/05 - P. Harvey Created
  7. #------------------------------------------------------------------------------
  8. package Image::ExifTool::SonyIDC;
  9. use strict;
  10. use vars qw($VERSION);
  11. use Image::ExifTool qw(:DataAccess :Utils);
  12. use Image::ExifTool::Exif;
  13. $VERSION = '1.05';
  14. # Sony IDC tags (ref PH)
  15. %Image::ExifTool::SonyIDC::Main = (
  16. WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
  17. CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
  18. GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
  19. NOTES => 'Tags written by the Sony Image Data Converter utility in ARW images.',
  20. SET_GROUP1 => 1,
  21. 0x201 => {
  22. Name => 'IDCPreviewStart',
  23. IsOffset => 1,
  24. OffsetPair => 0x202,
  25. DataTag => 'IDCPreview',
  26. Writable => 'int32u',
  27. Protected => 2,
  28. },
  29. 0x202 => {
  30. Name => 'IDCPreviewLength',
  31. OffsetPair => 0x201,
  32. DataTag => 'IDCPreview',
  33. Writable => 'int32u',
  34. Protected => 2,
  35. },
  36. 0x8000 => {
  37. Name => 'IDCCreativeStyle',
  38. Writable => 'int32u',
  39. PrintConvColumns => 2,
  40. PrintConv => {
  41. 1 => 'Camera Setting',
  42. 2 => 'Standard',
  43. 3 => 'Real',
  44. 4 => 'Vivid',
  45. 5 => 'Adobe RGB',
  46. 6 => 'A100 Standard', # shows up as '-' in IDC menu
  47. 7 => 'Neutral',
  48. 8 => 'Portrait',
  49. 9 => 'Landscape',
  50. 10 => 'Clear',
  51. 11 => 'Deep',
  52. 12 => 'Light',
  53. 13 => 'Sunset',
  54. 14 => 'Night View',
  55. 15 => 'Autumn Leaves',
  56. 16 => 'B&W',
  57. 17 => 'Sepia',
  58. },
  59. },
  60. 0x8001 => {
  61. Name => 'CreativeStyleWasChanged',
  62. Writable => 'int32u',
  63. Notes => 'set if the creative style was ever changed',
  64. # (even if it was changed back again later)
  65. PrintConv => { 0 => 'No', 1 => 'Yes' },
  66. },
  67. 0x8002 => {
  68. Name => 'PresetWhiteBalance',
  69. Writable => 'int32u',
  70. PrintConv => {
  71. 1 => 'Camera Setting',
  72. 2 => 'Color Temperature',
  73. 3 => 'Specify Gray Point',
  74. 4 => 'Daylight',
  75. 5 => 'Cloudy',
  76. 6 => 'Shade',
  77. 7 => 'Cool White Fluorescent',
  78. 8 => 'Day Light Fluorescent',
  79. 9 => 'Day White Fluorescent',
  80. 10 => 'Warm White Fluorescent',
  81. 11 => 'Tungsten',
  82. 12 => 'Flash',
  83. 13 => 'Auto',
  84. },
  85. },
  86. 0x8013 => { Name => 'ColorTemperatureAdj', Writable => 'int16u' },
  87. 0x8014 => { Name => 'PresetWhiteBalanceAdj',Writable => 'int32s' },
  88. 0x8015 => { Name => 'ColorCorrection', Writable => 'int32s' },
  89. 0x8016 => { Name => 'SaturationAdj', Writable => 'int32s' },
  90. 0x8017 => { Name => 'ContrastAdj', Writable => 'int32s' },
  91. 0x8018 => { Name => 'BrightnessAdj', Writable => 'int32s' },
  92. 0x8019 => { Name => 'HueAdj', Writable => 'int32s' },
  93. 0x801a => { Name => 'SharpnessAdj', Writable => 'int32s' },
  94. 0x801b => { Name => 'SharpnessOvershoot', Writable => 'int32s' },
  95. 0x801c => { Name => 'SharpnessUndershoot', Writable => 'int32s' },
  96. 0x801d => { Name => 'SharpnessThreshold', Writable => 'int32s' },
  97. 0x801e => {
  98. Name => 'NoiseReductionMode',
  99. Writable => 'int16u',
  100. PrintConv => {
  101. 0 => 'Off',
  102. 1 => 'On',
  103. },
  104. },
  105. 0x8021 => {
  106. Name => 'GrayPoint',
  107. Writable => 'int16u',
  108. Count => 4,
  109. },
  110. 0x8022 => {
  111. Name => 'D-RangeOptimizerMode',
  112. Writable => 'int16u',
  113. PrintConv => {
  114. 0 => 'Off',
  115. 1 => 'Auto',
  116. 2 => 'Manual',
  117. },
  118. },
  119. 0x8023 => { Name => 'D-RangeOptimizerValue', Writable => 'int32s' },
  120. 0x8024 => { Name => 'D-RangeOptimizerHighlight',Writable => 'int32s' },
  121. 0x8026 => {
  122. Name => 'HighlightColorDistortReduct',
  123. Writable => 'int16u',
  124. PrintConv => {
  125. 0 => 'Standard',
  126. 1 => 'Advanced',
  127. },
  128. },
  129. 0x8027 => {
  130. Name => 'NoiseReductionValue',
  131. Writable => 'int32s',
  132. ValueConv => '($val + 100) / 2',
  133. ValueConvInv => '$val * 2 - 100',
  134. },
  135. 0x8028 => {
  136. Name => 'EdgeNoiseReduction',
  137. Writable => 'int32s',
  138. ValueConv => '($val + 100) / 2',
  139. ValueConvInv => '$val * 2 - 100',
  140. },
  141. 0x8029 => {
  142. Name => 'ColorNoiseReduction',
  143. Writable => 'int32s',
  144. ValueConv => '($val + 100) / 2',
  145. ValueConvInv => '$val * 2 - 100',
  146. },
  147. 0x802d => { Name => 'D-RangeOptimizerShadow', Writable => 'int32s' },
  148. 0x8030 => { Name => 'PeripheralIllumCentralRadius', Writable => 'int32s' },
  149. 0x8031 => { Name => 'PeripheralIllumCentralValue', Writable => 'int32s' },
  150. 0x8032 => { Name => 'PeripheralIllumPeriphValue', Writable => 'int32s' },
  151. 0x9000 => {
  152. Name => 'ToneCurveBrightnessX',
  153. Writable => 'int16u',
  154. Count => -1,
  155. },
  156. 0x9001 => {
  157. Name => 'ToneCurveRedX',
  158. Writable => 'int16u',
  159. Count => -1,
  160. },
  161. 0x9002 => {
  162. Name => 'ToneCurveGreenX',
  163. Writable => 'int16u',
  164. Count => -1,
  165. },
  166. 0x9003 => {
  167. Name => 'ToneCurveBlueX',
  168. Writable => 'int16u',
  169. Count => -1,
  170. },
  171. 0x9004 => {
  172. Name => 'ToneCurveBrightnessY',
  173. Writable => 'int16u',
  174. Count => -1,
  175. },
  176. 0x9005 => {
  177. Name => 'ToneCurveRedY',
  178. Writable => 'int16u',
  179. Count => -1,
  180. },
  181. 0x9006 => {
  182. Name => 'ToneCurveGreenY',
  183. Writable => 'int16u',
  184. Count => -1,
  185. },
  186. 0x9007 => {
  187. Name => 'ToneCurveBlueY',
  188. Writable => 'int16u',
  189. Count => -1,
  190. },
  191. 0xd000 => { Name => 'CurrentVersion', Writable => 'int32u' },
  192. 0xd001 => {
  193. Name => 'VersionIFD',
  194. Groups => { 1 => 'Version0' },
  195. Flags => 'SubIFD',
  196. Notes => 'there is one VersionIFD for each entry in the "Version Stack"',
  197. SubDirectory => {
  198. DirName => 'Version0',
  199. TagTable => 'Image::ExifTool::SonyIDC::Main',
  200. Start => '$val',
  201. Base => '$start',
  202. MaxSubdirs => 20, # (IDC v3.0 writes max. 10)
  203. RelativeBase => 1, # needed to write SubIFD with relative offsets
  204. },
  205. },
  206. 0xd100 => {
  207. Name => 'VersionCreateDate',
  208. Writable => 'string',
  209. Groups => { 2 => 'Time' },
  210. Notes => 'date/time when this entry was created in the "Version Stack"',
  211. Shift => 'Time',
  212. PrintConv => '$self->ConvertDateTime($val)',
  213. PrintConvInv => '$self->InverseDateTime($val,0)',
  214. },
  215. 0xd101 => {
  216. Name => 'VersionModifyDate',
  217. Writable => 'string',
  218. Groups => { 2 => 'Time' },
  219. Shift => 'Time',
  220. PrintConv => '$self->ConvertDateTime($val)',
  221. PrintConvInv => '$self->InverseDateTime($val,0)',
  222. },
  223. );
  224. # extract IDC preview images as composite tags
  225. %Image::ExifTool::SonyIDC::Composite = (
  226. GROUPS => { 2 => 'Image' },
  227. IDCPreviewImage => {
  228. Groups => { 2 => 'Preview' },
  229. Require => {
  230. 0 => 'IDCPreviewStart',
  231. 1 => 'IDCPreviewLength',
  232. },
  233. # extract all preview images (not just one)
  234. RawConv => q{
  235. require Image::ExifTool::SonyIDC;
  236. Image::ExifTool::SonyIDC::ExtractPreviews($self);
  237. },
  238. },
  239. );
  240. # add our composite tags
  241. Image::ExifTool::AddCompositeTags('Image::ExifTool::SonyIDC');
  242. # set "Permanent" flag for all tags
  243. {
  244. my $key;
  245. foreach $key (TagTableKeys(\%Image::ExifTool::SonyIDC::Main)) {
  246. $Image::ExifTool::SonyIDC::Main{$key}{Permanent} = 1;
  247. }
  248. }
  249. #------------------------------------------------------------------------------
  250. # Extract all IDC preview images
  251. # Inputs: 0) ExifTool object ref
  252. # Returns: data for "IDCPreviewImage" tag (which I have never seen),
  253. # or undef if there was no preview in the SonyIDC IFD
  254. sub ExtractPreviews($)
  255. {
  256. my $et = shift;
  257. my $i = 1;
  258. my $xtra = ' (1)';
  259. my $preview;
  260. # loop through all available IDC preview images in the order they were found
  261. for (;;) {
  262. my $key = "IDCPreviewStart$xtra";
  263. unless (defined $$et{VALUE}{$key}) {
  264. last unless $xtra;
  265. $xtra = ''; # do the last tag extracted last
  266. next;
  267. }
  268. # run through IDC preview images in the same order they were extracted
  269. my $off = $et->GetValue($key, 'ValueConv') or last;
  270. my $len = $et->GetValue("IDCPreviewLength$xtra", 'ValueConv') or last;
  271. # get stack version from number in group 1 name
  272. my $grp1 = $et->GetGroup($key, 1);
  273. if ($grp1 =~ /(\d+)$/) {
  274. my $tag = "IDCPreviewImage$1";
  275. unless ($Image::ExifTool::Extra{$tag}) {
  276. AddTagToTable(\%Image::ExifTool::Extra, $tag, {
  277. Name => $tag,
  278. Groups => { 0 => 'Composite', 1 => 'Composite', 2 => 'Preview'},
  279. });
  280. }
  281. my $val = Image::ExifTool::Exif::ExtractImage($et, $off, $len, $tag);
  282. $et->FoundTag($tag, $val);
  283. } else {
  284. $preview = Image::ExifTool::Exif::ExtractImage($et, $off, $len, 'IDCPreviewImage');
  285. }
  286. # step to next set of tags unless we are done
  287. last unless $xtra;
  288. ++$i;
  289. $xtra = " ($i)";
  290. }
  291. return $preview;
  292. }
  293. 1; # end
  294. __END__
  295. =head1 NAME
  296. Image::ExifTool::SonyIDC - Read/write Sony IDC information
  297. =head1 SYNOPSIS
  298. This module is used by Image::ExifTool
  299. =head1 DESCRIPTION
  300. This module contains definitions required by Image::ExifTool to read and
  301. write Sony Image Data Converter version 3.0 metadata in ARW images.
  302. =head1 AUTHOR
  303. Copyright 2003-2016, Phil Harvey (phil at owl.phy.queensu.ca)
  304. This library is free software; you can redistribute it and/or modify it
  305. under the same terms as Perl itself.
  306. =head1 SEE ALSO
  307. L<Image::ExifTool::TagNames/SonyIDC Tags>,
  308. L<Image::ExifTool(3pm)|Image::ExifTool>
  309. =cut