
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7327 8e941d3f-bd1b-0410-a28a-d453659cc2b4
517 lines
19 KiB
ObjectPascal
517 lines
19 KiB
ObjectPascal
unit fpeMakerNoteNikon;
|
|
|
|
{$IFDEF FPC}
|
|
{$MODE DELPHI}
|
|
//{$mode objfpc}{$H+}
|
|
{$ENDIF}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils,
|
|
fpeGlobal, fpeTags, fpeExifReadWrite;
|
|
|
|
type
|
|
TNikonMakerNoteReader = class(TMakerNoteReader)
|
|
protected
|
|
function AddTag(AStream: TStream; const AIFDRecord: TIFDRecord;
|
|
const AData: TBytes; AParent: TTagID): Integer; override;
|
|
procedure GetTagDefs(AStream: TStream); override;
|
|
function Prepare(AStream: TStream): Boolean; override;
|
|
end;
|
|
|
|
TNikonCropHiSpeedTag = class(TIntegerTag)
|
|
public
|
|
function GetAsString: String; override;
|
|
end;
|
|
|
|
TNikonLensTypeTag = class(TIntegerTag)
|
|
public
|
|
function GetAsString: string; override;
|
|
end;
|
|
|
|
TNikonLensTag = class(TFloatTag)
|
|
public
|
|
function GetAsString: string; override;
|
|
end;
|
|
|
|
TNikonShootingModeTag = class(TIntegerTag)
|
|
public
|
|
function GetAsString: String; override;
|
|
end;
|
|
|
|
TNikonNEFBitDepthTag = class(TIntegerTag)
|
|
public
|
|
function GetAsString: String; override;
|
|
end;
|
|
|
|
|
|
implementation
|
|
|
|
uses
|
|
Math,
|
|
fpeStrConsts, fpeUtils, fpeExifData;
|
|
|
|
resourcestring
|
|
rsNikonActiveDLightingLkUp = '0:Off,1:Low,3:Normal,5:High,7:Extra High,'+
|
|
'8:Extra High 1,9:Extra High 2,10:Extra High 3,11:Extra High 4,65535:Auto';
|
|
rsNikonAFAreaMode = '0:Single Area,1:Dynamic Area,2:Dynamic Area (closest subject),'+
|
|
'3:Group Dynamic,4:Single Area (wide),5:Dynamic Area (wide)';
|
|
rsNikonAFPoint = '0:Center,1:Top,2:Bottom,3:Mid-left,4:Mid-right,5:Upper-left,'+
|
|
'6:Upper-right,7:Lower-left,8:Lower-right,9:Far Left,10:Far Right';
|
|
rsNikonAFPointsInFocus = '0:(none),$7FF:All 11 points,1:Center,2:Top,4:Bottom,'+
|
|
'8:Mid-left,16:Mid-right,32:Upper-left,64:Upper-right,128:Lower-left,'+
|
|
'256:Lower-right,512:Far left,1024:Far right';
|
|
// To do: This is a bit-mask. Combinations should be calculated!
|
|
rsNikonColorModeLkup = '1:Color,2:Monochrome';
|
|
rsNikonColorSpaceLkup = '1:sRGB,2:Adobe RGB';
|
|
rsNikonConverterLkup = '0:Not used,1:Used';
|
|
rsNikonCropHiSpeedLkup = '0:Off,1:1.3x Crop,2:DX Crop,3:5/4 Crop,4:3/2 Crop,'+
|
|
'6:16/9 Crop,9:DX Movie Crop,11:FX Uncropped,12:DX Uncropped,17:1/1 Crop';
|
|
rsNikonCropHiSpeedMask = '%0:s (%1:dx%2:d cropped to %3:dx%4:d at pixel %5:d,%6:d)';
|
|
rsNikonDateDisplayFormat = '0:Y/M/D,1:M/D/Y,2:D/M/Y';
|
|
rsNikonFlashModeLkUp = '0:Did Not Fire,1:Fired, Manual,3:Not Ready,'+
|
|
'7:Fired External,8:Fired Commander Mode,9:Fired TTL Mode';
|
|
rsNikonHighISONoiseReductionLkUp = '0:Off,1:Minimal,2:Low,3:Medium Low,'+
|
|
'4:Normal,5:Medium High,6:High';
|
|
rsNikonImgAdjLkup = '0:Normal,1:Bright+,2:Bright-,3:Contrast+,4:Contrast-';
|
|
rsNikonISOLkup = '0:ISO80,2:ISO160,4:ISO320,5:ISO100';
|
|
rsNikonNEFCompressionLkUp = '1:Lossy (type 1),2: Uncompressed,3:Lossless,'+
|
|
'4:Lossy (type 2),5:Striped packed 12 bits,6:Uncompressed (reduced to 12 bit),'+
|
|
'7:Unpacked 12 bits,8:Small,9:Packed 12 bits';
|
|
rsNikonOffOn='-1:Off,1:On';
|
|
rsNikonQualityLkup = '1:Vga Basic,2:Vga Normal,3:Vga Fine,4:SXGA Basic,'+
|
|
'5:SXGA Normal,6:SXGA Fine,10:2 Mpixel Basic,11:2 Mpixel Normal,'+
|
|
'12:2 Mpixel Fine';
|
|
rsNikonRetoucheHistoryLkup = '0:None,3:B & W,4:Sepia,5:Trim,6:Small Picture,'+
|
|
'7:D-Lighting,8:Red Eye,9:Cyanotype,10:Sky Light,11:Warm Tone,'+
|
|
'12:Color Custom,13:Image Overlay,14:Red Intensifier,15:Green Intensifier,'+
|
|
'16:Blue Intensifier,17:Cross Screen,18:Quick Retouch,19:NEF Processing,'+
|
|
'23:Distortion Control,25:Fisheye,26:Straighten,29:Perspective Control,'+
|
|
'30:Color Outline,31:Soft Filter,32:Resize,33: Miniature Effect,'+
|
|
'34:Skin Softening,35:Selected Frame,37:Color Sketch,38:Selective Color,'+
|
|
'39:Glamour,40:Drawing,44:Pop,45:Toy Camera Effect 1,46:Toy Camera Effect 2,'+
|
|
'47:Cross Process (red),48:Cross Process (blue),49:Cross Process (green),'+
|
|
'50:Cross Process (yellow),51:Super Vivid,52:High-contrast Monochrome,'+
|
|
'53:High Key,54:Low Key';
|
|
rsNikonShutterModeLkUp = '0:Mechanical,16:Electronic,48:Electronic Front Curtain';
|
|
rsNikonVignetteControlLkUp = '0:Off,1:Low,3:Normal,5:High';
|
|
rsNikonVibrationReductionLkUp = '0:n/a,1:On,2:Off';
|
|
rsNikonVRModeLkUp = '0:Normal,1:On (1),2:Active,3:Sport';
|
|
rsNikonWhiteBalanceLkup = '0:Auto,1:Preset,2:Daylight,3:Incandescense,'+
|
|
'4:Fluorescence,5:Cloudy,6:SpeedLight';
|
|
|
|
const
|
|
M = DWord(TAGPARENT_MAKERNOTE);
|
|
|
|
// not tested
|
|
procedure BuildNikon1TagDefs(AList: TTagDefList);
|
|
begin
|
|
Assert(AList <> nil);
|
|
with AList do begin
|
|
AddUShortTag(M+$0002, 'FamilyID');
|
|
AddUShortTag(M+$0003, 'Quality', 1, '', rsNikonQualityLkup);
|
|
AddUShortTag(M+$0004, 'ColorMode', 1, '', rsNikonColorModeLkup);
|
|
AddUShortTag(M+$0005, 'ImageAdjustment', 1, '', rsNikonImgAdjLkup);
|
|
AddUShortTag(M+$0006, 'ISOSpeed', 1, '', rsNikonISOLkup);
|
|
AddUShortTag(M+$0007, 'WhiteBalance', 1, '', rsNikonWhiteBalanceLkup);
|
|
AddUShortTag(M+$0008, 'Focus');
|
|
AddUShortTag(M+$000A, 'DigitalZoom');
|
|
AddUShortTag(M+$000B, 'Converter', 1, '', rsNikonConverterLkup);
|
|
end;
|
|
end;
|
|
|
|
{ for Nikon D1, E880, E885, E990, E995, E2500, E5000
|
|
Ref http://www.tawbaware.com/990exif.htm
|
|
https://sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html }
|
|
procedure BuildNikon2TagDefs(AList: TTagDefList);
|
|
begin
|
|
Assert(AList <> nil);
|
|
with AList do begin
|
|
AddBinaryTag (M+$0001, 'Version', 4, '', '', '', TVersionTag);
|
|
AddUShortTag (M+$0002, 'ISO', 2);
|
|
AddStringTag (M+$0003, 'ColorMode');
|
|
AddStringTag (M+$0004, 'Quality');
|
|
AddStringTag (M+$0005, 'WhiteBalance');
|
|
AddStringtag (M+$0006, 'ImageSharpening');
|
|
AddStringTag (M+$0007, 'FocusMode');
|
|
AddStringTag (M+$0008, 'FlashSetting');
|
|
AddStringTag (M+$0009, 'FlashType');
|
|
AddURationalTag(M+$000A, 'UNKNOWN');
|
|
AddStringTag (M+$000F, 'ISOSelection');
|
|
AddStringTag (M+$0080, 'ImageAdjustment');
|
|
AddStringTag (M+$0081, 'ToneComp');
|
|
AddStringTag (M+$0082, 'AuxiliaryLens');
|
|
AddURationalTag(M+$0085, 'ManualFocusDistance');
|
|
AddURationalTag(M+$0086, 'DigitalZoom');
|
|
AddBinaryTag (M+$0088, 'AFInfo');
|
|
AddStringTag (M+$008D, 'ColorHue');
|
|
AddStringTag (M+$008F, 'SceneMode');
|
|
AddStringTag (M+$0090, 'LightSource');
|
|
AddBinaryTag (M+$0010, 'DataDump');
|
|
end;
|
|
end;
|
|
|
|
// Ref.: https://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html
|
|
procedure BuildNikon3TagDefs(AList: TTagDefList);
|
|
begin
|
|
Assert(AList <> nil);
|
|
with AList do begin
|
|
// Tags in main MakerNote IFD
|
|
AddBinaryTag (M+$0001, 'Version', 4, '', '', '', TVersionTag);
|
|
AddUShortTag (M+$0002, 'ISO', 2);
|
|
AddStringTag (M+$0003, 'ColorMode');
|
|
AddStringTag (M+$0004, 'Quality');
|
|
AddStringTag (M+$0005, 'WhiteBalance');
|
|
AddStringtag (M+$0006, 'Sharpness');
|
|
AddStringTag (M+$0007, 'FocusMode');
|
|
AddStringTag (M+$0008, 'FlashSetting');
|
|
AddStringTag (M+$0009, 'FlashType');
|
|
AddURationalTag(M+$000A, 'UNKNOWN');
|
|
AddSShortTag (M+$000B, 'WhiteBalanceFineTune');
|
|
AddURationalTag(M+$000C, 'WB_RBLevels', 4);
|
|
AddBinaryTag (M+$000D, 'ProgramShift', 1);
|
|
AddBinaryTag (M+$000E, 'ExposureDifference', 1);
|
|
AddBinaryTag (M+$000F, 'ISOSelection');
|
|
AddBinaryTag (M+$0010, 'DataDump');
|
|
// ...
|
|
AddBinaryTag (M+$0012, 'FlashExposureComp', 4);
|
|
AddUShortTag (M+$0013, 'ISO Setting', 2);
|
|
AddUShortTag (M+$0016, 'ImageBoundary', 4);
|
|
AddBinaryTag (M+$0017, 'ExternalFlashExposureComp', 4);
|
|
AddBinaryTag (M+$0018, 'FlashExposureBracketValue', 4);
|
|
AddSRationalTag(M+$0019, 'ExposureBracketValue');
|
|
AddStringTag (M+$001A, 'ImageProcessing');
|
|
AddUShortTag (M+$001B, 'CropHiSpeed', 7, '', rsNikonCropHiSpeedLkUp, '', TNikonCropHiSpeedTag);
|
|
AddBinaryTag (M+$001C, 'ExposureTuning', 3);
|
|
AddStringTag (M+$001D, 'SerialNumber', 1, '', '', nil, true);
|
|
AddUShortTag (M+$001E, 'ColorSpace', 1, '', rsNikonColorSpaceLkUp);
|
|
AddBinaryTag (M+$001F, 'VRInfo', 8);
|
|
AddByteTag (M+$0020, 'ImageAuthentication', 1, '', rsOffOn);
|
|
// 21
|
|
AddUShortTag (M+$0022, 'ActiveD-Lighting', 1, '', rsNikonActiveDLightingLkUp);
|
|
AddBinaryTag (M+$0024, 'WorldTime');
|
|
//...
|
|
AddUShortTag (M+$002A, 'VignetteControl', 1, '', rsNikonVignetteControlLkUp);
|
|
//...
|
|
AddUShortTag (M+$0034, 'ShutterMode', 1, '', '', rsNikonShutterModeLkUp);
|
|
//..
|
|
AddULongTag (M+$0037, 'MechanicalShutterCount');
|
|
AddBinaryTag (M+$0039, 'LocationInfo');
|
|
//..
|
|
AddUShortTag (M+$003D, 'BlackLevel', 4);
|
|
AddUShortTag (M+$004F, 'ColorTemperatureAuto');
|
|
AddStringTag (M+$0080, 'ImageAdjustment');
|
|
AddStringTag (M+$0081, 'ToneComp');
|
|
AddStringTag (M+$0082, 'AuxiliaryLens');
|
|
AddByteTag (M+$0083, 'LensType', 1, '', '', '', TNikonLensTypeTag);
|
|
AddURationalTag(M+$0084, 'Lens', 4, '', '', '', TNikonLensTag);
|
|
AddURationalTag(M+$0085, 'ManualFocusDistance');
|
|
AddURationalTag(M+$0086, 'DigitalZoom');
|
|
AddByteTag (M+$0087, 'FlashMode', 1, '', rsNikonFlashModeLkUp);
|
|
AddBinaryTag (M+$0088, 'AFInfo', 4);
|
|
// ..
|
|
AddUShortTag (M+$0089, 'ShootingMode', 1, '', '', '', TNikonShootingModeTag);
|
|
AddBinaryTag (M+$008B, 'LensFStops', 4);
|
|
AddBinaryTag (M+$008C, 'ContrastCurve');
|
|
AddStringTag (M+$008D, 'ColorHude');
|
|
AddStringTag (M+$008F, 'SceneMode');
|
|
AddStringTag (M+$0090, 'LightSource');
|
|
AddSShortTag (M+$0092, 'HueAdjustment');
|
|
AddUShortTag (M+$0093, 'NEFCompression', 1, '', rsNikonNEFCompressionLkUp);
|
|
AddSShortTag (M+$0094, 'Saturation');
|
|
AddStringTag (M+$0095, 'NoiseReduction');
|
|
AddBinaryTag (M+$0097, 'NEFLinearizationTable');
|
|
AddUShortTag (M+$0099, 'RawImageCenter', 2);
|
|
AddURationalTag(M+$009A, 'SensorPixelSize', 2);
|
|
AddStringTag (M+$009C, 'SceneAssist');
|
|
AddUShortTag (M+$009E, 'RetoucheHistory', 10, '', rsNikonRetoucheHistoryLkup);
|
|
AddStringTag (M+$00A0, 'SerialNumber');
|
|
AddULongTag (M+$00A2, 'ImageDataSize');
|
|
AddULongTag (M+$00A5, 'ImageCount');
|
|
AddULongTag (M+$00A6, 'DeletedImageCount');
|
|
AddULongTag (M+$00A7, 'ShutterCount', 1, '', '', '', nil, true);
|
|
AddStringTag (M+$00A9, 'ImageOptimization');
|
|
AddStringTag (M+$00AA, 'Saturation');
|
|
AddStringTag (M+$00AB, 'VariProgram');
|
|
AddStringTag (M+$00AC, 'ImageStabilization');
|
|
AddStringTag (M+$00AD, 'AFResponse');
|
|
AddUShortTag (M+$00B1, 'HighISONoiseReduction', 1, '', rsNikonHighISONoiseReductionLkup);
|
|
AddStringTag (M+$00B3, 'ToningEffect');
|
|
AddBinaryTag (M+$00B6, 'PowerUpTime');
|
|
|
|
// ...
|
|
AddBinaryTag (M+$00B8, 'FileInfo');
|
|
AddBinaryTag (M+$00BB, 'RetoucheInfo');
|
|
|
|
AddBinaryTag (M+$00C3, 'BarometerInfo');
|
|
AddStringTag (M+$0E09, 'NikonCaptureVersion');
|
|
// ...
|
|
AddUShortTag (M+$0E22, 'NEFBitDepth', 4, '', '', '', TNikonNEFBitDepthTag);
|
|
|
|
// AddBinaryTag (M+$0103, 'CompressionValue', 1, '', rsCompressionLkUp);
|
|
end;
|
|
end;
|
|
|
|
|
|
//==============================================================================
|
|
// MakerNote reader
|
|
//==============================================================================
|
|
|
|
function TNikonMakerNoteReader.AddTag(AStream: TStream;
|
|
const AIFDRecord: TIFDRecord; const AData: TBytes; AParent: TTagID): Integer;
|
|
var
|
|
tagDef: TTagDef;
|
|
t: TTagID;
|
|
idx: Integer;
|
|
b: Byte;
|
|
w: Word;
|
|
r: TExifRational;
|
|
begin
|
|
Result := -1;
|
|
|
|
tagDef := FindTagDef(AIFDRecord.TagID or AParent);
|
|
if (tagDef = nil) then
|
|
exit;
|
|
|
|
Result := inherited AddTag(AStream, AIFDRecord, AData, AParent);
|
|
t := tagDef.TagID;
|
|
case tagDef.TagID of
|
|
TAGPARENT_MAKERNOTE+$001F: // VR info
|
|
if Length(AData) >= 8 then
|
|
with FImgInfo.ExifData do begin
|
|
AddMakerNoteStringTag(0, t, 'VRInfoVersion', AData, 4, '');
|
|
AddMakerNoteTag(4, t, 'VibrationReduction', AData[4], rsNikonVibrationReductionLkUp, '', ttUInt8);
|
|
AddMakerNoteTag(6, t, 'VRMode', AData[6], rsNikonVRModeLkUp, '', ttUInt8);
|
|
end;
|
|
TAGPARENT_MAKERNOTE+$0088:
|
|
if Length(AData) >= 4 then // AF Info
|
|
with FImgInfo.ExifData do begin
|
|
b := AData[0];
|
|
AddMakerNoteTag(0, t, 'AFAreaMode', b, rsNikonAFAreaMode, '', ttUInt8);
|
|
b := AData[1];
|
|
AddMakerNoteTag(1, t, 'AFPoint', b, rsNikonAFPoint, '', ttUInt8);
|
|
w := FixEndian16(PWord(@AData[2])^);
|
|
AddmakerNoteTag(2, t, 'AFPointsInFocus', w, rsNikonAFPointsInFocus, '', ttUInt16);
|
|
end;
|
|
TAGPARENT_MAKERNOTE+$0024:
|
|
if Length(AData) >= 4 then // WorldTime
|
|
with FImgInfo.ExifData do begin
|
|
w := FixEndian16(PWord(@AData[0])^);
|
|
AddMakerNoteTag(0, t, 'TimeZone', Integer(w), '', '', ttSInt16);
|
|
AddMakerNoteTag(2, t, 'DaylightSavings', byte(AData[2]), rsNoYes, '', ttUInt8);
|
|
AddMakerNoteTag(3, t, 'DateDisplayFormat', byte(AData[3]), rsNikonDateDisplayformat, '', ttUInt8);
|
|
end;
|
|
TAGPARENT_MAKERNOTE+$00B8:
|
|
if Length(AData) >= 8 then
|
|
with FImgInfo.ExifData do begin
|
|
idx := 0;
|
|
AddMakerNoteStringTag(idx, t, 'FileInfoVersion', AData, 4);
|
|
inc(idx, 4);
|
|
w := FixEndian16(PWord(@AData[idx])^);
|
|
AddMakerNoteTag(idx, t, 'MemoryCardNumber', Integer(w), '', '', ttUInt16);
|
|
inc(idx, 2);
|
|
w := FixEndian16(PWord(@AData[idx])^);
|
|
AddMakerNoteTag(idx, t, 'DirectoryNumber', Integer(w), '', '', ttUInt16);
|
|
inc(idx, 2);
|
|
w := FixEndian16(PWord(@AData[idx])^);
|
|
AddMakerNoteTag(idx, t, 'FileNumber', Integer(w), '', '', ttUInt16);
|
|
end;
|
|
TAGPARENT_MAKERNOTE+$BB:
|
|
if Length(ADAta) >= 6 then
|
|
with FImgInfo.ExifData do begin
|
|
AddMakerNoteStringTag(0, t, 'RetouchInfoVersion', AData, 5);
|
|
AddMakerNoteTag(5, t, 'RetouchNEFProcessing', byte(AData[5]), '', rsNikonOffOn, ttSInt8);
|
|
end;
|
|
TAGPARENT_MAKERNOTE+$00C3:
|
|
if Length(AData) >= 10 then
|
|
with FImgInfo.ExifData do begin
|
|
idx := 0;
|
|
AddMakerNoteStringTag(idx, t, 'BarometerInfoVersion', AData, 6);
|
|
inc(idx, 6);
|
|
Move(AData[idx], r{%H-}, SizeOf(r));
|
|
r.Numerator := FixEndian32(r.Numerator);
|
|
r.Denominator := FixEndian32(r.Denominator);
|
|
AddMakerNoteTag(idx, t, 'Altitude', r.Numerator/r.Denominator, '', ttSRational);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TNikonMakerNoteReader.GetTagDefs(AStream: TStream);
|
|
var
|
|
b: TBytes; //array of byte;
|
|
tmp, tmp2: String;
|
|
p: Integer;
|
|
streamPos: Int64;
|
|
begin
|
|
if Uppercase(FMake) = 'NIKON CORPORATION' then begin
|
|
SetLength(b, 20);
|
|
streamPos := AStream.Position;
|
|
AStream.Read(b[0], 20);
|
|
AStream.Position := streamPos;
|
|
SetLength(tmp, 5);
|
|
Move(b[0], tmp[1], 5);
|
|
if (PosInBytes('Nikon'#00, b) = 0) and (
|
|
(PosInBytes('MM'#00#42#00#00#00#08, b) = 10) or
|
|
(PosInBytes('II'#42#00#08#00#00#00, b) = 10)
|
|
)
|
|
then
|
|
BuildNikon3TagDefs(FTagDefs)
|
|
else begin
|
|
p := Max(0, Pos(' ', FModel));
|
|
tmp2 := FModel[p+1];
|
|
if (FExifVersion > '0210') or
|
|
((FExifVersion = '') and (tmp2 = 'D') and (FImgFormat = ifTiff))
|
|
then
|
|
BuildNikon2TagDefs(FTagDefs)
|
|
else
|
|
if (tmp = 'Nikon') then
|
|
BuildNikon1TagDefs(FTagDefs)
|
|
else
|
|
BuildNikon2TagDefs(FTagDefs);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TNikonMakerNoteReader.Prepare(AStream: TStream): Boolean;
|
|
var
|
|
b: TBytes;
|
|
UCMake: String;
|
|
dw: DWord;
|
|
begin
|
|
Result := false;
|
|
UCMake := Uppercase(FMake);
|
|
if UCMake = 'NIKON CORPORATION' then begin
|
|
SetLength(b, 10);
|
|
AStream.Read(b[0], 10);
|
|
if PosInBytes('Nikon'#0{#$10#00#00}, b) = 0 then begin
|
|
// These MakerNotes are relative to the beginning of the MakerNote's
|
|
// TIFF header!
|
|
FStartPosition := AStream.Position;
|
|
AStream.Read(b[0], 4);
|
|
if PosInBytes('MM'#00#42, b) = 0 then
|
|
FBigEndian := true
|
|
else
|
|
if PosInBytes('II'#42#00, b) = 0 then
|
|
FBigEndian := false
|
|
else
|
|
exit;
|
|
dw := ReadDWord(AStream);
|
|
// dw := AStream.ReadDWord;
|
|
if FBigEndian then dw := BEToN(dw) else dw := LEToN(dw);
|
|
if dw = 8 then
|
|
Result := true;
|
|
// The stream is now at the beginning of the IFD structure used by
|
|
// the Nikon maker notes.
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
//==============================================================================
|
|
// Special tags
|
|
//==============================================================================
|
|
|
|
function TNikonCropHiSpeedTag.GetAsString: String;
|
|
var
|
|
s: String;
|
|
intVal: TExifIntegerArray;
|
|
begin
|
|
if (FCount = 7) and (toDecodeValue in FOptions) then begin
|
|
intVal := AsIntegerArray;
|
|
s := Lookup(IntToStr(intVal[0]), FLkupTbl, @SameIntegerFunc);
|
|
Result := Format(rsNikonCropHiSpeedMask, [
|
|
s, intval[1], intVal[2], intVal[3], intVal[4], intVal[5], intVal[6]
|
|
]);
|
|
end else
|
|
Result := inherited;
|
|
end;
|
|
|
|
function TNikonLensTypeTag.GetAsString: String;
|
|
var
|
|
intVal: Integer;
|
|
begin
|
|
if (toDecodeValue in FOptions) then begin
|
|
Result := '';
|
|
intVal := AsInteger;
|
|
if intVal and 1 <> 0 then Result := Result + 'MF+';
|
|
if intVal and 2 <> 0 then Result := Result + 'D+';
|
|
if intVal and 4 <> 0 then Result := Result + 'G+';
|
|
if intVal and 8 <> 0 then Result := Result + 'VR+';
|
|
if intval and 16 <> 0 then Result := Result + '1+';
|
|
if intVal and 32 <> 0 then Result := Result + 'E+';
|
|
if Result <> '' then SetLength(Result, Length(Result)-1);
|
|
end else
|
|
Result := inherited;
|
|
end;
|
|
|
|
function TNikonLensTag.GetAsString: String;
|
|
var
|
|
values: TExifDoubleArray;
|
|
begin
|
|
values := AsFloatArray;
|
|
if (toDecodeValue in FOptions) and (Length(values) = 4) then
|
|
Result := Format('%g-%gmm f/%g-%g', [values[0], values[1], values[2], values[3]], fpExifFmtSettings)
|
|
else
|
|
Result := inherited;
|
|
end;
|
|
|
|
function TNikonShootingModetag.GetAsString: String;
|
|
var
|
|
intVal: Integer;
|
|
begin
|
|
if (toDecodeValue in FOptions) then begin
|
|
intVal := AsInteger;
|
|
if intVal = 0 then
|
|
Result := 'Single frame'
|
|
else begin
|
|
Result := '';
|
|
if intVal and 1 <> 0 then Result := Result + 'Continuous, ';
|
|
if intVal and 2 <> 0 then Result := Result + 'Delay, ';
|
|
if intVal and 4 <> 0 then Result := Result + 'PC Control, ';
|
|
if intVal and 8 <> 0 then Result := Result + 'Self-timer, ';
|
|
if intval and 16 <> 0 then Result := Result + 'Exposure bracketing, ';
|
|
if intVal and 32 <> 0 then Result := Result + 'Auto ISO, ';
|
|
if intVal and 64 <> 0 then Result := Result + 'White-balance bracketing, ';
|
|
if intVal and 128 <> 0 then Result := Result + 'IR control, ';
|
|
if intVal and 256 <> 0 then Result := Result + 'D-Lighting bracketing, ';
|
|
if Result <> '' then SetLength(Result, Length(Result)-2);
|
|
end;
|
|
end else
|
|
Result := inherited;
|
|
end;
|
|
|
|
function TNikonNEFBitDepthTag.GetAsString: String;
|
|
var
|
|
iVal: TExifIntegerArray;
|
|
i: Integer;
|
|
n: Integer;
|
|
begin
|
|
if (FCount = 4) and (toDecodeValue in FOptions) then begin
|
|
iVal := AsIntegerArray;
|
|
if iVal[0] = 0 then
|
|
Result := 'n/a (JPEG)'
|
|
else begin
|
|
Result := intToStr(iVal[0]);
|
|
n := 1;
|
|
for i:= Succ(Low(iVal)) to High(iVal) do
|
|
if iVal[i] = 0 then
|
|
break
|
|
else if iVal[i] = iVal[0] then
|
|
inc(n)
|
|
else begin
|
|
Result := inherited;
|
|
exit;
|
|
end;
|
|
Result := Result + ' x ' + IntToStr(n);
|
|
end;
|
|
end else
|
|
Result := inherited;
|
|
end;
|
|
|
|
initialization
|
|
RegisterMakerNoteReader(TNikonMakerNoteReader, 'Nikon Corporation;Nikon', '');
|
|
|
|
end.
|
|
|