diff --git a/ExtLibs/ArduPilot/CurrentState.cs b/ExtLibs/ArduPilot/CurrentState.cs index 34b60fc28d..f37b93b2a5 100644 --- a/ExtLibs/ArduPilot/CurrentState.cs +++ b/ExtLibs/ArduPilot/CurrentState.cs @@ -181,6 +181,8 @@ public bool prearmstatus get => connected && (sensors_health.prearm || !sensors_enabled.prearm); } + private readonly PrearmFailureTracker _prearmFailureTracker = new PrearmFailureTracker(); + private bool useLocation; /// @@ -1274,10 +1276,10 @@ public string messageHigh if (value == null || value == "") return; // check against get + _messageHighTime = DateTime.Now; if (messageHigh == value) return; log.Info("messageHigh " + value); - _messageHighTime = DateTime.Now; _messagehigh = value; messageHighSeverity = MAVLink.MAV_SEVERITY.EMERGENCY; } @@ -2967,16 +2969,17 @@ private void Parent_OnPacketReceived(object sender, MAVLink.MAVLinkMessage mavLi safetyactive = !sensors_enabled.motor_control; + string latestPrearmFailure = _prearmFailureTracker.Update( + sensors_health.prearm, + sensors_enabled.prearm, + sensors_present.prearm, + messages, + DateTime.Now); + if (errors_count1 > 0 || errors_count2 > 0) { messageHigh = "InternalError 0x" + (errors_count1 + (errors_count2 << 16)).ToString("X"); } - - if (!sensors_health.prearm && sensors_enabled.prearm && sensors_present.prearm) - { - messageHigh = messages.LastOrDefault(a => a.message.ToLower().Contains("prearm")).message - ?.ToString(); - } else if (!sensors_health.gps && sensors_enabled.gps && sensors_present.gps) { messageHigh = Strings.BadGPSHealth; @@ -3053,6 +3056,10 @@ private void Parent_OnPacketReceived(object sender, MAVLink.MAVLinkMessage mavLi { messageHigh = Strings.BadAirspeed; } + else if (!string.IsNullOrEmpty(latestPrearmFailure)) + { + messageHigh = latestPrearmFailure; + } } break; @@ -4056,11 +4063,11 @@ private void Parent_OnPacketReceived(object sender, MAVLink.MAVLinkMessage mavLi case (uint)MAVLink.MAVLINK_MSG_ID.HIGHRES_IMU: { const ushort HIGHRES_IMU_UPDATED_XACC = 0x01; - const ushort HIGHRES_IMU_UPDATED_XGYRO = 0x08; - const ushort HIGHRES_IMU_UPDATED_XMAG = 0x40; - const ushort HIGHRES_IMU_UPDATED_ABS_PRESSURE = 0x200; - const ushort HIGHRES_IMU_UPDATED_PRESSURE_ALT = 0x800; - const ushort HIGHRES_IMU_UPDATED_TEMPERATURE = 0x1000; + const ushort HIGHRES_IMU_UPDATED_XGYRO = 0x08; + const ushort HIGHRES_IMU_UPDATED_XMAG = 0x40; + const ushort HIGHRES_IMU_UPDATED_ABS_PRESSURE = 0x200; + const ushort HIGHRES_IMU_UPDATED_PRESSURE_ALT = 0x800; + const ushort HIGHRES_IMU_UPDATED_TEMPERATURE = 0x1000; var imu = mavLinkMessage.ToStructure(); if (imu.id == 0) @@ -4643,8 +4650,8 @@ public void UpdateCurrentSettings(Action bs, bool updatenow, mavinterface.requestDatastream(MAVLink.MAV_DATA_STREAM.RC_CHANNELS, MAV.cs.raterc, MAV.sysid, MAV.compid); // request rc info - MAV.Camera?.RequestMessageIntervals(MAV.cs.ratestatus); // use ratestatus until we create a new setting for this - MAV.GimbalManager?.Discover(); + // Use ratestatus until camera-specific configuration is available. + MAV.Camera?.UpdateRateIfChanged(MAV.cs.ratestatus); } catch { diff --git a/ExtLibs/ArduPilot/Mavlink/CameraProtocol.cs b/ExtLibs/ArduPilot/Mavlink/CameraProtocol.cs index 7a20964583..c9279891f1 100644 --- a/ExtLibs/ArduPilot/Mavlink/CameraProtocol.cs +++ b/ExtLibs/ArduPilot/Mavlink/CameraProtocol.cs @@ -1,8 +1,10 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Linq; using System.Reflection; using System.Text.RegularExpressions; +using System.Threading; using System.Threading.Tasks; using Core.Geometry; using GeoAPI.DataStructures; @@ -15,7 +17,7 @@ namespace MissionPlanner.ArduPilot.Mavlink /// Handles communication and control for camera operations via MAVLink protocol. /// This includes starting/stopping video capture, taking pictures, and fetching camera settings and status. /// - public class CameraProtocol + public class CameraProtocol : IDisposable { // Logger for capturing runtime information and errors private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -26,6 +28,17 @@ public class CameraProtocol // Tracks whether we have received a `CAMERA_INFORMATION` message yet private bool have_camera_information = false; + private readonly object _leaseLock = new object(); + private readonly CancellationTokenSource _lifetime = new CancellationTokenSource(); + private List _streamingLeases = new List(); + private MessageRateLease _trackingLease; + private int _desiredRateHz; + private int _appliedRateHz = -1; + private int _desiredTrackingRateHz; + private int _appliedTrackingRateHz; + private int _started; + private int _disposed; + public bool HasCameraInformation => have_camera_information; public MAVLink.mavlink_camera_information_t CameraInformation { get; private set; } @@ -178,7 +191,7 @@ public float HFOV { get { - if (!UseFOVStatus || CameraFOVStatus.hfov == float.NaN) + if (!UseFOVStatus || float.IsNaN(CameraFOVStatus.hfov)) { return _hfov; } @@ -195,7 +208,7 @@ public float VFOV { get { - if (!UseFOVStatus || CameraFOVStatus.vfov == float.NaN) + if (!UseFOVStatus || float.IsNaN(CameraFOVStatus.vfov)) { return _vfov; } @@ -208,61 +221,97 @@ public float VFOV } /// - /// Initializes the camera protocol by setting up message parsing and requesting initial camera information. + /// Initializes camera discovery and asks the target to announce camera information + /// approximately every 30 seconds. /// - /// MAVState parent of this driver - public Task StartID(MAVState mavState) - { - parent = mavState; + public async Task StartID(MAVState mavState) + { + if (mavState == null) + throw new ArgumentNullException(nameof(mavState)); + if (Volatile.Read(ref _disposed) != 0) + return; + if (Interlocked.Exchange(ref _started, 1) != 0) + return; - mavState.parent.OnPacketReceived += ParseMessages; + parent = mavState; + MAVLinkInterface port = mavState.parent; + if (port == null) + return; + port.OnPacketReceived += ParseMessages; + + const ushort cameraInformationId = + (ushort)MAVLink.MAVLINK_MSG_ID.CAMERA_INFORMATION; + const float intervalMicroseconds = 30_000_000; + int confirmed = 0; + int subscription = port.SubscribeToPacketType( + MAVLink.MAVLINK_MSG_ID.MESSAGE_INTERVAL, + message => + { + MAVLink.mavlink_message_interval_t interval = + message.ToStructure(); + if (interval.message_id == cameraInformationId) + { + Interlocked.Exchange(ref confirmed, 1); + log.InfoFormat( + "Camera: CAMERA_INFORMATION interval response {0} us", + interval.interval_us); + } + return true; + }, parent.sysid, parent.compid); - return RequestCameraInformationAsync(); + try + { + for (int attempt = 0; attempt < 3 && !have_camera_information && + Volatile.Read(ref confirmed) == 0; attempt++) + { + SendDiscoveryIntervalRequest(port, cameraInformationId, + intervalMicroseconds); + await Task.Delay(5000, _lifetime.Token).ConfigureAwait(false); + } + } + catch (OperationCanceledException) + { + } + finally + { + port.UnSubscribeToPacketType(subscription); + } } - /// - /// Sends an asynchronous request to fetch camera information via. - /// - public async Task RequestCameraInformationAsync() + private void SendDiscoveryIntervalRequest(MAVLinkInterface port, + ushort messageId, float intervalMicroseconds) { try { - if (parent?.parent != null) - { - // New-style request - var resp = await parent.parent.doCommandAsync( - parent.sysid, parent.compid, - MAVLink.MAV_CMD.REQUEST_MESSAGE, - (float)MAVLink.MAVLINK_MSG_ID.CAMERA_INFORMATION, - 0, 0, 0, 0, 0, 0 - ); - // Fall back to deprecated request message - if (!resp) - { - await parent.parent.doCommandAsync( - parent.sysid, parent.compid, - MAVLink.MAV_CMD.REQUEST_CAMERA_INFORMATION, - 0, 0, 0, 0, 0, 0, 0, - false // Don't wait for response - ); - } - - // Get video stream information as well - await parent.parent.doCommandAsync( - parent.sysid, parent.compid, - MAVLink.MAV_CMD.REQUEST_MESSAGE, - (float)MAVLink.MAVLINK_MSG_ID.VIDEO_STREAM_INFORMATION, - 0, 0, 0, 0, 0, 0, - false // Don't wait for response - ); - } + ObserveFault(port.doCommandAsync(parent.sysid, parent.compid, + MAVLink.MAV_CMD.SET_MESSAGE_INTERVAL, + messageId, intervalMicroseconds, + 0, 0, 0, 0, 0, false), "camera discovery SET"); + ObserveFault(port.doCommandAsync(parent.sysid, parent.compid, + MAVLink.MAV_CMD.GET_MESSAGE_INTERVAL, + messageId, 0, 0, 0, 0, 0, 0, false), "camera discovery GET"); } catch (Exception ex) { - log.Error(ex); + log.Debug("Camera discovery request failed: " + ex.Message); } } + /// + /// Compatibility one-shot request for plugins that used the previous API. + /// + public Task RequestCameraInformationAsync() + { + if (parent?.parent == null) + return Task.CompletedTask; + Task request = parent.parent.doCommandAsync(parent.sysid, parent.compid, + MAVLink.MAV_CMD.REQUEST_MESSAGE, + (float)MAVLink.MAVLINK_MSG_ID.CAMERA_INFORMATION, + 0, 0, 0, 0, 0, 0, false); + RequestVideoStreamInformation(); + return request; + } + /// /// Event handler for OnPacketReceived. /// Parses incoming MAVLink messages related to camera operations and updates internal state accordingly. @@ -271,14 +320,22 @@ await parent.parent.doCommandAsync( /// MAVLink message to parse public void ParseMessages(object sender, MAVLink.MAVLinkMessage message) { - if (message.sysid != parent.sysid || message.compid != parent.compid) + if (Volatile.Read(ref _disposed) != 0 || parent == null || + message.sysid != parent.sysid || message.compid != parent.compid) return; switch ((MAVLink.MAVLINK_MSG_ID)message.msgid) { case MAVLink.MAVLINK_MSG_ID.CAMERA_INFORMATION: - have_camera_information = true; CameraInformation = (MAVLink.mavlink_camera_information_t)message.data; + if (!have_camera_information) + { + have_camera_information = true; + ApplyDesiredRates(); + if ((CameraInformation.flags & + (int)MAVLink.CAMERA_CAP_FLAGS.HAS_VIDEO_STREAM) != 0) + RequestVideoStreamWithRetry(); + } break; case MAVLink.MAVLINK_MSG_ID.CAMERA_SETTINGS: CameraSettings = (MAVLink.mavlink_camera_settings_t)message.data; @@ -299,97 +356,252 @@ public void ParseMessages(object sender, MAVLink.MAVLinkMessage message) } } - /// - /// Requests that the camera send specific messages types at a specified rate. - /// The messages are selected based on the camera's reported capabilities. - /// - /// Message frequency in messages per second. - public void RequestMessageIntervals(int ratehz) + public void UpdateRateIfChanged(int rateHz) + { + lock (_leaseLock) + _desiredRateHz = Math.Max(0, rateHz); + if (have_camera_information) + ApplyDesiredRates(); + } + + [Obsolete("Use UpdateRateIfChanged")] + public void RequestMessageIntervals(int rateHz) + { + UpdateRateIfChanged(rateHz); + } + + public void SubscribeTracking(int rateHz) + { + lock (_leaseLock) + _desiredTrackingRateHz = Math.Max(0, rateHz); + if (have_camera_information) + ApplyDesiredTrackingRate(); + } + + [Obsolete("Use SubscribeTracking")] + public void RequestTrackingMessageInterval(int rateHz) { - if (ratehz < 0) + SubscribeTracking(rateHz); + } + + public void StopTracking() + { + MessageRateLease old; + lock (_leaseLock) { - // -1 means don't try to configure message intervals - return; + _desiredTrackingRateHz = 0; + _appliedTrackingRateHz = 0; + old = _trackingLease; + _trackingLease = null; } + old?.Dispose(); + } - if (parent?.parent == null) + private void ApplyDesiredRates() + { + int desired; + lock (_leaseLock) + { + desired = _desiredRateHz; + if (desired == _appliedRateHz) + return; + } + + if (desired <= 0) + { + ReleaseStreamingLeases(); + } + else + { + TakeStreamingLeases(desired); + } + ApplyDesiredTrackingRate(); + } + + internal static IReadOnlyList StreamingMessageIds(uint flags) + { + var messages = new List + { + MAVLink.MAVLINK_MSG_ID.CAMERA_FOV_STATUS + }; + uint settingsCapabilities = + (uint)(MAVLink.CAMERA_CAP_FLAGS.HAS_MODES | + MAVLink.CAMERA_CAP_FLAGS.HAS_BASIC_ZOOM | + MAVLink.CAMERA_CAP_FLAGS.HAS_BASIC_FOCUS); + if ((flags & settingsCapabilities) != 0) + messages.Add(MAVLink.MAVLINK_MSG_ID.CAMERA_SETTINGS); + + uint captureCapabilities = + (uint)(MAVLink.CAMERA_CAP_FLAGS.CAPTURE_VIDEO | + MAVLink.CAMERA_CAP_FLAGS.CAPTURE_IMAGE); + if ((flags & captureCapabilities) != 0) + messages.Add(MAVLink.MAVLINK_MSG_ID.CAMERA_CAPTURE_STATUS); + return messages; + } + + private void TakeStreamingLeases(int rateHz) + { + if (parent?.parent == null || Volatile.Read(ref _disposed) != 0) + return; + + var replacement = new List(); + try + { + foreach (MAVLink.MAVLINK_MSG_ID messageId in + StreamingMessageIds(CameraInformation.flags)) + { + replacement.Add(parent.parent.RateManager.Subscribe( + parent.sysid, parent.compid, messageId, rateHz, + $"Camera({parent.sysid},{parent.compid})")); + } + } + catch (Exception ex) { + foreach (MessageRateLease lease in replacement) + lease.Dispose(); + log.Error("Camera rate subscription failed", ex); return; } - // ratehz of 0 means "stop sending", which is what -1 interval_us means in the MAVLink message - float interval_us = ratehz > 0 ? (float)(1e6 / ratehz) : -1; + List old; + lock (_leaseLock) + { + old = _streamingLeases; + _streamingLeases = replacement; + _appliedRateHz = rateHz; + } + foreach (MessageRateLease lease in old) + lease.Dispose(); + } + + private void ReleaseStreamingLeases() + { + List old; + lock (_leaseLock) + { + old = _streamingLeases; + _streamingLeases = new List(); + _appliedRateHz = 0; + } + foreach (MessageRateLease lease in old) + lease.Dispose(); + } - Task.Run(RequestCameraInformationAsync); + private void ApplyDesiredTrackingRate() + { + int desired; + lock (_leaseLock) + { + desired = _desiredTrackingRateHz; + if (desired == _appliedTrackingRateHz) + return; + } + if (desired <= 0) + { + StopTracking(); + return; + } - // Request FOV status - Task.Run(async () => + MessageRateLease replacement; + try { - await parent.parent.doCommandAsync( + replacement = parent.parent.RateManager.Subscribe( parent.sysid, parent.compid, - MAVLink.MAV_CMD.SET_MESSAGE_INTERVAL, - (float)MAVLink.MAVLINK_MSG_ID.CAMERA_FOV_STATUS, - interval_us, - 0, 0, 0, 0, 0, - false // Don't wait for response - ).ConfigureAwait(false); - }); + MAVLink.MAVLINK_MSG_ID.CAMERA_TRACKING_IMAGE_STATUS, + desired, $"Camera({parent.sysid},{parent.compid})"); + } + catch (Exception ex) + { + log.Error("Camera tracking rate subscription failed", ex); + return; + } - // Get camera settings - if (HasModes || HasZoom || HasFocus) + MessageRateLease old; + lock (_leaseLock) { - Task.Run(async () => - { - await parent.parent.doCommandAsync( - parent.sysid, parent.compid, - MAVLink.MAV_CMD.SET_MESSAGE_INTERVAL, - (float)MAVLink.MAVLINK_MSG_ID.CAMERA_SETTINGS, - interval_us, - 0, 0, 0, 0, 0, - false // Don't wait for response - ).ConfigureAwait(false); - }); - } - - // We use the capability flags directly here, and NOT whether we are currently able to do these things - var can_capture_video = (CameraInformation.flags & (int)MAVLink.CAMERA_CAP_FLAGS.CAPTURE_VIDEO) > 0; - var can_capture_image = (CameraInformation.flags & (int)MAVLink.CAMERA_CAP_FLAGS.CAPTURE_IMAGE) > 0; - if (can_capture_video || can_capture_image) - { - Task.Run(async () => - { - await parent.parent.doCommandAsync( - parent.sysid, parent.compid, - MAVLink.MAV_CMD.SET_MESSAGE_INTERVAL, - (float)MAVLink.MAVLINK_MSG_ID.CAMERA_CAPTURE_STATUS, - interval_us, - 0, 0, 0, 0, 0, - false // Don't wait for response - ).ConfigureAwait(false); - }); + old = _trackingLease; + _trackingLease = replacement; + _appliedTrackingRateHz = desired; } + old?.Dispose(); } - public void RequestTrackingMessageInterval(int ratehz) + private void RequestVideoStreamWithRetry() { if (parent?.parent == null) + return; + MAVLinkInterface port = parent.parent; + byte sysid = parent.sysid; + byte compid = parent.compid; + Task.Run(async () => { + try + { + for (int attempt = 0; attempt < 3; attempt++) + { + if (_lifetime.IsCancellationRequested || + parent?.parent?.BaseStream?.IsOpen != true || + VideoStreams.Keys.Any(key => + key.Item1 == sysid && key.Item2 == compid)) + return; + + RequestVideoStreamInformation(); + await Task.Delay(5000, _lifetime.Token).ConfigureAwait(false); + } + } + catch (OperationCanceledException) + { + } + catch (Exception ex) + { + log.Debug("Video stream discovery failed: " + ex.Message); + } + }); + } + + public void RequestVideoStreamInformation() + { + if (parent?.parent == null) return; + try + { + ObserveFault(parent.parent.doCommandAsync( + parent.sysid, parent.compid, + MAVLink.MAV_CMD.REQUEST_MESSAGE, + (float)MAVLink.MAVLINK_MSG_ID.VIDEO_STREAM_INFORMATION, + 0, 0, 0, 0, 0, 0, false), "video stream request"); } + catch (Exception ex) + { + log.Debug("Video stream request failed: " + ex.Message); + } + } - float interval_us = (float)(1e6 / ratehz); + private static void ObserveFault(Task task, string operation) + { + task?.ContinueWith(faulted => + log.Debug("Camera " + operation + " failed: " + + faulted.Exception?.GetBaseException().Message), + CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, + TaskScheduler.Default); + } - Task.Run(async () => + public void Dispose() + { + if (Interlocked.Exchange(ref _disposed, 1) != 0) + return; + _lifetime.Cancel(); + if (parent?.parent != null) + parent.parent.OnPacketReceived -= ParseMessages; + ReleaseStreamingLeases(); + StopTracking(); + + if (parent != null) { - await parent.parent.doCommandAsync( - parent.sysid, parent.compid, - MAVLink.MAV_CMD.SET_MESSAGE_INTERVAL, - (float)MAVLink.MAVLINK_MSG_ID.CAMERA_TRACKING_IMAGE_STATUS, - interval_us, - 0, 0, 0, 0, 0, - false // Don't wait for response - ).ConfigureAwait(false); - }); + foreach (var key in VideoStreams.Keys.Where(key => + key.Item1 == parent.sysid && key.Item2 == parent.compid).ToList()) + VideoStreams.TryRemove(key, out _); + } } /// @@ -606,7 +818,7 @@ public PointLatLngAlt CalculateImagePointLocation(double x, double y) private Vector3 CalculateImagePointVectorCameraFrame(double x, double y) { var vector = new Vector3(1, 0, 0); // Camera-frame vector pointing straight ahead - if (HFOV != float.NaN && VFOV != float.NaN && x != 0 && y != 0) + if (!float.IsNaN(HFOV) && !float.IsNaN(VFOV) && (x != 0 || y != 0)) { var hfov = HFOV * Math.PI / 180; var vfov = VFOV * Math.PI / 180; diff --git a/ExtLibs/ArduPilot/Mavlink/GimbalManagerProtocol.cs b/ExtLibs/ArduPilot/Mavlink/GimbalManagerProtocol.cs index c48193bd2c..db2ea47af6 100644 --- a/ExtLibs/ArduPilot/Mavlink/GimbalManagerProtocol.cs +++ b/ExtLibs/ArduPilot/Mavlink/GimbalManagerProtocol.cs @@ -1,13 +1,25 @@ using System; using System.Collections.Concurrent; +using System.Reflection; +using System.Threading; using System.Threading.Tasks; +using log4net; using MissionPlanner.Utilities; namespace MissionPlanner.ArduPilot.Mavlink { - public class GimbalManagerProtocol + public class GimbalManagerProtocol : IDisposable { - CurrentState cs; + private static readonly ILog log = LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + private readonly CurrentState cs; + private readonly MAVLinkInterface mavint; + private readonly CancellationTokenSource _lifetime = new CancellationTokenSource(); + private byte _systemId; + private byte _componentId; + private int _started; + private int _disposed; + private volatile bool _haveManagerInformation; // Stores the last GIMBAL_MANAGER_INFORMATION message for each gimbal device/component ID. // This index will be 1-6, or MAVLink component IDs 154, 171-175. @@ -27,32 +39,105 @@ public class GimbalManagerProtocol public ConcurrentDictionary GimbalStatus = new ConcurrentDictionary(); - private readonly MAVLinkInterface mavint; - public GimbalManagerProtocol(MAVLinkInterface mavint, CurrentState cs) { this.mavint = mavint; this.cs = cs; } - private bool first_discover = true; + [Obsolete("Use StartID")] public void Discover() { - if (first_discover) + ObserveFault(StartID((byte)mavint.sysidcurrent, (byte)mavint.compidcurrent)); + } + + public async Task StartID(byte sysid, byte compid) + { + if (Volatile.Read(ref _disposed) != 0) + return; + if (Interlocked.Exchange(ref _started, 1) != 0) + return; + + _systemId = sysid; + _componentId = compid; + mavint.OnPacketReceived += MessagesHandler; + + const ushort informationId = + (ushort)MAVLink.MAVLINK_MSG_ID.GIMBAL_MANAGER_INFORMATION; + const float intervalMicroseconds = 30_000_000; + int confirmed = 0; + int subscription = mavint.SubscribeToPacketType( + MAVLink.MAVLINK_MSG_ID.MESSAGE_INTERVAL, + message => + { + MAVLink.mavlink_message_interval_t interval = + message.ToStructure(); + if (interval.message_id == informationId) + { + Interlocked.Exchange(ref confirmed, 1); + log.InfoFormat( + "GimbalManager: information interval response {0} us", + interval.interval_us); + } + return true; + }, sysid, compid); + + try + { + for (int attempt = 0; attempt < 3 && !_haveManagerInformation && + Volatile.Read(ref confirmed) == 0; attempt++) + { + SendDiscoveryIntervalRequest(informationId, intervalMicroseconds); + await Task.Delay(5000, _lifetime.Token).ConfigureAwait(false); + } + } + catch (OperationCanceledException) + { + } + finally { - first_discover = false; - mavint.OnPacketReceived += MessagesHandler; + mavint.UnSubscribeToPacketType(subscription); } + } - mavint.doCommand(0, 0, MAVLink.MAV_CMD.REQUEST_MESSAGE, - (float)MAVLink.MAVLINK_MSG_ID.GIMBAL_MANAGER_INFORMATION, - 0, 0, 0, 0, 0, 0, false); + private void SendDiscoveryIntervalRequest(ushort messageId, float intervalMicroseconds) + { + try + { + ObserveFault(mavint.doCommandAsync(_systemId, _componentId, + MAVLink.MAV_CMD.SET_MESSAGE_INTERVAL, + messageId, intervalMicroseconds, + 0, 0, 0, 0, 0, false)); + ObserveFault(mavint.doCommandAsync(_systemId, _componentId, + MAVLink.MAV_CMD.GET_MESSAGE_INTERVAL, + messageId, 0, 0, 0, 0, 0, 0, false)); + } + catch (Exception ex) + { + log.Debug("Gimbal manager discovery failed: " + ex.Message); + } + } + + private static void ObserveFault(Task task) + { + task?.ContinueWith(faulted => + log.Debug("Gimbal manager request failed: " + + faulted.Exception?.GetBaseException().Message), + CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, + TaskScheduler.Default); } private void MessagesHandler(object sender, MAVLink.MAVLinkMessage message) { + // One protocol instance belongs to one vehicle. Attitude status may come + // from a gimbal component, while manager information comes from the manager. + if (message.sysid != _systemId) + return; + if (message.msgid == (uint)MAVLink.MAVLINK_MSG_ID.GIMBAL_MANAGER_INFORMATION) { + if (message.compid != _componentId) + return; var gmi = (MAVLink.mavlink_gimbal_manager_information_t)message.data; ManagerInfo[gmi.gimbal_device_id] = gmi; @@ -60,6 +145,7 @@ private void MessagesHandler(object sender, MAVLink.MAVLinkMessage message) { ManagerInfo[0] = gmi; } + _haveManagerInformation = true; } if (message.msgid == (uint)MAVLink.MAVLINK_MSG_ID.GIMBAL_MANAGER_STATUS) @@ -95,23 +181,24 @@ public bool HasAllCapability(MAVLink.GIMBAL_MANAGER_CAP_FLAGS flags, byte gimbal public bool HasStatusFlag(MAVLink.GIMBAL_DEVICE_FLAGS flags, byte gimbal_device_id = 0) { - return ManagerStatus.TryGetValue(gimbal_device_id, out var status) && ((status.flags & (uint)flags) != 0); + return GimbalStatus.TryGetValue(gimbal_device_id, out var status) && + ((status.flags & (uint)flags) != 0); } public bool YawInVehicleFrame(byte gimbal_device_id = 0) { - bool yaw_in_earth_frame = HasStatusFlag(MAVLink.GIMBAL_DEVICE_FLAGS.YAW_IN_EARTH_FRAME, gimbal_device_id); - bool yaw_in_vehicle_frame = HasStatusFlag(MAVLink.GIMBAL_DEVICE_FLAGS.YAW_IN_VEHICLE_FRAME, gimbal_device_id); - - // Some older protocols don't set YAW_IN_EARTH_FRAME or YAW_IN_VEHICLE_FRAME flags, - // with those, we have to infer it from whether YAW_LOCK is set. - if (!yaw_in_earth_frame && !yaw_in_vehicle_frame) - { - bool yaw_lock = HasStatusFlag(MAVLink.GIMBAL_DEVICE_FLAGS.YAW_LOCK, gimbal_device_id); - yaw_in_vehicle_frame = !yaw_lock; - } + return !GimbalStatus.TryGetValue(gimbal_device_id, out var status) || + YawIsInVehicleFrame(status.flags); + } - return yaw_in_vehicle_frame; + internal static bool YawIsInVehicleFrame(uint statusFlags) + { + var flags = (MAVLink.GIMBAL_DEVICE_FLAGS)statusFlags; + bool earth = (flags & MAVLink.GIMBAL_DEVICE_FLAGS.YAW_IN_EARTH_FRAME) != 0; + bool vehicle = (flags & MAVLink.GIMBAL_DEVICE_FLAGS.YAW_IN_VEHICLE_FRAME) != 0; + if (!earth && !vehicle) + vehicle = (flags & MAVLink.GIMBAL_DEVICE_FLAGS.YAW_LOCK) == 0; + return vehicle; } /// @@ -205,16 +292,14 @@ public Task SetRCYawLockAsync(bool yaw_lock, byte gimbal_device_id = 0) public Task SetAttitudeAsync(Quaternion q, bool yaw_lock, byte gimbal_device_id = 0) { var pitch = q.get_euler_pitch() * MathHelper.rad2deg; - var yaw = q.get_euler_yaw() * MathHelper.rad2deg; + var yaw = q.get_euler_yaw() * MathHelper.rad2deg; if (!yaw_lock) { yaw -= cs.yaw; } - Console.WriteLine("SetAttitudeAsync: pitch={0}, yaw={1}, yaw_lock={2}", pitch, yaw < 0 ? yaw + 360 : yaw, yaw_lock); return SetAnglesCommandAsync(pitch, yaw, yaw_lock, gimbal_device_id); - //return Task.FromResult(true); } private double wrap_180(double angle) @@ -353,5 +438,13 @@ public Task SetROISysIDAsync(byte sysid, byte gimbal_device_id = 0) gimbal_device_id, 0, 0, 0, 0, 0); } + + public void Dispose() + { + if (Interlocked.Exchange(ref _disposed, 1) != 0) + return; + _lifetime.Cancel(); + mavint.OnPacketReceived -= MessagesHandler; + } } } diff --git a/ExtLibs/ArduPilot/Mavlink/GimbalProtocol.cs b/ExtLibs/ArduPilot/Mavlink/GimbalProtocol.cs index b06a5fa0ec..6829bf722e 100644 --- a/ExtLibs/ArduPilot/Mavlink/GimbalProtocol.cs +++ b/ExtLibs/ArduPilot/Mavlink/GimbalProtocol.cs @@ -1,12 +1,18 @@ using System; using System.Collections.Generic; using System.Text; +using System.Threading; using MissionPlanner.Utilities; namespace MissionPlanner.ArduPilot.Mavlink { - public class GimbalProtocol + public class GimbalProtocol : IDisposable { + private MAVLinkInterface _interface; + private EventHandler _messageHandler; + private int _started; + private int _disposed; + //Multiple component IDs are reserved for gimbal devices: MAV_COMP_ID_GIMBAL, MAV_COMP_ID_GIMBAL2, MAV_COMP_ID_GIMBAL3, MAV_COMP_ID_GIMBAL4, MAV_COMP_ID_GIMBAL5, MAV_COMP_ID_GIMBAL6 //gsdk - gimbal @@ -25,13 +31,22 @@ public class GimbalProtocol public void Discover(MAVLinkInterface mint) { - mint.doCommand(0, 0, MAVLink.MAV_CMD.REQUEST_MESSAGE, - (float)MAVLink.MAVLINK_MSG_ID.GIMBAL_DEVICE_INFORMATION, - 0, 0, 0, 0, 0, 0, false); + Discover(mint, (byte)mint.sysidcurrent, (byte)mint.compidcurrent); + } - mint.OnPacketReceived += (sender, message) => + public void Discover(MAVLinkInterface mint, byte sysid, byte compid) + { + if (mint == null) + throw new ArgumentNullException(nameof(mint)); + if (Volatile.Read(ref _disposed) != 0 || + Interlocked.Exchange(ref _started, 1) != 0) + return; + + _interface = mint; + _messageHandler = (sender, message) => { - if (message.msgid == (uint)MAVLink.MAVLINK_MSG_ID.GIMBAL_DEVICE_INFORMATION) + if (message.sysid == sysid && message.compid == compid && + message.msgid == (uint)MAVLink.MAVLINK_MSG_ID.GIMBAL_DEVICE_INFORMATION) { var gi = (MAVLink.mavlink_gimbal_device_information_t)message.data; @@ -41,6 +56,20 @@ public void Discover(MAVLinkInterface mint) } } }; + mint.OnPacketReceived += _messageHandler; + mint.doCommand(sysid, compid, MAVLink.MAV_CMD.REQUEST_MESSAGE, + (float)MAVLink.MAVLINK_MSG_ID.GIMBAL_DEVICE_INFORMATION, + 0, 0, 0, 0, 0, 0, false); + } + + public void Dispose() + { + if (Interlocked.Exchange(ref _disposed, 1) != 0) + return; + if (_interface != null && _messageHandler != null) + _interface.OnPacketReceived -= _messageHandler; + _messageHandler = null; + _interface = null; } public bool Reboot(MAVLinkInterface mint, byte sysid, byte compid) diff --git a/ExtLibs/ArduPilot/Mavlink/LogDownloadTracker.cs b/ExtLibs/ArduPilot/Mavlink/LogDownloadTracker.cs new file mode 100644 index 0000000000..54727c1814 --- /dev/null +++ b/ExtLibs/ArduPilot/Mavlink/LogDownloadTracker.cs @@ -0,0 +1,135 @@ +using System; +using System.Collections.Generic; + +namespace MissionPlanner +{ + /// + /// Tracks byte ranges received by the MAVLink LOG_DATA protocol. Packets may be duplicated, + /// delayed or delivered out of order, so the last packet offset is not a reliable measure of + /// progress and a packet-number set cannot describe partially overlapping ranges. + /// + internal sealed class LogDownloadTracker + { + internal const uint PacketSize = 90; + + private readonly List _ranges = new List(); + + public uint? TotalLength { get; private set; } + + public ulong CoveredBytes + { + get + { + ulong limit = TotalLength.HasValue ? TotalLength.Value : ulong.MaxValue; + ulong covered = 0; + foreach (ByteRange range in _ranges) + { + if (range.Start >= limit) + break; + + covered += Math.Min(range.End, limit) - range.Start; + } + + return covered; + } + } + + public bool IsComplete => TotalLength.HasValue && CoveredBytes >= TotalLength.Value; + + /// + /// Records a valid LOG_DATA payload. A short packet from the initial unbounded request + /// identifies the end of the log; callers must stop inferring the end after it is known. + /// + public bool Add(uint offset, byte count, bool inferTotalLength) + { + ulong end = (ulong)offset + count; + if (end > uint.MaxValue) + return false; + + if (inferTotalLength && count < PacketSize) + TotalLength = (uint)end; + + if (count == 0) + return true; + + Merge(new ByteRange(offset, end)); + return true; + } + + /// + /// Returns the first missing range. Before the total is known, requesting to uint.MaxValue + /// resumes the initial stream at the first gap. Afterwards requests are bounded so one lost + /// packet does not force the flight controller to resend the rest of a large log. + /// + public LogDownloadRequest NextRequest(uint maximumKnownLength) + { + ulong cursor = 0; + ulong limit = TotalLength.HasValue ? TotalLength.Value : uint.MaxValue; + ulong missingEnd = limit; + + foreach (ByteRange range in _ranges) + { + if (range.Start > cursor) + { + missingEnd = Math.Min(range.Start, limit); + break; + } + + if (range.End > cursor) + cursor = range.End; + + if (cursor >= limit) + break; + } + + uint offset = (uint)Math.Min(cursor, uint.MaxValue); + if (!TotalLength.HasValue) + return new LogDownloadRequest(offset, uint.MaxValue); + + ulong remaining = missingEnd - cursor; + uint count = (uint)Math.Min(remaining, maximumKnownLength); + return new LogDownloadRequest(offset, count); + } + + private void Merge(ByteRange incoming) + { + int index = 0; + while (index < _ranges.Count && _ranges[index].End < incoming.Start) + index++; + + while (index < _ranges.Count && _ranges[index].Start <= incoming.End) + { + incoming = new ByteRange( + Math.Min(incoming.Start, _ranges[index].Start), + Math.Max(incoming.End, _ranges[index].End)); + _ranges.RemoveAt(index); + } + + _ranges.Insert(index, incoming); + } + + private struct ByteRange + { + public ByteRange(ulong start, ulong end) + { + Start = start; + End = end; + } + + public ulong Start { get; } + public ulong End { get; } + } + } + + internal struct LogDownloadRequest + { + public LogDownloadRequest(uint offset, uint count) + { + Offset = offset; + Count = count; + } + + public uint Offset { get; } + public uint Count { get; } + } +} diff --git a/ExtLibs/ArduPilot/Mavlink/MAVAuthKeys.cs b/ExtLibs/ArduPilot/Mavlink/MAVAuthKeys.cs index d6e494dc14..dbba7254aa 100644 --- a/ExtLibs/ArduPilot/Mavlink/MAVAuthKeys.cs +++ b/ExtLibs/ArduPilot/Mavlink/MAVAuthKeys.cs @@ -15,11 +15,18 @@ public class MAVAuthKeys private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - static string keyfile = Settings.GetUserDataDirectory() + "authkeys.xml"; - - static Crypto Rij = new Crypto(); - - public static AuthKeys Keys = new AuthKeys(); + private static readonly object Sync = new object(); + private static readonly string KeyFile = + Path.Combine(Settings.GetUserDataDirectory(), "authkeys.xml"); + private static readonly string MaterialFile = + Path.Combine(Settings.GetUserDataDirectory(), "authkeys.key"); + private static readonly MavAuthKeyStore Store = new MavAuthKeyStore(KeyFile, MaterialFile); + + public static AuthKeys Keys = new AuthKeys(); + + public static Exception LoadFailure { get; private set; } + + public static bool IsAvailable => LoadFailure == null; //https://msdn.microsoft.com/en-us/library/aa347850(v=vs.110).aspx @@ -42,54 +49,57 @@ static MAVAuthKeys() Load(); } - public static void AddKey(string name, string seed) - { - // sha the user input string - using (SHA256CryptoServiceProvider signit = new SHA256CryptoServiceProvider()) - { - var shauser = signit.ComputeHash(Encoding.UTF8.GetBytes(seed)); - Array.Resize(ref shauser, 32); - - Keys[name] = new AuthKey() {Key = shauser, Name = name}; - } - } - - public static void Save() - { - // save config - DataContractSerializer writer = - new DataContractSerializer(typeof(AuthKeys), - new Type[] {typeof (AuthKey)}); - - using (var fs = new FileStream(keyfile, FileMode.Create)) - using (var sw = new CryptoStream(fs, Rij.algorithm.CreateEncryptor(), CryptoStreamMode.Write)) - { - writer.WriteObject(sw, Keys); - } - } - - internal static void Load() - { - if (!File.Exists(keyfile)) - return; - - try - { - - DataContractSerializer reader = - new DataContractSerializer(typeof (AuthKeys), - new Type[] {typeof (AuthKey)}); - - using (var fs = new FileStream(keyfile, FileMode.Open)) - using (var sr = new CryptoStream(fs, Rij.algorithm.CreateDecryptor(), CryptoStreamMode.Read)) - { - Keys = (AuthKeys) reader.ReadObject(sr); - } - } - catch (Exception ex) - { - log.Error(ex); - } - } + public static void AddKey(string name, string seed) + { + lock (Sync) + { + EnsureAvailable(); + // sha the user input string + using (SHA256CryptoServiceProvider signit = new SHA256CryptoServiceProvider()) + { + var shauser = signit.ComputeHash(Encoding.UTF8.GetBytes(seed)); + Array.Resize(ref shauser, 32); + + Keys[name] = new AuthKey() {Key = shauser, Name = name}; + } + } + } + + public static void Save() + { + lock (Sync) + { + EnsureAvailable(); + Store.Save(Keys); + } + } + + internal static void Load() + { + lock (Sync) + { + try + { + Keys = Store.Load(); + LoadFailure = null; + } + catch (Exception ex) + { + // Never replace an unreadable file with an empty collection. Save/Add are + // disabled until a later process can decrypt it or the user restores its key. + Keys = new AuthKeys(); + LoadFailure = ex; + log.Error("MAVLink signing keys could not be loaded; preserving the existing file.", ex); + } + } + } + + private static void EnsureAvailable() + { + if (LoadFailure != null) + throw new InvalidOperationException( + "The existing MAVLink signing-key file could not be loaded and was left unchanged.", + LoadFailure); + } } } diff --git a/ExtLibs/ArduPilot/Mavlink/MAVFtp.cs b/ExtLibs/ArduPilot/Mavlink/MAVFtp.cs index a356fa9373..6a083f3511 100644 --- a/ExtLibs/ArduPilot/Mavlink/MAVFtp.cs +++ b/ExtLibs/ArduPilot/Mavlink/MAVFtp.cs @@ -2,6 +2,7 @@ using System.CodeDom; using System.Collections.Generic; using System.IO; +using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; @@ -32,6 +33,7 @@ public class MAVFtp const byte rwSize = 80; private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly UTF8Encoding StrictUtf8 = new UTF8Encoding(false, true); private readonly byte _compid; private readonly MAVLinkInterface _mavint; private readonly byte _sysid; @@ -1301,58 +1303,19 @@ public List kCmdListDirectory(string dir, CancellationTokenSource c if (ftphead.opcode != FTPOpcode.kRspAck) return true; var requested_offset = ftphead.offset; - var offset = 0; - while (offset < ftphead.size) + List packetEntries; + string parseError; + if (!TryParseDirectoryEntries( + ftphead.data, ftphead.size, dir, out packetEntries, out parseError)) { - var b = ftphead.data[offset++]; - switch (b) - { - case kDirentFile: - var filename = new StringBuilder(); - while (b != 0x0) - { - b = ftphead.data[offset++]; - if (b != 0x0) - filename.Append((char) b); - } - - var items = filename.ToString().Split('\t'); - var size = ulong.Parse(items[1]); - answer.Add(new FtpFileInfo(items[0], dir, false, size)); - break; - case kDirentDir: - var name = new StringBuilder(); - while (b != 0x0) - { - b = ftphead.data[offset++]; - if (b != 0x0) - name.Append((char) b); - } - - answer.Add(new FtpFileInfo(name.ToString(), dir, true)); - break; - case kDirentSkip: - while (b != 0x0) - { - b = ftphead.data[offset++]; - } - - answer.Add(new FtpFileInfo("", dir, true)); - break; - default: - var nameextra = new StringBuilder(); - while (b != 0x0) - { - b = ftphead.data[offset++]; - if (b != 0x0) - nameextra.Append((char) b); - } - - if (nameextra.ToString() != "") - answer.Add(new FtpFileInfo(nameextra.ToString(), dir, false)); - break; - } + timeout.Retries = 0; + timeout.Complete = true; + ex = new InvalidDataException( + $"Malformed MAVFTP directory response at offset {requested_offset}: {parseError}"); + log.Error(ex.Message); + return true; } + answer.AddRange(packetEntries); // 0 records if (answer.Count == 0) @@ -1388,6 +1351,104 @@ public List kCmdListDirectory(string dir, CancellationTokenSource c return answer; } + internal static bool TryParseDirectoryEntries( + uint8_t[] data, int count, string directory, + out List entries, out string error) + { + entries = new List(); + error = ""; + if (data == null) + { + error = "payload is null"; + return false; + } + if (count < 0 || count > data.Length) + { + error = $"payload size {count} exceeds the {data.Length}-byte buffer"; + return false; + } + + int offset = 0; + while (offset < count) + { + uint8_t entryType = data[offset++]; + if (entryType == 0) + continue; + + string value; + if (!TryExtractNullTerminatedUtf8( + data, offset, count, out value, out offset, out error)) + { + entries.Clear(); + return false; + } + + switch (entryType) + { + case kDirentFile: + int separator = value.LastIndexOf('\t'); + ulong size; + if (separator <= 0 || separator == value.Length - 1 || + !ulong.TryParse(value.Substring(separator + 1), NumberStyles.None, + CultureInfo.InvariantCulture, out size)) + { + entries.Clear(); + error = "file entry has no valid tab-separated size"; + return false; + } + entries.Add(new FtpFileInfo( + value.Substring(0, separator), directory, false, size)); + break; + case kDirentDir: + entries.Add(new FtpFileInfo(value, directory, true)); + break; + case kDirentSkip: + entries.Add(new FtpFileInfo("", directory, true)); + break; + default: + // Preserve the legacy handling of vendor-specific entry tags, but decode + // their names safely and never read past the reported packet size. + if (value.Length != 0) + entries.Add(new FtpFileInfo(value, directory, false)); + break; + } + } + return true; + } + + internal static bool TryExtractNullTerminatedUtf8( + uint8_t[] data, int offset, int limit, out string value, out int nextOffset, + out string error) + { + value = ""; + nextOffset = offset; + error = ""; + if (data == null || offset < 0 || limit < offset || limit > data.Length) + { + error = "invalid string bounds"; + return false; + } + + int tail = Array.IndexOf(data, (uint8_t)0, offset, limit - offset); + if (tail < 0) + { + error = "directory entry is not null terminated"; + return false; + } + + try + { + value = StrictUtf8.GetString(data, offset, tail - offset); + nextOffset = tail + 1; + return true; + } + catch (DecoderFallbackException) + { + error = "directory entry contains invalid UTF-8"; + return false; + } + } + public bool kCmdOpenFileWO(string file, ref int size, CancellationTokenSource cancel) { fileTransferProtocol.target_system = _sysid; diff --git a/ExtLibs/ArduPilot/Mavlink/MAVLinkInterface.cs b/ExtLibs/ArduPilot/Mavlink/MAVLinkInterface.cs index 29057ae6aa..6ce2fe3683 100644 --- a/ExtLibs/ArduPilot/Mavlink/MAVLinkInterface.cs +++ b/ExtLibs/ArduPilot/Mavlink/MAVLinkInterface.cs @@ -282,6 +282,8 @@ public bool giveComport public bool ReadOnly = false; + public MessageRateManager RateManager { get; private set; } + public TerrainFollow Terrain; public event ProgressEventHandler Progress; @@ -491,6 +493,8 @@ public MAVLinkInterface() _mavlink2count = 0; _mavlink2signed = 0; + RateManager = new MessageRateManager(this); + AIS.Start(this); // new hearbeat detected @@ -501,32 +505,43 @@ private void OnMAVDetected(object sender, (byte, byte) tuple) { // check for a camera - if (tuple.Item2 == (byte)MAVLink.MAV_COMPONENT.MAV_COMP_ID_AUTOPILOT1 || - (tuple.Item2 >= (byte) MAVLink.MAV_COMPONENT.MAV_COMP_ID_CAMERA && - tuple.Item2 <= (byte) MAV_COMPONENT.MAV_COMP_ID_CAMERA6)) - { - MAVlist[tuple.Item1, tuple.Item2].Camera = new CameraProtocol(); - Task.Run(async () => - { - try - { - // Open holds this - while (!_openComplete) - { - await Task.Delay(1000); - } - - await Task.Delay(2000); - - if (MAVlist[tuple.Item1, tuple.Item2].Camera == null) - return; - - while(giveComport) - await Task.Delay(100); - - await MAVlist[tuple.Item1, tuple.Item2] - .Camera.StartID(MAVlist[tuple.Item1, tuple.Item2]) - .ConfigureAwait(false); + if (tuple.Item2 == (byte)MAVLink.MAV_COMPONENT.MAV_COMP_ID_AUTOPILOT1 || + (tuple.Item2 >= (byte) MAVLink.MAV_COMPONENT.MAV_COMP_ID_CAMERA && + tuple.Item2 <= (byte) MAV_COMPONENT.MAV_COMP_ID_CAMERA6)) + { + MAVState cameraState = MAVlist[tuple.Item1, tuple.Item2]; + cameraState.Camera?.Dispose(); + var camera = new CameraProtocol(); + cameraState.Camera = camera; + Task.Run(async () => + { + try + { + // Open holds this + while (!_openComplete) + { + if (Volatile.Read(ref _disposeState) != 0 || + !ReferenceEquals(cameraState.Camera, camera)) + return; + await Task.Delay(1000); + } + + await Task.Delay(2000); + + if (Volatile.Read(ref _disposeState) != 0 || + !ReferenceEquals(cameraState.Camera, camera)) + return; + + while(giveComport) + { + if (Volatile.Read(ref _disposeState) != 0 || + !ReferenceEquals(cameraState.Camera, camera)) + return; + await Task.Delay(100); + } + + await camera.StartID(cameraState) + .ConfigureAwait(false); } catch (Exception e) { @@ -535,24 +550,32 @@ private void OnMAVDetected(object sender, (byte, byte) tuple) }); } // gimbals - if (tuple.Item2 >= (byte)MAVLink.MAV_COMPONENT.MAV_COMP_ID_GIMBAL && - tuple.Item2 <= (byte)MAV_COMPONENT.MAV_COMP_ID_GIMBAL6) - { - MAVlist[tuple.Item1, tuple.Item2].Gimbal = new GimbalProtocol(); - Task.Run(async () => - { + if (tuple.Item2 >= (byte)MAVLink.MAV_COMPONENT.MAV_COMP_ID_GIMBAL && + tuple.Item2 <= (byte)MAV_COMPONENT.MAV_COMP_ID_GIMBAL6) + { + MAVState gimbalState = MAVlist[tuple.Item1, tuple.Item2]; + gimbalState.Gimbal?.Dispose(); + var gimbal = new GimbalProtocol(); + gimbalState.Gimbal = gimbal; + Task.Run(async () => + { try { // Open holds this - while (!_openComplete) - { - await Task.Delay(1000); - } - - await Task.Delay(2000); - - MAVlist[tuple.Item1, tuple.Item2] - .Gimbal?.Discover(this); + while (!_openComplete) + { + if (Volatile.Read(ref _disposeState) != 0 || + !ReferenceEquals(gimbalState.Gimbal, gimbal)) + return; + await Task.Delay(1000); + } + + await Task.Delay(2000); + + if (Volatile.Read(ref _disposeState) != 0 || + !ReferenceEquals(gimbalState.Gimbal, gimbal)) + return; + gimbal.Discover(this, tuple.Item1, tuple.Item2); } catch (Exception e) { @@ -561,25 +584,35 @@ private void OnMAVDetected(object sender, (byte, byte) tuple) }); } - if (tuple.Item2 == (byte)MAV_COMPONENT.MAV_COMP_ID_AUTOPILOT1 || - (tuple.Item2 >= (byte)MAV_COMPONENT.MAV_COMP_ID_MISSIONPLANNER && - tuple.Item2 <= (byte)MAV_COMPONENT.MAV_COMP_ID_ONBOARD_COMPUTER4)) - { - MAVlist[tuple.Item1, tuple.Item2].GimbalManager = new GimbalManagerProtocol(this, MAVlist[tuple.Item1, tuple.Item2].cs); - Task.Run(async () => - { + if (tuple.Item2 == (byte)MAV_COMPONENT.MAV_COMP_ID_AUTOPILOT1 || + (tuple.Item2 >= (byte)MAV_COMPONENT.MAV_COMP_ID_MISSIONPLANNER && + tuple.Item2 <= (byte)MAV_COMPONENT.MAV_COMP_ID_ONBOARD_COMPUTER4)) + { + MAVState managerState = MAVlist[tuple.Item1, tuple.Item2]; + managerState.GimbalManager?.Dispose(); + var manager = new GimbalManagerProtocol(this, managerState.cs); + managerState.GimbalManager = manager; + Task.Run(async () => + { try { // Open holds this - while (!_openComplete) - { - await Task.Delay(1000); - } - - await Task.Delay(2000); - - MAVlist[tuple.Item1, tuple.Item2] - .GimbalManager?.Discover(); + while (!_openComplete) + { + if (Volatile.Read(ref _disposeState) != 0 || + !ReferenceEquals(managerState.GimbalManager, manager)) + return; + await Task.Delay(1000); + } + + await Task.Delay(2000); + + if (Volatile.Read(ref _disposeState) != 0 || + !ReferenceEquals(managerState.GimbalManager, manager)) + return; + + await manager.StartID(tuple.Item1, tuple.Item2) + .ConfigureAwait(false); } catch (Exception e) { @@ -970,6 +1003,7 @@ No Mavlink Heartbeat Packets where read from this port - Verify Baud Rate and se MAV.packetslost = 0; MAV.synclost = 0; _openComplete = true; + RateManager.OnConnectionOpen(); } private string getAppVersion() @@ -4425,6 +4459,24 @@ public void setGuidedModeWP(byte sysid, byte compid, Locationwp gotohere, bool s if (gotohere.alt == 0 || gotohere.lat == 0 || gotohere.lng == 0) return; + try + { + mavlink_command_int_t reposition = BuildGuidedRepositionCommand( + sysid, compid, gotohere, setguidedmode); + if (doCommandInt( + sysid, compid, (MAV_CMD)reposition.command, + reposition.param1, reposition.param2, reposition.param3, reposition.param4, + reposition.x, reposition.y, reposition.z, + true, null, (MAV_FRAME)reposition.frame)) + return; + } + catch (Exception ex) + { + // Older autopilots may not implement DO_REPOSITION. Keep the historical + // guided-position protocol as a compatibility fallback. + log.Error(ex); + } + try { gotohere.id = (ushort) MAV_CMD.WAYPOINT; @@ -4461,16 +4513,66 @@ public void setGuidedModeWP(byte sysid, byte compid, Locationwp gotohere, bool s } } + internal static mavlink_command_int_t BuildGuidedRepositionCommand( + byte sysid, byte compid, Locationwp target, bool setGuidedMode) + { + return new mavlink_command_int_t + { + target_system = sysid, + target_component = compid, + command = (ushort)MAV_CMD.DO_REPOSITION, + frame = target.frame, + param1 = -1, + param2 = setGuidedMode ? (float)MAV_DO_REPOSITION_FLAGS.CHANGE_MODE : 0, + param3 = 0, + // Preserve the current vehicle yaw mode, matching the old position-target path. + param4 = float.NaN, + x = (int)(target.lat * 1e7), + y = (int)(target.lng * 1e7), + z = target.alt + }; + } + [Obsolete] public void setNewWPAlt(Locationwp gotohere) { - setNewWPAlt((byte) sysidcurrent, (byte) compidcurrent, gotohere); + setNewAlt((byte)sysidcurrent, (byte)compidcurrent, gotohere.alt); } + [Obsolete] public void setNewWPAlt(byte sysid, byte compid, Locationwp gotohere) { + setNewAlt(sysid, compid, gotohere.alt); + } + + [Obsolete] + public void setNewAlt(float newRelativeHomeAltitudeMetres) + { + setNewAlt((byte)sysidcurrent, (byte)compidcurrent, newRelativeHomeAltitudeMetres); + } + + public void setNewAlt(byte sysid, byte compid, float newRelativeHomeAltitudeMetres) + { + try + { + mavlink_command_long_t altitude = BuildAltitudeChangeCommand( + sysid, compid, newRelativeHomeAltitudeMetres); + if (doCommand( + sysid, compid, (MAV_CMD)altitude.command, + altitude.param1, altitude.param2, altitude.param3, altitude.param4, + altitude.param5, altitude.param6, altitude.param7)) + return; + } + catch (Exception ex) + { + // Fall back to the special MISSION_ITEM current value understood by + // older ArduPilot firmware. + log.Error(ex); + } + try { + Locationwp gotohere = new Locationwp {alt = newRelativeHomeAltitudeMetres}; gotohere.id = (ushort) MAV_CMD.WAYPOINT; log.InfoFormat("setNewWPAlt {0}:{1} lat {2} lng {3} alt {4}", sysid, compid, gotohere.lat, gotohere.lng, @@ -4497,6 +4599,19 @@ public void setNewWPAlt(byte sysid, byte compid, Locationwp gotohere) } } + internal static mavlink_command_long_t BuildAltitudeChangeCommand( + byte sysid, byte compid, float newRelativeHomeAltitudeMetres) + { + return new mavlink_command_long_t + { + target_system = sysid, + target_component = compid, + command = (ushort)MAV_CMD.DO_CHANGE_ALTITUDE, + param1 = newRelativeHomeAltitudeMetres, + param2 = (float)MAV_FRAME.GLOBAL_RELATIVE_ALT + }; + } + public void setPositionTargetGlobalInt(byte sysid, byte compid, bool pos, bool vel, bool acc, bool yaw, MAV_FRAME frame, double lat, double lng, double alt, double vx, double vy, double vz, double yawangle, double yawrate) @@ -5975,230 +6090,152 @@ public async Task GetLog(ushort no) } public async Task GetLog(byte sysid, byte compid, ushort no) - { - var filename = Path.GetTempFileName(); - using (FileStream ms = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite)) - { - Hashtable set = new Hashtable(); - - giveComport = false; - MAVLinkMessage buffer = MAVLinkMessage.Invalid; - - if (Progress != null) - { - Progress((int) 0, ""); - } - - uint totallength = 0; - uint ofs = 0; - uint bps = 0; - DateTime bpstimer = DateTime.Now; - - ConcurrentQueue queue = new ConcurrentQueue(); - EventHandler handler = (sender, msg) => - { - queue.Enqueue(msg); - }; - OnPacketReceived += handler; - - _OnPacketReceived.GetInvocationList().ForEach(a => log.Info(a.GetMethodInfo().ToJSON())); - - - mavlink_log_request_data_t req = new mavlink_log_request_data_t(); - - req.target_component = compid; - req.target_system = sysid; - req.id = no; - req.ofs = ofs; - // entire log - req.count = 0xFFFFFFFF; - - // request point - generatePacket((byte) MAVLINK_MSG_ID.LOG_REQUEST_DATA, req); - - DateTime start = DateTime.Now; - int retrys = 3; - - - while (true) - { - if (!(start.AddMilliseconds(3000) > DateTime.Now)) - { - if (retrys > 0) - { - log.Info("GetLog Retry " + retrys + " - giv com " + giveComport); - generatePacket((byte) MAVLINK_MSG_ID.LOG_REQUEST_DATA, req); - start = DateTime.Now; - retrys--; - continue; - } - - giveComport = false; - OnPacketReceived -= handler; - throw new TimeoutException("Timeout on read - GetLog"); - } - - var start1 = DateTime.Now; - if (!queue.TryDequeue(out buffer)) - { - Thread.Sleep(10); - buffer = MAVLinkMessage.Invalid; - } - var end = DateTime.Now - start1; - var lapse = end.TotalMilliseconds; - //Console.WriteLine("readPacketAsync: " + lapse); - if (buffer.Length > 5) - { - if (buffer.msgid == (byte) MAVLINK_MSG_ID.LOG_DATA && buffer.sysid == req.target_system && - buffer.compid == req.target_component) - { - var data = buffer.ToStructure(); - - if (data.id != no) - continue; - - // reset retrys - retrys = 3; - start = DateTime.Now; - - bps += data.count; - - // record what we have received - set[(data.ofs / 90).ToString()] = 1; - - if (ms.Position != data.ofs) - ms.Seek((long) data.ofs, SeekOrigin.Begin); - ms.Write(data.data, 0, data.count); - - // update new start point - req.ofs = data.ofs + data.count; - - if (bpstimer.Second != DateTime.Now.Second) - { - if (Progress != null) - { - Progress((int) req.ofs, ""); - } - - //Console.WriteLine("log dl bps: " + bps.ToString()); - bpstimer = DateTime.Now; - bps = 0; - } - - // if data is less than max packet size or 0 > exit - if (data.count < 90 || data.count == 0) - { - totallength = data.ofs + data.count; - log.Info("start fillin len " + totallength + " count " + set.Count + " datalen " + - data.count); - break; - } - } - } - } - - log.Info("set count " + set.Count); - log.Info("count total " + ((totallength) / 90 + 1)); - log.Info("totallength " + totallength); - log.Info("current length " + ms.Length); - - while (true && ((BaseStream != null && BaseStream.IsOpen) || logreadmode)) - { - if (totallength == ms.Length && set.Count >= ((totallength) / 90 + 1)) - { - giveComport = false; - OnPacketReceived -= handler; - return filename; - } - - if (!(start.AddMilliseconds(500) > DateTime.Now)) - { - for (int a = 0; a < ((totallength) / 90 + 1); a++) - { - if (!set.ContainsKey(a.ToString())) - { - // request large chunk if they are back to back - uint bytereq = 90; - int b = a + 1; - while (!set.ContainsKey(b.ToString())) - { - bytereq += 90; - b++; - } - - req.ofs = (uint) (a * 90); - req.count = bytereq; - log.Info("req missing " + req.ofs + " bytes " + req.count + " got " + set.Count + "/" + - ((totallength) / 90 + 1)); - generatePacket((byte) MAVLINK_MSG_ID.LOG_REQUEST_DATA, req); - start = DateTime.Now; - break; - } - } - } - - if (!queue.TryDequeue(out buffer)) - { - Thread.Sleep(10); - buffer = MAVLinkMessage.Invalid; - } - if (buffer.Length > 5) - { - if (buffer.msgid == (byte) MAVLINK_MSG_ID.LOG_DATA && buffer.sysid == req.target_system && - buffer.compid == req.target_component) - { - var data = buffer.ToStructure(); - - if (data.id != no) - continue; - - // reset retrys - retrys = 3; - start = DateTime.Now; - - bps += data.count; - - // record what we have received - set[(data.ofs / 90).ToString()] = 1; - - ms.Seek((long) data.ofs, SeekOrigin.Begin); - ms.Write(data.data, 0, data.count); - - // update new start point - req.ofs = data.ofs + data.count; - - if (bpstimer.Second != DateTime.Now.Second) - { - if (Progress != null) - { - Progress((int) req.ofs, ""); - } - - //Console.WriteLine("log dl bps: " + bps.ToString()); - bpstimer = DateTime.Now; - bps = 0; - } - - // check if we have next set and invalidate to request next packets - if (set.ContainsKey(((data.ofs / 90) + 1).ToString())) - { - start = DateTime.MinValue; - } - - // if data is less than max packet size or 0 > exit - if (data.count < 90 || data.count == 0) - { - continue; - } - } - } - } - - OnPacketReceived -= handler; - throw new Exception("Failed to get log"); - } - } - + { + var filename = Path.GetTempFileName(); + try + { + using (FileStream ms = new FileStream(filename, FileMode.Create, FileAccess.ReadWrite)) + { + const int retryLimit = 10; + const int retryDelayMilliseconds = 3000; + const uint maximumRepairRequest = LogDownloadTracker.PacketSize * 50; + + giveComport = false; + Progress?.Invoke(0, ""); + + var tracker = new LogDownloadTracker(); + var queue = new ConcurrentQueue(); + EventHandler handler = (sender, msg) => + { + if (msg.Length > 5 && msg.msgid == (byte) MAVLINK_MSG_ID.LOG_DATA && + msg.sysid == sysid && msg.compid == compid) + { + queue.Enqueue(msg); + } + }; + OnPacketReceived += handler; + + var request = new mavlink_log_request_data_t + { + target_component = compid, + target_system = sysid, + id = no, + ofs = 0, + count = uint.MaxValue + }; + + try + { + generatePacket((byte) MAVLINK_MSG_ID.LOG_REQUEST_DATA, request); + int retriesRemaining = retryLimit; + DateTime nextRetryAt = DateTime.UtcNow.AddMilliseconds(retryDelayMilliseconds); + DateTime nextProgressAt = DateTime.UtcNow; + + while ((BaseStream != null && BaseStream.IsOpen) || logreadmode) + { + DateTime now = DateTime.UtcNow; + if (now >= nextRetryAt) + { + if (retriesRemaining-- <= 0) + throw new TimeoutException( + "Log download stopped responding before every byte was received."); + + LogDownloadRequest missing = tracker.NextRequest(maximumRepairRequest); + request.ofs = missing.Offset; + request.count = missing.Count; + log.Info("GetLog retry " + (retryLimit - retriesRemaining) + + " requesting offset " + request.ofs + " count " + request.count + + " received " + tracker.CoveredBytes + + (tracker.TotalLength.HasValue + ? "/" + tracker.TotalLength.Value + : "/unknown")); + generatePacket((byte) MAVLINK_MSG_ID.LOG_REQUEST_DATA, request); + nextRetryAt = now.AddMilliseconds(retryDelayMilliseconds); + continue; + } + + MAVLinkMessage buffer; + if (!queue.TryDequeue(out buffer)) + { + await Task.Delay(10).ConfigureAwait(false); + continue; + } + + var data = buffer.ToStructure(); + if (data.id != no || data.data == null || data.count > data.data.Length) + continue; + + ulong coveredBefore = tracker.CoveredBytes; + bool totalWasKnown = tracker.TotalLength.HasValue; + if (!tracker.Add(data.ofs, data.count, !totalWasKnown)) + continue; + + if (data.count > 0) + { + ms.Seek(data.ofs, SeekOrigin.Begin); + ms.Write(data.data, 0, data.count); + } + + ulong covered = tracker.CoveredBytes; + bool madeProgress = covered > coveredBefore || + (!totalWasKnown && tracker.TotalLength.HasValue); + if (madeProgress) + { + retriesRemaining = retryLimit; + nextRetryAt = now.AddMilliseconds(retryDelayMilliseconds); + } + + if (now >= nextProgressAt || tracker.IsComplete) + { + Progress?.Invoke((int) Math.Min(covered, int.MaxValue), ""); + nextProgressAt = now.AddMilliseconds(250); + } + + if (tracker.IsComplete) + { + ms.SetLength(tracker.TotalLength.Value); + ms.Flush(); + log.Info("GetLog complete: " + tracker.TotalLength.Value + " bytes"); + return filename; + } + } + + throw new IOException("Connection closed before the log download completed."); + } + finally + { + OnPacketReceived -= handler; + giveComport = false; + try + { + generatePacket((byte) MAVLINK_MSG_ID.LOG_REQUEST_END, + new mavlink_log_request_end_t + { + target_system = sysid, + target_component = compid + }); + } + catch (Exception ex) + { + log.Debug("Could not send LOG_REQUEST_END", ex); + } + } + } + } + catch + { + try + { + File.Delete(filename); + } + catch + { + } + + throw; + } + } + [Obsolete] public List GetLogList() { @@ -6831,8 +6868,14 @@ public override string ToString() return "MAV " + MAV.sysid + " on Ice"; } + private int _disposeState; + public void Dispose() { + if (Interlocked.Exchange(ref _disposeState, 1) != 0) + return; + + RateManager?.Dispose(); if (_bytesReceivedSubj != null) _bytesReceivedSubj.Dispose(); if (_bytesSentSubj != null) @@ -6849,6 +6892,7 @@ public void Dispose() logreadmode = false; logplaybackfile = null; + GC.SuppressFinalize(this); } public void uAvionixADSBControl(int baroAltMSL,ushort squawk,/*UAVIONIX_ADSB_OUT_CONTROL_STATE*/byte state,/*UAVIONIX_ADSB_EMERGENCY_STATUS*/byte emergencyStatus,byte[] flight_id,byte x_bit) @@ -6891,10 +6935,10 @@ public void RunBackgroundOperationAsync() if (this.DoWork != null) this.DoWork(this); log.Info("DoWork Done"); } - catch (Exception e) - { - log.Error(e); - } + catch (Exception e) + { + log.Error(e); + } }).Wait(); } diff --git a/ExtLibs/ArduPilot/Mavlink/MAVList.cs b/ExtLibs/ArduPilot/Mavlink/MAVList.cs index 48b86117e5..54c31a87d3 100644 --- a/ExtLibs/ArduPilot/Mavlink/MAVList.cs +++ b/ExtLibs/ArduPilot/Mavlink/MAVList.cs @@ -72,7 +72,16 @@ public List GetRawIDS() public void Clear() { - masterlist.Clear(); + lock (locker) + { + foreach (MAVState state in masterlist.Values) + state.Dispose(); + foreach (MAVState state in hiddenlist.Values) + state.Dispose(); + masterlist.Clear(); + hiddenlist.Clear(); + hiddenlist.Add(0, new MAVState(parent, 0, 0)); + } } public bool Contains(byte sysid, byte compid, bool includehidden = true) @@ -155,4 +164,4 @@ public void Dispose() } } } -} \ No newline at end of file +} diff --git a/ExtLibs/ArduPilot/Mavlink/MAVState.cs b/ExtLibs/ArduPilot/Mavlink/MAVState.cs index d76715fbcb..14c9753682 100644 --- a/ExtLibs/ArduPilot/Mavlink/MAVState.cs +++ b/ExtLibs/ArduPilot/Mavlink/MAVState.cs @@ -15,9 +15,9 @@ using System.Threading.Tasks; using System.Runtime.CompilerServices; -[assembly: InternalsVisibleTo("MissionPlanner")] - -namespace MissionPlanner +[assembly: InternalsVisibleTo("MissionPlanner")] + +namespace MissionPlanner { public class MAVState : MAVLink, IDisposable { @@ -57,12 +57,12 @@ public MAVState(MAVLinkInterface mavLinkInterface, byte sysid, byte compid) this.packetspersecond = new Dictionary(byte.MaxValue); this.packetspersecondbuild = new Dictionary(byte.MaxValue); this.lastvalidpacket = DateTime.MinValue; - sendlinkid = (byte)(new Random().Next(256)); - signing = false; - this.param = new MAVLinkParamList(); - // Safety policy: parameter lists are session-only. Persisting a completed list can - // display or write values from another UDP modem after a device/target switch. - this.packets = new Dictionary>(byte.MaxValue); + sendlinkid = (byte)(new Random().Next(256)); + signing = false; + this.param = new MAVLinkParamList(); + // Safety policy: parameter lists are session-only. Persisting a completed list can + // display or write values from another UDP modem after a device/target switch. + this.packets = new Dictionary>(byte.MaxValue); this.packetsLast = new Dictionary(byte.MaxValue); this.aptype = 0; this.apname = 0; @@ -233,6 +233,12 @@ public void clearPacket(uint mavlinkid) public void Dispose() { + Camera?.Dispose(); + Camera = null; + Gimbal?.Dispose(); + Gimbal = null; + GimbalManager?.Dispose(); + GimbalManager = null; if (Proximity != null) Proximity.Dispose(); } @@ -307,4 +313,4 @@ public override string ToString() return sysid.ToString(); } } -} +} diff --git a/ExtLibs/ArduPilot/Mavlink/MavAuthKeyStore.cs b/ExtLibs/ArduPilot/Mavlink/MavAuthKeyStore.cs new file mode 100644 index 0000000000..ac4f5fad14 --- /dev/null +++ b/ExtLibs/ArduPilot/Mavlink/MavAuthKeyStore.cs @@ -0,0 +1,303 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.Serialization; +using System.Security.Cryptography; +using System.Text; +using MissionPlanner.Mavlink; +using MissionPlanner.Utilities; + +namespace MissionPlanner +{ + /// + /// Durable encrypted storage for MAVLink signing keys. The encryption material is persisted + /// separately so changing NIC enumeration cannot make the key store unreadable. Existing files + /// are migrated by trying every currently available legacy MAC-derived key. + /// + internal sealed class MavAuthKeyStore : IDisposable + { + private static readonly byte[] MaterialMagic = Encoding.ASCII.GetBytes("MPAK1"); + private const int KeyLength = 32; + private const int IvLength = 16; + + private readonly object _sync = new object(); + private readonly string _keyFile; + private readonly string _materialFile; + private readonly Func> _legacyCandidates; + private Crypto _crypto; + private bool _loaded; + + public MavAuthKeyStore(string keyFile, string materialFile) + : this(keyFile, materialFile, Crypto.CreateLegacyCandidates) + { + } + + internal MavAuthKeyStore(string keyFile, string materialFile, + Func> legacyCandidates) + { + _keyFile = keyFile ?? throw new ArgumentNullException(nameof(keyFile)); + _materialFile = materialFile ?? throw new ArgumentNullException(nameof(materialFile)); + _legacyCandidates = legacyCandidates ?? + throw new ArgumentNullException(nameof(legacyCandidates)); + } + + public MAVAuthKeys.AuthKeys Load() + { + lock (_sync) + { + DisposeCrypto(); + _loaded = false; + + if (!File.Exists(_keyFile)) + { + _crypto = File.Exists(_materialFile) + ? ReadMaterial() + : CreateAndPersistMaterial(); + _loaded = true; + return new MAVAuthKeys.AuthKeys(); + } + + Exception materialError = null; + if (File.Exists(_materialFile)) + { + Crypto persisted = null; + try + { + persisted = ReadMaterial(); + MAVAuthKeys.AuthKeys loaded = Deserialize(persisted); + _crypto = persisted; + persisted = null; + _loaded = true; + return loaded; + } + catch (Exception ex) + { + materialError = ex; + } + finally + { + persisted?.Dispose(); + } + } + + IReadOnlyList candidates = _legacyCandidates(); + Exception legacyError = null; + for (int index = 0; index < candidates.Count; index++) + { + Crypto candidate = candidates[index]; + try + { + MAVAuthKeys.AuthKeys loaded = Deserialize(candidate); + _crypto = candidate; + TryPersistMaterial(candidate); + for (int remaining = index + 1; remaining < candidates.Count; remaining++) + candidates[remaining]?.Dispose(); + candidate = null; + _loaded = true; + return loaded; + } + catch (Exception ex) + { + legacyError = ex; + } + finally + { + candidate?.Dispose(); + } + } + + throw new InvalidDataException( + "The existing MAVLink signing-key file could not be decrypted. It was left " + + "unchanged; reconnect the network adapter used when it was created or restore " + + "the matching authkeys.key file.", legacyError ?? materialError); + } + } + + public void Save(MAVAuthKeys.AuthKeys keys) + { + if (keys == null) + throw new ArgumentNullException(nameof(keys)); + + lock (_sync) + { + if (!_loaded || _crypto == null) + throw new InvalidOperationException( + "Signing keys were not loaded successfully; the existing file will not be overwritten."); + + string directory = Path.GetDirectoryName(_keyFile); + if (!string.IsNullOrEmpty(directory)) + Directory.CreateDirectory(directory); + + string temporary = _keyFile + ".tmp-" + Guid.NewGuid().ToString("N"); + try + { + var serializer = CreateSerializer(); + using (var file = new FileStream( + temporary, FileMode.CreateNew, FileAccess.Write, FileShare.None)) + using (var encrypted = new CryptoStream( + file, _crypto.algorithm.CreateEncryptor(), CryptoStreamMode.Write)) + { + serializer.WriteObject(encrypted, keys); + } + + ReplaceAtomically(temporary, _keyFile); + } + finally + { + TryDelete(temporary); + } + } + } + + private MAVAuthKeys.AuthKeys Deserialize(Crypto crypto) + { + var serializer = CreateSerializer(); + using (var file = new FileStream( + _keyFile, FileMode.Open, FileAccess.Read, FileShare.Read)) + using (var decrypted = new CryptoStream( + file, crypto.algorithm.CreateDecryptor(), CryptoStreamMode.Read)) + { + var keys = serializer.ReadObject(decrypted) as MAVAuthKeys.AuthKeys; + if (keys == null) + throw new SerializationException("The signing-key file contained no key collection."); + return keys; + } + } + + private Crypto CreateAndPersistMaterial() + { + var key = new byte[KeyLength]; + var iv = new byte[IvLength]; + using (RandomNumberGenerator random = RandomNumberGenerator.Create()) + { + random.GetBytes(key); + random.GetBytes(iv); + } + + try + { + var crypto = new Crypto(key, iv); + PersistMaterial(crypto); + return crypto; + } + finally + { + Array.Clear(key, 0, key.Length); + Array.Clear(iv, 0, iv.Length); + } + } + + private Crypto ReadMaterial() + { + byte[] contents = File.ReadAllBytes(_materialFile); + int expectedLength = MaterialMagic.Length + KeyLength + IvLength; + if (contents.Length != expectedLength) + throw new InvalidDataException("The MAVLink signing-key material file has an invalid length."); + + for (int index = 0; index < MaterialMagic.Length; index++) + { + if (contents[index] != MaterialMagic[index]) + throw new InvalidDataException("The MAVLink signing-key material file has an invalid header."); + } + + var key = new byte[KeyLength]; + var iv = new byte[IvLength]; + Buffer.BlockCopy(contents, MaterialMagic.Length, key, 0, key.Length); + Buffer.BlockCopy(contents, MaterialMagic.Length + key.Length, iv, 0, iv.Length); + return new Crypto(key, iv); + } + + private void TryPersistMaterial(Crypto crypto) + { + try + { + PersistMaterial(crypto); + } + catch + { + // The already-readable legacy file remains usable and unchanged. A later start can + // retry migration; failing the whole load here would unnecessarily hide valid keys. + } + } + + private void PersistMaterial(Crypto crypto) + { + byte[] key; + byte[] iv; + crypto.ExtractBinaryKeys(out key, out iv); + + var contents = new byte[MaterialMagic.Length + key.Length + iv.Length]; + Buffer.BlockCopy(MaterialMagic, 0, contents, 0, MaterialMagic.Length); + Buffer.BlockCopy(key, 0, contents, MaterialMagic.Length, key.Length); + Buffer.BlockCopy(iv, 0, contents, MaterialMagic.Length + key.Length, iv.Length); + + string directory = Path.GetDirectoryName(_materialFile); + if (!string.IsNullOrEmpty(directory)) + Directory.CreateDirectory(directory); + + string temporary = _materialFile + ".tmp-" + Guid.NewGuid().ToString("N"); + try + { + using (var file = new FileStream( + temporary, FileMode.CreateNew, FileAccess.Write, FileShare.None)) + { + file.Write(contents, 0, contents.Length); + file.Flush(); + } + + ReplaceAtomically(temporary, _materialFile); + } + finally + { + TryDelete(temporary); + Array.Clear(key, 0, key.Length); + Array.Clear(iv, 0, iv.Length); + Array.Clear(contents, 0, contents.Length); + } + } + + private static DataContractSerializer CreateSerializer() + { + return new DataContractSerializer(typeof(MAVAuthKeys.AuthKeys), + new[] { typeof(MAVAuthKeys.AuthKey) }); + } + + private static void ReplaceAtomically(string temporary, string destination) + { + if (File.Exists(destination)) + { + File.Replace(temporary, destination, destination + ".bak"); + return; + } + + File.Move(temporary, destination); + } + + private static void TryDelete(string path) + { + try + { + if (File.Exists(path)) + File.Delete(path); + } + catch + { + } + } + + private void DisposeCrypto() + { + _crypto?.Dispose(); + _crypto = null; + } + + public void Dispose() + { + lock (_sync) + { + DisposeCrypto(); + _loaded = false; + } + } + } +} diff --git a/ExtLibs/ArduPilot/Mavlink/MessageRateManager.cs b/ExtLibs/ArduPilot/Mavlink/MessageRateManager.cs new file mode 100644 index 0000000000..2c0dce8e00 --- /dev/null +++ b/ExtLibs/ArduPilot/Mavlink/MessageRateManager.cs @@ -0,0 +1,688 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using System.Threading; +using System.Threading.Tasks; +using log4net; + +namespace MissionPlanner.ArduPilot.Mavlink +{ + internal interface IMessageRateTransport + { + bool IsCommandChannelBusy { get; } + int Subscribe(MAVLink.MAVLINK_MSG_ID messageId, + Func handler, byte sysid, byte compid); + void Unsubscribe(int subscriptionId); + bool HasEverReceived(uint messageId, byte sysid, byte compid); + int GetLinkQualityPercent(byte sysid, byte compid); + Task SetIntervalAsync(uint messageId, byte sysid, byte compid, + int intervalMicroseconds, bool requireAcknowledgement); + Task GetIntervalAsync(uint messageId, byte sysid, byte compid); + } + + internal sealed class MavlinkMessageRateTransport : IMessageRateTransport + { + private readonly MAVLinkInterface _port; + + internal MavlinkMessageRateTransport(MAVLinkInterface port) + { + _port = port ?? throw new ArgumentNullException(nameof(port)); + } + + public bool IsCommandChannelBusy => _port.giveComport; + + public int Subscribe(MAVLink.MAVLINK_MSG_ID messageId, + Func handler, byte sysid, byte compid) + { + return _port.SubscribeToPacketType(messageId, handler, sysid, compid); + } + + public void Unsubscribe(int subscriptionId) + { + _port.UnSubscribeToPacketType(subscriptionId); + } + + public bool HasEverReceived(uint messageId, byte sysid, byte compid) + { + try + { + return _port.MAVlist[sysid, compid].packetspersecondbuild.ContainsKey(messageId); + } + catch + { + return false; + } + } + + public int GetLinkQualityPercent(byte sysid, byte compid) + { + try + { + return _port.MAVlist[sysid, compid].cs.linkqualitygcs; + } + catch + { + return 100; + } + } + + public Task SetIntervalAsync(uint messageId, byte sysid, byte compid, + int intervalMicroseconds, bool requireAcknowledgement) + { + return _port.doCommandAsync(sysid, compid, + MAVLink.MAV_CMD.SET_MESSAGE_INTERVAL, + messageId, intervalMicroseconds, + 0, 0, 0, 0, 0, requireAcknowledgement); + } + + public Task GetIntervalAsync(uint messageId, byte sysid, byte compid) + { + return _port.doCommandAsync(sysid, compid, + MAVLink.MAV_CMD.GET_MESSAGE_INTERVAL, + messageId, 0, 0, 0, 0, 0, 0, false); + } + } + + /// + /// Represents a disposable request for a minimum MAVLink message rate. + /// + public sealed class MessageRateLease : IDisposable + { + private readonly MessageRateManager _manager; + + internal readonly uint MessageId; + internal readonly byte SystemId; + internal readonly byte ComponentId; + internal readonly double Hertz; + internal readonly string Owner; + internal int Released; + + internal MessageRateLease(MessageRateManager manager, uint messageId, + byte systemId, byte componentId, double hertz, string owner) + { + _manager = manager; + MessageId = messageId; + SystemId = systemId; + ComponentId = componentId; + Hertz = hertz; + Owner = owner ?? ""; + } + + public void Dispose() + { + _manager.Release(this); + } + } + + /// + /// Coordinates per-message MAVLink streaming rates. The fastest active lease wins, + /// and releasing the final lease restores the autopilot's default rate. + /// + public sealed class MessageRateManager : IDisposable + { + private static readonly ILog log = LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private readonly IMessageRateTransport _transport; + private readonly object _lock = new object(); + private readonly TimeSpan _monitorInterval; + private readonly CancellationTokenSource _lifetime = new CancellationTokenSource(); + private readonly SemaphoreSlim _wakeWorker = new SemaphoreSlim(0, 1); + + private readonly Dictionary<(uint messageId, byte sysid, byte compid), List> _leases + = new Dictionary<(uint, byte, byte), List>(); + private readonly HashSet<(uint messageId, byte sysid, byte compid)> _unsupported + = new HashSet<(uint, byte, byte)>(); + private readonly HashSet<(uint messageId, byte sysid, byte compid)> _pendingRestores + = new HashSet<(uint, byte, byte)>(); + private readonly Dictionary<(byte sysid, byte compid), int> _intervalSubscriptions + = new Dictionary<(byte, byte), int>(); + private readonly Dictionary<(uint messageId, byte sysid, byte compid), int> _packetSubscriptions + = new Dictionary<(uint, byte, byte), int>(); + private readonly Dictionary<(uint messageId, byte sysid, byte compid), long> _packetCounts + = new Dictionary<(uint, byte, byte), long>(); + private readonly Dictionary<(uint messageId, byte sysid, byte compid), (long count, long ticks)> _snapshots + = new Dictionary<(uint, byte, byte), (long, long)>(); + + private Task _worker; + private bool _drainingRestores; + private int _disposed; + + public MessageRateManager(MAVLinkInterface port) + : this(new MavlinkMessageRateTransport(port), TimeSpan.FromSeconds(30)) + { + } + + internal MessageRateManager(IMessageRateTransport transport, TimeSpan monitorInterval) + { + _transport = transport ?? throw new ArgumentNullException(nameof(transport)); + if (monitorInterval <= TimeSpan.Zero) + throw new ArgumentOutOfRangeException(nameof(monitorInterval)); + _monitorInterval = monitorInterval; + } + + public MessageRateLease Subscribe(byte sysid, byte compid, + MAVLink.MAVLINK_MSG_ID messageId, double hertz, string owner = null) + { + ThrowIfDisposed(); + int intervalMicroseconds = HertzToIntervalMicroseconds(hertz); + uint id = (uint)messageId; + if (id > ushort.MaxValue) + throw new ArgumentOutOfRangeException(nameof(messageId), + "MESSAGE_INTERVAL only supports message IDs up to 65535."); + + var lease = new MessageRateLease(this, id, sysid, compid, hertz, owner); + if (sysid == 0 || compid == 0) + return lease; + + var key = (id, sysid, compid); + bool unsupported; + lock (_lock) + { + if (!_leases.TryGetValue(key, out List active)) + { + active = new List(); + _leases[key] = active; + } + active.Add(lease); + _pendingRestores.Remove(key); + unsupported = _unsupported.Contains(key); + + EnsureIntervalSubscriptionLocked(sysid, compid); + if (!unsupported) + EnsurePacketSubscriptionLocked(key); + intervalMicroseconds = FastestIntervalLocked(key).Value; + } + + if (!unsupported) + { + SendSetWithoutAcknowledgement(key, intervalMicroseconds); + if (!_transport.HasEverReceived(id, sysid, compid)) + SendGetWithoutAcknowledgement(key); + } + else + { + log.InfoFormat( + "RateManager: {0} subscribed to unsupported msg {1} ({2},{3}); waiting for reconnect", + owner ?? "", id, sysid, compid); + } + + EnsureWorkerStarted(); + return lease; + } + + internal void Release(MessageRateLease lease) + { + if (lease == null || Interlocked.CompareExchange(ref lease.Released, 1, 0) != 0) + return; + if (lease.SystemId == 0 || lease.ComponentId == 0 || Volatile.Read(ref _disposed) != 0) + return; + + var key = (lease.MessageId, lease.SystemId, lease.ComponentId); + int? nextInterval = null; + bool restore = false; + lock (_lock) + { + if (!_leases.TryGetValue(key, out List active)) + return; + + active.Remove(lease); + if (active.Count == 0) + { + _leases.Remove(key); + RemovePacketSubscriptionLocked(key); + if (_unsupported.Remove(key)) + { + _pendingRestores.Remove(key); + } + else + { + _pendingRestores.Add(key); + restore = true; + } + } + else if (!_unsupported.Contains(key)) + { + nextInterval = FastestIntervalLocked(key); + } + } + + if (nextInterval.HasValue) + SendSetWithoutAcknowledgement(key, nextInterval.Value); + if (restore) + SignalWorker(); + + TryRemoveIntervalSubscription(lease.SystemId, lease.ComponentId); + log.InfoFormat("RateManager: {0} released msg {1} ({2},{3}){4}", + lease.Owner, lease.MessageId, lease.SystemId, lease.ComponentId, + restore ? " -- restoring default" : ""); + } + + /// + /// Clears connection-specific observations and re-applies every active lease. + /// + public void OnConnectionOpen() + { + if (Volatile.Read(ref _disposed) != 0) + return; + + List<((uint messageId, byte sysid, byte compid) key, int interval)> active; + lock (_lock) + { + _unsupported.Clear(); + _pendingRestores.Clear(); + _snapshots.Clear(); + active = new List<((uint, byte, byte), int)>(); + foreach (var key in _leases.Keys.ToList()) + { + EnsureIntervalSubscriptionLocked(key.sysid, key.compid); + EnsurePacketSubscriptionLocked(key); + int? interval = FastestIntervalLocked(key); + if (interval.HasValue) + active.Add((key, interval.Value)); + } + } + + foreach (var request in active) + { + SendSetWithoutAcknowledgement(request.key, request.interval); + if (!_transport.HasEverReceived( + request.key.messageId, request.key.sysid, request.key.compid)) + SendGetWithoutAcknowledgement(request.key); + } + EnsureWorkerStarted(); + } + + public void Dispose() + { + if (Interlocked.CompareExchange(ref _disposed, 1, 0) != 0) + return; + + _lifetime.Cancel(); + List subscriptions; + Task worker; + lock (_lock) + { + subscriptions = _intervalSubscriptions.Values + .Concat(_packetSubscriptions.Values).ToList(); + _intervalSubscriptions.Clear(); + _packetSubscriptions.Clear(); + _packetCounts.Clear(); + _snapshots.Clear(); + _leases.Clear(); + _unsupported.Clear(); + _pendingRestores.Clear(); + worker = _worker; + } + + foreach (int subscription in subscriptions) + { + try + { + _transport.Unsubscribe(subscription); + } + catch + { + } + } + + if (worker == null || worker.IsCompleted) + { + _wakeWorker.Dispose(); + _lifetime.Dispose(); + } + else + { + worker.ContinueWith(_ => + { + _wakeWorker.Dispose(); + _lifetime.Dispose(); + }, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, + TaskScheduler.Default); + } + } + + private void EnsureWorkerStarted() + { + if (Volatile.Read(ref _disposed) != 0) + return; + lock (_lock) + { + if (_worker == null || _worker.IsCompleted) + _worker = Task.Run(RunWorkerAsync); + } + } + + private async Task RunWorkerAsync() + { + CancellationToken token = _lifetime.Token; + while (!token.IsCancellationRequested) + { + try + { + await _wakeWorker.WaitAsync(_monitorInterval, token).ConfigureAwait(false); + if (token.IsCancellationRequested) + break; + Tick(); + await ProcessPendingRestoresAsync().ConfigureAwait(false); + } + catch (OperationCanceledException) + { + break; + } + catch (Exception ex) + { + log.Error("RateManager: worker failed", ex); + } + } + } + + private void SignalWorker() + { + EnsureWorkerStarted(); + try + { + if (_wakeWorker.CurrentCount == 0) + _wakeWorker.Release(); + } + catch (ObjectDisposedException) + { + } + } + + private void Tick() + { + List<((uint messageId, byte sysid, byte compid) key, int interval)> requests; + lock (_lock) + { + requests = new List<((uint, byte, byte), int)>(); + foreach (var key in _leases.Keys.ToList()) + { + if (_unsupported.Contains(key)) + continue; + int? interval = FastestIntervalLocked(key); + if (interval.HasValue && !IsRateSatisfiedLocked(key, interval.Value)) + requests.Add((key, interval.Value)); + + if (_packetCounts.TryGetValue(key, out long count)) + _snapshots[key] = (count, Stopwatch.GetTimestamp()); + } + } + + foreach (var request in requests) + { + SendSetWithoutAcknowledgement(request.key, request.interval); + if (!_transport.HasEverReceived( + request.key.messageId, request.key.sysid, request.key.compid)) + SendGetWithoutAcknowledgement(request.key); + } + } + + private bool IsRateSatisfiedLocked( + (uint messageId, byte sysid, byte compid) key, int desiredInterval) + { + if (!_packetCounts.TryGetValue(key, out long count) || + !_snapshots.TryGetValue(key, out (long count, long ticks) snapshot)) + return false; + + double elapsed = (double)(Stopwatch.GetTimestamp() - snapshot.ticks) / + Stopwatch.Frequency; + if (elapsed < 1) + return true; + + long received = count - snapshot.count; + if (received <= 0) + return false; + + double observedHertz = received / elapsed; + int linkQuality = _transport.GetLinkQualityPercent(key.sysid, key.compid); + double quality = linkQuality > 0 ? Math.Min(1, linkQuality / 100.0) : 1; + double lossCompensation = quality > 0.5 ? 1 / quality : 2; + double estimatedHertz = observedHertz * lossCompensation; + double desiredHertz = IntervalMicrosecondsToHertz(desiredInterval); + return estimatedHertz >= desiredHertz * 0.8; + } + + private void EnsureIntervalSubscriptionLocked(byte sysid, byte compid) + { + var target = (sysid, compid); + if (_intervalSubscriptions.ContainsKey(target)) + return; + + int subscription = _transport.Subscribe( + MAVLink.MAVLINK_MSG_ID.MESSAGE_INTERVAL, + message => + { + MAVLink.mavlink_message_interval_t interval = + message.ToStructure(); + OnMessageInterval(interval.message_id, sysid, compid, interval.interval_us); + return true; + }, sysid, compid); + _intervalSubscriptions[target] = subscription; + } + + private void TryRemoveIntervalSubscription(byte sysid, byte compid) + { + int subscription; + lock (_lock) + { + if (_leases.Keys.Any(key => key.sysid == sysid && key.compid == compid) || + !_intervalSubscriptions.TryGetValue((sysid, compid), out subscription)) + return; + _intervalSubscriptions.Remove((sysid, compid)); + } + + try + { + _transport.Unsubscribe(subscription); + } + catch + { + } + } + + private void OnMessageInterval(ushort messageId, byte sysid, byte compid, + int intervalMicroseconds) + { + if (intervalMicroseconds != 0) + return; + + var key = ((uint)messageId, sysid, compid); + lock (_lock) + { + if (!_leases.ContainsKey(key)) + return; + _unsupported.Add(key); + RemovePacketSubscriptionLocked(key); + } + log.WarnFormat("RateManager: msg {0} ({1},{2}) is unsupported", messageId, sysid, compid); + } + + private void EnsurePacketSubscriptionLocked( + (uint messageId, byte sysid, byte compid) key) + { + if (_packetSubscriptions.ContainsKey(key)) + return; + + _packetCounts[key] = 0; + _snapshots[key] = (0, Stopwatch.GetTimestamp()); + int subscription = _transport.Subscribe( + (MAVLink.MAVLINK_MSG_ID)key.messageId, + _ => + { + lock (_lock) + { + if (_packetCounts.TryGetValue(key, out long count)) + _packetCounts[key] = count + 1; + } + return true; + }, key.sysid, key.compid); + _packetSubscriptions[key] = subscription; + } + + private void RemovePacketSubscriptionLocked( + (uint messageId, byte sysid, byte compid) key) + { + if (_packetSubscriptions.TryGetValue(key, out int subscription)) + { + _packetSubscriptions.Remove(key); + try + { + _transport.Unsubscribe(subscription); + } + catch + { + } + } + _packetCounts.Remove(key); + _snapshots.Remove(key); + } + + internal async Task ProcessPendingRestoresAsync() + { + lock (_lock) + { + if (_drainingRestores || _pendingRestores.Count == 0 || + Volatile.Read(ref _disposed) != 0) + return; + _drainingRestores = true; + } + + try + { + List<(uint messageId, byte sysid, byte compid)> pending; + lock (_lock) + pending = _pendingRestores.ToList(); + + foreach (var key in pending) + { + CancellationToken token = _lifetime.Token; + token.ThrowIfCancellationRequested(); + + bool shouldRestore; + lock (_lock) + { + shouldRestore = _pendingRestores.Contains(key) && + !_leases.ContainsKey(key); + } + if (!shouldRestore) + continue; + + for (int attempt = 0; + attempt < 5 && _transport.IsCommandChannelBusy; + attempt++) + await Task.Delay(200, token).ConfigureAwait(false); + if (_transport.IsCommandChannelBusy) + continue; + + try + { + bool accepted = await _transport.SetIntervalAsync( + key.messageId, key.sysid, key.compid, 0, true) + .ConfigureAwait(false); + if (accepted) + { + lock (_lock) + _pendingRestores.Remove(key); + } + } + catch (Exception ex) + { + log.WarnFormat( + "RateManager: restore failed for msg {0} ({1},{2}): {3}", + key.messageId, key.sysid, key.compid, ex.Message); + } + } + } + catch (OperationCanceledException) + { + } + finally + { + lock (_lock) + _drainingRestores = false; + } + } + + private void SendSetWithoutAcknowledgement( + (uint messageId, byte sysid, byte compid) key, int intervalMicroseconds) + { + lock (_lock) + { + if (_packetCounts.TryGetValue(key, out long count)) + _snapshots[key] = (count, Stopwatch.GetTimestamp()); + } + + try + { + ObserveFault(_transport.SetIntervalAsync( + key.messageId, key.sysid, key.compid, intervalMicroseconds, false), + "SET_MESSAGE_INTERVAL"); + } + catch (Exception ex) + { + log.Debug("RateManager: SET_MESSAGE_INTERVAL failed: " + ex.Message); + } + } + + private void SendGetWithoutAcknowledgement( + (uint messageId, byte sysid, byte compid) key) + { + try + { + ObserveFault(_transport.GetIntervalAsync( + key.messageId, key.sysid, key.compid), "GET_MESSAGE_INTERVAL"); + } + catch (Exception ex) + { + log.Debug("RateManager: GET_MESSAGE_INTERVAL failed: " + ex.Message); + } + } + + private static void ObserveFault(Task task, string operation) + { + if (task == null) + return; + task.ContinueWith(faulted => + log.Debug("RateManager: " + operation + " failed: " + + faulted.Exception?.GetBaseException().Message), + CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, + TaskScheduler.Default); + } + + private int? FastestIntervalLocked( + (uint messageId, byte sysid, byte compid) key) + { + if (!_leases.TryGetValue(key, out List active) || active.Count == 0) + return null; + return active.Min(lease => HertzToIntervalMicroseconds(lease.Hertz)); + } + + internal static int HertzToIntervalMicroseconds(double hertz) + { + if (double.IsNaN(hertz) || double.IsInfinity(hertz) || hertz <= 0) + throw new ArgumentOutOfRangeException(nameof(hertz), + "Message rate must be a finite positive value."); + + double interval = 1e6 / hertz; + if (interval <= 1) + return 1; + if (interval >= int.MaxValue) + return int.MaxValue; + return (int)Math.Round(interval, MidpointRounding.AwayFromZero); + } + + internal static double IntervalMicrosecondsToHertz(int intervalMicroseconds) + { + return intervalMicroseconds > 0 ? 1e6 / intervalMicroseconds : 0; + } + + private void ThrowIfDisposed() + { + if (Volatile.Read(ref _disposed) != 0) + throw new ObjectDisposedException(nameof(MessageRateManager)); + } + } +} diff --git a/ExtLibs/ArduPilot/MissionPlanner.ArduPilot.csproj b/ExtLibs/ArduPilot/MissionPlanner.ArduPilot.csproj index f5a50c1bde..a794156758 100644 --- a/ExtLibs/ArduPilot/MissionPlanner.ArduPilot.csproj +++ b/ExtLibs/ArduPilot/MissionPlanner.ArduPilot.csproj @@ -35,6 +35,10 @@ + + + + True diff --git a/ExtLibs/ArduPilot/PrearmFailureTracker.cs b/ExtLibs/ArduPilot/PrearmFailureTracker.cs new file mode 100644 index 0000000000..aef7d17a99 --- /dev/null +++ b/ExtLibs/ArduPilot/PrearmFailureTracker.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; + +namespace MissionPlanner.ArduPilot +{ + internal sealed class PrearmFailureTracker + { + private DateTime _lastHealthy = DateTime.MaxValue; + + internal string Update(bool healthy, bool enabled, bool present, + IReadOnlyList<(DateTime time, string message)> messages, DateTime now) + { + if (healthy || !enabled || !present) + { + _lastHealthy = now; + return null; + } + + if (_lastHealthy > now) + { + _lastHealthy = now; + return null; + } + + for (int index = messages.Count - 1; index >= 0; index--) + { + (DateTime time, string message) candidate = messages[index]; + if (candidate.time > _lastHealthy && + candidate.message?.IndexOf("prearm", StringComparison.OrdinalIgnoreCase) >= 0) + { + return candidate.message; + } + } + + return null; + } + } +} diff --git a/ExtLibs/ArduPilot/Proximity.cs b/ExtLibs/ArduPilot/Proximity.cs index c9eeab63ad..d26e9ed3d4 100644 --- a/ExtLibs/ArduPilot/Proximity.cs +++ b/ExtLibs/ArduPilot/Proximity.cs @@ -2,9 +2,8 @@ using System; using System.Collections.Generic; using System.Drawing; -using System.Linq; using System.Reflection; -using System.Text; +using System.Threading; using MissionPlanner.ArduPilot; using static MAVLink; @@ -22,6 +21,7 @@ public class Proximity : IDisposable int sub2; private byte sysid; private byte compid; + private int _disposed; public bool DataAvailable { get; set; } = false; @@ -41,12 +41,13 @@ public Proximity(MAVState mavInt, byte sysid, byte compid) ~Proximity() { - _parent?.parent?.UnSubscribeToPacketType(sub); - _parent?.parent?.UnSubscribeToPacketType(sub2); + Dispose(false); } private bool messageReceived(MAVLinkMessage arg) { + if (Volatile.Read(ref _disposed) != 0 || _parent == null) + return true; //accept any compid, but filter sysid if (arg.sysid != _parent.sysid) return true; @@ -107,13 +108,27 @@ private bool messageReceived(MAVLinkMessage arg) public void Dispose() { - if (_parent != null) - _parent.parent.UnSubscribeToPacketType(sub); + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (Interlocked.Exchange(ref _disposed, 1) != 0) + return; + + MAVState parent = _parent; + _parent = null; + if (parent?.parent == null) + return; + parent.parent.UnSubscribeToPacketType(sub); + parent.parent.UnSubscribeToPacketType(sub2); } public class directionState { - List _dists = new List(); + private readonly object _sync = new object(); + private readonly List _dists = new List(); public class data { @@ -151,30 +166,25 @@ public data(uint id, double angle, double size, double distance, DateTime receiv public void Add(uint id, MAV_SENSOR_ORIENTATION orientation, double distance, DateTime received, double age = 1) { - var existing = _dists.Where((a) => { return a.SensorId == id && a.Orientation == orientation; }); - - foreach (var item in existing.ToList()) + lock (_sync) { - _dists.Remove(item); - } - - _dists.Add(new data(id, orientation, distance, received, age)); + _dists.RemoveAll(item => + item.SensorId == id && item.Orientation == orientation); - expire(); + _dists.Add(new data(id, orientation, distance, received, age)); + ExpireLocked(); + } } public void Add(uint id, double angle, double size, double distance, DateTime received, double age = 1) { - var existing = _dists.Where((a) => { return a.SensorId == id && a.Angle == angle; }); - - foreach (var item in existing.ToList()) + lock (_sync) { - _dists.Remove(item); - } - - _dists.Add(new data(id, angle, size, distance, received, age)); + _dists.RemoveAll(item => item.SensorId == id && item.Angle == angle); - expire(); + _dists.Add(new data(id, angle, size, distance, received, age)); + ExpireLocked(); + } } /// @@ -183,16 +193,15 @@ public void Add(uint id, double angle, double size, double distance, DateTime re /// public double GetClosest() { - expire(); - - double min = double.MaxValue; - - for (int a = 0; a < _dists.Count; a++) + lock (_sync) { - min = Math.Min(min, _dists[a].Distance); - } + ExpireLocked(); + double min = double.MaxValue; + for (int a = 0; a < _dists.Count; a++) + min = Math.Min(min, _dists[a].Distance); - return min; + return min; + } } /// @@ -202,48 +211,39 @@ public double GetClosest() /// List of directions public List GetWarnings(double min_distance = 2) { - expire(); - - List list = new List(); - - for (int a = 0; a < _dists.Count; a++) + lock (_sync) { - if (_dists[a].Distance < min_distance) + ExpireLocked(); + var list = new List(); + for (int a = 0; a < _dists.Count; a++) { - list.Add(_dists[a].Orientation); + if (_dists[a].Distance < min_distance) + list.Add(_dists[a].Orientation); } + return list; } - - return list; } public List GetRaw() { - expire(); - - return _dists; + lock (_sync) + { + ExpireLocked(); + return new List(_dists); + } } - void expire() + private void ExpireLocked() { - lock (this) + for (int a = 0; a < _dists.Count; a++) { - for (int a = 0; a < _dists.Count; a++) + if (_dists[a].ExpireTime < DateTime.Now) { - var expireat = _dists[a].ExpireTime; - - if (expireat < DateTime.Now) - { - // remove it - _dists.RemoveAt(a); - // make sure we dont skip an element - a--; - // move on - continue; - } + _dists.RemoveAt(a); + a--; } } } } } -} \ No newline at end of file +} diff --git a/ExtLibs/ArduPilot/mav_mission.cs b/ExtLibs/ArduPilot/mav_mission.cs index a13c6e0ccf..e7c9bbc32d 100644 --- a/ExtLibs/ArduPilot/mav_mission.cs +++ b/ExtLibs/ArduPilot/mav_mission.cs @@ -148,9 +148,7 @@ public static async Task upload(MAVLinkInterface port, byte sysid, byte compid, } } - port.setWPACK(sysid, compid, type); - - } + } catch (Exception ex) { log.Error(ex); @@ -245,9 +243,7 @@ await port.setWPPartialUpdateAsync(sysid, compid, start, (ushort) (start + comma } } - port.setWPACK(sysid, compid, type); - - } + } catch (Exception ex) { log.Error(ex); @@ -255,4 +251,4 @@ await port.setWPPartialUpdateAsync(sysid, compid, start, (ushort) (start + comma } } } -} \ No newline at end of file +} diff --git a/ExtLibs/Comms/BoundedPortNameEnumerator.cs b/ExtLibs/Comms/BoundedPortNameEnumerator.cs new file mode 100644 index 0000000000..034e89e627 --- /dev/null +++ b/ExtLibs/Comms/BoundedPortNameEnumerator.cs @@ -0,0 +1,128 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace MissionPlanner.Comms +{ + /// + /// Runs the platform serial-port probe on one dedicated background thread. A platform driver + /// can block forever, so timed-out callers stop waiting and reuse the same outstanding probe + /// instead of consuming more ThreadPool workers or creating an unbounded number of threads. + /// + internal sealed class BoundedPortNameEnumerator + { + private readonly Func _provider; + private readonly object _sync = new object(); + private Task _attempt; + private bool _timeoutObserved; + private string[] _lastSuccessful = Array.Empty(); + + internal BoundedPortNameEnumerator(Func provider) + { + _provider = provider ?? throw new ArgumentNullException(nameof(provider)); + } + + internal PortNameEnumerationResult TryEnumerate(int timeoutMilliseconds) + { + if (timeoutMilliseconds <= 0) + throw new ArgumentOutOfRangeException(nameof(timeoutMilliseconds)); + + Task attempt; + lock (_sync) + { + if (_attempt != null && !_attempt.IsCompleted && _timeoutObserved) + { + return PortNameEnumerationResult.Timeout(_lastSuccessful); + } + + if (_attempt == null) + { + _timeoutObserved = false; + _attempt = Task.Factory.StartNew( + _provider, + CancellationToken.None, + TaskCreationOptions.LongRunning, + TaskScheduler.Default); + } + + attempt = _attempt; + } + + bool completed; + try + { + completed = attempt.Wait(timeoutMilliseconds); + } + catch (AggregateException) + { + // The provider exception is unwrapped below so callers get the original failure. + completed = true; + } + + if (!completed) + { + lock (_sync) + { + if (ReferenceEquals(_attempt, attempt)) + _timeoutObserved = true; + return PortNameEnumerationResult.Timeout(_lastSuccessful); + } + } + + try + { + string[] ports = attempt.GetAwaiter().GetResult() ?? Array.Empty(); + string[] snapshot = (string[])ports.Clone(); + lock (_sync) + { + if (ReferenceEquals(_attempt, attempt)) + { + _lastSuccessful = snapshot; + _attempt = null; + _timeoutObserved = false; + } + } + return PortNameEnumerationResult.Success(snapshot); + } + catch (Exception ex) + { + lock (_sync) + { + string[] fallback = (string[])_lastSuccessful.Clone(); + if (ReferenceEquals(_attempt, attempt)) + { + _attempt = null; + _timeoutObserved = false; + } + return PortNameEnumerationResult.Failure(ex, fallback); + } + } + } + } + + internal sealed class PortNameEnumerationResult + { + private PortNameEnumerationResult( + bool succeeded, bool timedOut, string[] ports, Exception error) + { + Succeeded = succeeded; + TimedOut = timedOut; + Ports = ports ?? Array.Empty(); + Error = error; + } + + internal bool Succeeded { get; } + internal bool TimedOut { get; } + internal string[] Ports { get; } + internal Exception Error { get; } + + internal static PortNameEnumerationResult Success(string[] ports) => + new PortNameEnumerationResult(true, false, ports, null); + + internal static PortNameEnumerationResult Timeout(string[] fallback) => + new PortNameEnumerationResult(false, true, (string[])fallback.Clone(), null); + + internal static PortNameEnumerationResult Failure(Exception error, string[] fallback) => + new PortNameEnumerationResult(false, false, (string[])fallback.Clone(), error); + } +} diff --git a/ExtLibs/Comms/CommsSerialPort.cs b/ExtLibs/Comms/CommsSerialPort.cs index 06d8df8481..e59a09eb8b 100644 --- a/ExtLibs/Comms/CommsSerialPort.cs +++ b/ExtLibs/Comms/CommsSerialPort.cs @@ -7,6 +7,7 @@ using System.Text; using System.Threading; using log4net; +using Microsoft.Win32; using Microsoft.Win32.SafeHandles; namespace MissionPlanner.Comms @@ -206,6 +207,13 @@ public void toggleDTR() private static string portnamenice = ""; + private const int SystemPortEnumerationTimeoutMs = 2000; + private const int RegistryPortEnumerationTimeoutMs = 500; + private static readonly BoundedPortNameEnumerator systemPortEnumerator = + new BoundedPortNameEnumerator(System.IO.Ports.SerialPort.GetPortNames); + private static readonly BoundedPortNameEnumerator registryPortEnumerator = + new BoundedPortNameEnumerator(GetWindowsRegistryPortNames); + public static string[] GetPortNames() { // prevent hammering @@ -215,9 +223,6 @@ public static string[] GetPortNames() if (Directory.Exists("/dev/")) { - // cleanup now - GC.Collect(); - // mono is failing in here on linux "too many open files" try { if (Directory.Exists("/dev/serial/by-id/")) @@ -280,7 +285,7 @@ public static string[] GetPortNames() try { - ports = System.IO.Ports.SerialPort.GetPortNames(); + ports = GetSystemPortNames(); // any exceptions will still result in a list ports = ports.Select(p => p?.TrimEnd()).ToArray(); ports = ports.Select(FixBlueToothPortNameBug).ToArray(); @@ -305,8 +310,58 @@ public static string[] GetPortNames() } } - return allPorts.Distinct().ToArray(); + return allPorts + .Where(port => !string.IsNullOrWhiteSpace(port)) + .Distinct(StringComparer.OrdinalIgnoreCase) + .ToArray(); + } + } + + private static string[] GetSystemPortNames() + { + PortNameEnumerationResult system = + systemPortEnumerator.TryEnumerate(SystemPortEnumerationTimeoutMs); + if (system.Succeeded) + return system.Ports; + + if (system.TimedOut) + log.Warn($"System serial-port enumeration timed out after {SystemPortEnumerationTimeoutMs} ms."); + else if (system.Error != null) + log.Error("System serial-port enumeration failed.", system.Error); + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + PortNameEnumerationResult registry = + registryPortEnumerator.TryEnumerate(RegistryPortEnumerationTimeoutMs); + if (registry.Succeeded && registry.Ports.Length != 0) + return registry.Ports; + if (registry.TimedOut) + log.Warn($"Windows registry serial-port enumeration timed out after {RegistryPortEnumerationTimeoutMs} ms."); + else if (registry.Error != null) + log.Error("Windows registry serial-port enumeration failed.", registry.Error); + } + + // A failed refresh must not make an already known removable device disappear. + return system.Ports; + } + + private static string[] GetWindowsRegistryPortNames() + { + var ports = new List(); + using (RegistryKey subkey = Registry.LocalMachine.OpenSubKey( + @"HARDWARE\DEVICEMAP\SERIALCOMM")) + { + if (subkey == null) + return ports.ToArray(); + + foreach (string valueName in subkey.GetValueNames()) + { + string port = subkey.GetValue(valueName)?.ToString(); + if (!string.IsNullOrWhiteSpace(port)) + ports.Add(port); + } } + return ports.ToArray(); } public static Func> GetCustomPorts; diff --git a/ExtLibs/Comms/MissionPlanner.Comms.csproj b/ExtLibs/Comms/MissionPlanner.Comms.csproj index 41e61b30f8..417e67a884 100644 --- a/ExtLibs/Comms/MissionPlanner.Comms.csproj +++ b/ExtLibs/Comms/MissionPlanner.Comms.csproj @@ -51,6 +51,7 @@ + diff --git a/ExtLibs/Mavlink/Mavlink.cs b/ExtLibs/Mavlink/Mavlink.cs index fb2d326c49..3b6028230c 100644 --- a/ExtLibs/Mavlink/Mavlink.cs +++ b/ExtLibs/Mavlink/Mavlink.cs @@ -6012,12 +6012,21 @@ public enum MAG_CAL_STATUS: byte /// | [Description("")] MAG_CAL_FAILED=5, - /// | - [Description("")] - MAG_CAL_BAD_ORIENTATION=6, - /// | - [Description("")] - MAG_CAL_BAD_RADIUS=7, + /// Compass calibration failed: the vehicle orientation is outside the required tolerance. | + [Description("Compass calibration failed: the vehicle orientation is outside the required tolerance.")] + MAG_CAL_FAILED_ORIENTATION=6, + /// Compass calibration failed: the radius of the fitted sphere is unrealistically small or large. | + [Description("Compass calibration failed: the radius of the fitted sphere is unrealistically small or large.")] + MAG_CAL_FAILED_RADIUS=7, + /// Compass calibration failed: offset magnitude too large. | + [Description("Compass calibration failed: offset magnitude too large.")] + MAG_CAL_FAILED_OFFSETS=8, + /// Compass calibration failed: diagonal or off-diagonal scaling values out of valid range. | + [Description("Compass calibration failed: diagonal or off-diagonal scaling values out of valid range.")] + MAG_CAL_FAILED_DIAG_SCALING=9, + /// Compass calibration failed: fitness (RMS residual) exceeds tolerance. | + [Description("Compass calibration failed: fitness (RMS residual) exceeds tolerance.")] + MAG_CAL_FAILED_RESIDUALS_HIGH=10, }; diff --git a/ExtLibs/Mavlink/message_definitions/common.xml b/ExtLibs/Mavlink/message_definitions/common.xml index 856160b534..059c6ef448 100644 --- a/ExtLibs/Mavlink/message_definitions/common.xml +++ b/ExtLibs/Mavlink/message_definitions/common.xml @@ -4142,8 +4142,21 @@ - - + + Compass calibration failed: the vehicle orientation is outside the required tolerance. + + + Compass calibration failed: the radius of the fitted sphere is unrealistically small or large. + + + Compass calibration failed: offset magnitude too large. + + + Compass calibration failed: diagonal or off-diagonal scaling values out of valid range. + + + Compass calibration failed: fitness (RMS residual) exceeds tolerance. + diff --git a/ExtLibs/MetaDataExtractorCSharp240d/App.ico b/ExtLibs/MetaDataExtractorCSharp240d/App.ico deleted file mode 100644 index a40ce43789..0000000000 Binary files a/ExtLibs/MetaDataExtractorCSharp240d/App.ico and /dev/null differ diff --git a/ExtLibs/MetaDataExtractorCSharp240d/MetaDataExtractor.csproj b/ExtLibs/MetaDataExtractorCSharp240d/MetaDataExtractor.csproj deleted file mode 100644 index a2ed2f9c69..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/MetaDataExtractor.csproj +++ /dev/null @@ -1,68 +0,0 @@ - - - - netstandard2.0 - library - - - - portable - true - - - - portable - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - - \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/MetadataExtractor.dtd b/ExtLibs/MetaDataExtractorCSharp240d/MetadataExtractor.dtd deleted file mode 100644 index e6f045f93f..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/MetadataExtractor.dtd +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/ExtLibs/MetaDataExtractorCSharp240d/MetadataExtractorNew.dtd b/ExtLibs/MetaDataExtractorCSharp240d/MetadataExtractorNew.dtd deleted file mode 100644 index 0efdaa410b..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/MetadataExtractorNew.dtd +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ExtLibs/MetaDataExtractorCSharp240d/Properties/app.manifest b/ExtLibs/MetaDataExtractorCSharp240d/Properties/app.manifest deleted file mode 100644 index 42ff09e5ea..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/Properties/app.manifest +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/Run.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/Run.cs deleted file mode 100644 index 397bc46983..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/Run.cs +++ /dev/null @@ -1,274 +0,0 @@ -using System; -using System.Text; -using System.IO; -using System.Resources; -using System.Reflection; -using System.Collections; -using System.Collections.Generic; -using System.Globalization; -using System.Diagnostics; - -using com.drew.lang; -using com.drew.metadata; -using com.drew.metadata.exif; -using com.drew.imaging.jpg; -using com.drew.imaging.tiff; - -using com.utils; -using com.utils.bundle; -using com.utils.xml; - -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com -{ - public sealed class Run - { - private static readonly string AS_XML = "asXml"; - private static readonly string AS_XML2 = "asXml2"; - private static readonly string NO_UNKNOWN = "noUnknown"; - private static readonly string DO_SUB = "doSub"; - - private static byte asXml = 0; - private static bool noUnknown = false; - private static bool doSub = false; - - /// - /// Search for the asXml parameter in the given args. - /// - /// the given args - private static void FindAsXml(string[] someArgs) - { - for (int i = 0; i < someArgs.Length; i++) - { - if (AS_XML2.Equals(someArgs[i], StringComparison.OrdinalIgnoreCase)) - { - Run.asXml = (byte)2; - break; - } - - if (AS_XML.Equals(someArgs[i], StringComparison.OrdinalIgnoreCase)) - { - Run.asXml = (byte)1; - break; - } - } - } - - /// - /// Search for the noUnknown parameter in the given args. - /// - /// the given args - private static void FindNoUnknown(string[] someArgs) - { - for (int i = 0; i < someArgs.Length; i++) - { - if (NO_UNKNOWN.Equals(someArgs[i], StringComparison.OrdinalIgnoreCase)) - { - Run.noUnknown = true; - break; - } - } - } - - /// - /// Search for the doSub parameter in the given args. - /// - /// the given args - private static void FindDoSub(string[] someArgs) - { - for (int i = 0; i < someArgs.Length; i++) - { - if (DO_SUB.Equals(someArgs[i], StringComparison.OrdinalIgnoreCase)) - { - Run.doSub = true; - break; - } - } - } - - /// - /// Search for file names in the given args. - /// - /// the given args - /// a file name list - private static List FindFileNames(string[] someArgs) - { - List lcResu = new List(someArgs.Length); - for (int i = 0; i < someArgs.Length; i++) - { - if (AS_XML.Equals(someArgs[i], StringComparison.OrdinalIgnoreCase) || - NO_UNKNOWN.Equals(someArgs[i], StringComparison.OrdinalIgnoreCase) || - DO_SUB.Equals(someArgs[i], StringComparison.OrdinalIgnoreCase)) - { - continue; - } - lcResu.AddRange(Utils.SearchAllFileIn(someArgs[i], Run.doSub, "*.jpg")); - lcResu.AddRange(Utils.SearchAllFileIn(someArgs[i], Run.doSub, "*.raw")); - lcResu.AddRange(Utils.SearchAllFileIn(someArgs[i], Run.doSub, "*.cr2")); - lcResu.AddRange(Utils.SearchAllFileIn(someArgs[i], Run.doSub, "*.crw")); - } - return lcResu; - } - - - /// - /// The example. - /// - /// Arguments - [STAThread] - public static void Main(string[] someArgs) - { - - string aFileName = @"C:\Users\hog\Downloads\IMG_6528.JPG"; - - Metadata lcMetadata = null; - try - { - FileInfo lcImgFile = new FileInfo(aFileName); - // Loading all meta data - lcMetadata = JpegMetadataReader.ReadMetadata(lcImgFile); - } - catch (JpegProcessingException e) - { - Console.Error.WriteLine(e.Message); - return; - } - - foreach(AbstractDirectory lcDirectory in lcMetadata) - { - - if (lcDirectory.ContainsTag(0x9003)) - { - Console.WriteLine("does "+ lcDirectory.GetTagName(0x9003) +" " + lcDirectory.GetDate(0x9003) ); - } - - } - Console.ReadLine(); - - if (someArgs.Length == 0) - { - Console.Error.WriteLine("Use: MetaDataExtractor [FilePaths|DirectoryPaths] [noUnknown|asXml|asXml2|doSub]"); - Console.Error.WriteLine(" - noUnknown: will hide unknown metadata tag"); - Console.Error.WriteLine(" - asXml : will generate an XML stream"); - Console.Error.WriteLine(" - asXml2 : will generate an XML stream with more information than asXml"); - Console.Error.WriteLine(" - doSub : will search subdirectories for *.jpg, *.raw, *.cr2, *.crw"); - Console.Error.WriteLine("Examples:"); - Console.Error.WriteLine(" - Will show you MyImage.jpg info as text:"); - Console.Error.WriteLine(" MetaDataExtractor c:\\MyImage.jpg"); - Console.Error.WriteLine(" or "); - Console.Error.WriteLine(" - Will show you all *.jpg|*.raw|*.cr2|*.crw in c:\\ and img1.jpg and img2.jpg info as text:"); - Console.Error.WriteLine(" MetaDataExtractor c:\\ d:\\img1.jpg e:\\img2.jpg"); - Console.Error.WriteLine(" - Will show you all *.jpg|*.raw|*.cr2|*.crw in c:\\ as text but with no unkown tags:"); - Console.Error.WriteLine(" MetaDataExtractor c:\\ noUnknown"); - Console.Error.WriteLine(" - Will show you all *.jpg|*.raw|*.cr2|*.crw in c:\\ as XML:"); - Console.Error.WriteLine(" MetaDataExtractor c:\\ asXml"); - Console.Error.WriteLine(" - Will show you all *.jpg|*.raw|*.cr2|*.crw in c:\\ as XML2 but with no unkown tags:"); - Console.Error.WriteLine(" MetaDataExtractor c:\\ noUnknown asXml2"); - Console.Error.WriteLine(" - Will show you all *.jpg|*.raw|*.cr2|*.crw in c:\\Temp\\ and all its subdirectories as XML but with no unkown tags:"); - Console.Error.WriteLine(" MetaDataExtractor c:\\Temp noUnknown asXml doSub"); - Console.Error.WriteLine(" - Will put in a file called sample.xml all c:\\Temp\\ *.jpg|*.raw|*.cr2|*.crw and all its subdirectories as XML but with no unkown tags:"); - Console.Error.WriteLine(" MetaDataExtractor c:\\Temp noUnknown asXml doSub > sample.xml"); - Console.Error.WriteLine("Cautions:"); - Console.Error.WriteLine(" + Pointing on c:\\ with doSub option is a very bad idea ;-)"); - Console.ReadLine(); - } - else - { - Run.FindAsXml(someArgs); - Run.FindNoUnknown(someArgs); - Run.FindDoSub(someArgs); - - StringBuilder lcGlobalBuff = new StringBuilder(1024); - - IOutPutTextStreamHandler lcXmlHandler = null; - - string dtdFile = null; - if (Run.asXml == (byte)1) - { - lcXmlHandler = new XmlOutPutStreamHandler(); - dtdFile = "MetadataExtractor.dtd"; - } - else if (Run.asXml == (byte)2) - { - lcXmlHandler = new XmlNewOutPutStreamHandler(); - dtdFile = "MetadataExtractorNew.dtd"; - } - else - { - lcXmlHandler = new TxtOutPutStreamHandler(); - } - lcXmlHandler.DoUnknown = !Run.noUnknown; - - List lcFileNameLst = Run.FindFileNames(someArgs); - // Args for OutPutTextStream objects - - // Indicate your Xsl here - string lcXslFileName = null; // For example: ="exif.xslt"; - // Indicate if you want to use CDDATA in your XML stream - string useCDDATA = "false"; - string[] lcOutputParams = new string[] { "ISO-8859-1", lcXslFileName, lcFileNameLst.Count.ToString(), dtdFile, useCDDATA }; - - lcXmlHandler.StartTextStream(lcGlobalBuff, lcOutputParams); - foreach(string lcFileName in lcFileNameLst) - { - StringBuilder lcBuff = new StringBuilder(2048); - //Metadata lcMetadata = null; - try - { - FileInfo lcImgFileInfo = new FileInfo(lcFileName); - if (lcFileName.ToLower().EndsWith(".raw") || - lcFileName.ToLower().EndsWith(".cr2") || - lcFileName.ToLower().EndsWith(".crw")) - { - lcMetadata = TiffMetadataReader.ReadMetadata(lcImgFileInfo); - } - else - { - lcMetadata = JpegMetadataReader.ReadMetadata(lcImgFileInfo); - } - lcXmlHandler.Metadata = lcMetadata; - } - catch (JpegProcessingException e) - { - Console.Error.WriteLine("Could note analyse the file '" + lcFileName + "' error message is:" + e.Message); - break; - } - - if (Run.asXml != (byte)0) - { - // First open file name tag - lcBuff.Append("").AppendLine(); - // Then create all directory tag - lcBuff.Append(lcXmlHandler.AsText()); - // Then close file tag - lcBuff.Append("").AppendLine().AppendLine(); - } - else - { - lcBuff.Append("-> "); - lcXmlHandler.Normalize(lcBuff, lcFileName, false); - lcBuff.Append(" <-").AppendLine(); - // Then create all directory tag - lcBuff.Append(lcXmlHandler.AsText()).AppendLine(); - } - lcMetadata = null; - // Adds result for this file to big buffer - lcGlobalBuff.Append(lcBuff); - lcGlobalBuff.AppendLine(); - } - lcXmlHandler.EndTextStream(lcGlobalBuff, lcOutputParams); - - Console.Out.WriteLine(lcGlobalBuff.ToString()); - } - - // Uncomment if you are running under VisualStudio - Console.In.ReadLine(); - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/SimpleRun.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/SimpleRun.cs deleted file mode 100644 index 3c9deb8fd0..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/SimpleRun.cs +++ /dev/null @@ -1,210 +0,0 @@ -using System; -using System.Text; -using System.IO; -using System.Resources; -using System.Reflection; -using System.Collections; -using System.Collections.Generic; - -using com.drew.metadata; -using com.drew.metadata.iptc; -using com.drew.imaging.jpg; - -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com -{ - /// - /// This class is a simple example of how to use the classes inside this project. - /// - public sealed class SimpleRun - { - /// - /// Shows all metadata and all tag for one file. - /// - /// the image file name (ex: c:/temp/a.jpg) - /// The information about the image as a string - public static String ShowOneFileAllMetaDataAllTag(string aFileName) - { - Metadata lcMetadata = null; - try - { - FileInfo lcImgFile = new FileInfo(aFileName); - // Loading all meta data - lcMetadata = JpegMetadataReader.ReadMetadata(lcImgFile); - } - catch (JpegProcessingException e) - { - Console.Error.WriteLine(e.Message); - return "Error"; - } - - // Now try to print them - StringBuilder lcBuff = new StringBuilder(1024); - lcBuff.Append("---> ").Append(aFileName).Append(" <---").AppendLine(); - // We want all directory, so we iterate on each - foreach(AbstractDirectory lcDirectory in lcMetadata) - { - // We look for potential error - if (lcDirectory.HasError) - { - Console.Error.WriteLine("Some errors were found, activate trace using /d:TRACE option with the compiler"); - } - lcBuff.Append("---+ ").Append(lcDirectory.GetName()).AppendLine(); - // Then we want all tags, so we iterate on the current directory - foreach(Tag lcTag in lcDirectory) { - string lcTagDescription = null; - try - { - lcTagDescription = lcTag.GetDescription(); - } - catch (MetadataException e) - { - Console.Error.WriteLine(e.Message); - } - string lcTagName = lcTag.GetTagName(); - lcBuff.Append(lcTagName).Append('=').Append(lcTagDescription).AppendLine(); - - lcTagDescription = null; - lcTagName = null; - } - } - lcMetadata = null; - - return lcBuff.ToString(); - } - - /// - /// Shows only IPTC directory and all of its tag for one file. - /// - /// the image file name (ex: c:/temp/a.jpg) - /// The information about IPTC for this image as a string - public static String ShowOneFileOnlyIptcAllTag(string aFileName) - { - Metadata lcMetadata = null; - try - { - FileInfo lcImgFile = new FileInfo(aFileName); - // Loading all meta data - lcMetadata = JpegMetadataReader.ReadMetadata(lcImgFile); - } - catch (JpegProcessingException e) - { - Console.Error.WriteLine(e.Message); - return "Error"; - } - - // Now try to print them - StringBuilder lcBuff = new StringBuilder(1024); - lcBuff.Append("---> ").Append(aFileName).Append(" <---").AppendLine(); - // We want anly IPCT directory - IptcDirectory lcIptDirectory = (IptcDirectory)lcMetadata.GetDirectory("com.drew.metadata.iptc.IptcDirectory"); - if (lcIptDirectory == null) - { - lcBuff.Append("No Iptc for this image.!").AppendLine(); - return lcBuff.ToString(); - } - - // We look for potential error - if (lcIptDirectory.HasError) - { - Console.Error.WriteLine("Some errors were found, activate trace using /d:TRACE option with the compiler"); - } - - // Then we want all tags, so we iterate on the Iptc directory - foreach(Tag lcTag in lcIptDirectory) { - string lcTagDescription = null; - try - { - lcTagDescription = lcTag.GetDescription(); - } - catch (MetadataException e) - { - Console.Error.WriteLine(e.Message); - } - string lcTagName = lcTag.GetTagName(); - lcBuff.Append(lcTagName).Append('=').Append(lcTagDescription).AppendLine(); - - lcTagDescription = null; - lcTagName = null; - } - - return lcBuff.ToString(); - } - - /// - /// Shows only IPTC directory and only the TAG_HEADLINE value for one file. - /// - /// the image file name (ex: c:/temp/a.jpg) - /// The information about IPTC for this image but only the TAG_HEADLINE tag as a string - public static string ShowOneFileOnlyIptcOnlyTagTAG_HEADLINE(string aFileName) - { - Metadata lcMetadata = null; - try - { - FileInfo lcImgFile = new FileInfo(aFileName); - // Loading all meta data - lcMetadata = JpegMetadataReader.ReadMetadata(lcImgFile); - } - catch (JpegProcessingException e) - { - Console.Error.WriteLine(e.Message); - return "Error"; - } - - // Now try to print them - StringBuilder lcBuff = new StringBuilder(1024); - lcBuff.Append("---> ").Append(aFileName).Append(" <---").AppendLine(); - // We want anly IPCT directory - IptcDirectory lcIptDirectory = (IptcDirectory)lcMetadata.GetDirectory("com.drew.metadata.iptc.IptcDirectory"); - if (lcIptDirectory == null) - { - lcBuff.Append("No Iptc for this image.!").AppendLine(); - return lcBuff.ToString(); - } - - // We look for potential error - if (lcIptDirectory.HasError) - { - Console.Error.WriteLine("Some errors were found, activate trace using /d:TRACE option with the compiler"); - } - - // Then we want only the TAG_HEADLINE tag - if (!lcIptDirectory.ContainsTag(IptcDirectory.TAG_HEADLINE)) - { - lcBuff.Append("No TAG_HEADLINE for this image.!").AppendLine(); - return lcBuff.ToString(); - } - string lcTagDescription = null; - try - { - lcTagDescription = lcIptDirectory.GetDescription(IptcDirectory.TAG_HEADLINE); - } - catch (MetadataException e) - { - Console.Error.WriteLine(e.Message); - } - string lcTagName = lcIptDirectory.GetTagName(IptcDirectory.TAG_HEADLINE); - lcBuff.Append(lcTagName).Append('=').Append(lcTagDescription).AppendLine(); - - return lcBuff.ToString(); - } - - /* - [STAThread] - public static void Main(string[] someArgs) - { - string lcFileName = "c:/temp/a.jpg"; - Console.WriteLine(ShowOneFileAllMetaDataAllTag(lcFileName)); - Console.ReadLine(); - Console.WriteLine(ShowOneFileOnlyIptcAllTag(lcFileName)); - Console.ReadLine(); - Console.WriteLine(ShowOneFileOnlyIptcOnlyTagTAG_HEADLINE(lcFileName)); - Console.ReadLine(); - } - */ - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/codec/jpeg/JPEGDecodeParam.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/codec/jpeg/JPEGDecodeParam.cs deleted file mode 100644 index 697817c3c1..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/codec/jpeg/JPEGDecodeParam.cs +++ /dev/null @@ -1,434 +0,0 @@ -using System; - -/// ********************************************************************** -/// ********************************************************************** -/// ********************************************************************** -/// *** COPYRIGHT (c) 1997-1998 Eastman Kodak Company. *** -/// *** As an unpublished work pursuant to Title 17 of the United *** -/// *** States Code. All rights reserved. *** -/// ********************************************************************** -/// ********************************************************************** -/// ********************************************************************** - -namespace com.codec.jpeg -{ - /// - /// JPEGDecodeParam encapsulates tables and options necessary to - /// control decoding JPEG datastreams. Parameters are either set explicitly - /// by the application for encoding, or read from the JPEG lcHeader for - /// decoding. In the case of decoding abbreviated data streams the - /// application may need to set some/all of the values it'str self. - /// - /// When working with BufferedImages, the codec will attempt to - /// generate an appropriate ColorModel for the JPEG COLOR_ID. This is - /// not always possible (example mappings are listed below) . In cases - /// where unsupported conversions are required, or unknown encoded - /// COLOR_ID'str are in use, the user must request the data as a Raster - /// and perform the transformations themselves. When decoding into a - /// raster no ColorSpace - /// adjustments are made. - /// - /// Note: The color ids described herein are simply enumerated values - /// that influence data processing by the JPEG codec. JPEG compression - /// is by definition color blind. These values are used as hints when - /// decompressing JPEG data. Of particular interest is the default - /// conversion from YCbCr to sRGB when decoding buffered Images. - /// - /// Note: because JPEG is mostly color-blind color fidelity can not be - /// garunteed. This will hopefully be rectified in the near future by - /// the wide spread inclusion of ICC-profiles in the JPEG data stream - /// (as a special marker). - /// - /// The following is an example of the conversions that take place. - /// This is only a guide to the types of conversions that are allowed. - /// This list is likely to change in the future so it is - /// strongly recommended that you check for thrown - /// ImageFormatExceptions and check the actual ColorModel associated - /// with the BufferedImage returned rather than make assumtions. - /// - /// DECODING: - /// - /// JPEG (Encoded) Color ID BufferedImage ColorSpace - /// ======================= ======================== - /// COLOR_ID_UNKNOWN ** Invalid ** - /// COLOR_ID_GRAY CS_GRAY - /// COLOR_ID_RGB CS_sRGB - /// COLOR_ID_YCbCr CS_sRGB - /// COLOR_ID_CMYK ** Invalid ** - /// COLOR_ID_PYCC CS_PYCC - /// COLOR_ID_RGBA CS_sRGB (w/ alpha) - /// COLOR_ID_YCbCrA CS_sRGB (w/ alpha) - /// COLOR_ID_RGBA_INVERTED ** Invalid ** - /// COLOR_ID_YCbCrA_INVERTED ** Invalid ** - /// COLOR_ID_PYCCA CS_PYCC (w/ alpha) - /// COLOR_ID_YCCK ** Invalid ** - /// - /// If the user needs better control over conversion, the user must - /// request the data as a Raster and handle the conversion of the image - /// data themselves. - /// - /// When decoding JFIF files the encoded COLOR_ID will always be one - /// of: COLOR_ID_UNKNOWN, COLOR_ID_GRAY, COLOR_ID_RGB, COLOR_ID_YCbCr, - /// COLOR_ID_CMYK, or COLOR_ID_YCCK - /// - /// Note that the classes in the com.sun.image.codec.jpeg package are not - /// part of the core Java APIs. They are a part of Sun'str JDK and JRE - /// distributions. Although other licensees may choose to distribute these - /// classes, developers cannot depend on their availability in non-Sun - /// implementations. We expect that equivalent functionality will eventually - /// be available in a core API or standard extension. - /// - public abstract class JPEGDecodeParam - { - /// - /// Unknown or Undefined Color ID - /// - public readonly static int COLOR_ID_UNKNOWN = 0; - - /// - /// Monochrome - /// - public readonly static int COLOR_ID_GRAY = 1; - - /// - /// Red, Green, and Blue - /// - public readonly static int COLOR_ID_RGB = 2; - - /// - /// YCbCr - /// - public readonly static int COLOR_ID_YCbCr = 3; - - /// - /// CMYK - /// - public readonly static int COLOR_ID_CMYK = 4; - - /// - /// PhotoYCC - /// - public readonly static int COLOR_ID_PYCC = 5; - - /// - /// RGB-Alpha - /// - public readonly static int COLOR_ID_RGBA = 6; - - /// - /// YCbCr-Alpha - /// - public readonly static int COLOR_ID_YCbCrA = 7; - - /// - /// RGB-Alpha with R, G, and B inverted. - /// - public readonly static int COLOR_ID_RGBA_INVERTED = 8; - - /// - /// YCbCr-Alpha with Y, Cb, and Cr inverted. - /// - public readonly static int COLOR_ID_YCbCrA_INVERTED = 9; - - /// - /// PhotoYCC-Alpha - /// - public readonly static int COLOR_ID_PYCCA = 10; - - /// - /// YCbCrK - /// - public readonly static int COLOR_ID_YCCK = 11; - - /// - /// Number of color ids defined. - /// - public readonly static int NUM_COLOR_ID = 12; - - /// - /// Number of allowed Huffman and Quantization Tables - /// - public readonly static int NUM_TABLES = 4; - - /// - /// The X and Y units simply indicate the aspect ratio of the pixels. - /// - public readonly static int DENSITY_UNIT_ASPECT_RATIO = 0; - - /// - /// Pixel density is in pixels per inch. - /// - public readonly static int DENSITY_UNIT_DOTS_INCH = 1; - - /// - /// Pixel density is in pixels per centemeter. - /// - public readonly static int DENSITY_UNIT_DOTS_CM = 2; - - /// - /// The max known value for DENSITY_UNIT - /// - public readonly static int NUM_DENSITY_UNIT = 3; - - /// - /// APP0 marker - JFIF info - /// - public readonly static int APP0_MARKER = 0xE0; - - /// - /// APP1 marker - /// - public readonly static int APP1_MARKER = 0xE1; - - /// - /// APP2 marker - /// - public readonly static int APP2_MARKER = 0xE2; - - /// - /// APP3 marker - /// - public readonly static int APP3_MARKER = 0xE3; - - /// - /// APP4 marker - /// - public readonly static int APP4_MARKER = 0xE4; - - /// - /// APP5 marker - /// - public readonly static int APP5_MARKER = 0xE5; - - /// - /// APP6 marker - /// - public readonly static int APP6_MARKER = 0xE6; - - /// - /// APP7 marker - /// - public readonly static int APP7_MARKER = 0xE7; - - /// - /// APP8 marker - /// - public readonly static int APP8_MARKER = 0xE8; - - /// - /// APP9 marker - /// - public readonly static int APP9_MARKER = 0xE9; - - /// - /// APPA marker - /// - public readonly static int APPA_MARKER = 0xEA; - - /// - /// APPB marker - /// - public readonly static int APPB_MARKER = 0xEB; - - /// - /// APPC marker - /// - public readonly static int APPC_MARKER = 0xEC; - - /// - /// APPD marker - /// - public readonly static int APPD_MARKER = 0xED; - - /// - /// APPE marker - Adobe info - /// - public readonly static int APPE_MARKER = 0xEE; - - /// - /// APPF marker - /// - public readonly static int APPF_MARKER = 0xEF; - - /// - /// Adobe marker indicates presence/need for Adobe marker. - /// - public readonly static int COMMENT_MARKER = 0XFE; - - /// - /// Get the image width - /// - /// the width of the image data in pixels. - public abstract int GetWidth(); - - /// - /// Get the image height - /// - /// The height of the image data in pixels. - public abstract int GetHeight(); - - /// - /// Return the Horizontal subsampling lcFactor for requested - /// Component. The Subsample lcFactor is the number of input pixels - /// that contribute to each output pixel. This is distinct from - /// the way the JPEG to each output pixel. This is distinct from - /// the way the JPEG standard defines this quantity, because - /// fractional subsampling factors are not allowed, and it was felt - /// - /// The component of the encoded image to return the subsampling lcFactor for. - /// The subsample lcFactor. - public abstract int GetHorizontalSubsampling(int component); - - /// - /// Return the Vertical subsampling lcFactor for requested Component. - /// The Subsample lcFactor is the number of input pixels that contribute to each output pixel. - /// This is distinct from the way the JPEG to each output pixel. - /// This is distinct from the way the JPEG standard defines this quantity, because - /// fractional subsampling factors are not allowed, and it was felt - /// - /// The component of the encoded image to return the subsampling lcFactor for. - /// The subsample lcFactor. - public abstract int GetVerticalSubsampling(int component); - - /// - /// Returns the coefficient quantization tables or NULL if not defined. - /// tableNum must range in value from 0 - 3. - /// - /// the index of the table to be returned. - /// Quantization table stored at index tableNum. - public abstract JPEGQTable GetQTable(int tableNum ); - - /// - /// Returns the Quantization table for the requested component. - /// - /// the image component of interest. - /// Quantization table associated with component - public abstract JPEGQTable GetQTableForComponent(int component); - - /// - /// Returns the DC Huffman coding table requested or null if not defined - /// - /// the index of the table to be returned. - /// Huffman table stored at index tableNum. - public abstract JPEGHuffmanTable GetDCHuffmanTable( int tableNum ); - - /// - /// Returns the DC Huffman coding table for the requested component. - /// - /// the image component of interest. - /// Huffman table associated with component - public abstract JPEGHuffmanTable GetDCHuffmanTableForComponent(int component); - - /// - /// Returns the AC Huffman coding table requested or null if not defined - /// - /// the index of the table to be returned. - /// Huffman table stored at index tableNum. - public abstract JPEGHuffmanTable GetACHuffmanTable( int tableNum ); - - /// - /// Returns the AC Huffman coding table for the requested component. - /// - /// the image component of interest. - /// Huffman table associated with component - public abstract JPEGHuffmanTable GetACHuffmanTableForComponent(int component); - - /// - /// Get the number of the DC Huffman table that will be used for a particular component. - /// - /// The Component of interest. - /// The table number of the DC Huffman table for component. - public abstract int GetDCHuffmanComponentMapping(int component); - - /// - /// Get the number of the AC Huffman table that will be used for a particular component. - /// - /// The Component of interest. - /// The table number of the AC Huffman table for component. - public abstract int GetACHuffmanComponentMapping(int component); - - /// - /// Get the number of the quantization table that will be used for a particular component. - /// - /// The Component of interest. - /// The table number of the Quantization table for component. - public abstract int GetQTableComponentMapping(int component); - - /// - /// Returns true if the image information in the ParamBlock is currently valid. - /// This indicates if image data was read from the stream for decoding and weather - /// image data should be written when encoding. - /// - /// true if the image information in the ParamBlock is currently valid. - public abstract bool IsImageInfoValid(); - - /// - /// Returns true if the tables in the ParamBlock are currently valid. - /// This indicates that tables were read from the stream for decoding. - /// When encoding this indicates wether tables should be written to the stream. - /// - /// true if the tables in the ParamBlock are currently valid. - public abstract bool IsTableInfoValid(); - - /// - /// Returns true if at least one instance of the marker is present in the Parameter object. - /// For encoding returns true if there is at least one instance of the marker to be written. - /// - /// - /// The marker of interest. - public abstract bool GetMarker(int marker); - - /// - /// Returns a 'byte[][]' associated with the requested marker in the parameter object. - /// Each entry in the 'byte[][]' is the data associated with one instance of - /// the marker (each marker can theoretically appear any number of times in a stream). - /// - /// The marker of interest. - /// The 'byte[][]' for this marker or null if none available. - public abstract byte[][] GetMarkerData(int marker); - - /// - /// Returns the JPEG Encoded color id. This is generally speaking only used - /// if you are decoding into Rasters. Note that when decoding into a Raster no - /// color conversion is performed. - /// - /// The value of the JPEG encoded data'str color id. - public abstract int GetEncodedColorID(); - - /// - /// Returns the number of components for the current encoding COLOR_ID. - /// - /// the number of Components - public abstract int GetNumComponents(); - - /// - /// Get the MCUs per restart marker. - /// - /// The number of MCUs between restart markers. - public abstract int GetRestartInterval(); - - /// - /// Get the code for pixel size units This value is copied from the APP0 marker. - /// It isn't used by the JPEG codec. If the APP0 marker wasn't present then you - /// can not rely on this value. - /// - /// Value indicating the density unit one of the DENSITY_UNIT_* constants. - public abstract int GetDensityUnit(); - - /// - /// Get the horizontal pixel density This value is copied from the APP0 marker. - /// It isn't used by the JPEG code. If the APP0 marker wasn't present then - /// you can not rely on this value. - /// - /// The horizontal pixel density, in units described by - public abstract int GetXDensity(); - - /// - /// Get the vertical pixel density This value is copied into the APP0 marker. - /// It isn't used by the JPEG code. If the APP0 marker wasn't present then - /// you can not rely on this value. - /// - /// The verticle pixel density, in units described by - public abstract int getYDensity(); - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/codec/jpeg/JPEGHuffmanTable.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/codec/jpeg/JPEGHuffmanTable.cs deleted file mode 100644 index d542d00a46..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/codec/jpeg/JPEGHuffmanTable.cs +++ /dev/null @@ -1,261 +0,0 @@ -using System; - -/// ********************************************************************** -/// ********************************************************************** -/// ********************************************************************** -/// *** COPYRIGHT (c) 1997-1998 Eastman Kodak Company. *** -/// *** As an unpublished work pursuant to Title 17 of the United *** -/// *** States Code. All rights reserved. *** -/// ********************************************************************** -/// ********************************************************************** -/// ********************************************************************** - -namespace com.codec.jpeg -{ - /// - /// A class to encapsulate a JPEG Huffman table. - /// - public sealed class JPEGHuffmanTable - { - /// - /// The maximum number of symbol lengths (max symbol length in bits = 16) - /// - private static readonly int HUFF_MAX_LEN=17; - - /// - /// the maximum number of symbols - /// - private static readonly int HUFF_MAX_SYM=256; - - /// - /// bits[k] = number of symbols with length k bits - /// - private short[] lengths; - - /// - /// Symbols in order of increasing length - /// - private short[] symbols; - - /// - /// Standard Huffman table ( JPEG standard section K.3 ) - /// - public static readonly JPEGHuffmanTable StdDCLuminance = JPEGHuffmanTable.InitStdDCLuminance(); - - /// - /// Initialize Standard Huffman table. - /// - /// Standard Huffman table ( JPEG standard section K.3 ) - private static JPEGHuffmanTable InitStdDCLuminance() - { - short[] lengths = { - 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }; - short[] symbols = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; - JPEGHuffmanTable resu = new JPEGHuffmanTable(); - resu.lengths = lengths; - resu.symbols = symbols; - resu.checkTable(); - return resu; - } - - - - /// - /// Standard Huffman table Chrominance ( JPEG standard section K.3 ) - /// - public static readonly JPEGHuffmanTable StdDCChrominance = JPEGHuffmanTable.InitStdDCChrominance(); - - /// - /// Initialize Standard Huffman table Chrominance. - /// - /// Standard Huffman table Chrominance ( JPEG standard section K.3 ) - private static JPEGHuffmanTable InitStdDCChrominance() - { - short[] lengths = { // 0-base - 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }; - short[] symbols = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; - JPEGHuffmanTable resu = new JPEGHuffmanTable(); - resu.lengths = lengths; - resu.symbols = symbols; - resu.checkTable(); - return resu; - } - - /// - /// Standard Huffman table Luminance. - /// - public static readonly JPEGHuffmanTable StdACLuminance = JPEGHuffmanTable.InitStdACLuminance(); - - /// - /// Initialize Standard Huffman table Luminance. - /// - /// Standard Huffman table Luminance ( JPEG standard section K.3 ) - private static JPEGHuffmanTable InitStdACLuminance() - { - short[] lengths = { // 0-base - 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d }; - short[] symbols = { - 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, - 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, - 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, - 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, - 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, - 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, - 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, - 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, - 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, - 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, - 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, - 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, - 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, - 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, - 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, - 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, - 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa }; - JPEGHuffmanTable resu = new JPEGHuffmanTable(); - resu.lengths = lengths; - resu.symbols = symbols; - resu.checkTable(); - return resu; - } - - /// - /// Standard Huffman table ACChrominance ( JPEG standard section K.3 ) - /// - public static readonly JPEGHuffmanTable StdACChrominance = JPEGHuffmanTable.InitStdACChrominance(); - - /// - /// Initialize Standard Huffman table ACChrominance. - /// - /// Standard Huffman table ACChrominance ( JPEG standard section K.3 ) - private static JPEGHuffmanTable InitStdACChrominance() - { - short[] lengths = { // 0-base - 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 }; - short[] symbols = { - 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, - 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, - 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, - 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, - 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, - 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, - 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, - 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, - 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, - 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, - 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, - 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, - 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, - 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, - 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, - 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, - 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, - 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa }; - JPEGHuffmanTable resu = new JPEGHuffmanTable(); - resu.lengths = lengths; - resu.symbols = symbols; - resu.checkTable(); - return resu; - } - - /// - /// Private constructor used to construct the Standard Huffman tables - /// - private JPEGHuffmanTable() : base() - { - lengths = null; - symbols = null; - } - - /// - /// Creates a Huffman Table and initializes it. - /// - /// lengths[k] = # of symbols with codes of length k bits; lengths[0] is ignored - /// symbols in order of increasing code length - /// if the length of lengths is greater than 17 or if the length of symbols is greater than 256 or if any of the values in lengths or symbols is less than zero - public JPEGHuffmanTable( short[] lengths, short[] symbols ) - { - if ( lengths.Length > HUFF_MAX_LEN ) - throw new ArgumentException( "lengths array is too long" ); - for (int i=1; i < lengths.Length; i++) - if (lengths[i] < 0) - throw new ArgumentException - ( "Values in lengths array must be non-negative." ); - - - if ( symbols.Length > HUFF_MAX_SYM ) - throw new ArgumentException( "symbols array is too long" ); - for (int i=0; i < symbols.Length; i++) - if (symbols[i] < 0) - throw new ArgumentException - ( "Values in symbols array must be non-negative." ); - - this.lengths = new short[lengths.Length]; - this.symbols = new short[symbols.Length]; - - Array.Copy( lengths, 0, this.lengths, 0, lengths.Length ); - Array.Copy( symbols, 0, this.symbols, 0, symbols.Length ); - - checkTable(); - } - - /// - /// This checks that the table they gave us isn't 'illegal' It checks that the symbol - /// length counts are possible, and that they gave us at least enough symbols for - /// the symbol length counts. Eventually this might check that there aren't duplicate - /// symbols. - /// - private void checkTable() - { - int numVals=2; - int sum=0; - for (int i=1; i symbols.Length) - throw new ArgumentException - ("Invalid Huffman Table provided, not enough symbols."); - } - - /// - /// Return a copy of the array containing the number of symbols for each length in the Huffman table. - /// - /// A short array where array[k] = # of symbols in the table of length k. array[0] is unused - public short[] GetLengths() - { - short[] ret = new short[ lengths.Length]; - Array.Copy( lengths, 0, ret, 0, lengths.Length); - return ret; - } - - /// - /// Return an array containing the Huffman symbols arranged by increasing length. - /// To make use of this array you must refer the the lengths array. - /// - /// A short array of Huffman symbols - public short[] GetSymbols() - { - short[] ret = new short[symbols.Length]; - Array.Copy( symbols, 0, ret, 0, symbols.Length); - return ret; - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/codec/jpeg/JPEGQTable.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/codec/jpeg/JPEGQTable.cs deleted file mode 100644 index 7adbc4864c..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/codec/jpeg/JPEGQTable.cs +++ /dev/null @@ -1,158 +0,0 @@ -using System; - -/// ********************************************************************** -/// ********************************************************************** -/// ********************************************************************** -/// *** COPYRIGHT (c) 1997-1998 Eastman Kodak Company. *** -/// *** As an unpublished work pursuant to Title 17 of the United *** -/// *** States Code. All rights reserved. *** -/// ********************************************************************** -/// ********************************************************************** -/// ********************************************************************** - -namespace com.codec.jpeg -{ - /// - /// Class to encapsulate the JPEG quantization tables. - /// - public sealed class JPEGQTable - { - /// - /// Quantization step for each coefficient in zig-zag order - /// - private int[] quantval; - - /// - /// The number of coefficients in a DCT block - /// - private static readonly byte QTABLESIZE = 64; - - - /// - /// This is the sample luminance quantization table given in the JPEG spec - /// section K.1, expressed in zigzag order. The spec says that the values - /// given produce "good" quality, and when divided by 2, "very good" quality. - /// - public static readonly JPEGQTable StdLuminance = JPEGQTable.InitStdLuminance(); - - /// - /// Initialize the StdLuminance table. - /// - /// the StdLuminance table. - private static JPEGQTable InitStdLuminance() - { - int[] lumVals = { - 16, 11, 12, 14, 12, 10, 16, 14, - 13, 14, 18, 17, 16, 19, 24, 40, - 26, 24, 22, 22, 24, 49, 35, 37, - 29, 40, 58, 51, 61, 60, 57, 51, - 56, 55, 64, 72, 92, 78, 64, 68, - 87, 69, 55, 56, 80, 109, 81, 87, - 95, 98, 103, 104, 103, 62, 77, 113, - 121, 112, 100, 120, 92, 101, 103, 99 - }; - JPEGQTable resu = new JPEGQTable(); - resu.quantval = lumVals; - return resu; - } - - /// - /// This is the sample luminance quantization table given in the JPEG spec - /// section K.1, expressed in zigzag order. The spec says that the values - /// given produce "good" quality, and when divided by 2, "very good" quality. - /// - public static readonly JPEGQTable StdChrominance = JPEGQTable.InitStdChrominance(); - - /// - /// Initialize the StdChrominance table. - /// - /// the StdChrominance table. - private static JPEGQTable InitStdChrominance() - { - int [] chromVals = { - 17, 18, 18, 24, 21, 24, 47, 26, - 26, 47, 99, 66, 56, 66, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 99 - }; - JPEGQTable resu = new JPEGQTable(); - resu.quantval = chromVals; - return resu; - } - - /// - /// Constructs an empty quantization table. This is used to create the Std Q-Tables. - /// - private JPEGQTable() : base() - { - quantval = new int[QTABLESIZE]; - } - - /// - /// Constructs an quantization table from the array that was passed. - /// The coefficents must be in zig-zag order. - /// The array must be of length 64. - /// - /// the quantization table (this is copied). - /// if table has not a length of 64 - public JPEGQTable(int[] table ) - { - if ( table.Length != QTABLESIZE ) - { - throw new ArgumentException("Quantization table is the wrong size."); - } - else - { - quantval = new int[QTABLESIZE]; - Array.Copy(table, 0, quantval, 0, QTABLESIZE ); - } - } - - /// - /// Returns the current quantization table as an array of someInts in zig zag order. - /// - /// A copy of the contained quantization table. - public int[] GetTable() - { - int[] table = new int[QTABLESIZE]; - Array.Copy(quantval, 0, table, 0, QTABLESIZE ); - return table; - } - - /// - /// Returns a new Quantization table where the values are multiplied by - /// scaleFactor and then clamped to the range 1..32767 (or to 1..255 if - /// forceBaseline is 'true'). - /// - /// Values less than one tend to improve the quality level of the table, - /// and values greater than one degrade the quality level of the table. - /// - /// the multiplication lcFactor for the table - /// if true the values will be clamped to the range [1 .. 255] - /// A new Q-Table that is a linear multiple of this Q-Table - public JPEGQTable GetScaledInstance(float scaleFactor, - bool forceBaseline ) - { - long max = (forceBaseline)?255L:32767L; - int []ret = new int[QTABLESIZE]; - - for (int i=0; i max ) holder = max; - - ret[i] = (int)holder; - } - return new JPEGQTable(ret); - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/imaging/jpg/JpegMetadataReader.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/imaging/jpg/JpegMetadataReader.cs deleted file mode 100644 index 23705e5e29..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/imaging/jpg/JpegMetadataReader.cs +++ /dev/null @@ -1,169 +0,0 @@ -using System; -using System.Diagnostics; -using System.IO; -using com.codec.jpeg; -using com.drew.metadata; -using com.drew.metadata.jpeg; -using com.drew.metadata.iptc; -using com.drew.metadata.exif; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.imaging.jpg -{ - /// - /// This class will extract MetaData from a picture. - /// - public class JpegMetadataReader - { - /// - /// Constructor of the object - /// - /// Allways - private JpegMetadataReader() : base() - { - throw new Exception("Do not use"); - } - - /// - /// Reads MetaData from a aFile - /// - /// where to read information - /// the aMetadata object - public static Metadata ReadMetadata(FileInfo aFile) - { - JpegSegmentReader lcSegmentReader = null; - Metadata lcMetadata = null; - try - { - lcSegmentReader = new JpegSegmentReader(aFile); - lcMetadata = JpegMetadataReader.ExtractJpegSegmentReaderMetadata(lcSegmentReader); - - } - finally - { - if (lcSegmentReader != null) - { - // Dispose will call close for this class - lcSegmentReader.Dispose(); - } - } - return lcMetadata; - } - - /// - /// Extracts aMetadata from a SegmentReader - /// - /// where to extract aMetadata - /// the aMetadata found - private static Metadata ExtractJpegSegmentReaderMetadata(JpegSegmentReader aSegmentReader) - { - Metadata lcMetadata = new Metadata(); - try - { - byte[] lcExifSegment = - aSegmentReader.ReadSegment(JpegSegmentReader.SEGMENT_APP1); - new ExifReader(lcExifSegment).Extract(lcMetadata); - } - catch (Exception e) - { - Trace.TraceWarning("Error in reading Exif segment ("+e.Message+")"); - // in the interests of catching as much data as possible, continue - } - - try - { - byte[] lcIptcSegment = - aSegmentReader.ReadSegment(JpegSegmentReader.SEGMENT_APPD); - new IptcReader(lcIptcSegment).Extract(lcMetadata); - } - catch (Exception e) - { - Trace.TraceWarning("Error in reading Iptc segment (" + e.Message + ")"); - } - - try - { - byte[] lcJpegSegment = - aSegmentReader.ReadSegment(JpegSegmentReader.SEGMENT_SOF0); - new JpegReader(lcJpegSegment).Extract(lcMetadata); - } - catch (Exception e) - { - Trace.TraceWarning("Error in reading Jpeg segment (" + e.Message + ")"); - } - - try - { - byte[] lcJpegCommentSegment = - aSegmentReader.ReadSegment(JpegSegmentReader.SEGMENT_COM); - new JpegCommentReader(lcJpegCommentSegment).Extract(lcMetadata); - } - catch (Exception e) - { - Trace.TraceWarning("Error in reading Jpeg Comment segment (" + e.Message + ")"); - } - - return lcMetadata; - } - - /// - /// Reads aMetadata from a JPEGDecodeParam object - /// - /// where to find aMetadata - /// the aMetadata found - public static Metadata ReadMetadata(JPEGDecodeParam aDecodeParam) - { - Metadata lcMetadata = new Metadata(); - - // We should only really be seeing Exif in _data[0]... the 2D array exists - // because markers can theoretically appear multiple times in the aFile. - // TODO test this method - byte[][] lcExifSegment = - aDecodeParam.GetMarkerData(JPEGDecodeParam.APP1_MARKER); - if (lcExifSegment != null && lcExifSegment[0].Length > 0) - { - new ExifReader(lcExifSegment[0]).Extract(lcMetadata); - } - - // similarly, use only the first IPTC segment - byte[][] lcIptcSegment = - aDecodeParam.GetMarkerData(JPEGDecodeParam.APPD_MARKER); - if (lcIptcSegment != null && lcIptcSegment[0].Length > 0) - { - new IptcReader(lcIptcSegment[0]).Extract(lcMetadata); - } - - // NOTE: Unable to utilise JpegReader for the SOF0 frame here, as the aDecodeParam doesn't contain the byte[] - - // similarly, use only the first Jpeg Comment segment - byte[][] lcJpegCommentSegment = - aDecodeParam.GetMarkerData(JPEGDecodeParam.COMMENT_MARKER); - if (lcJpegCommentSegment != null && lcJpegCommentSegment[0].Length > 0) - { - new JpegCommentReader(lcJpegCommentSegment[0]).Extract(lcMetadata); - } - - return lcMetadata; - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/imaging/jpg/JpegProcessingException.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/imaging/jpg/JpegProcessingException.cs deleted file mode 100644 index e71bfb152e..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/imaging/jpg/JpegProcessingException.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System; -using com.drew.lang; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.imaging.jpg -{ - /// - /// Represents a JpegProcessing exception - /// - public class JpegProcessingException : CompoundException - { - /// - /// Constructor of the object - /// - /// The error aMessage - public JpegProcessingException(string aMessage) : base(aMessage) - { - } - - /// - /// Constructor of the object - /// - /// The error aMessage - /// The aCause of the exception - public JpegProcessingException(string aMessage, Exception aCause) : base(aMessage, aCause) - { - } - - /// - /// Constructor of the object - /// - /// The aCause of the exception - public JpegProcessingException(Exception aCause) : base(aCause) - { - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/imaging/jpg/JpegSegmentData.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/imaging/jpg/JpegSegmentData.cs deleted file mode 100644 index 0ee5634ec9..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/imaging/jpg/JpegSegmentData.cs +++ /dev/null @@ -1,223 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Collections; -using System.IO; -using System.Runtime.Serialization.Formatters.Binary; -using System.Runtime.Serialization; - - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.imaging.jpg -{ - [Serializable] - public class JpegSegmentData - { - - /// - /// A map of byte[], keyed by the segment marker. - /// - private IDictionary> segmentDataMap; - - /// - /// Constructor of the object. - /// - public JpegSegmentData() - : base() - { - this.segmentDataMap = new Dictionary>(10); - } - - /// - /// Adds a segment. - /// - /// the marker - /// the value of the segment - public void AddSegment(byte aSegmentMarker, byte[] aSegmentBytes) - { - IList lcSegmentList = this.GetOrCreateSegmentList(aSegmentMarker); - lcSegmentList.Add(aSegmentBytes); - } - - /// - /// Gets a segment using its key. - /// - /// the segment'str key - /// The segment found or null if none found - public byte[] GetSegment(byte aSegmentMarker) - { - return this.GetSegment(aSegmentMarker, 0); - } - - /// - /// Gets a segment using its marker and occurence value. - /// - /// the segment'str marker - /// the segment'str occurence - /// the segment found at the given occurence, or null if none found - public byte[] GetSegment(byte aSegmentMarker, int anOccurrence) - { - IList lcSegmentList = this.GetSegmentList(aSegmentMarker); - - if (lcSegmentList == null || lcSegmentList.Count <= anOccurrence) - { - return null; - } - return lcSegmentList[anOccurrence]; - } - - /// - /// Gets a segment size. - /// - /// the segment'str marker - /// the size of the marker, zero if none found - public int GetSegmentCount(byte aSegmentMarker) - { - IList lcSegmentList = this.GetSegmentList(aSegmentMarker); - if (lcSegmentList == null) - { - return 0; - } - return lcSegmentList.Count; - } - - /// - /// Removes a segment using its marker and occurence value. - /// - /// the segment'str marker - /// the segment'str occurence - public void RemoveSegmentOccurrence(byte aSegmentMarker, int anOccurrence) - { - IList lcSegmentList = this.GetSegmentList(aSegmentMarker); - if (lcSegmentList != null) - { - lcSegmentList.RemoveAt(anOccurrence); - } - - } - - /// - /// Removes a segment using its marker and occurence value. - /// - /// the segment'str marker - public void RemoveSegment(byte aSegmentMarker) - { - if (this.segmentDataMap.ContainsKey(aSegmentMarker)) - { - this.segmentDataMap.Remove(aSegmentMarker); - } - } - - /// - /// Gets the segment list of value. - /// - /// the segment marker - /// the segemnt list of value, null if none found - private IList GetSegmentList(byte aSegmentMarker) - { - if (this.segmentDataMap.ContainsKey(aSegmentMarker)) - { - return this.segmentDataMap[aSegmentMarker]; - } - return null; - } - - /// - /// Gets or creates the segment value with the given marker key. - /// - /// the segment'str marker - /// the segment marker you were looking for, or a new one if none exist - private IList GetOrCreateSegmentList(byte aSegmentMarker) - { - IList lcSegmentList = null; - if (this.segmentDataMap.ContainsKey(aSegmentMarker)) - { - lcSegmentList = this.segmentDataMap[aSegmentMarker]; - } - else - { - lcSegmentList = new List(); - segmentDataMap.Add(aSegmentMarker, lcSegmentList); - } - return lcSegmentList; - } - - /// - /// Indicates if the segment is present or not. - /// - /// the segment'str marker you are looking for - /// true if present false if not - public bool ContainsSegment(byte aSegmentMarker) - { - return this.segmentDataMap.ContainsKey(aSegmentMarker); - } - - /// - /// Writes the aSegmentData to a aFile. - /// - /// where to write the information - /// what to write in the aFile - public static void ToFile(string aFileName, JpegSegmentData aSegmentData) - { - FileStream lcFileStream = null; - try - { - lcFileStream = new FileStream(aFileName, FileMode.CreateNew); - BinaryFormatter lcBinFor = new BinaryFormatter(); - lcBinFor.Serialize(lcFileStream, aSegmentData); - } - finally - { - if (lcFileStream != null) - { - lcFileStream.Close(); - lcFileStream.Dispose(); - } - } - } - - /// - /// Loads a jpegsegmentdata from a file. - /// - /// where to find data - /// the jpegsegment asked - public static JpegSegmentData FromFile(string aFileName) - { - FileStream lcFileStream = null; - try - { - lcFileStream = new FileStream(aFileName, FileMode.Open); - BinaryFormatter lcBinFor = new BinaryFormatter(); - return (JpegSegmentData)lcBinFor.Deserialize(lcFileStream); - } - finally - { - if (lcFileStream != null) - { - lcFileStream.Close(); - lcFileStream.Dispose(); - } - } - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/imaging/jpg/JpegSegmentReader.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/imaging/jpg/JpegSegmentReader.cs deleted file mode 100644 index ae1d3c9137..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/imaging/jpg/JpegSegmentReader.cs +++ /dev/null @@ -1,379 +0,0 @@ -using System; -using System.IO; -using System.Collections; -using System.Collections.Generic; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.imaging.jpg -{ - /// - /// Will analyze a stream form an image - /// - public class JpegSegmentReader - { - private FileInfo file; - - private byte[] data; - - private Stream stream; - - private JpegSegmentData segmentDataMap; - - /// - /// Private, because this segment crashes my algorithm, and searching for it doesn't work (yet). - /// - private const byte SEGMENT_SOS = (byte)0xDA; - - /// - /// Private, because one wouldn't search for it. - /// - private const byte MARKER_EOI = (byte)0xD9; - - /// - /// APP0 Jpeg segment identifier -- Jfif data. - /// - public const byte SEGMENT_APP0 = (byte)0xE0; - /// - /// APP1 Jpeg segment identifier -- where Exif data is kept. - /// - public const byte SEGMENT_APP1 = (byte)0xE1; - /// - /// APP2 Jpeg segment identifier. - /// - public const byte SEGMENT_APP2 = (byte)0xE2; - /// - /// APP3 Jpeg segment identifier. - /// - public const byte SEGMENT_APP3 = (byte)0xE3; - /// - /// APP4 Jpeg segment identifier. - /// - public const byte SEGMENT_APP4 = (byte)0xE4; - /// - /// APP5 Jpeg segment identifier. - /// - public const byte SEGMENT_APP5 = (byte)0xE5; - /// - /// APP6 Jpeg segment identifier. - /// - public const byte SEGMENT_APP6 = (byte)0xE6; - /// - /// APP7 Jpeg segment identifier. - /// - public const byte SEGMENT_APP7 = (byte)0xE7; - /// - /// APP8 Jpeg segment identifier. - /// - public const byte SEGMENT_APP8 = (byte)0xE8; - /// - /// APP9 Jpeg segment identifier. - /// - public const byte SEGMENT_APP9 = (byte)0xE9; - /// - /// APPA Jpeg segment identifier -- can hold Unicode comments. - /// - public const byte SEGMENT_APPA = (byte)0xEA; - /// - /// APPB Jpeg segment identifier. - /// - public const byte SEGMENT_APPB = (byte)0xEB; - /// - /// APPC Jpeg segment identifier. - /// - public const byte SEGMENT_APPC = (byte)0xEC; - /// - /// APPD Jpeg segment identifier -- IPTC data in here. - /// - public const byte SEGMENT_APPD = (byte)0xED; - /// - /// APPE Jpeg segment identifier. - /// - public const byte SEGMENT_APPE = (byte)0xEE; - /// - /// APPF Jpeg segment identifier. - /// - public const byte SEGMENT_APPF = (byte)0xEF; - /// - /// Start Of Image segment identifier. - /// - public const byte SEGMENT_SOI = (byte)0xD8; - /// - /// Define Quantization Table segment identifier. - /// - public const byte SEGMENT_DQT = (byte)0xDB; - /// - /// Define Huffman Table segment identifier. - /// - public const byte SEGMENT_DHT = (byte)0xC4; - /// - /// Start-of-Frame Zero segment identifier. - /// - public const byte SEGMENT_SOF0 = (byte)0xC0; - /// - /// Jpeg comment segment identifier. - /// - public const byte SEGMENT_COM = (byte)0xFE; - - - /// - /// Constructor of the object - /// - /// where to read - public JpegSegmentReader(FileInfo aFile) - : base() - { - this.file = aFile; - this.data = null; - this.stream = null; - this.ReadSegments(); - } - - /// - /// Constructor of the object - /// - /// where to read - public JpegSegmentReader(byte[] aFileContents) - { - this.file = null; - this.stream = null; - this.data = aFileContents; - this.ReadSegments(); - } - - - /// - /// Constructor of the object - /// - /// where to read. - public JpegSegmentReader(Stream aStream) - { - this.stream = aStream; - this.file = null; - this.data = null; - this.ReadSegments(); - } - - /// - /// Reads the first instance of a given Jpeg segment, returning the contents as a byte array. - /// - /// the byte identifier for the desired segment - /// the byte array if found, else null - /// for any problems processing the Jpeg data - public byte[] ReadSegment(byte aSegmentMarker) - { - return this.ReadSegment(aSegmentMarker, 0); - } - - /// - /// Reads the first instance of a given Jpeg segment, returning the contents as a byte array. - /// - /// the byte identifier for the desired segment - /// the anOccurrence of the specified segment within the jpeg aFile - /// the byte array if found, else null - /// for any problems processing the Jpeg data - public byte[] ReadSegment(byte aSegmentMarker, int anOccurrence) - { - return this.segmentDataMap.GetSegment(aSegmentMarker); - } - - /// - /// Gets the number of segment - /// - /// the byte identifier for the desired segment - /// the number of segment or zero if segment does not exist - public int GetSegmentCount(byte aSegmentMarker) - { - return this.segmentDataMap.GetSegmentCount(aSegmentMarker); - } - - /// - /// Reads segments - /// - /// for any problems processing the Jpeg data - private void ReadSegments() - { - this.segmentDataMap = new JpegSegmentData(); - BufferedStream lcInStream = this.GetJpegInputStream(); - try - { - int lcOffset = 0; - // first two bytes should be jpeg magic number - if (!this.IsValidJpegHeaderBytes(lcInStream)) - { - throw new JpegProcessingException("not a jpeg file"); - } - lcOffset += 2; - do - { - // next byte is 0xFF - byte lcSegmentIdentifier = (byte)(lcInStream.ReadByte() & 0xFF); - if ((lcSegmentIdentifier & 0xFF) != 0xFF) - { - throw new JpegProcessingException( - "expected jpeg segment start identifier 0xFF at offset " - + lcOffset - + ", not 0x" - + (lcSegmentIdentifier & 0xFF).ToString("X")); - } - lcOffset++; - // next byte is - byte lcSegmentMarker = (byte)(lcInStream.ReadByte() & 0xFF); - lcOffset++; - // next 2-bytes are : [high-byte] [low-byte] - byte[] lcSegmentLengthBytes = new byte[2]; - lcInStream.Read(lcSegmentLengthBytes, 0, 2); - lcOffset += 2; - int lcSegmentLength = - ((lcSegmentLengthBytes[0] << 8) & 0xFF00) - | (lcSegmentLengthBytes[1] & 0xFF); - // segment length includes size bytes, so subtract two - lcSegmentLength -= 2; - if (lcSegmentLength > (lcInStream.Length - lcInStream.Position)) - { - throw new JpegProcessingException("segment size would extend beyond file stream length"); - } - else if (lcSegmentLength < 0) - { - throw new JpegProcessingException("segment size would be less than zero"); - } - byte[] lcSegmentBytes = new byte[lcSegmentLength]; - lcInStream.Read(lcSegmentBytes, 0, lcSegmentLength); - lcOffset += lcSegmentLength; - if ((lcSegmentMarker & 0xFF) == (SEGMENT_SOS & 0xFF)) - { - // The 'Start-Of-Scan' segment'str length doesn't include the image data, instead would - // have to search for the two bytes: 0xFF 0xD9 (EOI). - // It comes last so simply return at this point - return; - } - else if ((lcSegmentMarker & 0xFF) == (MARKER_EOI & 0xFF)) - { - // the 'End-Of-Image' segment -- this should never be found in this fashion - return; - } - else - { - this.segmentDataMap.AddSegment(lcSegmentMarker, lcSegmentBytes); - } - // didn't find the one we're looking for, loop through to the next segment - } while (true); - } - catch (IOException ioe) - { - //throw new JpegProcessingException("IOException processing Jpeg aFile", ioe); - throw new JpegProcessingException( - "IOException processing Jpeg file: " + ioe.Message, - ioe); - } - finally - { - if (lcInStream != null) - { - lcInStream.Close(); - lcInStream.Dispose(); - } - } - } - - /// - /// Private helper method to create a BufferedInputStream of Jpeg data - /// from whichever data source was specified upon construction of this instance. - /// - /// a BufferedStream of Jpeg data - /// for any problems processing the Jpeg data - private BufferedStream GetJpegInputStream() - { - if (this.stream != null) - { - if (this.stream is BufferedStream) - { - return (BufferedStream)this.stream; - } - else - { - return new BufferedStream(this.stream); - } - } - Stream lcInputStream = null; - if (this.data == null) - { - try - { - // Added read only access for ASPX use, thanks for Ryan Patridge - lcInputStream = this.file.Open(FileMode.Open, FileAccess.Read); - } - catch (FileNotFoundException e) - { - throw new JpegProcessingException( - "Jpeg file \"" + file.FullName + "\" does not exist", - e); - } - } - else - { - lcInputStream = new MemoryStream(this.data); - } - return new BufferedStream(lcInputStream, 1024 * 50); - } - - /// - /// Helper method that validates the Jpeg aFile'str magic number. - /// - /// the InputStream to read bytes from, which must be positioned at its start (i.e. no bytes read yet) - /// true if the magic number is Jpeg (0xFFD8) - /// for any problems processing the Jpeg data - private bool IsValidJpegHeaderBytes(BufferedStream aFileStream) - { - byte[] lcHeader = new byte[2]; - aFileStream.Read(lcHeader, 0, 2); - return ((lcHeader[0] & 0xFF) == 0xFF && (lcHeader[1] & 0xFF) == 0xD8); - } - - /// - /// Close the stream. - /// - public void Close() - { - if (this.stream != null) - { - this.stream.Close(); - } - } - - /// - /// Dispose the stream and all object linked with it - /// - public void Dispose() - { - if (this.stream != null) - { - this.stream.Close(); - this.stream.Dispose(); - } - if (this.file != null) - { - this.file = null; - } - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/imaging/tiff/TiffMetadataReader.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/imaging/tiff/TiffMetadataReader.cs deleted file mode 100644 index 6b1412c233..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/imaging/tiff/TiffMetadataReader.cs +++ /dev/null @@ -1,98 +0,0 @@ -using System; -using System.IO; -using com.codec.jpeg; -using com.drew.metadata; -using com.drew.metadata.jpeg; -using com.drew.metadata.iptc; -using com.drew.metadata.exif; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.imaging.tiff -{ - /// - /// This class will extract MetaData from a picture. - /// - public class TiffMetadataReader - { - /// - /// Constructor of the object. - /// - private TiffMetadataReader() - : base() - { - throw new Exception("Do not use"); - } - - /// - /// Constructor of the object. - /// - /// Where to read metadata from - /// a meta data - public static Metadata ReadMetadata(FileInfo aFile) - { - Stream lcStream = null; - Metadata lcMetadata = null; - try - { - lcStream = aFile.OpenRead(); - lcMetadata = ReadMetadata(lcStream); - - } - catch (Exception e) - { - throw e; - } - finally - { - if (lcStream != null) - { - lcStream.Close(); - lcStream.Dispose(); - } - } - return lcMetadata; - } - - /// - /// Constructor of the object. - /// - /// Where to read information from. Caution, you are responsible for closing this stream. - /// a meta data object - public static Metadata ReadMetadata(Stream aStream) - { - Metadata metadata = new Metadata(); - try - { - byte[] buffer = new byte[(int)aStream.Length]; - aStream.Read(buffer, 0, buffer.Length); - - new ExifReader(buffer).ExtractTiff(metadata); - } - catch (MetadataException e) - { - throw new TiffProcessingException(e); - } - return metadata; - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/imaging/tiff/TiffProcessingException.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/imaging/tiff/TiffProcessingException.cs deleted file mode 100644 index c46997bdde..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/imaging/tiff/TiffProcessingException.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using com.drew.lang; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.imaging.tiff -{ - /// - /// Represents a TiffProcessing exception - /// - public class TiffProcessingException : CompoundException - { - /// - /// Constructor of the object - /// - /// The error aMessage - public TiffProcessingException(string aMessage) - : base(aMessage) - { - } - - /// - /// Constructor of the object - /// - /// The error aMessage - /// The aCause of the exception - public TiffProcessingException(string aMessage, Exception aCause) - : base(aMessage, aCause) - { - } - - /// - /// Constructor of the object - /// - /// The aCause of the exception - public TiffProcessingException(Exception aCause) - : base(aCause) - { - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/lang/CompoundException.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/lang/CompoundException.cs deleted file mode 100644 index 7a5cb474bd..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/lang/CompoundException.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.lang -{ - /// - /// This is Compound exception - /// - public class CompoundException : Exception - { - /// - /// Constructor of the object - /// - /// The error aMessage - public CompoundException(string aMessage) : base(aMessage) - { - } - - /// - /// Constructor of the object - /// - /// The error aMessage - /// The aCause of the exception - public CompoundException(string aMessage, Exception aCause) : base(aMessage, aCause) - { - } - - /// - /// Constructor of the object - /// - /// The aCause of the exception - public CompoundException(Exception aCause) : base(null, aCause) - { - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/lang/Rational.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/lang/Rational.cs deleted file mode 100644 index bca2790236..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/lang/Rational.cs +++ /dev/null @@ -1,309 +0,0 @@ -using System; -using System.IO; -using System.Collections; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.lang -{ - /// - /// Created on 6 May 2002, 18:06 - /// Updated 26 Aug 2002 by Drew - /// - Added toSimpleString() method, which returns a simplified and hopefully - /// more readable version of the Rational. i.e. 2/10 -> 1/5, and 10/2 -> 5 - /// Modified 29 Oct 2002 (v1.2) - /// - Improved toSimpleString() to lcFactor more complex rational numbers into - /// a simpler form i.e. 10/15 -> 2/3 - /// - toSimpleString() now accepts a boolean flag, 'allowDecimals' which - /// will display the rational number in decimal form if it fits within 5 - /// digits i.e. 3/4 -> 0.75 when isAllowDecimal == true - /// - [Serializable] - public class Rational - { - /// - /// Holds the numerator. - /// - private readonly int numerator; - - /// - /// Holds the denominator. - /// - private readonly int denominator; - - private int maxSimplificationCalculations = 1000; - - /// - /// Creates a new instance of Rational. - /// Rational objects are immutable, so once you've set your numerator and - /// denominator values here, you're stuck with them! - /// - /// a numerator - /// a denominator - public Rational(int aNumerator, int aDenominator) - : base() - { - this.numerator = aNumerator; - this.denominator = aDenominator; - } - - /// - /// Returns the value of the specified number as a double. This may involve rounding.
- /// Caution: if denominator is 0, then result in Double.PositiveInfinity or Double.NegativeInfinity. - ///
- /// the numeric value represented by this object after conversion to type double. - public double DoubleValue() - { - return (double)this.numerator / (double)this.denominator; - } - - /// - /// Returns the value of the specified number as a float. This may involve rounding. - /// Caution: if denominator is 0, then result in Double.PositiveInfinity or Double.NegativeInfinity. - /// - /// the numeric value represented by this object after conversion to type float. - public float FloatValue() - { - return (float)this.numerator / (float)this.denominator; - } - - /// - /// Returns the value of the specified number as a byte. This may involve rounding or truncation. - /// This implementation simply casts the result of doubleValue() to byte. If denominator is 0 then - /// value returned is Byte.MinValue. - /// - /// the numeric value represented by this object after conversion to type byte. - public byte ByteValue() - { - return (byte)this.DoubleValue(); - } - - /// - /// Returns the value of the specified number as an int. - /// This may involve rounding or truncation. - /// This implementation simply casts the result of doubleValue() to int. If denominator is 0 then - /// value returned is Integer.MinValue. - /// - /// the numeric value represented by this object after conversion to type int. - public int IntValue() - { - return (int)this.DoubleValue(); - } - - /// - /// Returns the value of the specified number as a long. - /// This may involve rounding or truncation. - /// This implementation simply casts the result of doubleValue() to long. If denominator is 0 then - /// value returned is Long.MinValue. - /// - /// the numeric value represented by this object after conversion to type long. - public long LongValue() - { - return (long)this.DoubleValue(); - } - - /// - /// Returns the value of the specified number as a short. - /// This may involve rounding or truncation. - /// This implementation simply casts the result of doubleValue() to short. If denominator is 0 then - /// value returned is Short.MinValue. - /// - /// the numeric value represented by this object after conversion to type short. - public short ShortValue() - { - return (short)this.DoubleValue(); - } - - /// - /// Returns the denominator. - /// - /// the denominator. - public int GetDenominator() - { - return this.denominator; - } - - /// - /// Returns the numerator. - /// - /// the numerator. - public int GetNumerator() - { - return this.numerator; - } - - /// - /// Returns the reciprocal value of this obejct as a new Rational. - /// - /// the reciprocal in a new object - public Rational GetReciprocal() - { - return new Rational(this.denominator, this.numerator); - } - - /// - /// Checks if this rational number is an Integer, either positive or negative. - /// - /// true is Rational is an integer, false otherwize - public bool IsInteger() - { - return (this.denominator == 1 - || (this.denominator != 0 && (this.numerator % this.denominator == 0)) - || (this.denominator == 0 && this.numerator == 0)); - } - - /// - /// Returns a string representation of the object of form numerator/denominator. - /// - /// a string representation of the object. - public override String ToString() - { - return this.numerator + "/" + this.denominator; - } - - /// - /// Returns the simplest represenation of this Rational'str value possible. - /// - /// if true then decimal will be showned - /// the simplest represenation of this Rational'str value possible. - public String ToSimpleString(bool isAllowDecimal) - { - if (this.denominator == 0 && this.numerator != 0) - { - return this.ToString(); - } - else if (this.IsInteger()) - { - return this.IntValue().ToString(); - } - else if (this.numerator != 1 && this.denominator % this.numerator == 0) - { - // common lcFactor between denominator and numerator - int lcNewDenominator = this.denominator / this.numerator; - return new Rational(1, lcNewDenominator).ToSimpleString(isAllowDecimal); - } - else - { - Rational lcSimplifiedInstance = this.GetSimplifiedInstance(); - if (isAllowDecimal) - { - String lcDoubleString = - lcSimplifiedInstance.DoubleValue().ToString(); - if (lcDoubleString.Length < 5) - { - return lcDoubleString; - } - } - return lcSimplifiedInstance.ToString(); - } - } - - - /// - /// Decides whether a brute-force simplification calculation should be avoided by comparing the - /// maximum number of possible calculations with some threshold. - /// - /// true if the simplification should be performed, otherwise false - private bool TooComplexForSimplification() - { - double lcMaxPossibleCalculations = - (((double)(Math.Min(this.denominator, this.numerator) - 1) / 5d) + 2); - return lcMaxPossibleCalculations > this.maxSimplificationCalculations; - } - - /// - /// Compares two Rational instances, returning true if they are mathematically equivalent. - /// - /// the Rational to compare this instance to. - /// true if instances are mathematically equivalent, otherwise false. Will also return false if anObject is not an instance of Rational. - public override bool Equals(object anObject) - { - if (anObject == null) return false; - if (anObject == this) return true; - if (anObject is Rational) - { - Rational that = (Rational)anObject; - return this.DoubleValue() == that.DoubleValue(); - } - return false; - } - - /// - /// Simplifies the Rational number. - /// - /// Prime number series: 1, 2, 3, 5, 7, 9, 11, 13, 17 - /// - /// To reduce a rational, need to see if both numerator and denominator are divisible - /// by a common lcFactor. Using the prime number series in ascending order guarantees - /// the minimun number of checks required. - /// - /// However, generating the prime number series seems to be a hefty task. Perhaps - /// it'str simpler to check if both d & n are divisible by all numbers from 2 -> - /// (Math.min(denominator, numerator) / 2). In doing this, one can check for 2 - /// and 5 once, then ignore all even numbers, and all numbers ending in 0 or 5. - /// This leaves four numbers from every ten to check. - /// - /// Therefore, the max number of pairs of modulus divisions required will be: - /// - /// 4 Math.min(denominator, numerator) - 1 - /// -- * ------------------------------------ + 2 - /// 10 2 - /// - /// Math.min(denominator, numerator) - 1 - /// = ------------------------------------ + 2 - /// 5 - /// - /// a simplified instance, or if the Rational could not be simpliffied, returns itself (unchanged) - public Rational GetSimplifiedInstance() - { - if (this.TooComplexForSimplification()) - { - return this; - } - for (int lcFactor = 2; - lcFactor <= Math.Min(this.denominator, this.numerator); - lcFactor++) - { - if ((lcFactor % 2 == 0 && lcFactor > 2) - || (lcFactor % 5 == 0 && lcFactor > 5)) - { - continue; - } - if (this.denominator % lcFactor == 0 && this.numerator % lcFactor == 0) - { - // found a common lcFactor - return new Rational(this.numerator / lcFactor, this.denominator / lcFactor); - } - } - return this; - } - - /// - /// Returns the hash code of the object - /// - /// the hash code of the object - public override int GetHashCode() - { - return this.denominator.GetHashCode() >> this.numerator.GetHashCode() * this.DoubleValue().GetHashCode(); - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/AbstractDirectory.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/AbstractDirectory.cs deleted file mode 100644 index 2ce7d58292..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/AbstractDirectory.cs +++ /dev/null @@ -1,853 +0,0 @@ -using System; -using System.IO; -using System.Text; -using System.Reflection; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.Globalization; -using com.drew.lang; -using com.drew.metadata.iptc; -using com.utils.bundle; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata -{ - /// - /// Base class for all Metadata directory types with supporting - /// methods for setting and getting tag values. - /// - [Serializable] - public abstract class AbstractDirectory : IEnumerable - { - /// - /// Returns an Iterator of Tag instances that have been set in this Directory. - /// - /// an Iterator of Tag instances - IEnumerator IEnumerable.GetEnumerator() - { - return GetTagIterator(); - } - - /// - /// Returns an Iterator of Tag instances that have been set in this Directory. - /// - /// an Iterator of Tag instances - IEnumerator IEnumerable.GetEnumerator() - { - return GetTagIterator(); - } - - /// - /// List of date format that will be used if standard format does not work. - /// - private readonly static string[] DATE_FORMATS = new string[] { "dd/MM/yyyy HH:mm:ss", "yyyy:MM:dd HH:mm:ss", "yyyy-MM-dd_HH-mm-ss", "yyyy/MM/dd HH:mm:ss", "dd/MM/yyyy", "yyyy/MM/dd", "yyyy-MM-dd" }; - - /// - /// Map of values hashed by type identifiers. - /// - private IDictionary tagMap; - - /// - /// The descriptor used to interpret tag values. - /// - private AbstractTagDescriptor descriptor; - - /// - /// A convenient list holding tag values in the order in which they were stored.
- /// This is used for creation of an iterator, and for counting the number of defined tags. - ///
- private IList definedTagList; - - /// - /// The bundle name used by this directory. - /// - private string bundleName; - protected string BundleName - { - get - { - return this.bundleName; - } - set - { - this.bundleName = value; - } - } - - /// - /// Indicates if there is error in this directory - /// - private bool hasError; - public bool HasError - { - get - { - return this.hasError; - } - set - { - this.hasError = value; - } - } - - /// - /// Provides the map of tag names, hashed by tag type identifier.
- /// Will contain all tag value and tag name for all descriptor. - ///
- private static IDictionary> tagNameMap; - - - - /// - /// Creates a new Directory. - /// - private AbstractDirectory() : base() - { - this.tagMap = new Dictionary(); - this.definedTagList = new List(); - this.HasError = false; - if (AbstractDirectory.tagNameMap == null) - { - AbstractDirectory.tagNameMap = new Dictionary>(25); - } - } - - /// - /// Creates a new Directory. - /// - /// bundle name for this directory - protected AbstractDirectory(string aBundleName) - : this() - { - this.BundleName = aBundleName; - // Load the bundle - IResourceBundle bundle = ResourceBundleFactory.CreateDefaultBundle(aBundleName); - AbstractDirectory.tagNameMap[this.GetType()] = AbstractDirectory.FillTagMap(this.GetType(), bundle); - } - - /// - /// Indicates whether the specified tag type has been set. - /// - /// the tag type to check for - /// true if a value exists for the specified tag type, false if not - public bool ContainsTag(int aTagType) - { - return this.tagMap.ContainsKey(aTagType); - } - - /// - /// Returns an Iterator of Tag instances that have been set in this Directory. - /// - /// an Iterator of Tag instances - public IEnumerator GetTagIterator() - { - return this.definedTagList.GetEnumerator(); - } - - /// - /// Returns the number of tags set in this Directory. - /// - /// the number of tags set in this Directory - public int GetTagCount() - { - return this.definedTagList.Count; - } - - /// - /// Sets the descriptor used to interperet tag values. - /// - /// the descriptor used to interperet tag values - /// if aDescriptor is null - public void SetDescriptor(AbstractTagDescriptor aDescriptor) - { - if (aDescriptor == null) - { - throw new NullReferenceException("Cannot set a null descriptor"); - } - this.descriptor = aDescriptor; - } - - /// - /// Sets an int array for the specified tag. - /// - /// the tag identifier - /// the int array to store - public virtual void SetIntArray(int aTagType, int[] someInts) - { - this.SetObject(aTagType, someInts); - } - - /// - /// Helper method, containing common functionality for all 'add' methods. - /// - /// the tag value as an int - /// the value for the specified tag - /// if aValue is null - public void SetObject(int aTagType, object aValue) - { - if (aValue == null) - { - throw new NullReferenceException("Cannot set a null object"); - } - - if (!this.tagMap.ContainsKey(aTagType)) - { - this.tagMap.Add(aTagType, aValue); - this.definedTagList.Add(new Tag(aTagType, this)); - } - else - { - // We remove it and re-add it with the new value - this.tagMap.Remove(aTagType); - this.tagMap.Add(aTagType, aValue); - } - } - - /// - /// Returns the specified tag value as an int, if possible. - /// - /// the specified tag type - /// the specified tag value as an int, if possible. - /// if tag not found - public int GetInt(int aTagType) - { - object lcObj = this.GetObject(aTagType); - if (lcObj == null) - { - throw new MetadataException( - "Tag " - + GetTagName(aTagType) - + " has not been set -- check using containsTag() first"); - } - else if (lcObj is string) - { - try - { - return Convert.ToInt32((string)lcObj); - } - catch (FormatException) - { - string lcStr = (string)lcObj; - int lcVal = 0; - for (int i = lcStr.Length - 1; i >= 0; i--) - { - lcVal += lcStr[i] << (i * 8); - } - return lcVal; - } - } - else if (lcObj is Rational) - { - return ((Rational)lcObj).IntValue(); - } - else if (lcObj is byte[]) - { - byte[] lcTab = (byte[])lcObj; - if (lcTab.Length >= 0) - { - return (int)lcTab[0]; - } - - } - else if (lcObj is int || lcObj is byte || lcObj is long || lcObj is float || lcObj is double) - { - try - { - return Convert.ToInt32(lcObj); - } - catch (FormatException e) - { - throw new MetadataException("Unable to parse as int object of type:'" + lcObj.GetType() + "' that look like:'" + lcObj.ToString() + "'", e); - } - } - throw new MetadataException("Obj is :" + lcObj.GetType() + " and look like:" + lcObj.ToString()); - } - - /// - /// Gets the specified tag value as a string array, if possible. Only supported where the tag is set as string[], string, int[], byte[] or Rational[]. - /// - /// the tag identifier - /// the tag value as an array of Strings - /// if tag not found or if it cannot be represented as a string[] - public string[] GetStringArray(int aTagType) - { - object lcObj = GetObject(aTagType); - if (lcObj == null) - { - throw new MetadataException( - "Tag " - + GetTagName(aTagType) - + " has not been set -- check using containsTag() first"); - } - else if (lcObj is string[]) - { - return (string[]) lcObj; - } - else if (lcObj is string) - { - return new string[] { (string)lcObj }; - } - else if (lcObj is int[]) - { - int[] lcInts = (int[]) lcObj; - string[] lcStrings = new string[lcInts.Length]; - for (int i = 0; i < lcStrings.Length; i++) - { - lcStrings[i] = lcInts[i].ToString(); - } - return lcStrings; - } - else if (lcObj is byte[]) - { - byte[] lcBytes = (byte[]) lcObj; - string[] lcStrings = new string[lcBytes.Length]; - for (int i = 0; i < lcStrings.Length; i++) - { - lcStrings[i] = lcBytes[i].ToString(); - } - return lcStrings; - } - else if (lcObj is Rational[]) - { - Rational[] lcRationals = (Rational[]) lcObj; - string[] lcStrings = new string[lcRationals.Length]; - for (int i = 0; i < lcStrings.Length; i++) - { - lcStrings[i] = lcRationals[i].ToSimpleString(false); - } - return lcStrings; - } - throw new MetadataException("Obj is :" + lcObj.GetType() + " and look like:" + lcObj.ToString()); - } - - /// - /// Gets the specified tag value as an int array, if possible. Only supported where the tag is set as string, int[], byte[] or Rational[]. - /// - /// the tag identifier - /// the tag value as an int array - /// if tag not found or if it cannot be represented as a int[] - public int[] GetIntArray(int aTagType) - { - object lcObj = GetObject(aTagType); - if (lcObj == null) - { - throw new MetadataException( - "Tag " - + GetTagName(aTagType) - + " has not been set -- check using containsTag() first"); - } - else if (lcObj is Rational[]) - { - Rational[] lcRationals = (Rational[]) lcObj; - int[] lcInts = new int[lcRationals.Length]; - for (int i = 0; i < lcInts.Length; i++) - { - lcInts[i] = lcRationals[i].IntValue(); - } - return lcInts; - } - else if (lcObj is int[]) - { - return (int[]) lcObj; - } - else if (lcObj is byte[]) - { - byte[] lcBytes = (byte[]) lcObj; - int[] lcInts = new int[lcBytes.Length]; - for (int i = 0; i < lcBytes.Length; i++) - { - lcInts[i] = lcBytes[i]; - } - return lcInts; - } - else if (lcObj is string) - { - string lcStr = (string) lcObj; - int[] lcInts = new int[lcStr.Length]; - for (int i = 0; i < lcStr.Length; i++) - { - lcInts[i] = lcStr[i]; - } - return lcInts; - } - throw new MetadataException("Obj is :" + lcObj.GetType() + " and look like:" + lcObj.ToString()); - } - - /// - /// Gets the specified tag value as an byte array, if possible. Only supported where the tag is set as string, int[], byte[] or Rational[]. - /// - /// the tag identifier - /// the tag value as a byte array - /// if tag not found or if it cannot be represented as a byte[] - public byte[] GetByteArray(int aTagType) - { - object lcObj = GetObject(aTagType); - if (lcObj == null) - { - throw new MetadataException( - "Tag " - + GetTagName(aTagType) - + " has not been set -- check using containsTag() first"); - } - else if (lcObj is Rational[]) - { - Rational[] lcRationals = (Rational[]) lcObj; - byte[] lcBytes = new byte[lcRationals.Length]; - for (int i = 0; i < lcBytes.Length; i++) - { - lcBytes[i] = lcRationals[i].ByteValue(); - } - return lcBytes; - } - else if (lcObj is byte[]) - { - return (byte[]) lcObj; - } - else if (lcObj is int[]) - { - int[] lcInts = (int[]) lcObj; - byte[] lcBytes = new byte[lcInts.Length]; - for (int i = 0; i < lcInts.Length; i++) - { - lcBytes[i] = (byte) lcInts[i]; - } - return lcBytes; - } - else if (lcObj is string) - { - string lcStr = (string) lcObj; - byte[] lcBytes = new byte[lcStr.Length]; - for (int i = 0; i < lcStr.Length; i++) - { - lcBytes[i] = (byte) lcStr[i]; - } - return lcBytes; - } - throw new MetadataException("Obj is :" + lcObj.GetType() + " and look like:" + lcObj.ToString()); - } - - /// - /// Returns the specified tag value as a double, if possible. - /// - /// the specified tag type - /// the specified tag value as a double, if possible. - public double GetDouble(int aTagType) - { - object lcObj = GetObject(aTagType); - if (lcObj == null) - { - throw new MetadataException( - "Tag " - + GetTagName(aTagType) - + " has not been set -- check using containsTag() first"); - } - else if (lcObj is Rational) - { - return ((Rational)lcObj).DoubleValue(); - } - else if (lcObj is double || lcObj is string || lcObj is int || lcObj is byte || lcObj is long || lcObj is float) - { - try - { - return Convert.ToDouble(lcObj); - } - catch (FormatException e) - { - throw new MetadataException("Unable to parse as double object of type:'" + lcObj.GetType() + "' that look like:'" + lcObj.ToString() + "'", e); - } - } - throw new MetadataException("Obj is :" + lcObj.GetType() + " and look like:" + lcObj.ToString()); - } - - /// - /// Returns the specified tag value as a float, if possible. - /// - /// the specified tag type - /// the specified tag value as a float, if possible. - public float GetFloat(int aTagType) - { - object lcObj = GetObject(aTagType); - if (lcObj == null) - { - throw new MetadataException( - "Tag " - + GetTagName(aTagType) - + " has not been set -- check using containsTag() first"); - } - else if (lcObj is Rational) - { - return ((Rational)lcObj).FloatValue(); - } - else if (lcObj is float || lcObj is string || lcObj is int || lcObj is byte || lcObj is long || lcObj is double) - { - try - { - return (float)Convert.ToDouble(lcObj); - } - catch (FormatException e) - { - throw new MetadataException("Unable to parse as float object of type:'" + lcObj.GetType() + "' that look like:'" + lcObj.ToString() + "'", e); - } - } - throw new MetadataException("Obj is :" + lcObj.GetType() + " and look like:" + lcObj.ToString()); - } - - /// - /// Returns the specified tag value as a long, if possible. - /// - /// the specified tag type - /// the specified tag value as a long, if possible. - public long GetLong(int aTagType) - { - object lcObj = GetObject(aTagType); - if (lcObj == null) - { - throw new MetadataException( - "Tag " - + GetTagName(aTagType) - + " has not been set -- check using containsTag() first"); - } - else if (lcObj is Rational) - { - return ((Rational)lcObj).LongValue(); - } - else if (lcObj is long || lcObj is string || lcObj is int || lcObj is byte || lcObj is double || lcObj is double) - { - try - { - return Convert.ToInt64(lcObj); - } - catch (FormatException e) - { - throw new MetadataException("Unable to parse as long object of type:'" + lcObj.GetType() + "' that look like:'" + lcObj.ToString() + "'", e); - } - } - throw new MetadataException("Obj is :" + lcObj.GetType() + " and look like:" + lcObj.ToString()); - } - - /// - /// Returns the specified tag value as a boolean, if possible. - /// - /// the specified tag type - /// the specified tag value as a boolean, if possible. - public bool GetBoolean(int aTagType) - { - object lcObj = GetObject(aTagType); - if (lcObj == null) - { - throw new MetadataException( - "Tag " - + GetTagName(aTagType) - + " has not been set -- check using containsTag() first"); - } - else if (lcObj is Boolean) - { - return ((Boolean) lcObj); - } - else if (lcObj is string) - { - try - { - return Convert.ToBoolean((string) lcObj); - } - catch (FormatException e) - { - throw new MetadataException("Unable to parse as boolean object of type:'" + lcObj.GetType() + "' that look like:'" + lcObj.ToString() + "'", e); - } - } - throw new MetadataException("Obj is :" + lcObj.GetType() + " and look like:" + lcObj.ToString()); - } - - /// - /// Returns the specified tag value as a date, if possible. - /// - /// the specified tag type - /// the specified tag value as a date, if possible. - public DateTime GetDate(int aTagType) - { - object lcObj = GetObject(aTagType); - if (lcObj == null) - { - throw new MetadataException( - "Tag " - + GetTagName(aTagType) - + " has not been set -- check using containsTag() first"); - } - else if (lcObj is DateTime) - { - return (DateTime) lcObj; - } - else if (lcObj is string) - { - string lcDateString = (string) lcObj; - try - { - DateTime res = DateTime.Today; - if (DateTime.TryParse(lcDateString, out res)) - return res; - - // Was not able to parse date using standard format - // We try the following format - DateTime resu = AbstractDirectory.ParseDate(lcDateString); - if (resu == DateTime.Today) - { - Trace.TraceWarning("Was not able to parse date '"+lcDateString+"'"); - } - return resu; - } - catch { } - } - throw new MetadataException("Obj is :" + lcObj.GetType() + " and look like:" + lcObj.ToString()); - } - - /// - /// Will try to transform the string in date.
- /// Will use all date format found in DATE_FORMATS - ///
- /// the date to parse - /// the date found or today if none found (today because null is not a date in C#) - private static DateTime ParseDate(string aDate) - { - if (aDate == null || aDate.Trim().Length == 0) - { - return DateTime.Today; - } - for (int i = 0; i < DATE_FORMATS.Length; i++) - { - try - { - DateTime res = DateTime.Today; - if (DateTime.TryParseExact(aDate, DATE_FORMATS[i], null, DateTimeStyles.None, out res)) - { - return res; - } - } - catch (FormatException) - { - Debug.Write("Date '" + aDate + "' does not match patern '" + DATE_FORMATS[i] + "', will try an other one"); - } - } - // If we get here it means that no format worked. - return DateTime.Today; - } - - - /// - /// Returns the specified tag value as a rational, if possible. - /// - /// the specified tag type - /// the specified tag value as a rational, if possible. - public Rational GetRational(int aTagType) - { - object lcObj = GetObject(aTagType); - if (lcObj == null) - { - throw new MetadataException( - "Tag " - + GetTagName(aTagType) - + " has not been set -- check using containsTag() first"); - } - else if (lcObj is Rational) - { - return (Rational) lcObj; - } - throw new MetadataException("Obj is :" + lcObj.GetType().Name + " and look like:" + lcObj.ToString()); - } - - /// - /// Gets the specified tag value as a rational array, if possible. Only supported where the tag is set as Rational[]. - /// - /// the tag identifier - /// the tag value as a rational array - /// if tag not found or if it cannot be represented as a rational[] - public Rational[] GetRationalArray(int aTagType) - { - object lcObj = GetObject(aTagType); - if (lcObj == null) - { - throw new MetadataException( - "Tag " - + GetTagName(aTagType) - + " has not been set -- check using containsTag() first"); - } - else if (lcObj is Rational[]) - { - return (Rational[]) lcObj; - } - throw new MetadataException("Obj is :" + lcObj.GetType().Name + " and look like:" + lcObj.ToString()); - } - - /// - /// Returns the specified tag value as a string. - /// This value is the 'raw' value. - /// A more presentable decoding of this value may be obtained from the corresponding Descriptor. - /// - /// the specified tag type - /// the string reprensentation of the tag value, or null if the tag hasn't been defined. - public string GetString(int aTagType) - { - - object lcObj = GetObject(aTagType); - if (lcObj == null) - { - return null; - } - else if (lcObj is Rational) - { - return ((Rational) lcObj).ToSimpleString(true); - } - else if (lcObj.GetType().IsArray) - { - string lcStr = lcObj.GetType().ToString(); - - int lcArrayLength = 0; - - if (lcStr.IndexOf("Int")!=-1) - { - // handle arrays of objects and primitives - lcArrayLength = ((int[])lcObj).Length; - } - else if (lcStr.IndexOf("Rational")!=-1) - { - lcArrayLength = ((Rational[])lcObj).Length; - } - else if (lcStr.IndexOf("string")!=-1 || lcStr.IndexOf("String")!=-1) - { - lcArrayLength = ((string[])lcObj).Length; - } - - StringBuilder lcBuff = new StringBuilder(); - for (int i = 0; i < lcArrayLength; i++) - { - if (i != 0) - { - lcBuff.Append(' '); - } - if (lcStr.IndexOf("Int")!=-1) - { - lcBuff.Append(((int[])lcObj)[i].ToString()); - } - else if (lcStr.IndexOf("Rational")!=-1) - { - lcBuff.Append(((Rational[])lcObj)[i].ToString()); - } - else if (lcStr.IndexOf("string")!=-1 || lcStr.IndexOf("String")!=-1) - { - lcBuff.Append(((string[])lcObj)[i].ToString()); - } - } - return lcBuff.ToString(); - } - return lcObj.ToString(); - } - - /// - /// Returns the object hashed for the particular tag type specified, if available. - /// - /// the tag type identifier - /// the tag value as an object if available, else null - public object GetObject(int aTagType) - { - if (this.tagMap.ContainsKey(aTagType)) - { - return this.tagMap[aTagType]; - } - return null; - } - - /// - /// Returns the name of a specified tag as a string. - /// - /// the tag type identifier - /// the tag name as a string - public string GetTagName(int aTagType) - { - if (!AbstractDirectory.tagNameMap[this.GetType()].ContainsKey(aTagType)) - { - StringBuilder buff = new StringBuilder(32); - buff.Append("Unknown tag (0x"); - string lcHex = aTagType.ToString("X"); - for (int i = 0; i < 4 - lcHex.Length; i++) - { - buff.Append('0'); - } - return buff.Append(lcHex).Append(')').ToString(); - } - return AbstractDirectory.tagNameMap[this.GetType()][aTagType]; - } - - /// - /// Provides a description of a tag value using the descriptor set by setDescriptor(Descriptor). - /// - /// the tag type identifier - /// the tag value'str description as a string - /// if a descriptor hasn't been set, or if an error occurs during calculation of the description within the Descriptor - public string GetDescription(int aTagType) - { - if (this.descriptor == null) - { - throw new MetadataException("A descriptor must be set using setDescriptor(...) before descriptions can be provided"); - } - - return this.descriptor.GetDescription(aTagType); - } - - /// - /// Provides the name of the directory, for display purposes. E.g. Exif - /// - /// the name of the directory - public string GetName() - { - return ResourceBundleFactory.CreateDefaultBundle(this.BundleName)["MARKER_NOTE_NAME"]; - } - - /// - /// Fill the map with all (TAG_xxx value, BUNDLE[TAG_xxx name]). - /// - /// where to look for fields like TAG_xxx - /// where to put tag found - protected static IDictionary FillTagMap(Type aType, IResourceBundle aBundle) - { - FieldInfo[] lcAllContTag = aType.GetFields(); - IDictionary lcResu = new Dictionary(lcAllContTag.Length); - for (int i = 0; i < lcAllContTag.Length; i++) - { - string lcMemberName = lcAllContTag[i].Name; - if (lcAllContTag[i].IsPublic && lcMemberName.StartsWith("TAG_")) - { - int lcMemberValue = (int)lcAllContTag[i].GetValue(null); - try - { - lcResu.Add(lcMemberValue, aBundle[lcMemberName]); - } - catch (MissingResourceException mre) - { - Trace.TraceError("Could not find the key '" + aType + "' for type '" + lcMemberName + "' (" + mre.Message + ")"); - } - } - } - return lcResu; - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/AbstractMetadataReader.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/AbstractMetadataReader.cs deleted file mode 100644 index 6ea68ac541..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/AbstractMetadataReader.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System; -using System.Collections; -using System.IO; -using com.drew.lang; -using com.drew.metadata; -using com.drew.imaging.jpg; -using com.utils; -using System.Diagnostics; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata -{ - /// - /// An abstract reader class - /// - public abstract class AbstractMetadataReader : IMetadataReader - { - /// - /// The data segment - /// - protected readonly byte[] data; - - /// - /// Creates a new Reader for the specified file. - /// - /// where to read - protected AbstractMetadataReader(FileInfo aFile, byte aSegment) - : this( - new JpegSegmentReader(aFile).ReadSegment( - aSegment)) - { - } - - /// - /// Constructor of the object - /// - /// the data to read - protected AbstractMetadataReader(byte[] aData) - { - this.data = aData; - } - - /// - /// Performs the data extraction, returning a new instance of Metadata. - /// - /// a new instance of Metadata - public Metadata Extract() - { - return Extract(new Metadata()); - } - - /// - /// Extracts aMetadata - /// - /// where to add aMetadata - /// the aMetadata found - public abstract Metadata Extract(Metadata metadata); - - /// - /// Returns an int calculated from two bytes of data at the specified lcOffset (MSB, LSB). - /// - /// position within the data buffer to read first byte - /// the 32 bit int value, between 0x0000 and 0xFFFF - protected virtual int Get32Bits(int anOffset) - { - if (anOffset >= this.data.Length) - { - throw new MetadataException("Attempt to read bytes from outside Iptc data buffer"); - } - return ((this.data[anOffset] & 255) << 8) | (this.data[anOffset + 1] & 255); - } - - /// - /// Returns an int calculated from one byte of data at the specified lcOffset. - /// - /// position within the data buffer to read byte - /// the 16 bit int value, between 0x00 and 0xFF - protected virtual int Get16Bits(int anOffset) - { - if (anOffset >= this.data.Length) - { - throw new MetadataException("Attempt to read bytes from outside Jpeg segment data buffer"); - } - - return (this.data[anOffset] & 255); - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/AbstractTagDescriptor.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/AbstractTagDescriptor.cs deleted file mode 100644 index 7105123476..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/AbstractTagDescriptor.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.IO; -using System.Collections; -using com.utils.bundle; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata -{ - /// - /// This abstract class represent the mother class of all tag descriptor. - /// - [Serializable] - public abstract class AbstractTagDescriptor - { - /// - /// Contains all commons words. - /// - protected static readonly IResourceBundle BUNDLE = ResourceBundleFactory.CreateDefaultBundle("Commons"); - - protected AbstractDirectory directory; - - /// - /// Constructor of the object - /// - /// a directory - public AbstractTagDescriptor(AbstractDirectory aDirectory) : base() - { - this.directory = aDirectory; - } - - /// - /// Returns a descriptive value of the the specified tag for this image. - /// Where possible, known values will be substituted here in place of the raw tokens actually - /// kept in the Exif segment. - /// If no substitution is available, the value provided by GetString(int) will be returned. - /// This and GetString(int) are the only 'get' methods that won't throw an exception. - /// - /// the tag to find a description for - /// a description of the image'str value for the specified tag, or null if the tag hasn't been defined. - public abstract string GetDescription(int aTagType); - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/IMetadataReader.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/IMetadataReader.cs deleted file mode 100644 index 542937dea4..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/IMetadataReader.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.IO; -using System.Text; -using System.Collections; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata -{ - /// - /// This interface represents a Metadata reader object - /// - public interface IMetadataReader - { - /// - /// Extracts aMetadata - /// - /// the aMetadata found - Metadata Extract(); - - /// - /// Extracts aMetadata - /// - /// where to add aMetadata - /// the aMetadata found - Metadata Extract(Metadata aMetadata); - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/Metadata.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/Metadata.cs deleted file mode 100644 index 689c216c00..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/Metadata.cs +++ /dev/null @@ -1,136 +0,0 @@ -using System; -using System.IO; -using System.Text; -using System.Collections; -using System.Collections.Generic; -using System.Reflection; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// Created on 28 April 2002, 17:40 -/// Modified 04 Aug 2002 -/// - Adjusted javadoc -/// - Added -/// Modified 29 Oct 2002 (v1.2) -/// - Stored IFD directories in separate tag-spaces -/// - iterator() now returns an Iterator over a list of TagValue objects -/// - More get///Description() methods to detail GPS tags, among others -/// - Put spaces between words of tag name for presentation reasons (they had no significance in compound form) -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata -{ - [Serializable] - public sealed class Metadata : IEnumerable - { - - /// - /// Creates an Iterator over the tag types set against this image, preserving the - /// order in which they were set. Should the same tag have been set more than once, - /// it'str first position is maintained, even though the final value is used. - /// - /// an Iterator of tag types set for this image - IEnumerator IEnumerable.GetEnumerator() - { - return GetDirectoryIterator(); - } - - /// - /// Creates an Iterator over the tag types set against this image, preserving the - /// order in which they were set. Should the same tag have been set more than once, - /// it'str first position is maintained, even though the final value is used. - /// - /// an Iterator of tag types set for this image - IEnumerator IEnumerable.GetEnumerator() - { - return GetDirectoryIterator(); - } - - private IDictionary directoryMap; - - /// - /// Creates a new instance of Metadata. - /// - public Metadata() : base() - { - this.directoryMap = new Dictionary(); - } - - /// - /// Creates an Iterator over the tag types set against this image, preserving the - /// order in which they were set. Should the same tag have been set more than once, - /// it'str first position is maintained, even though the final value is used. - /// - /// an Iterator of tag types set for this image - public IEnumerator GetDirectoryIterator() - { - return this.directoryMap.Values.GetEnumerator(); - } - - /// - /// Gets a directory regarding its type - /// - /// the type you are looking for - /// the directory found - /// if aType is not a Directory like class - public AbstractDirectory GetDirectory(string aTypeStr) - { - Type aType = Type.GetType(aTypeStr); - if (!Type.GetType("com.drew.metadata.AbstractDirectory").IsAssignableFrom(aType)) - { - throw new ArgumentException("Class type passed to GetDirectory must be an implementation of com.drew.metadata.AbstractDirectory"); - } - - // check if we've already issued this type of directory - if (this.ContainsDirectory(aType)) - { - return directoryMap[aType]; - } - AbstractDirectory lcDirectory = null; - try - { - ConstructorInfo[] lcConstructor = aType.GetConstructors(); - lcDirectory = (AbstractDirectory) lcConstructor[0].Invoke(null); - } - catch (Exception e) - { - throw new SystemException( - "Cannot instantiate provided Directory type: " - + aType, e); - } - // store the directory in case it'str requested later - this.directoryMap.Add(aType, lcDirectory); - - return lcDirectory; - } - - /// - /// Indicates whether a given directory type has been created in this aMetadata repository. - /// Directories are created by calling getDirectory(Class). - /// - /// the Directory type - /// true if the aMetadata directory has been created - public bool ContainsDirectory(Type aType) - { - return this.directoryMap.ContainsKey(aType); - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/MetadataException.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/MetadataException.cs deleted file mode 100644 index b9d090e458..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/MetadataException.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using com.drew.lang; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata -{ - /// - /// This class represents a Metadata exception - /// - public class MetadataException : CompoundException - { - /// - /// Constructor of the object - /// - /// The error aMessage - public MetadataException(string aMessage) : base(aMessage) - { - } - - /// - /// Constructor of the object - /// - /// The error aMessage - /// The aCause of the exception - public MetadataException(string aMessage, Exception aCause) : base(aMessage, aCause) - { - } - - /// - /// Constructor of the object - /// - /// The aCause of the exception - public MetadataException(Exception aCause) - : base(aCause.Message, aCause) - { - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/Tag.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/Tag.cs deleted file mode 100644 index ef695d9aae..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/Tag.cs +++ /dev/null @@ -1,151 +0,0 @@ -using System; -using System.IO; -using System.Text; -using com.drew.metadata.exif; -using com.drew.metadata.iptc; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata -{ - /// - /// This class represent a basic tag - /// - [Serializable] - public class Tag - { - private int tagType; - private AbstractDirectory directory; - - /// - /// Constructor of the object - /// - /// the type of this tag - /// the directory of this tag - public Tag(int aTagType, AbstractDirectory aDirectory) : base() - { - this.tagType = aTagType; - this.directory = aDirectory; - } - - /// - /// Gets the tag type as an int - /// - /// the tag type as an int - public int GetTagType() - { - return this.tagType; - } - - /// - /// Gets the tag type in hex notation as a string with padded leading zeroes if necessary (i.e. 0x100E). - /// - /// the tag type as a string in hexadecimal notation - public string GetTagTypeHex() - { - string lcHex = this.tagType.ToString("X"); - while (lcHex.Length < 4) - { - lcHex = "0" + lcHex; - } - return "0x" + lcHex; - } - - /// - /// Get a description of the tag'str value, considering enumerated values and units. - /// - /// a description of the tag'str value - public string GetDescription() - { - return this.directory.GetDescription(this.tagType); - } - - /// - /// Get the name of the tag, such as Aperture, or InteropVersion. - /// - /// the tag'str name - public string GetTagName() - { - return this.directory.GetTagName(this.tagType); - } - - /// - /// Gets the tag value. - /// - /// the tag value - public object GetTagValue() - { - object obj = this.directory.GetObject(this.tagType); - // In order to make the XML import/export work - // We need to handle Date manually - if (this.tagType == ExifDirectory.TAG_DATETIME - || this.tagType == ExifDirectory.TAG_DATETIME_DIGITIZED - || this.tagType == ExifDirectory.TAG_DATETIME_ORIGINAL - || this.tagType == IptcDirectory.TAG_DATE_CREATED) - { - try - { - return this.directory.GetDate(this.tagType); - } - catch (MetadataException) - { - // Do nothing - } - } - return obj; - } - - - /// - /// Get the name of the directory in which the tag exists, such as Exif, GPS or Interoperability. - /// - /// name of the directory in which this tag exists - public string GetDirectoryName() - { - return this.directory.GetName(); - } - - /// - /// A basic representation of the tag'str type and value in format: FNumber - F2.8. - /// - /// the tag'str type and value - public override string ToString() - { - string lcDescription = null; - try - { - lcDescription = this.GetDescription(); - } - catch (MetadataException ) - { - lcDescription = - this.directory.GetString(GetTagType()) - + " (unable to formulate description)"; - } - StringBuilder buff = new StringBuilder(64); - buff.Append('[').Append(this.directory.GetName()); - buff.Append(']').Append(this.GetTagName()); - buff.Append(" - ").Append(lcDescription); - return buff.ToString(); - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/AbstractCasioTypeDirectory.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/AbstractCasioTypeDirectory.cs deleted file mode 100644 index e82d7ec38a..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/AbstractCasioTypeDirectory.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using com.drew.metadata; -using com.drew.lang; -using com.utils.bundle; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// Mother class for all CasioMarkerNote directory. - /// - public abstract class AbstractCasioTypeDirectory : AbstractDirectory - { - /// - /// Creates a new Directory. - /// - /// bundle name for this directory - protected AbstractCasioTypeDirectory(string aBundleName) - : base(aBundleName) - { - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/AbstractNikonTypeDirectory.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/AbstractNikonTypeDirectory.cs deleted file mode 100644 index 23d5e58bc1..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/AbstractNikonTypeDirectory.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using com.drew.metadata; -using com.drew.lang; -using com.utils.bundle; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// Class for all Nikon directory. - /// - public abstract class AbstractNikonTypeDirectory : AbstractDirectory - { - /// - /// Creates a new Directory. - /// - /// bundle name for this directory - protected AbstractNikonTypeDirectory(string aBundleName) - : base(aBundleName) - { - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/CanonDescriptor.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/CanonDescriptor.cs deleted file mode 100644 index 12a03fce7e..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/CanonDescriptor.cs +++ /dev/null @@ -1,1147 +0,0 @@ -using System; -using com.drew.metadata; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// Tag descriptor for a Canon camera - /// - public class CanonDescriptor : AbstractTagDescriptor - { - /// - /// Constructor of the object - /// - /// a directory - public CanonDescriptor(AbstractDirectory aDirectory) : base(aDirectory) - { - } - - /// - /// Returns a descriptive value of the the specified tag for this image. - /// Where possible, known values will be substituted here in place of the raw tokens actually - /// kept in the Exif segment. - /// If no substitution is available, the value provided by GetString(int) will be returned. - /// This and GetString(int) are the only 'get' methods that won't throw an exception. - /// - /// the tag to find a description for - /// a description of the image'str value for the specified tag, or null if the tag hasn't been defined. - public override string GetDescription(int aTagType) - { - switch(aTagType) - { - case CanonDirectory.TAG_CANON_STATE1_MACRO_MODE: - return this.GetMacroModeDescription(); - case CanonDirectory.TAG_CANON_STATE1_SELF_TIMER_DELAY: - return this.GetSelfTimerDelayDescription(); - case CanonDirectory.TAG_CANON_STATE1_FLASH_MODE: - return this.GetFlashModeDescription(); - case CanonDirectory.TAG_CANON_STATE1_CONTINUOUS_DRIVE_MODE: - return this.GetContinuousDriveModeDescription(); - case CanonDirectory.TAG_CANON_STATE1_FOCUS_MODE_1: - return this.GetFocusMode1Description(); - case CanonDirectory.TAG_CANON_STATE1_IMAGE_SIZE: - return this.GetImageSizeDescription(); - case CanonDirectory.TAG_CANON_STATE1_EASY_SHOOTING_MODE: - return this.GetEasyShootingModeDescription(); - case CanonDirectory.TAG_CANON_STATE1_CONTRAST: - return this.GetContrastDescription(); - case CanonDirectory.TAG_CANON_STATE1_SATURATION: - return this.GetSaturationDescription(); - case CanonDirectory.TAG_CANON_STATE1_SHARPNESS: - return this.GetSharpnessDescription(); - case CanonDirectory.TAG_CANON_STATE1_ISO: - return this.GetIsoDescription(); - case CanonDirectory.TAG_CANON_STATE1_METERING_MODE: - return this.GetMeteringModeDescription(); - case CanonDirectory.TAG_CANON_STATE1_AF_POINT_SELECTED: - return this.GetAfPointSelectedDescription(); - case CanonDirectory.TAG_CANON_STATE1_EXPOSURE_MODE: - return this.GetExposureModeDescription(); - case CanonDirectory.TAG_CANON_STATE1_LONG_FOCAL_LENGTH: - return this.GetLongFocalLengthDescription(); - case CanonDirectory.TAG_CANON_STATE1_SHORT_FOCAL_LENGTH: - return this.GetShortFocalLengthDescription(); - case CanonDirectory.TAG_CANON_STATE1_FOCAL_UNITS_PER_MM: - return this.GetFocalUnitsPerMillimetreDescription(); - case CanonDirectory.TAG_CANON_STATE1_FLASH_DETAILS: - return this.GetFlashDetailsDescription(); - case CanonDirectory.TAG_CANON_STATE1_FOCUS_MODE_2: - return this.GetFocusMode2Description(); - case CanonDirectory.TAG_CANON_STATE2_WHITE_BALANCE: - return this.GetWhiteBalanceDescription(); - case CanonDirectory.TAG_CANON_STATE2_AF_POINT_USED: - return this.GetAfPointUsedDescription(); - case CanonDirectory.TAG_CANON_STATE2_FLASH_BIAS: - return this.GetFlashBiasDescription(); - - case CanonDirectory.TAG_CANON_STATE1_FLASH_ACTIVITY: - return this.GetFlashActivityDescription(); - case CanonDirectory.TAG_CANON_STATE1_FOCUS_TYPE: - return this.GetFocusTypeDescription(); - case CanonDirectory.TAG_CANON_STATE1_DIGITAL_ZOOM: - return this.GetDigitalZoomDescription(); - case CanonDirectory.TAG_CANON_STATE1_QUALITY: - return this.GetQualityDescription(); - case CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_LONG_EXPOSURE_NOISE_REDUCTION: - return this.GetLongExposureNoiseReductionDescription(); - case CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_SHUTTER_AUTO_EXPOSURE_LOCK_BUTTONS: - return this.GetShutterAutoExposureLockButtonDescription(); - case CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_MIRROR_LOCKUP: - return this.GetMirrorLockupDescription(); - case CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_TV_AV_AND_EXPOSURE_LEVEL: - return this.GetTvAndAvExposureLevelDescription(); - case CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_AF_ASSIST_LIGHT: - return this.GetAutoFocusAssistLightDescription(); - case CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_SHUTTER_SPEED_IN_AV_MODE: - return this.GetShutterSpeedInAvModeDescription(); - case CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_BRACKETTING: - return this.GetAutoExposureBrackettingSequenceAndAutoCancellationDescription(); - case CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_SHUTTER_CURTAIN_SYNC: - return this.GetShutterCurtainSyncDescription(); - case CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_AF_STOP: - return this.GetLensAutoFocusStopButtonDescription(); - case CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_FILL_FLASH_REDUCTION: - return this.GetFillFlashReductionDescription(); - case CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_MENU_BUTTON_RETURN: - return this.GetMenuButtonReturnPositionDescription(); - case CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_SET_BUTTON_FUNCTION: - return this.GetSetButtonFunctionWhenShootingDescription(); - case CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_SENSOR_CLEANING: - return this.GetSensorCleaningDescription(); - default: - return base.directory.GetString(aTagType); - } - } - - /// - /// Returns the menu button return position Description. - /// - /// the menu button return position Description. - private string GetMenuButtonReturnPositionDescription() - { - if (!base.directory.ContainsTag(CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_MENU_BUTTON_RETURN)) - { - return null; - } - int lcVal = base.directory.GetInt(CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_MENU_BUTTON_RETURN); - switch (lcVal) - { - case 0: return BUNDLE["TOP"]; - case 1: return BUNDLE["PREVIOUS_VOLATILE"]; - case 2: return BUNDLE["PREVIOUS"]; - default: return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns the set button function when shooting Description. - /// - /// the set button function when shooting Description. - private string GetSetButtonFunctionWhenShootingDescription() - { - if (!base.directory.ContainsTag(CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_SET_BUTTON_FUNCTION)) - { - return null; - } - int lcVal = base.directory.GetInt(CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_SET_BUTTON_FUNCTION); - switch (lcVal) - { - case 0: return BUNDLE["NOT_ASSIGNED"]; - case 1: return BUNDLE["CHANGE_QUALITY"]; - case 2: return BUNDLE["CHANGE_ISO_SPEED"]; - case 3: return BUNDLE["SELECT_PARAMETERS"]; - default: return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns the sensor cleaning Description. - /// - /// the sensor cleaning Description. - private string GetSensorCleaningDescription() - { - if (!base.directory.ContainsTag(CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_SENSOR_CLEANING)) - { - return null; - } - int lcVal = base.directory.GetInt(CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_SENSOR_CLEANING); - switch (lcVal) - { - case 0: return BUNDLE["DISABLED"]; - case 1: return BUNDLE["ENABLED"]; - default: return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns the fill flash reduction Description. - /// - /// the fill flash reduction Description. - private string GetFillFlashReductionDescription() - { - if (!base.directory.ContainsTag(CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_FILL_FLASH_REDUCTION)) - { - return null; - } - int lcVal = base.directory.GetInt(CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_FILL_FLASH_REDUCTION); - switch (lcVal) - { - case 0: return BUNDLE["ENABLED"]; - case 1: return BUNDLE["DISABLED"]; - default: return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns the lens auto focus stop Description. - /// - /// the lens auto focus stop Description. - private string GetLensAutoFocusStopButtonDescription() - { - if (!base.directory.ContainsTag(CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_AF_STOP)) - { - return null; - } - int lcVal = base.directory.GetInt(CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_AF_STOP); - switch (lcVal) - { - case 0: return BUNDLE["AF_STOP"]; - case 1: return BUNDLE["OPERATE_AF"]; - case 2: return BUNDLE["LOCK_AE_AND_START_TIMER"]; - default: return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns the shutter curtain sync Description. - /// - /// the shutter curtain sync Description. - private string GetShutterCurtainSyncDescription() - { - if (!base.directory.ContainsTag(CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_SHUTTER_CURTAIN_SYNC)) - { - return null; - } - int lcVal = base.directory.GetInt(CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_SHUTTER_CURTAIN_SYNC); - switch (lcVal) - { - case 0: return BUNDLE["1_CURTAIN_SYNC"]; - case 1: return BUNDLE["2_CURTAIN_SYNC"]; - default: return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns the auto exposure bracketting sequence and auto cancellation Description. - /// - /// the auto exposure bracketting sequence and auto cancellation Description. - private string GetAutoExposureBrackettingSequenceAndAutoCancellationDescription() - { - if (!base.directory.ContainsTag(CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_BRACKETTING)) - { - return null; - } - int lcVal = base.directory.GetInt(CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_BRACKETTING); - switch (lcVal) - { - case 0: return BUNDLE["0_M_P_ENABLED"]; - case 1: return BUNDLE["0_M_P_DISABLED"]; - case 2: return BUNDLE["M_0_P_ENABLED"]; - case 3: return BUNDLE["M_0_P_DISABLED"]; - default: return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns the shutter speed in Av mode Description. - /// - /// the shutter speed in Av mode Description. - private string GetShutterSpeedInAvModeDescription() - { - if (!base.directory.ContainsTag(CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_SHUTTER_SPEED_IN_AV_MODE)) - { - return null; - } - int lcVal = base.directory.GetInt(CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_SHUTTER_SPEED_IN_AV_MODE); - switch (lcVal) - { - case 0: return BUNDLE["AUTOMATIC"]; - case 1: return BUNDLE["1_200_FIXED"]; - default: return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns the auto focus assist light Description. - /// - /// the auto focus assist light Description. - private string GetAutoFocusAssistLightDescription() - { - if (!base.directory.ContainsTag(CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_AF_ASSIST_LIGHT)) - { - return null; - } - int lcVal = base.directory.GetInt(CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_AF_ASSIST_LIGHT); - switch (lcVal) - { - case 0: return BUNDLE["ON_AUTO"]; - case 1: return BUNDLE["OFF"]; - default: return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns the Tv and Av exposure level Description. - /// - /// the Tv and Av exposure level Description. - private string GetTvAndAvExposureLevelDescription() - { - if (!base.directory.ContainsTag(CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_TV_AV_AND_EXPOSURE_LEVEL)) - { - return null; - } - int lcVal = base.directory.GetInt(CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_TV_AV_AND_EXPOSURE_LEVEL); - switch (lcVal) - { - case 0: return BUNDLE["1_2_STOP"]; - case 1: return BUNDLE["1_2_STOP"]; - default: return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns the mirror lock up Description. - /// - /// the mirror lock up Description. - private string GetMirrorLockupDescription() - { - if (!base.directory.ContainsTag(CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_MIRROR_LOCKUP)) - { - return null; - } - int lcVal = base.directory.GetInt(CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_MIRROR_LOCKUP); - switch (lcVal) - { - case 0: return BUNDLE["DISABLED"]; - case 1: return BUNDLE["ENABLED"]; - default: return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns the shutter auto exposure lock button Description. - /// - /// the shutter auto exposure lock button Description. - private string GetShutterAutoExposureLockButtonDescription() - { - if (!base.directory.ContainsTag(CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_SHUTTER_AUTO_EXPOSURE_LOCK_BUTTONS)) - { - return null; - } - int lcVal = base.directory.GetInt(CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_SHUTTER_AUTO_EXPOSURE_LOCK_BUTTONS); - switch (lcVal) - { - case 0: return BUNDLE["AF_AE_LOCK"]; - case 1: return BUNDLE["AE_LOCK_AF"]; - case 2: return BUNDLE["AE_AF_LOCK"]; - case 3: return BUNDLE["AE_RELEASE_AE_AF"]; - default: return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns the long exposure noise reduction Description. - /// - /// the long exposure noise reduction Description. - private string GetLongExposureNoiseReductionDescription() - { - if (!base.directory.ContainsTag(CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_LONG_EXPOSURE_NOISE_REDUCTION)) - { - return null; - } - int lcVal = base.directory.GetInt(CanonDirectory.TAG_CANON_CUSTOM_FUNCTION_LONG_EXPOSURE_NOISE_REDUCTION); - switch (lcVal) - { - case 0: return BUNDLE["OFF"]; - case 1: return BUNDLE["ON"]; - default: return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns the quality Description. - /// - /// the quality Description. - private string GetQualityDescription() - { - if (!base.directory.ContainsTag(CanonDirectory.TAG_CANON_STATE1_QUALITY)) - { - return null; - } - int lcVal = base.directory.GetInt(CanonDirectory.TAG_CANON_STATE1_QUALITY); - switch (lcVal) - { - case 2: - return BUNDLE["NORMAL"]; - case 3: - return BUNDLE["FINE"]; - case 5: - return BUNDLE["SUPERFINE"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns the digital zoom Description. - /// - /// the digital zoom Description. - private string GetDigitalZoomDescription() - { - if (!base.directory.ContainsTag(CanonDirectory.TAG_CANON_STATE1_DIGITAL_ZOOM)) - { - return null; - } - int lcVal = base.directory.GetInt(CanonDirectory.TAG_CANON_STATE1_DIGITAL_ZOOM); - switch (lcVal) - { - case 0: - return BUNDLE["NO_DIGITAL_ZOOM"]; - case 1: - return BUNDLE["DIGITAL_ZOOM", "2"]; - case 2: - return BUNDLE["DIGITAL_ZOOM", "4"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns the focus type Description. - /// - /// the focus type Description. - private string GetFocusTypeDescription() - { - if (!base.directory.ContainsTag(CanonDirectory.TAG_CANON_STATE1_FOCUS_TYPE)) - { - return null; - } - int lcVal = base.directory.GetInt(CanonDirectory.TAG_CANON_STATE1_FOCUS_TYPE); - switch (lcVal) - { - case 0: - return BUNDLE["MANUAL"]; - case 1: - case 2: - return BUNDLE["AUTO"]; - case 3: - return BUNDLE["CLOSE_UP_MACRO"]; - case 8: - return BUNDLE["LOCKED_PAN_MODE"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns the Flash actvity Description. - /// - /// the Flash activity Description. - private string GetFlashActivityDescription() - { - if (!base.directory.ContainsTag(CanonDirectory.TAG_CANON_STATE1_FLASH_ACTIVITY)) - { - return null; - } - int lcVal = base.directory.GetInt(CanonDirectory.TAG_CANON_STATE1_FLASH_ACTIVITY); - switch (lcVal) - { - case 0: - return BUNDLE["FLASH_DID_NOT_FIRE"]; - case 1: - return BUNDLE["FLASH_FIRED"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - - /// - /// Returns the Flash Bias Description. - /// - /// the Flash Bias Description. - private string GetFlashBiasDescription() - { - if (!base.directory - .ContainsTag(CanonDirectory.TAG_CANON_STATE2_FLASH_BIAS)) - { - return null; - } - int lcVal = - base.directory.GetInt( - CanonDirectory.TAG_CANON_STATE2_FLASH_BIAS); - bool isNegative = false; - if (lcVal > 0xF000) - { - isNegative = true; - lcVal = 0xFFFF - lcVal; - lcVal++; - } - - // this tag is interesting in that the values returned are: - // 0, 0.375, 0.5, 0.626, 1 - // not - // 0, 0.33, 0.5, 0.66, 1 - return BUNDLE["FLASH_BIAS_NEW", ((isNegative) ? "-" : ""), (lcVal / 32.0).ToString()]; - } - - /// - /// Returns Af Point Used Description. - /// - /// the Af Point Used Description. - private string GetAfPointUsedDescription() - { - if (!base.directory - .ContainsTag( - CanonDirectory.TAG_CANON_STATE2_AF_POINT_USED)) - { - return null; - } - int lcVal = - base.directory.GetInt( - CanonDirectory.TAG_CANON_STATE2_AF_POINT_USED); - if ((lcVal & 0x7) == 0) - { - return BUNDLE["RIGHT"]; - } - else if ((lcVal & 0x7) == 1) - { - return BUNDLE["CENTER"];; - } - else if ((lcVal & 0x7) == 2) - { - return BUNDLE["LEFT"]; - } - else - { - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns White Balance Description. - /// - /// the White Balance Description. - private string GetWhiteBalanceDescription() - { - if (!base.directory - .ContainsTag( - CanonDirectory.TAG_CANON_STATE2_WHITE_BALANCE)) - return null; - int lcVal = - base.directory.GetInt( - CanonDirectory.TAG_CANON_STATE2_WHITE_BALANCE); - switch (lcVal) - { - case 0 : - return BUNDLE["AUTO"]; - case 1 : - return BUNDLE["SUNNY"]; - case 2 : - return BUNDLE["CLOUDY"]; - case 3 : - return BUNDLE["TUNGSTEN"]; - case 4 : - return BUNDLE["FLUORESCENT"]; - case 5 : - return BUNDLE["FLASH"]; - case 6 : - return BUNDLE["CUSTOM"]; - default : - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns Focus Mode 2 description. - /// - /// the Focus Mode 2 description - private string GetFocusMode2Description() - { - if (!base.directory - .ContainsTag(CanonDirectory.TAG_CANON_STATE1_FOCUS_MODE_2)) - { - return null; - } - int lcVal = - base.directory.GetInt( - CanonDirectory.TAG_CANON_STATE1_FOCUS_MODE_2); - switch (lcVal) - { - case 0 : - return BUNDLE["SINGLE"]; - case 1 : - return BUNDLE["CONTINUOUS"]; - default : - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns Flash Details description. - /// - /// the Flash Details description - private string GetFlashDetailsDescription() - { - if (!base.directory - .ContainsTag( - CanonDirectory.TAG_CANON_STATE1_FLASH_DETAILS)) - { - return null; - } - int lcVal = - base.directory.GetInt( - CanonDirectory.TAG_CANON_STATE1_FLASH_DETAILS); - if (((lcVal << 14) & 1) > 0) - { - return BUNDLE["EXTERNAL_E_TTL"]; - } - if (((lcVal << 13) & 1) > 0) - { - return BUNDLE["INTERNAL_FLASH"]; - } - if (((lcVal << 11) & 1) > 0) - { - return BUNDLE["FP_SYNC_USED"]; - } - if (((lcVal << 4) & 1) > 0) - { - return BUNDLE["FP_SYNC_ENABLED"]; - } - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - - /// - /// Returns Focal Units Per Millimetre description. - /// - /// the Focal Units Per Millimetre description - private string GetFocalUnitsPerMillimetreDescription() - { - if (!base.directory - .ContainsTag( - CanonDirectory.TAG_CANON_STATE1_FOCAL_UNITS_PER_MM)) - { - return ""; - } - int lcVal = - base.directory.GetInt( - CanonDirectory.TAG_CANON_STATE1_FOCAL_UNITS_PER_MM); - if (lcVal != 0) - { - return lcVal.ToString(); - } - return ""; - } - - /// - /// Returns Short Focal Length description. - /// - /// the Short Focal Length description - private string GetShortFocalLengthDescription() - { - if (!base.directory - .ContainsTag( - CanonDirectory.TAG_CANON_STATE1_SHORT_FOCAL_LENGTH)) - { - return null; - } - int lcVal = - base.directory.GetInt( - CanonDirectory.TAG_CANON_STATE1_SHORT_FOCAL_LENGTH); - string units = GetFocalUnitsPerMillimetreDescription(); - return BUNDLE["FOCAL_LENGTH", lcVal.ToString(), units]; - } - - /// - /// Returns Long Focal Length description. - /// - /// the Long Focal Length description - private string GetLongFocalLengthDescription() - { - if (!base.directory - .ContainsTag( - CanonDirectory.TAG_CANON_STATE1_LONG_FOCAL_LENGTH)) - { - return null; - } - int lcVal = - base.directory.GetInt( - CanonDirectory.TAG_CANON_STATE1_LONG_FOCAL_LENGTH); - string units = GetFocalUnitsPerMillimetreDescription(); - return BUNDLE["FOCAL_LENGTH", lcVal.ToString(), units]; - } - - /// - /// Returns Exposure Mode description. - /// - /// the Exposure Mode description - private string GetExposureModeDescription() - { - if (!base.directory - .ContainsTag( - CanonDirectory.TAG_CANON_STATE1_EXPOSURE_MODE)) - { - return null; - } - int lcVal = - base.directory.GetInt( - CanonDirectory.TAG_CANON_STATE1_EXPOSURE_MODE); - switch (lcVal) - { - case 0 : - return BUNDLE["EASY_SHOOTING"]; - case 1 : - return BUNDLE["PROGRAM"]; - case 2 : - return BUNDLE["TV_PRIORITY"]; - case 3 : - return BUNDLE["AV_PRIORITY"]; - case 4 : - return BUNDLE["MANUAL"]; - case 5 : - return BUNDLE["A_DEP"]; - default : - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns Af Point Selected description. - /// - /// the Af Point Selected description - private string GetAfPointSelectedDescription() - { - if (!base.directory - .ContainsTag( - CanonDirectory.TAG_CANON_STATE1_AF_POINT_SELECTED)) - { - return null; - } - int lcVal = - base.directory.GetInt( - CanonDirectory.TAG_CANON_STATE1_AF_POINT_SELECTED); - switch (lcVal) - { - case 0x3000 : - return BUNDLE["NONE_MF"]; - case 0x3001 : - return BUNDLE["AUTO_SELECTED"]; - case 0x3002 : - return BUNDLE["RIGHT"]; - case 0x3003 : - return BUNDLE["CENTER"]; - case 0x3004 : - return BUNDLE["LEFT"]; - default : - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns Metering Mode description. - /// - /// the Metering Mode description - private string GetMeteringModeDescription() - { - if (!base.directory - .ContainsTag( - CanonDirectory.TAG_CANON_STATE1_METERING_MODE)) - { - return null; - } - int lcVal = - base.directory.GetInt( - CanonDirectory.TAG_CANON_STATE1_METERING_MODE); - switch (lcVal) - { - case 3 : - return BUNDLE["EVALUATIVE"]; - case 4 : - return BUNDLE["PARTIAL"]; - case 5 : - return BUNDLE["CENTER_WEIGHTED"]; - default : - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns ISO description. - /// - /// the ISO description - private string GetIsoDescription() - { - if (!base.directory - .ContainsTag(CanonDirectory.TAG_CANON_STATE1_ISO)) - { - return null; - } - int lcVal = - base.directory.GetInt(CanonDirectory.TAG_CANON_STATE1_ISO); - switch (lcVal) - { - case 0 : - return BUNDLE["ISO_NOT_SPECIFIED"]; - case 15 : - return BUNDLE["AUTO"]; - case 16 : - return BUNDLE["ISO", "50"]; - case 17 : - return BUNDLE["ISO", "100"]; - case 18 : - return BUNDLE["ISO", "200"]; - case 19 : - return BUNDLE["ISO", "400"]; - default : - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns Sharpness description. - /// - /// the Sharpness description - private string GetSharpnessDescription() - { - if (!base.directory - .ContainsTag(CanonDirectory.TAG_CANON_STATE1_SHARPNESS)) - { - return null; - } - int lcVal = - base.directory.GetInt( - CanonDirectory.TAG_CANON_STATE1_SHARPNESS); - switch (lcVal) - { - case 0xFFFF : - return BUNDLE["LOW"]; - case 0x000 : - return BUNDLE["NORMAL"]; - case 0x001 : - return BUNDLE["HIGH"]; - default : - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns Saturation description. - /// - /// the Saturation description - private string GetSaturationDescription() - { - if (!base.directory - .ContainsTag(CanonDirectory.TAG_CANON_STATE1_SATURATION)) - { - return null; - } - int lcVal = - base.directory.GetInt( - CanonDirectory.TAG_CANON_STATE1_SATURATION); - switch (lcVal) - { - case 0xFFFF : - return BUNDLE["LOW"]; - case 0x000 : - return BUNDLE["NORMAL"]; - case 0x001 : - return BUNDLE["HIGH"]; - default : - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns Contrast description. - /// - /// the Contrast description - private string GetContrastDescription() - { - if (!base.directory - .ContainsTag(CanonDirectory.TAG_CANON_STATE1_CONTRAST)) - { - return null; - } - int lcVal = - base.directory.GetInt( - CanonDirectory.TAG_CANON_STATE1_CONTRAST); - switch (lcVal) - { - case 0xFFFF : - return BUNDLE["LOW"]; - case 0x000 : - return BUNDLE["NORMAL"]; - case 0x001 : - return BUNDLE["HIGH"]; - default : - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns Easy Shooting Mode description. - /// - /// the Easy Shooting Mode description - private string GetEasyShootingModeDescription() - { - if (!base.directory - .ContainsTag( - CanonDirectory.TAG_CANON_STATE1_EASY_SHOOTING_MODE)) - { - return null; - } - int lcVal = - base.directory.GetInt( - CanonDirectory.TAG_CANON_STATE1_EASY_SHOOTING_MODE); - switch (lcVal) - { - case 0 : - return BUNDLE["FULL_AUTO"]; - case 1 : - return BUNDLE["MANUAL"]; - case 2 : - return BUNDLE["LANDSCAPE"]; - case 3 : - return BUNDLE["FAST_SHUTTER"]; - case 4 : - return BUNDLE["SLOW_SHUTTER"]; - case 5 : - return BUNDLE["NIGHT"]; - case 6 : - return BUNDLE["BLACK_AND_WHITE"]; - case 7 : - return BUNDLE["SEPIA"]; - case 8 : - return BUNDLE["PORTRAIT"]; - case 9 : - return BUNDLE["SPORTS"]; - case 10 : - return BUNDLE["MACRO_CLOSEUP"]; - case 11 : - return BUNDLE["PAN_FOCUS"]; - default : - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns Image Size description. - /// - /// the Image Size description - private string GetImageSizeDescription() - { - if (!base.directory - .ContainsTag(CanonDirectory.TAG_CANON_STATE1_IMAGE_SIZE)) - { - return null; - } - int lcVal = - base.directory.GetInt( - CanonDirectory.TAG_CANON_STATE1_IMAGE_SIZE); - switch (lcVal) - { - case 0 : - return BUNDLE["LARGE"]; - case 1 : - return BUNDLE["MEDIUM"]; - case 2 : - return BUNDLE["SMALL"]; - default : - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns Focus Mode 1 description. - /// - /// the Focus Mode 1 description - private string GetFocusMode1Description() - { - if (!base.directory - .ContainsTag(CanonDirectory.TAG_CANON_STATE1_FOCUS_MODE_1)) - { - return null; - } - int lcVal = - base.directory.GetInt( - CanonDirectory.TAG_CANON_STATE1_FOCUS_MODE_1); - switch (lcVal) - { - case 0 : - return BUNDLE["ONE_SHOT"]; - case 1 : - return BUNDLE["AI_SERVO"]; - case 2 : - return BUNDLE["AI_FOCUS"]; - case 3 : - return BUNDLE["MF"]; - case 4 : - // TODO should check field 32 here (FOCUS_MODE_2) - return BUNDLE["SINGLE"]; - case 5 : - return BUNDLE["CONTINUOUS"]; - case 6 : - return BUNDLE["MF"]; - default : - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns Continuous Drive Mode description. - /// - /// the Continuous Drive Mode description - private string GetContinuousDriveModeDescription() - { - if (!base.directory - .ContainsTag( - CanonDirectory - .TAG_CANON_STATE1_CONTINUOUS_DRIVE_MODE)) - { - return null; - } - int lcVal = - base.directory.GetInt( - CanonDirectory.TAG_CANON_STATE1_CONTINUOUS_DRIVE_MODE); - switch (lcVal) - { - case 0 : - if (base.directory - .GetInt( - CanonDirectory - .TAG_CANON_STATE1_SELF_TIMER_DELAY) - == 0) - { - return BUNDLE["SINGLE_SHOT"]; - } - else - { - return BUNDLE["SINGLE_SHOT_WITH_SELF_TIMER"]; - } - case 1 : - return BUNDLE["CONTINUOUS"]; - default : - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns Flash Mode description. - /// - /// the Flash Mode description - private string GetFlashModeDescription() - { - if (!base.directory - .ContainsTag(CanonDirectory.TAG_CANON_STATE1_FLASH_MODE)) - { - return null; - } - int lcVal = - base.directory.GetInt( - CanonDirectory.TAG_CANON_STATE1_FLASH_MODE); - switch (lcVal) - { - case 0 : - return BUNDLE["NO_FLASH_FIRED"]; - case 1 : - return BUNDLE["AUTO"]; - case 2 : - return BUNDLE["ON"]; - case 3 : - return BUNDLE["RED_EYE_REDUCTION"]; - case 4 : - return BUNDLE["SLOW_SYNCHRO"]; - case 5 : - return BUNDLE["AUTO_AND_RED_EYE_REDUCTION"]; - case 6 : - return BUNDLE["ON_AND_RED_EYE_REDUCTION"]; - case 16 : - // note: this lcVal not set on Canon D30 - return BUNDLE["EXTERNAL_FLASH"]; - default : - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns Self Timer Delay description. - /// - /// the Self Timer Delay description - private string GetSelfTimerDelayDescription() - { - if (!base.directory - .ContainsTag( - CanonDirectory.TAG_CANON_STATE1_SELF_TIMER_DELAY)) - { - return null; - } - int lcVal = - base.directory.GetInt( - CanonDirectory.TAG_CANON_STATE1_SELF_TIMER_DELAY); - if (lcVal == 0) - { - return BUNDLE["SELF_TIMER_DELAY_NOT_USED"]; - } - // TODO find an image that tests this calculation - return BUNDLE["SELF_TIMER_DELAY", ((double) lcVal * 0.1d).ToString()]; - } - - /// - /// Returns Macro Mode description. - /// - /// the Macro Mode description - private string GetMacroModeDescription() - { - if (!base.directory - .ContainsTag(CanonDirectory.TAG_CANON_STATE1_MACRO_MODE)) - { - return null; - } - int lcVal = - base.directory.GetInt( - CanonDirectory.TAG_CANON_STATE1_MACRO_MODE); - switch (lcVal) - { - case 0: - return BUNDLE["OFF"]; - case 1 : - return BUNDLE["MACRO"]; - case 2 : - return BUNDLE["NORMAL"]; - default : - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/CanonDirectory.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/CanonDirectory.cs deleted file mode 100644 index 6185a13426..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/CanonDirectory.cs +++ /dev/null @@ -1,740 +0,0 @@ -using System; -using System.Reflection; -using System.Collections; -using System.Collections.Generic; -using com.drew.metadata; -using com.utils.bundle; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// This class represents CANON marker note. - /// - public class CanonDirectory : AbstractDirectory - { - // CANON cameras have some funny bespoke fields that need further processing... - public const int TAG_CANON_CAMERA_STATE_1 = 0x0001; - public const int TAG_CANON_CAMERA_STATE_2 = 0x0004; - - public const int TAG_CANON_IMAGE_TYPE = 0x0006; - public const int TAG_CANON_FIRMWARE_VERSION = 0x0007; - public const int TAG_CANON_IMAGE_NUMBER = 0x0008; - public const int TAG_CANON_OWNER_NAME = 0x0009; - /// - /// To display serial number as on camera use: printf( "%04X%05d", highbyte, lowbyte ) - /// TODO handle this in CanonMakernoteDescriptor - /// - public const int TAG_CANON_SERIAL_NUMBER = 0x000C; - /// - /// xb: 15.05.2008 -- http://owl.phy.queensu.ca/~phil/exiftool/TagNames/Canon.html#CameraSettings - /// Old State TAG_CANON_UNKNOWN_1 - /// - public const int TAG_CANON_CanonCameraInfo = 0x000D; - public const int TAG_CANON_CUSTOM_FUNCTIONS = 0x000F; - - // These 'sub'-tag values have been created for consistency -- they don't exist within the exif segment - /// - /// 1 = Macro - /// 2 = Normal - /// - public const int TAG_CANON_STATE1_MACRO_MODE = 0xC101; - public const int TAG_CANON_STATE1_SELF_TIMER_DELAY = 0xC102; - /// - /// 2 = Normal - /// 3 = Fine - /// 5 = Superfine - /// - public const int TAG_CANON_STATE1_QUALITY = 0xC103; - /// - /// 0 = Flash Not Fired - /// 1 = Auto - /// 2 = On - /// 3 = Red Eye Reduction - /// 4 = Slow Synchro - /// 5 = Auto + Red Eye Reduction - /// 6 = On + Red Eye Reduction - /// 16 = External Flash - /// - public const int TAG_CANON_STATE1_FLASH_MODE = 0xC104; - /// - /// 0 = Single Frame or Timer Mode - /// 1 = Continuous - /// - public const int TAG_CANON_STATE1_CONTINUOUS_DRIVE_MODE = 0xC105; - public const int TAG_CANON_STATE1_UNKNOWN_2 = 0xC106; - /// - /// 0 = One-Shot - /// 1 = AI Servo - /// 2 = AI Focus - /// 3 = Manual Focus - /// 4 = Single - /// 5 = Continuous - /// 6 = Manual Focus - /// - public const int TAG_CANON_STATE1_FOCUS_MODE_1 = 0xC107; - public const int TAG_CANON_STATE1_UNKNOWN_3 = 0xC108; - - /// - /// xb: 15.05.2008 -- http://owl.phy.queensu.ca/~phil/exiftool/TagNames/Canon.html#CameraSettings - /// Old State TAG_CANON_STATE1_UNKNOWN_4 - /// 1 = JPEG - /// 2 = CRW+THM - /// 3 = AVI+THM - /// 4 = TIF - /// 5 = TIF+JPEG - /// 6 = CR2 - /// 7 = CR2+JPEG - /// - public const int TAG_CANON_STATE1_RecordMode = 0xC109; - - /// - /// 0 = Large - /// 1 = Medium - /// 2 = Small - /// - public const int TAG_CANON_STATE1_IMAGE_SIZE = 0xC10A; - /// - /// 0 = Full Auto - /// 1 = Manual - /// 2 = Landscape - /// 3 = Fast Shutter - /// 4 = Slow Shutter - /// 5 = Night - /// 6 = Black & White - /// 7 = Sepia - /// 8 = Portrait - /// 9 = Sports - /// 10 = Macro / Close-Up - /// 11 = Pan Focus - /// - public const int TAG_CANON_STATE1_EASY_SHOOTING_MODE = 0xC10B; - /// - /// 0 = No Digital Zoom - /// 1 = 2x - /// 2 = 4x - /// - public const int TAG_CANON_STATE1_DIGITAL_ZOOM = 0xC10C; - /// - /// 0 = Normal - /// 1 = High - /// 65535 = Low - /// - public const int TAG_CANON_STATE1_CONTRAST = 0xC10D; - /// - /// 0 = Normal - /// 1 = High - /// 65535 = Low - /// - public const int TAG_CANON_STATE1_SATURATION = 0xC10E; - /// - /// 0 = Normal - /// 1 = High - /// 65535 = Low - /// - public const int TAG_CANON_STATE1_SHARPNESS = 0xC10F; - /// - /// 0 = Check ISOSpeedRatings EXIF tag for ISO Speed - /// 15 = Auto ISO - /// 16 = ISO 50 - /// 17 = ISO 100 - /// 18 = ISO 200 - /// 19 = ISO 400 - /// - public const int TAG_CANON_STATE1_ISO = 0xC110; - /// - /// 3 = Evaluative - /// 4 = Partial - /// 5 = Center Weighted - /// - public const int TAG_CANON_STATE1_METERING_MODE = 0xC111; - /// - /// 0 = Manual - /// 1 = Auto - /// 3 = Close-up (Macro) - /// 8 = Locked (Pan Mode) - /// - public const int TAG_CANON_STATE1_FOCUS_TYPE = 0xC112; - /// - /// 12288 = None (Manual Focus) - /// 12289 = Auto Selected - /// 12290 = Right - /// 12291 = Center - /// 12292 = Left - /// - public const int TAG_CANON_STATE1_AF_POINT_SELECTED = 0xC113; - /// - /// 0 = Easy Shooting (See Easy Shooting Mode) - /// 1 = Program - /// 2 = Tv-Priority - /// 3 = Av-Priority - /// 4 = Manual - /// 5 = A-DEP - /// - public const int TAG_CANON_STATE1_EXPOSURE_MODE = 0xC114; - public const int TAG_CANON_STATE1_UNKNOWN_7 = 0xC115; - /// - /// xb: 15.05.2008 -- http://owl.phy.queensu.ca/~phil/exiftool/TagNames/Canon.html#CameraSettings - /// Old State TAG_CANON_STATE1_UNKNOWN_8 - /// Canon LensType Values - /// 1 = Canon EF 50mm f/1.8 - /// 2 = Canon EF 28mm f/2.8 - /// 4 = Canon EF 35-105mm f/3.5-4.5 or Sigma UC Zoom 35-135mm f/4-5.6 - /// 6 = Tokina AF193-2 19-35mm f/3.5-4.5 or Sigma Lens - /// 7 = Canon EF 100-300mm f/5.6L - /// ...... - /// - public const int TAG_CANON_STATE1_LensType = 0xC116; - public const int TAG_CANON_STATE1_LONG_FOCAL_LENGTH = 0xC117; - public const int TAG_CANON_STATE1_SHORT_FOCAL_LENGTH = 0xC118; - public const int TAG_CANON_STATE1_FOCAL_UNITS_PER_MM = 0xC119; - /// - /// xb: 15.05.2008 -- http://owl.phy.queensu.ca/~phil/exiftool/TagNames/Canon.html#CameraSettings - /// Old State TAG_CANON_STATE1_UNKNOWN_10 - /// - public const int TAG_CANON_STATE1_MaxAperture = 0xC11A; - /// - /// xb: 15.05.2008 -- http://owl.phy.queensu.ca/~phil/exiftool/TagNames/Canon.html#CameraSettings - /// Old State TAG_CANON_STATE1_UNKNOWN_10 - /// - public const int TAG_CANON_STATE1_MinAperture = 0xC11B; - /// - /// 0 = Flash Did Not Fire - /// 1 = Flash Fired - /// - public const int TAG_CANON_STATE1_FLASH_ACTIVITY = 0xC11C; - public const int TAG_CANON_STATE1_FLASH_DETAILS = 0xC11D; - public const int TAG_CANON_STATE1_UNKNOWN_12 = 0xC11E; - public const int TAG_CANON_STATE1_UNKNOWN_13 = 0xC11F; - /// - /// 0 = Focus Mode: Single - /// 1 = Focus Mode: Continuous - /// - public const int TAG_CANON_STATE1_FOCUS_MODE_2 = 0xC120; - - /// - /// xb: 15.05.2008 -- http://owl.phy.queensu.ca/~phil/exiftool/TagNames/Canon.html#CameraSettings - /// New constante - /// - public const int TAG_CANON_STATE1_AESetting = 0xC121; - /// - /// xb: 15.05.2008 -- http://owl.phy.queensu.ca/~phil/exiftool/TagNames/Canon.html#CameraSettings - /// New constante - /// - public const int TAG_CANON_STATE1_ImageStabilization = 0xC122; - /// - /// xb: 15.05.2008 -- http://owl.phy.queensu.ca/~phil/exiftool/TagNames/Canon.html#CameraSettings - /// New constante - /// - public const int TAG_CANON_STATE1_DisplayAperture = 0xC123; - /// - /// xb: 15.05.2008 -- http://owl.phy.queensu.ca/~phil/exiftool/TagNames/Canon.html#CameraSettings - /// New constante - /// - public const int TAG_CANON_STATE1_ZoomSourceWidth = 0xC124; - /// - /// xb: 15.05.2008 -- http://owl.phy.queensu.ca/~phil/exiftool/TagNames/Canon.html#CameraSettings - /// New constante - /// - public const int TAG_CANON_STATE1_ZoomTargetWidth = 0xC125; - - /// - /// xb: 15.05.2008 -- http://owl.phy.queensu.ca/~phil/exiftool/TagNames/Canon.html#CameraSettings - /// New constante - /// - public const int TAG_CANON_STATE1_SpotMeteringMode = 0xC127; - /// - /// xb: 15.05.2008 -- http://owl.phy.queensu.ca/~phil/exiftool/TagNames/Canon.html#CameraSettings - /// New constante - /// - public const int TAG_CANON_STATE1_PhotoEffect = 0xC128; - /// - /// xb: 15.05.2008 -- http://owl.phy.queensu.ca/~phil/exiftool/TagNames/Canon.html#CameraSettings - /// New constante - /// - public const int TAG_CANON_STATE1_ManualFlashOutput = 0xC129; - /// - /// xb: 15.05.2008 -- http://owl.phy.queensu.ca/~phil/exiftool/TagNames/Canon.html#CameraSettings - /// New constante - /// - public const int TAG_CANON_STATE1_ColorTone = 0xC12A; - - /// - /// xb: 15.05.2008 -- http://owl.phy.queensu.ca/~phil/exiftool/TagNames/Canon.html#CameraSettings - /// New Tags - /// - public const int TAG_CANON_FocalLength_FocalType = 0xC401; - public const int TAG_CANON_FocalLength_FocalLength = 0xC402; - public const int TAG_CANON_FocalLength_FocalPlaneXSize = 0xC403; - public const int TAG_CANON_FocalLength_FocalPlaneYSize = 0xC404; - /// ============================================================================================= - - /// - /// 0 = Auto - /// 1 = Sunny - /// 2 = Cloudy - /// 3 = Tungsten - /// 4 = Fluorescent - /// 5 = Flash - /// 6 = Custom - /// - public const int TAG_CANON_STATE2_WHITE_BALANCE = 0xC207; - public const int TAG_CANON_STATE2_SEQUENCE_NUMBER = 0xC209; - public const int TAG_CANON_STATE2_AF_POINT_USED = 0xC20E; - /// - /// The value of this tag may be translated into a flash bias value, in EV. - /// - /// 0xffc0 = -2 EV - /// 0xffcc = -1.67 EV - /// 0xffd0 = -1.5 EV - /// 0xffd4 = -1.33 EV - /// 0xffe0 = -1 EV - /// 0xffec = -0.67 EV - /// 0xfff0 = -0.5 EV - /// 0xfff4 = -0.33 EV - /// 0x0000 = 0 EV - /// 0x000c = 0.33 EV - /// 0x0010 = 0.5 EV - /// 0x0014 = 0.67 EV - /// 0x0020 = 1 EV - /// 0x002c = 1.33 EV - /// 0x0030 = 1.5 EV - /// 0x0034 = 1.67 EV - /// 0x0040 = 2 EV - /// - public const int TAG_CANON_STATE2_FLASH_BIAS = 0xC20F; - public const int TAG_CANON_STATE2_AUTO_EXPOSURE_BRACKETING = 0xC210; - public const int TAG_CANON_STATE2_AEB_BRACKET_VALUE = 0xC211; - public const int TAG_CANON_STATE2_SUBJECT_DISTANCE = 0xC213; - - /// - /// Long Exposure Noise Reduction - /// 0 = Off - /// 1 = On - /// - public const int TAG_CANON_CUSTOM_FUNCTION_LONG_EXPOSURE_NOISE_REDUCTION = 0xC301; - - /// - /// Shutter/Auto Exposure-lock buttons - /// 0 = AF/AE lock - /// 1 = AE lock/AF - /// 2 = AF/AF lock - /// 3 = AE+release/AE+AF - /// - public const int TAG_CANON_CUSTOM_FUNCTION_SHUTTER_AUTO_EXPOSURE_LOCK_BUTTONS = 0xC302; - - /// - /// Mirror lockup - /// 0 = Disable - /// 1 = Enable - /// - public const int TAG_CANON_CUSTOM_FUNCTION_MIRROR_LOCKUP = 0xC303; - - /// - /// Tv/Av and exposure level - /// 0 = 1/2 stop - /// 1 = 1/3 stop - /// - public const int TAG_CANON_CUSTOM_FUNCTION_TV_AV_AND_EXPOSURE_LEVEL = 0xC304; - - /// - /// AF-assist light - /// 0 = On (Auto) - /// 1 = Off - /// - public const int TAG_CANON_CUSTOM_FUNCTION_AF_ASSIST_LIGHT = 0xC305; - - /// - /// Shutter speed in Av mode - /// 0 = Automatic - /// 1 = 1/200 (fixed) - /// - public const int TAG_CANON_CUSTOM_FUNCTION_SHUTTER_SPEED_IN_AV_MODE = 0xC306; - - /// - /// Auto-Exposure Bracketting sequence/auto cancellation - /// 0 = 0,-,+ / Enabled - /// 1 = 0,-,+ / Disabled - /// 2 = -,0,+ / Enabled - /// 3 = -,0,+ / Disabled - /// - public const int TAG_CANON_CUSTOM_FUNCTION_BRACKETTING = 0xC307; - - /// - /// Shutter Curtain Sync - /// 0 = 1st Curtain Sync - /// 1 = 2nd Curtain Sync - /// - public const int TAG_CANON_CUSTOM_FUNCTION_SHUTTER_CURTAIN_SYNC = 0xC308; - - /// - /// Lens Auto-Focus stop button Function Switch - /// 0 = AF stop - /// 1 = Operate AF - /// 2 = Lock AE and start timer - /// - public const int TAG_CANON_CUSTOM_FUNCTION_AF_STOP = 0xC309; - - /// - /// Auto reduction of fill flash - /// 0 = Enable - /// 1 = Disable - /// - public const int TAG_CANON_CUSTOM_FUNCTION_FILL_FLASH_REDUCTION = 0xC30A; - - /// - /// Menu button return position - /// 0 = Top - /// 1 = Previous (volatile) - /// 2 = Previous - /// - public const int TAG_CANON_CUSTOM_FUNCTION_MENU_BUTTON_RETURN = 0xC30B; - - /// - /// SET button function when shooting - /// 0 = Not Assigned - /// 1 = Change Quality - /// 2 = Change ISO Speed - /// 3 = Select Parameters - /// - public const int TAG_CANON_CUSTOM_FUNCTION_SET_BUTTON_FUNCTION = 0xC30C; - - /// - /// Sensor cleaning - /// 0 = Disable - /// 1 = Enable - /// - public const int TAG_CANON_CUSTOM_FUNCTION_SENSOR_CLEANING = 0xC30D; - - /// - /// Constructor of the object. - /// - public CanonDirectory() - : base("CanonMarkernote") - { - base.SetDescriptor(new CanonDescriptor(this)); - } - - // ============================================================================================== - // xb: 15.05.2008 -- http://owl.phy.queensu.ca/~phil/exiftool/TagNames/Canon.html#CameraSettings - // New Tags - // ============================================================================================== - - /// - /// --> Canon FocalLength Tags - /// - public const int TAG_CANON_FocalLength = 0x0002; - - /// - /// --> Canon CanonModelID Values - /// - public const int TAG_CANON_CanonModelID = 0x0010; - /// - /// --> Canon AFInfo Tags - /// - public const int TAG_CANON_CanonAFInfo = 0x0012; - // public const int TAG_CANON_ThumbnailImageValidArea = 0x0013; // int16u[4] (all zeros for full frame) - /// - /// 0x90000000 = Format 1 - /// 0xa0000000 = Format 2 - /// - public const int TAG_CANON_SerialNumberFormat = 0x0015; - /// - /// N 0 = Off - /// 1 = On (1) - /// 2 = On (2) - /// - public const int TAG_CANON_SuperMacro = 0x001a; - /// - /// (only used in postcard mode) - /// 0 = Off - /// 1 = Date - /// 2 = Date & Time - /// - public const int TAG_CANON_DateStampMode = 0x001c; - /// - /// --> Canon MyColors Tags - /// - public const int TAG_CANON_MyColors = 0x001d; - public const int TAG_CANON_FirmwareRevision = 0x001e; - /// - /// --> Canon FaceDetect1 Tags - /// - public const int TAG_CANON_FaceDetect1 = 0x0024; - /// - /// --> Canon FaceDetect2 Tags - /// - public const int TAG_CANON_FaceDetect2 = 0x0025; - /// - /// --> Canon AFInfo2 Tags - /// - public const int TAG_CANON_CanonAFInfo2 = 0x0026; - public const int TAG_CANON_RawDataOffset = 0x0081; - public const int TAG_CANON_OriginalDecisionDataOffset = 0x0083; - /// - /// --> CanonCustom Functions1D Tags - /// - public const int TAG_CANON_CustomFunctions1D = 0x0090; - /// - /// --> CanonCustom PersonalFuncs Tags - /// - public const int TAG_CANON_PersonalFunctions = 0x0091; - /// - /// --> CanonCustom PersonalFuncValues Tags - /// - public const int TAG_CANON_PersonalFunctionValues = 0x0092; - /// - /// --> Canon FileInfo Tags - /// - public const int TAG_CANON_CanonFileInfo = 0x0093; - /// - /// (EOS 1D -- 5 rows: A1-7, B1-10, C1-11, D1-10, E1-7, center point is C6) - /// - public const int TAG_CANON_AFPointsInFocus1D = 0x0094; - public const int TAG_CANON_LensType = 0x0095; - /// - /// --> Canon SerialInfo Tags - /// - public const int TAG_CANON_InternalSerialNumber = 0x0096; - public const int TAG_CANON_DustRemovalData = 0x0097; - /// - /// --> CanonCustom Functions2 Tags - /// - public const int TAG_CANON_CustomFunctions2 = 0x0099; - /// - /// --> Canon Processing Tags - /// - public const int TAG_CANON_ProcessingInfo = 0x00a0; - public const int TAG_CANON_ToneCurveTable = 0x00a1; - public const int TAG_CANON_SharpnessTable = 0x00a2; - public const int TAG_CANON_SharpnessFreqTable = 0x00a3; - public const int TAG_CANON_WhiteBalanceTable = 0x00a4; - /// - /// --> Canon ColorBalance Tags - /// - public const int TAG_CANON_ColorBalance = 0x00a9; - public const int TAG_CANON_ColorTemperature = 0x00ae; - /// - /// --> Canon Flags Tags - /// - public const int TAG_CANON_CanonFlags = 0x00b0; - /// - /// --> Canon ModifiedInfo Tags - /// - public const int TAG_CANON_ModifiedInfo = 0x00b1; - public const int TAG_CANON_ToneCurveMatching = 0x00b2; - public const int TAG_CANON_WhiteBalanceMatching = 0x00b3; - /// - /// 1 = sRGB - /// 2 = Adobe RGB - /// - public const int TAG_CANON_ColorSpace = 0x00b4; - /// - /// --> Canon PreviewImageInfo Tags - /// - public const int TAG_CANON_PreviewImageInfo = 0x00b6; - /// - /// (offset of VRD "recipe data" if it exists) - /// - public const int TAG_CANON_VRDOffset = 0x00d0; - /// - /// --> Canon SensorInfo Tags - /// - public const int TAG_CANON_SensorInfo = 0x00e0; - /// - /// --> Canon ColorBalance1 Tags - /// --> Canon ColorBalance2 Tags - /// --> Canon ColorBalance3 Tags - /// --> Canon ColorBalance4 Tags - /// - public const int TAG_CANON_ColorBalance1to4 = 0x4001; - public const int TAG_CANON_UnknownBlock1 = 0x4002; - /// - /// --> Canon ColorInfo Tags - /// - public const int TAG_CANON_ColorInfo = 0x4003; - public const int TAG_CANON_UnknownBlock2 = 0x4005; - public const int TAG_CANON_BlackLevel = 0x4008; - - public const int TAG_CANON_STATE2_AutoISO = 0xC201; - public const int TAG_CANON_STATE2_BaseISO = 0xC202; - public const int TAG_CANON_STATE2_MeasuredEV = 0xC203; - public const int TAG_CANON_STATE2_TargetAperture = 0xC204; - public const int TAG_CANON_STATE2_TargetExposureTime = 0xC205; - public const int TAG_CANON_STATE2_ExposureCompensation = 0xC206; - /// - /// 0 = Off - /// 1 = Night Scene - /// 2 = On - /// 3 = None - /// - public const int TAG_CANON_STATE2_SlowShutter = 0xC208; - public const int TAG_CANON_STATE2_OpticalZoomCode = 0xC20A; - public const int TAG_CANON_STATE2_FlashGuideNumber = 0xC212; - public const int TAG_CANON_STATE2_ControlMode = 0xC20D; - public const int TAG_CANON_STATE2_FocusDistanceLower = 0xC214; - public const int TAG_CANON_STATE2_FNumber = 0xC215; - public const int TAG_CANON_STATE2_ExposureTime = 0xC216; - public const int TAG_CANON_STATE2_BulbDuration = 0xC218; - public const int TAG_CANON_STATE2_CameraType = 0xC21A; - public const int TAG_CANON_STATE2_AutoRotate = 0xC21B; - public const int TAG_CANON_STATE2_NDFilter = 0xC21C; - public const int TAG_CANON_STATE2_SelfTimer2 = 0xC21D; - public const int TAG_CANON_STATE2_FlashOutput = 0xC221; - - - /// - /// 0 = Standard - /// 1 = Manual - /// 2 = Custom - /// - public const int TAG_CANON_ProcessingInfo_ToneCurve = 0xC501; - /// - /// (1D and 5D only) - /// - public const int TAG_CANON_ProcessingInfo_Sharpness = 0xC502; - /// - /// 0 = n/a - /// 1 = Lowest - /// 2 = Low - /// 3 = Standard - /// 4 = High - /// 5 = Highest - /// - public const int TAG_CANON_ProcessingInfo_SharpnessFrequency = 0xC503; - public const int TAG_CANON_ProcessingInfo_SensorRedLevel = 0xC504; - public const int TAG_CANON_ProcessingInfo_SensorBlueLevel = 0xC505; - public const int TAG_CANON_ProcessingInfo_WhiteBalanceRed = 0xC506; - public const int TAG_CANON_ProcessingInfo_WhiteBalanceBlue = 0xC507; - /// - /// --> Canon WhiteBalance Values - /// - public const int TAG_CANON_ProcessingInfo_WhiteBalance = 0xC508; - public const int TAG_CANON_ProcessingInfo_ColorTemperature = 0xC509; - /// - /// --> Canon PictureStyle Values - /// - public const int TAG_CANON_ProcessingInfo_PictureStyle = 0xC50a; - public const int TAG_CANON_ProcessingInfo_DigitalGain = 0xC50b; - /// - /// (positive is a shift toward amber) - /// - public const int TAG_CANON_ProcessingInfo_WBShiftAB = 0xC50c; - /// - /// (positive is a shift toward green) - /// - public const int TAG_CANON_ProcessingInfo_WBShiftGM = 0xC50d; - - public const int TAG_CANON_SensorInfo_SensorWidth = 0xC601; - public const int TAG_CANON_SensorInfo_SensorHeight = 0xC602; - public const int TAG_CANON_SensorInfo_SensorLeftBorder = 0xC605; - public const int TAG_CANON_SensorInfo_SensorTopBorder = 0xC606; - public const int TAG_CANON_SensorInfo_SensorRightBorder = 0xC607; - public const int TAG_CANON_SensorInfo_SensorBottomBorder = 0xC608; - public const int TAG_CANON_SensorInfo_BlackMaskLeftBorder = 0xC609; - public const int TAG_CANON_SensorInfo_BlackMaskTopBorder = 0xC60a; - public const int TAG_CANON_SensorInfo_BlackMaskRightBorder = 0xC60b; - public const int TAG_CANON_SensorInfo_BlackMaskBottomBorder = 0xC60c; - - // xb: 15.05.2008 - // ============================================================================================= - - /// - /// We need special handling for selected tags. - /// - /// the tag type - /// what to set - public override void SetIntArray(int tagType, int[] ints) - { - if (tagType == TAG_CANON_CAMERA_STATE_1) - { - // this single tag has multiple values within - int subTagTypeBase = 0xC100; - // we intentionally skip the first array member - for (int i = 1; i < ints.Length; i++) - { - base.SetObject(subTagTypeBase + i, ints[i]); - } - } - else if (tagType == TAG_CANON_CAMERA_STATE_2) - { - // this single tag has multiple values within - int subTagTypeBase = 0xC200; - // we intentionally skip the first array member - for (int i = 1; i < ints.Length; i++) - { - base.SetObject(subTagTypeBase + i, ints[i]); - } - } - - /// xb: 15.05.2008 -- http://owl.phy.queensu.ca/~phil/exiftool/TagNames/Canon.html#CameraSettings - else if (tagType == TAG_CANON_FocalLength) - { - // this single tag has multiple values within - int subTagTypeBase = 0xC400; - // we intentionally skip the first array member - for (int i = 0; i < ints.Length; i++) - { - base.SetObject(subTagTypeBase + i+1, ints[i]); - } - } - else if (tagType == TAG_CANON_ProcessingInfo) - { - // this single tag has multiple values within - int subTagTypeBase = 0xC500; - // we intentionally skip the first array member - for (int i = 1; i < ints.Length; i++) - { - base.SetObject(subTagTypeBase + i, ints[i]); - } - } - else if (tagType == TAG_CANON_SensorInfo) - { - // this single tag has multiple values within - int subTagTypeBase = 0xC600; - // we intentionally skip the first array member - for (int i = 1; i < ints.Length; i++) - { - base.SetObject(subTagTypeBase + i, ints[i]); - } - } - /// xb: 15.05.2008 - - if (tagType == TAG_CANON_CUSTOM_FUNCTIONS) - { - // this single tag has multiple values within - int subTagTypeBase = 0xC300; - // we intentionally skip the first array member - for (int i = 1; i < ints.Length; i++) - { - base.SetObject(subTagTypeBase + i + 1, ints[i] & 0x0F); - } - } - else - { - // no special handling... - base.SetIntArray(tagType, ints); - } - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/CasioType1Descriptor.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/CasioType1Descriptor.cs deleted file mode 100644 index 360b0fdc62..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/CasioType1Descriptor.cs +++ /dev/null @@ -1,440 +0,0 @@ -using System; -using System.Collections; -using com.drew.metadata; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// Tag descriptor for a casio camera - /// - public class CasioType1Descriptor : AbstractTagDescriptor - { - /// - /// Constructor of the object - /// - /// a base.directory - public CasioType1Descriptor(AbstractDirectory aDirectory) : base(aDirectory) - { - } - - /// - /// Returns a descriptive value of the the specified tag for this image. - /// Where possible, known values will be substituted here in place of the raw tokens actually - /// kept in the Exif segment. - /// If no substitution is available, the value provided by GetString(int) will be returned. - /// This and GetString(int) are the only 'get' methods that won't throw an exception. - /// - /// the tag to find a description for - /// a description of the image'str value for the specified tag, or null if the tag hasn't been defined. - public override string GetDescription(int aTagType) - { - switch(aTagType) - { - case CasioType1Directory.TAG_CASIO_RECORDING_MODE: - return this.GetRecordingModeDescription(); - case CasioType1Directory.TAG_CASIO_QUALITY: - return this.GetQualityDescription(); - case CasioType1Directory.TAG_CASIO_FOCUSING_MODE: - return this.GetFocusingModeDescription(); - case CasioType1Directory.TAG_CASIO_FLASH_MODE: - return this.GetFlashModeDescription(); - case CasioType1Directory.TAG_CASIO_FLASH_INTENSITY: - return this.GetFlashIntensityDescription(); - case CasioType1Directory.TAG_CASIO_OBJECT_DISTANCE: - return this.GetObjectDistanceDescription(); - case CasioType1Directory.TAG_CASIO_WHITE_BALANCE: - return this.GetWhiteBalanceDescription(); - case CasioType1Directory.TAG_CASIO_DIGITAL_ZOOM: - return this.GetDigitalZoomDescription(); - case CasioType1Directory.TAG_CASIO_SHARPNESS: - return this.GetSharpnessDescription(); - case CasioType1Directory.TAG_CASIO_CONTRAST: - return this.GetContrastDescription(); - case CasioType1Directory.TAG_CASIO_SATURATION: - return this.GetSaturationDescription(); - case CasioType1Directory.TAG_CASIO_CCD_SENSITIVITY: - return GetCcdSensitivityDescription(); - default : - return base.directory.GetString(aTagType); - } - } - - /// - /// Returns the Ccd Sensitivity Description. - /// - /// the Ccd Sensitivity Description. - private string GetCcdSensitivityDescription() - { - if (!base.directory - .ContainsTag(CasioType1Directory.TAG_CASIO_CCD_SENSITIVITY)) - { - return null; - } - int lcVal = - base.directory.GetInt( - CasioType1Directory.TAG_CASIO_CCD_SENSITIVITY); - switch (lcVal) - { - // these four for QV3000 - case 64 : - return BUNDLE["NORMAL"]; - case 125 : - return BUNDLE["CCD_P_1"]; - case 250 : - return BUNDLE["CCD_P_2"]; - case 244 : - return BUNDLE["CCD_P_3"]; - // these two for QV8000/2000 - case 80 : - return BUNDLE["NORMAL"]; - case 100 : - return BUNDLE["HIGH"]; - default : - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns the saturation Description. - /// - /// the saturation Description. - private string GetSaturationDescription() - { - if (!base.directory - .ContainsTag(CasioType1Directory.TAG_CASIO_SATURATION)) - { - return null; - } - int lcVal = - base.directory.GetInt(CasioType1Directory.TAG_CASIO_SATURATION); - switch (lcVal) - { - case 0 : - return BUNDLE["NORMAL"]; - case 1 : - return BUNDLE["LOW"]; - case 2 : - return BUNDLE["HIGH"]; - default : - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns the contrast Description. - /// - /// the contrast Description. - private string GetContrastDescription() - { - if (!base.directory - .ContainsTag(CasioType1Directory.TAG_CASIO_CONTRAST)) - { - return null; - } - int lcVal = - base.directory.GetInt(CasioType1Directory.TAG_CASIO_CONTRAST); - switch (lcVal) - { - case 0 : - return BUNDLE["NORMAL"]; - case 1 : - return BUNDLE["LOW"]; - case 2 : - return BUNDLE["HIGH"]; - default : - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns the sharpness Description. - /// - /// the sharpness Description. - private string GetSharpnessDescription() - { - if (!base.directory - .ContainsTag(CasioType1Directory.TAG_CASIO_SHARPNESS)) - { - return null; - } - int lcVal = - base.directory.GetInt(CasioType1Directory.TAG_CASIO_SHARPNESS); - switch (lcVal) - { - case 0 : - return BUNDLE["NORMAL"]; - case 1 : - return BUNDLE["SOFT"];; - case 2 : - return BUNDLE["HARD"];; - default : - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns the Digital Zoom Description. - /// - /// the Digital Zoom Description. - private string GetDigitalZoomDescription() - { - if (!base.directory - .ContainsTag(CasioType1Directory.TAG_CASIO_DIGITAL_ZOOM)) - { - return null; - } - int lcVal = - base.directory.GetInt(CasioType1Directory.TAG_CASIO_DIGITAL_ZOOM); - switch (lcVal) - { - case 0x10000: - return BUNDLE["NO_DIGITAL_ZOOM"]; - case 0x10001: - case 0x20000: - return BUNDLE["DIGITAL_ZOOM", "2"]; - case 0x40000: - return BUNDLE["DIGITAL_ZOOM", "4"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns the White Balance Description. - /// - /// the White Balance Description. - private string GetWhiteBalanceDescription() - { - if (!base.directory - .ContainsTag(CasioType1Directory.TAG_CASIO_WHITE_BALANCE)) - { - return null; - } - int lcVal = - base.directory.GetInt(CasioType1Directory.TAG_CASIO_WHITE_BALANCE); - switch (lcVal) - { - case 1 : - return BUNDLE["AUTO"]; - case 2 : - return BUNDLE["TUNGSTEN"]; - case 3 : - return BUNDLE["DAYLIGHT"]; - case 4 : - return BUNDLE["FLUORESCENT"]; - case 5 : - return BUNDLE["SHADE"]; - case 129 : - return BUNDLE["MANUAL"]; - default : - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns the Object Distance Description. - /// - /// the Object Distance Description. - private string GetObjectDistanceDescription() - { - if (!base.directory - .ContainsTag(CasioType1Directory.TAG_CASIO_OBJECT_DISTANCE)) - { - return null; - } - int lcVal = - base.directory.GetInt( - CasioType1Directory.TAG_CASIO_OBJECT_DISTANCE); - return BUNDLE["DISTANCE_MM", lcVal.ToString()]; - } - - /// - /// Returns the Flash Intensity Description. - /// - /// the Flash Intensity Description. - private string GetFlashIntensityDescription() - { - if (!base.directory - .ContainsTag(CasioType1Directory.TAG_CASIO_FLASH_INTENSITY)) - { - return null; - } - int lcVal = - base.directory.GetInt( - CasioType1Directory.TAG_CASIO_FLASH_INTENSITY); - switch (lcVal) - { - case 11 : - return BUNDLE["WEAK"]; - case 13 : - return BUNDLE["NORMAL"]; - case 15 : - return BUNDLE["STRONG"]; - default : - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns the Flash Mode Description. - /// - /// the Flash Mode Description. - private string GetFlashModeDescription() - { - if (!base.directory - .ContainsTag(CasioType1Directory.TAG_CASIO_FLASH_MODE)) - { - return null; - } - int lcVal = - base.directory.GetInt(CasioType1Directory.TAG_CASIO_FLASH_MODE); - switch (lcVal) - { - case 1 : - return BUNDLE["AUTO"]; - case 2 : - return BUNDLE["ON"]; - case 3 : - return BUNDLE["OFF"]; - case 4 : - // this documented as additional value for off here: - // http://www.ozhiker.com/electronics/pjmt/jpeg_info/casio_mn.html - return BUNDLE["RED_EYE_REDUCTION"]; - default : - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns the Focusing Mode Description. - /// - /// the Focusing Mode Description. - private string GetFocusingModeDescription() - { - if (!base.directory - .ContainsTag(CasioType1Directory.TAG_CASIO_FOCUSING_MODE)) - { - return null; - } - int lcVal = - base.directory.GetInt(CasioType1Directory.TAG_CASIO_FOCUSING_MODE); - switch (lcVal) - { - case 2 : - return BUNDLE["MACRO"]; - case 3 : - return BUNDLE["AUTO_FOCUS"]; - case 4 : - return BUNDLE["MANUAL_FOCUS"]; - case 5 : - return BUNDLE["INFINITY"]; - default : - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns the quality Description. - /// - /// the quality Description. - private string GetQualityDescription() - { - if (!base.directory.ContainsTag(CasioType1Directory.TAG_CASIO_QUALITY)) - { - return null; - } - int lcVal = - base.directory.GetInt(CasioType1Directory.TAG_CASIO_QUALITY); - switch (lcVal) - { - case 1 : - return BUNDLE["ECONOMY"]; - case 2 : - return BUNDLE["NORMAL"]; - case 3 : - return BUNDLE["FINE"]; - default : - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns the Focussing Mode Description. - /// - /// the Focussing Mode Description. - private string GetFocussingModeDescription() - { - if (!base.directory - .ContainsTag(CasioType1Directory.TAG_CASIO_FOCUSING_MODE)) - { - return null; - } - int lcVal = - base.directory.GetInt(CasioType1Directory.TAG_CASIO_FOCUSING_MODE); - switch (lcVal) - { - case 2 : - return BUNDLE["MACRO"]; - case 3 : - return BUNDLE["AUTO_FOCUS"]; - case 4 : - return BUNDLE["MANUAL_FOCUS"]; - case 5 : - return BUNDLE["INFINITY"]; - default : - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns the Recording Mode Description. - /// - /// the Recording Mode Description. - private string GetRecordingModeDescription() - { - if (!base.directory - .ContainsTag(CasioType1Directory.TAG_CASIO_RECORDING_MODE)) - { - return null; - } - int lcVal = - base.directory.GetInt(CasioType1Directory.TAG_CASIO_RECORDING_MODE); - switch (lcVal) - { - case 1 : - return BUNDLE["SINGLE_SHUTTER"]; - case 2 : - return BUNDLE["PANORAMA"]; - case 3 : - return BUNDLE["NIGHT_SCENE"]; - case 4 : - return BUNDLE["PORTRAIT"]; - case 5 : - return BUNDLE["LANDSCAPE"]; - default : - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/CasioType1Directory.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/CasioType1Directory.cs deleted file mode 100644 index 45b45fef62..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/CasioType1Directory.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using com.drew.metadata; -using com.utils; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// This class represents CASIO marker note. - /// - public class CasioType1Directory : AbstractCasioTypeDirectory - { - public const int TAG_CASIO_RECORDING_MODE = 0x0001; - public const int TAG_CASIO_QUALITY = 0x0002; - public const int TAG_CASIO_FOCUSING_MODE = 0x0003; - public const int TAG_CASIO_FLASH_MODE = 0x0004; - public const int TAG_CASIO_FLASH_INTENSITY = 0x0005; - public const int TAG_CASIO_OBJECT_DISTANCE = 0x0006; - public const int TAG_CASIO_WHITE_BALANCE = 0x0007; - public const int TAG_CASIO_UNKNOWN_1 = 0x0008; - public const int TAG_CASIO_UNKNOWN_2 = 0x0009; - public const int TAG_CASIO_DIGITAL_ZOOM = 0x000A; - public const int TAG_CASIO_SHARPNESS = 0x000B; - public const int TAG_CASIO_CONTRAST = 0x000C; - public const int TAG_CASIO_SATURATION = 0x000D; - public const int TAG_CASIO_UNKNOWN_3 = 0x000E; - public const int TAG_CASIO_UNKNOWN_4 = 0x000F; - public const int TAG_CASIO_UNKNOWN_5 = 0x0010; - public const int TAG_CASIO_UNKNOWN_6 = 0x0011; - public const int TAG_CASIO_UNKNOWN_7 = 0x0012; - public const int TAG_CASIO_UNKNOWN_8 = 0x0013; - public const int TAG_CASIO_CCD_SENSITIVITY = 0x0014; - - /// - /// Constructor of the object. - /// - public CasioType1Directory() - : base("CasioMarkernote") - { - base.SetDescriptor(new CasioType1Descriptor(this)); - } - - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/CasioType2Descriptor.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/CasioType2Descriptor.cs deleted file mode 100644 index aef0b17636..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/CasioType2Descriptor.cs +++ /dev/null @@ -1,664 +0,0 @@ -using System; -using System.Collections; -using com.drew.metadata; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// Tag descriptor for a casio camera type 2 - /// - public class CasioType2Descriptor : AbstractTagDescriptor - { - /// - /// Constructor of the object - /// - /// a base.directory - public CasioType2Descriptor(AbstractDirectory aDirectory) - : base(aDirectory) - { - } - - /// - /// Returns a descriptive value of the the specified tag for this image. - /// Where possible, known values will be substituted here in place of the raw tokens actually - /// kept in the Exif segment. - /// If no substitution is available, the value provided by GetString(int) will be returned. - /// This and GetString(int) are the only 'get' methods that won't throw an exception. - /// - /// the tag to find a description for - /// a description of the image'str value for the specified tag, or null if the tag hasn't been defined. - public override string GetDescription(int aTagType) - { - switch (aTagType) - { - case CasioType2Directory.TAG_CASIO_TYPE2_THUMBNAIL_DIMENSIONS: - return this.GetThumbnailDimensionsDescription(); - case CasioType2Directory.TAG_CASIO_TYPE2_THUMBNAIL_SIZE: - return this.GetThumbnailSizeDescription(); - case CasioType2Directory.TAG_CASIO_TYPE2_THUMBNAIL_OFFSET: - return this.GetThumbnailOffsetDescription(); - case CasioType2Directory.TAG_CASIO_TYPE2_QUALITY_MODE: - return this.GetQualityModeDescription(); - case CasioType2Directory.TAG_CASIO_TYPE2_IMAGE_SIZE: - return this.GetImageSizeDescription(); - case CasioType2Directory.TAG_CASIO_TYPE2_FOCUS_MODE_1: - return this.GetFocusMode1Description(); - case CasioType2Directory.TAG_CASIO_TYPE2_ISO_SENSITIVITY: - return this.GetIsoSensitivityDescription(); - case CasioType2Directory.TAG_CASIO_TYPE2_WHITE_BALANCE_1: - return this.GetWhiteBalance1Description(); - case CasioType2Directory.TAG_CASIO_TYPE2_FOCAL_LENGTH: - return this.GetFocalLengthDescription(); - case CasioType2Directory.TAG_CASIO_TYPE2_SATURATION: - return this.GetSaturationDescription(); - case CasioType2Directory.TAG_CASIO_TYPE2_CONTRAST: - return this.GetContrastDescription(); - case CasioType2Directory.TAG_CASIO_TYPE2_SHARPNESS: - return this.GetSharpnessDescription(); - case CasioType2Directory.TAG_CASIO_TYPE2_PRINT_IMAGE_MATCHING_INFO: - return this.GetPrintImageMatchingInfoDescription(); - case CasioType2Directory.TAG_CASIO_TYPE2_CASIO_PREVIEW_THUMBNAIL: - return this.GetCasioPreviewThumbnailDescription(); - case CasioType2Directory.TAG_CASIO_TYPE2_WHITE_BALANCE_BIAS: - return this.GetWhiteBalanceBiasDescription(); - case CasioType2Directory.TAG_CASIO_TYPE2_WHITE_BALANCE_2: - return this.GetWhiteBalance2Description(); - case CasioType2Directory.TAG_CASIO_TYPE2_OBJECT_DISTANCE: - return this.GetObjectDistanceDescription(); - case CasioType2Directory.TAG_CASIO_TYPE2_FLASH_DISTANCE: - return this.GetFlashDistanceDescription(); - case CasioType2Directory.TAG_CASIO_TYPE2_RECORD_MODE: - return this.GetRecordModeDescription(); - case CasioType2Directory.TAG_CASIO_TYPE2_SELF_TIMER: - return this.GetSelfTimerDescription(); - case CasioType2Directory.TAG_CASIO_TYPE2_QUALITY: - return this.GetQualityDescription(); - case CasioType2Directory.TAG_CASIO_TYPE2_FOCUS_MODE_2: - return this.GetFocusMode2Description(); - case CasioType2Directory.TAG_CASIO_TYPE2_TIME_ZONE: - return this.GetTimeZoneDescription(); - case CasioType2Directory.TAG_CASIO_TYPE2_BESTSHOT_MODE: - return this.GetBestShotModeDescription(); - case CasioType2Directory.TAG_CASIO_TYPE2_CCD_ISO_SENSITIVITY: - return this.GetCcdIsoSensitivityDescription(); - case CasioType2Directory.TAG_CASIO_TYPE2_COLOR_MODE: - return this.GetColorModeDescription(); - case CasioType2Directory.TAG_CASIO_TYPE2_ENHANCEMENT: - return this.GetEnhancementDescription(); - case CasioType2Directory.TAG_CASIO_TYPE2_FILTER: - return this.GetFilterDescription(); - default: - return base.directory.GetString(aTagType); - } - } - - /// - /// Returns filter Description. - /// - /// the filter Description. - private string GetFilterDescription() - { - if (!base.directory.ContainsTag(CasioType2Directory.TAG_CASIO_TYPE2_FILTER)) - { - return null; - } - int lcVal = base.directory.GetInt(CasioType2Directory.TAG_CASIO_TYPE2_FILTER); - switch (lcVal) - { - case 0: - return BUNDLE["OFF"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns enhancement Description. - /// - /// the enhancement Description. - private string GetEnhancementDescription() - { - if (!base.directory.ContainsTag(CasioType2Directory.TAG_CASIO_TYPE2_ENHANCEMENT)) - { - return null; - } - int lcVal = base.directory.GetInt(CasioType2Directory.TAG_CASIO_TYPE2_ENHANCEMENT); - switch (lcVal) - { - case 0: - return BUNDLE["OFF"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns color mode Description. - /// - /// the color mode Description. - private string GetColorModeDescription() - { - if (!base.directory.ContainsTag(CasioType2Directory.TAG_CASIO_TYPE2_COLOR_MODE)) - { - return null; - } - int lcVal = base.directory.GetInt(CasioType2Directory.TAG_CASIO_TYPE2_COLOR_MODE); - switch (lcVal) - { - case 0: - return BUNDLE["OFF"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns CCD ISO sensitivity Description. - /// - /// the CCD ISO sensitivity Description. - private string GetCcdIsoSensitivityDescription() - { - if (!base.directory.ContainsTag(CasioType2Directory.TAG_CASIO_TYPE2_CCD_ISO_SENSITIVITY)) - { - return null; - } - int lcVal = base.directory.GetInt(CasioType2Directory.TAG_CASIO_TYPE2_CCD_ISO_SENSITIVITY); - switch (lcVal) - { - case 0: - return BUNDLE["OFF"]; - case 1: - return BUNDLE["ON"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns best shot mode Description. - /// - /// the best shot mode Description. - private string GetBestShotModeDescription() - { - if (!base.directory.ContainsTag(CasioType2Directory.TAG_CASIO_TYPE2_BESTSHOT_MODE)) - { - return null; - } - int lcVal = base.directory.GetInt(CasioType2Directory.TAG_CASIO_TYPE2_BESTSHOT_MODE); - switch (lcVal) - { - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns time zone Description. - /// - /// the time zone Description. - private string GetTimeZoneDescription() - { - if (!base.directory.ContainsTag(CasioType2Directory.TAG_CASIO_TYPE2_TIME_ZONE)) - { - return null; - } - return base.directory.GetString(CasioType2Directory.TAG_CASIO_TYPE2_TIME_ZONE); - } - - /// - /// Returns focus mode 2 Description. - /// - /// the focus mode 2 Description. - private string GetFocusMode2Description() - { - if (!base.directory.ContainsTag(CasioType2Directory.TAG_CASIO_TYPE2_FOCUS_MODE_2)) - { - return null; - } - int lcVal = base.directory.GetInt(CasioType2Directory.TAG_CASIO_TYPE2_FOCUS_MODE_2); - switch (lcVal) - { - case 1: - return BUNDLE["FIXATION"]; - case 6: - return BUNDLE["MULTI_AREA_FOCUS"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns quality description Description. - /// - /// the quality description Description. - private string GetQualityDescription() - { - if (!base.directory.ContainsTag(CasioType2Directory.TAG_CASIO_TYPE2_QUALITY)) - { - return null; - } - int lcVal = base.directory.GetInt(CasioType2Directory.TAG_CASIO_TYPE2_QUALITY); - switch (lcVal) - { - case 3: - return BUNDLE["FINE"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns self timer Description. - /// - /// the self timer Description. - private string GetSelfTimerDescription() - { - if (!base.directory.ContainsTag(CasioType2Directory.TAG_CASIO_TYPE2_SELF_TIMER)) - { - return null; - } - int lcVal = base.directory.GetInt(CasioType2Directory.TAG_CASIO_TYPE2_SELF_TIMER); - switch (lcVal) - { - case 1: - return BUNDLE["OFF"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns record mode Description. - /// - /// the record mode Description. - private string GetRecordModeDescription() - { - if (!base.directory.ContainsTag(CasioType2Directory.TAG_CASIO_TYPE2_RECORD_MODE)) - { - return null; - } - int lcVal = base.directory.GetInt(CasioType2Directory.TAG_CASIO_TYPE2_RECORD_MODE); - switch (lcVal) - { - case 2: - return BUNDLE["NORMAL"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns flash distance Description. - /// - /// the flash distance Description. - private string GetFlashDistanceDescription() - { - if (!base.directory.ContainsTag(CasioType2Directory.TAG_CASIO_TYPE2_FLASH_DISTANCE)) - { - return null; - } - int lcVal = base.directory.GetInt(CasioType2Directory.TAG_CASIO_TYPE2_FLASH_DISTANCE); - switch (lcVal) - { - case 0: - return BUNDLE["OFF"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns object distance Description. - /// - /// the object distance Description. - private string GetObjectDistanceDescription() - { - if (!base.directory.ContainsTag(CasioType2Directory.TAG_CASIO_TYPE2_OBJECT_DISTANCE)) - { - return null; - } - int lcVal = base.directory.GetInt(CasioType2Directory.TAG_CASIO_TYPE2_OBJECT_DISTANCE); - return BUNDLE["DISTANCE_MM", lcVal.ToString()]; - } - - /// - /// Returns white balance 2 Description. - /// - /// the white balance 2 Description. - private string GetWhiteBalance2Description() - { - if (!base.directory.ContainsTag(CasioType2Directory.TAG_CASIO_TYPE2_WHITE_BALANCE_2)) - { - return null; - } - int lcVal = base.directory.GetInt(CasioType2Directory.TAG_CASIO_TYPE2_WHITE_BALANCE_2); - switch (lcVal) - { - case 0: - return BUNDLE["MANUAL"]; - case 1: - return BUNDLE["AUTO"]; // unsure about this - case 4: - return BUNDLE["FLASH"]; // unsure about this - case 12: - return BUNDLE["FLASH"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns white balance bias Description. - /// - /// the white balance bias Description. - private string GetWhiteBalanceBiasDescription() - { - if (!base.directory.ContainsTag(CasioType2Directory.TAG_CASIO_TYPE2_WHITE_BALANCE_BIAS)) - { - return null; - } - return base.directory.GetString(CasioType2Directory.TAG_CASIO_TYPE2_WHITE_BALANCE_BIAS); - } - - /// - /// Returns casio preview thumbnail Description. - /// - /// the casio preview thumbnail Description. - private string GetCasioPreviewThumbnailDescription() - { - if (!base.directory.ContainsTag(CasioType2Directory.TAG_CASIO_TYPE2_CASIO_PREVIEW_THUMBNAIL)) - { - return null; - } - byte[] lcBytes = base.directory.GetByteArray(CasioType2Directory.TAG_CASIO_TYPE2_CASIO_PREVIEW_THUMBNAIL); - return BUNDLE["BYTES_OF_IMAGE_DATA", lcBytes.Length.ToString()]; - } - - /// - /// Returns Print Image Matching Info Description. - /// - /// the Print Image Matching Info Description. - private string GetPrintImageMatchingInfoDescription() - { - // TODO research PIM specification http://www.ozhiker.com/electronics/pjmt/jpeg_info/pim.html - if (!base.directory.ContainsTag(CasioType2Directory.TAG_CASIO_TYPE2_PRINT_IMAGE_MATCHING_INFO)) - { - return null; - } - return base.directory.GetString(CasioType2Directory.TAG_CASIO_TYPE2_PRINT_IMAGE_MATCHING_INFO); - } - - /// - /// Returns sharpness description Description. - /// - /// the sharpness description Description. - private string GetSharpnessDescription() - { - if (!base.directory.ContainsTag(CasioType2Directory.TAG_CASIO_TYPE2_SHARPNESS)) - { - return null; - } - int lcVal = base.directory.GetInt(CasioType2Directory.TAG_CASIO_TYPE2_SHARPNESS); - switch (lcVal) - { - case 0: - return "-1"; - case 1: - return BUNDLE["NORMAL"]; - case 2: - return "+1"; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns contrast Description. - /// - /// the contrast Description. - private string GetContrastDescription() - { - if (!base.directory.ContainsTag(CasioType2Directory.TAG_CASIO_TYPE2_CONTRAST)) - { - return null; - } - int lcVal = base.directory.GetInt(CasioType2Directory.TAG_CASIO_TYPE2_CONTRAST); - switch (lcVal) - { - case 0: - return "-1"; - case 1: - return BUNDLE["NORMAL"]; - case 2: - return "+1"; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns saturation Description. - /// - /// the saturation Description. - private string GetSaturationDescription() - { - if (!base.directory.ContainsTag(CasioType2Directory.TAG_CASIO_TYPE2_SATURATION)) - { - return null; - } - int lcVal = base.directory.GetInt(CasioType2Directory.TAG_CASIO_TYPE2_SATURATION); - switch (lcVal) - { - case 0: - return "-1"; - case 1: - return BUNDLE["NORMAL"]; - case 2: - return "+1"; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns focal length Description. - /// - /// the focal length Description. - private string GetFocalLengthDescription() - { - if (!base.directory.ContainsTag(CasioType2Directory.TAG_CASIO_TYPE2_FOCAL_LENGTH)) return null; - double lcVal = base.directory.GetDouble(CasioType2Directory.TAG_CASIO_TYPE2_FOCAL_LENGTH); - return BUNDLE["DISTANCE_MM", (lcVal / 10.0).ToString()]; - } - - /// - /// Returns white balance 1 Description. - /// - /// the white balance 1 Description. - private string GetWhiteBalance1Description() - { - if (!base.directory.ContainsTag(CasioType2Directory.TAG_CASIO_TYPE2_WHITE_BALANCE_1)) - { - return null; - } - int lcVal = base.directory.GetInt(CasioType2Directory.TAG_CASIO_TYPE2_WHITE_BALANCE_1); - switch (lcVal) - { - case 0: - return BUNDLE["AUTO"]; - case 1: - return BUNDLE["DAYLIGHT"]; - case 2: - return BUNDLE["SHADE"]; - case 3: - return BUNDLE["TUNGSTEN"]; - case 4: - return BUNDLE["FLUORESCENT"]; - case 5: - return BUNDLE["MANUAL"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns ISO sensitivity Description. - /// - /// the ISO sensitivity Description. - private string GetIsoSensitivityDescription() - { - if (!base.directory.ContainsTag(CasioType2Directory.TAG_CASIO_TYPE2_ISO_SENSITIVITY)) - { - return null; - } - int lcVal = base.directory.GetInt(CasioType2Directory.TAG_CASIO_TYPE2_ISO_SENSITIVITY); - switch (lcVal) - { - case 3: - return BUNDLE["ISO", "50"]; - case 4: - return BUNDLE["ISO","64"]; - case 6: - return BUNDLE["ISO","100"]; - case 9: - return BUNDLE["ISO","200"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns focus mode 1 Description. - /// - /// the focus mode 1 Description. - private string GetFocusMode1Description() - { - if (!base.directory.ContainsTag(CasioType2Directory.TAG_CASIO_TYPE2_FOCUS_MODE_1)) - { - return null; - } - int lcVal = base.directory.GetInt(CasioType2Directory.TAG_CASIO_TYPE2_FOCUS_MODE_1); - switch (lcVal) - { - case 0: - return BUNDLE["NORMAL"]; - case 1: - return BUNDLE["MACRO"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns image size Description. - /// - /// the image size Description. - private string GetImageSizeDescription() - { - if (!base.directory.ContainsTag(CasioType2Directory.TAG_CASIO_TYPE2_IMAGE_SIZE)) - { - return null; - } - int lcVal = base.directory.GetInt(CasioType2Directory.TAG_CASIO_TYPE2_IMAGE_SIZE); - switch (lcVal) - { - case 0: return BUNDLE["PIXELS", "640 x 480"]; - case 4: return BUNDLE["PIXELS", "1600 x 1200"]; - case 5: return BUNDLE["PIXELS", "2048 x 1536"]; - case 20: return BUNDLE["PIXELS", "2288 x 1712"]; - case 21: return BUNDLE["PIXELS", "2592 x 1944"]; - case 22: return BUNDLE["PIXELS", "2304 x 1728"]; - case 36: return BUNDLE["PIXELS", "3008 x 2008"]; - default: return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns quality mode Description. - /// - /// the quality mode Description. - private string GetQualityModeDescription() - { - if (!base.directory.ContainsTag(CasioType2Directory.TAG_CASIO_TYPE2_QUALITY_MODE)) - { - return null; - } - int lcVal = base.directory.GetInt(CasioType2Directory.TAG_CASIO_TYPE2_QUALITY_MODE); - switch (lcVal) - { - case 1: - return BUNDLE["FINE"]; - case 2: - return BUNDLE["SUPERFINE"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns thumbnail lcOffset Description. - /// - /// the thumbnail lcOffset Description. - private string GetThumbnailOffsetDescription() - { - if (!base.directory.ContainsTag(CasioType2Directory.TAG_CASIO_TYPE2_THUMBNAIL_OFFSET)) - { - return null; - } - return base.directory.GetString(CasioType2Directory.TAG_CASIO_TYPE2_THUMBNAIL_OFFSET); - } - - /// - /// Returns thumbnail size Description. - /// - /// the thumbnail size Description. - private string GetThumbnailSizeDescription() - { - if (!base.directory.ContainsTag(CasioType2Directory.TAG_CASIO_TYPE2_THUMBNAIL_SIZE)) - { - return null; - } - int lcVal = base.directory.GetInt(CasioType2Directory.TAG_CASIO_TYPE2_THUMBNAIL_SIZE); - return BUNDLE["BYTES", lcVal.ToString()]; - } - - /// - /// Returns thumbnail dimension Description. - /// - /// the thumbnail dimension Description. - private string GetThumbnailDimensionsDescription() - { - if (!base.directory.ContainsTag(CasioType2Directory.TAG_CASIO_TYPE2_THUMBNAIL_DIMENSIONS)) - { - return null; - } - int[] lcDimensions = base.directory.GetIntArray(CasioType2Directory.TAG_CASIO_TYPE2_THUMBNAIL_DIMENSIONS); - if (lcDimensions.Length != 2) - { - return base.directory.GetString(CasioType2Directory.TAG_CASIO_TYPE2_THUMBNAIL_DIMENSIONS); - } - return BUNDLE["PIXELS_BI", lcDimensions[0].ToString(), lcDimensions[1].ToString()]; - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/CasioType2Directory.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/CasioType2Directory.cs deleted file mode 100644 index bece701495..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/CasioType2Directory.cs +++ /dev/null @@ -1,201 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using com.drew.metadata; -using com.utils; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// This class represents CASIO marker note type 2. - /// - public class CasioType2Directory : AbstractCasioTypeDirectory - { - /// - /// 2 values - x,y dimensions in pixels. - /// - public const int TAG_CASIO_TYPE2_THUMBNAIL_DIMENSIONS = 0x0002; - - /// - /// Size in bytes - /// - public const int TAG_CASIO_TYPE2_THUMBNAIL_SIZE = 0x0003; - - /// - /// Offset of Preview Thumbnail - /// - public const int TAG_CASIO_TYPE2_THUMBNAIL_OFFSET = 0x0004; - - /// - /// 1 = Fine - /// 2 = Super Fine - /// - public const int TAG_CASIO_TYPE2_QUALITY_MODE = 0x0008; - - /// - /// 0 = 640 x 480 pixels - /// 4 = 1600 x 1200 pixels - /// 5 = 2048 x 1536 pixels - /// 20 = 2288 x 1712 pixels - /// 21 = 2592 x 1944 pixels - /// 22 = 2304 x 1728 pixels - /// 36 = 3008 x 2008 pixels - /// - public const int TAG_CASIO_TYPE2_IMAGE_SIZE = 0x0009; - - /// - /// 0 = Normal - /// 1 = Macro - /// - public const int TAG_CASIO_TYPE2_FOCUS_MODE_1 = 0x000D; - - /// - /// 3 = 50 - /// 4 = 64 - /// 6 = 100 - /// 9 = 200 - /// - public const int TAG_CASIO_TYPE2_ISO_SENSITIVITY = 0x0014; - - /// - /// 0 = Auto - /// 1 = Daylight - /// 2 = Shade - /// 3 = Tungsten - /// 4 = Fluorescent - /// 5 = Manual - /// - public const int TAG_CASIO_TYPE2_WHITE_BALANCE_1 = 0x0019; - - /// - /// Units are tenths of a millimetre - /// - public const int TAG_CASIO_TYPE2_FOCAL_LENGTH = 0x001D; - - /// - /// 0 = -1 - /// 1 = Normal - /// 2 = +1 - /// - public const int TAG_CASIO_TYPE2_SATURATION = 0x001F; - - /// - /// 0 = -1 - /// 1 = Normal - /// 2 = +1 - /// - public const int TAG_CASIO_TYPE2_CONTRAST = 0x0020; - - /// - /// 0 = -1 - /// 1 = Normal - /// 2 = +1 - /// - public const int TAG_CASIO_TYPE2_SHARPNESS = 0x0021; - - /// - /// See PIM specification here: http://www.ozhiker.com/electronics/pjmt/jpeg_info/pim.html - /// - public const int TAG_CASIO_TYPE2_PRINT_IMAGE_MATCHING_INFO = 0x0E00; - - /// - /// Alternate thumbnail lcOffset - /// - public const int TAG_CASIO_TYPE2_CASIO_PREVIEW_THUMBNAIL = 0x2000; - - public const int TAG_CASIO_TYPE2_WHITE_BALANCE_BIAS = 0x2011; - - /// - /// 12 = Flash - /// 0 = Manual - /// 1 = Auto? - /// 4 = Flash? - /// - public const int TAG_CASIO_TYPE2_WHITE_BALANCE_2 = 0x2012; - - /// - /// Units are millimetres - /// - public const int TAG_CASIO_TYPE2_OBJECT_DISTANCE = 0x2022; - - /// - /// 0 = Off - /// - public const int TAG_CASIO_TYPE2_FLASH_DISTANCE = 0x2034; - - /// - /// 2 = Normal Mode - /// - public const int TAG_CASIO_TYPE2_RECORD_MODE = 0x3000; - - /// - /// 1 = Off? - /// - public const int TAG_CASIO_TYPE2_SELF_TIMER = 0x3001; - - /// - /// 3 = Fine - /// - public const int TAG_CASIO_TYPE2_QUALITY = 0x3002; - - /// - /// 1 = Fixation - /// 6 = Multi-Area Auto Focus - /// - public const int TAG_CASIO_TYPE2_FOCUS_MODE_2 = 0x3003; - - public const int TAG_CASIO_TYPE2_TIME_ZONE = 0x3006; - public const int TAG_CASIO_TYPE2_BESTSHOT_MODE = 0x3007; - - /// - /// 0 = Off - /// 1 = On? - /// - public const int TAG_CASIO_TYPE2_CCD_ISO_SENSITIVITY = 0x3014; - - /// - /// 0 = Off - /// - public const int TAG_CASIO_TYPE2_COLOR_MODE = 0x3015; - - /// - /// 0 = Off - /// - public const int TAG_CASIO_TYPE2_ENHANCEMENT = 0x3016; - - /// - /// 0 = Off - /// - public const int TAG_CASIO_TYPE2_FILTER = 0x3017; - - /// - /// Constructor of the object. - /// - public CasioType2Directory() - : base("CasioMarkernote") - { - base.SetDescriptor(new CasioType2Descriptor(this)); - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/ExifDescriptor.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/ExifDescriptor.cs deleted file mode 100644 index 8e4803bf84..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/ExifDescriptor.cs +++ /dev/null @@ -1,1594 +0,0 @@ -using System; -using System.Collections; -using System.Text; -using com.drew.metadata; -using com.drew.lang; -using com.utils; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// Tag descriptor for almost every images - /// - public class ExifDescriptor : AbstractTagDescriptor - { - /// - /// Dictates whether rational values will be represented in decimal format in instances - /// where decimal notation is elegant (such as 1/2 -> 0.5, but not 1/3). - /// - private readonly bool allowDecimalRepresentationOfRationals = true; - - /// - /// Constructor of the object - /// - /// a directory - public ExifDescriptor(AbstractDirectory directory) : base(directory) - { - } - - /// - /// Returns a descriptive value of the the specified tag for this image. - /// Where possible, known values will be substituted here in place of the raw tokens actually - /// kept in the Exif segment. - /// If no substitution is available, the value provided by GetString(int) will be returned. - /// This and GetString(int) are the only 'get' methods that won't throw an exception. - /// - /// the tag to find a description for - /// a description of the image'str value for the specified tag, or null if the tag hasn't been defined. - public override string GetDescription(int aTagType) - { - switch(aTagType) - { - case ExifDirectory.TAG_ORIENTATION: - return GetOrientationDescription(); - case ExifDirectory.TAG_RESOLUTION_UNIT: - return GetResolutionDescription(); - case ExifDirectory.TAG_YCBCR_POSITIONING: - return GetYCbCrPositioningDescription(); - case ExifDirectory.TAG_EXPOSURE_TIME: - return GetExposureTimeDescription(); - case ExifDirectory.TAG_SHUTTER_SPEED: - return GetShutterSpeedDescription(); - case ExifDirectory.TAG_FNUMBER: - return GetFNumberDescription(); - case ExifDirectory.TAG_X_RESOLUTION: - return GetXResolutionDescription(); - case ExifDirectory.TAG_Y_RESOLUTION: - return GetYResolutionDescription(); - case ExifDirectory.TAG_THUMBNAIL_OFFSET: - return GetThumbnailOffSetDescription(); - case ExifDirectory.TAG_THUMBNAIL_LENGTH: - return GetThumbnailLengthDescription(); - case ExifDirectory.TAG_COMPRESSION_LEVEL: - return GetCompressionLevelDescription(); - case ExifDirectory.TAG_SUBJECT_DISTANCE: - return GetSubjectDistanceDescription(); - case ExifDirectory.TAG_METERING_MODE: - return GetMeteringModeDescription(); - case ExifDirectory.TAG_FLASH: - return GetFlashDescription(); - case ExifDirectory.TAG_FOCAL_LENGTH: - return GetFocalLengthDescription(); - case ExifDirectory.TAG_COLOR_SPACE: - return GetColorSpaceDescription(); - case ExifDirectory.TAG_EXIF_IMAGE_WIDTH: - return GetExifImageWidthDescription(); - case ExifDirectory.TAG_EXIF_IMAGE_HEIGHT: - return GetExifImageHeightDescription(); - case ExifDirectory.TAG_FOCAL_PLANE_UNIT: - return GetFocalPlaneResolutionUnitDescription(); - case ExifDirectory.TAG_FOCAL_PLANE_X_RES: - return GetFocalPlaneXResolutionDescription(); - case ExifDirectory.TAG_FOCAL_PLANE_Y_RES: - return GetFocalPlaneYResolutionDescription(); - case ExifDirectory.TAG_THUMBNAIL_IMAGE_WIDTH: - return GetThumbnailImageWidthDescription(); - case ExifDirectory.TAG_THUMBNAIL_IMAGE_HEIGHT: - return GetThumbnailImageHeightDescription(); - case ExifDirectory.TAG_BITS_PER_SAMPLE: - return GetBitsPerSampleDescription(); - case ExifDirectory.TAG_COMPRESSION: - return GetCompressionDescription(); - case ExifDirectory.TAG_PHOTOMETRIC_INTERPRETATION: - return GetPhotometricInterpretationDescription(); - case ExifDirectory.TAG_ROWS_PER_STRIP: - return GetRowsPerStripDescription(); - case ExifDirectory.TAG_STRIP_BYTE_COUNTS: - return GetStripByteCountsDescription(); - case ExifDirectory.TAG_SAMPLES_PER_PIXEL: - return GetSamplesPerPixelDescription(); - case ExifDirectory.TAG_PLANAR_CONFIGURATION: - return GetPlanarConfigurationDescription(); - case ExifDirectory.TAG_YCBCR_SUBSAMPLING: - return GetYCbCrSubsamplingDescription(); - case ExifDirectory.TAG_EXPOSURE_PROGRAM: - return GetExposureProgramDescription(); - case ExifDirectory.TAG_APERTURE: - return GetApertureValueDescription(); - case ExifDirectory.TAG_MAX_APERTURE: - return GetMaxApertureValueDescription(); - case ExifDirectory.TAG_SENSING_METHOD: - return GetSensingMethodDescription(); - case ExifDirectory.TAG_EXPOSURE_BIAS: - return GetExposureBiasDescription(); - case ExifDirectory.TAG_FILE_SOURCE: - return GetFileSourceDescription(); - case ExifDirectory.TAG_SCENE_TYPE: - return GetSceneTypeDescription(); - case ExifDirectory.TAG_COMPONENTS_CONFIGURATION: - return GetComponentConfigurationDescription(); - case ExifDirectory.TAG_EXIF_VERSION: - return GetExifVersionDescription(); - case ExifDirectory.TAG_FLASHPIX_VERSION: - return GetFlashPixVersionDescription(); - case ExifDirectory.TAG_REFERENCE_BLACK_WHITE: - return GetReferenceBlackWhiteDescription(); - case ExifDirectory.TAG_ISO_EQUIVALENT: - return GetIsoEquivalentDescription(); - case ExifDirectory.TAG_THUMBNAIL_DATA: - return GetThumbnailDescription(); - case ExifDirectory.TAG_XP_AUTHOR: - return GetXPAuthorDescription(); - case ExifDirectory.TAG_XP_COMMENTS: - return GetXPCommentsDescription(); - case ExifDirectory.TAG_XP_KEYWORDS: - return GetXPKeywordsDescription(); - case ExifDirectory.TAG_XP_SUBJECT: - return GetXPSubjectDescription(); - case ExifDirectory.TAG_XP_TITLE: - return GetXPTitleDescription(); - case ExifDirectory.TAG_SUBFILE_TYPE: - return GetNewSubfileTypeDescription(); - case ExifDirectory.TAG_NEW_SUBFILE_TYPE : - return GetNewSubfileTypeDescription(); - case ExifDirectory.TAG_THRESHOLDING : - return GetThresholdingDescription(); - case ExifDirectory.TAG_FILL_ORDER : - return GetFillOrderDescription(); - case ExifDirectory.TAG_SUBJECT_DISTANCE_RANGE : - return GetSubjectDistanceRangeDescription(); - case ExifDirectory.TAG_SHARPNESS : - return GetSharpnessDescription(); - case ExifDirectory.TAG_SATURATION : - return GetSaturationDescription(); - case ExifDirectory.TAG_CONTRAST: - return GetContrastDescription(); - case ExifDirectory.TAG_GAIN_CONTROL: - return GetGainControlDescription(); - case ExifDirectory.TAG_SCENE_CAPTURE_TYPE: - return GetSceneCaptureTypeDescription(); - case ExifDirectory.TAG_FOCAL_LENGTH_IN_35MM_FILM: - return Get35mmFilmEquivFocalLengthDescription(); - case ExifDirectory.TAG_DIGITAL_ZOOM_RATIO: - return GetDigitalZoomRatioDescription(); - case ExifDirectory.TAG_WHITE_BALANCE_MODE : - return GetWhiteBalanceModeDescription(); - case ExifDirectory.TAG_EXPOSURE_MODE: - return GetExposureModeDescription(); - - default : - return base.directory.GetString(aTagType); - } - } - - /// - /// Gets the custom rendered description. - /// - /// The custom rendered description - private string GetCustomRenderedDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_CUSTOM_RENDERED)) - { - return null; - } - int lcVal = base.directory.GetInt(ExifDirectory.TAG_CUSTOM_RENDERED); - switch (lcVal) - { - case 0: - return BUNDLE["NORMAL_PROCESS"]; - case 1: - return BUNDLE["CUSTOM_PROCESS"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Gets the exposure mode description. - /// - /// The exposure mode description - private string GetExposureModeDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_EXPOSURE_MODE)) - { - return null; - } - int lcVal = base.directory.GetInt(ExifDirectory.TAG_EXPOSURE_MODE); - switch (lcVal) - { - case 0: - return BUNDLE["AUTO_EXPOSURE"]; - case 1: - return BUNDLE["MANUAL_EXPOSURE"]; - case 2: - return BUNDLE["AUTO_BRACKET"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - - /// - /// Gets the white balance mode description. - /// - /// The white balance mode description - private string GetWhiteBalanceModeDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_WHITE_BALANCE_MODE)) - { - return null; - } - int lcVal = base.directory.GetInt(ExifDirectory.TAG_WHITE_BALANCE_MODE); - switch (lcVal) - { - case 0: - return BUNDLE["AUTO_WHITE_BALANCE"]; - case 1: - return BUNDLE["MANUAL_WHITE_BALANCE"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - - /// - /// Gets the digital zoom ratio description. - /// - /// The digital zoom ratio description - private string GetDigitalZoomRatioDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_DIGITAL_ZOOM_RATIO)) - { - return null; - } - Rational lcRational = base.directory.GetRational(ExifDirectory.TAG_DIGITAL_ZOOM_RATIO); - if (lcRational.GetNumerator() == 0) - { - return BUNDLE["DIGITAL_ZOOM_NOT_USED"]; - } - - return (lcRational.DoubleValue()).ToString(); - } - - /// - /// Gets the 35mm film equivalent focal length description. - /// - /// The 35mm film equivalent focal length description - private string Get35mmFilmEquivFocalLengthDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_FOCAL_LENGTH_IN_35MM_FILM)) - { - return null; - } - int lcEquivalentFocalLength = base.directory.GetInt(ExifDirectory.TAG_FOCAL_LENGTH_IN_35MM_FILM); - - if (lcEquivalentFocalLength == 0) - { - return BUNDLE["UNKNOWN", lcEquivalentFocalLength.ToString()]; - } - return BUNDLE["DISTANCE_MM", lcEquivalentFocalLength.ToString()]; - } - - /// - /// Gets the scene capture type description. - /// - /// The scene capture type description - private string GetSceneCaptureTypeDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_SCENE_CAPTURE_TYPE)) - { - return null; - } - int lcVal = base.directory.GetInt(ExifDirectory.TAG_SCENE_CAPTURE_TYPE); - switch (lcVal) - { - case 0: - return BUNDLE["STANDARD"]; - case 1: - return BUNDLE["LANDSCAPE"]; - case 2: - return BUNDLE["PORTRAIT"]; - case 3: - return BUNDLE["NIGHT_SCENE"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Gets the gain control description. - /// - /// The gain control description - private string GetGainControlDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_GAIN_CONTROL)) - { - return null; - } - int lcVal = base.directory.GetInt(ExifDirectory.TAG_GAIN_CONTROL); - switch (lcVal) - { - case 0: - return BUNDLE["NONE"]; - case 1: - return BUNDLE["LOW_GAIN_UP"]; - case 2: - return BUNDLE["LOW_GAIN_DOWN"]; - case 3: - return BUNDLE["HIGH_GAIN_UP"]; - case 4: - return BUNDLE["HIGH_GAIN_DOWN"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - - /// - /// Gets the contrast description. - /// - /// The constrast description - private string GetContrastDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_CONTRAST)) - { - return null; - } - int lcVal = base.directory.GetInt(ExifDirectory.TAG_CONTRAST); - switch (lcVal) - { - case 0: - return BUNDLE["NONE"]; - case 1: - return BUNDLE["SOFT"]; - case 2: - return BUNDLE["HARD"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Gets the subfile type description. - /// - /// The subfile type description - private string getSubfileTypeDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_SUBFILE_TYPE)) - { - return null; - } - int lcVal = base.directory.GetInt(ExifDirectory.TAG_SUBFILE_TYPE); - switch (lcVal) - { - case 1: return BUNDLE["FULL_RESOLUTION_IMAGE"]; - case 2: return BUNDLE["REDUCED_RESOLUTION_IMAGE"]; - case 3: return BUNDLE["SINGLE_PAGE_OF_MULTI_PAGE_IMAGE"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Gets the new subfile type description. - /// - /// The new subfile type description - private string GetNewSubfileTypeDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_NEW_SUBFILE_TYPE)) - { - return null; - } - int lcVal = base.directory.GetInt(ExifDirectory.TAG_NEW_SUBFILE_TYPE); - switch (lcVal) - { - case 1: return BUNDLE["FULL_RESOLUTION_IMAGE"]; - case 2: return BUNDLE["REDUCED_RESOLUTION_IMAGE"]; - case 3: return BUNDLE["SINGLE_PAGE_OF_MULTI_PAGE_REDUCED_RESOLUTION_IMAGE"]; - case 4: return BUNDLE["TRANSPARENCY_MASK"]; - case 5: return BUNDLE["TRANSPARENCY_MASK_OF_REDUCED_RESOLUTION_IMAGE"]; - case 6: return BUNDLE["TRANSPARENCY_MASK_OF_MULTI_PAGE_IMAGE"]; - case 7: return BUNDLE["TRANSPARENCY_MASK_OF_REDUCED_RESOLUTION_MULTI_PAGE_IMAGE"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Gets the new thresholding description. - /// - /// The thresholding description - private string GetThresholdingDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_THRESHOLDING)) - { - return null; - } - int lcVal = base.directory.GetInt(ExifDirectory.TAG_THRESHOLDING); - switch (lcVal) - { - case 1: return BUNDLE["NO_DITHERING_OR_HALFTONING"]; - case 2: return BUNDLE["ORDERED_DITHER_OR_HALFTONE"]; - case 3: return BUNDLE["RANDOMIZED_DITHER"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Gets the fill order description. - /// - /// The fill order description - private string GetFillOrderDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_FILL_ORDER)) - { - return null; - } - int lcVal = base.directory.GetInt(ExifDirectory.TAG_FILL_ORDER); - switch (lcVal) - { - case 1: return BUNDLE["NORMAL"]; - case 2: return BUNDLE["REVERSED"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Gets the subject distance range description. - /// - /// The subject distance range description - private string GetSubjectDistanceRangeDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_SUBJECT_DISTANCE_RANGE)) - { - return null; - } - int lcVal = base.directory.GetInt(ExifDirectory.TAG_SUBJECT_DISTANCE_RANGE); - switch (lcVal) - { - case 1: - return BUNDLE["MACRO"]; - case 2: - return BUNDLE["CLOSE_VIEW"]; - case 3: - return BUNDLE["DISTANT_VIEW"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Gets the sharpness description. - /// - /// The sharpness description - private string GetSharpnessDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_SHARPNESS)) - { - return null; - } - int lcVal = base.directory.GetInt(ExifDirectory.TAG_SHARPNESS); - switch (lcVal) - { - case 0: - return BUNDLE["NONE"]; - case 1: - return BUNDLE["LOW"]; - case 2: - return BUNDLE["HARD"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Gets the saturation description. - /// - /// The saturation description - private string GetSaturationDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_SATURATION)) - { - return null; - } - int lcVal = base.directory.GetInt(ExifDirectory.TAG_SATURATION); - switch (lcVal) - { - case 0: - return BUNDLE["NONE"]; - case 1: - return BUNDLE["LOW_SATURATION"]; - case 2: - return BUNDLE["HIGH_SATURATION"]; - default: - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - - - /// - /// Returns the Thumbnail Description. - /// - /// the Thumbnail Description. - private string GetThumbnailDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_THUMBNAIL_DATA)) - { - return null; - } - int[] lcThumbnailBytes = - base.directory.GetIntArray(ExifDirectory.TAG_THUMBNAIL_DATA); - return BUNDLE["THUMBNAIL_BYTES", lcThumbnailBytes.Length.ToString()]; - } - - /// - /// Returns the Iso Equivalent Description. - /// - /// the Iso Equivalent Description. - private string GetIsoEquivalentDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_ISO_EQUIVALENT)) - { - return null; - } - int lcIsoEquiv = base.directory.GetInt(ExifDirectory.TAG_ISO_EQUIVALENT); - if (lcIsoEquiv < 50) - { - lcIsoEquiv *= 200; - } - return lcIsoEquiv.ToString(); - } - - /// - /// Returns the Reference Black White Description. - /// - /// the Reference Black White Description. - private string GetReferenceBlackWhiteDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_REFERENCE_BLACK_WHITE)) - { - return null; - } - int[] lcInts = - base.directory.GetIntArray(ExifDirectory.TAG_REFERENCE_BLACK_WHITE); - - string[] lcSPos = new string[] {lcInts[0].ToString(), lcInts[1].ToString(),lcInts[2].ToString(),lcInts[3].ToString(),lcInts[4].ToString(),lcInts[5].ToString()}; - return BUNDLE["POS",lcSPos]; - } - - /// - /// Returns the Exif Version Description. - /// - /// the Exif Version Description. - private string GetExifVersionDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_EXIF_VERSION)) - { - return null; - } - int[] lcInts = base.directory.GetIntArray(ExifDirectory.TAG_EXIF_VERSION); - return ExifDescriptor.ConvertBytesToVersionString(lcInts); - } - - /// - /// Returns the Flash Pix Version Description. - /// - /// the Flash Pix Version Description. - private string GetFlashPixVersionDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_FLASHPIX_VERSION)) - { - return null; - } - int[] lcInts = base.directory.GetIntArray(ExifDirectory.TAG_FLASHPIX_VERSION); - return ExifDescriptor.ConvertBytesToVersionString(lcInts); - } - - /// - /// Returns the Scene Type Description. - /// - /// the Scene Type Description. - private string GetSceneTypeDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_SCENE_TYPE)) - { - return null; - } - int lcSceneType = base.directory.GetInt(ExifDirectory.TAG_SCENE_TYPE); - if (lcSceneType == 1) - { - return BUNDLE["DIRECTLY_PHOTOGRAPHED_IMAGE"]; - } - return BUNDLE["UNKNOWN", lcSceneType.ToString()]; - } - - /// - /// Returns the File Source Description. - /// - /// the File Source Description. - private string GetFileSourceDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_FILE_SOURCE)) - { - return null; - } - int lcFileSource = base.directory.GetInt(ExifDirectory.TAG_FILE_SOURCE); - if (lcFileSource == 3) - { - return BUNDLE["DIGITAL_STILL_CAMERA"]; - } - return BUNDLE["UNKNOWN", lcFileSource.ToString()]; - } - - /// - /// Returns the Exposure Bias Description. - /// - /// the Exposure Bias Description. - private string GetExposureBiasDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_EXPOSURE_BIAS)) - { - return null; - } - Rational lcExposureBias = - base.directory.GetRational(ExifDirectory.TAG_EXPOSURE_BIAS); - return lcExposureBias.ToSimpleString(true); - } - - /// - /// Returns the Max Aperture Value Description. - /// - /// the Max Aperture Value Description. - private string GetMaxApertureValueDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_MAX_APERTURE)) - { - return null; - } - double lcApertureApex = - base.directory.GetDouble(ExifDirectory.TAG_MAX_APERTURE); - double lcRootTwo = Math.Sqrt(2); - double lcFStop = Math.Pow(lcRootTwo, lcApertureApex); - return BUNDLE["APERTURE", lcFStop.ToString("0.#")]; - } - - /// - /// Returns the Aperture Value Description. - /// - /// the Aperture Value Description. - private string GetApertureValueDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_APERTURE)) - { - return null; - } - double lcApertureApex = base.directory.GetDouble(ExifDirectory.TAG_APERTURE); - double lcRootTwo = Math.Sqrt(2); - double lcFStop = Math.Pow(lcRootTwo, lcApertureApex); - return BUNDLE["APERTURE", lcFStop.ToString("0.#")]; - } - - /// - /// Returns the Exposure Program Description. - /// - /// the Exposure Program Description. - private string GetExposureProgramDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_EXPOSURE_PROGRAM)) - { - return null; - } - int lcVal = base.directory.GetInt(ExifDirectory.TAG_EXPOSURE_PROGRAM); - switch (lcVal) - { - case 1 : - return BUNDLE["MANUAL_CONTROL"]; - case 2 : - return BUNDLE["PROGRAM_NORMAL"]; - case 3 : - return BUNDLE["APERTURE_PRIORITY"]; - case 4 : - return BUNDLE["SHUTTER_PRIORITY"]; - case 5 : - return BUNDLE["PROGRAM_CREATIVE"]; - case 6 : - return BUNDLE["PROGRAM_ACTION"]; - case 7 : - return BUNDLE["PORTRAIT_MODE"]; - case 8 : - return BUNDLE["LANDSCAPE_MODE"]; - default : - return BUNDLE["UNKNOWN_PROGRAM", lcVal.ToString()]; - } - } - - /// - /// Returns the YCbCr Subsampling Description. - /// - /// the YCbCr Subsampling Description. - private string GetYCbCrSubsamplingDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_YCBCR_SUBSAMPLING)) - { - return null; - } - int[] lcPositions = - base.directory.GetIntArray(ExifDirectory.TAG_YCBCR_SUBSAMPLING); - if (lcPositions[0] == 2 && lcPositions[1] == 1) - { - return BUNDLE["YCBCR_422"]; - } - else if (lcPositions[0] == 2 && lcPositions[1] == 2) - { - return BUNDLE["YCBCR_420"]; - } - return BUNDLE["UNKNOWN"]; - } - - /// - /// Returns the Planar Configuration Description. - /// - /// the Planar Configuration Description. - private string GetPlanarConfigurationDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_PLANAR_CONFIGURATION)) - { - return null; - } - // When image format is no compression YCbCr, this aValue shows byte aligns of YCbCr - // data. If aValue is '1', Y/Cb/Cr aValue is chunky format, contiguous for each subsampling - // pixel. If aValue is '2', Y/Cb/Cr aValue is separated and stored to Y plane/Cb plane/Cr - // plane format. - - switch (base.directory.GetInt(ExifDirectory.TAG_PLANAR_CONFIGURATION)) - { - case 1 : - return BUNDLE["CHUNKY"]; - case 2 : - return BUNDLE["SEPARATE"]; - default : - return BUNDLE["UNKNOWN_CONFIGURATION"]; - } - } - - /// - /// Returns the Samples Per Pixel Description. - /// - /// the Samples Per Pixel Description. - private string GetSamplesPerPixelDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_SAMPLES_PER_PIXEL)) - { - return null; - } - return BUNDLE["SAMPLES_PIXEL", base.directory.GetString(ExifDirectory.TAG_SAMPLES_PER_PIXEL)]; - } - - /// - /// Returns the Rows Per Strip Description. - /// - /// the Rows Per Strip Description. - private string GetRowsPerStripDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_ROWS_PER_STRIP)) - { - return null; - } - return BUNDLE["ROWS_STRIP", base.directory.GetString(ExifDirectory.TAG_ROWS_PER_STRIP)]; - } - - /// - /// Returns the Strip Byte Counts Description. - /// - /// the Strip Byte Counts Description. - private string GetStripByteCountsDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_STRIP_BYTE_COUNTS)) - { - return null; - } - return BUNDLE["BYTES", base.directory.GetString(ExifDirectory.TAG_STRIP_BYTE_COUNTS)]; - } - - /// - /// Returns the Photometric Interpretation Description. - /// - /// the Photometric Interpretation Description. - private string GetPhotometricInterpretationDescription() - { - if (!base.directory - .ContainsTag(ExifDirectory.TAG_PHOTOMETRIC_INTERPRETATION)) - { - return null; - } - // Shows the color space of the image data components. '1' means monochrome, - // '2' means RGB, '6' means YCbCr. - switch (base.directory - .GetInt(ExifDirectory.TAG_PHOTOMETRIC_INTERPRETATION)) - { - case 0: return BUNDLE["WHITE_IS_ZERO"]; - case 1: return BUNDLE["BLACK_IS_ZERO"]; - case 2: return BUNDLE["RGB"]; - case 3: return BUNDLE["RGB_PALETTE"]; - case 4: return BUNDLE["TRANSPARENCY_MASK"]; - case 5: return BUNDLE["CMYK"]; - case 6: return BUNDLE["YCBCR"]; - case 8: return BUNDLE["CIELAB"]; - case 9: return BUNDLE["ICCLAB"]; - case 10: return BUNDLE["ITULAB"]; - case 32803: return BUNDLE["COLOR_FILTER_ARRAY"]; - case 32844: return BUNDLE["PIXAR_LOGL"]; - case 32845: return BUNDLE["PIXAR_LOGLUV"]; - case 32892: return BUNDLE["LINEAR_RAW"]; - default: return BUNDLE["UNKNOWN_COLOR_SPACE"]; - } - } - - /// - /// Returns the Compression Description. - /// - /// the Compression Description. - private string GetCompressionDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_COMPRESSION)) - { - return null; - } - // '1' means no compression, '6' means JPEG compression. - switch (base.directory.GetInt(ExifDirectory.TAG_COMPRESSION)) - { - case 1: return BUNDLE["UNCOMPRESSED"]; - case 2: return BUNDLE["CCITT_1D"]; - case 3: return BUNDLE["T4_GROUP_3_FAC"]; - case 4: return BUNDLE["T6_GROUP_4_FAC"]; - case 5: return BUNDLE["LZW"]; - case 6: return BUNDLE["JPEG_OLD_STYLE"]; - case 7: return BUNDLE["JPEG"]; - case 8: return BUNDLE["ADOBE_DEFLATE"]; - case 9: return BUNDLE["JBIG_B_W"]; - case 10: return BUNDLE["JBIG_COLOR"]; - case 32766: return BUNDLE["NEXT"]; - case 32771: return BUNDLE["CCIRLEW"]; - case 32773: return BUNDLE["PACKBITS"]; - case 32809: return BUNDLE["THUNDERSCA"]; - case 32895: return BUNDLE["IT8CTPAD"]; - case 32896: return BUNDLE["IT8LW"]; - case 32897: return BUNDLE["IT8MP"]; - case 32898: return BUNDLE["IT8BL"]; - case 32908: return BUNDLE["PIXARFILM"]; - case 32909: return BUNDLE["PIXARLOG"]; - case 32946: return BUNDLE["DEFLATE"]; - case 32947: return BUNDLE["DCS"]; - case 32661: return BUNDLE["JBIG"]; - case 32676: return BUNDLE["SGILOG"]; - case 32677: return BUNDLE["SGILOG24"]; - case 32712: return BUNDLE["JPEG_2000"]; - case 32713: return BUNDLE["NIKON_NEF_COMPRESSED"]; - default: return BUNDLE["UNKNOWN_COMPRESSION"]; - } - } - - /// - /// Returns the Bits Per Sample Description. - /// - /// the Bits Per Sample Description. - private string GetBitsPerSampleDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_BITS_PER_SAMPLE)) - { - return null; - } - return BUNDLE["BITS_COMPONENT_PIXEL",base.directory.GetString(ExifDirectory.TAG_BITS_PER_SAMPLE)]; - } - - /// - /// Returns the Thumbnail Image Width Description. - /// - /// the Thumbnail Image Width Description. - private string GetThumbnailImageWidthDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_THUMBNAIL_IMAGE_WIDTH)) - { - return null; - } - return BUNDLE["PIXELS", base.directory.GetString(ExifDirectory.TAG_THUMBNAIL_IMAGE_WIDTH)]; - } - - /// - /// Returns the Thumbnail Image Height Description. - /// - /// the Thumbnail Image Height Description. - private string GetThumbnailImageHeightDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_THUMBNAIL_IMAGE_HEIGHT)) - { - return null; - } - return BUNDLE["PIXELS", base.directory.GetString(ExifDirectory.TAG_THUMBNAIL_IMAGE_HEIGHT)]; - } - - /// - /// Returns the Focal Plane X Resolution Description. - /// - /// the Focal Plane X Resolution Description. - private string GetFocalPlaneXResolutionDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_FOCAL_PLANE_X_RES)) - { - return null; - } - Rational lcRational = - base.directory.GetRational(ExifDirectory.TAG_FOCAL_PLANE_X_RES); - return BUNDLE["FOCAL_PLANE", lcRational.GetReciprocal().ToSimpleString(allowDecimalRepresentationOfRationals), - GetFocalPlaneResolutionUnitDescription().ToLower()]; - } - - /// - /// Returns the Focal Plane Y Resolution Description. - /// - /// the Focal Plane Y Resolution Description. - private string GetFocalPlaneYResolutionDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_FOCAL_PLANE_Y_RES)) - { - return null; - } - Rational lcRational = - base.directory.GetRational(ExifDirectory.TAG_FOCAL_PLANE_Y_RES); - return BUNDLE["FOCAL_PLANE", lcRational.GetReciprocal().ToSimpleString(allowDecimalRepresentationOfRationals), - GetFocalPlaneResolutionUnitDescription().ToLower()]; - } - - /// - /// Returns the Focal Plane Resolution Unit Description. - /// - /// the Focal Plane Resolution Unit Description. - private string GetFocalPlaneResolutionUnitDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_FOCAL_PLANE_UNIT)) - { - return null; - } - // Unit of FocalPlaneXResoluton/FocalPlaneYResolution. '1' means no-unit, - // '2' inch, '3' centimeter. - switch (base.directory.GetInt(ExifDirectory.TAG_FOCAL_PLANE_UNIT)) - { - case 1 : - return BUNDLE["NO_UNIT"]; - case 2 : - return BUNDLE["INCHES"]; - case 3 : - return BUNDLE["CM"]; - default : - return ""; - } - } - - /// - /// Returns the Exif Image Width Description. - /// - /// the Exif Image Width Description. - private string GetExifImageWidthDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_EXIF_IMAGE_WIDTH)) - { - return null; - } - return BUNDLE["PIXELS", base.directory.GetInt(ExifDirectory.TAG_EXIF_IMAGE_WIDTH).ToString()]; - } - - /// - /// Returns the Exif Image Height Description. - /// - /// the Exif Image Height Description. - private string GetExifImageHeightDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_EXIF_IMAGE_HEIGHT)) - { - return null; - } - return BUNDLE["PIXELS", base.directory.GetInt(ExifDirectory.TAG_EXIF_IMAGE_HEIGHT).ToString()]; - } - - /// - /// Returns the Color Space Description. - /// - /// the Color Space Description. - private string GetColorSpaceDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_COLOR_SPACE)) - { - return null; - } - int lcColorSpace = base.directory.GetInt(ExifDirectory.TAG_COLOR_SPACE); - switch (lcColorSpace) - { - case 1: return BUNDLE["SRGB"]; - case 65535: return BUNDLE["UNDEFINED"]; - default: return BUNDLE["UNKNOWN"]; - } - } - - /// - /// Returns the Focal Length Description. - /// - /// the Focal Length Description. - private string GetFocalLengthDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_FOCAL_LENGTH)) - { - return null; - } - Rational lcFocalLength = - base.directory.GetRational(ExifDirectory.TAG_FOCAL_LENGTH); - return BUNDLE["DISTANCE_MM", (lcFocalLength.DoubleValue()).ToString("0.0##")]; - } - - /// - /// Returns the Flash Description. - /// - /// the Flash Description. - private string GetFlashDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_FLASH)) - { - return null; - } - int lcVal = base.directory.GetInt(ExifDirectory.TAG_FLASH); - StringBuilder sb = new StringBuilder(); - - if ((lcVal & 0x1) != 0) - { - sb.Append(BUNDLE["FLASH_FIRED"]); - } - else - { - sb.Append(BUNDLE["FLASH_DID_NOT_FIRE"]); - } - - // check if we're able to detect a return, before we mention it - if ((lcVal & 0x4) != 0) - { - sb.Append(", "); - if ((lcVal & 0x2) != 0) - { - sb.Append(BUNDLE["RETURN_DETECTED"]); - } - else - { - sb.Append(BUNDLE["RETURN_NOT_DETECTED"]); - } - } - - if ((lcVal & 0x10) != 0) - { - sb.Append(", ").Append(BUNDLE["AUTO"]); - } - - if ((lcVal & 0x40) != 0) - { - sb.Append(", ").Append(BUNDLE["RED_EYE_REDUCTION"]); - } - - return sb.ToString(); - } - - /// - /// Returns the light source Description. - /// - /// the light source Description. - private string GetLightSourceDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_LIGHT_SOURCE)) - { - return null; - } - int lcVal = base.directory.GetInt(ExifDirectory.TAG_LIGHT_SOURCE); - switch (lcVal) - { - case 0 : - return BUNDLE["UNKNOWN"]; - case 1 : - return BUNDLE["DAYLIGHT"]; - case 2 : - return BUNDLE["FLUORESCENT"]; - case 3 : - return BUNDLE["TUNGSTEN"]; - case 10 : - return BUNDLE["FLASH"]; - case 17 : - return BUNDLE["STANDARD_LIGHT"]; - case 18 : - return BUNDLE["STANDARD_LIGHT_B"]; - case 19 : - return BUNDLE["STANDARD_LIGHT_C"]; - case 20 : - return BUNDLE["D55"]; - case 21 : - return BUNDLE["D65"]; - case 22 : - return BUNDLE["D75"]; - case 255 : - return BUNDLE["OTHER"]; - default : - return BUNDLE["UNKNOWN", lcVal.ToString()]; - } - } - - /// - /// Returns the Metering Mode Description. - /// - /// the Metering Mode Description. - private string GetMeteringModeDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_METERING_MODE)) - { - return null; - } - // '0' means unknown, '1' average, '2' center weighted average, '3' spot - // '4' multi-spot, '5' multi-segment, '6' partial, '255' other - int lcMeteringMode = base.directory.GetInt(ExifDirectory.TAG_METERING_MODE); - switch (lcMeteringMode) - { - case 0 : - return BUNDLE["UNKNOWN"]; - case 1 : - return BUNDLE["AVERAGE"]; - case 2 : - return BUNDLE["CENTER_WEIGHTED_AVERAGE"]; - case 3 : - return BUNDLE["SPOT"]; - case 4 : - return BUNDLE["MULTI_SPOT"]; - case 5 : - return BUNDLE["MULTI_SEGMENT"]; - case 6 : - return BUNDLE["PARTIAL"]; - case 255 : - return BUNDLE["OTHER"]; - default : - return ""; - } - } - - /// - /// Returns the Subject Distance Description. - /// - /// the Subject Distance Description. - private string GetSubjectDistanceDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_SUBJECT_DISTANCE)) - { - return null; - } - Rational lcDistance = - base.directory.GetRational(ExifDirectory.TAG_SUBJECT_DISTANCE); - return BUNDLE["METRES", (lcDistance.DoubleValue()).ToString("0.0##")]; - } - - /// - /// Returns the Compression Level Description. - /// - /// the Compression Level Description. - private string GetCompressionLevelDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_COMPRESSION_LEVEL)) - { - return null; - } - Rational lcCompressionRatio = - base.directory.GetRational(ExifDirectory.TAG_COMPRESSION_LEVEL); - string lcRatio = - lcCompressionRatio.ToSimpleString( - allowDecimalRepresentationOfRationals); - if (lcCompressionRatio.IsInteger() && lcCompressionRatio.IntValue() == 1) - { - return BUNDLE["BIT_PIXEL", lcRatio]; - } - return BUNDLE["BITS_PIXEL", lcRatio]; - } - - /// - /// Returns the Thumbnail Length Description. - /// - /// the Thumbnail Length Description. - private string GetThumbnailLengthDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_THUMBNAIL_LENGTH)) - { - return null; - } - return BUNDLE["BYTES", base.directory.GetString(ExifDirectory.TAG_THUMBNAIL_LENGTH)]; - } - - /// - /// Returns the Thumbnail OffSet Description. - /// - /// the Thumbnail OffSet Description. - private string GetThumbnailOffSetDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_THUMBNAIL_OFFSET)) - { - return null; - } - return BUNDLE["BYTES", base.directory.GetString(ExifDirectory.TAG_THUMBNAIL_OFFSET)]; - } - - /// - /// Returns the Y Resolution Description. - /// - /// the Y Resolution Description. - private string GetYResolutionDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_Y_RESOLUTION)) - { - return null; - } - Rational lcResolution = - base.directory.GetRational(ExifDirectory.TAG_Y_RESOLUTION); - return BUNDLE["DOTS_PER", lcResolution.ToSimpleString(allowDecimalRepresentationOfRationals),GetResolutionDescription().ToLower()]; - } - - /// - /// Returns the X Resolution Description. - /// - /// the X Resolution Description. - private string GetXResolutionDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_X_RESOLUTION)) - { - return null; - } - Rational lcResolution = - base.directory.GetRational(ExifDirectory.TAG_X_RESOLUTION); - return BUNDLE["DOTS_PER", lcResolution.ToSimpleString(allowDecimalRepresentationOfRationals),GetResolutionDescription().ToLower()]; - } - - /// - /// Returns the Exposure Time Description. - /// - /// the Exposure Time Description. - private string GetExposureTimeDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_EXPOSURE_TIME)) - { - return null; - } - return BUNDLE["SEC", base.directory.GetString(ExifDirectory.TAG_EXPOSURE_TIME)]; - } - - /// - /// Returns the Shutter Speed Description. - /// - /// the Shutter Speed Description. - private string GetShutterSpeedDescription() - { - // I believe this method to now be stable, but am leaving some - // alternative snippets of code in here, to assist anyone who'lcStr - // looking into this (given that I don't have a public CVS). - if (!base.directory.ContainsTag(ExifDirectory.TAG_SHUTTER_SPEED)) - { - return null; - } - // Thanks to Mark Edwards for spotting and patching a bug in the calculation of this - // description (spotted bug using a Canon EOS 300D) - // thanks also to Gli Blr for spotting this bug - float lcApexValue = base.directory.GetFloat(ExifDirectory.TAG_SHUTTER_SPEED); - if (lcApexValue <= 1) - { - float lcApexPower = (float)(1 / (Math.Exp(lcApexValue * Math.Log(2)))); - long lcApexPower10 = (long)Math.Round((double)lcApexPower * 10.0); - float lcFApexPower = (float)lcApexPower10 / 10.0f; - return BUNDLE["SHUTTER_SPEED_SEC", lcFApexPower.ToString()]; - } - else - { - int apexPower = (int)((Math.Exp(lcApexValue * Math.Log(2)))); - return BUNDLE["SHUTTER_SPEED", apexPower.ToString()]; - } - - // This alternative implementation offered by Bill Richards - // TODO determine which is the correct / more-correct implementation - // double apexValue = base.directory.GetDouble(ExifDirectory.TAG_SHUTTER_SPEED); - // double apexPower = Math.Pow(2.0, apexValue); - - // StringBuilder sb = new StringBuilder(); - // if (apexPower > 1) { - // apexPower = Math.Floor(apexPower); - // } - // if (apexPower < 1) { - // sb.Append((int)Math.Round(1/apexPower)); - // } else { - // sb.Append("1/"); - // sb.Append((int)apexPower); - // } - // sb.Append(" sec"); - // return sb.ToString(); - } - - /// - /// Returns the F Number Description. - /// - /// the F Number Description. - private string GetFNumberDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_FNUMBER)) - { - return null; - } - Rational lcFNumber = base.directory.GetRational(ExifDirectory.TAG_FNUMBER); - return BUNDLE["APERTURE", lcFNumber.DoubleValue().ToString("0.#")]; - } - - /// - /// Returns the YCbCr Positioning Description. - /// - /// the YCbCr Positioning Description. - private string GetYCbCrPositioningDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_YCBCR_POSITIONING)) - { - return null; - } - int lcYCbCrPosition = - base.directory.GetInt(ExifDirectory.TAG_YCBCR_POSITIONING); - switch (lcYCbCrPosition) - { - case 1 : - return BUNDLE["CENTER_OF_PIXEL_ARRAY"]; - case 2 : - return BUNDLE["DATUM_POINT"]; - default : - return lcYCbCrPosition.ToString(); - } - } - - /// - /// Returns the Orientation Description. - /// - /// the Orientation Description. - private string GetOrientationDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_ORIENTATION)) - { - return null; - } - int lcOrientation = base.directory.GetInt(ExifDirectory.TAG_ORIENTATION); - switch (lcOrientation) - { - case 1 : - return BUNDLE["TOP_LEFT_SIDE"]; - case 2 : - return BUNDLE["TOP_RIGHT_SIDE"]; - case 3 : - return BUNDLE["BOTTOM_RIGHT_SIDE"]; - case 4 : - return BUNDLE["BOTTOM_LEFT_SIDE"]; - case 5 : - return BUNDLE["LEFT_SIDE_TOP"]; - case 6 : - return BUNDLE["RIGHT_SIDE_TOP"]; - case 7 : - return BUNDLE["RIGHT_SIDE_BOTTOM"]; - case 8 : - return BUNDLE["LEFT_SIDE_BOTTOM"]; - default : - return lcOrientation.ToString(); - } - } - - /// - /// Returns the Resolution Description. - /// - /// the Resolution Description. - private string GetResolutionDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_RESOLUTION_UNIT)) - { - return ""; - } - // '1' means no-unit, '2' means inch, '3' means centimeter. Default aValue is '2'(inch) - int lcResolutionUnit = base.directory.GetInt(ExifDirectory.TAG_RESOLUTION_UNIT); - switch (lcResolutionUnit) - { - case 1 : - return BUNDLE["NO_UNIT"]; - case 2 : - return BUNDLE["INCHES"]; - case 3 : - return BUNDLE["CM"]; - default : - return ""; - } - } - - /// - /// Returns the Sensing Method Description. - /// - /// the Sensing Method Description. - private string GetSensingMethodDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_SENSING_METHOD)) - { - return null; - } - // '1' Not defined, '2' One-chip color area sensor, '3' Two-chip color area sensor - // '4' Three-chip color area sensor, '5' Color sequential area sensor - // '7' Trilinear sensor '8' Color sequential linear sensor, 'Other' reserved - int lcSensingMethod = base.directory.GetInt(ExifDirectory.TAG_SENSING_METHOD); - switch (lcSensingMethod) - { - case 1 : - return BUNDLE["NOT_DEFINED"]; - case 2 : - return BUNDLE["ONE_CHIP_COLOR"]; - case 3 : - return BUNDLE["TWO_CHIP_COLOR"]; - case 4 : - return BUNDLE["THREE_CHIP_COLOR"]; - case 5 : - return BUNDLE["COLOR_SEQUENTIAL"]; - case 7 : - return BUNDLE["TRILINEAR_SENSOR"]; - case 8 : - return BUNDLE["COLOR_SEQUENTIAL_LINEAR"]; - default : - return ""; - } - } - - /// - /// Returns the XP author description. - /// - /// the XP author description. - private string GetXPAuthorDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_XP_AUTHOR)) - { - return null; - } - return Utils.Decode(base.directory.GetByteArray(ExifDirectory.TAG_XP_AUTHOR), true); - } - - /// - /// Returns the XP comments description. - /// - /// the XP comments description. - private string GetXPCommentsDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_XP_COMMENTS)) - { - return null; - } - return Utils.Decode(base.directory.GetByteArray(ExifDirectory.TAG_XP_COMMENTS), true); - } - - /// - /// Returns the XP keywords description. - /// - /// the XP keywords description. - private string GetXPKeywordsDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_XP_KEYWORDS)) - { - return null; - } - return Utils.Decode(base.directory.GetByteArray(ExifDirectory.TAG_XP_KEYWORDS), true); - } - - /// - /// Returns the XP subject description. - /// - /// the XP subject description. - private string GetXPSubjectDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_XP_SUBJECT)) - { - return null; - } - return Utils.Decode(base.directory.GetByteArray(ExifDirectory.TAG_XP_SUBJECT), true); - } - - /// - /// Returns the XP title description. - /// - /// the XP title description. - private string GetXPTitleDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_XP_TITLE)) - { - return null; - } - return Utils.Decode(base.directory.GetByteArray(ExifDirectory.TAG_XP_TITLE), true); - } - - - /// - /// Returns the Component Configuration Description. - /// - /// the Component Configuration Description. - private string GetComponentConfigurationDescription() - { - if (!base.directory.ContainsTag(ExifDirectory.TAG_COMPONENTS_CONFIGURATION)) - { - return null; - } - int[] lcComponents = - base.directory.GetIntArray(ExifDirectory.TAG_COMPONENTS_CONFIGURATION); - string[] lcComponentStrings = { "", "Y", "Cb", "Cr", "R", "G", "B" }; - StringBuilder lcComponentConfig = new StringBuilder(); - for (int i = 0; i < Math.Min(4, lcComponents.Length); i++) - { - int lcId = lcComponents[i]; - if (lcId > 0 && lcId < lcComponentStrings.Length) - { - lcComponentConfig.Append(lcComponentStrings[lcId]); - } - } - return lcComponentConfig.ToString(); - } - - /// - /// Takes a series of 4 bytes from the specified offSet, and converts these to a - /// well-known version number, where possible. For example, (hex) 30 32 31 30 == 2.10). - /// - /// the four version values - /// the version as a string of form 2.10 - public static string ConvertBytesToVersionString(int[] someComponents) - { - StringBuilder lcVersion = new StringBuilder(); - for (int i = 0; i < 4 && i < someComponents.Length; i++) - { - // In order to avoid strange characters in some version (like Nikon) - if (someComponents[i] > 31) - { - if (i == 2) - { - lcVersion.Append('.'); - } - string digit = ((char)someComponents[i]).ToString(); - if (i == 0 && "0".Equals(digit)) - { - continue; - } - lcVersion.Append(digit); - } - } - return lcVersion.ToString(); - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/ExifDirectory.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/ExifDirectory.cs deleted file mode 100644 index 2e56391cd4..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/ExifDirectory.cs +++ /dev/null @@ -1,636 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text; -using System.IO; -using com.drew.metadata; -using com.drew.lang; -using com.utils.bundle; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// The Exif Directory class - /// - public class ExifDirectory : AbstractDirectory - { - // TODO do these tags belong in the exif directory? - public const int TAG_SUB_IFDS = 0x014A; - public const int TAG_GPS_INFO = 0x8825; - - /// - /// The actual aperture value of lens when the image was taken. Unit is APEX. - /// To convert this value to ordinary F-number (F-stop), calculate this value'str power - /// of root 2 (=1.4142). For example, if the ApertureValue is '5', F-number is 1.4142^5 = F5.6. - /// - public const int TAG_APERTURE = 0x9202; - - /// - /// When image format is no compression, this value shows the number of bits - /// per component for each pixel. Usually this value is '8,8,8'. - /// - public const int TAG_BITS_PER_SAMPLE = 0x0102; - - /// - /// Shows compression method for Thumbnail. - /// 1 = Uncompressed - /// 2 = CCITT 1D - /// 3 = T4/Group 3 Fax - /// 4 = T6/Group 4 Fax - /// 5 = LZW - /// 6 = JPEG (old-style) - /// 7 = JPEG - /// 8 = Adobe Deflate - /// 9 = JBIG B&W - /// 10 = JBIG Color - /// 32766 = Next - /// 32771 = CCIRLEW - /// 32773 = PackBits - /// 32809 = Thunderscan - /// 32895 = IT8CTPAD - /// 32896 = IT8LW - /// 32897 = IT8MP - /// 32898 = IT8BL - /// 32908 = PixarFilm - /// 32909 = PixarLog - /// 32946 = Deflate - /// 32947 = DCS - /// 34661 = JBIG - /// 34676 = SGILog - /// 34677 = SGILog24 - /// 34712 = JPEG 2000 - /// 34713 = Nikon NEF Compressed - /// - public const int TAG_COMPRESSION = 0x0103; - public const int COMPRESSION_NONE = 1; - public const int COMPRESSION_JPEG = 6; - - - /// - /// Shows the color space of the image data components. - /// 0 = WhiteIsZero - /// 1 = BlackIsZero - /// 2 = RGB - /// 3 = RGB Palette - /// 4 = Transparency Mask - /// 5 = CMYK - /// 6 = YCbCr - /// 8 = CIELab - /// 9 = ICCLab - /// 10 = ITULab - /// 32803 = Color Filter Array - /// 32844 = Pixar LogL - /// 32845 = Pixar LogLuv - /// 34892 = Linear Raw - /// - public const int TAG_PHOTOMETRIC_INTERPRETATION = 0x0106; - - /// - /// 1 = No dithering or halftoning - /// 2 = Ordered dither or halftone - /// 3 = Randomized dither - /// - public const int TAG_THRESHOLDING = 0x0107; - public const int PHOTOMETRIC_INTERPRETATION_MONOCHROME = 1; - public const int PHOTOMETRIC_INTERPRETATION_RGB = 2; - public const int PHOTOMETRIC_INTERPRETATION_YCBCR = 6; - - /// - /// The position in the file of raster data. - /// - public const int TAG_STRIP_OFFSETS = 0x0111; - /// - /// Each pixel is composed of this many samples. - /// - public const int TAG_SAMPLES_PER_PIXEL = 0x0115; - /// - /// The raster is codified by a single block of data holding this many rows. - /// - public const int TAG_ROWS_PER_STRIP = 0x116; - /// - /// The size of the raster data in bytes. - /// - public const int TAG_STRIP_BYTE_COUNTS = 0x0117; - public const int TAG_MIN_SAMPLE_VALUE = 0x0118; - public const int TAG_MAX_SAMPLE_VALUE = 0x0119; - - - /// - /// When image format is no compression YCbCr, this value shows byte aligns of YCbCr data. - /// If value is '1', Y/Cb/Cr value is chunky format, contiguous for each subsampling pixel. - /// If value is '2', Y/Cb/Cr value is separated and stored to Y plane/Cb plane/Cr plane format. - /// - public const int TAG_PLANAR_CONFIGURATION = 0x011C; - public const int TAG_YCBCR_SUBSAMPLING = 0x0212; - public const int TAG_IMAGE_DESCRIPTION = 0x010E; - public const int TAG_SOFTWARE = 0x0131; - public const int TAG_DATETIME = 0x0132; - public const int TAG_WHITE_POINT = 0x013E; - public const int TAG_PRIMARY_CHROMATICITIES = 0x013F; - public const int TAG_YCBCR_COEFFICIENTS = 0x0211; - public const int TAG_REFERENCE_BLACK_WHITE = 0x0214; - public const int TAG_COPYRIGHT = 0x8298; - /// - /// The new subfile type tag. - /// 0 = Full-resolution Image - /// 1 = Reduced-resolution image - /// 2 = Single page of multi-page image - /// 3 = Single page of multi-page reduced-resolution image - /// 4 = Transparency mask - /// 5 = Transparency mask of reduced-resolution image - /// 6 = Transparency mask of multi-page image - /// 7 = Transparency mask of reduced-resolution multi-page image - /// - public const int TAG_NEW_SUBFILE_TYPE = 0x00FE; - /// - /// The old subfile type tag. - /// 1 = Full-resolution image (Main image) - /// 2 = Reduced-resolution image (Thumbnail) - /// 3 = Single page of multi-page image - /// - public const int TAG_SUBFILE_TYPE = 0x00FF; - public const int TAG_TRANSFER_FUNCTION = 0x012D; - public const int TAG_ARTIST = 0x013B; - public const int TAG_PREDICTOR = 0x013D; - public const int TAG_TILE_WIDTH = 0x0142; - public const int TAG_TILE_LENGTH = 0x0143; - public const int TAG_TILE_OFFSETS = 0x0144; - public const int TAG_TILE_BYTE_COUNTS = 0x0145; - public const int TAG_JPEG_TABLES = 0x015B; - public const int TAG_CFA_REPEAT_PATTERN_DIM = 0x828D; - - /// - /// There are two definitions for CFA pattern, I don't know the difference... - /// - public const int TAG_CFA_PATTERN_2 = 0x828E; - public const int TAG_BATTERY_LEVEL = 0x828F; - public const int TAG_IPTC_NAA = 0x83BB; - public const int TAG_INTER_COLOR_PROFILE = 0x8773; - public const int TAG_SPECTRAL_SENSITIVITY = 0x8824; - public const int TAG_OECF = 0x8828; - public const int TAG_INTERLACE = 0x8829; - public const int TAG_TIME_ZONE_OFFSET = 0x882A; - public const int TAG_SELF_TIMER_MODE = 0x882B; - public const int TAG_FLASH_ENERGY = 0x920B; - public const int TAG_SPATIAL_FREQ_RESPONSE = 0x920C; - public const int TAG_NOISE = 0x920D; - public const int TAG_IMAGE_NUMBER = 0x9211; - public const int TAG_SECURITY_CLASSIFICATION = 0x9212; - public const int TAG_IMAGE_HISTORY = 0x9213; - public const int TAG_SUBJECT_LOCATION = 0x9214; - - /// - /// There are two definitions for exposure index, I don't know the difference... - /// - public const int TAG_EXPOSURE_INDEX_2 = 0x9215; - public const int TAG_TIFF_EP_STANDARD_ID = 0x9216; - public const int TAG_FLASH_ENERGY_2 = 0xA20B; - public const int TAG_SPATIAL_FREQ_RESPONSE_2 = 0xA20C; - public const int TAG_SUBJECT_LOCATION_2 = 0xA214; - public const int TAG_MAKE = 0x010F; - public const int TAG_MODEL = 0x0110; - public const int TAG_ORIENTATION = 0x0112; - public const int TAG_X_RESOLUTION = 0x011A; - public const int TAG_Y_RESOLUTION = 0x011B; - public const int TAG_PAGE_NAME = 0x011D; - public const int TAG_RESOLUTION_UNIT = 0x0128; - public const int TAG_THUMBNAIL_OFFSET = 0x0201; - public const int TAG_THUMBNAIL_LENGTH = 0x0202; - public const int TAG_YCBCR_POSITIONING = 0x0213; - - /// - /// Exposure time (reciprocal of shutter speed). Unit is second. - /// - public const int TAG_EXPOSURE_TIME = 0x829A; - - /// - /// The actual F-number(F-stop) of lens when the image was taken. - /// - public const int TAG_FNUMBER = 0x829D; - - /// - /// Exposure program that the camera used when image was taken. - /// '1' means manual control, '2' program normal, '3' aperture priority, '4' - /// shutter priority, '5' program creative (slow program), - /// '6' program action (high-speed program), '7' portrait mode, '8' landscape mode. - /// - public const int TAG_EXPOSURE_PROGRAM = 0x8822; - public const int TAG_ISO_EQUIVALENT = 0x8827; - public const int TAG_EXIF_VERSION = 0x9000; - public const int TAG_DATETIME_ORIGINAL = 0x9003; - public const int TAG_DATETIME_DIGITIZED = 0x9004; - public const int TAG_COMPONENTS_CONFIGURATION = 0x9101; - - /// - /// Average (rough estimate) compression level in JPEG bits per pixel. - /// - public const int TAG_COMPRESSION_LEVEL = 0x9102; - - /// - /// Shutter speed by APEX value. To convert this value to ordinary 'Shutter Speed'; - /// calculate this value'str power of 2, then reciprocal. For example, if the - /// ShutterSpeedValue is '4', shutter speed is 1/(24)=1/16 second. - /// - public const int TAG_SHUTTER_SPEED = 0x9201; - public const int TAG_BRIGHTNESS_VALUE = 0x9203; - public const int TAG_EXPOSURE_BIAS = 0x9204; - - /// - /// Maximum aperture value of lens. You can convert to F-number by calculating - /// power of root 2 (same process of ApertureValue:0x9202). - /// The actual aperture value of lens when the image was taken. To convert this - /// value to ordinary f-number(f-stop), calculate the value'lcStr power of root 2 - /// (=1.4142). For example, if the ApertureValue is '5', f-number is 1.41425^5 = F5.6. - /// - public const int TAG_MAX_APERTURE = 0x9205; - /// - /// Indicates the distance the autofocus camera is focused to. Tends to be less accurate as distance increases. - /// - public const int TAG_SUBJECT_DISTANCE = 0x9206; - - /// - /// Exposure metering method. '0' means unknown, '1' average, '2' center - /// weighted average, '3' spot, '4' multi-spot, '5' multi-segment, '6' partial, '255' other. - /// - public const int TAG_METERING_MODE = 0x9207; - - /// - /// White balance (aka light source). '0' means unknown, '1' daylight, - /// '2' fluorescent, '3' tungsten, '10' flash, '17' standard light A, - /// '18' standard light B, '19' standard light C, '20' D55, '21' D65, - /// '22' D75, '255' other. - /// - public const int TAG_LIGHT_SOURCE = 0x9208; - - /// - /// This tag indicates the white balance mode set when the image was shot. - /// Tag = 41987 (A403.H) - /// Type = SHORT - /// Count = 1 - /// Default = none - /// 0 = Auto white balance - /// 1 = Manual white balance - /// Other = reserved - /// - public const int TAG_WHITE_BALANCE_MODE = 0xA403; - - - /// - /// 0x0 = 0000000 = No Flash - /// 0x1 = 0000001 = Fired - /// 0x5 = 0000101 = Fired, Return not detected - /// 0x7 = 0000111 = Fired, Return detected - /// 0x9 = 0001001 = On - /// 0xd = 0001101 = On, Return not detected - /// 0xf = 0001111 = On, Return detected - /// 0x10 = 0010000 = Off - /// 0x18 = 0011000 = Auto, Did not fire - /// 0x19 = 0011001 = Auto, Fired - /// 0x1d = 0011101 = Auto, Fired, Return not detected - /// 0x1f = 0011111 = Auto, Fired, Return detected - /// 0x20 = 0100000 = No flash function - /// 0x41 = 1000001 = Fired, Red-eye reduction - /// 0x45 = 1000101 = Fired, Red-eye reduction, Return not detected - /// 0x47 = 1000111 = Fired, Red-eye reduction, Return detected - /// 0x49 = 1001001 = On, Red-eye reduction - /// 0x4d = 1001101 = On, Red-eye reduction, Return not detected - /// 0x4f = 1001111 = On, Red-eye reduction, Return detected - /// 0x59 = 1011001 = Auto, Fired, Red-eye reduction - /// 0x5d = 1011101 = Auto, Fired, Red-eye reduction, Return not detected - /// 0x5f = 1011111 = Auto, Fired, Red-eye reduction, Return detected - /// 6543210 (positions) - /// - /// This is a bitmask. - /// 0 = flash fired - /// 1 = return detected - /// 2 = return able to be detected - /// 3 = unknown - /// 4 = auto used - /// 5 = unknown - /// 6 = red eye reduction used - /// - public const int TAG_FLASH = 0x9209; - - /// - /// Focal length of lens used to take image. Unit is millimeter. - /// - public const int TAG_FOCAL_LENGTH = 0x920A; - public const int TAG_USER_COMMENT = 0x9286; - public const int TAG_SUBSECOND_TIME = 0x9290; - public const int TAG_SUBSECOND_TIME_ORIGINAL = 0x9291; - public const int TAG_SUBSECOND_TIME_DIGITIZED = 0x9292; - public const int TAG_FLASHPIX_VERSION = 0xA000; - - /// - /// Defines Color Space. DCF image must use sRGB color space so value is always '1'. - /// If the picture uses the other color space, value is '65535':Uncalibrated. - /// - public const int TAG_COLOR_SPACE = 0xA001; - public const int TAG_EXIF_IMAGE_WIDTH = 0xA002; - public const int TAG_EXIF_IMAGE_HEIGHT = 0xA003; - public const int TAG_RELATED_SOUND_FILE = 0xA004; - public const int TAG_FOCAL_PLANE_X_RES = 0xA20E; - public const int TAG_FOCAL_PLANE_Y_RES = 0xA20F; - - /// - /// Unit of FocalPlaneXResoluton/FocalPlaneYResolution. - /// '1' means no-unit, '2' inch, '3' centimeter. - /// - /// Note: Some of Fujifilm'str digicam(e.g.FX2700,FX2900,Finepix4700Z/40i etc) - /// uses value '3' so it must be 'centimeter', but it seems that they use a '8.3mm?' - /// (1/3in.?) to their ResolutionUnit. Fuji'str BUG? Finepix4900Z has been changed to - /// use value '2' but it doesn't match to actual value also. - /// - public const int TAG_FOCAL_PLANE_UNIT = 0xA210; - public const int TAG_EXPOSURE_INDEX = 0xA215; - public const int TAG_SENSING_METHOD = 0xA217; - public const int TAG_FILE_SOURCE = 0xA300; - public const int TAG_SCENE_TYPE = 0xA301; - public const int TAG_CFA_PATTERN = 0xA302; - - public const int TAG_THUMBNAIL_IMAGE_WIDTH = 0x0100; - public const int TAG_THUMBNAIL_IMAGE_HEIGHT = 0x0101; - public const int TAG_THUMBNAIL_DATA = 0xF001; - - // these tags new with Exif 2.2 (?) [A401 - A4 - /// - ///This tag indicates the use of special processing on image data, such as rendering - ///geared to output. When special processing is performed, the reader is expected to - ///disable or minimize any further processing. - ///Tag = 41985 (A401.H) - ///Type = SHORT - ///Count = 1 - ///Default = 0 - /// 0 = Normal process - /// 1 = Custom process - /// Other = reserved - /// - public const int TAG_CUSTOM_RENDERED = 0xA401; - - /// - /// This tag indicates the exposure mode set when the image was shot. In auto-bracketing - /// mode, the camera shoots a series of frames of the same scene at different exposure settings. - /// Tag = 41986 (A402.H) - /// Type = SHORT - /// Count = 1 - /// Default = none - /// 0 = Auto exposure - /// 1 = Manual exposure - /// 2 = Auto bracket - /// Other = reserved - /// - public const int TAG_EXPOSURE_MODE = 0xA402; - - /// - /// This tag indicates the digital zoom ratio when the image was shot. If the - /// numerator of the recorded value is 0, this indicates that digital zoom was - /// not used. - /// Tag = 41988 (A404.H) - /// Type = RATIONAL - /// Count = 1 - /// Default = none - /// - public const int TAG_DIGITAL_ZOOM_RATIO = 0xA404; - - /// - /// This tag indicates the type of scene that was shot. It can also be used to - /// record the mode in which the image was shot. Note that this differs from - /// the scene type (SceneType) tag. - /// Tag = 41990 (A406.H) - /// Type = SHORT - /// Count = 1 - /// Default = 0 - /// 0 = Standard - /// 1 = Landscape - /// 2 = Portrait - /// 3 = Night scene - /// Other = reserved - /// - public const int TAG_SCENE_CAPTURE_TYPE = 0xA406; - - /// - /// This tag indicates the degree of overall image gain adjustment. - /// Tag = 41991 (A407.H) - /// Type = SHORT - /// Count = 1 - /// Default = none - /// 0 = None - /// 1 = Low gain up - /// 2 = High gain up - /// 3 = Low gain down - /// 4 = High gain down - /// Other = reserved - /// - public const int TAG_GAIN_CONTROL = 0xA407; - - /// - /// This tag indicates the direction of contrast processing applied by the camera - /// when the image was shot. - /// Tag = 41992 (A408.H) - /// Type = SHORT - /// Count = 1 - /// Default = 0 - /// 0 = Normal - /// 1 = Soft - /// 2 = Hard - /// Other = reserved - /// - public const int TAG_CONTRAST = 0xA408; - - /// - /// This tag indicates the direction of saturation processing applied by the camera - /// when the image was shot. - /// Tag = 41993 (A409.H) - /// Type = SHORT - /// Count = 1 - /// Default = 0 - /// 0 = Normal - /// 1 = Low saturation - /// 2 = High saturation - /// Other = reserved - /// - public const int TAG_SATURATION = 0xA409; - - /// - /// This tag indicates the direction of sharpness processing applied by the camera - /// when the image was shot. - /// Tag = 41994 (A40A.H) - /// Type = SHORT - /// Count = 1 - /// Default = 0 - /// 0 = Normal - /// 1 = Soft - /// 2 = Hard - /// Other = reserved - /// - public const int TAG_SHARPNESS = 0xA40A; - - // TODO support this tag (I haven't seen a camera'lcStr actual implementation of this yet) - - /// - ///This tag indicates information on the picture-taking conditions of a particular - /// camera model. The tag is used only to indicate the picture-taking conditions in - /// the reader. - /// Tag = 41995 (A40B.H) - /// Type = UNDEFINED - /// Count = Any - /// Default = none - /// - /// The information is recorded in the format shown below. The data is recorded - /// in Unicode using SHORT type for the number of display rows and columns and - /// UNDEFINED type for the camera settings. The Unicode (UCS-2) string including - /// Signature is NULL terminated. The specifics of the Unicode string are as given - /// in ISO/IEC 10464-1. - /// - /// Length Type Meaning - /// ------+-----------+------------------ - /// 2 SHORT Display columns - /// 2 SHORT Display rows - /// Any UNDEFINED Camera setting-1 - /// Any UNDEFINED Camera setting-2 - /// : : : - /// Any UNDEFINED Camera setting-n - /// - public const int TAG_DEVICE_SETTING_DESCRIPTION = 0xA40B; - - /// - /// This tag indicates the distance to the subject. - ///Tag = 41996 (A40C.H) - /// Type = SHORT - /// Count = 1 - /// Default = none - /// 0 = unknown - /// 1 = Macro - /// 2 = Close view - /// 3 = Distant view - /// Other = reserved - /// - public const int TAG_SUBJECT_DISTANCE_RANGE = 0xA40C; - - // Windows Attributes added/found by Ryan Patridge - public const int TAG_XP_TITLE = 0x9C9B; - public const int TAG_XP_COMMENTS = 0x9C9C; - public const int TAG_XP_AUTHOR = 0x9C9D; - public const int TAG_XP_KEYWORDS = 0x9C9E; - public const int TAG_XP_SUBJECT = 0x9C9F; - - - /// - /// This tag indicates the equivalent focal length assuming a 35mm film camera, - /// in mm. A value of 0 means the focal length is unknown. Note that this tag - /// differs from the FocalLength tag. - /// Tag = 41989 (A405.H) - /// Type = SHORT - /// Count = 1 - /// Default = none - /// - public const int TAG_FOCAL_LENGTH_IN_35MM_FILM = 0xA405; - /// - /// This tag indicates an identifier assigned uniquely to each image. It is - /// recorded as an ASCII string equivalent to hexadecimal notation and 128-bit - /// fixed length. - /// Tag = 42016 (A420.H) - /// Type = ASCII - /// Count = 33 - /// Default = none - /// - public const int TAG_IMAGE_UNIQUE_ID = 0xA420; - - - // are these two exif values? - public const int TAG_FILL_ORDER = 0x010A; - public const int TAG_DOCUMENT_NAME = 0x010D; - - public const int TAG_RELATED_IMAGE_FILE_FORMAT = 0x1000; - public const int TAG_RELATED_IMAGE_WIDTH = 0x1001; - public const int TAG_RELATED_IMAGE_LENGTH = 0x1002; - public const int TAG_TRANSFER_RANGE = 0x0156; - public const int TAG_JPEG_PROC = 0x0200; - public const int TAG_EXIF_OFFSET = 0x8769; - public const int TAG_MARKER_NOTE = 0x927C; - public const int TAG_INTEROPERABILITY_OFFSET = 0xA005; - - /// - /// Constructor of the object. - /// - public ExifDirectory() - : base("ExifMarkernote") - { - this.SetDescriptor(new ExifDescriptor(this)); - } - - /// - /// Gets the thumbnail data. - /// - /// the thumbnail data or null if none - public byte[] GetThumbnailData() - { - if (!ContainsThumbnail()) - { - return null; - } - - return this.GetByteArray(ExifDirectory.TAG_THUMBNAIL_DATA); - } - - /// - /// Writes the thumbnail in the given aFile - /// - /// where to write the thumbnail - /// if there is not data in thumbnail - public void WriteThumbnail(string filename) - { - byte[] data = GetThumbnailData(); - - if (data == null) - { - throw new MetadataException("No thumbnail data exists."); - } - - FileStream stream = null; - try - { - stream = new FileStream(filename, FileMode.CreateNew); - stream.Write(data, 0, data.Length); - } - finally - { - if (stream != null) - { - stream.Close(); - stream.Dispose(); - } - } - } - - /// - /// Indicates if there is thumbnail data or not - /// - /// true if there is thumbnail data, false if not - public bool ContainsThumbnail() - { - return ContainsTag(ExifDirectory.TAG_THUMBNAIL_DATA); - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/ExifInteropDescriptor.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/ExifInteropDescriptor.cs deleted file mode 100644 index 6e82fa4e00..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/ExifInteropDescriptor.cs +++ /dev/null @@ -1,98 +0,0 @@ -using System; -using System.Collections; -using System.Text; -using com.drew.metadata; -using com.drew.lang; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// Tag descriptor for almost every images - /// - public class ExifInteropDescriptor : AbstractTagDescriptor - { - /// - /// Constructor of the object - /// - /// a base.directory - public ExifInteropDescriptor(AbstractDirectory aDirectory) : base(aDirectory) - { - } - - /// - /// Returns a descriptive value of the the specified tag for this image. - /// Where possible, known values will be substituted here in place of the raw tokens actually - /// kept in the Exif segment. - /// If no substitution is available, the value provided by GetString(int) will be returned. - /// This and GetString(int) are the only 'get' methods that won't throw an exception. - /// - /// the tag to find a description for - /// a description of the image'str value for the specified tag, or null if the tag hasn't been defined. - public override string GetDescription(int tagType) - { - switch(tagType) - { - case ExifInteropDirectory.TAG_INTEROP_INDEX: - return GetInteropIndexDescription(); - case ExifInteropDirectory.TAG_INTEROP_VERSION: - return GetInteropVersionDescription(); - default: - return base.directory.GetString(tagType); - } - } - - /// - /// Returns the Interop Version Description. - /// - /// the Interop Version Description. - private string GetInteropVersionDescription() - { - if (!base.directory.ContainsTag(ExifInteropDirectory.TAG_INTEROP_VERSION)) - return null; - int[] ints = - base.directory.GetIntArray(ExifInteropDirectory.TAG_INTEROP_VERSION); - return ExifDescriptor.ConvertBytesToVersionString(ints); - } - - /// - /// Returns the Interop index Description. - /// - /// the Interop index Description. - private string GetInteropIndexDescription() - { - if (!base.directory.ContainsTag(ExifInteropDirectory.TAG_INTEROP_INDEX)) - return null; - string interopIndex = - base.directory.GetString(ExifInteropDirectory.TAG_INTEROP_INDEX).Trim(); - if ("R98".Equals(interopIndex.ToUpper())) - { - return BUNDLE["RECOMMENDED_EXIF_INTEROPERABILITY"]; - } - else - { - return BUNDLE["UNKNOWN", interopIndex.ToString()]; - } - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/ExifInteropDirectory.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/ExifInteropDirectory.cs deleted file mode 100644 index 36b18c630f..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/ExifInteropDirectory.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text; -using com.drew.metadata; -using com.drew.lang; -using com.utils.bundle; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// This class represents EXIF INTEROP marker note. - /// - public class ExifInteropDirectory : AbstractDirectory - { - public const int TAG_INTEROP_INDEX = 0x0001; - public const int TAG_INTEROP_VERSION = 0x0002; - public const int TAG_RELATED_IMAGE_FILE_FORMAT = 0x1000; - public const int TAG_RELATED_IMAGE_WIDTH = 0x1001; - public const int TAG_RELATED_IMAGE_LENGTH = 0x1002; - - /// - /// Constructor of the object. - /// - public ExifInteropDirectory() - : base("ExifInteropMarkernote") - { - this.SetDescriptor(new ExifInteropDescriptor(this)); - } - - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/ExifProcessingException.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/ExifProcessingException.cs deleted file mode 100644 index c8014effd0..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/ExifProcessingException.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using System.Collections; -using System.Text; -using com.drew.metadata; -using com.drew.lang; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// The exception type raised during reading of Exif data in the instance of unexpected data conditions. - /// - public class ExifProcessingException : MetadataException - { - /// - /// Constructor of the object - /// - /// The error aMessage - public ExifProcessingException(string message) : base(message) - { - } - - /// - /// Constructor of the object - /// - /// The error aMessage - /// The aCause of the exception - public ExifProcessingException(string message, Exception cause) : base(message, cause) - { - } - - /// - /// Constructor of the object - /// - /// The aCause of the exception - public ExifProcessingException(Exception cause) : base(cause) - { - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/ExifReader.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/ExifReader.cs deleted file mode 100644 index 69e458e03d..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/ExifReader.cs +++ /dev/null @@ -1,1026 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text; -using System.IO; -using com.drew.metadata; -using com.drew.imaging.jpg; -using com.drew.lang; -using com.utils; -using System.Diagnostics; - -/// -/// This class based upon code from Jhead, a C program for extracting and -/// manipulating the Exif data within files written by Matthias Wandel. -/// http://www.sentex.net/~mwandel/jhead/ -/// -/// Jhead is public domain software - that is, you can do whatever -/// you want with it, and include it software that is licensed under -/// the GNU or the BSD license, or whatever other licence you choose, -/// including proprietary closed source licenses. Similarly, I release -/// this Java version under the same license, though I do ask that you -/// leave this lcHeader in tact. -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// Created on 28 April 2002, 23:54 -/// Modified 04 Aug 2002 -/// - Renamed constants to be inline with changes to ExifTagValues interface -/// - Substituted usage of JDK 1.4 features (java.nio package) -/// Modified 29 Oct 2002 (v1.2) -/// - Proper traversing of Exif aFile structure and complete refactor & tidy of -/// the codebase (a few unnoticed bugs removed) -/// - Reads makernote data for 6 families of camera (5 makes) -/// - Tags now stored in directories... use the IFD_* constants to refer to the -/// image aFile directory you require (Exif, Interop, GPS and Makernote*) -/// -- this avoids collisions where two tags share the same code -/// - Takes componentCount of unknown tags into account -/// - Now understands GPS tags (thanks to Colin Briton for his help with this) -/// - Some other bug fixes, pointed out by users around the world. Thanks! -/// Modified 27 Nov 2002 (v2.0) -/// - Renamed to ExifReader -/// - Moved to new package com.drew.aMetadata.exif -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// Extracts Exif data from a JPEG lcHeader segment, providing information about - /// the camera/scanner/capture device (if available). - /// Information is encapsulated in an Metadata object. - /// - public class ExifReader : AbstractMetadataReader - { - - /// - /// Represents the native byte ordering used in the JPEG segment. - /// If true, then we're using Motorolla ordering (Big endian), else - /// we're using Intel ordering (Little endian). - /// - private bool isMotorollaByteOrder; - - /// - /// Bean instance to store information about the image and camera/scanner/capture device. - /// - private Metadata metadata; - private ExifDirectory _exifDirectory; - private ExifDirectory ExifDirectory - { - get - { - if (this._exifDirectory == null) - { - this._exifDirectory = (ExifDirectory)this.metadata.GetDirectory("com.drew.metadata.exif.ExifDirectory"); - - } - return this._exifDirectory; - } - } - - - /// - /// The number of bytes used per format descriptor. - /// - private static readonly int[] BYTES_PER_FORMAT = { 0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8 }; - - /// - /// The number of formats known. - /// - private static readonly int MAX_FORMAT_CODE = 12; - - // the format enumeration - // TODO use the new DataFormat enumeration instead of these values - private const int FMT_BYTE = 1; - private const int FMT_STRING = 2; - private const int FMT_USHORT = 3; - private const int FMT_ULONG = 4; - private const int FMT_URATIONAL = 5; - private const int FMT_SBYTE = 6; - private const int FMT_UNDEFINED = 7; - private const int FMT_SSHORT = 8; - private const int FMT_SLONG = 9; - private const int FMT_SRATIONAL = 10; - private const int FMT_SINGLE = 11; - private const int FMT_DOUBLE = 12; - - public const int TAG_EXIF_OFFSET = 0x8769; - public const int TAG_INTEROP_OFFSET = 0xA005; - public const int TAG_GPS_INFO_OFFSET = 0x8825; - public const int TAG_MAKER_NOTE = 0x927C; - - // NOT READONLY - public static int TIFF_HEADER_START_OFFSET = 6; - - private const string MARK_AS_PROCESSED = "processed"; - - - /// - /// Creates a new ExifReader for the specified Jpeg jpegFile. - /// - /// where to read - public ExifReader(FileInfo aFile) - : base(aFile, JpegSegmentReader.SEGMENT_APP1) - { - } - - /// - /// Constructor of the object - /// - /// the data to read - public ExifReader(byte[] aData) - : base(aData) - { - } - - /// - /// Extract tiff information (used by raw files) - /// - /// where to extract information - /// the information extracted - public Metadata ExtractTiff(Metadata aMetadata) - { - return this.ExtractIFD(aMetadata, 0); - } - - /// - /// Reads metatdata from raw file. - /// - /// a meta data - /// an offset - /// the metadata found - private Metadata ExtractIFD(Metadata aMetadata, int aTiffHeaderOffset) - { - this.metadata = aMetadata; - if (base.data == null) - { - return this.metadata; - } - - ExifDirectory directory = this.ExifDirectory; - - // this should be either "MM" or "II" - string byteOrderIdentifier = Utils.Decode(base.data, aTiffHeaderOffset, 2, false); - if (!this.SetByteOrder(byteOrderIdentifier)) - { - directory.HasError = true; - Trace.TraceError("Unclear distinction between Motorola/Intel byte ordering: " - + byteOrderIdentifier); - return this.metadata; - } - - // Check the next two values for correctness. - if (this.Get16Bits(2 + aTiffHeaderOffset) != 0x2a) - { - // directory.AddError("Invalid Exif start - should have 0x2A at offset 8 in Exif header"); - // return this.metadata; - } - - int firstDirectoryOffset = this.Get32Bits(4 + aTiffHeaderOffset) + aTiffHeaderOffset; - - // David Ekholm sent an digital camera image that has this problem - if (firstDirectoryOffset >= base.data.Length - 1) - { - directory.HasError = true; - Trace.TraceError("First exif directory offset is beyond end of Exif data segment"); - // First directory normally starts 14 bytes in -- try it here and catch another error in the worst case - firstDirectoryOffset = 14; - } - - IDictionary processedDirectoryOffsets = new Dictionary(); - - // 0th IFD (we merge with Exif IFD) - try - { - this.ProcessDirectory(directory, processedDirectoryOffsets, - firstDirectoryOffset, aTiffHeaderOffset); - } - catch (Exception e) - { - throw new MetadataException(e); - } - - // after the extraction process, if we have the correct tags, we may be able to store thumbnail information - this.StoreThumbnailBytes(directory, aTiffHeaderOffset); - - return this.metadata; - } - - - /// - /// Performs the Exif data extraction, adding found values to the specified instance of Metadata. - /// - /// where to add meta data - /// the aMetadata - public override Metadata Extract(Metadata metadata) - { - this.metadata = metadata; - if (base.data == null) - { - return this.metadata; - } - - // once we know there'str some data, create the directory and start working on it - AbstractDirectory directory = this.metadata.GetDirectory("com.drew.metadata.exif.ExifDirectory"); - - if (base.data.Length <= 14) - { - directory.HasError = true; - Trace.TraceError("Exif data segment must contain at least 14 bytes"); - return this.metadata; - } - if (!"Exif\0\0".Equals(Utils.Decode(base.data, 0, 6, false))) - { - directory.HasError = true; - Trace.TraceError("Exif data segment doesn't begin with 'Exif'"); - return this.metadata; - } - - // this should be either "MM" or "II" - string byteOrderIdentifier = Utils.Decode(base.data, 6, 2, false); - if (!SetByteOrder(byteOrderIdentifier)) - { - directory.HasError = true; - Trace.TraceError("Unclear distinction between Motorola/Intel byte ordering"); - return this.metadata; - } - - // Check the next two values for correctness. - if (Get16Bits(8) != 0x2a) - { - directory.HasError = true; - Trace.TraceError("Invalid Exif start - should have 0x2A at offSet 8 in Exif header"); - return this.metadata; - } - - int firstDirectoryOffSet = Get32Bits(10) + TIFF_HEADER_START_OFFSET; - - // David Ekholm sent an digital camera image that has this problem - if (firstDirectoryOffSet >= base.data.Length - 1) - { - directory.HasError = true; - Trace.TraceError("First exif directory offSet is beyond end of Exif data segment"); - // First directory normally starts 14 bytes in -- try it here and catch another error in the worst case - firstDirectoryOffSet = 14; - } - - // 0th IFD (we merge with Exif IFD) - //ProcessDirectory(directory, firstDirectoryOffSet); - // after the extraction process, if we have the correct tags, we may be able to extract thumbnail information - //ExtractThumbnail(directory); - - Dictionary processedDirectoryOffsets = new Dictionary(); - - // 0th IFD (we merge with Exif IFD) - ProcessDirectory(directory, processedDirectoryOffsets, firstDirectoryOffSet, TIFF_HEADER_START_OFFSET); - - // after the extraction process, if we have the correct tags, we may be able to store thumbnail information - StoreThumbnailBytes(directory, TIFF_HEADER_START_OFFSET); - - - return this.metadata; - } - - /// - /// Will stock the thumbnail into exif directory if available. - /// - /// where to stock the thumbnail - /// the tiff lcHeader lcOffset value - private void StoreThumbnailBytes(AbstractDirectory exifDirectory, int tiffHeaderOffset) - { - if (!exifDirectory.ContainsTag(ExifDirectory.TAG_COMPRESSION)) - { - return; - } - - if (!exifDirectory.ContainsTag(ExifDirectory.TAG_THUMBNAIL_LENGTH) || - !exifDirectory.ContainsTag(ExifDirectory.TAG_THUMBNAIL_OFFSET)) - { - return; - } - try - { - int offset = exifDirectory.GetInt(ExifDirectory.TAG_THUMBNAIL_OFFSET); - int length = exifDirectory.GetInt(ExifDirectory.TAG_THUMBNAIL_LENGTH); - byte[] result = new byte[length]; - Buffer.BlockCopy(base.data, tiffHeaderOffset + offset, result, 0, length); - //for (int i = 0; i < result.Length; i++) - //{ - // result[i] = base.data[tiffHeaderOffset + offset + i]; - //} - exifDirectory.SetObject(ExifDirectory.TAG_THUMBNAIL_DATA, result); - } - catch (Exception e) - { - exifDirectory.HasError = true; - Trace.TraceError("Unable to extract thumbnail: " + e.Message); - } - } - - - /// - /// Sets Motorolla byte order and idicates that it was found. - /// - /// true if the Motorolla byte order is identified - /// - private bool SetByteOrder(string byteOrderIdentifier) - { - if ("MM".Equals(byteOrderIdentifier)) - { - this.isMotorollaByteOrder = true; - return true; - } - else if ("II".Equals(byteOrderIdentifier)) - { - this.isMotorollaByteOrder = false; - return true; - } - return false; - } - - /// - /// Indicates if Directory Length is valid or not - /// - /// where to start - /// The tiff lcHeader lcOffset - /// true if Directory Length is valid - private bool IsDirectoryLengthValid(int dirStartOffset, int tiffHeaderOffset) - { - int dirTagCount = Get16Bits(dirStartOffset); - int dirLength = (2 + (12 * dirTagCount) + 4); - // Note: Files that had thumbnails trimmed with jhead 1.3 or earlier might trigger this - return !(dirLength + dirStartOffset + tiffHeaderOffset >= base.data.Length); - } - - /// - /// Determine the lcOffset at which a given InteropArray entry begins within the specified IFD. - /// - /// the lcOffset at which the IFD starts - /// the zero-based entry number - /// the lcOffset at which a given InteropArray entry begins within the specified IFD - private int CalculateTagOffset(int dirStartOffset, int entryNumber) - { - // add 2 bytes for the tag count - // each entry is 12 bytes, so we skip 12 * the number seen so far - return dirStartOffset + 2 + (12 * entryNumber); - } - - /// - /// Calculates tag value lcOffset - /// - /// the byte count - /// the dir entry lcOffset - /// the tiff lcHeader ofset - /// -1 if error, or the valus lcOffset - private int CalculateTagValueOffset(int byteCount, int dirEntryOffset, int tiffHeaderOffset) - { - if (byteCount > 4) - { - // If its bigger than 4 bytes, the dir entry contains an lcOffset. - // dirEntryOffset must be passed, as some makernote implementations (e.g. FujiFilm) incorrectly use an - // lcOffset relative to the start of the makernote itself, not the TIFF segment. - int offsetVal = Get32Bits(dirEntryOffset + 8); - if (offsetVal + byteCount > base.data.Length) - { - // Bogus pointer lcOffset and / or bytecount value - return -1; // signal error - } - return tiffHeaderOffset + offsetVal; - } - // 4 bytes or less and value is in the dir entry itself - return dirEntryOffset + 8; - } - - - /// - /// Process one of the nested Tiff IFD directories. - /// 2 bytes: number of tags for each tag - /// 2 bytes: tag type - /// 2 bytes: format code - /// 4 bytes: component count - /// - /// the directory - /// where to start - private void ProcessDirectory(AbstractDirectory directory, IDictionary processedDirectoryOffsets, int dirStartOffset, int tiffHeaderOffset) - { - // check for directories we've already visited to avoid stack overflows when recursive/cyclic directory structures exist - if (processedDirectoryOffsets.ContainsKey(dirStartOffset)) - { - return; - } - // remember that we've visited this directory so that we don't visit it again later - processedDirectoryOffsets.Add(dirStartOffset, MARK_AS_PROCESSED); - - if (dirStartOffset >= base.data.Length || dirStartOffset < 0) - { - directory.HasError = true; - Trace.TraceError("Ignored directory marked to start outside data segement"); - return; - } - - if (!IsDirectoryLengthValid(dirStartOffset, tiffHeaderOffset)) - { - directory.HasError = true; - Trace.TraceError("Illegally sized directory"); - return; - } - - // First two bytes in the IFD are the tag count - int dirTagCount = Get16Bits(dirStartOffset); - - // Handle each tag in this directory - for (int tagNumber = 0; tagNumber < dirTagCount; tagNumber++) - { - int tagOffset = CalculateTagOffset(dirStartOffset, tagNumber); - - // 2 bytes for the tag type - int tagType = Get16Bits(tagOffset); - - // 2 bytes for the format code - int formatCode = Get16Bits(tagOffset + 2); - if (formatCode < 1 || formatCode > MAX_FORMAT_CODE) - { - directory.HasError = true; - Trace.TraceError("Invalid format code: " + formatCode); - continue; - } - - // 4 bytes dictate the number of components in this tag'lcStr data - int componentCount = Get32Bits(tagOffset + 4); - if (componentCount < 0) - { - directory.HasError = true; - Trace.TraceError("Negative component count in EXIF"); - continue; - } - - // each component may have more than one byte... calculate the total number of bytes - int byteCount = componentCount * BYTES_PER_FORMAT[formatCode]; - int tagValueOffset = CalculateTagValueOffset(byteCount, tagOffset, tiffHeaderOffset); - if (tagValueOffset < 0 || tagValueOffset > base.data.Length) - { - directory.HasError = true; - Trace.TraceError("Illegal pointer offset value in EXIF"); - continue; - } - - - // Check that this tag isn't going to allocate outside the bounds of the data array. - // This addresses an uncommon OutOfMemoryError. - if (byteCount < 0 || tagValueOffset + byteCount > base.data.Length) - { - directory.HasError = true; - Trace.TraceError("Illegal number of bytes: " + byteCount); - continue; - } - - // Calculate the value as an lcOffset for cases where the tag represents directory - int subdirOffset = tiffHeaderOffset + Get32Bits(tagValueOffset); - - switch (tagType) - { - case TAG_EXIF_OFFSET: - ProcessDirectory(this.metadata.GetDirectory("com.drew.metadata.exif.ExifDirectory"), processedDirectoryOffsets, subdirOffset, tiffHeaderOffset); - continue; - case TAG_INTEROP_OFFSET: - ProcessDirectory(this.metadata.GetDirectory("com.drew.metadata.exif.ExifInteropDirectory"), processedDirectoryOffsets, subdirOffset, tiffHeaderOffset); - continue; - case TAG_GPS_INFO_OFFSET: - ProcessDirectory(this.metadata.GetDirectory("com.drew.metadata.exif.GpsDirectory"), processedDirectoryOffsets, subdirOffset, tiffHeaderOffset); - continue; - case TAG_MAKER_NOTE: - ProcessMakerNote(tagValueOffset, processedDirectoryOffsets, tiffHeaderOffset); - continue; - default: - ProcessTag(directory, tagType, tagValueOffset, componentCount, formatCode); - break; - } - } // End of for - // at the end of each IFD is an optional link to the next IFD - int finalTagOffset = CalculateTagOffset(dirStartOffset, dirTagCount); - int nextDirectoryOffset = Get32Bits(finalTagOffset); - if (nextDirectoryOffset != 0) - { - nextDirectoryOffset += tiffHeaderOffset; - if (nextDirectoryOffset >= base.data.Length) - { - Trace.TraceWarning("Last 4 bytes of IFD reference another IFD with an address that is out of bounds\nNote this could have been caused by jhead 1.3 cropping too much"); - return; - } - else if (nextDirectoryOffset < dirStartOffset) - { - Trace.TraceWarning("Last 4 bytes of IFD reference another IFD with an address that is before the start of this directory"); - return; - } - // the next directory is of same type as this one - ProcessDirectory(directory, processedDirectoryOffsets, nextDirectoryOffset, tiffHeaderOffset); - } - } - - /// - /// Determine the camera model and makernote format - /// - /// the sub lcOffset dir - /// the processed directory offsets - /// the tiff lcHeader lcOffset - private void ProcessMakerNote(int subdirOffset, IDictionary processedDirectoryOffsets, int tiffHeaderOffset) - { - // Console.WriteLine("ProcessMakerNote value="+subdirOffSet); - // Determine the camera model and makernote format - AbstractDirectory exifDirectory = this.metadata.GetDirectory("com.drew.metadata.exif.ExifDirectory"); - if (exifDirectory == null) - { - return; - } - - string cameraModel = exifDirectory.GetString(ExifDirectory.TAG_MAKE); - string firstTwoChars = Utils.Decode(base.data, subdirOffset, 2, false); - string firstThreeChars = Utils.Decode(base.data, subdirOffset, 3, false); - string firstFourChars = Utils.Decode(base.data, subdirOffset, 4, false); - string firstFiveChars = Utils.Decode(base.data, subdirOffset, 5, false); - string firstSixChars = Utils.Decode(base.data, subdirOffset, 6, false); - string firstSevenChars = Utils.Decode(base.data, subdirOffset, 7, false); - string firstEightChars = Utils.Decode(base.data, subdirOffset, 8, false); - - if ("OLYMP".Equals(firstFiveChars) || "EPSON".Equals(firstFiveChars) || "AGFA".Equals(firstFourChars)) - { - Trace.TraceInformation("Found an Olympus/Epson/Agfa directory."); - // Olympus Makernote - // Epson and Agfa use Olypus maker note standard, see: - // http://www.ozhiker.com/electronics/pjmt/jpeg_info/ - ProcessDirectory( - this.metadata.GetDirectory("com.drew.metadata.exif.OlympusDirectory"), processedDirectoryOffsets, subdirOffset + 8, tiffHeaderOffset); - } - else if (cameraModel != null && cameraModel.Trim().ToUpper().StartsWith("NIKON")) - { - if ("Nikon".Equals(Utils.Decode(base.data, subdirOffset, 5, false))) - { - // There are two scenarios here: - // Type 1: - // :0000: 4E 69 6B 6F 6E 00 01 00-05 00 02 00 02 00 06 00 Nikon........... - // :0010: 00 00 EC 02 00 00 03 00-03 00 01 00 00 00 06 00 ................ - // Type 3: - // :0000: 4E 69 6B 6F 6E 00 02 00-00 00 4D 4D 00 2A 00 00 Nikon....MM.*... - // :0010: 00 08 00 1E 00 01 00 07-00 00 00 04 30 32 30 30 ............0200 - if (base.data[subdirOffset + 6] == 1) - { - Trace.TraceInformation("Found an Nykon Type 1 directory."); - ProcessDirectory( - this.metadata.GetDirectory("com.drew.metadata.exif.NikonType1Directory"), processedDirectoryOffsets, subdirOffset + 8, tiffHeaderOffset); - } - else if (base.data[subdirOffset + 6] == 2) - { - Trace.TraceInformation("Found an Nykon Type 2 directory."); - ProcessDirectory( - this.metadata.GetDirectory("com.drew.metadata.exif.NikonType2Directory"), processedDirectoryOffsets, subdirOffset + 18, subdirOffset + 10); - } - else - { - exifDirectory.HasError = true; - Trace.TraceError( - "Unsupported makernote for Nikon data ignored."); - } - } - else - { - Trace.TraceInformation("Found an Nykon Type 2 directory."); - ProcessDirectory( - this.metadata.GetDirectory("com.drew.metadata.exif.NikonType2Directory"), processedDirectoryOffsets, subdirOffset, tiffHeaderOffset); - } - } - else if ("SONY CAM".Equals(firstEightChars) || "SONY DSC".Equals(firstEightChars)) - { - Trace.TraceInformation("Found a Sony directory."); - ProcessDirectory( - this.metadata.GetDirectory("com.drew.metadata.exif.SonyDirectory"), processedDirectoryOffsets, subdirOffset + 12, tiffHeaderOffset); - } - else if ("KDK".Equals(firstThreeChars)) - { - Trace.TraceInformation("Found a Kodak directory."); - ProcessDirectory( - this.metadata.GetDirectory("com.drew.metadata.exif.KodakDirectory"), processedDirectoryOffsets, subdirOffset + 20, tiffHeaderOffset); - } - - - else if ("Canon".ToUpper().Equals(cameraModel.ToUpper())) - { - Trace.TraceInformation("Found a Canon directory."); - ProcessDirectory( - this.metadata.GetDirectory("com.drew.metadata.exif.CanonDirectory"), processedDirectoryOffsets, subdirOffset, tiffHeaderOffset); - } - else if (cameraModel != null && cameraModel.ToUpper().StartsWith("CASIO")) - { - if ("QVC\u0000\u0000\u0000".Equals(firstSixChars)) - { - Trace.TraceInformation("Found a Casion Type 2 directory."); - ProcessDirectory(this.metadata.GetDirectory("com.drew.metadata.exif.CasioType2Directory"), processedDirectoryOffsets, subdirOffset + 6, tiffHeaderOffset); - } - else - { - Trace.TraceInformation("Found a Casion Type 1 directory."); - ProcessDirectory(this.metadata.GetDirectory("com.drew.metadata.exif.CasioType1Directory"), processedDirectoryOffsets, subdirOffset, tiffHeaderOffset); - } - } - else if ("FUJIFILM".Equals(firstEightChars) || "Fujifilm".ToUpper().Equals(cameraModel.ToUpper())) - { - Trace.TraceInformation("Found a Fujifilm directory."); - // TODO make this field a passed parameter, to avoid threading issues - bool byteOrderBefore = this.isMotorollaByteOrder; - // bug in fujifilm makernote ifd means we temporarily use Intel byte ordering - this.isMotorollaByteOrder = false; - // the 4 bytes after "FUJIFILM" in the makernote point to the start of the makernote - // IFD, though the lcOffset is relative to the start of the makernote, not the TIFF - // lcHeader (like everywhere else) - int ifdStart = subdirOffset + Get32Bits(subdirOffset + 8); - ProcessDirectory(this.metadata.GetDirectory("com.drew.metadata.exif.FujifilmDirectory"), processedDirectoryOffsets, ifdStart, tiffHeaderOffset); - this.isMotorollaByteOrder = byteOrderBefore; - } - else if (cameraModel != null && cameraModel.ToUpper().StartsWith("MINOLTA")) - { - Trace.TraceInformation("Found a Minolta directory, will use Olympus directory."); - // Cases seen with the model starting with MINOLTA in capitals seem to have a valid Olympus makernote - // area that commences immediately. - ProcessDirectory(this.metadata.GetDirectory("com.drew.metadata.exif.OlympusDirectory"), processedDirectoryOffsets, subdirOffset, tiffHeaderOffset); - } - else if ("KC".Equals(firstTwoChars) || "MINOL".Equals(firstFiveChars) || "MLY".Equals(firstThreeChars) || "+M+M+M+M".Equals(firstEightChars)) - { - // This Konica data is not understood. Header identified in accordance with information at this site: - // http://www.ozhiker.com/electronics/pjmt/jpeg_info/minolta_mn.html - // TODO determine how to process the information described at the above website - Trace.TraceError("Unsupported Konica/Minolta data ignored."); - } - else if ("KYOCERA".Equals(firstSevenChars)) - { - Trace.TraceInformation("Found a Kyocera directory"); - // http://www.ozhiker.com/electronics/pjmt/jpeg_info/kyocera_mn.html - ProcessDirectory(this.metadata.GetDirectory("com.drew.metadata.exif.KyoceraDirectory"), processedDirectoryOffsets, subdirOffset + 22, tiffHeaderOffset); - } - else if ("Panasonic\u0000\u0000\u0000".Equals(Utils.Decode(base.data, subdirOffset, 12, false))) - { - Trace.TraceInformation("Found a panasonic directory"); - // NON-Standard TIFF IFD Data using Panasonic Tags. There is no Next-IFD pointer after the IFD - // Offsets are relative to the start of the TIFF lcHeader at the beginning of the EXIF segment - // more information here: http://www.ozhiker.com/electronics/pjmt/jpeg_info/panasonic_mn.html - ProcessDirectory(this.metadata.GetDirectory("com.drew.metadata.exif.PanasonicDirectory"), processedDirectoryOffsets, subdirOffset + 12, tiffHeaderOffset); - } - else if ("AOC\u0000".Equals(firstFourChars)) - { - Trace.TraceInformation("Found a Casio type 2 directory"); - // NON-Standard TIFF IFD Data using Casio Type 2 Tags - // IFD has no Next-IFD pointer at end of IFD, and - // Offsets are relative to the start of the current IFD tag, not the TIFF lcHeader - // Observed for: - // - Pentax ist D - ProcessDirectory(this.metadata.GetDirectory("com.drew.metadata.exif.CasioType2Directory"), processedDirectoryOffsets, subdirOffset + 6, subdirOffset); - } - else if (cameraModel != null && (cameraModel.ToUpper().StartsWith("PENTAX") || cameraModel.ToUpper().StartsWith("ASAHI"))) - { - Trace.TraceInformation("Found a Pentax directory"); - // NON-Standard TIFF IFD Data using Pentax Tags - // IFD has no Next-IFD pointer at end of IFD, and - // Offsets are relative to the start of the current IFD tag, not the TIFF lcHeader - // Observed for: - // - PENTAX Optio 330 - // - PENTAX Optio 430 - ProcessDirectory(this.metadata.GetDirectory("com.drew.metadata.exif.PentaxDirectory"), processedDirectoryOffsets, subdirOffset, subdirOffset); - } - else - { - // TODO how to store makernote data when it'str not from a supported camera model? - Trace.TraceError("Unsupported directory data ignored."); - } - } - - - /// - /// Processes tag - /// - /// the directory - /// the tag type - /// the lcOffset value - /// the component count - /// the format code - private void ProcessTag( - AbstractDirectory directory, - int tagType, - int tagValueOffset, - int componentCount, - int formatCode) - { - // Directory simply stores raw values - // The display side uses a Descriptor class per directory to turn the raw values into 'pretty' descriptions - switch (formatCode) - { - case FMT_UNDEFINED: - Debug.Write("Found a tag made of bytes"); - // this includes exif user comments - byte[] tagBytes = new byte[componentCount]; - int byteCount = componentCount * BYTES_PER_FORMAT[formatCode]; - for (int i = 0; i < byteCount; i++) - { - tagBytes[i] = base.data[tagValueOffset + i]; - } - directory.SetObject(tagType, tagBytes); - break; - case FMT_STRING: - Debug.Write("Found a tag made of string"); - string lcStr = null; - if (tagType == ExifDirectory.TAG_USER_COMMENT) - { - lcStr = - ReadCommentString( - tagValueOffset, - componentCount, - formatCode); - } - else - { - lcStr = ReadString(tagValueOffset, componentCount); - } - directory.SetObject(tagType, lcStr); - break; - case FMT_SRATIONAL: //goto case FMT_URATIONAL; - case FMT_URATIONAL: - if (componentCount == 1) - { - Debug.Write("Found a tag made of rational"); - Rational rational = new Rational(Get32Bits(tagValueOffset), Get32Bits(tagValueOffset + 4)); - directory.SetObject(tagType, rational); - - } - else - { - Debug.Write("Found a tag made of rationals"); - Rational[] rationals = new Rational[componentCount]; - for (int i = 0; i < componentCount; i++) - { - rationals[i] = new Rational(Get32Bits(tagValueOffset + (8 * i)), Get32Bits(tagValueOffset + 4 + (8 * i))); - } - directory.SetObject(tagType, rationals); - - } - - break; - case FMT_SBYTE: //goto case FMT_BYTE; - case FMT_BYTE: - if (componentCount == 1) - { - Debug.Write("Found a tag made of byte"); - // this may need to be a byte, but I think casting to int is fine - int b = base.data[tagValueOffset]; - directory.SetObject(tagType, b); - } - else - { - Debug.Write("Found a tag made of bytes but will use ints"); - int[] bytes = new int[componentCount]; - for (int i = 0; i < componentCount; i++) - { - bytes[i] = base.data[tagValueOffset + i]; - } - directory.SetIntArray(tagType, bytes); - } - break; - case FMT_SINGLE: //goto case FMT_DOUBLE; - case FMT_DOUBLE: - if (componentCount == 1) - { - Debug.Write("Found a tag made of double but will use int"); - int i = base.data[tagValueOffset]; - directory.SetObject(tagType, i); - } - else - { - Debug.Write("Found a tag made of doubles but will use ints"); - int[] ints = new int[componentCount]; - for (int i = 0; i < componentCount; i++) - { - ints[i] = base.data[tagValueOffset + i]; - } - directory.SetIntArray(tagType, ints); - } - break; - case FMT_USHORT: //goto case FMT_SSHORT; - case FMT_SSHORT: - if (componentCount == 1) - { - Debug.Write("Found a tag made of short but will use int"); - int i = Get16Bits(tagValueOffset); - directory.SetObject(tagType, i); - } - else - { - Debug.Write("Found a tag made of shorts but will use ints"); - int[] ints = new int[componentCount]; - for (int i = 0; i < componentCount; i++) - { - ints[i] = Get16Bits(tagValueOffset + (i * 2)); - } - directory.SetIntArray(tagType, ints); - } - break; - case FMT_SLONG: //goto case FMT_ULONG; - case FMT_ULONG: - if (componentCount == 1) - { - Debug.Write("Found a tag made of long but will use int"); - int i = Get32Bits(tagValueOffset); - directory.SetObject(tagType, i); - } - else - { - Debug.Write("Found a tag made of longs but will use ints"); - int[] ints = new int[componentCount]; - for (int i = 0; i < componentCount; i++) - { - ints[i] = Get32Bits(tagValueOffset + (i * 4)); - } - directory.SetIntArray(tagType, ints); - } - break; - default: - Trace.TraceWarning("Unknown format code " + formatCode + " for tag " + tagType); - break; - } - } - - /// - /// Creates a string from the _data buffer starting at the specified offSet, - /// and ending where byte=='\0' or where Length==maxLength. - /// - /// the lcOffset - /// the max length - /// a string representing what was read - private string ReadString(int offSet, int maxLength) - { - int Length = 0; - while ((offSet + Length) < base.data.Length - && base.data[offSet + Length] != '\0' - && Length < maxLength) - { - Length++; - } - return Utils.Decode(base.data, offSet, Length, false); - } - - /// - /// A special case of ReadString that handle Exif UserComment reading. - /// This method is necessary as certain camere models prefix the comment string - /// with "ASCII\0", which is all that would be returned by ReadString(...). - /// - /// the tag value lcOffset - /// the component count - /// the format code - /// a string - private string ReadCommentString( - int tagValueOffSet, - int componentCount, - int formatCode) - { - // Olympus has this padded with trailing spaces. Remove these first. - // ArrayIndexOutOfBoundsException bug fixed by Hendrik Wördehoff - 20 Sep 2002 - int byteCount = componentCount * BYTES_PER_FORMAT[formatCode]; - for (int i = byteCount - 1; i >= 0; i--) - { - if (base.data[tagValueOffSet + i] == ' ') - { - base.data[tagValueOffSet + i] = (byte)'\0'; - } - else - { - break; - } - } - // Copy the comment - if ("ASCII".Equals(Utils.Decode(base.data, tagValueOffSet, 5, false))) - { - for (int i = 5; i < 10; i++) - { - byte b = base.data[tagValueOffSet + i]; - if (b != '\0' && b != ' ') - { - return ReadString(tagValueOffSet + i, 1999); - } - } - } - else if ("UNICODE".Equals(Utils.Decode(base.data, tagValueOffSet, 7, false))) - { - int start = tagValueOffSet + 7; - for (int i = start; i < 10 + start; i++) - { - byte b = base.data[i]; - if (b == 0 || (char)b == ' ') - { - continue; - } - else - { - start = i; - break; - } - - } - int end = base.data.Length; - // TODO find a way to cut the string properly - return Utils.Decode(base.data, start, end - start, true); - - } - - // TODO implement support for UNICODE and JIS UserComment encodings..? - return ReadString(tagValueOffSet, 1999); - } - - /// - /// Determine the offSet at which a given InteropArray entry begins within the specified IFD. - /// - /// the offSet at which the IFD starts - /// the zero-based entry number - /// the directory entry lcOffset - private int CalculateDirectoryEntryOffSet( - int ifdStartOffSet, - int entryNumber) - { - return (ifdStartOffSet + 2 + (12 * entryNumber)); - } - - - /// - /// Gets a 16 bit aValue from aFile'str native byte order. Between 0x0000 and 0xFFFF. - /// - /// the lcOffset - /// a 16 bit int - protected override int Get16Bits(int offSet) - { - if (offSet < 0 || offSet >= base.data.Length) - { - throw new IndexOutOfRangeException( - "attempt to read data outside of exif segment (index " - + offSet - + " where max index is " - + (base.data.Length - 1) - + ")"); - } - if (this.isMotorollaByteOrder) - { - // Motorola big first - return (base.data[offSet] << 8 & 0xFF00) | (base.data[offSet + 1] & 0xFF); - } - else - { - // Intel ordering - return (base.data[offSet + 1] << 8 & 0xFF00) | (base.data[offSet] & 0xFF); - } - } - - /// - /// Gets a 32 bit aValue from aFile'str native byte order. - /// - /// the lcOffset - /// a 32b int - protected override int Get32Bits(int offSet) - { - if (offSet < 0 || offSet >= base.data.Length) - { - throw new IndexOutOfRangeException( - "attempt to read data outside of exif segment (index " - + offSet - + " where max index is " - + (base.data.Length - 1) - + ")"); - } - - if (this.isMotorollaByteOrder) - { - // Motorola big first - return (int)(((uint)(base.data[offSet] << 24 & 0xFF000000)) - | ((uint)(base.data[offSet + 1] << 16 & 0xFF0000)) - | ((uint)(base.data[offSet + 2] << 8 & 0xFF00)) - | ((uint)(base.data[offSet + 3] & 0xFF))); - } - else - { - // Intel ordering - return (int)(((uint)(base.data[offSet + 3] << 24 & 0xFF000000)) - | ((uint)(base.data[offSet + 2] << 16 & 0xFF0000)) - | ((uint)(base.data[offSet + 1] << 8 & 0xFF00)) - | ((uint)(base.data[offSet] & 0xFF))); - } - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/FujifilmDescriptor.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/FujifilmDescriptor.cs deleted file mode 100644 index 82e3c4c444..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/FujifilmDescriptor.cs +++ /dev/null @@ -1,452 +0,0 @@ -using System; -using System.Collections; -using System.Text; -using System.IO; -using com.drew.metadata; -using com.drew.lang; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// Fujifilm'str digicam added the MakerNote tag from the Year2000'str model - /// (e.g.Finepix1400, Finepix4700). It uses IFD format and start from ASCII character - /// 'FUJIFILM', and next 4 bytes(aValue 0x000c) points the offSet to first IFD entry. - /// Example of actual data structure is shown below. - /// :0000: 46 55 4A 49 46 49 4C 4D-0C 00 00 00 0F 00 00 00 :0000: FUJIFILM........ - /// :0010: 07 00 04 00 00 00 30 31-33 30 00 10 02 00 08 00 :0010: ......0130...... - /// There are two big differences to the other manufacturers. - /// - Fujifilm'str Exif data uses Motorola align, but MakerNote ignores it and uses Intel align. - /// - The other manufacturer'str MakerNote counts the "offSet to data" from the first byte of - /// TIFF lcHeader (same as the other IFD), but Fujifilm counts it from the first byte of MakerNote itself. - /// - public class FujifilmDescriptor : AbstractTagDescriptor - { - /// - /// Constructor of the object - /// - /// a base.directory - public FujifilmDescriptor(AbstractDirectory aDirectory) : base(aDirectory) - { - } - - /// - /// Returns a descriptive value of the the specified tag for this image. - /// Where possible, known values will be substituted here in place of the raw tokens actually - /// kept in the Exif segment. - /// If no substitution is available, the value provided by GetString(int) will be returned. - /// This and GetString(int) are the only 'get' methods that won't throw an exception. - /// - /// the tag to find a description for - /// a description of the image'str value for the specified tag, or null if the tag hasn't been defined. - public override string GetDescription(int tagType) - { - switch(tagType) - { - case FujifilmDirectory.TAG_FUJIFILM_SHARPNESS : - return GetSharpnessDescription(); - case FujifilmDirectory.TAG_FUJIFILM_WHITE_BALANCE : - return GetWhiteBalanceDescription(); - case FujifilmDirectory.TAG_FUJIFILM_COLOR : - return GetColorDescription(); - case FujifilmDirectory.TAG_FUJIFILM_TONE : - return GetToneDescription(); - case FujifilmDirectory.TAG_FUJIFILM_FLASH_MODE : - return GetFlashModeDescription(); - case FujifilmDirectory.TAG_FUJIFILM_FLASH_STRENGTH : - return GetFlashStrengthDescription(); - case FujifilmDirectory.TAG_FUJIFILM_MACRO : - return GetMacroDescription(); - case FujifilmDirectory.TAG_FUJIFILM_FOCUS_MODE : - return GetFocusModeDescription(); - case FujifilmDirectory.TAG_FUJIFILM_SLOW_SYNCHRO : - return GetSlowSyncDescription(); - case FujifilmDirectory.TAG_FUJIFILM_PICTURE_MODE : - return GetPictureModeDescription(); - case FujifilmDirectory.TAG_FUJIFILM_CONTINUOUS_TAKING_OR_AUTO_BRACKETTING : - return GetContinuousTakingOrAutoBrackettingDescription(); - case FujifilmDirectory.TAG_FUJIFILM_BLUR_WARNING : - return GetBlurWarningDescription(); - case FujifilmDirectory.TAG_FUJIFILM_FOCUS_WARNING : - return GetFocusWarningDescription(); - case FujifilmDirectory.TAG_FUJIFILM_AE_WARNING : - return GetAutoExposureWarningDescription(); - default : - return base.directory.GetString(tagType); - } - } - - /// - /// Returns the Auto Exposure Description. - /// - /// the Auto Exposure Description. - private string GetAutoExposureWarningDescription() - { - if (!base.directory - .ContainsTag(FujifilmDirectory.TAG_FUJIFILM_AE_WARNING)) - return null; - int aValue = - base.directory.GetInt( - FujifilmDirectory.TAG_FUJIFILM_AE_WARNING); - switch (aValue) - { - case 0 : - return BUNDLE["AE_GOOD"]; - case 1 : - return BUNDLE["OVER_EXPOSED"]; - default : - return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - - /// - /// Returns the Focus Warning Description. - /// - /// the Focus Warning Description. - private string GetFocusWarningDescription() - { - if (!base.directory - .ContainsTag(FujifilmDirectory.TAG_FUJIFILM_FOCUS_WARNING)) - return null; - int aValue = - base.directory.GetInt( - FujifilmDirectory.TAG_FUJIFILM_FOCUS_WARNING); - switch (aValue) - { - case 0 : - return BUNDLE["AUTO_FOCUS_GOOD"]; - case 1 : - return BUNDLE["OUT_OF_FOCUS"]; - default : - return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - - /// - /// Returns the Blur Warning Description. - /// - /// the Blur Warning Description. - private string GetBlurWarningDescription() - { - if (!base.directory - .ContainsTag(FujifilmDirectory.TAG_FUJIFILM_BLUR_WARNING)) - return null; - int aValue = - base.directory.GetInt( - FujifilmDirectory.TAG_FUJIFILM_BLUR_WARNING); - switch (aValue) - { - case 0 : - return BUNDLE["NO_BLUR_WARNING"]; - case 1 : - return BUNDLE["BLUR_WARNING"]; - default : - return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - - /// - /// Returns the Continuous Taking Or AutoBracketting Description. - /// - /// the Continuous Taking Or AutoBracketting Description. - private string GetContinuousTakingOrAutoBrackettingDescription() - { - if (!base.directory - .ContainsTag( - FujifilmDirectory - .TAG_FUJIFILM_CONTINUOUS_TAKING_OR_AUTO_BRACKETTING)) - return null; - int aValue = - base.directory.GetInt( - FujifilmDirectory - .TAG_FUJIFILM_CONTINUOUS_TAKING_OR_AUTO_BRACKETTING); - switch (aValue) - { - case 0 : - return BUNDLE["OFF"]; - case 1 : - return BUNDLE["ON"]; - default : - return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - - /// - /// Returns the Picture Mode Description. - /// - /// the Picture Mode Description. - private string GetPictureModeDescription() - { - if (!base.directory - .ContainsTag(FujifilmDirectory.TAG_FUJIFILM_PICTURE_MODE)) - return null; - int aValue = - base.directory.GetInt( - FujifilmDirectory.TAG_FUJIFILM_PICTURE_MODE); - switch (aValue) - { - case 0 : - return BUNDLE["AUTO"]; - case 1 : - return BUNDLE["PORTRAIT_SCENE"]; - case 2 : - return BUNDLE["LANDSCAPE_SCENE"]; - case 4 : - return BUNDLE["SPORTS_SCENE"]; - case 5 : - return BUNDLE["NIGHT_SCENE"]; - case 6 : - return BUNDLE["PROGRAM_AE"]; - case 256 : - return BUNDLE["APERTURE_PRIORITY_AE"]; - case 512 : - return BUNDLE["SHUTTER_PRIORITY_AE"]; - case 768 : - return BUNDLE["MANUAL_EXPOSURE"]; - default : - return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - - /// - /// Returns the Slow Sync Description. - /// - /// the Slow Sync Description. - private string GetSlowSyncDescription() - { - if (!base.directory - .ContainsTag(FujifilmDirectory.TAG_FUJIFILM_SLOW_SYNCHRO)) - return null; - int aValue = - base.directory.GetInt( - FujifilmDirectory.TAG_FUJIFILM_SLOW_SYNCHRO); - switch (aValue) - { - case 0 : - return BUNDLE["OFF"]; - case 1 : - return BUNDLE["ON"]; - default : - return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - - /// - /// Returns the Focus Mode Description. - /// - /// the Focus Mode Description. - private string GetFocusModeDescription() - { - if (!base.directory - .ContainsTag(FujifilmDirectory.TAG_FUJIFILM_FOCUS_MODE)) - return null; - int aValue = - base.directory.GetInt( - FujifilmDirectory.TAG_FUJIFILM_FOCUS_MODE); - switch (aValue) - { - case 0 : - return BUNDLE["AUTO_FOCUS"]; - case 1 : - return BUNDLE["MANUAL_FOCUS"]; - default : - return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - - /// - /// Returns the Macro Description. - /// - /// the Macro Description. - private string GetMacroDescription() - { - if (!base.directory - .ContainsTag(FujifilmDirectory.TAG_FUJIFILM_MACRO)) - return null; - int aValue = - base.directory.GetInt(FujifilmDirectory.TAG_FUJIFILM_MACRO); - switch (aValue) - { - case 0 : - return BUNDLE["OFF"]; - case 1 : - return BUNDLE["ON"]; - default : - return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - - /// - /// Returns the Flash Strength Description. - /// - /// the Flash Strength Description. - private string GetFlashStrengthDescription() - { - if (!base.directory - .ContainsTag( - FujifilmDirectory.TAG_FUJIFILM_FLASH_STRENGTH)) - return null; - Rational aValue = - base.directory.GetRational( - FujifilmDirectory.TAG_FUJIFILM_FLASH_STRENGTH); - return BUNDLE["FLASH_STRENGTH", aValue.ToSimpleString(false)]; - } - - /// - /// Returns the Flash Mode Description. - /// - /// the Flash Mode Description. - private string GetFlashModeDescription() - { - if (!base.directory - .ContainsTag(FujifilmDirectory.TAG_FUJIFILM_FLASH_MODE)) - return null; - int aValue = - base.directory.GetInt( - FujifilmDirectory.TAG_FUJIFILM_FLASH_MODE); - switch (aValue) - { - case 0 : - return BUNDLE["AUTO"]; - case 1 : - return BUNDLE["ON"]; - case 2 : - return BUNDLE["OFF"]; - case 3 : - return BUNDLE["RED_EYE_REDUCTION"]; - default : - return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - - /// - /// Returns the Tone Description. - /// - /// the Tone Description. - private string GetToneDescription() - { - if (!base.directory - .ContainsTag(FujifilmDirectory.TAG_FUJIFILM_TONE)) - return null; - int aValue = - base.directory.GetInt(FujifilmDirectory.TAG_FUJIFILM_TONE); - switch (aValue) - { - case 0 : - return BUNDLE["NORMAL_STD"]; - case 256 : - return BUNDLE["HIGH_HARD"]; - case 512 : - return BUNDLE["LOW_ORG"]; - default : - return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - - /// - /// Returns the Color Description. - /// - /// the Color Description. - private string GetColorDescription() - { - if (!base.directory - .ContainsTag(FujifilmDirectory.TAG_FUJIFILM_COLOR)) - return null; - int aValue = - base.directory.GetInt(FujifilmDirectory.TAG_FUJIFILM_COLOR); - switch (aValue) - { - case 0 : - return BUNDLE["NORMAL_STD"]; - case 256 : - return BUNDLE["HIGH"]; - case 512 : - return BUNDLE["LOW_ORG"]; - default : - return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - - /// - /// Returns the White Balance Description. - /// - /// the White Balance Description. - private string GetWhiteBalanceDescription() - { - if (!base.directory - .ContainsTag(FujifilmDirectory.TAG_FUJIFILM_WHITE_BALANCE)) - return null; - int aValue = - base.directory.GetInt( - FujifilmDirectory.TAG_FUJIFILM_WHITE_BALANCE); - switch (aValue) - { - case 0 : - return BUNDLE["AUTO"]; - case 256 : - return BUNDLE["DAYLIGHT"]; - case 512 : - return BUNDLE["CLOUDY"]; - case 768 : - return BUNDLE["DAYLIGHTCOLOR_FLUORESCENCE"]; - case 769 : - return BUNDLE["DAYWHITECOLOR_FLUORESCENCE"]; - case 770 : - return BUNDLE["WHITE_FLUORESCENCE"]; - case 1024 : - return BUNDLE["INCANDENSCENSE"]; - case 3840 : - return BUNDLE["CUSTOM_WHITE_BALANCE"]; - default : - return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - - /// - /// Returns the Sharpness Description. - /// - /// the Sharpness Description. - private string GetSharpnessDescription() - { - if (!base.directory - .ContainsTag(FujifilmDirectory.TAG_FUJIFILM_SHARPNESS)) - return null; - int aValue = - base.directory.GetInt( - FujifilmDirectory.TAG_FUJIFILM_SHARPNESS); - switch (aValue) - { - case 1 : - case 2 : - return BUNDLE["SOFT"]; - case 3 : - return BUNDLE["NORMAL"]; - case 4 : - case 5 : - return BUNDLE["HARD"]; - default : - return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/FujifilmDirectory.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/FujifilmDirectory.cs deleted file mode 100644 index 28f5dc3e57..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/FujifilmDirectory.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text; -using System.IO; -using com.drew.metadata; -using com.drew.lang; -using com.utils.bundle; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// The Fuji Film Makernote Directory - /// - public class FujifilmDirectory : AbstractDirectory - { - public const int TAG_FUJIFILM_MAKERNOTE_VERSION = 0x0000; - public const int TAG_FUJIFILM_QUALITY = 0x1000; - public const int TAG_FUJIFILM_SHARPNESS = 0x1001; - public const int TAG_FUJIFILM_WHITE_BALANCE = 0x1002; - public const int TAG_FUJIFILM_COLOR = 0x1003; - public const int TAG_FUJIFILM_TONE = 0x1004; - public const int TAG_FUJIFILM_FLASH_MODE = 0x1010; - public const int TAG_FUJIFILM_FLASH_STRENGTH = 0x1011; - public const int TAG_FUJIFILM_MACRO = 0x1020; - public const int TAG_FUJIFILM_FOCUS_MODE = 0x1021; - public const int TAG_FUJIFILM_SLOW_SYNCHRO = 0x1030; - public const int TAG_FUJIFILM_PICTURE_MODE = 0x1031; - public const int TAG_FUJIFILM_UNKNOWN_1 = 0x1032; - public const int TAG_FUJIFILM_CONTINUOUS_TAKING_OR_AUTO_BRACKETTING = 0x1100; - public const int TAG_FUJIFILM_UNKNOWN_2 = 0x1200; - public const int TAG_FUJIFILM_BLUR_WARNING = 0x1300; - public const int TAG_FUJIFILM_FOCUS_WARNING = 0x1301; - public const int TAG_FUJIFILM_AE_WARNING = 0x1302; - - /// - /// Constructor of the object. - /// - public FujifilmDirectory() - : base("FujiFilmMarkernote") - { - this.SetDescriptor(new FujifilmDescriptor(this)); - } - - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/GpsDescriptor.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/GpsDescriptor.cs deleted file mode 100644 index ee7734bd79..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/GpsDescriptor.cs +++ /dev/null @@ -1,302 +0,0 @@ -using System; -using System.Collections; -using System.Text; -using System.IO; -using com.drew.metadata; -using com.drew.lang; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// Tag descriptor for GPS - /// - public class GpsDescriptor : AbstractTagDescriptor - { - /// - /// Constructor of the object - /// - /// a base.directory - public GpsDescriptor(AbstractDirectory aDirectory) : base(aDirectory) - { - } - - /// - /// Returns a descriptive value of the the specified tag for this image. - /// Where possible, known values will be substituted here in place of the raw tokens actually - /// kept in the Exif segment. - /// If no substitution is available, the value provided by GetString(int) will be returned. - /// This and GetString(int) are the only 'get' methods that won't throw an exception. - /// - /// the tag to find a description for - /// a description of the image'str value for the specified tag, or null if the tag hasn't been defined. - public override string GetDescription(int tagType) - { - switch(tagType) - { - case GpsDirectory.TAG_GPS_ALTITUDE : - return GetGpsAltitudeDescription(); - case GpsDirectory.TAG_GPS_ALTITUDE_REF : - return GetGpsAltitudeRefDescription(); - case GpsDirectory.TAG_GPS_STATUS : - return GetGpsStatusDescription(); - case GpsDirectory.TAG_GPS_MEASURE_MODE : - return GetGpsMeasureModeDescription(); - case GpsDirectory.TAG_GPS_SPEED_REF : - return GetGpsSpeedRefDescription(); - case GpsDirectory.TAG_GPS_TRACK_REF : - case GpsDirectory.TAG_GPS_IMG_DIRECTION_REF : - case GpsDirectory.TAG_GPS_DEST_BEARING_REF : - return GetGpsDirectionReferenceDescription(tagType); - case GpsDirectory.TAG_GPS_TRACK : - case GpsDirectory.TAG_GPS_IMG_DIRECTION : - case GpsDirectory.TAG_GPS_DEST_BEARING : - return GetGpsDirectionDescription(tagType); - case GpsDirectory.TAG_GPS_DEST_DISTANCE_REF : - return GetGpsDestinationReferenceDescription(); - case GpsDirectory.TAG_GPS_TIME_STAMP : - return GetGpsTimeStampDescription(); - // three rational numbers -- displayed in HH"MM"SS.ss - case GpsDirectory.TAG_GPS_LONGITUDE : - return GetGpsLongitudeDescription(); - case GpsDirectory.TAG_GPS_LATITUDE : - return GetGpsLatitudeDescription(); - default : - return base.directory.GetString(tagType); - } - } - - /// - /// Returns the Gps Latitude Description. - /// - /// the Gps Latitude Description. - private string GetGpsLatitudeDescription() - { - if (!base.directory.ContainsTag(GpsDirectory.TAG_GPS_LATITUDE)) - { - return null; - } - return GetHoursMinutesSecondsDescription(GpsDirectory.TAG_GPS_LATITUDE); - } - - /// - /// Returns the Gps Longitude Description. - /// - /// the Gps Longitude Description. - private string GetGpsLongitudeDescription() - { - if (!base.directory.ContainsTag(GpsDirectory.TAG_GPS_LONGITUDE)) - { - return null; - } - return GetHoursMinutesSecondsDescription( - GpsDirectory.TAG_GPS_LONGITUDE); - } - - /// - /// Returns the Hours Minutes Seconds Description. - /// - /// the tag type - /// the Hours Minutes Seconds Description. - private string GetHoursMinutesSecondsDescription(int tagType) - { - Rational[] components = base.directory.GetRationalArray(tagType); - // TODO create an HoursMinutesSecods class ?? - int deg = components[0].IntValue(); - float min = components[1].FloatValue(); - float sec = components[2].FloatValue(); - // carry fractions of minutes into seconds -- thanks Colin Briton - sec += (min % 1) * 60; - string[] tab = new string[] {deg.ToString(), ((int) min).ToString(), sec.ToString()}; - return BUNDLE["HOURS_MINUTES_SECONDS", tab]; - } - - /// - /// Returns the Gps Time Stamp Description. - /// - /// the Gps Time Stamp Description. - private string GetGpsTimeStampDescription() - { - // time in hour, min, sec - if (!base.directory.ContainsTag(GpsDirectory.TAG_GPS_TIME_STAMP)) - { - return null; - } - int[] timeComponents = - base.directory.GetIntArray(GpsDirectory.TAG_GPS_TIME_STAMP); - string[] tab = new string[] {timeComponents[0].ToString(), timeComponents[1].ToString(), timeComponents[2].ToString()}; - return BUNDLE["GPS_TIME_STAMP", tab]; - } - - /// - /// Returns the Gps Destination Reference Description. - /// - /// the Gps Destination Reference Description. - private string GetGpsDestinationReferenceDescription() - { - if (!base.directory.ContainsTag(GpsDirectory.TAG_GPS_DEST_DISTANCE_REF)) - { - return null; - } - string destRef = - base.directory.GetString(GpsDirectory.TAG_GPS_DEST_DISTANCE_REF).Trim().ToUpper(); - switch (destRef) - { - case "K": return BUNDLE["KILOMETERS"]; - case "M": return BUNDLE["MILES"]; - case "N": return BUNDLE["KNOTS"]; - default: return BUNDLE["UNKNOWN", destRef]; - } - } - - /// - /// Returns the Gps Direction Description. - /// - /// the Gps Direction Description. - private string GetGpsDirectionDescription(int tagType) - { - if (!base.directory.ContainsTag(tagType)) - { - return null; - } - string gpsDirection = base.directory.GetString(tagType).Trim(); - return BUNDLE["DEGREES", gpsDirection]; - } - - /// - /// Returns the Gps Direction Reference Description. - /// - /// the Gps Direction Reference Description. - private string GetGpsDirectionReferenceDescription(int tagType) - { - if (!base.directory.ContainsTag(tagType)) - { - return null; - } - string gpsDistRef = base.directory.GetString(tagType).Trim().ToUpper(); - switch (gpsDistRef) - { - case "T": return BUNDLE["TRUE_DIRECTION"]; - case "M": return BUNDLE["MAGNETIC_DIRECTION"]; - default: return BUNDLE["UNKNOWN", gpsDistRef]; - } - } - - /// - /// Returns the Gps Speed Ref Description. - /// - /// the Gps Speed Ref Description. - private string GetGpsSpeedRefDescription() - { - if (!base.directory.ContainsTag(GpsDirectory.TAG_GPS_SPEED_REF)) - { - return null; - } - string gpsSpeedRef = - base.directory.GetString(GpsDirectory.TAG_GPS_SPEED_REF).Trim().ToUpper(); - switch (gpsSpeedRef) - { - case "K": return BUNDLE["KPH"]; - case "M": return BUNDLE["MPH"]; - case "N": return BUNDLE["KNOTS"]; - default: return BUNDLE["UNKNOWN", gpsSpeedRef]; - } - } - - /// - /// Returns the Gps Measure Mode Description. - /// - /// the Gps Measure Mode Description. - private string GetGpsMeasureModeDescription() - { - if (!base.directory.ContainsTag(GpsDirectory.TAG_GPS_MEASURE_MODE)) - { - return null; - } - string gpsSpeedMeasureMode = - base.directory.GetString(GpsDirectory.TAG_GPS_MEASURE_MODE).Trim(); - - switch (gpsSpeedMeasureMode) - { - case "2": - case "3": return BUNDLE["DIMENSIONAL_MEASUREMENT", gpsSpeedMeasureMode]; - default: return BUNDLE["UNKNOWN", gpsSpeedMeasureMode]; - } - } - - /// - /// Returns the Gps Status Description. - /// - /// the Gps Status Description. - private string GetGpsStatusDescription() - { - if (!base.directory.ContainsTag(GpsDirectory.TAG_GPS_STATUS)) - { - return null; - } - string gpsStatus = - base.directory.GetString(GpsDirectory.TAG_GPS_STATUS).Trim().ToUpper(); - switch (gpsStatus) - { - case "A": return BUNDLE["MEASUREMENT_IN_PROGESS"]; - case "V": return BUNDLE["MEASUREMENT_INTEROPERABILITY"]; - default: return BUNDLE["UNKNOWN", gpsStatus]; - } - } - - /// - /// Returns the Gps Altitude Ref Description. - /// - /// the Gps Altitude Ref Description. - private string GetGpsAltitudeRefDescription() - { - if (!base.directory.ContainsTag(GpsDirectory.TAG_GPS_ALTITUDE_REF)) - { - return null; - } - int alititudeRef = base.directory.GetInt(GpsDirectory.TAG_GPS_ALTITUDE_REF); - if (alititudeRef == 0) - { - return BUNDLE["SEA_LEVEL"]; - } - return BUNDLE["UNKNOWN", alititudeRef.ToString()]; - } - - /// - /// Returns the Gps Altitude Description. - /// - /// the Gps Altitude Description. - private string GetGpsAltitudeDescription() - { - if (!base.directory.ContainsTag(GpsDirectory.TAG_GPS_ALTITUDE)) - { - return null; - } - string alititude = - base.directory.GetRational( - GpsDirectory.TAG_GPS_ALTITUDE).ToSimpleString( - true); - return BUNDLE["METRES", alititude]; - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/GpsDirectory.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/GpsDirectory.cs deleted file mode 100644 index 726b07d444..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/GpsDirectory.cs +++ /dev/null @@ -1,156 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text; -using System.IO; -using com.drew.metadata; -using com.drew.lang; -using com.utils.bundle; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// The GPS Directory class - /// - public class GpsDirectory : AbstractDirectory - { - /// - /// GPS tag version GPSVersionID 0 0 BYTE 4 - /// - public const int TAG_GPS_VERSION_ID = 0x0000; - /// - /// North or South Latitude GPSLatitudeRef 1 1 ASCII 2 - /// - public const int TAG_GPS_LATITUDE_REF = 0x0001; - /// - /// Latitude GPSLatitude 2 2 RATIONAL 3 - /// - public const int TAG_GPS_LATITUDE = 0x0002; - /// - /// East or West Longitude GPSLongitudeRef 3 3 ASCII 2 - /// - public const int TAG_GPS_LONGITUDE_REF = 0x0003; - /// - /// Longitude GPSLongitude 4 4 RATIONAL 3 - /// - public const int TAG_GPS_LONGITUDE = 0x0004; - /// - /// Altitude reference GPSAltitudeRef 5 5 BYTE 1 - /// - public const int TAG_GPS_ALTITUDE_REF = 0x0005; - /// - /// Altitude GPSAltitude 6 6 RATIONAL 1 - /// - public const int TAG_GPS_ALTITUDE = 0x0006; - /// - /// GPS time (atomic clock) GPSTimeStamp 7 7 RATIONAL 3 - /// - public const int TAG_GPS_TIME_STAMP = 0x0007; - /// - /// GPS satellites used for measurement GPSSatellites 8 8 ASCII Any - /// - public const int TAG_GPS_SATELLITES = 0x0008; - /// - /// GPS receiver status GPSStatus 9 9 ASCII 2 - /// - public const int TAG_GPS_STATUS = 0x0009; - /// - /// GPS measurement mode GPSMeasureMode 10 A ASCII 2 - /// - public const int TAG_GPS_MEASURE_MODE = 0x000A; - /// - /// Measurement precision GPSDOP 11 B RATIONAL 1 - /// - public const int TAG_GPS_DOP = 0x000B; - /// - /// Speed unit GPSSpeedRef 12 C ASCII 2 - /// - public const int TAG_GPS_SPEED_REF = 0x000C; - /// - /// Speed of GPS receiver GPSSpeed 13 D RATIONAL 1 - /// - public const int TAG_GPS_SPEED = 0x000D; - /// - /// Reference for direction of movement GPSTrackRef 14 E ASCII 2 - /// - public const int TAG_GPS_TRACK_REF = 0x000E; - /// - /// Direction of movement GPSTrack 15 F RATIONAL 1 - /// - public const int TAG_GPS_TRACK = 0x000F; - /// - /// Reference for direction of image GPSImgDirectionRef 16 10 ASCII 2 - /// - public const int TAG_GPS_IMG_DIRECTION_REF = 0x0010; - /// - /// Direction of image GPSImgDirection 17 11 RATIONAL 1 - /// - public const int TAG_GPS_IMG_DIRECTION = 0x0011; - /// - /// Geodetic survey data used GPSMapDatum 18 12 ASCII Any - /// - public const int TAG_GPS_MAP_DATUM = 0x0012; - /// - /// Reference for latitude of destination GPSDestLatitudeRef 19 13 ASCII 2 - /// - public const int TAG_GPS_DEST_LATITUDE_REF = 0x0013; - /// - /// Latitude of destination GPSDestLatitude 20 14 RATIONAL 3 - /// - public const int TAG_GPS_DEST_LATITUDE = 0x0014; - /// - /// Reference for longitude of destination GPSDestLongitudeRef 21 15 ASCII 2 - /// - public const int TAG_GPS_DEST_LONGITUDE_REF = 0x0015; - /// - /// Longitude of destination GPSDestLongitude 22 16 RATIONAL 3 - /// - public const int TAG_GPS_DEST_LONGITUDE = 0x0016; - /// - /// Reference for bearing of destination GPSDestBearingRef 23 17 ASCII 2 - /// - public const int TAG_GPS_DEST_BEARING_REF = 0x0017; - /// - /// Bearing of destination GPSDestBearing 24 18 RATIONAL 1 - /// - public const int TAG_GPS_DEST_BEARING = 0x0018; - /// - /// Reference for distance to destination GPSDestDistanceRef 25 19 ASCII 2 - /// - public const int TAG_GPS_DEST_DISTANCE_REF = 0x0019; - /// - /// Distance to destination GPSDestDistance 26 1A RATIONAL 1 - /// - public const int TAG_GPS_DEST_DISTANCE = 0x001A; - - /// - /// Constructor of the object. - /// - public GpsDirectory() - : base("GpsMarkernote") - { - this.SetDescriptor(new GpsDescriptor(this)); - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/KodakDescriptor.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/KodakDescriptor.cs deleted file mode 100644 index 164ddca275..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/KodakDescriptor.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.Collections; -using System.Text; -using System.IO; -using com.drew.metadata; -using com.drew.lang; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// Tag descriptor for Kodak - /// - /// Thanks to David Carson for the initial version of this class. - /// - public class KodakDescriptor : AbstractTagDescriptor - { - /// - /// Constructor of the object - /// - /// a directory - public KodakDescriptor(AbstractDirectory directory) - : base(directory) - { - } - - /// - /// Returns a descriptive value of the the specified tag for this image. - /// Where possible, known values will be substituted here in place of the raw tokens actually - /// kept in the Exif segment. - /// If no substitution is available, the value provided by GetString(int) will be returned. - /// This and GetString(int) are the only 'get' methods that won't throw an exception. - /// - /// the tag to find a description for - /// a description of the image'str value for the specified tag, or null if the tag hasn't been defined. - public override string GetDescription(int aTagType) - { - return base.directory.GetString(aTagType); - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/KodakDirectory.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/KodakDirectory.cs deleted file mode 100644 index c0e35ed101..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/KodakDirectory.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text; -using System.IO; -using com.drew.metadata; -using com.drew.lang; -using com.utils.bundle; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// The GPS Directory class - /// - public class KodakDirectory : AbstractDirectory - { - // No Tag for now - - /// - /// Constructor of the object. - /// - public KodakDirectory() - : base("KodakMarkernote") - { - this.SetDescriptor(new KodakDescriptor(this)); - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/KyoceraDescriptor.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/KyoceraDescriptor.cs deleted file mode 100644 index f8234ff4f0..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/KyoceraDescriptor.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System; -using System.Collections; -using System.Text; -using System.IO; -using com.drew.metadata; -using com.drew.lang; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// Tag descriptor for Kyocera - /// - public class KyoceraDescriptor : AbstractTagDescriptor - { - /// - /// Constructor of the object - /// - /// a base.directory - public KyoceraDescriptor(AbstractDirectory aDirectory) - : base(aDirectory) - { - } - - /// - /// Returns a descriptive value of the the specified tag for this image. - /// Where possible, known values will be substituted here in place of the raw tokens actually - /// kept in the Exif segment. - /// If no substitution is available, the value provided by GetString(int) will be returned. - /// This and GetString(int) are the only 'get' methods that won't throw an exception. - /// - /// the tag to find a description for - /// a description of the image'str value for the specified tag, or null if the tag hasn't been defined. - public override string GetDescription(int aTagType) - { - switch (aTagType) - { - case KyoceraDirectory.TAG_KYOCERA_PRINT_IMAGE_MATCHING_INFO: - return GetPrintImageMatchingInfoDescription(); - case KyoceraDirectory.TAG_KYOCERA_PROPRIETARY_THUMBNAIL: - return GetProprietaryThumbnailDataDescription(); - default: - return base.directory.GetString(aTagType); - } - } - - /// - /// Returns Print Image Matching (PIM) Info Description. - /// - /// the Print Image Matching (PIM) Info Description. - private string GetPrintImageMatchingInfoDescription() - { - if (!base.directory.ContainsTag(KyoceraDirectory.TAG_KYOCERA_PRINT_IMAGE_MATCHING_INFO)) - { - return null; - } - byte[] bytes = base.directory.GetByteArray(KyoceraDirectory.TAG_KYOCERA_PRINT_IMAGE_MATCHING_INFO); - return BUNDLE["BYTES",bytes.Length.ToString()]; - } - - /// - /// Returns Proprietary Thumbnail Format Data Description. - /// - /// the Proprietary Thumbnail Format Data Description. - private string GetProprietaryThumbnailDataDescription() - { - if (!base.directory.ContainsTag(KyoceraDirectory.TAG_KYOCERA_PROPRIETARY_THUMBNAIL)) - { - return null; - } - byte[] bytes = base.directory.GetByteArray(KyoceraDirectory.TAG_KYOCERA_PROPRIETARY_THUMBNAIL); - return BUNDLE["BYTES", bytes.Length.ToString()]; - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/KyoceraDirectory.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/KyoceraDirectory.cs deleted file mode 100644 index 947d66a00e..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/KyoceraDirectory.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text; -using System.IO; -using com.drew.metadata; -using com.drew.lang; -using com.utils.bundle; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// The GPS Directory class - /// - public class KyoceraDirectory : AbstractDirectory - { - public const int TAG_KYOCERA_PROPRIETARY_THUMBNAIL = 0x0001; - public const int TAG_KYOCERA_PRINT_IMAGE_MATCHING_INFO = 0x0E00; - - /// - /// Constructor of the object. - /// - public KyoceraDirectory() - : base("KyoceraMarkernote") - { - this.SetDescriptor(new KyoceraDescriptor(this)); - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/NikonType1Descriptor.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/NikonType1Descriptor.cs deleted file mode 100644 index 319f01c5ce..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/NikonType1Descriptor.cs +++ /dev/null @@ -1,310 +0,0 @@ -using System; -using System.Collections; -using System.Text; -using System.IO; -using com.drew.metadata; -using com.drew.lang; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// There are 3 formats of Nikon'str MakerNote. MakerNote of E700/E800/E900/E900S/E910/E950 starts - /// from ASCII string "Nikon". Data format is the same as IFD, but it starts from offSet 0x08. - /// This is the same as Olympus except start string. Example of actual data structure is shown below. - /// :0000: 4E 69 6B 6F 6E 00 01 00-05 00 02 00 02 00 06 00 Nikon........... - /// :0010: 00 00 EC 02 00 00 03 00-03 00 01 00 00 00 06 00 ................ - /// - public class NikonType1Descriptor : AbstractTagDescriptor - { - - /// - /// Constructor of the object - /// - /// a base.directory - public NikonType1Descriptor(AbstractDirectory aDirectory) : base(aDirectory) - { - } - - /// - /// Returns a descriptive value of the the specified tag for this image. - /// Where possible, known values will be substituted here in place of the raw tokens actually - /// kept in the Exif segment. - /// If no substitution is available, the value provided by GetString(int) will be returned. - /// This and GetString(int) are the only 'get' methods that won't throw an exception. - /// - /// the tag to find a description for - /// a description of the image'str value for the specified tag, or null if the tag hasn't been defined. - public override string GetDescription(int tagType) - { - switch(tagType) - { - case NikonType1Directory.TAG_NIKON_TYPE1_QUALITY : - return GetQualityDescription(); - case NikonType1Directory.TAG_NIKON_TYPE1_COLOR_MODE : - return GetColorModeDescription(); - case NikonType1Directory.TAG_NIKON_TYPE1_IMAGE_ADJUSTMENT : - return GetImageAdjustmentDescription(); - case NikonType1Directory.TAG_NIKON_TYPE1_CCD_SENSITIVITY : - return GetCcdSensitivityDescription(); - case NikonType1Directory.TAG_NIKON_TYPE1_WHITE_BALANCE : - return GetWhiteBalanceDescription(); - case NikonType1Directory.TAG_NIKON_TYPE1_FOCUS : - return GetFocusDescription(); - case NikonType1Directory.TAG_NIKON_TYPE1_DIGITAL_ZOOM : - return GetDigitalZoomDescription(); - case NikonType1Directory.TAG_NIKON_TYPE1_CONVERTER : - return GetConverterDescription(); - default : - return base.directory.GetString(tagType); - } - } - - /// - /// Returns the Converter Description. - /// - /// the Converter Description. - private string GetConverterDescription() - { - if (!base.directory - .ContainsTag( - NikonType1Directory.TAG_NIKON_TYPE1_CONVERTER)) - { - return null; - } - int aValue = - base.directory.GetInt( - NikonType1Directory.TAG_NIKON_TYPE1_CONVERTER); - switch (aValue) - { - case 0 : - return BUNDLE["NONE"]; - case 1 : - return BUNDLE["FISHEYE_CONVERTER"]; - default : - return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - - /// - /// Returns the Digital Zoom Description. - /// - /// the Digital Zoom Description. - private string GetDigitalZoomDescription() - { - if (!base.directory - .ContainsTag( - NikonType1Directory.TAG_NIKON_TYPE1_DIGITAL_ZOOM)) - { - return null; - } - Rational aValue = - base.directory.GetRational( - NikonType1Directory.TAG_NIKON_TYPE1_DIGITAL_ZOOM); - if (aValue.GetNumerator() == 0) - { - return BUNDLE["NO_DIGITAL_ZOOM"]; - } - return BUNDLE["DIGITAL_ZOOM", aValue.ToSimpleString(true)]; - } - - /// - /// Returns the Focus Description. - /// - /// the Focus Description. - private string GetFocusDescription() - { - if (!base.directory - .ContainsTag(NikonType1Directory.TAG_NIKON_TYPE1_FOCUS)) - { - return null; - } - Rational aValue = - base.directory.GetRational( - NikonType1Directory.TAG_NIKON_TYPE1_FOCUS); - if (aValue.GetNumerator() == 1 && aValue.GetDenominator() == 0) - { - return BUNDLE["INFINITE"]; - } - return aValue.ToSimpleString(true); - } - - /// - /// Returns the White Balance Description. - /// - /// the White Balance Description. - private string GetWhiteBalanceDescription() - { - if (!base.directory - .ContainsTag( - NikonType1Directory.TAG_NIKON_TYPE1_WHITE_BALANCE)) - { - - return null; - } - int aValue = - base.directory.GetInt( - NikonType1Directory.TAG_NIKON_TYPE1_WHITE_BALANCE); - switch (aValue) - { - case 0 : - return BUNDLE["AUTO"]; - case 1 : - return BUNDLE["PRESET"]; - case 2 : - return BUNDLE["DAYLIGHT"]; - case 3 : - return BUNDLE["INCANDESCENSE"]; - case 4 : - return BUNDLE["FLUORESCENT"]; - case 5 : - return BUNDLE["CLOUDY"]; - case 6 : - return BUNDLE["SPEEDLIGHT"]; - default : - return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - - /// - /// Returns the Ccd Sensitivity Description. - /// - /// the Ccd Sensitivity Description. - private string GetCcdSensitivityDescription() - { - if (!base.directory - .ContainsTag( - NikonType1Directory.TAG_NIKON_TYPE1_CCD_SENSITIVITY)) - { - return null; - } - int aValue = - base.directory.GetInt( - NikonType1Directory.TAG_NIKON_TYPE1_CCD_SENSITIVITY); - switch (aValue) - { - case 0 : - return BUNDLE["ISO","80"]; - case 2 : - return BUNDLE["ISO","160"]; - case 4 : - return BUNDLE["ISO","320"]; - case 5 : - return BUNDLE["ISO","100"]; - default : - return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - - /// - /// Returns the Image Adjustment Description. - /// - /// the Image Adjustment Description. - private string GetImageAdjustmentDescription() - { - if (!base.directory - .ContainsTag( - NikonType1Directory.TAG_NIKON_TYPE1_IMAGE_ADJUSTMENT)) - { - return null; - } - int aValue = - base.directory.GetInt( - NikonType1Directory.TAG_NIKON_TYPE1_IMAGE_ADJUSTMENT); - switch (aValue) - { - case 0 : - return BUNDLE["NORMAL"]; - case 1 : - return BUNDLE["BRIGHT_P"]; - case 2 : - return BUNDLE["BRIGHT_M"]; - case 3 : - return BUNDLE["CONTRAST_P"]; - case 4 : - return BUNDLE["CONTRAST_M"]; - default : - return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - - /// - /// Returns the Color Mode Description. - /// - /// the Color Mode Description. - private string GetColorModeDescription() - { - if (!base.directory - .ContainsTag( - NikonType1Directory.TAG_NIKON_TYPE1_COLOR_MODE)) - { - return null; - } - int aValue = - base.directory.GetInt( - NikonType1Directory.TAG_NIKON_TYPE1_COLOR_MODE); - switch (aValue) - { - case 1 : - return BUNDLE["COLOR"]; - case 2 : - return BUNDLE["MONOCHROME"]; - default : - return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - - /// - /// Returns the Quality Description. - /// - /// the Quality Description. - private string GetQualityDescription() - { - if (!base.directory - .ContainsTag(NikonType1Directory.TAG_NIKON_TYPE1_QUALITY)) - { - return null; - } - int aValue = - base.directory.GetInt( - NikonType1Directory.TAG_NIKON_TYPE1_QUALITY); - switch (aValue) - { - case 1 : - return BUNDLE["VGA_BASIC"]; - case 2 : - return BUNDLE["VGA_NORMAL"]; - case 3 : - return BUNDLE["VGA_FINE"]; - case 4 : - return BUNDLE["SXGA_BASIC"]; - case 5 : - return BUNDLE["SXGA_NORMAL"]; - case 6 : - return BUNDLE["SXGA_FINE"]; - default : - return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/NikonType1Directory.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/NikonType1Directory.cs deleted file mode 100644 index 50c4eabe37..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/NikonType1Directory.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text; -using System.IO; -using com.drew.metadata; -using com.drew.lang; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - public class NikonType1Directory : AbstractNikonTypeDirectory - { - // TYPE1 is for E-Series cameras prior to (not including) E990 - public const int TAG_NIKON_TYPE1_UNKNOWN_1 = 0x0002; - public const int TAG_NIKON_TYPE1_QUALITY = 0x0003; - public const int TAG_NIKON_TYPE1_COLOR_MODE = 0x0004; - public const int TAG_NIKON_TYPE1_IMAGE_ADJUSTMENT = 0x0005; - public const int TAG_NIKON_TYPE1_CCD_SENSITIVITY = 0x0006; - public const int TAG_NIKON_TYPE1_WHITE_BALANCE = 0x0007; - public const int TAG_NIKON_TYPE1_FOCUS = 0x0008; - public const int TAG_NIKON_TYPE1_UNKNOWN_2 = 0x0009; - public const int TAG_NIKON_TYPE1_DIGITAL_ZOOM = 0x000A; - public const int TAG_NIKON_TYPE1_CONVERTER = 0x000B; - public const int TAG_NIKON_TYPE1_UNKNOWN_3 = 0x0F00; - - /// - /// Constructor of the object. - /// - public NikonType1Directory() - : base("NikonTypeMarkernote") - { - this.SetDescriptor(new NikonType1Descriptor(this)); - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/NikonType2Descriptor.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/NikonType2Descriptor.cs deleted file mode 100644 index 6253f99a19..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/NikonType2Descriptor.cs +++ /dev/null @@ -1,253 +0,0 @@ -using System; -using System.Collections; -using System.Text; -using System.IO; -using com.drew.metadata; -using com.drew.lang; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// Tag descriptor for Nikon - /// - public class NikonType2Descriptor : AbstractTagDescriptor - { - /// - /// Constructor of the object - /// - /// a base.directory - public NikonType2Descriptor(AbstractDirectory aDirectory) - : base(aDirectory) - { - } - - /// - /// Returns a descriptive value of the the specified tag for this image. - /// Where possible, known values will be substituted here in place of the raw tokens actually - /// kept in the Exif segment. - /// If no substitution is available, the value provided by GetString(int) will be returned. - /// This and GetString(int) are the only 'get' methods that won't throw an exception. - /// - /// the tag to find a description for - /// a description of the image'str value for the specified tag, or null if the tag hasn't been defined. - public override string GetDescription(int tagType) - { - switch (tagType) - { - case NikonType2Directory.TAG_NIKON_TYPE2_LENS: - return GetLensDescription(); - case NikonType2Directory.TAG_NIKON_TYPE2_CAMERA_HUE_ADJUSTMENT: - return GetHueAdjustmentDescription(); - case NikonType2Directory.TAG_NIKON_TYPE2_CAMERA_COLOR_MODE: - return GetColorModeDescription(); - case NikonType2Directory.TAG_NIKON_TYPE2_AUTO_FLASH_COMPENSATION: - return GetAutoFlashCompensationDescription(); - case NikonType2Directory.TAG_NIKON_TYPE2_ISO_1: - return GetIsoSettingDescription(); - case NikonType2Directory.TAG_NIKON_TYPE2_DIGITAL_ZOOM: - return GetDigitalZoomDescription(); - case NikonType2Directory.TAG_NIKON_TYPE2_AF_FOCUS_POSITION: - return GetAutoFocusPositionDescription(); - case NikonType2Directory.TAG_NIKON_TYPE2_FIRMWARE_VERSION: - return GetAutoFirmwareVersionDescription(); - default: - return base.directory.GetString(tagType); - } - } - - /// - /// Returns auto focus position Description. - /// - /// the auto focus position Description. - private string GetAutoFocusPositionDescription() - { - if (!base.directory.ContainsTag(NikonType2Directory.TAG_NIKON_TYPE2_AF_FOCUS_POSITION)) - { - return null; - } - int[] values = base.directory.GetIntArray(NikonType2Directory.TAG_NIKON_TYPE2_AF_FOCUS_POSITION); - if (values.Length != 4 || values[0] != 0 || values[2] != 0 || values[3] != 0) - { - return BUNDLE["UNKNOWN", base.directory.GetString(NikonType2Directory.TAG_NIKON_TYPE2_AF_FOCUS_POSITION)]; - } - switch (values[1]) - { - case 0: - return BUNDLE["CENTER"]; - case 1: - return BUNDLE["TOP"]; - case 2: - return BUNDLE["BOTTOM"]; - case 3: - return BUNDLE["LEFT"]; - case 4: - return BUNDLE["RIGHT"]; - default: - return BUNDLE["UNKNOWN", values[1].ToString()]; - } - } - - /// - /// Returns digital zoom Description. - /// - /// the digital zoom Description. - private string GetDigitalZoomDescription() - { - if (!base.directory.ContainsTag(NikonType2Directory.TAG_NIKON_TYPE2_DIGITAL_ZOOM)) - { - return null; - } - Rational rational = base.directory.GetRational(NikonType2Directory.TAG_NIKON_TYPE2_DIGITAL_ZOOM); - if (rational.IntValue() == 1) - { - return BUNDLE["NO_DIGITAL_ZOOM"]; - } - return BUNDLE["DIGITAL_ZOOM", rational.ToSimpleString(true)]; - } - - /// - /// Returns iso setting Description. - /// - /// the iso setting Description. - private string GetIsoSettingDescription() - { - if (!base.directory.ContainsTag(NikonType2Directory.TAG_NIKON_TYPE2_ISO_1)) - { - return null; - } - int[] values = base.directory.GetIntArray(NikonType2Directory.TAG_NIKON_TYPE2_ISO_1); - if (values[0] != 0 || values[1] == 0) - { - return BUNDLE["UNKNOWN", base.directory.GetString(NikonType2Directory.TAG_NIKON_TYPE2_ISO_1)]; - } - return BUNDLE["ISO", values[1].ToString()]; - } - - /// - /// Returns auto flash compensation Description. - /// - /// the auto flash compensation Description. - private Rational GetAutoFlashCompensation() - { - if (!base.directory.ContainsTag(NikonType2Directory.TAG_NIKON_TYPE2_AUTO_FLASH_COMPENSATION)) - { - return null; - } - byte[] bytes = base.directory.GetByteArray(NikonType2Directory.TAG_NIKON_TYPE2_AUTO_FLASH_COMPENSATION); - - if (bytes.Length == 3) - { - byte denominator = bytes[2]; - int numerator = (int)bytes[0] * bytes[1]; - return new Rational(numerator, denominator); - } - return null; - } - - /// - /// Returns auto falsh compensation Description. - /// - /// the auto falsh compensation Description. - private string GetAutoFlashCompensationDescription() - { - Rational ev = this.GetAutoFlashCompensation(); - - if (ev == null) - { - return BUNDLE["UNKNOWN", "null"]; - } - return BUNDLE["FLASH_SIMPLE", ev.FloatValue().ToString("0.##")]; - } - - /// - /// Returns lens Description. - /// - /// the lens Description. - private string GetLensDescription() - { - if (!base.directory.ContainsTag(NikonType2Directory.TAG_NIKON_TYPE2_LENS)) - { - return null; - } - - Rational[] lensValues = base.directory.GetRationalArray(NikonType2Directory.TAG_NIKON_TYPE2_LENS); - - if (lensValues.Length != 4) - { - return base.directory.GetString(NikonType2Directory.TAG_NIKON_TYPE2_LENS); - } - string[] tab = new string[] { lensValues[0].IntValue().ToString(), lensValues[1].IntValue().ToString(), lensValues[2].IntValue().ToString(), lensValues[3].IntValue().ToString() }; - return BUNDLE["LENS", tab]; - } - - /// - /// Returns hue adjustement Description. - /// - /// the hue adjustement Description. - private string GetHueAdjustmentDescription() - { - if (!base.directory.ContainsTag(NikonType2Directory.TAG_NIKON_TYPE2_CAMERA_HUE_ADJUSTMENT)) - { - return null; - } - - return BUNDLE["DEGREES", base.directory.GetString(NikonType2Directory.TAG_NIKON_TYPE2_CAMERA_HUE_ADJUSTMENT)]; - } - - /// - /// Returns color mode Description. - /// - /// the color mode Description. - private string GetColorModeDescription() - { - if (!base.directory.ContainsTag(NikonType2Directory.TAG_NIKON_TYPE2_CAMERA_COLOR_MODE)) - { - return null; - } - - String raw = base.directory.GetString(NikonType2Directory.TAG_NIKON_TYPE2_CAMERA_COLOR_MODE); - if (raw.StartsWith("MODE1")) - { - return BUNDLE["MODE_I_SRGB"]; - } - - return raw; - } - - /// - /// Returns auto firmware version Description. - /// - /// the auto firmware version Description. - private string GetAutoFirmwareVersionDescription() - { - if (!base.directory.ContainsTag(NikonType2Directory.TAG_NIKON_TYPE2_FIRMWARE_VERSION)) - { - return null; - } - - int[] ints = base.directory.GetIntArray(NikonType2Directory.TAG_NIKON_TYPE2_FIRMWARE_VERSION); - return ExifDescriptor.ConvertBytesToVersionString(ints); - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/NikonType2Directory.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/NikonType2Directory.cs deleted file mode 100644 index 416480908d..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/NikonType2Directory.cs +++ /dev/null @@ -1,447 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text; -using System.IO; -using com.drew.metadata; -using com.drew.lang; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - public class NikonType2Directory : AbstractNikonTypeDirectory - { - /// - /// Values observed - /// - 0200 (D70) - /// - 0200 (D1X) - /// - public const int TAG_NIKON_TYPE2_FIRMWARE_VERSION = 0x0001; - - /// - /// Values observed - /// - 0 250 - /// - 0 400 - /// - public const int TAG_NIKON_TYPE2_ISO_1 = 0x0002; - - /// - /// Values observed - /// - COLOR (seen in the D1X) - /// - public const int TAG_NIKON_TYPE2_COLOR_MODE = 0x0003; - - /// - /// Values observed - /// - FILE - /// - RAW - /// - NORMAL - /// - FINE - /// - public const int TAG_NIKON_TYPE2_QUALITY_AND_FILE_FORMAT = 0x0004; - - /// - /// The white balance as set in the camera. - /// - /// Values observed - /// - AUTO - /// - SUNNY (D70) - /// - FLASH (D1X) - /// (presumably also SHADOW / INCANDESCENT / FLUORESCENT / CLOUDY) - /// - public const int TAG_NIKON_TYPE2_CAMERA_WHITE_BALANCE = 0x0005; - - /// - /// The sharpening as set in the camera. - /// - /// Values observed - /// - AUTO - /// - NORMAL (D70) - /// - NONE (D1X) - /// - public const int TAG_NIKON_TYPE2_CAMERA_SHARPENING = 0x0006; - - /// - /// The auto-focus type used by the camera. - /// - /// Values observed - /// - AF-S - /// - AF-C - /// - MANUAL - /// - public const int TAG_NIKON_TYPE2_AF_TYPE = 0x0007; - - /// - /// Values observed - /// - NORMAL - /// - RED-EYE - /// - /// Note: when TAG_NIKON_TYPE2_AUTO_FLASH_MODE is blank, Nikon Browser displays "Flash Sync Mode: Not Attached" - /// - public const int TAG_NIKON_TYPE2_FLASH_SYNC_MODE = 0x0008; - - /// - /// Values observed - /// - Built-in,TTL - /// - Optional,TTL (with speedlight SB800, flash sync mode as NORMAL. NikonBrowser reports Auto Flash Comp: 0 EV -- which tag is that?) (D70) - /// - NEW_TTL (Nikon Browser interprets as "D-TTL") - /// - (blank -- accompanied FlashSyncMode of NORMAL) (D70) - /// - public const int TAG_NIKON_TYPE2_AUTO_FLASH_MODE = 0x0009; - - /// - /// Added during merge of Type2 & Type3. May apply to earlier models, such as E990 and D1. - /// - public const int TAG_NIKON_TYPE2_UNKNOWN_34 = 0x000A; - - /// - /// Values observed - /// - 0 - /// - public const int TAG_NIKON_TYPE2_CAMERA_WHITE_BALANCE_FINE = 0x000B; - - /// - /// The first two numbers are coefficients to multiply red and blue channels according to white balance as set in the - /// camera. The meaning of the third and the fourth numbers is unknown. - /// - /// Values observed - /// - 2.25882352 1.76078431 0.0 0.0 - /// - 10242/1 34305/1 0/1 0/1 - /// - 234765625/100000000 1140625/1000000 1/1 1/1 - /// - public const int TAG_NIKON_TYPE2_CAMERA_WHITE_BALANCE_RB_COEFF = 0x000C; - - /// - /// Values observed - /// - 0,1,6,0 (hex) - /// - public const int TAG_NIKON_TYPE2_UNKNOWN_1 = 0x000D; - - /// - /// Values observed - /// - î - /// - 0,1,c,0 (hex) - /// - public const int TAG_NIKON_TYPE2_UNKNOWN_2 = 0x000E; - - /// - /// Added during merge of Type2 & Type3. May apply to earlier models, such as E990 and D1. - /// - public const int TAG_NIKON_TYPE2_ISO_SELECTION = 0x000F; - - /// - /// Added during merge of Type2 & Type3. May apply to earlier models, such as E990 and D1. - /// - public const int TAG_NIKON_TYPE2_DATA_DUMP = 0x0010; - - /// - /// Values observed - /// - 914 - /// - 1379 (D70) - /// - 2781 (D1X) - /// - 6942 (D100) - /// - public const int TAG_NIKON_TYPE2_UNKNOWN_3 = 0x0011; - - /// - /// Values observed - /// - (no value -- blank) - /// - public const int TAG_NIKON_TYPE2_AUTO_FLASH_COMPENSATION = 0x0012; - - /// - /// Values observed - /// - 0 250 - /// - 0 400 - /// - public const int TAG_NIKON_TYPE2_ISO_2 = 0x0013; - - /// - /// Values observed - /// - 0 0 49163 53255 - /// - 0 0 3008 2000 (the image dimensions were 3008x2000) (D70) - /// - public const int TAG_NIKON_TYPE2_UNKNOWN_21 = 0x0016; - - /// - /// Values observed - /// - (blank) - /// - public const int TAG_NIKON_TYPE2_UNKNOWN_22 = 0x0017; - - /// - /// Values observed - /// - (blank) - /// - public const int TAG_NIKON_TYPE2_UNKNOWN_23 = 0x0018; - - /// - /// Values observed - /// - 0 - /// - public const int TAG_NIKON_TYPE2_UNKNOWN_24 = 0x0019; - - /// - /// Added during merge of Type2 & Type3. May apply to earlier models, such as E990 and D1. - /// - public const int TAG_NIKON_TYPE2_IMAGE_ADJUSTMENT = 0x0080; - - /// - /// The tone compensation as set in the camera. - /// - /// Values observed - /// - AUTO - /// - NORMAL (D1X, D100) - /// - public const int TAG_NIKON_TYPE2_CAMERA_TONE_COMPENSATION = 0x0081; - - /// - /// Added during merge of Type2 & Type3. May apply to earlier models, such as E990 and D1. - /// - public const int TAG_NIKON_TYPE2_ADAPTER = 0x0082; - - /// - /// Values observed - /// - 6 - /// - 6 (D70) - /// - 2 (D1X) - /// - public const int TAG_NIKON_TYPE2_UNKNOWN_4 = 0x0083; - - /// - /// A pair of focal/max-fstop values that describe the lens used. - /// - /// Values observed - /// - 180.0,180.0,2.8,2.8 (D100) - /// - 240/10 850/10 35/10 45/10 - /// - 18-70mm f/3.5-4.5 (D70) - /// - 17-35mm f/2.8-2.8 (D1X) - /// - 70-200mm f/2.8-2.8 (D70) - /// - /// Nikon Browser identifies the lens as "18-70mm F/3.5-4.5 G" which - /// is identical to lcMetadata extractor, except for the "G". This must - /// be coming from another tag... - /// - public const int TAG_NIKON_TYPE2_LENS = 0x0084; - - /// - /// Added during merge of Type2 & Type3. May apply to earlier models, such as E990 and D1. - /// - public const int TAG_NIKON_TYPE2_MANUAL_FOCUS_DISTANCE = 0x0085; - - /// - /// Added during merge of Type2 & Type3. May apply to earlier models, such as E990 and D1. - /// - public const int TAG_NIKON_TYPE2_DIGITAL_ZOOM = 0x0086; - - /// - /// Values observed - /// - 0 - /// - 9 - /// - 3 (D1X) - /// - public const int TAG_NIKON_TYPE2_UNKNOWN_5 = 0x0087; - - /// - /// Values observed - /// - - /// - public const int TAG_NIKON_TYPE2_AF_FOCUS_POSITION = 0x0088; - - /// - /// Values observed - /// - 0 - /// - 1 - /// - public const int TAG_NIKON_TYPE2_UNKNOWN_7 = 0x0089; - - /// - /// Values observed - /// - 0 - /// - 0 - /// - public const int TAG_NIKON_TYPE2_UNKNOWN_20 = 0x008A; - - /// - /// Values observed - /// - 48,1,c,0 (hex) (D100) - /// - @ - /// - public const int TAG_NIKON_TYPE2_UNKNOWN_8 = 0x008B; - - /// - /// Unknown. Fabrizio believes this may be a lookup table for the user-defined curve. - /// - /// Values observed - /// - (blank) (D1X) - /// - public const int TAG_NIKON_TYPE2_UNKNOWN_9 = 0x008C; - - /// - /// The color space as set in the camera. - /// - /// Values observed - /// - MODE1 - /// - Mode I (sRGB) (D70) - /// - MODE2 (D1X, D100) - /// - public const int TAG_NIKON_TYPE2_CAMERA_COLOR_MODE = 0x008D; - - /// - /// Values observed - /// - NATURAL - /// - SPEEDLIGHT (D70, D1X) - /// - public const int TAG_NIKON_TYPE2_LIGHT_SOURCE = 0x0090; - - /// - /// Values observed - /// - 0100) - /// - 0103 (D70) - /// - 0100 (D1X) - /// - public const int TAG_NIKON_TYPE2_UNKNOWN_11 = 0x0091; - - /// - /// The hue adjustment as set in the camera. - /// - /// Values observed - /// - 0 - /// - public const int TAG_NIKON_TYPE2_CAMERA_HUE_ADJUSTMENT = 0x0092; - - /// - /// Values observed - /// - OFF - /// - public const int TAG_NIKON_TYPE2_NOISE_REDUCTION = 0x0095; - - /// - /// Values observed - /// - 0100 '~e3 - /// - 0103 - /// - public const int TAG_NIKON_TYPE2_UNKNOWN_12 = 0x0097; - - /// - /// Values observed - /// - 0100fht@7b,4x,D"Y - /// - 01015 - /// - 0100w\cH+D$$h$î5Q (D1X) - /// - 30,31,30,30,0,0,b,48,7c,7c,24,24,5,15,24,0,0,0,0,0 (hex) (D100) - /// - public const int TAG_NIKON_TYPE2_UNKNOWN_13 = 0x0098; - - /// - /// Values observed - /// - 2014 662 (D1X) - /// - 1517,1012 (D100) - /// - public const int TAG_NIKON_TYPE2_UNKNOWN_14 = 0x0099; - - /// - /// Values observed - /// - 78/10 78/10 - /// - 78/10 78/10 (D70) - /// - 59/10 59/5 (D1X) - /// - 7.8,7.8 (D100) - /// - public const int TAG_NIKON_TYPE2_UNKNOWN_15 = 0x009A; - - /// - /// Values observed - /// - NO= 00002539 - /// - public const int TAG_NIKON_TYPE2_UNKNOWN_25 = 0x00A0; - - /// - /// Values observed - /// - 1564851 - /// - public const int TAG_NIKON_TYPE2_UNKNOWN_26 = 0x00A2; - - /// - /// Values observed - /// - 0 - /// - public const int TAG_NIKON_TYPE2_UNKNOWN_27 = 0x00A3; - - /// - /// This appears to be a sequence number to indentify the exposure. This value seems to increment - /// for constecutive exposures (observed on D70). - /// - /// Values observed - /// - 5062 - /// - public const int TAG_NIKON_TYPE2_EXPOSURE_SEQUENCE_NUMBER = 0x00A7; - - /// - /// Values observed - /// - 0100 (D70) - /// - public const int TAG_NIKON_TYPE2_UNKNOWN_32 = 0x00A8; - - /// - /// Values observed - /// - NORMAL (D70) - /// - public const int TAG_NIKON_TYPE2_UNKNOWN_33 = 0x00A9; - - /// - /// Nikon Browser suggests this value represents Saturation... - /// Values observed - /// - NORMAL (D70) - /// - public const int TAG_NIKON_TYPE2_UNKNOWN_29 = 0x00AA; - - /// - /// Values observed - /// - AUTO (D70) - /// - (blank) (D70) - /// - public const int TAG_NIKON_TYPE2_UNKNOWN_30 = 0x00AB; - - /// - /// Data about changes set by Nikon Capture Editor. - /// - /// Values observed - /// - public const int TAG_NIKON_TYPE2_CAPTURE_EDITOR_DATA = 0x0E01; - - /// - /// Values observed - /// - 1473 - /// - 7036 (D100) - /// - public const int TAG_NIKON_TYPE2_UNKNOWN_16 = 0x0E10; - - /// - /// Constructor of the object. - /// - public NikonType2Directory() - : base("NikonTypeMarkernote") - { - this.SetDescriptor(new NikonType2Descriptor(this)); - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/OlympusDescriptor.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/OlympusDescriptor.cs deleted file mode 100644 index fac4ec64bc..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/OlympusDescriptor.cs +++ /dev/null @@ -1,209 +0,0 @@ -using System; -using System.Collections; -using System.Text; -using System.IO; -using com.drew.metadata; -using com.drew.lang; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// Tag descriptor for Olympus - /// - public class OlympusDescriptor : AbstractTagDescriptor - { - /// - /// Constructor of the object - /// - /// a base.directory - public OlympusDescriptor(AbstractDirectory aDirectory) : base(aDirectory) - { - } - - /// - /// Returns a descriptive value of the the specified tag for this image. - /// Where possible, known values will be substituted here in place of the raw tokens actually - /// kept in the Exif segment. - /// If no substitution is available, the value provided by GetString(int) will be returned. - /// This and GetString(int) are the only 'get' methods that won't throw an exception. - /// - /// the tag to find a description for - /// a description of the image'str value for the specified tag, or null if the tag hasn't been defined. - public override string GetDescription(int tagType) - { - switch(tagType) - { - case OlympusDirectory.TAG_OLYMPUS_SPECIAL_MODE : - return GetSpecialModeDescription(); - case OlympusDirectory.TAG_OLYMPUS_JPEG_QUALITY : - return GetJpegQualityDescription(); - case OlympusDirectory.TAG_OLYMPUS_MACRO_MODE : - return GetMacroModeDescription(); - case OlympusDirectory.TAG_OLYMPUS_DIGI_ZOOM_RATIO : - return GetDigiZoomRatioDescription(); - default: - return base.directory.GetString(tagType); - } - } - - /// - /// Returns the Digi Zoom Ratio Description. - /// - /// the Digi Zoom Ratio Description. - private string GetDigiZoomRatioDescription() - { - if (!base.directory - .ContainsTag(OlympusDirectory.TAG_OLYMPUS_DIGI_ZOOM_RATIO)) - { - return null; - } - int aValue = - base.directory.GetInt( - OlympusDirectory.TAG_OLYMPUS_DIGI_ZOOM_RATIO); - switch (aValue) - { - case 0 : - return BUNDLE["NORMAL"]; - case 1: - return BUNDLE["DIGITAL_ZOOM", "1"]; - case 2 : - return BUNDLE["DIGITAL_ZOOM", "2"]; - default : - return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - - /// - /// Returns the Macro Mode Description. - /// - /// the Macro Mode Description. - private string GetMacroModeDescription() - { - if (!base.directory - .ContainsTag(OlympusDirectory.TAG_OLYMPUS_MACRO_MODE)) - { - return null; - } - int aValue = - base.directory.GetInt(OlympusDirectory.TAG_OLYMPUS_MACRO_MODE); - switch (aValue) - { - case 0 : - return BUNDLE["NORMAL_NO_MACRO"]; - case 1 : - return BUNDLE["MACRO"]; - default : - return BUNDLE["UNKNOWN", aValue.ToString() ]; - } - } - - /// - /// Returns the Jpeg Quality Description. - /// - /// the Jpeg Quality Description. - private string GetJpegQualityDescription() - { - if (!base.directory - .ContainsTag(OlympusDirectory.TAG_OLYMPUS_JPEG_QUALITY)) - { - return null; - } - int aValue = - base.directory.GetInt( - OlympusDirectory.TAG_OLYMPUS_JPEG_QUALITY); - switch (aValue) - { - case 1 : - return BUNDLE["SQ"]; - case 2 : - return BUNDLE["HQ"]; - case 3 : - return BUNDLE["SHQ"]; - default : - return BUNDLE["UNKNOWN", aValue.ToString() ]; - } - } - - /// - /// Returns the Special Mode Description. - /// - /// the Special Mode Description. - private string GetSpecialModeDescription() - { - if (!base.directory - .ContainsTag(OlympusDirectory.TAG_OLYMPUS_SPECIAL_MODE)) - { - return null; - } - int[] values = - base.directory.GetIntArray( - OlympusDirectory.TAG_OLYMPUS_SPECIAL_MODE); - StringBuilder desc = new StringBuilder(); - switch (values[0]) - { - case 0 : - desc.Append(BUNDLE["NORMAL_PICTURE_TAKING_MODE"]); - break; - case 1 : - desc.Append(BUNDLE["UNKNOWN_PICTURE_TAKING_MODE"]); - break; - case 2 : - desc.Append(BUNDLE["FAST_PICTURE_TAKING_MODE"]); - break; - case 3 : - desc.Append(BUNDLE["PANORAMA_PICTURE_TAKING_MODE"]); - break; - default : - desc.Append(BUNDLE["UNKNOWN_PICTURE_TAKING_MODE"]); - break; - } - desc.Append(" - "); - switch (values[1]) - { - case 0 : - desc.Append(BUNDLE["UNKNOWN_SEQUENCE_NUMBER"]); - break; - default : - desc.Append(BUNDLE["X_RD_IN_A_SEQUENCE", values[1].ToString()]); - break; - } - switch (values[2]) - { - case 1 : - desc.Append(BUNDLE["LEFT_TO_RIGHT_PAN_DIR"]); - break; - case 2 : - desc.Append(BUNDLE["RIGHT_TO_LEFT_PAN_DIR"]); - break; - case 3 : - desc.Append(BUNDLE["BOTTOM_TO_TOP_PAN_DIR"]); - break; - case 4 : - desc.Append(BUNDLE["TOP_TO_BOTTOM_PAN_DIR"]); - break; - } - return desc.ToString(); - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/OlympusDirectory.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/OlympusDirectory.cs deleted file mode 100644 index 912e33a140..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/OlympusDirectory.cs +++ /dev/null @@ -1,199 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text; -using System.IO; -using com.drew.metadata; -using com.drew.lang; -using com.utils.bundle; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - public class OlympusDirectory : AbstractDirectory - { - /// - /// Used by Konica / Minolta cameras. - /// - public const int TAG_OLYMPUS_MAKERNOTE_VERSION = 0x0000; - - /// - /// Used by Konica / Minolta cameras. - /// - public const int TAG_OLYMPUS_CAMERA_SETTINGS_1 = 0x0001; - - /// - /// Alternate Camera Settings Tag. Used by Konica / Minolta cameras. - /// - public const int TAG_OLYMPUS_CAMERA_SETTINGS_2 = 0x0003; - - /// - /// Used by Konica / Minolta cameras. - /// - public const int TAG_OLYMPUS_COMPRESSED_IMAGE_SIZE = 0x0040; - - /// - /// Used by Konica / Minolta cameras. - /// - public const int TAG_OLYMPUS_MINOLTA_THUMBNAIL_OFFSET_1 = 0x0081; - - /// - /// Alternate Thumbnail Offset. Used by Konica / Minolta cameras. - /// - public const int TAG_OLYMPUS_MINOLTA_THUMBNAIL_OFFSET_2 = 0x0088; - - /// - /// Length of thumbnail in bytes. Used by Konica / Minolta cameras. - /// - public const int TAG_OLYMPUS_MINOLTA_THUMBNAIL_LENGTH = 0x0089; - - /// - /// Used by Konica / Minolta cameras - /// 0 = Natural Color - /// 1 = Black & White - /// 2 = Vivid color - /// 3 = Solarization - /// 4 = AdobeRGB - /// - public const int TAG_OLYMPUS_COLOR_MODE = 0x0101; - - /// - /// Used by Konica / Minolta cameras. - /// 0 = Raw - /// 1 = Super Fine - /// 2 = Fine - /// 3 = Standard - /// 4 = Extra Fine - /// - public const int TAG_OLYMPUS_IMAGE_QUALITY_1 = 0x0102; - - /// - /// Not 100% sure about this tag. - /// - /// Used by Konica / Minolta cameras. - /// 0 = Raw - /// 1 = Super Fine - /// 2 = Fine - /// 3 = Standard - /// 4 = Extra Fine - /// - public const int TAG_OLYMPUS_IMAGE_QUALITY_2 = 0x0103; - - - /// - /// Three values: - /// Value 1: 0=Normal, 2=Fast, 3=Panorama - /// Value 2: Sequence Number Value 3: - /// 1 = Panorama Direction: Left to Right - /// 2 = Panorama Direction: Right to Left - /// 3 = Panorama Direction: Bottom to Top - /// 4 = Panorama Direction: Top to Bottom - /// - public const int TAG_OLYMPUS_SPECIAL_MODE = 0x0200; - - /// - /// 1 = Standard Quality - /// 2 = High Quality - /// 3 = Super High Quality - /// - public const int TAG_OLYMPUS_JPEG_QUALITY = 0x0201; - - /// - /// 0 = Normal (Not Macro) - /// 1 = Macro - /// - public const int TAG_OLYMPUS_MACRO_MODE = 0x0202; - - - public const int TAG_OLYMPUS_UNKNOWN_1 = 0x0203; - - /// - /// Zoom Factor (0 or 1 = normal) - /// - public const int TAG_OLYMPUS_DIGI_ZOOM_RATIO = 0x0204; - - - public const int TAG_OLYMPUS_UNKNOWN_2 = 0x0205; - public const int TAG_OLYMPUS_UNKNOWN_3 = 0x0206; - public const int TAG_OLYMPUS_FIRMWARE_VERSION = 0x0207; - public const int TAG_OLYMPUS_PICT_INFO = 0x0208; - public const int TAG_OLYMPUS_CAMERA_ID = 0x0209; - - /// - /// Used by Epson cameras - /// Units = pixels - /// - public const int TAG_OLYMPUS_IMAGE_WIDTH = 0x020B; - - /// - /// Used by Epson cameras - /// Units = pixels - /// - public const int TAG_OLYMPUS_IMAGE_HEIGHT = 0x020C; - - /// - /// A string. Used by Epson cameras. - /// - public const int TAG_OLYMPUS_ORIGINAL_MANUFACTURER_MODEL = 0x020D; - - /// - /// See the PIM specification here: - /// http://www.ozhiker.com/electronics/pjmt/jpeg_info/pim.html - /// - public const int TAG_OLYMPUS_PRINT_IMAGE_MATCHING_INFO = 0x0E00; - - - public const int TAG_OLYMPUS_DATA_DUMP = 0x0F00; - public const int TAG_OLYMPUS_FLASH_MODE = 0x1004; - public const int TAG_OLYMPUS_BRACKET = 0x1006; - public const int TAG_OLYMPUS_FOCUS_MODE = 0x100B; - public const int TAG_OLYMPUS_FOCUS_DISTANCE = 0x100C; - public const int TAG_OLYMPUS_ZOOM = 0x100D; - public const int TAG_OLYMPUS_MACRO_FOCUS = 0x100E; - public const int TAG_OLYMPUS_SHARPNESS = 0x100F; - public const int TAG_OLYMPUS_COLOR_MATRIX = 0x1011; - public const int TAG_OLYMPUS_BLACK_LEVEL = 0x1012; - public const int TAG_OLYMPUS_WHITE_BALANCE = 0x1015; - public const int TAG_OLYMPUS_RED_BIAS = 0x1017; - public const int TAG_OLYMPUS_BLUE_BIAS = 0x1018; - public const int TAG_OLYMPUS_SERIAL_NUMBER = 0x101A; - public const int TAG_OLYMPUS_FLASH_BIAS = 0x1023; - public const int TAG_OLYMPUS_CONTRAST = 0x1029; - public const int TAG_OLYMPUS_SHARPNESS_FACTOR = 0x102A; - public const int TAG_OLYMPUS_COLOR_CONTROL = 0x102B; - public const int TAG_OLYMPUS_VALID_BITS = 0x102C; - public const int TAG_OLYMPUS_CORING_FILTER = 0x102D; - public const int TAG_OLYMPUS_FINAL_WIDTH = 0x102E; - public const int TAG_OLYMPUS_FINAL_HEIGHT = 0x102F; - public const int TAG_OLYMPUS_COMPRESSION_RATIO = 0x1034; - - /// - /// Constructor of the object. - /// - public OlympusDirectory() - : base("OlympusMarkernote") - { - this.SetDescriptor(new OlympusDescriptor(this)); - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/PanasonicDescriptor.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/PanasonicDescriptor.cs deleted file mode 100644 index 92863577bb..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/PanasonicDescriptor.cs +++ /dev/null @@ -1,131 +0,0 @@ -using System; -using System.Collections; -using System.Text; -using System.IO; -using com.drew.metadata; -using com.drew.lang; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// Tag descriptor for Panasonic - /// - public class PanasonicDescriptor : AbstractTagDescriptor - { - /// - /// Constructor of the object - /// - /// a base.directory - public PanasonicDescriptor(AbstractDirectory aDirectory) - : base(aDirectory) - { - } - - /// - /// Returns a descriptive value of the the specified tag for this image. - /// Where possible, known values will be substituted here in place of the raw tokens actually - /// kept in the Exif segment. - /// If no substitution is available, the value provided by GetString(int) will be returned. - /// This and GetString(int) are the only 'get' methods that won't throw an exception. - /// - /// the tag to find a description for - /// a description of the image'str value for the specified tag, or null if the tag hasn't been defined. - public override string GetDescription(int tagType) - { - switch (tagType) - { - case PanasonicDirectory.TAG_PANASONIC_MACRO_MODE: - return GetMacroModeDescription(); - case PanasonicDirectory.TAG_PANASONIC_RECORD_MODE: - return GetRecordModeDescription(); - case PanasonicDirectory.TAG_PANASONIC_PRINT_IMAGE_MATCHING_INFO: - return GetPrintImageMatchingInfoDescription(); - default: - return base.directory.GetString(tagType); - } - } - - /// - /// Returns the print image matching info Description. - /// - /// the print image matching info Description. - private string GetPrintImageMatchingInfoDescription() - { - if (!base.directory.ContainsTag(PanasonicDirectory.TAG_PANASONIC_PRINT_IMAGE_MATCHING_INFO)) - { - return null; - } - byte[] bytes = base.directory.GetByteArray(PanasonicDirectory.TAG_PANASONIC_PRINT_IMAGE_MATCHING_INFO); - return BUNDLE["BYTES", bytes.Length.ToString()]; - } - - /// - /// Returns the macro mode Description. - /// - /// the macro mode Description. - private string GetMacroModeDescription() - { - if (!base.directory.ContainsTag(PanasonicDirectory.TAG_PANASONIC_MACRO_MODE)) - { - return null; - } - int value = base.directory.GetInt(PanasonicDirectory.TAG_PANASONIC_MACRO_MODE); - switch (value) - { - case 1: - return BUNDLE["ON"]; - case 2: - return BUNDLE["OFF"]; - default: - return BUNDLE["UNKNOWN", value.ToString()]; - } - } - - /// - /// Returns record mode Description. - /// - /// the record mode Description. - private string GetRecordModeDescription() - { - if (!base.directory.ContainsTag(PanasonicDirectory.TAG_PANASONIC_RECORD_MODE)) - { - return null; - } - int value = base.directory.GetInt(PanasonicDirectory.TAG_PANASONIC_RECORD_MODE); - switch (value) - { - case 1: - return BUNDLE["NORMAL"]; - case 2: - return BUNDLE["PORTRAIT"]; - case 9: - return BUNDLE["MACRO"]; - default: - return BUNDLE["UNKNOWN", value.ToString()]; - } - } - - - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/PanasonicDirectory.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/PanasonicDirectory.cs deleted file mode 100644 index 22b19e95d2..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/PanasonicDirectory.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text; -using System.IO; -using com.drew.metadata; -using com.drew.lang; -using com.utils.bundle; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// The panasonic directory class. - /// - public class PanasonicDirectory : AbstractDirectory - { - public const int TAG_PANASONIC_QUALITY_MODE = 0x0001; - public const int TAG_PANASONIC_VERSION = 0x0002; - - /// - /// 1 = On - /// 2 = Off - /// - public const int TAG_PANASONIC_MACRO_MODE = 0x001C; - - /// - /// 1 = Normal - /// 2 = Portrait - /// 9 = Macro - /// - public const int TAG_PANASONIC_RECORD_MODE = 0x001F; - public const int TAG_PANASONIC_PRINT_IMAGE_MATCHING_INFO = 0x0E00; - - /// - /// Constructor of the object. - /// - public PanasonicDirectory() - : base("PanasonicMarkernote") - { - this.SetDescriptor(new PanasonicDescriptor(this)); - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/PentaxDescriptor.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/PentaxDescriptor.cs deleted file mode 100644 index 433d363f54..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/PentaxDescriptor.cs +++ /dev/null @@ -1,325 +0,0 @@ -using System; -using System.Collections; -using System.Text; -using System.IO; -using com.drew.metadata; -using com.drew.lang; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// Tag descriptor for pentax - /// - public class PentaxDescriptor : AbstractTagDescriptor - { - /// - /// Constructor of the object - /// - /// a base.directory - public PentaxDescriptor(AbstractDirectory aDirectory) - : base(aDirectory) - { - } - - /// - /// Returns a descriptive value of the the specified tag for this image. - /// Where possible, known values will be substituted here in place of the raw tokens actually - /// kept in the Exif segment. - /// If no substitution is available, the value provided by GetString(int) will be returned. - /// This and GetString(int) are the only 'get' methods that won't throw an exception. - /// - /// the tag to find a description for - /// a description of the image'str value for the specified tag, or null if the tag hasn't been defined. - public override string GetDescription(int tagType) - { - switch (tagType) - { - case PentaxDirectory.TAG_PENTAX_CAPTURE_MODE: - return GetCaptureModeDescription(); - case PentaxDirectory.TAG_PENTAX_QUALITY_LEVEL: - return GetQualityLevelDescription(); - case PentaxDirectory.TAG_PENTAX_FOCUS_MODE: - return GetFocusModeDescription(); - case PentaxDirectory.TAG_PENTAX_FLASH_MODE: - return GetFlashModeDescription(); - case PentaxDirectory.TAG_PENTAX_WHITE_BALANCE: - return GetWhiteBalanceDescription(); - case PentaxDirectory.TAG_PENTAX_DIGITAL_ZOOM: - return GetDigitalZoomDescription(); - case PentaxDirectory.TAG_PENTAX_SHARPNESS: - return GetSharpnessDescription(); - case PentaxDirectory.TAG_PENTAX_CONTRAST: - return GetContrastDescription(); - case PentaxDirectory.TAG_PENTAX_SATURATION: - return GetSaturationDescription(); - case PentaxDirectory.TAG_PENTAX_ISO_SPEED: - return GetIsoSpeedDescription(); - case PentaxDirectory.TAG_PENTAX_COLOR: - return GetColorDescription(); - case PentaxDirectory.TAG_PENTAX_PRINT_IMAGE_MATCHING_INFO: - return GetPrintImageMatchingInfoDescription(); - default: - return base.directory.GetString(tagType); - } - } - - /// - /// Returns the color Description. - /// - /// the color Description. - private string GetColorDescription() - { - if (!base.directory.ContainsTag(PentaxDirectory.TAG_PENTAX_COLOR)) - { - return null; - } - int aValue = base.directory.GetInt(PentaxDirectory.TAG_PENTAX_COLOR); - switch (aValue) - { - case 1: return BUNDLE["NORMAL"]; - case 2: return BUNDLE["BLACK_AND_WHITE"]; - case 3: return BUNDLE["SEPIA"]; - default: return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - - /// - /// Returns the iso speed Description. - /// - /// the iso speed Description. - private string GetIsoSpeedDescription() - { - if (!base.directory.ContainsTag(PentaxDirectory.TAG_PENTAX_ISO_SPEED)) - { - return null; - } - int aValue = base.directory.GetInt(PentaxDirectory.TAG_PENTAX_ISO_SPEED); - switch (aValue) - { - case 100: - case 10: return BUNDLE["ISO", "100"]; - case 16: - case 200: return BUNDLE["ISO", "200"]; - default: return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - - /// - /// Returns the saturation Description. - /// - /// the saturation Description. - private string GetSaturationDescription() - { - if (!base.directory.ContainsTag(PentaxDirectory.TAG_PENTAX_SATURATION)) - { - return null; - } - int aValue = base.directory.GetInt(PentaxDirectory.TAG_PENTAX_SATURATION); - switch (aValue) - { - case 0: return BUNDLE["NORMAL"]; - case 1: return BUNDLE["LOW"]; - case 2: return BUNDLE["HIGH"]; - default: return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - - /// - /// Returns the contrast Description. - /// - /// the contrast Description. - private string GetContrastDescription() - { - if (!base.directory.ContainsTag(PentaxDirectory.TAG_PENTAX_CONTRAST)) - { - return null; - } - int aValue = base.directory.GetInt(PentaxDirectory.TAG_PENTAX_CONTRAST); - switch (aValue) - { - case 0: return BUNDLE["NORMAL"]; - case 1: return BUNDLE["LOW"]; - case 2: return BUNDLE["HIGH"]; - default: return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - - /// - /// Returns the sharpness Description. - /// - /// the sharpness Description. - private string GetSharpnessDescription() - { - if (!base.directory.ContainsTag(PentaxDirectory.TAG_PENTAX_SHARPNESS)) - { - return null; - } - int aValue = base.directory.GetInt(PentaxDirectory.TAG_PENTAX_SHARPNESS); - switch (aValue) - { - case 0: return BUNDLE["NORMAL"]; - case 1: return BUNDLE["SOFT"]; - case 2: return BUNDLE["HARD"]; - default: return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - - /// - /// Returns the digial zoom Description. - /// - /// the digital zoom Description. - private string GetDigitalZoomDescription() - { - if (!base.directory.ContainsTag(PentaxDirectory.TAG_PENTAX_DIGITAL_ZOOM)) - { - return null; - } - float aValue = base.directory.GetFloat(PentaxDirectory.TAG_PENTAX_DIGITAL_ZOOM); - if (aValue == 0) - { - return BUNDLE["OFF"]; - } - return aValue.ToString(); - } - - /// - /// Returns the white balance Description. - /// - /// the white balance Description. - private string GetWhiteBalanceDescription() - { - if (!base.directory.ContainsTag(PentaxDirectory.TAG_PENTAX_WHITE_BALANCE)) - { - return null; - } - int aValue = base.directory.GetInt(PentaxDirectory.TAG_PENTAX_WHITE_BALANCE); - switch (aValue) - { - case 0: return BUNDLE["AUTO"]; - case 1: return BUNDLE["DAYLIGHT"]; - case 2: return BUNDLE["SHADE"]; - case 3: return BUNDLE["TUNGSTEN"]; - case 4: return BUNDLE["FLUORESCENT"]; - case 5: return BUNDLE["MANUAL"]; - default: return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - - /// - /// Returns the flash mode Description. - /// - /// the dlash mode Description. - private string GetFlashModeDescription() - { - if (!base.directory.ContainsTag(PentaxDirectory.TAG_PENTAX_FLASH_MODE)) - { - return null; - } - int aValue = base.directory.GetInt(PentaxDirectory.TAG_PENTAX_FLASH_MODE); - switch (aValue) - { - case 1: return BUNDLE["AUTO"]; - case 2: return BUNDLE["FLASH_ON"]; - case 4: return BUNDLE["FLASH_OFF"]; - case 6: return BUNDLE["RED_EYE_REDUCTION"]; - default: return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - - /// - /// Returns the focus mode Description. - /// - /// the focus mode Description. - private string GetFocusModeDescription() - { - if (!base.directory.ContainsTag(PentaxDirectory.TAG_PENTAX_FOCUS_MODE)) - { - return null; - } - int aValue = base.directory.GetInt(PentaxDirectory.TAG_PENTAX_FOCUS_MODE); - switch (aValue) - { - case 2: return BUNDLE["CUSTOM"]; - case 3: return BUNDLE["AUTO"]; - default: return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - - /// - /// Returns the quality level Description. - /// - /// the quality level Description. - private string GetQualityLevelDescription() - { - if (!base.directory.ContainsTag(PentaxDirectory.TAG_PENTAX_QUALITY_LEVEL)) - { - return null; - } - int aValue = base.directory.GetInt(PentaxDirectory.TAG_PENTAX_QUALITY_LEVEL); - switch (aValue) - { - case 0: return BUNDLE["GOOD"]; - case 1: return BUNDLE["BETTER"]; - case 2: return BUNDLE["BEST"]; - default: return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - - /// - /// Returns the capture mode Description. - /// - /// the capture mode Description. - private string GetCaptureModeDescription() - { - if (!base.directory.ContainsTag(PentaxDirectory.TAG_PENTAX_CAPTURE_MODE)) - { - return null; - } - int aValue = base.directory.GetInt(PentaxDirectory.TAG_PENTAX_CAPTURE_MODE); - switch (aValue) - { - case 1: return BUNDLE["AUTO"]; - case 2: return BUNDLE["NIGHT_SCENE"]; - case 3: return BUNDLE["MANUAL"]; - case 4: return BUNDLE["MULTIPLE"]; - default: return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - - /// - /// Returns the print image matching info Description. - /// - /// the print image matching info Description. - private string GetPrintImageMatchingInfoDescription() - { - if (!base.directory.ContainsTag(PentaxDirectory.TAG_PENTAX_PRINT_IMAGE_MATCHING_INFO)) - { - return null; - } - byte[] bytes = base.directory.GetByteArray(PentaxDirectory.TAG_PENTAX_PRINT_IMAGE_MATCHING_INFO); - return BUNDLE["BYTES", bytes.Length.ToString()]; - } - - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/PentaxDirectory.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/PentaxDirectory.cs deleted file mode 100644 index b0b435bf80..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/PentaxDirectory.cs +++ /dev/null @@ -1,145 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text; -using System.IO; -using com.drew.metadata; -using com.drew.lang; -using com.utils.bundle; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// The pentax directory class. - /// - public class PentaxDirectory : AbstractDirectory - { - /// - /// 0 = Auto - /// 1 = Night-scene - /// 2 = Manual - /// 4 = Multiple - /// - public const int TAG_PENTAX_CAPTURE_MODE = 0x0001; - - /// - /// 0 = Good - /// 1 = Better - /// 2 = Best - /// - public const int TAG_PENTAX_QUALITY_LEVEL = 0x0002; - - /// - /// 2 = Custom - /// 3 = Auto - /// - public const int TAG_PENTAX_FOCUS_MODE = 0x0003; - - /// - /// 1 = Auto - /// 2 = Flash on - /// 4 = Flash off - /// 6 = Red-eye Reduction - /// - public const int TAG_PENTAX_FLASH_MODE = 0x0004; - - /// - /// 0 = Auto - /// 1 = Daylight - /// 2 = Shade - /// 3 = Tungsten - /// 4 = Fluorescent - /// 5 = Manual - /// - public const int TAG_PENTAX_WHITE_BALANCE = 0x0007; - - /// - /// (0 = Off) - /// - public const int TAG_PENTAX_DIGITAL_ZOOM = 0x000A; - - /// - /// 0 = Normal - /// 1 = Soft - /// 2 = Hard - /// - public const int TAG_PENTAX_SHARPNESS = 0x000B; - - /// - /// 0 = Normal - /// 1 = Low - /// 2 = High - /// - public const int TAG_PENTAX_CONTRAST = 0x000C; - - /// - /// 0 = Normal - /// 1 = Low - /// 2 = High - /// - public const int TAG_PENTAX_SATURATION = 0x000D; - - /// - /// 10 = ISO 100 - /// 16 = ISO 200 - /// 100 = ISO 100 - /// 200 = ISO 200 - /// - public const int TAG_PENTAX_ISO_SPEED = 0x0014; - - /// - /// 1 = Normal - /// 2 = Black & White - /// 3 = Sepia - /// - public const int TAG_PENTAX_COLOR = 0x0017; - - /// - /// See Print Image Matching for specification. - /// http://www.ozhiker.com/electronics/pjmt/jpeg_info/pim.html - /// - public const int TAG_PENTAX_PRINT_IMAGE_MATCHING_INFO = 0x0E00; - - /// - /// (String). - /// - public const int TAG_PENTAX_TIME_ZONE = 0x1000; - - /// - /// (String). - /// - public const int TAG_PENTAX_DAYLIGHT_SAVINGS = 0x1001; - - - /// - /// Constructor of the object. - /// - public PentaxDirectory() - : base("PentaxMarkernote") - { - this.SetDescriptor(new PentaxDescriptor(this)); - } - - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/SonyDescriptor.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/SonyDescriptor.cs deleted file mode 100644 index adb7bd96eb..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/SonyDescriptor.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using System.Collections; -using System.Text; -using System.IO; -using com.drew.metadata; -using com.drew.lang; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// Tag descriptor for sony - /// - public class SonyDescriptor : AbstractTagDescriptor - { - /// - /// Constructor of the object - /// - /// a directory - public SonyDescriptor(AbstractDirectory directory) - : base(directory) - { - } - - /// - /// Returns a descriptive value of the the specified tag for this image. - /// Where possible, known values will be substituted here in place of the raw tokens actually - /// kept in the Exif segment. - /// If no substitution is available, the value provided by GetString(int) will be returned. - /// This and GetString(int) are the only 'get' methods that won't throw an exception. - /// - /// the tag to find a description for - /// a description of the image'str value for the specified tag, or null if the tag hasn't been defined. - public override string GetDescription(int tagType) - { - return base.directory.GetString(tagType); - } - - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/SonyDirectory.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/SonyDirectory.cs deleted file mode 100644 index 12b053d307..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/exif/SonyDirectory.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text; -using System.IO; -using com.drew.metadata; -using com.drew.lang; -using com.utils.bundle; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.exif -{ - /// - /// The sony directory class. - /// - public class SonyDirectory : AbstractDirectory - { - // No tag for now - - /// - /// Constructor of the object. - /// - public SonyDirectory() - : base("SonyMarkernote") - { - this.SetDescriptor(new SonyDescriptor(this)); - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/iptc/IptcDescriptor.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/iptc/IptcDescriptor.cs deleted file mode 100644 index 6deca5367a..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/iptc/IptcDescriptor.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System; -using com.drew.lang; -using com.drew.metadata; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.iptc -{ - /// - /// Tag descriptor for IPTC - /// - public class IptcDescriptor : AbstractTagDescriptor - { - /// - /// Constructor of the object - /// - /// a base.directory - public IptcDescriptor(AbstractDirectory aDirectory) : base(aDirectory) - { - } - - /// - /// Returns a descriptive value of the the specified tag for this image. - /// Where possible, known values will be substituted here in place of the raw tokens actually - /// kept in the Exif segment. - /// If no substitution is available, the value provided by GetString(int) will be returned. - /// This and GetString(int) are the only 'get' methods that won't throw an exception. - /// - /// the tag to find a description for - /// a description of the image'str value for the specified tag, or null if the tag hasn't been defined. - public override string GetDescription(int tagType) - { - switch (tagType) - { - case IptcDirectory.TAG_URGENCY : - return GetUrgencyDescription(); - default: - return base.directory.GetString(tagType); - } - - } - - /// - /// Returns urgency Description. - /// - /// the urgency Description. - private string GetUrgencyDescription() - { - if (!base.directory - .ContainsTag(IptcDirectory.TAG_URGENCY)) - { - return null; - } - int aValue = - base.directory.GetInt( - IptcDirectory.TAG_URGENCY); - switch (aValue) - { - case 49: - return BUNDLE["HIGH"]; - case 54: - return BUNDLE["NORMAL"]; - case 56: - return BUNDLE["LOW"]; - default: - return BUNDLE["UNKNOWN", aValue.ToString()]; - } - } - - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/iptc/IptcDirectory.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/iptc/IptcDirectory.cs deleted file mode 100644 index 98fb307574..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/iptc/IptcDirectory.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using com.drew.lang; -using com.drew.metadata; -using com.utils.bundle; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.iptc -{ - /// - /// The Iptc Directory class - /// - public class IptcDirectory : AbstractDirectory - { - public const int TAG_RECORD_VERSION = 0x0200; - public const int TAG_CAPTION = 0x0278; - public const int TAG_WRITER = 0x027a; - public const int TAG_HEADLINE = 0x0269; - public const int TAG_SPECIAL_INSTRUCTIONS = 0x0228; - public const int TAG_BY_LINE = 0x0250; - public const int TAG_BY_LINE_TITLE = 0x0255; - public const int TAG_CREDIT = 0x026e; - public const int TAG_SOURCE = 0x0273; - public const int TAG_OBJECT_NAME = 0x0205; - public const int TAG_DATE_CREATED = 0x0237; - public const int TAG_CITY = 0x025a; - public const int TAG_PROVINCE_OR_STATE = 0x025f; - public const int TAG_COUNTRY_OR_PRIMARY_LOCATION = 0x0265; - public const int TAG_ORIGINAL_TRANSMISSION_REFERENCE = 0x0267; - public const int TAG_CATEGORY = 0x020f; - public const int TAG_SUPPLEMENTAL_CATEGORIES = 0x0214; - public const int TAG_URGENCY = 0x0200 | 10; - public const int TAG_KEYWORDS = 0x0200 | 25; - public const int TAG_COPYRIGHT_NOTICE = 0x0274; - - public const int TAG_RELEASE_DATE = 0x0200 | 30; - public const int TAG_RELEASE_TIME = 0x0200 | 35; - public const int TAG_TIME_CREATED = 0x0200 | 60; - public const int TAG_ORIGINATING_PROGRAM = 0x0200 | 65; - - /// - /// Constructor of the object. - /// - public IptcDirectory() - : base("IptcMarkernote") - { - this.SetDescriptor(new IptcDescriptor(this)); - } - - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/iptc/IptcProcessingException.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/iptc/IptcProcessingException.cs deleted file mode 100644 index 21a3373c11..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/iptc/IptcProcessingException.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using com.drew.lang; -using com.drew.metadata; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.iptc -{ - /// - /// The exception type raised during reading of Iptc data in the instance of unexpected data conditions. - /// - public class IptcProcessingException : MetadataException - { - /// - /// Constructor of the object - /// - /// The error aMessage - public IptcProcessingException(string aMessage) - : base(aMessage) - { - } - - /// - /// Constructor of the object - /// - /// The error aMessage - /// The aCause of the exception - public IptcProcessingException(string aMessage, Exception aCause) - : base(aMessage, aCause) - { - } - - /// - /// Constructor of the object - /// - /// The aCause of the exception - public IptcProcessingException(Exception aCause) - : base(aCause.Message, aCause) - { - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/iptc/IptcReader.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/iptc/IptcReader.cs deleted file mode 100644 index 286c32f2c6..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/iptc/IptcReader.cs +++ /dev/null @@ -1,231 +0,0 @@ -using System; -using System.Collections; -using System.IO; -using com.drew.lang; -using com.drew.metadata; -using com.drew.imaging.jpg; -using com.utils; -using System.Diagnostics; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.iptc -{ - /// - /// The Iptc reader class - /// - public class IptcReader : AbstractMetadataReader - { - - /// - /// Creates a new IptcReader for the specified Jpeg jpegFile. - /// - /// where to read - public IptcReader(FileInfo aFile) : base(aFile, JpegSegmentReader.SEGMENT_APPD) - { - } - - /// - /// Constructor of the object - /// - /// the data to read - public IptcReader(byte[] aData) - : base(aData) - { - } - - /// - /// Extracts aMetadata - /// - /// where to add aMetadata - /// the aMetadata found - public override Metadata Extract(Metadata aMetadata) - { - if (base.data == null) - { - return aMetadata; - } - - AbstractDirectory lcDirectory = aMetadata.GetDirectory("com.drew.metadata.iptc.IptcDirectory"); - - // find start of data - int offset = 0; - try - { - while (offset < base.data.Length - 1 && Get32Bits(offset) != 0x1c02) - { - offset++; - } - } - catch (MetadataException e) - { - lcDirectory.HasError = true; - Trace.TraceError( - "Couldn't find start of Iptc data (invalid segment) ("+e.Message+")"); - return aMetadata; - } - - // for each tag - while (offset < base.data.Length) - { - // identifies start of a tag - if (base.data[offset] != 0x1c) - { - break; - } - // we need at least five bytes left to read a tag - if ((offset + 5) >= base.data.Length) - { - break; - } - - offset++; - - int directoryType; - int tagType; - int tagByteCount; - try - { - directoryType = base.data[offset++]; - tagType = base.data[offset++]; - tagByteCount = Get32Bits(offset); - } - catch (MetadataException e) - { - lcDirectory.HasError = true; - Trace.TraceError( - "Iptc data segment ended mid-way through tag descriptor ("+e.Message+")"); - return aMetadata; - } - offset += 2; - if ((offset + tagByteCount) > base.data.Length) - { - lcDirectory.HasError = true; - Trace.TraceError( - "Data for tag extends beyond end of IPTC segment"); - break; - } - - ProcessTag(lcDirectory, directoryType, tagType, offset, tagByteCount); - offset += tagByteCount; - } - - return aMetadata; - } - - - /// - /// This method serves as marsheller of objects for dataset. - /// It converts from IPTC octets to relevant java object. - /// - /// the directory - /// the directory type - /// the tag type - /// the lcOffset - /// the tag byte count - private void ProcessTag( - AbstractDirectory aDirectory, - int aDirectoryType, - int aTagType, - int anOffset, - int aTagByteCount) - { - int tagIdentifier = aTagType | (aDirectoryType << 8); - switch (tagIdentifier) - { - case IptcDirectory.TAG_RECORD_VERSION: - // short - short shortValue = (short)((base.data[anOffset] << 8) | base.data[anOffset + 1]); - aDirectory.SetObject(tagIdentifier, shortValue); - return; - case IptcDirectory.TAG_URGENCY: - // byte - aDirectory.SetObject(tagIdentifier, base.data[anOffset]); - return; - case IptcDirectory.TAG_RELEASE_DATE: - case IptcDirectory.TAG_DATE_CREATED: - // Date object - if (aTagByteCount >= 8) - { - string dateStr = Utils.Decode(base.data, anOffset, aTagByteCount, false); - try - { - int year = Convert.ToInt32(dateStr.Substring(0, 4)); - int month = Convert.ToInt32(dateStr.Substring(4, 2)); //No -1 here; - int day = Convert.ToInt32(dateStr.Substring(6, 2)); - DateTime date = new DateTime(year, month, day); - aDirectory.SetObject(tagIdentifier, date); - return; - } - catch (Exception) - { - // fall through and we'll store whatever was there as a String - } - } - break; // Added for .Net compiler - //case IptcDirectory.TAG_RELEASE_TIME: - //case IptcDirectory.TAG_TIME_CREATED: - } - // If no special handling by now, treat it as a string - string str = null; - if (aTagByteCount < 1) - { - str = ""; - } - else - { - str = Utils.Decode(base.data, anOffset, aTagByteCount, false); - } - if (aDirectory.ContainsTag(tagIdentifier)) - { - string[] oldStrings; - string[] newStrings; - try - { - oldStrings = aDirectory.GetStringArray(tagIdentifier); - } - catch (MetadataException) - { - oldStrings = null; - } - if (oldStrings == null) - { - newStrings = new String[1]; - } - else - { - newStrings = new string[oldStrings.Length + 1]; - for (int i = 0; i < oldStrings.Length; i++) - { - newStrings[i] = oldStrings[i]; - } - } - newStrings[newStrings.Length - 1] = str; - aDirectory.SetObject(tagIdentifier, newStrings); - } - else - { - aDirectory.SetObject(tagIdentifier, str); - } - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/jpeg/JpegCommentDescriptor.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/jpeg/JpegCommentDescriptor.cs deleted file mode 100644 index decf290a2e..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/jpeg/JpegCommentDescriptor.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using com.drew.metadata; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.jpeg -{ - /// - /// Tag descriptor for Jpeg - /// - public class JpegCommentDescriptor : AbstractTagDescriptor - { - /// - /// Constructor of the object - /// - /// a directory - public JpegCommentDescriptor(AbstractDirectory directory) : base(directory) - { - } - - /// - /// Returns a descriptive value of the the specified tag for this image. - /// Where possible, known values will be substituted here in place of the raw tokens actually - /// kept in the Exif segment. - /// If no substitution is available, the value provided by GetString(int) will be returned. - /// This and GetString(int) are the only 'get' methods that won't throw an exception. - /// - /// the tag to find a description for - /// a description of the image'str value for the specified tag, or null if the tag hasn't been defined. - public override string GetDescription(int tagType) - { - return base.directory.GetString(tagType); - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/jpeg/JpegCommentDirectory.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/jpeg/JpegCommentDirectory.cs deleted file mode 100644 index 2d48103785..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/jpeg/JpegCommentDirectory.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using com.drew.metadata; -using com.utils.bundle; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.jpeg -{ - /// - /// The JpegComment Directory class - /// - public class JpegCommentDirectory : AbstractDirectory - { - /// - /// This is in bits/sample, usually 8 (12 and 16 not supported by most software). - /// - public static int TAG_JPEG_COMMENT = 0; - - /// - /// Constructor of the object. - /// - public JpegCommentDirectory() - : base("JpegMarkernote") - { - this.SetDescriptor(new JpegCommentDescriptor(this)); - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/jpeg/JpegCommentReader.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/jpeg/JpegCommentReader.cs deleted file mode 100644 index 9742526bd2..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/jpeg/JpegCommentReader.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System; -using System.Collections; -using System.IO; -using com.drew.metadata; -using com.drew.imaging.jpg; -using com.utils; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.jpeg -{ - /// - /// The Jpeg reader class - /// - public class JpegCommentReader : AbstractMetadataReader - { - - /// - /// Creates a new JpegCommentReader for the specified Jpeg jpegFile. - /// - /// where to read - public JpegCommentReader(FileInfo aFile) : base(aFile, JpegSegmentReader.SEGMENT_COM) - { - } - - /// - /// Constructor of the object - /// - /// the data to read - public JpegCommentReader(byte[] aData) - : base(aData) - { - } - - /// - /// Extracts aMetadata - /// - /// where to add aMetadata - /// the aMetadata found - public override Metadata Extract(Metadata aMetadata) - { - if (base.data == null) - { - return aMetadata; - } - - AbstractDirectory lcDirectory = aMetadata.GetDirectory("com.drew.metadata.jpeg.JpegCommentDirectory"); - string comment = Utils.Decode(base.data, true); - lcDirectory.SetObject(JpegCommentDirectory.TAG_JPEG_COMMENT,comment); - return aMetadata; - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/jpeg/JpegComponent.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/jpeg/JpegComponent.cs deleted file mode 100644 index 8a9d7bb424..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/jpeg/JpegComponent.cs +++ /dev/null @@ -1,131 +0,0 @@ -using System; -using System.Collections; -using System.IO; -using com.drew.metadata; -using System.Text; - - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.jpeg -{ - /// - /// The Jpeg component class - /// - [Serializable] - public class JpegComponent - { - private int componentId; - public int ComponentId - { - get - { - return this.componentId; - } - } - - private int quantizationTableNumber; - public int QuantizationTableNumber - { - get - { - return this.quantizationTableNumber; - } - } - - private int samplingFactorByte; - /// - /// Gets the Horizontal Sampling Factor - /// - /// the Horizontal Sampling Factor - public int HorizontalSamplingFactor - { - get - { - return this.samplingFactorByte & 0x0F; - } - } - /// - /// Gets the Vertical Sampling Factor - /// - /// the Vertical Sampling Factor - public int VerticalSamplingFactor - { - get - { - return (this.samplingFactorByte >> 4) & 0x0F; - } - } - - /// - /// The constructor of the object - /// - /// the component id - /// the sampling lcFactor byte - /// the quantization table number - public JpegComponent( - int aComponentId, - int aSamplingFactorByte, - int aQuantizationTableNumber) : base() - { - this.componentId = aComponentId; - this.samplingFactorByte = aSamplingFactorByte; - this.quantizationTableNumber = aQuantizationTableNumber; - } - - /// - /// The component name - /// - /// The component name - public string GetComponentName() - { - switch (this.componentId) - { - case 1 : - return "Y"; - case 2 : - return "Cb"; - case 3 : - return "Cr"; - case 4 : - return "I"; - case 5 : - return "Q"; - default : - throw new MetadataException("Unsupported component id: " + this.componentId); - } - } - - /// - /// Gives a representation of the JpegComponent. - /// - /// The JpegComponent in a readable way - public override string ToString() - { - StringBuilder buff = new StringBuilder(); - buff.Append(this.componentId).Append(','); - buff.Append(this.samplingFactorByte).Append(','); - buff.Append(this.quantizationTableNumber).Append(','); - return buff.ToString(); - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/jpeg/JpegDescriptor.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/jpeg/JpegDescriptor.cs deleted file mode 100644 index 794edfffed..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/jpeg/JpegDescriptor.cs +++ /dev/null @@ -1,124 +0,0 @@ -using System; -using System.Text; -using System.IO; -using com.drew.metadata; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.jpeg -{ - /// - /// Tag descriptor for Jpeg - /// - public class JpegDescriptor : AbstractTagDescriptor - { - /// - /// Constructor of the object - /// - /// a directory - public JpegDescriptor(AbstractDirectory directory) : base(directory) - { - } - - /// - /// Returns a descriptive value of the the specified tag for this image. - /// Where possible, known values will be substituted here in place of the raw tokens actually - /// kept in the Exif segment. - /// If no substitution is available, the value provided by GetString(int) will be returned. - /// This and GetString(int) are the only 'get' methods that won't throw an exception. - /// - /// the tag to find a description for - /// a description of the image'str value for the specified tag, or null if the tag hasn't been defined. - public override string GetDescription(int tagType) - { - switch(tagType) - { - case JpegDirectory.TAG_JPEG_COMPONENT_DATA_1 : - return GetComponentDataDescription(0); - case JpegDirectory.TAG_JPEG_COMPONENT_DATA_2 : - return GetComponentDataDescription(1); - case JpegDirectory.TAG_JPEG_COMPONENT_DATA_3 : - return GetComponentDataDescription(2); - case JpegDirectory.TAG_JPEG_COMPONENT_DATA_4 : - return GetComponentDataDescription(3); - case JpegDirectory.TAG_JPEG_DATA_PRECISION : - return GetDataPrecisionDescription(); - case JpegDirectory.TAG_JPEG_IMAGE_HEIGHT : - return GetImageHeightDescription(); - case JpegDirectory.TAG_JPEG_IMAGE_WIDTH : - return GetImageWidthDescription(); - default : - return base.directory.GetString(tagType); - } - } - - /// - /// Gets the image width description - /// - /// the image width description - public string GetImageWidthDescription() - { - return BUNDLE["PIXELS", base.directory.GetString(JpegDirectory.TAG_JPEG_IMAGE_WIDTH)]; - } - - /// - /// Gets the image height description - /// - /// the image height description - public string GetImageHeightDescription() - { - return BUNDLE["PIXELS", base.directory.GetString(JpegDirectory.TAG_JPEG_IMAGE_HEIGHT)]; - } - - /// - /// Gets the Data Precision description - /// - /// the Data Precision description - public string GetDataPrecisionDescription() - { - return BUNDLE["BITS", base.directory.GetString(JpegDirectory.TAG_JPEG_DATA_PRECISION)]; - } - - /// - /// Gets the Component Data description - /// - /// the component number - /// the Component Data description - public string GetComponentDataDescription(int componentNumber) - { - JpegComponent component = - ((JpegDirectory)base.directory).GetComponent(componentNumber); - if (component == null) - { - throw new MetadataException("No Jpeg component exists with number " + componentNumber); - } - - // {0} component: Quantization table {1}, Sampling factors {2} horiz/{3} vert - string[] tab = new string[] {component.GetComponentName(), - component.QuantizationTableNumber.ToString(), - component.HorizontalSamplingFactor.ToString(), - component.VerticalSamplingFactor.ToString()}; - - return BUNDLE["COMPONENT_DATA", tab]; - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/jpeg/JpegDirectory.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/jpeg/JpegDirectory.cs deleted file mode 100644 index 72a8c9223b..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/jpeg/JpegDirectory.cs +++ /dev/null @@ -1,133 +0,0 @@ -using System; -using System.Text; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using com.drew.metadata; -using com.utils.bundle; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.jpeg -{ - /// - /// The Jpeg Directory class - /// - public class JpegDirectory : AbstractDirectory - { - /// - /// This is in bits/sample, usually 8 (12 and 16 not supported by most software). - /// - public const int TAG_JPEG_DATA_PRECISION = 0; - - /// - /// The image'str height. Necessary for decoding the image, so it should always be there. - /// - public const int TAG_JPEG_IMAGE_HEIGHT = 1; - - /// - /// The image'str width. Necessary for decoding the image, so it should always be there. - /// - public const int TAG_JPEG_IMAGE_WIDTH = 3; - - /// - /// Usually 1 = grey scaled, 3 = color YcbCr or YIQ, 4 = color CMYK Each component TAG_COMPONENT_DATA_[1-4], - /// has the following meaning: component Id(1byte)(1 = Y, 2 = Cb, 3 = Cr, 4 = I, 5 = Q), - /// sampling factors (1byte) (bit 0-3 vertical., 4-7 horizontal.), - /// quantization table number (1 byte). - /// This info is from http://www.funducode.com/freec/Fileformats/format3/format3b.htm - /// - public const int TAG_JPEG_NUMBER_OF_COMPONENTS = 5; - - // NOTE! Component tag type int values must increment in steps of 1 - - /// - /// the first of a possible 4 color components. Number of components specified in TAG_JPEG_NUMBER_OF_COMPONENTS. - /// - public const int TAG_JPEG_COMPONENT_DATA_1 = 6; - - /// - /// the second of a possible 4 color components. Number of components specified in TAG_JPEG_NUMBER_OF_COMPONENTS. - /// - public const int TAG_JPEG_COMPONENT_DATA_2 = 7; - - /// - /// the third of a possible 4 color components. Number of components specified in TAG_JPEG_NUMBER_OF_COMPONENTS. - /// - public const int TAG_JPEG_COMPONENT_DATA_3 = 8; - - /// - /// the fourth of a possible 4 color components. Number of components specified in TAG_JPEG_NUMBER_OF_COMPONENTS. - /// - public const int TAG_JPEG_COMPONENT_DATA_4 = 9; - - /// - /// Constructor of the object. - /// - public JpegDirectory() - : base("JpegMarkernote") - { - this.SetDescriptor(new JpegDescriptor(this)); - } - - /// - /// Gets the component - /// - /// The zero-based index of the component. This number is normally between 0 and 3. Use GetNumberOfComponents for bounds-checking. - /// the JpegComponent - public JpegComponent GetComponent(int componentNumber) - { - int tagType = JpegDirectory.TAG_JPEG_COMPONENT_DATA_1 + componentNumber; - - JpegComponent component = (JpegComponent) GetObject(tagType); - - return component; - } - - /// - /// Gets image width - /// - /// image width - public int GetImageWidth() - { - return GetInt(JpegDirectory.TAG_JPEG_IMAGE_WIDTH); - } - - /// - /// Gets image height - /// - /// image height - public int GetImageHeight() - { - return GetInt(JpegDirectory.TAG_JPEG_IMAGE_HEIGHT); - } - - /// - /// Gets the Number Of Components - /// - /// the Number Of Components - public int GetNumberOfComponents() - { - return GetInt(JpegDirectory.TAG_JPEG_NUMBER_OF_COMPONENTS); - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/jpeg/JpegReader.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/jpeg/JpegReader.cs deleted file mode 100644 index 575f627bed..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/drew/metadata/jpeg/JpegReader.cs +++ /dev/null @@ -1,124 +0,0 @@ -using System; -using System.Text; -using System.Collections; -using System.IO; -using com.drew.metadata; -using com.drew.imaging.jpg; -using System.Diagnostics; - -/// -/// This class was first written by Drew Noakes in Java. -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// If you make use of this code, Drew Noakes will appreciate hearing -/// about it: drew@drewnoakes.com -/// -/// Latest Java version of this software kept at -/// http://drewnoakes.com/ -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.drew.metadata.jpeg -{ - /// - /// The JPEG reader class - /// - public class JpegReader : AbstractMetadataReader - { - - /// - /// Creates a new JpegReader for the specified Jpeg jpegFile. - /// - /// where to read - public JpegReader(FileInfo aFile) : base(aFile, JpegSegmentReader.SEGMENT_SOF0) - { - } - - /// - /// Constructor of the object - /// - /// the data to read - public JpegReader(byte[] aData) - : base(aData) - { - } - - /// - /// Extracts aMetadata - /// - /// where to add aMetadata - /// the aMetadata found - public override Metadata Extract(Metadata aMetadata) - { - if (base.data == null) - { - return aMetadata; - } - - AbstractDirectory lcDirectory = aMetadata.GetDirectory("com.drew.metadata.jpeg.JpegDirectory"); - - try - { - // data precision - int dataPrecision = - base.Get16Bits(JpegDirectory.TAG_JPEG_DATA_PRECISION); - lcDirectory.SetObject( - JpegDirectory.TAG_JPEG_DATA_PRECISION, - dataPrecision); - - // process height - int height = base.Get32Bits(JpegDirectory.TAG_JPEG_IMAGE_HEIGHT); - lcDirectory.SetObject(JpegDirectory.TAG_JPEG_IMAGE_HEIGHT, height); - - // process width - int width = base.Get32Bits(JpegDirectory.TAG_JPEG_IMAGE_WIDTH); - lcDirectory.SetObject(JpegDirectory.TAG_JPEG_IMAGE_WIDTH, width); - - // number of components - int numberOfComponents = - base.Get16Bits(JpegDirectory.TAG_JPEG_NUMBER_OF_COMPONENTS); - lcDirectory.SetObject( - JpegDirectory.TAG_JPEG_NUMBER_OF_COMPONENTS, - numberOfComponents); - - // for each component, there are three bytes of data: - // 1 - Component ID: 1 = Y, 2 = Cb, 3 = Cr, 4 = I, 5 = Q - // 2 - Sampling factors: bit 0-3 vertical, 4-7 horizontal - // 3 - Quantization table number - int offset = 6; - for (int i = 0; i < numberOfComponents; i++) - { - int componentId = base.Get16Bits(offset++); - int samplingFactorByte = base.Get16Bits(offset++); - int quantizationTableNumber = base.Get16Bits(offset++); - JpegComponent lcJpegComponent = - new JpegComponent( - componentId, - samplingFactorByte, - quantizationTableNumber); - lcDirectory.SetObject( - JpegDirectory.TAG_JPEG_COMPONENT_DATA_1 + i, - lcJpegComponent); - } - - } - catch (MetadataException me) - { - lcDirectory.HasError = true; - Trace.TraceError("MetadataException: " + me.Message); - } - - return aMetadata; - } - - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/test/resouces/TestAllKeyWords.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/test/resouces/TestAllKeyWords.cs deleted file mode 100644 index 297d56911c..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/test/resouces/TestAllKeyWords.cs +++ /dev/null @@ -1,126 +0,0 @@ -using System; -using System.Text; -using System.IO; -using System.Resources; -using System.Reflection; -using System.Collections; -using System.Collections.Generic; - -using com.drew.metadata; -using com.drew.metadata.exif; -using com.drew.metadata.iptc; -using com.drew.metadata.jpeg; -using com.drew.imaging.jpg; - -using com.utils; -using com.utils.bundle; -using com.utils.xml; - -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.test.resources -{ - /// - /// Test if all references to BUNDLE["xxx"] works. - /// - public sealed class TestAllKeyWords - { - ///// - ///// Where are all cs file, asking for the top root folder (ex: c:/temp/com") - ///// - //private static string CS_ROOT_FOLDER = "C:/Documents and Settings/Renaud91/Mes documents/MetaDataExtractorCSharp/MetaDataExtractor/com"; - //private static IResourceBundle BUNDLE = ResourceBundleFactory.CreateDefaultBundle("Commons", null); - - //public static void SearchAndExecuteBundle(string aCsFileName) - //{ - // Console.WriteLine("Reading file '" + aCsFileName + "'"); - // FileStream lcFileStream = File.Open(aCsFileName, FileMode.Open, FileAccess.Read); - // byte[] lcByteRead = new byte[lcFileStream.Length]; - // lcFileStream.Read(lcByteRead, 0, (int)lcFileStream.Length); - // StringBuilder lcBuff = new StringBuilder((int)lcFileStream.Length); - // for (int i = 0; i < lcFileStream.Length; i++) - // { - // lcBuff.Append((char)lcByteRead[i]); - // } - // // Search for BUNDLE[" - // string lcStr = lcBuff.ToString(); - // int lcStartIndex = 0; - // while (lcStartIndex >= 0 &&lcStartIndex < lcStr.Length) - // { - // int lcFoundIndex = lcStr.IndexOf("BUNDLE[\"", lcStartIndex); - // int lcEndIndex = -1; - // if (lcFoundIndex > 0) - // { - // lcFoundIndex += +"BUNDLE[\"".Length; - // lcEndIndex = lcStr.IndexOf("\"", lcFoundIndex); - // if (lcEndIndex != -1) - // { - // try - // { - // string tmp = BUNDLE[lcStr.Substring(lcFoundIndex, lcEndIndex - lcFoundIndex)]; - // } - // catch (MissingResourceException e) - // { - // Console.Error.WriteLine(e.Message); - // break; - // } - // } - // } - // lcStartIndex = lcEndIndex; - // } - //} - - /// - /// Test if all references to BUNDLE["xxx"] works. - /// - /// Arguments - //[STAThread] - //public static void Main(string[] someArgs) - //{ - // Console.WriteLine("-- Starting TestAllKeyWords class --"); - // // First instanciate all Directory in order to fill the Dictionnary and checks key - // try - // { - // new CanonDirectory(); - // new CasioType1Directory(); - // new CasioType2Directory(); - // new ExifDirectory(); - // new ExifInteropDirectory(); - // new FujifilmDirectory(); - // new GpsDirectory(); - // new KodakDirectory(); - // new KyoceraDirectory(); - // new NikonType1Directory(); - // new NikonType2Directory(); - // new OlympusDirectory(); - // new PanasonicDirectory(); - // new PentaxDirectory(); - // new SonyDirectory(); - // new IptcDirectory(); - // new JpegCommentDirectory(); - // new JpegDirectory(); - // } - // catch (Exception e) - // { - // Console.WriteLine(e.Message); - // } - // // Then look for all CS - // List lcAllCs = Utils.SearchAllFileIn(CS_ROOT_FOLDER, true, "*.cs"); - // IEnumerator lcEnumCs = lcAllCs.GetEnumerator(); - // while (lcEnumCs.MoveNext()) - // { - // string lcCsFileName = lcEnumCs.Current; - // if (lcCsFileName.Contains("Descriptor")) - // { - // //But only for descriptor ones, we checks Commons.txt - // SearchAndExecuteBundle(lcCsFileName); - // } - // } - // Console.WriteLine("-- Ending TestAllKeyWords class --"); - // Console.ReadLine(); - //} - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/utils/Utils.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/utils/Utils.cs deleted file mode 100644 index 2aec460b6e..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/utils/Utils.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System; -using System.Text; -using System.IO; -using System.Collections; -using System.Collections.Generic; - -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.utils -{ - /// - /// Class that try to recreate some Java functionnalities. - /// - public sealed class Utils - { - /// - /// Constructor of the object - /// - /// always - private Utils() - : base() - { - throw new UnauthorizedAccessException("Do not use"); - } - - /// - /// Builds a string from a byte array - /// - /// the array of byte - /// where to start - /// the length to transform in string - /// if true, spaces will be avoid - /// a string representing the array of byte - public static string Decode(byte[] anArray, int offset, int length, bool removeSpace) - { - StringBuilder sb = new StringBuilder(length); - for(int i=offset; i - /// Builds a string from a byte array - ///
- /// the array of byte - /// if true, spaces will be avoid - /// a string representing the array of byte - public static string Decode(byte[] anArray, bool removeSpace) - { - return Decode(anArray, 0, anArray.Length, removeSpace); - } - - /// - /// Search for files in the given directory. - /// - /// Where to start the search - /// if true will do sub directories as well - /// if not null will take only file with the given axtension (ex "*.jpg") - /// a list of file name - public static List SearchAllFileIn(String aRootDirectory, bool doRecurse, string aSearchPattern) - { - List lcResult = new List(); - if (File.Exists(aRootDirectory)) - { - FileInfo f = new FileInfo(aRootDirectory); - if (aSearchPattern.Contains(f.Extension)) - { - lcResult.Add(aRootDirectory); - } - } - else if (Directory.Exists(aRootDirectory)) - { - string[] lc2List = Directory.GetFiles(aRootDirectory, aSearchPattern, (doRecurse) ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly); - for (int i = 0; i < lc2List.Length; i++) - { - lcResult.Add(lc2List[i]); - } - } - return lcResult; - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/utils/bundle/AbstractResourceBundle.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/utils/bundle/AbstractResourceBundle.cs deleted file mode 100644 index 47d89df024..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/utils/bundle/AbstractResourceBundle.cs +++ /dev/null @@ -1,151 +0,0 @@ -using System; -using System.Text; -using System.IO; -using System.Reflection; -using System.Collections; -using System.Collections.Generic; -using System.Resources; -using System.Globalization; - -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.utils.bundle -{ - /// - /// This class is an abstract bundle class.
- /// - /// Used for internationalisation (multi-language).
- /// - /// Allow the use of messages with holes.
- /// - /// Example: - ///
-    /// KEY1=Hello
-    /// KEY2=Hello {0}
-    /// KEY3=Hello {0} with an age of {1}
-    /// Then you will use :
-    /// myBundle["KEY1"];
-    /// myBundle["KEY2", "Jhon"];
-    /// myBundle["KEY3", "Jhon", 32.ToString()];
-    /// myBundle["KEY3", new string[] {"Jhon", 32.ToString()}];
-    /// 
- ///
- abstract class AbstractResourceBundle : IResourceBundle - { - private string name; - - public string Name - { - get { return this.name; } - set { this.name = value; } - } - - private string fullName; - - public string Fullname - { - get { return this.fullName; } - set { this.fullName = value; } - } - - public abstract IDictionary Entries - { - get; - } - - /// - /// Indexator on a simple aMessage. - /// - /// the referenced key - /// the aMessage attached to this key, or launch a MissingResourceException if none found - public string this[string aKey] - { - get - { - return this[aKey, new string[] { null }]; - } - } - - /// - /// Indexator on a aMessage with one hole {0} in it. - /// - /// the referenced key - /// what to put in hole {0} - /// the aMessage attached to this key, or launch a MissingResourceException if none found - public string this[string aKey, string fillGapWith] - { - get - { - return this[aKey, new string[] { fillGapWith }]; - } - } - - /// - /// Indexator on a aMessage with two holes {0} and {1} in it. - /// - /// the referenced key - /// what to put in hole {0} - /// what to put in hole {1} - /// the aMessage attached to this key, or launch a MissingResourceException if none found - public string this[string aKey, string fillGap0, string fillGap1] - { - get - { - return this[aKey, new string[] { fillGap0, fillGap1 }]; - } - } - - - /// - /// Indexator on a aMessage with many holes {0}, {1}, {2] ... in it. - /// - /// the referenced key - /// what to put in holes. fillGapWith[0] used for {0}, fillGapWith[1] used for {1} ... - /// the aMessage attached to this key, or launch a MissingResourceException if none found - public abstract string this[string aKey, string[] fillGapWith] - { - get; - } - - /// - /// Constructor of the object. - /// - /// Keep private, use the other one. - /// - protected AbstractResourceBundle() - : base() - { - } - - - /// - /// Fills the gap in a string. - /// - /// where to fill the gap. A gap is {0} or {1} ... - /// what to put in the gap. fillGapWith[0] will go in {0} and so on - /// - protected string replace(string aLine, string[] fillGapWith) - { - for (int i = 0; i < fillGapWith.Length; i++) - { - if (fillGapWith[i] == null) - { - fillGapWith[i] = ""; - } - aLine = aLine.Replace("{" + i + "}", fillGapWith[i]); - } - return aLine; - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/utils/bundle/IResourceBundle.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/utils/bundle/IResourceBundle.cs deleted file mode 100644 index c11e4bb94e..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/utils/bundle/IResourceBundle.cs +++ /dev/null @@ -1,107 +0,0 @@ -using System; -using System.Text; -using System.IO; -using System.Reflection; -using System.Collections; -using System.Collections.Generic; -using System.Resources; -using System.Globalization; - -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.utils.bundle -{ - /// - /// This interface represent a bundle class.
- /// - /// Used for internationalisation (multi-language).
- /// - /// Allow the use of messages with holes.
- /// - ///
- public interface IResourceBundle - { - /// - /// Gets/sets the name of this bundle (ex: CanonMarkernote). - /// - string Name - { - get; - set; - } - - /// - /// Gets/sets the full name of this bundle (ex: /resources/en/CanonMarkernote.txt) - /// - string Fullname - { - get; - set; - } - - /// - /// Gets the dictionnaries entry for this bundle. - /// - IDictionary Entries - { - get; - } - - - - /// - /// Indexator on a simple aMessage. - /// - /// the referenced key - /// the aMessage attached to this key, or launch a MissingResourceException if none found - string this[string aKey] - { - get; - } - - /// - /// Indexator on a aMessage with one hole {0} in it. - /// - /// the referenced key - /// what to put in hole {0} - /// the aMessage attached to this key, or launch a MissingResourceException if none found - string this[string aKey, string fillGapWith] - { - get; - } - - /// - /// Indexator on a aMessage with two holes {0} and {1} in it. - /// - /// the referenced key - /// what to put in hole {0} - /// what to put in hole {1} - /// the aMessage attached to this key, or launch a MissingResourceException if none found - string this[string aKey, string fillGap0, string fillGap1] - { - get; - } - - /// - /// Indexator on a aMessage with many holes {0}, {1}, {2] ... in it. - /// - /// the referenced key - /// what to put in holes. fillGapWith[0] used for {0}, fillGapWith[1] used for {1} ... - /// the aMessage attached to this key, or launch a MissingResourceException if none found - string this[string aKey, string[] fillGapWith] - { - get; - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/utils/bundle/MissingResourceException.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/utils/bundle/MissingResourceException.cs deleted file mode 100644 index 08596e9ac9..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/utils/bundle/MissingResourceException.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System; -using com.drew.lang; - -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.utils.bundle -{ - /// - /// This class represents a missing resource exception. - /// - /// Used by ResourveBundle class. - /// - public class MissingResourceException : CompoundException - { - /// - /// Constructor of the object - /// - /// The error aMessage - public MissingResourceException(string message) : base(message) - { - } - - /// - /// Constructor of the object - /// - /// The error aMessage - /// The aCause of the exception - public MissingResourceException(string message, Exception cause) : base(message, cause) - { - } - - /// - /// Constructor of the object - /// - /// The aCause of the exception - public MissingResourceException(Exception cause) - : base(cause) - { - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/utils/bundle/ResourceBundle.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/utils/bundle/ResourceBundle.cs deleted file mode 100644 index 6dd4258e2f..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/utils/bundle/ResourceBundle.cs +++ /dev/null @@ -1,181 +0,0 @@ -using System; -using System.Text; -using System.IO; -using System.Reflection; -using System.Collections; -using System.Collections.Generic; -using System.Resources; -using System.Globalization; - -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.utils.bundle -{ - /// - /// This class is a bundle class.
- /// - /// Used for internationalisation (multi-language).
- /// - /// Allow the use of messages with holes.
- /// - /// Example: - ///
-    /// KEY1=Hello
-    /// KEY2=Hello {0}
-    /// KEY3=Hello {0} with an age of {1}
-    /// Then you will use :
-    /// myBundle["KEY1"];
-    /// myBundle["KEY2", "Jhon"];
-    /// myBundle["KEY3", "Jhon", 32.ToString()];
-    /// myBundle["KEY3", new string[] {"Jhon", 32.ToString()}];
-    /// 
- ///
- sealed class ResourceBundle : AbstractResourceBundle - { - private IDictionary resourceManager; - public override IDictionary Entries - { - get { return this.resourceManager; } - } - - - /// - /// Indexator on a aMessage with many holes {0}, {1}, {2] ... in it. - /// - /// the referenced key - /// what to put in holes. fillGapWith[0] used for {0}, fillGapWith[1] used for {1} ... - /// the aMessage attached to this key, or launch a MissingResourceException if none found - public override string this[string aKey, string[] fillGapWith] - { - get - { - string resu = this.resourceManager[aKey]; - if (resu == null) - { - throw new MissingResourceException("\"" + aKey + "\" Not found"); - } - return replace(resu, fillGapWith); - } - } - - /// - /// Constructor of the object. - /// - /// Keep private, use the other one. - /// - private ResourceBundle() - : base() - { - } - - /// - /// Constructor of the object.
- /// Will use default resources by default. - ///
- /// The resource file where to find keys. Do not add the extension and do not forget to add your resource file into the assembly. - public ResourceBundle(string aPropertyFileName) - : this(aPropertyFileName, null) - { - } - - /// - /// Constructor of the object. - /// - /// The resource file where to find keys. Do not add the extension and do not forget to add your resource file into the assembly. - /// The culture info. Can be null - public ResourceBundle(string aPropertyFileName, CultureInfo aCultureInfo) - : base() - { - Assembly assembly = Assembly.GetExecutingAssembly(); - - StreamReader reader = null; - string cultureInfo = ""; - if (aCultureInfo != null && !aCultureInfo.IsNeutralCulture) - { - cultureInfo = aCultureInfo.TwoLetterISOLanguageName + "."; - } - string rsFile = assembly.GetName().Name +".resources." + cultureInfo + aPropertyFileName + ".txt"; - string defaultFile = assembly.GetName().Name + ".resources." + aPropertyFileName + ".txt"; - Stream strm = null; - Encoding useEncoding = Encoding.UTF8; - try - { - - strm = assembly.GetManifestResourceStream(rsFile); - reader = new StreamReader(strm, useEncoding); - this.resourceManager = this.LoadFromFile(reader); - } - catch (Exception) - { - // Console.Error.WriteLine("Caution : Resource file '" + rsFile + "' was not found ! (" + e.Message + "). Will use default file '" + defaultFile + "'"); - try - { - - strm = assembly.GetManifestResourceStream(defaultFile); - reader = new StreamReader(strm, useEncoding); - this.resourceManager = this.LoadFromFile(reader); - } - catch (Exception e2) - { - Console.Error.WriteLine("Caution : Default Resource file '" + defaultFile + "' was not found too ! (" + e2.Message + ")."); - this.resourceManager = new Dictionary(0); - } - - } - finally - { - if (strm != null) - { - strm.Close(); - strm.Dispose(); - } - - if (reader != null) - { - reader.Close(); - reader.Dispose(); - } - } - this.Name = aPropertyFileName; - this.Fullname = rsFile; - } - - /// - /// Reads a stream and take out the bundle.
- /// This method was created beacause resources file is a pain in the ace to handle for consol application. - ///
- /// A stream. Caution : you are responsible for opening and closing this stream. - /// A dictionnary with all info stored as key=value - private IDictionary LoadFromFile(StreamReader aStream) - { - string line = null; - IDictionary bundle = new Dictionary(); - while (!aStream.EndOfStream) - { - line = aStream.ReadLine(); - if (line != null && !line.StartsWith("#") && line.Length > 0) - { - int id = line.IndexOf("="); - if (id > 0) - { - string key = line.Substring(0, id); - string valueFk = line.Substring(id + 1); - bundle.Add(key, valueFk); - } - } - } - return bundle; - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/utils/bundle/ResourceBundleFactory.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/utils/bundle/ResourceBundleFactory.cs deleted file mode 100644 index e1ac6250b0..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/utils/bundle/ResourceBundleFactory.cs +++ /dev/null @@ -1,131 +0,0 @@ -using System; -using System.Text; -using System.IO; -using System.Reflection; -using System.Collections; -using System.Collections.Generic; -using System.Resources; -using System.Diagnostics; -using System.Globalization; - -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.utils.bundle -{ - /// - /// This class is a bundle factory class.
- /// - /// You can switch the implementation or ResourceBundle using this class.
- /// - ///
- public sealed class ResourceBundleFactory - { - public static int USE_MANAGER = 0; - public static int USE_TXTFILE = 1; - - /// - /// Indicates the default instance you want to use for ALL your bundle. - /// - private static int DEFAULT_USE = USE_TXTFILE; - - /// - /// All bundle stored in this dictionnary. - /// - private static IDictionary BUNDLES = new Dictionary(); - - - - /// - /// Constructor of the object.
- /// Does nothing, do not use. - ///
- private ResourceBundleFactory() - { - } - - /// - /// Gives an instance of resource bundle using default choice (see DEFAULT_USE). - /// Caution CultureInfo.CurrentCulture will be used. - /// - /// Name of the bundle you are looking for (ex: CanonMarkernote) - /// - public static IResourceBundle CreateDefaultBundle(string aName) - { - return ResourceBundleFactory.CreateBundle(aName, CultureInfo.CurrentCulture, ResourceBundleFactory.DEFAULT_USE); - } - - /// - /// Gives an instance of resource bundle using default choice (see DEFAULT_USE). - /// - /// Name of the bundle you are looking for (ex: CanonMarkernote) - /// a cultural info. Can be null - /// - public static IResourceBundle CreateDefaultBundle(string aName, CultureInfo aCulturalInfo) - { - return ResourceBundleFactory.CreateBundle(aName, aCulturalInfo, ResourceBundleFactory.DEFAULT_USE); - } - - static readonly object Locker = new object(); - - /// - /// Gives an instance of resource bundle. - /// - /// Name of the bundle you are looking for (ex: CanonMarkernote) - /// a cultural info. Can be null - /// a type of bundle (See USE_MANAGER or USE_TXTFILE) - /// the bundle found or loade. - public static IResourceBundle CreateBundle(string aName, CultureInfo aCulturalInfo, int aType) - { - string key = aName; - if (aCulturalInfo != null) - { - key += "_" + aCulturalInfo.ToString(); - } - lock (Locker) - { - IResourceBundle resu = null; - if (!ResourceBundleFactory.BUNDLES.ContainsKey(key)) - { - try - { - if (aType == ResourceBundleFactory.USE_MANAGER) - { - resu = new ResourceBundleWithManager(aName, aCulturalInfo); - } - else if (aType == ResourceBundleFactory.USE_TXTFILE) - { - resu = new ResourceBundle(aName, aCulturalInfo); - } - } - catch (Exception e) - { - Trace.TraceError("Could not load bundle '" + aName + "' (" + e.Message + ")"); - } - if (resu == null || resu["TEST"] == null) - { - throw new Exception("Error while loading bundle '" + aName + "' for cultural '" + aCulturalInfo + - "'"); - } - ResourceBundleFactory.BUNDLES.Add(key, resu); - } - else - { - resu = ResourceBundleFactory.BUNDLES[key]; - } - - return resu; - } - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/utils/bundle/ResourceBundleWithManager.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/utils/bundle/ResourceBundleWithManager.cs deleted file mode 100644 index 6e25d4822c..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/utils/bundle/ResourceBundleWithManager.cs +++ /dev/null @@ -1,118 +0,0 @@ -using System; -using System.Text; -using System.IO; -using System.Reflection; -using System.Collections; -using System.Collections.Generic; -using System.Resources; -using System.Globalization; - -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.utils.bundle -{ - /// - /// This class is a bundle class that try to use the xxx.resources file.
- /// - /// For some misterious reason I could not make it work so it is not use.
- /// I keep it in cas I would need it some day.
- ///
- sealed class ResourceBundleWithManager : AbstractResourceBundle - { - private CultureInfo culturalInfo; - private ResourceManager resourceManager; - - private IDictionary resourceManagerAsDic; - public override IDictionary Entries - { - get { return this.resourceManagerAsDic; } - } - - - /// - /// Indexator on a aMessage with many holes {0}, {1}, {2] ... in it. - /// - /// the referenced key - /// what to put in holes. fillGapWith[0] used for {0}, fillGapWith[1] used for {1} ... - /// the aMessage attached to this key, or launch a MissingResourceException if none found - public override string this[string aKey, string[] fillGapWith] - { - get - { - string resu = this.resourceManager.GetString(aKey, this.culturalInfo); - if (resu == null) - { - throw new MissingResourceException("\"" + aKey + "\" Not found"); - } - return replace(resu, fillGapWith); - } - } - - /// - /// Constructor of the object. - /// - /// Keep private, use the other one. - /// - private ResourceBundleWithManager() - : base() - { - } - - /// - /// Constructor of the object. - /// - /// The resource file where to find keys. Do not add the extension and do not forget to add your resource file into the assembly. - public ResourceBundleWithManager(string aPropertyFileName) - : this(aPropertyFileName, null) - { - } - - /// - /// Constructor of the object. - /// - /// The resource file where to find keys. Do not add the extension and do not forget to add your resource file into the assembly. - /// The culture info. Can be null - public ResourceBundleWithManager(string aPropertyFileName, CultureInfo aCulturalInfo) - : base() - { - this.resourceManager = new ResourceManager(aPropertyFileName, Assembly.GetExecutingAssembly()); - this.resourceManagerAsDic = new Dictionary(); - if (aCulturalInfo != null) - { - ResourceSet rs = this.resourceManager.GetResourceSet(aCulturalInfo, false, false); - IDictionaryEnumerator idicnum = rs.GetEnumerator(); - while (idicnum.MoveNext()) - { - this.resourceManagerAsDic.Add((string)idicnum.Key, (string)idicnum.Value); - } - } - this.Name = aPropertyFileName; - this.Fullname = this.resourceManager.BaseName; - - this.culturalInfo = aCulturalInfo; - } - - /// - /// Clean the object. - /// - public void Dispose() - { - if (this.resourceManager != null) - { - this.resourceManager.ReleaseAllResources(); - this.resourceManager = null; - } - } - } -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/utils/bundle/SpecialResourceWriter.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/utils/bundle/SpecialResourceWriter.cs deleted file mode 100644 index fd94cb34ac..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/utils/bundle/SpecialResourceWriter.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.Text; -using System.IO; -using System.Reflection; -using System.Collections; -using System.Collections.Generic; -using System.Resources; -using System.Globalization; - -/// -/// This is public domain software - that is, you can do whatever you want -/// with it, and include it software that is licensed under the GNU or the -/// BSD license, or whatever other licence you choose, including proprietary -/// closed source licenses. I do ask that you leave this lcHeader in tact. -/// -/// If you make modifications to this code that you think would benefit the -/// wider community, please send me a copy and I'll post it on my site. -/// -/// The C# class was made by Ferret Renaud: -/// renaud91@free.fr -/// If you find a bug in the C# code, feel free to mail me. -/// -namespace com.utils.bundle -{ - /// - /// This class is a bundle factory class.
- /// - /// You can switch the implementation or ResourceBundle using this class.
- /// - ///
- public sealed class SpecialResourceWriter - { - public SpecialResourceWriter() - { - // Load all bunlde - IList allBundle = new List(20); - allBundle.Add(ResourceBundleFactory.CreateBundle("CanonMarkernote", null, ResourceBundleFactory.USE_TXTFILE)); - allBundle.Add(ResourceBundleFactory.CreateBundle("CasioMarkernote", null, ResourceBundleFactory.USE_TXTFILE)); - allBundle.Add(ResourceBundleFactory.CreateBundle("Commons", null, ResourceBundleFactory.USE_TXTFILE)); - allBundle.Add(ResourceBundleFactory.CreateBundle("ExifInteropMarkernote", null, ResourceBundleFactory.USE_TXTFILE)); - allBundle.Add(ResourceBundleFactory.CreateBundle("ExifMarkernote", null, ResourceBundleFactory.USE_TXTFILE)); - allBundle.Add(ResourceBundleFactory.CreateBundle("FujiFilmMarkernote", null, ResourceBundleFactory.USE_TXTFILE)); - allBundle.Add(ResourceBundleFactory.CreateBundle("GpsMarkernote", null, ResourceBundleFactory.USE_TXTFILE)); - allBundle.Add(ResourceBundleFactory.CreateBundle("IptcMarkernote", null, ResourceBundleFactory.USE_TXTFILE)); - allBundle.Add(ResourceBundleFactory.CreateBundle("JpegMarkernote", null, ResourceBundleFactory.USE_TXTFILE)); - allBundle.Add(ResourceBundleFactory.CreateBundle("KodakMarkernote", null, ResourceBundleFactory.USE_TXTFILE)); - allBundle.Add(ResourceBundleFactory.CreateBundle("KyoceraMarkernote", null, ResourceBundleFactory.USE_TXTFILE)); - allBundle.Add(ResourceBundleFactory.CreateBundle("NikonTypeMarkernote", null, ResourceBundleFactory.USE_TXTFILE)); - allBundle.Add(ResourceBundleFactory.CreateBundle("OlympusMarkernote", null, ResourceBundleFactory.USE_TXTFILE)); - allBundle.Add(ResourceBundleFactory.CreateBundle("PanasonicMarkernote", null, ResourceBundleFactory.USE_TXTFILE)); - allBundle.Add(ResourceBundleFactory.CreateBundle("PentaxMarkernote", null, ResourceBundleFactory.USE_TXTFILE)); - allBundle.Add(ResourceBundleFactory.CreateBundle("SonyMarkernote", null, ResourceBundleFactory.USE_TXTFILE)); - - foreach(IResourceBundle bdl in allBundle) - { - ResourceWriter rw = new ResourceWriter(bdl.Fullname+".resources"); - IDictionary idic = bdl.Entries; - IDictionaryEnumerator enumDic = (IDictionaryEnumerator)idic.GetEnumerator(); - while (enumDic.MoveNext()) - { - rw.AddResource((string)enumDic.Key, (string)enumDic.Value); - } - rw.Close(); - rw.Dispose(); - - } - } - } - -} \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/utils/xml/IOutPutTextStreamHandler.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/utils/xml/IOutPutTextStreamHandler.cs deleted file mode 100644 index d601d34fa8..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/utils/xml/IOutPutTextStreamHandler.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using com.drew.metadata; - -namespace com.utils.xml -{ - /// - /// This class handles output text format for metadata. - /// - public interface IOutPutTextStreamHandler - { - /// - /// Get/set the unknown option - /// - bool DoUnknown - { - get; - set; - } - - /// - /// Get/set the metdata attribute - /// - Metadata Metadata - { - get; - set; - } - - /// - /// Start out put stream - /// - /// where to put informations - /// Can be used for anything - void StartTextStream(StringBuilder aBuff, string[] someParam); - - /// - /// Finish out put stream - /// - /// where to put informations - /// Can be used for anything - void EndTextStream(StringBuilder aBuff, string[] someParam); - - - /// - /// Transform the Metadata object into a text stream. - /// - /// The Metadata object as a text stream - string AsText(); - - /// - /// Normalize a value into the text stream - /// - /// where to put normalized value - /// the value to normalize - /// if true will use specific stream, if false will replace FORBIDEN chars by their normal value - void Normalize(StringBuilder aBuff, string aValue, bool useSpecific); - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/utils/xml/TxtOutPutStreamHandler.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/utils/xml/TxtOutPutStreamHandler.cs deleted file mode 100644 index 3bf11eaf96..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/utils/xml/TxtOutPutStreamHandler.cs +++ /dev/null @@ -1,194 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text; -using com.drew.metadata; - -namespace com.utils.xml -{ - /// - /// This class will handle text for a metatdata class - /// - public class TxtOutPutStreamHandler : IOutPutTextStreamHandler - { - private static Dictionary FORBIDEN_CHAR = TxtOutPutStreamHandler.BuildForbidenChar(); - - private Metadata metadata; - public Metadata Metadata - { - get - { - return this.metadata; - } - set - { - this.metadata = value; - } - } - - /// - /// Get/set the unknown option - /// - private bool doUnknown; - public bool DoUnknown - { - get - { - return this.doUnknown; - } - set - { - this.doUnknown = value; - } - } - - /// - /// Constructor of the object. - /// - public TxtOutPutStreamHandler() - : this(null) - { - } - - /// - /// Constructor of the object. - /// - /// the metadata that shoud be transformed into txt - public TxtOutPutStreamHandler(Metadata aMetadata) - : base() - { - this.Metadata = aMetadata; - } - - /// - /// Gives all forbiden letter in txt standard and their correspondance. - /// - /// All forbiden chars and their txt correspondance - private static Dictionary BuildForbidenChar() - { - // Dos consol hates french and no US language ;-) - Dictionary lcResu = new Dictionary(11); - // Usion Unicode for better behavior - lcResu.Add("\xE9", "e");//e2 - lcResu.Add("\xE8", "e");//e4 - lcResu.Add("\xEA", "e");//e3 - lcResu.Add("\xF9", "u");//u4 - lcResu.Add("\xE2", "a");//a3 - lcResu.Add("\xE0", "a");//a4 - lcResu.Add("\xE4", "a");//a5 - lcResu.Add("\xEE", "i");//i3 - lcResu.Add("\xEF", "i");//i5 - lcResu.Add("\xF4", "o");//o3 - lcResu.Add("\xF6", "o");//o5 - return lcResu; - } - - /// - /// Normalize a value into Txt - /// - /// where to put new XML value - /// the value to normalize - /// if false will replace FORBIDEN chars by their normal value, else will do nothing - public virtual void Normalize(StringBuilder aBuff, string aValue, bool useCdata) - { - if (aValue != null) - { - if (useCdata) - { - aBuff.Append(aValue); - } - else - { - // check if value contains strange char and replace them if needed - foreach(KeyValuePair lcPair in FORBIDEN_CHAR) - { - aValue = aValue.Replace(lcPair.Key, lcPair.Value); - } - aBuff.Append(aValue); - } - } - } - - /// - /// Creates an TXT tag using the Tag object info. - /// - /// where to put tag - /// the tag - protected virtual void CreateTag(StringBuilder aBuff, Tag aTag) - { - if (aTag != null) - { - string lcDescription = null; - try - { - lcDescription = aTag.GetDescription(); - } - catch (MetadataException) - { - // Does not care here - } - string lcName = aTag.GetTagName(); - if (!this.DoUnknown && (lcName.ToLower().StartsWith("unknown") || lcDescription.ToLower().StartsWith("unknown"))) - { - // No unKnown and is unKnown so do nothing - return; - } - Normalize(aBuff, lcName, false); - aBuff.Append('='); - Normalize(aBuff, lcDescription, false); - aBuff.AppendLine(); - } - } - - /// - /// Creates a directory tag. - /// - /// where to put info - /// the information to add - protected virtual void CreateDirectory(StringBuilder aBuff, AbstractDirectory aDirectory) - { - if (aDirectory != null) - { - aBuff.Append("--| ").Append(aDirectory.GetName()).Append(" |--"); - aBuff.AppendLine(); - foreach(Tag lcTag in aDirectory) { - CreateTag(aBuff, lcTag); - } - } - } - - /// - /// Transform the metatdat object into an TXT stream. - /// - /// The metadata object as TXT stream - public virtual string AsText() - { - StringBuilder lcBuff = new StringBuilder(); - foreach(AbstractDirectory lcDirectory in this.Metadata) - { - CreateDirectory(lcBuff, lcDirectory); - } - return lcBuff.ToString(); - } - - /// - /// Start out put stream. Does nothing. - /// - /// where to put informations - /// Can be used for anything - public void StartTextStream(StringBuilder aBuff, string[] someParam) - { - // Does nothing - } - - /// - /// Finish out put stream. Does nothing. - /// - /// where to put informations - /// Can be used for anything - public void EndTextStream(StringBuilder aBuff, string[] someParam) - { - // Does nothing - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/utils/xml/XmlNewOutPutStreamHandler.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/utils/xml/XmlNewOutPutStreamHandler.cs deleted file mode 100644 index 0257b22cdf..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/utils/xml/XmlNewOutPutStreamHandler.cs +++ /dev/null @@ -1,579 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text; -using System.IO; -using com.drew.metadata; -using com.drew.metadata.jpeg; -using com.drew.lang; - -namespace com.utils.xml -{ - /// - /// This class will handle XML for a Directory class. - /// - /// For default XML stream you can have a look to MetadataExtractor.dtd file and sampleFile.xml. - /// - public class XmlNewOutPutStreamHandler : IOutPutTextStreamHandler - { - private static Dictionary FORBIDEN_CHAR; - - /// - /// The cached DTD. - /// - private static string LOADED_DTD = null; - - /// - /// The DTD path and file name. - /// - private string dtdFileName; - public string DtdFileName - { - get - { - return this.dtdFileName; - } - set - { - this.dtdFileName = value; - LoadDtd(); - } - } - - - private Metadata metadata; - public Metadata Metadata - { - get - { - return this.metadata; - } - set - { - this.metadata = value; - } - } - - private bool useCDData; - public bool UseCDData - { - get - { - return this.useCDData; - } - set - { - this.useCDData = value; - } - } - - /// - /// Get/set the unknown option - /// - private bool doUnknown; - public bool DoUnknown - { - get - { - return this.doUnknown; - } - set - { - this.doUnknown = value; - } - } - - - /// - /// Constructor of the object. - /// - public XmlNewOutPutStreamHandler() - : this(null) - { - } - - /// - /// Constructor of the object. - /// - /// the metadata that shoud be transformed into XML - public XmlNewOutPutStreamHandler(Metadata aMetadata) - : base() - { - this.Metadata = aMetadata; - this.DtdFileName = "MetadataExtractorNew.dtd"; - XmlNewOutPutStreamHandler.FORBIDEN_CHAR = XmlNewOutPutStreamHandler.BuildForbidenChar(); - } - - /// - /// Gives all forbiden letter in XML standard and their correspondance. - /// - /// All forbiden chars and their XML correspondance - private void LoadDtd() - { - FileStream lcStream = null; - StreamReader lcStreamReader = null; - try - { - - lcStream = File.Open(this.DtdFileName, FileMode.Open, FileAccess.Read); - lcStreamReader = new StreamReader(lcStream); - StringBuilder lcBuff = new StringBuilder(); - while (!lcStreamReader.EndOfStream) - { - lcBuff.Append(lcStreamReader.ReadLine()); - lcBuff.AppendLine(); - } - LOADED_DTD = lcBuff.ToString(); - } - catch (Exception) - { - // Oups Dtd not found - LOADED_DTD = null; - } - finally - { - if (lcStreamReader != null) - { - lcStreamReader.Close(); - lcStreamReader.Dispose(); - } - if (lcStream != null) - { - lcStream.Close(); - lcStream.Dispose(); - } - } - } - - - /// - /// Gives all forbiden letter in XML standard and their correspondance. - /// - /// All forbiden chars and their XML correspondance - private static Dictionary BuildForbidenChar() - { - Dictionary lcResu = new Dictionary(5); - lcResu.Add("<", "<"); - lcResu.Add(">", ">"); - lcResu.Add("&", "&"); - lcResu.Add("\'", "'"); - lcResu.Add("\"", """); - return lcResu; - } - - /// - /// Start out put stream - /// - /// where to put informations - /// Specify encoding here in 0, in 1 you can add a XSLT ref, in 2 the number of files, in 3 the dtd path, in 4 true or false for the use of CDDATA - public void StartTextStream(StringBuilder aBuff, string[] someParam) - { - aBuff.Append("").AppendLine(); - - if (someParam.Length > 4) - { - // We want to use CDDATA - this.UseCDData = "true".Equals(someParam[4], StringComparison.OrdinalIgnoreCase); - } - else - { - this.UseCDData = false; - } - - if (someParam.Length > 3) - { - // We've got a DTD - this.DtdFileName = someParam[3]; - } - - // If we have a DTD - if (LOADED_DTD != null) - { - aBuff.Append(""); - aBuff.AppendLine(); - } - - if (someParam.Length > 1 && someParam[1] != null) - { - aBuff.Append(""); - } - if (someParam.Length > 2) - { - int lcNbFile = 0; - try - { - lcNbFile = Convert.ToInt16(someParam[2]); - // Finally will Open tag - } - catch (FormatException e) - { - // An error occured - aBuff.Append(""); - lcNbFile = -1; - } - finally - { - // Then we deal with more than one file - Open(aBuff, "metadataExtractor", "nbFile", lcNbFile.ToString(), true); - } - } - } - - /// - /// Finish out put stream - /// - /// where to put informations - /// Should contain nb file in [2] - public void EndTextStream(StringBuilder aBuff, string[] someParam) - { - if (someParam.Length >= 2) - { - int lcNbFile = 0; - try - { - lcNbFile = Convert.ToInt16(someParam[2]); - // Finally will close files tag - } - catch (FormatException e) - { - // An error occured - aBuff.Append(""); - } - finally - { - Close(aBuff, "metadataExtractor", true); - } - } - } - - - /// - /// Normalize a value into XML - /// - /// where to put new XML value - /// the value to normalize - /// if true will use CDATA, if false will replace FORBIDEN chars by their normal value - public virtual void Normalize(StringBuilder aBuff, string aValue, bool useCdata) - { - if (aValue != null) - { - aValue = aValue.Trim(); - if (useCdata) - { - aBuff.Append(""); - } - else - { - // check if value contains strange char and replace them if needed - foreach (KeyValuePair lcPair in FORBIDEN_CHAR) - { - aValue = aValue.Replace(lcPair.Key, lcPair.Value); - } - aBuff.Append(aValue); - } - } - } - - /// - /// Opens an XML tag. - /// - /// where to Open tag - /// what to put inside the tag - /// if true will go to new line after Open - private void Close(StringBuilder aBuff, string aTag, bool isNewLine) - { - aBuff.Append("'); - if (isNewLine) - { - aBuff.AppendLine(); - } - } - - /// - /// Opens an XML tag. - /// - /// where to open tag - /// what to put inside the tag - /// if true will go to new line after open - private void Open(StringBuilder aBuff, string aTagName, bool isNewLine) - { - aBuff.Append('<').Append(aTagName).Append('>'); - if (isNewLine) - { - aBuff.AppendLine(); - } - } - - /// - /// Opens an XML tag. - /// - /// where to open tag - /// what to put inside the tag - /// name of an attribute for this tag (can be null) - /// value of the first attribute for this tag - /// if true will go to new line after open - private void Open(StringBuilder aBuff, string aTagName, string attName1, object attValue1, bool isNewLine) - { - aBuff.Append('<').Append(aTagName); - if (attName1 != null) - { - aBuff.Append(' ').Append(attName1).Append("=\""); - aBuff.Append(attValue1).Append('\"'); - } - aBuff.Append('>'); - if (isNewLine) - { - aBuff.AppendLine(); - } - } - - /// - /// Opens an XML tag. - /// - /// where to open tag - /// what to put inside the tag - /// name of an attribute for this tag (can be null) - /// value of the first attribute for this tag - /// name of a second attribute for this tag (can be null) - /// value of the second attribute for this tag - /// if true will go to new line after open - private void Open(StringBuilder aBuff, string aTagName, string attName1, object attValue1, string attName2, object attValue2, bool isNewLine) - { - aBuff.Append('<').Append(aTagName); - if (attName1 != null) - { - aBuff.Append(' ').Append(attName1).Append("=\""); - aBuff.Append(attValue1).Append('\"'); - } - if (attName2 != null) - { - aBuff.Append(' ').Append(attName2).Append("=\""); - aBuff.Append(attValue2).Append('\"'); - } - aBuff.Append('>'); - if (isNewLine) - { - aBuff.AppendLine(); - } - } - - /// - /// Creates an XML tag using the Tag object info. - /// Examples : - ///
-        /// <tag type="0x0044">
-        ///   <tagLabel>White Balance</tagLabel>
-        ///   <tagDescription><![CDATA[Very bright]]></tagDescription>
-        /// </tag>
-        /// 
- /// <tag type="0x0044"> - /// <tagLabel>White Balance</tagLabel> - /// <tagDescription/> - /// </tag> - ///
- /// <tag type="0x0044"> - /// <tagLabel>White Balance</tagLabel> - /// <tagDescription/> - /// <tagError><![CDATA[Oups something is wrong]]></tagError> - /// </tag> - ///
- ///
- /// where to put tag - /// the tag - protected virtual void CreateTag(StringBuilder aBuff, Tag aTag) - { - if (aTag != null) - { - string lcDescription = null; - string lcError = null; - try - { - lcDescription = aTag.GetDescription(); - } - catch (MetadataException e) - { - lcError = e.Message; - } - string lcName = aTag.GetTagName(); - string lcHexName = aTag.GetTagTypeHex(); - object lcValue = aTag.GetTagValue(); - string lcValueStr = (lcValue != null) ? lcValue.ToString() : null; - - if (!this.DoUnknown - && (lcName.ToLower().StartsWith("unknown") || (lcDescription != null && lcDescription - .ToLower().StartsWith("unknown")))) - { - // No unKnown and is unKnown so do nothing - return; - } - this.Open(aBuff, "tag", "typeHex", lcHexName,"type",aTag.GetTagType(), true); - - this.Open(aBuff, "tagLabel", false); - this.Normalize(aBuff, lcName, UseCDData); - this.Close(aBuff, "tagLabel", true); - - if (lcDescription != null && lcDescription.Trim().Length > 0) - { - this.Open(aBuff, "tagDescription", false); - this.Normalize(aBuff, lcDescription, UseCDData); - this.Close(aBuff, "tagDescription", true); - } - else - { - aBuff.Append("").AppendLine(); - } - - if (lcValueStr == null || lcValueStr.Trim().Length == 0 - || "null".Equals(lcValueStr)) - { - aBuff.Append("").AppendLine(); - } - else - { - this.Open(aBuff, "tagValue", "class", lcValue.GetType(), false); - if (lcValue.GetType().IsArray) - { - if (this.UseCDData) - { - aBuff.Append(""); - } - } - else if (lcValue.GetType().Equals(typeof(DateTime))) - { - if (this.UseCDData) - { - aBuff.Append(""); - } - } - else - { - this.Normalize(aBuff, lcValueStr, UseCDData); - } - this.Close(aBuff, "tagValue", true); - } - - if (lcError != null) - { - lcError = lcError + " for typeHex=\"" + lcHexName + "\" type=\"" + aTag.GetTagType() + "\""; - this.Open(aBuff, "tagError", false); - this.Normalize(aBuff, lcError, UseCDData); - this.Close(aBuff, "tagError", true); - } - else - { - // Does nothing if no error, this will limit the size of the XML - // stream since 99% of tag will be fine - // aBuff.Append(""); - } - this.Close(aBuff, "tag", true); - } - } - - - - /// - /// Creates a directory tag. - /// - /// Examples : - ///
-        /// <directory name="Exif">
-        ///   <tag>
-        ///     ...
-        ///   </tag>
-        ///   <tag>
-        ///     ...
-        ///   </tag>
-        /// </directory>
-        /// 
- ///
- /// where to put info - /// the information to add - protected virtual void CreateDirectory(StringBuilder aBuff, AbstractDirectory aDirectory) - { - if (aDirectory != null) - { - this.Open(aBuff, "directory", "name", aDirectory.GetName(),"class", aDirectory.GetType(), true); - foreach(Tag lcTag in aDirectory){ - this.CreateTag(aBuff, lcTag); - } - this.Close(aBuff, "directory", true); - } - } - - - /// - /// Transform the metatdat object into an XML stream. - /// - /// The metadata object as XML stream - public virtual string AsText() - { - StringBuilder lcBuff = new StringBuilder(); - foreach(AbstractDirectory lcDirectory in this.Metadata) - { - CreateDirectory(lcBuff, lcDirectory); - } - return lcBuff.ToString(); - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/com/utils/xml/XmlOutPutStreamHandler.cs b/ExtLibs/MetaDataExtractorCSharp240d/com/utils/xml/XmlOutPutStreamHandler.cs deleted file mode 100644 index aa85af7cf5..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/com/utils/xml/XmlOutPutStreamHandler.cs +++ /dev/null @@ -1,430 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text; -using System.IO; -using com.drew.metadata; - -namespace com.utils.xml -{ - /// - /// This class will handle XML for a Directory class. - /// - /// For default XML stream you can have a look to MetadataExtractor.dtd file and sampleFile.xml. - /// - public class XmlOutPutStreamHandler : IOutPutTextStreamHandler - { - private static Dictionary FORBIDEN_CHAR = XmlOutPutStreamHandler.BuildForbidenChar(); - - /// - /// The cached DTD. - /// - private static string LOADED_DTD = null; - - /// - /// The DTD path and file name. - /// - private string dtdFileName; - public string DtdFileName - { - get - { - return this.dtdFileName; - } - set - { - this.dtdFileName = value; - LoadDtd(); - } - } - - - private Metadata metadata; - public Metadata Metadata - { - get - { - return this.metadata; - } - set - { - this.metadata = value; - } - } - - /// - /// Get/set the unknown option - /// - private bool doUnknown; - public bool DoUnknown - { - get - { - return this.doUnknown; - } - set - { - this.doUnknown = value; - } - } - - - /// - /// Constructor of the object. - /// - public XmlOutPutStreamHandler() - : this(null) - { - } - - /// - /// Constructor of the object. - /// - /// the metadata that shoud be transformed into XML - public XmlOutPutStreamHandler(Metadata aMetadata) - : base() - { - this.Metadata = aMetadata; - this.DtdFileName = "MetadataExtractor.dtd"; - } - - /// - /// Gives all forbiden letter in XML standard and their correspondance. - /// - /// All forbiden chars and their XML correspondance - private void LoadDtd() - { - FileStream lcStream = null; - StreamReader lcStreamReader = null; - try - { - - lcStream = File.Open(this.DtdFileName, FileMode.Open, FileAccess.Read); - lcStreamReader = new StreamReader(lcStream); - StringBuilder lcBuff = new StringBuilder(); - while (!lcStreamReader.EndOfStream) - { - lcBuff.Append(lcStreamReader.ReadLine()); - lcBuff.AppendLine(); - } - LOADED_DTD = lcBuff.ToString(); - } - catch (Exception) - { - // Oups Dtd not found - LOADED_DTD = null; - } - finally - { - if (lcStreamReader != null) - { - lcStreamReader.Close(); - lcStreamReader.Dispose(); - } - if (lcStream != null) - { - lcStream.Close(); - lcStream.Dispose(); - } - } - } - - - /// - /// Gives all forbiden letter in XML standard and their correspondance. - /// - /// All forbiden chars and their XML correspondance - protected static Dictionary BuildForbidenChar() - { - Dictionary lcResu = new Dictionary(5); - lcResu.Add("<", "<"); - lcResu.Add(">", ">"); - lcResu.Add("&", "&"); - lcResu.Add("\'", "'"); - lcResu.Add("\"", """); - return lcResu; - } - - /// - /// Start out put stream - /// - /// where to put informations - /// Specify encoding here in 0, in 1 you can add a XSLT ref, in 2 the number of files, in 3 the dtd path - public void StartTextStream(StringBuilder aBuff, string[] someParam) - { - aBuff.Append("").AppendLine(); - if (someParam.Length > 3) - { - // We've got a DTD - this.DtdFileName = someParam[3]; - } - - // If we have a DTD - if (LOADED_DTD != null) - { - aBuff.Append(""); - aBuff.AppendLine(); - } - - if (someParam.Length > 1 && someParam[1] != null) - { - aBuff.Append(""); - } - if (someParam.Length > 2) - { - int lcNbFile = 0; - try - { - lcNbFile = Convert.ToInt16(someParam[2]); - // Finally will open tag - } - catch (FormatException e) - { - // An error occured - aBuff.Append(""); - lcNbFile = -1; - } - finally - { - // Then we deal with more than one file - Open(aBuff, "metadataExtractor", "nbFile", lcNbFile.ToString(), true); - } - } - } - - /// - /// Finish out put stream - /// - /// where to put informations - /// Should contain nb file in [2] - public void EndTextStream(StringBuilder aBuff, string[] someParam) - { - if (someParam.Length >= 2) - { - int lcNbFile = 0; - try - { - lcNbFile = Convert.ToInt16(someParam[2]); - // Finally will close files tag - } - catch (FormatException e) - { - // An error occured - aBuff.Append(""); - } - finally - { - Close(aBuff, "metadataExtractor", true); - } - } - } - - - /// - /// Normalize a value into XML - /// - /// where to put new XML value - /// the value to normalize - /// if true will use CDATA, if false will replace FORBIDEN chars by their normal value - public virtual void Normalize(StringBuilder aBuff, string aValue, bool useCdata) - { - if (aValue != null) - { - aValue = aValue.Trim(); - if (useCdata) - { - aBuff.Append(""); - } - else - { - // check if value contains strange char and replace them if needed - IEnumerator lcEnumChar = FORBIDEN_CHAR.GetEnumerator(); - while(lcEnumChar.MoveNext()) - { - KeyValuePair lcPair = (KeyValuePair)lcEnumChar.Current; - aValue = aValue.Replace(lcPair.Key, lcPair.Value); - } - aBuff.Append(aValue); - } - } - } - - /// - /// Opens an XML tag. - /// - /// where to open tag - /// what to put inside the tag - /// if true will go to new line after open - private void Close(StringBuilder aBuff, string aTag, bool isNewLine) - { - aBuff.Append("'); - if (isNewLine) - { - aBuff.AppendLine(); - } - } - - /// - /// Closes an XML tag. - /// - /// where to close tag - /// what to put inside the tag - /// if true will go to new line after close - private void Open(StringBuilder aBuff, string aTag, bool isNewLine) - { - aBuff.Append('<').Append(aTag).Append('>'); - if (isNewLine) - { - aBuff.AppendLine(); - } - } - - /// - /// Opens an XML tag. - /// - /// where to open tag - /// what to put inside the tag - /// name of an attribute for this tag (can be null) - /// value of the first attribute for this tag - /// if true will go to new line after open - private void Open(StringBuilder aBuff, string aTagName, string attName1, object attValue1, bool isNewLine) - { - aBuff.Append('<').Append(aTagName); - if (attName1 != null) - { - aBuff.Append(' ').Append(attName1).Append("=\""); - aBuff.Append(attValue1).Append('\"'); - } - aBuff.Append('>'); - if (isNewLine) - { - aBuff.AppendLine(); - } - } - - /// - /// Creates an XML tag using the Tag object info. - /// Examples : - ///
-        /// <tag type="0x0044">
-        ///   <tagLabel>White Balance</tagLabel>
-        ///   <tagDescription><![CDATA[Very bright]]></tagDescription>
-        /// </tag>
-        /// 
- /// <tag type="0x0044"> - /// <tagLabel>White Balance</tagLabel> - /// <tagDescription/> - /// </tag> - ///
- /// <tag type="0x0044"> - /// <tagLabel>White Balance</tagLabel> - /// <tagDescription/> - /// <tagError><![CDATA[Oups something is wrong]]></tagError> - /// </tag> - ///
- ///
- /// where to put tag - /// the tag - protected virtual void CreateTag(StringBuilder aBuff, Tag aTag) - { - if (aTag != null) - { - string lcDescription = null; - string lcError = null; - try - { - lcDescription = aTag.GetDescription(); - } - catch (MetadataException e) - { - lcError = e.Message; - } - string lcName = aTag.GetTagName(); - string lcHexName = aTag.GetTagTypeHex(); - - if (!this.DoUnknown && (lcName.ToLower().StartsWith("unknown") || lcDescription.ToLower().StartsWith("unknown"))) - { - // No unKnown and is unKnown so do nothing - return; - } - Open(aBuff, "tag", "type", lcHexName, true); - - Open(aBuff, "tagLabel", false); - Normalize(aBuff, lcName, false); - Close(aBuff, "tagLabel", false); - - if (lcDescription != null && lcDescription.Length > 0) - { - Open(aBuff, "tagDescription", false); - Normalize(aBuff, lcDescription, false); - Close(aBuff, "tagDescription", false); - } - else - { - aBuff.Append("").AppendLine(); - } - - if (lcError != null) - { - Open(aBuff, "tagError", false); - Normalize(aBuff, lcError, false); - Close(aBuff, "tagError", false); - } - else - { - // Does nothing if no error, this will limit the size of the XML - // stream since 99% of tag will be fine - // aBuff.Append(""); - } - Close(aBuff, "tag", true); - } - } - - /// - /// Creates a directory tag. - /// - /// Examples : - ///
-        /// <directory name="Exif">
-        ///   <tag>
-        ///     ...
-        ///   </tag>
-        ///   <tag>
-        ///     ...
-        ///   </tag>
-        /// </directory>
-        /// 
- ///
- /// where to put info - /// the information to add - protected virtual void CreateDirectory(StringBuilder aBuff, AbstractDirectory aDirectory) - { - if (aDirectory != null) - { - Open(aBuff, "directory name=\"" + aDirectory.GetName() + "\"", true); - foreach(Tag lcTag in aDirectory) { - CreateTag(aBuff, lcTag); - } - Close(aBuff, "directory", true); - } - } - - - /// - /// Transform the metatdat object into an XML stream. - /// - /// The metadata object as XML stream - public virtual string AsText() - { - StringBuilder lcBuff = new StringBuilder(); - foreach(AbstractDirectory lcDirectory in this.Metadata) - { - CreateDirectory(lcBuff, lcDirectory); - } - return lcBuff.ToString(); - } - } -} diff --git a/ExtLibs/MetaDataExtractorCSharp240d/exif.xslt b/ExtLibs/MetaDataExtractorCSharp240d/exif.xslt deleted file mode 100644 index b078b8c3a5..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/exif.xslt +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - -

- -

- - - - - - - - -
- - -
-
\ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/CanonMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/CanonMarkernote.txt deleted file mode 100644 index a05eb21de3..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/CanonMarkernote.txt +++ /dev/null @@ -1,167 +0,0 @@ -# This file contains label of property for MetaDataExtractor -TEST=For testing. Do not remove -MARKER_NOTE_NAME=Canon Makernote -TAG_CANON_CAMERA_STATE_1=Camera State 1 -TAG_CANON_CAMERA_STATE_2=Camera State 2 -TAG_CANON_CUSTOM_FUNCTIONS=Custom functions -TAG_CANON_CUSTOM_FUNCTION_AF_ASSIST_LIGHT=Custom functions AF assist light -TAG_CANON_CUSTOM_FUNCTION_AF_STOP=Custom functions AF stop -TAG_CANON_CUSTOM_FUNCTION_BRACKETTING=Custom functions bracketting -TAG_CANON_CUSTOM_FUNCTION_FILL_FLASH_REDUCTION=Custom functions fill flash reduction -TAG_CANON_CUSTOM_FUNCTION_LONG_EXPOSURE_NOISE_REDUCTION=Custom functions long exposure noise reduction -TAG_CANON_CUSTOM_FUNCTION_MENU_BUTTON_RETURN=Custom functions menu button return -TAG_CANON_CUSTOM_FUNCTION_MIRROR_LOCKUP=Custom functions mirror lockup -TAG_CANON_CUSTOM_FUNCTION_SENSOR_CLEANING=Custom functions sensor cleaning -TAG_CANON_CUSTOM_FUNCTION_SET_BUTTON_FUNCTION=Custom functions set button function -TAG_CANON_CUSTOM_FUNCTION_SHUTTER_AUTO_EXPOSURE_LOCK_BUTTONS=Custom functions shutter auto exposure -TAG_CANON_CUSTOM_FUNCTION_SHUTTER_CURTAIN_SYNC=Custom functions shutter curtain sync -TAG_CANON_CUSTOM_FUNCTION_SHUTTER_SPEED_IN_AV_MODE=Custom functions speed in AV mode -TAG_CANON_CUSTOM_FUNCTION_TV_AV_AND_EXPOSURE_LEVEL=Custom functions TV AV and exposure level -TAG_CANON_FIRMWARE_VERSION=Firware version -TAG_CANON_IMAGE_NUMBER=Image number -TAG_CANON_IMAGE_TYPE=Image type -TAG_CANON_OWNER_NAME=Owner name -TAG_CANON_SERIAL_NUMBER=Serial number -TAG_CANON_STATE1_AF_POINT_SELECTED=AF point selected -TAG_CANON_STATE1_CONTINUOUS_DRIVE_MODE=Continuous drive mode -TAG_CANON_STATE1_CONTRAST=Contrast -TAG_CANON_STATE1_DIGITAL_ZOOM=Digital zoom -TAG_CANON_STATE1_EASY_SHOOTING_MODE=Easy shooting mode -TAG_CANON_STATE1_EXPOSURE_MODE=Exposure mode -TAG_CANON_STATE1_FLASH_ACTIVITY=Flash activity -TAG_CANON_STATE1_FLASH_DETAILS=Flash Details -TAG_CANON_STATE1_FLASH_MODE=Flash mode -TAG_CANON_STATE1_FOCAL_UNITS_PER_MM=Focal units per mm -TAG_CANON_STATE1_FOCUS_MODE_1=Focus mode 1 -TAG_CANON_STATE1_FOCUS_MODE_2=Focus mode 2 -TAG_CANON_STATE1_FOCUS_TYPE=Focus type -TAG_CANON_STATE1_IMAGE_SIZE=Image size -TAG_CANON_STATE1_ISO=ISO -TAG_CANON_STATE1_LONG_FOCAL_LENGTH=Long focal length -TAG_CANON_STATE1_MACRO_MODE=Macro mode -TAG_CANON_STATE1_METERING_MODE=Metering methode -TAG_CANON_STATE1_QUALITY=Quality -TAG_CANON_STATE1_SATURATION=Saturation -TAG_CANON_STATE1_SELF_TIMER_DELAY=Self timer delay -TAG_CANON_STATE1_SHARPNESS=Sharpness -TAG_CANON_STATE1_SHORT_FOCAL_LENGTH=Short focal length -TAG_CANON_STATE1_UNKNOWN_12=Unknown 12 -TAG_CANON_STATE1_UNKNOWN_13=Unknown 13 -TAG_CANON_STATE1_UNKNOWN_2=Unknown 2 -TAG_CANON_STATE1_UNKNOWN_3=Unknown 3 -TAG_CANON_STATE1_UNKNOWN_7=Unknown 7 -TAG_CANON_STATE2_AEB_BRACKET_VALUE=AEB bracket value -TAG_CANON_STATE2_AF_POINT_USED=AF point used -TAG_CANON_STATE2_AUTO_EXPOSURE_BRACKETING=Auto exposure bracketing -TAG_CANON_STATE2_FLASH_BIAS=Flash bias -TAG_CANON_STATE2_SEQUENCE_NUMBER=Sequence number -TAG_CANON_STATE2_SUBJECT_DISTANCE=Subject distance -TAG_CANON_STATE2_WHITE_BALANCE=White balance -# -# xb: 15.06.2008 -TAG_CANON_CanonCameraInfo=Canon Camera Info -TAG_CANON_FocalLength=Canon Focal Length -TAG_CANON_STATE1_LensType=Lens type -TAG_CANON_STATE1_RecordMode=Record Mode -TAG_CANON_STATE1_MaxAperture=Max aperture -TAG_CANON_STATE1_MinAperture=Min aperture -TAG_CANON_STATE1_AESetting=AESetting -TAG_CANON_STATE1_ImageStabilization=Image stabilization -TAG_CANON_STATE1_DisplayAperture=Display aperture -TAG_CANON_STATE1_ZoomSourceWidth=Zoom wource width -TAG_CANON_STATE1_ZoomTargetWidth=Zoom target width -TAG_CANON_STATE1_SpotMeteringMode=Spot metering mode -TAG_CANON_STATE1_PhotoEffect=Photo effect -TAG_CANON_STATE1_ManualFlashOutput=Manual flash output -TAG_CANON_STATE1_ColorTone=Color tone -TAG_CANON_FocalLength_FocalType=Focal type -TAG_CANON_FocalLength_FocalLength=Focal length -TAG_CANON_FocalLength_FocalPlaneXSize=Focal plane X-size -TAG_CANON_FocalLength_FocalPlaneYSize=Focal plane Y-size - -TAG_CANON_STATE2_AutoISO=Auto ISO -TAG_CANON_STATE2_BaseISO=Base ISO -TAG_CANON_STATE2_MeasuredEV=Measured EV -TAG_CANON_STATE2_TargetAperture=Target aperture -TAG_CANON_STATE2_TargetExposureTime=Target exposure time -TAG_CANON_STATE2_ExposureCompensation=Exposure compensation -TAG_CANON_STATE2_SlowShutter=Slow shutter -TAG_CANON_STATE2_OpticalZoomCode=Optical zoom code -TAG_CANON_STATE2_FlashGuideNumber=Flash guide number -TAG_CANON_STATE2_ControlMode=Control mode -TAG_CANON_STATE2_FocusDistanceLower=Focus distance lower -TAG_CANON_STATE2_FNumber=FNumber -TAG_CANON_STATE2_ExposureTime=Exposure time -TAG_CANON_STATE2_BulbDuration=Bulb duration -TAG_CANON_STATE2_CameraType=Camera type -TAG_CANON_STATE2_AutoRotate=Auto rotate -TAG_CANON_STATE2_NDFilter=ND filter -TAG_CANON_STATE2_SelfTimer2=Self timer 2 -TAG_CANON_STATE2_FlashOutput=Flash output - -TAG_CANON_CanonModelID=Canon Model ID -TAG_CANON_CanonAFInfo=Canon AF Info -TAG_CANON_SerialNumberFormat=Serial Number Format -TAG_CANON_SuperMacro=Super Macro -TAG_CANON_DateStampMode=Date Stamp Mode -TAG_CANON_MyColors=My Colors -TAG_CANON_FirmwareRevision=Firmware Revision -TAG_CANON_FaceDetect1=Face Detect 1 -TAG_CANON_FaceDetect2=Face Detect 2 -TAG_CANON_CanonAFInfo2=Canon AF Info 2 -TAG_CANON_RawDataOffset=Raw Data Offset -TAG_CANON_OriginalDecisionDataOffset=Original Decision Data Offset -TAG_CANON_CustomFunctions1D=Custom Functions 1D -TAG_CANON_PersonalFunctions=Personal Functions -TAG_CANON_PersonalFunctionValues=Personal Function Values -TAG_CANON_CanonFileInfo=Canon File Info -TAG_CANON_AFPointsInFocus1D=AF Points In Focus 1D -TAG_CANON_LensType=Lens Type -TAG_CANON_InternalSerialNumber=Internal Serial Number -TAG_CANON_DustRemovalData=Dust Removal Data -TAG_CANON_CustomFunctions2=Custom Functions 2 -TAG_CANON_ProcessingInfo=Proccessing Info -TAG_CANON_ToneCurveTable=Tone Curve Table -TAG_CANON_SharpnessTable=Sharpness Table -TAG_CANON_SharpnessFreqTable=Sharpness Freq Table -TAG_CANON_WhiteBalanceTable=White Balance Table -TAG_CANON_ColorBalance=Color Balance -TAG_CANON_ColorTemperature=Color Temperature -TAG_CANON_CanonFlags=Canon Flags -TAG_CANON_ModifiedInfo=Modified Info -TAG_CANON_ToneCurveMatching=Tone Curve Matching -TAG_CANON_WhiteBalanceMatching=White Balance Matching -TAG_CANON_ColorSpace=Color Space -TAG_CANON_PreviewImageInfo=Preview Image Info -TAG_CANON_VRDOffset=VRD Offset -TAG_CANON_SensorInfo=Sensor Info -TAG_CANON_ColorBalance1to4=Color Balance 1 to 4 -TAG_CANON_UnknownBlock1=Unknown Block 1 -TAG_CANON_ColorInfo=Color Info -TAG_CANON_UnknownBlock2=Unknown Block 2 -TAG_CANON_BlackLevel=Black Level - -TAG_CANON_ProcessingInfo_ToneCurve=Tone curve -TAG_CANON_ProcessingInfo_Sharpness=Sharpness -TAG_CANON_ProcessingInfo_SharpnessFrequency=Sharpness frequency -TAG_CANON_ProcessingInfo_SensorRedLevel=Sensor red level -TAG_CANON_ProcessingInfo_SensorBlueLevel=Sensor blue level -TAG_CANON_ProcessingInfo_WhiteBalanceRed=White balance red -TAG_CANON_ProcessingInfo_WhiteBalanceBlue=White balance blue -TAG_CANON_ProcessingInfo_WhiteBalance=White balance -TAG_CANON_ProcessingInfo_ColorTemperature=Color temperature -TAG_CANON_ProcessingInfo_PictureStyle=Picture style -TAG_CANON_ProcessingInfo_DigitalGain=Digital gain -TAG_CANON_ProcessingInfo_WBShiftAB=WB Shift AB -TAG_CANON_ProcessingInfo_WBShiftGM=WB Shift GM - -TAG_CANON_SensorInfo_SensorWidth=Sensor width -TAG_CANON_SensorInfo_SensorHeight=Sensor height -TAG_CANON_SensorInfo_SensorLeftBorder=Sensor left border -TAG_CANON_SensorInfo_SensorTopBorder=Sensor top border -TAG_CANON_SensorInfo_SensorRightBorder=Sensor right border -TAG_CANON_SensorInfo_SensorBottomBorder=Sensor bottom border -TAG_CANON_SensorInfo_BlackMaskLeftBorder=Black mask left border -TAG_CANON_SensorInfo_BlackMaskTopBorder=Black mask top border -TAG_CANON_SensorInfo_BlackMaskRightBorder=Black mask right border -TAG_CANON_SensorInfo_BlackMaskBottomBorder=Black mask bottom border diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/CasioMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/CasioMarkernote.txt deleted file mode 100644 index 1b78c403e9..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/CasioMarkernote.txt +++ /dev/null @@ -1,51 +0,0 @@ -# This file contains label of property for MetaDataExtractor -TEST=For testing. Do not remove -MARKER_NOTE_NAME=Casio Makernote -TAG_CASIO_CCD_SENSITIVITY=CCD Sensitivity -TAG_CASIO_CONTRAST=Contrast -TAG_CASIO_DIGITAL_ZOOM=Digital Zoom -TAG_CASIO_FLASH_INTENSITY=Flash Intensity -TAG_CASIO_FLASH_MODE=Flash Mode -TAG_CASIO_FOCUSING_MODE=Focussing Mode -TAG_CASIO_OBJECT_DISTANCE=Object Distance -TAG_CASIO_QUALITY=Quality -TAG_CASIO_RECORDING_MODE=Recording Mode -TAG_CASIO_SATURATION=Saturation -TAG_CASIO_SHARPNESS=Sharpness -TAG_CASIO_TYPE2_BESTSHOT_MODE=Bestshot mode -TAG_CASIO_TYPE2_CASIO_PREVIEW_THUMBNAIL=Preview thumbnail -TAG_CASIO_TYPE2_CCD_ISO_SENSITIVITY=CCD ISO sensitivity -TAG_CASIO_TYPE2_COLOR_MODE=Color mode -TAG_CASIO_TYPE2_CONTRAST=Contrast -TAG_CASIO_TYPE2_ENHANCEMENT=Enhancement -TAG_CASIO_TYPE2_FILTER=Filter -TAG_CASIO_TYPE2_FLASH_DISTANCE=Flash distance -TAG_CASIO_TYPE2_FOCAL_LENGTH=Focal length -TAG_CASIO_TYPE2_FOCUS_MODE_1=Focus mode 1 -TAG_CASIO_TYPE2_FOCUS_MODE_2=Focus mode 2 -TAG_CASIO_TYPE2_IMAGE_SIZE=Image size -TAG_CASIO_TYPE2_ISO_SENSITIVITY=ISO sensitivity -TAG_CASIO_TYPE2_OBJECT_DISTANCE=Object distance -TAG_CASIO_TYPE2_PRINT_IMAGE_MATCHING_INFO=Print image matching info -TAG_CASIO_TYPE2_QUALITY=Quality -TAG_CASIO_TYPE2_QUALITY_MODE=Quality mode -TAG_CASIO_TYPE2_RECORD_MODE=Record mode -TAG_CASIO_TYPE2_SATURATION=Saturation -TAG_CASIO_TYPE2_SELF_TIMER=Self timer -TAG_CASIO_TYPE2_SHARPNESS=Sharpness -TAG_CASIO_TYPE2_THUMBNAIL_DIMENSIONS=Thumbnail dimensions -TAG_CASIO_TYPE2_THUMBNAIL_OFFSET=Thumbnail offset -TAG_CASIO_TYPE2_THUMBNAIL_SIZE=Thumbnail size -TAG_CASIO_TYPE2_TIME_ZONE=Time zone -TAG_CASIO_TYPE2_WHITE_BALANCE_1=White balance 1 -TAG_CASIO_TYPE2_WHITE_BALANCE_2=White balance 2 -TAG_CASIO_TYPE2_WHITE_BALANCE_BIAS=White balance bias -TAG_CASIO_UNKNOWN_1=Makernote Unknown 1 -TAG_CASIO_UNKNOWN_2=Makernote Unknown 2 -TAG_CASIO_UNKNOWN_3=Makernote Unknown 3 -TAG_CASIO_UNKNOWN_4=Makernote Unknown 4 -TAG_CASIO_UNKNOWN_5=Makernote Unknown 5 -TAG_CASIO_UNKNOWN_6=Makernote Unknown 6 -TAG_CASIO_UNKNOWN_7=Makernote Unknown 7 -TAG_CASIO_UNKNOWN_8=Makernote Unknown 8 -TAG_CASIO_WHITE_BALANCE=White Balance diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/Commons.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/Commons.txt deleted file mode 100644 index f112e2f4bb..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/Commons.txt +++ /dev/null @@ -1,342 +0,0 @@ -TEST=For testing. Do not remove -0_M_P_DISABLED=0,-,+ / Disabled -0_M_P_ENABLED=0,-,+ / Enabled -1_200_FIXED=1/200 (fixed) -1_2_STOP=1/2 stop -1_3_STOP=1/3 stop -1_CURTAIN_SYNC=1st Curtain Sync -2_CURTAIN_SYNC=2nd Curtain Sync -ADOBE_DEFLATE=Adobe Deflate -AE_AF_LOCK=AF/AF lock -AE_GOOD=AE good -AE_LOCK_AF=AE lock/AF -AE_RELEASE_AE_AF=AE+release/AE+AF -AF_AE_LOCK=AF/AE lock -AF_STOP=AF stop -AI_FOCUS=AI Focus -AI_SERVO=AI Servo -APERTURE=F {0} -APERTURE_PRIORITY=Aperture priority -APERTURE_PRIORITY_AE=Aperture priority AE -AUTO=Auto -AUTOMATIC=Automatic -AUTO_AND_RED_EYE_REDUCTION=Auto and red-eye reduction -AUTO_BRACKET=Auto bracket -AUTO_EXPOSURE=Auto exposure -AUTO_FOCUS=Auto focus -AUTO_FOCUS_GOOD=Auto focus good -AUTO_SELECTED=Auto selected -AUTO_WHITE_BALANCE=Auto white balance -MONOCHROME=Monochrome -AVERAGE=Average -AV_PRIORITY=Av-priority -A_DEP=A-DEP -BEST=Best -BETTER=Better -BITS={0} bits -BITS_COMPONENT_PIXEL={0} bits/component/pixel -BITS_PIXEL={0} bits/pixel -BIT_PIXEL={0} bit/pixel -BLACK_AND_WHITE=Black & White -BLACK_IS_ZERO=Black Is Zero -BLUR_WARNING=Blur warning -BOTTOM=Bottom -BOTTOM_LEFT_SIDE=Bottom, left side (Mirror vertical) -BOTTOM_RIGHT_SIDE=Bottom, right side (Rotate 180) -BOTTOM_TO_TOP_PAN_DIR=Bottom to top panorama direction -BRIGHT_M=Bright - -BRIGHT_P=Bright + -BYTES={0} bytes -BYTES_OF_IMAGE_DATA={0} bytes of image data -CCD_P_1=+1.0 -CCD_P_2=+2.0 -CCD_P_3=+3.0 -CCIRLEW=CCIRLEW -CCITT_1D=CCITT 1D -CENTER=Center -CENTER_OF_PIXEL_ARRAY=Center of pixel array -CENTER_WEIGHTED_AVERAGE=Center weighted average -CENTER_WEIGHTED=Center weighted -CHANGE_ISO_SPEED=Change ISO Speed -CHANGE_QUALITY=Change Quality -CHUNKY=Chunky (contiguous for each subsampling pixel) -CIELAB=CIELab -CLOSE_UP_MACRO=Close-up (Macro) -CLOSE_VIEW=Close view -CLOUDY=Cloudy -CM=cm -CMYK=CMYK -COLOR=Color -COLOR_FILTER_ARRAY=Color Filter Array -COLOR_SEQUENTIAL=Color sequential area sensor -COLOR_SEQUENTIAL_LINEAR=Color sequential linear sensor -COMPONENT_DATA={0} component: Quantization table {1}, Sampling factors {2} horiz/{3} vert -CONTINUOUS=Continuous -CONTRAST_M=Contrast - -CONTRAST_P=Contrast + -CUSTOM=Custom -CUSTOM_PROCESS=Custom process -CUSTOM_WHITE_BALANCE=Custom white balance -D55=D55 -D65=D65 -D75=D75 -DATUM_POINT=Datum point -DAYLIGHT=Daylight -DAYLIGHTCOLOR_FLUORESCENCE=DaylightColor-fluorescence -DAYWHITECOLOR_FLUORESCENCE=DaywhiteColor-fluorescence -DCS=DCS -DEFLATE=Deflate -DEGREES={0} degrees -DIGITAL_STILL_CAMERA=Digital Still Camera (DSC) -DIGITAL_ZOOM={0}x digital zoom -DIGITAL_ZOOM_NOT_USED=Digital zoom not used -DIMENSIONAL_MEASUREMENT={0}-dimensional measurement -DIRECTLY_PHOTOGRAPHED_IMAGE=Directly photographed image -DISABLED=Disabled -DISTANCE_MM={0} mm -DISTANT_VIEW=Distant view -DOTS_PER={0} dots per {1} -EASY_SHOOTING=Easy shooting -ECONOMY=Economy -ENABLED=Enabled -EVALUATIVE=Evaluative -EXTERNAL_E_TTL=External E-TTL -EXTERNAL_FLASH=Extenal flash -FAST_PICTURE_TAKING_MODE=Fast picture taking mode -FAST_SHUTTER=Fast shutter -FINE=Fine -FISHEYE_CONVERTER=Fisheye converter -FIXATION=Fixation -FLASH=Flash -FLASH_BIAS_NEW={0} {1} EV -FLASH_DID_NOT_FIRE=Flash did not fire -FLASH_FIRED=Flash fired -FLASH_OFF=Flash Off -FLASH_ON=Flash On -FLASH_SIMPLE={0} EV -FLASH_STRENGTH={0} eV (Apex) -FLUORESCENT=Fluorescence -FOCAL_LENGTH={0} {1} -FOCAL_PLANE={0} {1} -FP_SYNC_ENABLED=FP sync enabled -FP_SYNC_USED=FP sync used -FULL_AUTO=Full auto -FULL_RESOLUTION_IMAGE=Full-resolution image -GOOD=Good -GPS_TIME_STAMP={0}:{1}:{2} UTC -HARD=Hard -HIGH=High -HIGH_GAIN_DOWN=High gain down -HIGH_GAIN_UP=High gain up -HIGH_HARD=High (HARD) -HIGH_SATURATION=High saturation -HOURS_MINUTES_SECONDS={0}"{1}'{2} -HQ=HQ -ICCLAB=ICCLab -INCANDENSCENSE=Incandenscense -INCANDESCENSE=Incandescense -INCHES=Inches -INFINITE=Infinite -INFINITY=Infinity -INTERNAL_FLASH=Internal flash -ISO=ISO {0} -ISO_NOT_SPECIFIED=Not specified (see ISOSpeedRatings tag) -IT8BL=IT8BL -IT8CTPAD=IT8CTPAD -IT8LW=IT8LW -IT8MP=IT8MP -ITULAB=ITULab -JBIG=JBIG -JBIG_B_W=JBIG B&W -JBIG_COLOR=JBIG Color -JPEG=JPEG -JPEG_2000=JPEG 2000 -JPEG_OLD_STYLE=JPEG (old-style) -KILOMETERS=kilometers -KNOTS=knots -KPH=kph -LANDSCAPE=Landscape -LANDSCAPE_MODE=Landscape mode -LANDSCAPE_SCENE=Landscape scene -LARGE=Large -LEFT=Left -LEFT_SIDE_BOTTOM=Left side, bottom (Rotate 270 CW) -LEFT_SIDE_TOP=Left side, top (Mirror horizontal and rotate 270 CW) -LEFT_TO_RIGHT_PAN_DIR=Left to right panorama direction -LENS={0}-{1}mm f/{2}-{3} -LINEAR_RAW=Linear Raw -LOCKED_PAN_MODE=Locked (Pan Mode) -LOCK_AE_AND_START_TIMER=Lock AE and start timer -LOW=Low -LOW_GAIN_DOWN=Low gain down -LOW_GAIN_UP=Low gain up -LOW_ORG=Low (ORG) -LOW_SATURATION=Low saturation -LZW=LZW -MACRO=Macro -MACRO_CLOSEUP=Macro / Closeup -MAGNETIC_DIRECTION=Magnetic direction -MANUAL=Manual -MANUAL_CONTROL=Manual control -MANUAL_EXPOSURE=Manual exposure -MANUAL_FOCUS=Manual focus -MANUAL_WHITE_BALANCE=Manual white balance -MEASUREMENT_INTEROPERABILITY=Measurement Interoperability -MEASUREMENT_IN_PROGESS=Measurement in progess -MEDIUM=Medium -METRES={0} metres -MF=MF -MILES=miles -MODE_I_SRGB=Mode I (sRGB) -MPH=mph -MULTIPLE=Multiple -MULTI_AREA_FOCUS=Multi-Area Focus -MULTI_SEGMENT=Multi-segment -MULTI_SPOT=Multi-spot -M_0_P_DISABLED=-,0,+ / Disabled -M_0_P_ENABLED=-,0,+ / Enabled -NEXT=Next -NIGHT=Night -NIGHT_SCENE=Night scene -NIKON_NEF_COMPRESSED=Nikon NEF Compressed -NONE=None -NONE_MF=None (MF) -NORMAL=Normal -NORMAL_NO_MACRO=Normal (no macro) -NORMAL_PICTURE_TAKING_MODE=Normal picture taking mode -NORMAL_PROCESS=Normal process -NORMAL_STD=Normal (STD) -NOT_ASSIGNED=Not Assigned -NOT_DEFINED=(Not defined) -NO_BLUR_WARNING=No blur warning -NO_DIGITAL_ZOOM=No digital zoom -NO_DITHERING_OR_HALFTONING=No dithering or halftoning -NO_FLASH_FIRED=No flash fired -NO_UNIT=(No unit) -OFF=Off -ON=On -ONE_CHIP_COLOR=One-chip color area sensor -ONE_SHOT=One-shot -ON_AND_RED_EYE_REDUCTION=On and red-eye reduction -ON_AUTO=On (auto) -OPERATE_AF=Operate AF -ORDERED_DITHER_OR_HALFTONE=Ordered dither or halftone -OTHER=(Other) -OUT_OF_FOCUS=Out of focus -OVER_EXPOSED=Over exposed (>1/1000s @ F11) -PACKBITS=PackBits -PANORAMA=Panorama -PANORAMA_PICTURE_TAKING_MODE=Panorama picture taking mode -PAN_FOCUS=Pan focus -PARTIAL=Partial -PIXARFILM=PixarFilm -PIXARLOG=PixarLog -PIXAR_LOGL=Pixar LogL -PIXAR_LOGLUV=Pixar LogLuv -PIXELS={0} pixels -PIXELS_BI={0} x {1} pixels -PORTRAIT=Portrait -PORTRAIT_MODE=Portrait mode -PORTRAIT_SCENE=Portrait scene -POS=[{0} {1} {2}] [{3} {4} {5}] -PRESET=PreSet -PREVIOUS=Previous -PREVIOUS_VOLATILE=Previous (volatile) -PROGRAM=Program -PROGRAM_ACTION=Program action (high-speed program) -PROGRAM_AE=Program AE -PROGRAM_CREATIVE=Program creative (slow program) -PROGRAM_NORMAL=Program normal -RANDOMIZED_DITHER=Randomized dither -RECOMMENDED_EXIF_INTEROPERABILITY=Recommended Exif Interoperability Rules (ExifR98) -REDUCED_RESOLUTION_IMAGE=Reduced-resolution image -RED_EYE_REDUCTION=Red-eye reduction -RETURN_DETECTED=return detected -RETURN_NOT_DETECTED=return not detected -REVERSED=Reversed -RGB=RGB -RGB_PALETTE=RGB Palette -RIGHT=Right -RIGHT_SIDE_BOTTOM=Right side, bottom (Mirror horizontal and rotate 90 CW) -RIGHT_SIDE_TOP=Right side, top (Rotate 90 CW) -RIGHT_TO_LEFT_PAN_DIR=Right to left panorama direction -ROWS_STRIP={0} rows/strip -SAMPLES_PIXEL={0} samples/pixel -SEA_LEVEL=Sea level -SEC={0} sec -SELECT_PARAMETERS=Select Parameters -SELF_TIMER_DELAY={0} sec -SELF_TIMER_DELAY_NOT_USED=Self timer not used -SEPARATE=Separate (Y-plane/Cb-plane/Cr-plane format) -SEPIA=Sepia -SGILOG24=SGILog24 -SGILOG=SGILog -SHADE=Shade -SHQ=SHQ -SHUTTER_PRIORITY=Shutter priority -SHUTTER_PRIORITY_AE=Shutter priority AE -SHUTTER_SPEED=1/{0} sec -SHUTTER_SPEED_SEC={0} sec -SINGLE=Single -SINGLE_PAGE_OF_MULTI_PAGE_IMAGE=Single page of multi-page image -SINGLE_PAGE_OF_MULTI_PAGE_REDUCED_RESOLUTION_IMAGE=Single page of multi-page reduced-resolution image -SINGLE_SHOT=Single shot -SINGLE_SHOT_WITH_SELF_TIMER=Single shot with self-timer -SINGLE_SHUTTER=Single shutter -SLOW_SHUTTER=Slow shutter -SLOW_SYNCHRO=Slow-synchro -SMALL=Small -SOFT=Soft -SPEEDLIGHT=SpeedLight -SPORTS=Sports -SPORTS_SCENE=Sports scene -SPOT=Spot -SQ=SQ -SRGB=sRGB -STANDARD=Standard -STANDARD_LIGHT=Standard light -STANDARD_LIGHT_B=Standard light (B) -STANDARD_LIGHT_C=Standard light (C) -STRONG=Strong -SUNNY=Sunny -SUPERFINE=Super fine -SXGA_BASIC=SXGA Basic -SXGA_FINE=SXGA Fine -SXGA_NORMAL=SXGA Normal -T4_GROUP_3_FAC=T4/Group 3 Fax -T6_GROUP_4_FAC=T6/Group 4 Fax -THREE_CHIP_COLOR=Three-chip color area sensor -THUMBNAIL_BYTES=[{0} bytes of thumbnail data] -THUNDERSCA=Thunderscan -TOP=Top -TOP_LEFT_SIDE=Top, left side (Horizontal / normal) -TOP_RIGHT_SIDE=Top, right side (Mirror horizontal) -TOP_TO_BOTTOM_PAN_DIR=Top to bottom panorama direction -TRANSPARENCY_MASK=Transparency Mask -TRANSPARENCY_MASK_OF_MULTI_PAGE_IMAGE=Transparency mask of multi-page image -TRANSPARENCY_MASK_OF_REDUCED_RESOLUTION_IMAGE=Transparency mask of reduced-resolution image -TRANSPARENCY_MASK_OF_REDUCED_RESOLUTION_MULTI_PAGE_IMAGE=Transparency mask of reduced-resolution multi-page image -TRILINEAR_SENSOR=Trilinear sensor -TRUE_DIRECTION=True direction -TUNGSTEN=Tungsten -TV_PRIORITY=Tv-priority -TWO_CHIP_COLOR=Two-chip color area sensor -UNCOMPRESSED=Uncompressed -UNDEFINED=Undefined -UNKNOWN=Unknown ("{0}") -UNKNOWN_COLOR_SPACE=Unknown color space -UNKNOWN_COMPRESSION=Unknown compression -UNKNOWN_CONFIGURATION=Unknown configuration -UNKNOWN_PICTURE_TAKING_MODE=Unknown picture taking mode -UNKNOWN_PROGRAM=Unknown program ({0}) -UNKNOWN_SEQUENCE_NUMBER=Unknown sequence number -VGA_BASIC=VGA Basic -VGA_FINE=VGA Fine -VGA_NORMAL=VGA Normal -WEAK=Weak -WHITE_FLUORESCENCE=White-fluorescence -WHITE_IS_ZERO=White Is Zero -X_RD_IN_A_SEQUENCE={0}rd in a sequence -YCBCR=YCbCr -YCBCR_420=YCbCr4:2:0 -YCBCR_422=YCbCr4:2:2 diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/ExifInteropMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/ExifInteropMarkernote.txt deleted file mode 100644 index c80a35085b..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/ExifInteropMarkernote.txt +++ /dev/null @@ -1,8 +0,0 @@ -TEST=For testing. Do not remove -# This file contains label of property for MetaDataExtractor -MARKER_NOTE_NAME=Exif Interoperability Makernote -TAG_INTEROP_INDEX=Interoperability Index -TAG_INTEROP_VERSION=Interoperability Version -TAG_RELATED_IMAGE_FILE_FORMAT=Related Image File Format -TAG_RELATED_IMAGE_LENGTH=Related Image Length -TAG_RELATED_IMAGE_WIDTH=Related Image Width diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/ExifMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/ExifMarkernote.txt deleted file mode 100644 index 70454d3e63..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/ExifMarkernote.txt +++ /dev/null @@ -1,135 +0,0 @@ -# This file contains label of property for MetaDataExtractor -TEST=For testing. Do not remove -MARKER_NOTE_NAME=Exif Makernote -TAG_APERTURE=Aperture Value -TAG_ARTIST=Artist -TAG_BATTERY_LEVEL=Battery Level -TAG_BITS_PER_SAMPLE=Bits Per Sample -TAG_BRIGHTNESS_VALUE=Brightness Value -TAG_CFA_PATTERN=CFA Pattern -TAG_CFA_PATTERN_2=CFA Pattern -TAG_CFA_REPEAT_PATTERN_DIM=CFA Repeat Pattern Dim -TAG_COLOR_SPACE=Color Space -TAG_COMPONENTS_CONFIGURATION=Components Configuration -TAG_COMPRESSION=Compression -TAG_COMPRESSION_LEVEL=Compressed Bits Per Pixel -TAG_CONTRAST=Contrast -TAG_COPYRIGHT=Copyright -TAG_CUSTOM_RENDERED=Custom Rendered -TAG_DATETIME=Date/Time -TAG_DATETIME_DIGITIZED=Date/Time Digitized -TAG_DATETIME_ORIGINAL=Date/Time Original -TAG_DEVICE_SETTING_DESCRIPTION=Device Setting Description -TAG_DIGITAL_ZOOM_RATIO=Digital Zoom Ratio -TAG_DOCUMENT_NAME=Document Name -TAG_EXIF_IMAGE_HEIGHT=Exif Image Height -TAG_EXIF_IMAGE_WIDTH=Exif Image Width -TAG_EXIF_OFFSET=Exif Offset -TAG_EXIF_VERSION=Exif Version -TAG_EXPOSURE_BIAS=Exposure Bias Value -TAG_EXPOSURE_INDEX=Exposure Index -TAG_EXPOSURE_INDEX_2=Exposure Index -TAG_EXPOSURE_MODE=Exposure Mode -TAG_EXPOSURE_PROGRAM=Exposure Program -TAG_EXPOSURE_TIME=Exposure Time -TAG_FILE_SOURCE=File Source -TAG_FILL_ORDER=Fill Order -TAG_FLASH=Flash -TAG_FLASHPIX_VERSION=FlashPix Version -TAG_FLASH_ENERGY=Flash Energy -TAG_FLASH_ENERGY_2=Flash Energy -TAG_FNUMBER=F-Number -TAG_FOCAL_LENGTH=Focal Length -TAG_FOCAL_LENGTH_IN_35MM_FILM=Focal Length in 35mm Film -TAG_FOCAL_PLANE_UNIT=Focal Plane Resolution Unit -TAG_FOCAL_PLANE_X_RES=Focal Plane X Resolution -TAG_FOCAL_PLANE_Y_RES=Focal Plane Y Resolution -TAG_GAIN_CONTROL=Gain Control -TAG_GPS_INFO=GPS Info -TAG_IMAGE_DESCRIPTION=Image Description -TAG_IMAGE_HISTORY=Image History -TAG_IMAGE_NUMBER=Image Number -TAG_IMAGE_UNIQUE_ID=Image Unique ID -TAG_INTERLACE=Interlace -TAG_INTEROPERABILITY_OFFSET=Interoperability Offset -TAG_INTER_COLOR_PROFILE=Inter Color Profile -TAG_IPTC_NAA=IPTC/NAA -TAG_ISO_EQUIVALENT=ISO Speed Ratings -TAG_JPEG_PROC=JPEG Proc -TAG_JPEG_TABLES=JPEG Tables -TAG_MAKE=Make -TAG_MARKER_NOTE=Maker Note -TAG_MAX_APERTURE=Max Aperture Value -TAG_MAX_SAMPLE_VALUE=Maximum sample value -TAG_METERING_MODE=Metering Mode -TAG_MIN_SAMPLE_VALUE=Minimum sample value -TAG_MODEL=Model -TAG_NEW_SUBFILE_TYPE=New Subfile Type -TAG_NOISE=Noise -TAG_OECF=OECF -TAG_ORIENTATION=Orientation -TAG_PAGE_NAME=Page name -TAG_PHOTOMETRIC_INTERPRETATION=Photometric Interpretation -TAG_PLANAR_CONFIGURATION=Planar Configuration -TAG_PREDICTOR=Predictor -TAG_PRIMARY_CHROMATICITIES=Primary Chromaticities -TAG_REFERENCE_BLACK_WHITE=Reference Black/White -TAG_RELATED_IMAGE_FILE_FORMAT=Related Image File Format -TAG_RELATED_IMAGE_LENGTH=Related Image Length -TAG_RELATED_IMAGE_WIDTH=Related Image Width -TAG_RELATED_SOUND_FILE=Related Sound File -TAG_RESOLUTION_UNIT=Resolution Unit -TAG_ROWS_PER_STRIP=Rows Per Strip -TAG_SAMPLES_PER_PIXEL=Samples Per Pixel -TAG_SATURATION=Saturation -TAG_SCENE_CAPTURE_TYPE=Scene Capture Type -TAG_SCENE_TYPE=Scene Type -TAG_SECURITY_CLASSIFICATION=Security Classification -TAG_SELF_TIMER_MODE=Self Timer Mode -TAG_SENSING_METHOD=Sensing Method -TAG_SHARPNESS=Sharpness -TAG_SHUTTER_SPEED=Shutter Speed Value -TAG_SOFTWARE=Software -TAG_SPATIAL_FREQ_RESPONSE=Spatial Frequency Response -TAG_SPATIAL_FREQ_RESPONSE_2=Spatial Frequency Response -TAG_SPECTRAL_SENSITIVITY=Spectral Sensitivity -TAG_STRIP_BYTE_COUNTS=Strip Byte Counts -TAG_STRIP_OFFSETS=Strip Offsets -TAG_SUBFILE_TYPE=Subfile Type -TAG_SUBJECT_DISTANCE=Subject Distance -TAG_SUBJECT_DISTANCE_RANGE=Subject Distance -TAG_SUBJECT_LOCATION=Subject Location -TAG_SUBJECT_LOCATION_2=Subject Location -TAG_SUBSECOND_TIME=Sub-Sec Time -TAG_SUBSECOND_TIME_DIGITIZED=Sub-Sec Time Digitized -TAG_SUBSECOND_TIME_ORIGINAL=Sub-Sec Time Original -TAG_SUB_IFDS=Sub IFDs -TAG_THRESHOLDING=Thresholding -TAG_THUMBNAIL_DATA=Thumbnail Data -TAG_THUMBNAIL_IMAGE_HEIGHT=Thumbnail Image Height -TAG_THUMBNAIL_IMAGE_WIDTH=Thumbnail Image Width -TAG_THUMBNAIL_LENGTH=Thumbnail Length -TAG_THUMBNAIL_OFFSET=Thumbnail Offset -TAG_TIFF_EP_STANDARD_ID=TIFF/EP Standard ID -TAG_TILE_BYTE_COUNTS=Tile Byte Counts -TAG_TILE_LENGTH=Tile Length -TAG_TILE_OFFSETS=Tile Offsets -TAG_TILE_WIDTH=Tile Width -TAG_TIME_ZONE_OFFSET=Time Zone Offset -TAG_TRANSFER_FUNCTION=Transfer Function -TAG_TRANSFER_RANGE=Transfer Range -TAG_USER_COMMENT=User Comment -TAG_WHITE_BALANCE=Light Source -TAG_WHITE_BALANCE_MODE=White balance mode -TAG_WHITE_POINT=White Point -TAG_XP_AUTHOR=Author (Win) -TAG_XP_COMMENTS=Comments (Win) -TAG_XP_KEYWORDS=Keyword (Win) -TAG_XP_SUBJECT=Subject (Win) -TAG_XP_TITLE=Title (Win) -TAG_X_RESOLUTION=X Resolution -TAG_YCBCR_COEFFICIENTS=YCbCr Coefficients -TAG_YCBCR_POSITIONING=YCbCr Positioning -TAG_YCBCR_SUBSAMPLING=YCbCr Sub-Sampling -TAG_Y_RESOLUTION=Y Resolution -TAG_LIGHT_SOURCE=Light source \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/FujiFilmMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/FujiFilmMarkernote.txt deleted file mode 100644 index 5bbb8e3a9f..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/FujiFilmMarkernote.txt +++ /dev/null @@ -1,21 +0,0 @@ -# This file contains label of property for MetaDataExtractor -TEST=For testing. Do not remove -MARKER_NOTE_NAME=FujiFilm Makernote -TAG_FUJIFILM_AE_WARNING=AE Warning -TAG_FUJIFILM_BLUR_WARNING=Blur Warning -TAG_FUJIFILM_COLOR=Color -TAG_FUJIFILM_CONTINUOUS_TAKING_OR_AUTO_BRACKETTING=Continuous Taking Or Auto Bracketting -TAG_FUJIFILM_FLASH_MODE=Flash Mode -TAG_FUJIFILM_FLASH_STRENGTH=Flash Strength -TAG_FUJIFILM_FOCUS_MODE=Focus Mode -TAG_FUJIFILM_FOCUS_WARNING=Focus Warning -TAG_FUJIFILM_MACRO=Macro -TAG_FUJIFILM_MAKERNOTE_VERSION=Makernote Version -TAG_FUJIFILM_PICTURE_MODE=Picture Mode -TAG_FUJIFILM_QUALITY=Quality -TAG_FUJIFILM_SHARPNESS=Sharpness -TAG_FUJIFILM_SLOW_SYNCHRO=Slow Synchro -TAG_FUJIFILM_TONE=Tone -TAG_FUJIFILM_UNKNOWN_1=Makernote Unknown 1 -TAG_FUJIFILM_UNKNOWN_2=Makernote Unknown 2 -TAG_FUJIFILM_WHITE_BALANCE=White Balance diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/GpsMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/GpsMarkernote.txt deleted file mode 100644 index 8ad755d036..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/GpsMarkernote.txt +++ /dev/null @@ -1,30 +0,0 @@ -# This file contains label of property for MetaDataExtractor -TEST=For testing. Do not remove -MARKER_NOTE_NAME=GPS Makernote -TAG_GPS_ALTITUDE=GPS Altitude -TAG_GPS_ALTITUDE_REF=GPS Altitude Ref -TAG_GPS_DEST_BEARING=GPS Dest Bearing -TAG_GPS_DEST_BEARING_REF=GPS Dest Bearing Ref -TAG_GPS_DEST_DISTANCE=GPS Dest Distance -TAG_GPS_DEST_DISTANCE_REF=GPS Dest Distance Ref -TAG_GPS_DEST_LATITUDE=GPS Dest Latitude -TAG_GPS_DEST_LATITUDE_REF=GPS Dest Latitude Ref -TAG_GPS_DEST_LONGITUDE=GPS Dest Longitude -TAG_GPS_DEST_LONGITUDE_REF=GPS Dest Longitude Ref -TAG_GPS_DOP=GPS DOP -TAG_GPS_IMG_DIRECTION=GPS Img Direction -TAG_GPS_IMG_DIRECTION_REF=GPS Img Direction Ref -TAG_GPS_LATITUDE=GPS Latitude -TAG_GPS_LATITUDE_REF=GPS Latitude Ref -TAG_GPS_LONGITUDE=GPS Longitude -TAG_GPS_LONGITUDE_REF=GPS Longitude Ref -TAG_GPS_MAP_DATUM=GPS Map Datum -TAG_GPS_MEASURE_MODE=GPS Measure Mode -TAG_GPS_SATELLITES=GPS Satellites -TAG_GPS_SPEED=GPS Speed -TAG_GPS_SPEED_REF=GPS Speed Ref -TAG_GPS_STATUS=GPS Status -TAG_GPS_TIME_STAMP=GPS Time-Stamp -TAG_GPS_TRACK=GPS Track -TAG_GPS_TRACK_REF=GPS Track Ref -TAG_GPS_VERSION_ID=GPS Version ID diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/IptcMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/IptcMarkernote.txt deleted file mode 100644 index 318584f0cd..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/IptcMarkernote.txt +++ /dev/null @@ -1,27 +0,0 @@ -# This file contains label of property for MetaDataExtractor -TEST=For testing. Do not remove -MARKER_NOTE_NAME=Iptc Makernote -TAG_BY_LINE=By-line -TAG_BY_LINE_TITLE=By-line Title -TAG_CAPTION=Caption/Abstract -TAG_CATEGORY=Category -TAG_CITY=City -TAG_COPYRIGHT_NOTICE=Copyright Notice -TAG_COUNTRY_OR_PRIMARY_LOCATION=Country/Primary Location -TAG_CREDIT=Credit -TAG_DATE_CREATED=Date Created -TAG_HEADLINE=Headline -TAG_KEYWORDS=Keywords -TAG_OBJECT_NAME=Object Name -TAG_ORIGINAL_TRANSMISSION_REFERENCE=Original Transmission Reference -TAG_ORIGINATING_PROGRAM=Originating Program -TAG_PROVINCE_OR_STATE=Province/State -TAG_RECORD_VERSION=Directory Version -TAG_RELEASE_DATE=Release Date -TAG_RELEASE_TIME=Release Time -TAG_SOURCE=Source -TAG_SPECIAL_INSTRUCTIONS=Special Instructions -TAG_SUPPLEMENTAL_CATEGORIES=Supplemental Category(s) -TAG_TIME_CREATED=Time Created -TAG_URGENCY=Urgency -TAG_WRITER=Writer/Editor diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/JpegMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/JpegMarkernote.txt deleted file mode 100644 index 826070ddcf..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/JpegMarkernote.txt +++ /dev/null @@ -1,12 +0,0 @@ -# This file contains label of property for MetaDataExtractor -TEST=For testing. Do not remove -MARKER_NOTE_NAME=Jpeg Makernote -TAG_JPEG_COMMENT=Jpeg Comment -TAG_JPEG_COMPONENT_DATA_1=Component 1 -TAG_JPEG_COMPONENT_DATA_2=Component 2 -TAG_JPEG_COMPONENT_DATA_3=Component 3 -TAG_JPEG_COMPONENT_DATA_4=Component 4 -TAG_JPEG_DATA_PRECISION=Data Precision -TAG_JPEG_IMAGE_HEIGHT=Image Height -TAG_JPEG_IMAGE_WIDTH=Image Width -TAG_JPEG_NUMBER_OF_COMPONENTS=Number of Components diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/KodakMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/KodakMarkernote.txt deleted file mode 100644 index 90775151db..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/KodakMarkernote.txt +++ /dev/null @@ -1,3 +0,0 @@ -# This file contains label of property for MetaDataExtractor -TEST=For testing. Do not remove -MARKER_NOTE_NAME=Kodak Makernote diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/KyoceraMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/KyoceraMarkernote.txt deleted file mode 100644 index a81a04bad0..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/KyoceraMarkernote.txt +++ /dev/null @@ -1,5 +0,0 @@ -# This file contains label of property for MetaDataExtractor -TEST=For testing. Do not remove -MARKER_NOTE_NAME=Kyocera Makernote -TAG_KYOCERA_PRINT_IMAGE_MATCHING_INFO=Print Image Matching (PIM) Info -TAG_KYOCERA_PROPRIETARY_THUMBNAIL=Proprietary Thumbnail Format Data diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/NikonTypeMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/NikonTypeMarkernote.txt deleted file mode 100644 index e6a6a2c427..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/NikonTypeMarkernote.txt +++ /dev/null @@ -1,69 +0,0 @@ -# This file contains label of property for MetaDataExtractor -TEST=For testing. Do not remove -MARKER_NOTE_NAME=Nikon Makernote -TAG_NIKON_TYPE1_CCD_SENSITIVITY=CCD Sensitivity -TAG_NIKON_TYPE1_COLOR_MODE=Color Mode -TAG_NIKON_TYPE1_CONVERTER=Fisheye Converter -TAG_NIKON_TYPE1_DIGITAL_ZOOM=Digital Zoom -TAG_NIKON_TYPE1_FOCUS=Focus -TAG_NIKON_TYPE1_IMAGE_ADJUSTMENT=Image Adjustment -TAG_NIKON_TYPE1_QUALITY=Quality -TAG_NIKON_TYPE1_UNKNOWN_1=Makernote Unknown 1 -TAG_NIKON_TYPE1_UNKNOWN_2=Makernote Unknown 2 -TAG_NIKON_TYPE1_UNKNOWN_3=Makernote Unknown 3 -TAG_NIKON_TYPE1_WHITE_BALANCE=White Balance -TAG_NIKON_TYPE2_ADAPTER=Adapter -TAG_NIKON_TYPE2_AF_FOCUS_POSITION=AF Focus Position -TAG_NIKON_TYPE2_AF_TYPE=AF Type -TAG_NIKON_TYPE2_AUTO_FLASH_COMPENSATION=Auto Flash Compensation -TAG_NIKON_TYPE2_AUTO_FLASH_MODE=Auto Flash Mode -TAG_NIKON_TYPE2_CAMERA_COLOR_MODE=Colour Mode -TAG_NIKON_TYPE2_CAMERA_HUE_ADJUSTMENT=Camera Hue Adjustment -TAG_NIKON_TYPE2_CAMERA_SHARPENING=Sharpening -TAG_NIKON_TYPE2_CAMERA_TONE_COMPENSATION=Tone Compensation -TAG_NIKON_TYPE2_CAMERA_WHITE_BALANCE=White Balance -TAG_NIKON_TYPE2_CAMERA_WHITE_BALANCE_FINE=White Balance Fine -TAG_NIKON_TYPE2_CAMERA_WHITE_BALANCE_RB_COEFF=White Balance RB Coefficients -TAG_NIKON_TYPE2_CAPTURE_EDITOR_DATA=Capture Editor Data -TAG_NIKON_TYPE2_COLOR_MODE=Color Mode -TAG_NIKON_TYPE2_DATA_DUMP=Data Dump -TAG_NIKON_TYPE2_DIGITAL_ZOOM=Digital Zoom -TAG_NIKON_TYPE2_EXPOSURE_SEQUENCE_NUMBER=Exposure Sequence Number -TAG_NIKON_TYPE2_FIRMWARE_VERSION=Firmware Version -TAG_NIKON_TYPE2_FLASH_SYNC_MODE=Flash Sync Mode -TAG_NIKON_TYPE2_IMAGE_ADJUSTMENT=Image Adjustment -TAG_NIKON_TYPE2_ISO_1=ISO -TAG_NIKON_TYPE2_ISO_2=ISO -TAG_NIKON_TYPE2_ISO_SELECTION=ISO Selection -TAG_NIKON_TYPE2_LENS=Lens -TAG_NIKON_TYPE2_LIGHT_SOURCE=Light source -TAG_NIKON_TYPE2_MANUAL_FOCUS_DISTANCE=Manual Focus Distance -TAG_NIKON_TYPE2_NOISE_REDUCTION=Noise Reduction -TAG_NIKON_TYPE2_QUALITY_AND_FILE_FORMAT=Quality & File Format -TAG_NIKON_TYPE2_UNKNOWN_11=Unknown 11 -TAG_NIKON_TYPE2_UNKNOWN_12=Unknown 12 -TAG_NIKON_TYPE2_UNKNOWN_13=Unknown 13 -TAG_NIKON_TYPE2_UNKNOWN_14=Unknown 14 -TAG_NIKON_TYPE2_UNKNOWN_15=Unknown 15 -TAG_NIKON_TYPE2_UNKNOWN_16=Unknown 16 -TAG_NIKON_TYPE2_UNKNOWN_1=Unknown 01 -TAG_NIKON_TYPE2_UNKNOWN_20=Unknown 20 -TAG_NIKON_TYPE2_UNKNOWN_21=Unknown 21 -TAG_NIKON_TYPE2_UNKNOWN_22=Unknown 22 -TAG_NIKON_TYPE2_UNKNOWN_23=Unknown 23 -TAG_NIKON_TYPE2_UNKNOWN_24=Unknown 24 -TAG_NIKON_TYPE2_UNKNOWN_25=Unknown 25 -TAG_NIKON_TYPE2_UNKNOWN_26=Unknown 26 -TAG_NIKON_TYPE2_UNKNOWN_27=Unknown 27 -TAG_NIKON_TYPE2_UNKNOWN_29=Unknown 29 -TAG_NIKON_TYPE2_UNKNOWN_2=Unknown 02 -TAG_NIKON_TYPE2_UNKNOWN_30=Unknown 30 -TAG_NIKON_TYPE2_UNKNOWN_32=Unknown 32 -TAG_NIKON_TYPE2_UNKNOWN_33=Unknown 33 -TAG_NIKON_TYPE2_UNKNOWN_34=Unknown 34 -TAG_NIKON_TYPE2_UNKNOWN_3=Unknown 03 -TAG_NIKON_TYPE2_UNKNOWN_4=Unknown 04 -TAG_NIKON_TYPE2_UNKNOWN_5=Unknown 05 -TAG_NIKON_TYPE2_UNKNOWN_7=Unknown 07 -TAG_NIKON_TYPE2_UNKNOWN_8=Unknown 08 -TAG_NIKON_TYPE2_UNKNOWN_9=Unknown 09 diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/OlympusMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/OlympusMarkernote.txt deleted file mode 100644 index 74ed29afe5..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/OlympusMarkernote.txt +++ /dev/null @@ -1,50 +0,0 @@ -# This file contains label of property for MetaDataExtractor -TEST=For testing. Do not remove -MARKER_NOTE_NAME=Olympus Makernote -TAG_OLYMPUS_BLACK_LEVEL=Black Level -TAG_OLYMPUS_BLUE_BIAS=Blue Bias -TAG_OLYMPUS_BRACKET=Bracket -TAG_OLYMPUS_CAMERA_ID=Camera Id -TAG_OLYMPUS_CAMERA_SETTINGS_1=Camera Settings (1) -TAG_OLYMPUS_CAMERA_SETTINGS_2=Camera Settings (2) -TAG_OLYMPUS_COLOR_CONTROL=Color Control -TAG_OLYMPUS_COLOR_MATRIX=Color Matrix -TAG_OLYMPUS_COLOR_MODE=Color Mode -TAG_OLYMPUS_COMPRESSED_IMAGE_SIZE=Compressed Image Size -TAG_OLYMPUS_COMPRESSION_RATIO=Compression Ratio -TAG_OLYMPUS_CONTRAST=Contrast -TAG_OLYMPUS_CORING_FILTER=Coring Filter -TAG_OLYMPUS_DATA_DUMP=Data Dump -TAG_OLYMPUS_DIGI_ZOOM_RATIO=Digital Zoom Ratio -TAG_OLYMPUS_FINAL_HEIGHT=Final Height -TAG_OLYMPUS_FINAL_WIDTH=Final Width -TAG_OLYMPUS_FIRMWARE_VERSION=Firmware Version -TAG_OLYMPUS_FLASH_BIAS=Flash Bias -TAG_OLYMPUS_FLASH_MODE=Flash Mode -TAG_OLYMPUS_FOCUS_DISTANCE=Focus Distance -TAG_OLYMPUS_FOCUS_MODE=Focus Mode -TAG_OLYMPUS_IMAGE_HEIGHT=Image Height -TAG_OLYMPUS_IMAGE_WIDTH=Image Width -TAG_OLYMPUS_IMAGE_QUALITY_1=Image Quality (1) -TAG_OLYMPUS_IMAGE_QUALITY_2=Image Quality (2) -TAG_OLYMPUS_JPEG_QUALITY=Jpeg Quality -TAG_OLYMPUS_MACRO_FOCUS=Macro Focus -TAG_OLYMPUS_MACRO_MODE=Macro -TAG_OLYMPUS_MAKERNOTE_VERSION=Makernote Version -TAG_OLYMPUS_MINOLTA_THUMBNAIL_LENGTH=Thumbnail Length -TAG_OLYMPUS_MINOLTA_THUMBNAIL_OFFSET_1=Thumbnail Offset (1) -TAG_OLYMPUS_MINOLTA_THUMBNAIL_OFFSET_2=Thumbnail Offset (2) -TAG_OLYMPUS_ORIGINAL_MANUFACTURER_MODEL=Original Manufacturer Model -TAG_OLYMPUS_PICT_INFO=Pict Info -TAG_OLYMPUS_PRINT_IMAGE_MATCHING_INFO=Print Image Matching (PIM) Info -TAG_OLYMPUS_RED_BIAS=Red Bias -TAG_OLYMPUS_SERIAL_NUMBER=Serial Number -TAG_OLYMPUS_SHARPNESS=Sharpness -TAG_OLYMPUS_SHARPNESS_FACTOR=Sharpness Factor -TAG_OLYMPUS_SPECIAL_MODE=Special Mode -TAG_OLYMPUS_UNKNOWN_1=Unknown 1 -TAG_OLYMPUS_UNKNOWN_2=Unknown 2 -TAG_OLYMPUS_UNKNOWN_3=Unknown 3 -TAG_OLYMPUS_VALID_BITS=Valid Bits -TAG_OLYMPUS_WHITE_BALANCE=White Balance -TAG_OLYMPUS_ZOOM=Zoom \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/PanasonicMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/PanasonicMarkernote.txt deleted file mode 100644 index effa56f3ec..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/PanasonicMarkernote.txt +++ /dev/null @@ -1,8 +0,0 @@ -# This file contains label of property for MetaDataExtractor -TEST=For testing. Do not remove -MARKER_NOTE_NAME=Panasonic Makernote -TAG_PANASONIC_MACRO_MODE=Macro Mode -TAG_PANASONIC_PRINT_IMAGE_MATCHING_INFO=Print Image Matching (PIM) Info -TAG_PANASONIC_QUALITY_MODE=Quality Mode -TAG_PANASONIC_RECORD_MODE=Record Mode -TAG_PANASONIC_VERSION=Version diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/PentaxMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/PentaxMarkernote.txt deleted file mode 100644 index 0c5ea88713..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/PentaxMarkernote.txt +++ /dev/null @@ -1,17 +0,0 @@ -# This file contains label of property for MetaDataExtractor -TEST=For testing. Do not remove -MARKER_NOTE_NAME=Pentax Makernote -TAG_PENTAX_CAPTURE_MODE=Capture Mode -TAG_PENTAX_COLOR=Color -TAG_PENTAX_CONTRAST=Contrast -TAG_PENTAX_DAYLIGHT_SAVINGS=Daylight Savings -TAG_PENTAX_DIGITAL_ZOOM=Digital Zoom -TAG_PENTAX_FLASH_MODE=Flash Mode -TAG_PENTAX_FOCUS_MODE=Focus Mode -TAG_PENTAX_ISO_SPEED=ISO Speed -TAG_PENTAX_PRINT_IMAGE_MATCHING_INFO=Print Image Matching (PIM) Info -TAG_PENTAX_QUALITY_LEVEL=Quality Level -TAG_PENTAX_SATURATION=Saturation -TAG_PENTAX_SHARPNESS=Sharpness -TAG_PENTAX_TIME_ZONE=Time Zone -TAG_PENTAX_WHITE_BALANCE=White Balance diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/SonyMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/SonyMarkernote.txt deleted file mode 100644 index 97df917464..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/SonyMarkernote.txt +++ /dev/null @@ -1,3 +0,0 @@ -# This file contains label of property for MetaDataExtractor -TEST=For testing. Do not remove -MARKER_NOTE_NAME=Sony Makernote diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/CanonMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/en/CanonMarkernote.txt deleted file mode 100644 index a05eb21de3..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/CanonMarkernote.txt +++ /dev/null @@ -1,167 +0,0 @@ -# This file contains label of property for MetaDataExtractor -TEST=For testing. Do not remove -MARKER_NOTE_NAME=Canon Makernote -TAG_CANON_CAMERA_STATE_1=Camera State 1 -TAG_CANON_CAMERA_STATE_2=Camera State 2 -TAG_CANON_CUSTOM_FUNCTIONS=Custom functions -TAG_CANON_CUSTOM_FUNCTION_AF_ASSIST_LIGHT=Custom functions AF assist light -TAG_CANON_CUSTOM_FUNCTION_AF_STOP=Custom functions AF stop -TAG_CANON_CUSTOM_FUNCTION_BRACKETTING=Custom functions bracketting -TAG_CANON_CUSTOM_FUNCTION_FILL_FLASH_REDUCTION=Custom functions fill flash reduction -TAG_CANON_CUSTOM_FUNCTION_LONG_EXPOSURE_NOISE_REDUCTION=Custom functions long exposure noise reduction -TAG_CANON_CUSTOM_FUNCTION_MENU_BUTTON_RETURN=Custom functions menu button return -TAG_CANON_CUSTOM_FUNCTION_MIRROR_LOCKUP=Custom functions mirror lockup -TAG_CANON_CUSTOM_FUNCTION_SENSOR_CLEANING=Custom functions sensor cleaning -TAG_CANON_CUSTOM_FUNCTION_SET_BUTTON_FUNCTION=Custom functions set button function -TAG_CANON_CUSTOM_FUNCTION_SHUTTER_AUTO_EXPOSURE_LOCK_BUTTONS=Custom functions shutter auto exposure -TAG_CANON_CUSTOM_FUNCTION_SHUTTER_CURTAIN_SYNC=Custom functions shutter curtain sync -TAG_CANON_CUSTOM_FUNCTION_SHUTTER_SPEED_IN_AV_MODE=Custom functions speed in AV mode -TAG_CANON_CUSTOM_FUNCTION_TV_AV_AND_EXPOSURE_LEVEL=Custom functions TV AV and exposure level -TAG_CANON_FIRMWARE_VERSION=Firware version -TAG_CANON_IMAGE_NUMBER=Image number -TAG_CANON_IMAGE_TYPE=Image type -TAG_CANON_OWNER_NAME=Owner name -TAG_CANON_SERIAL_NUMBER=Serial number -TAG_CANON_STATE1_AF_POINT_SELECTED=AF point selected -TAG_CANON_STATE1_CONTINUOUS_DRIVE_MODE=Continuous drive mode -TAG_CANON_STATE1_CONTRAST=Contrast -TAG_CANON_STATE1_DIGITAL_ZOOM=Digital zoom -TAG_CANON_STATE1_EASY_SHOOTING_MODE=Easy shooting mode -TAG_CANON_STATE1_EXPOSURE_MODE=Exposure mode -TAG_CANON_STATE1_FLASH_ACTIVITY=Flash activity -TAG_CANON_STATE1_FLASH_DETAILS=Flash Details -TAG_CANON_STATE1_FLASH_MODE=Flash mode -TAG_CANON_STATE1_FOCAL_UNITS_PER_MM=Focal units per mm -TAG_CANON_STATE1_FOCUS_MODE_1=Focus mode 1 -TAG_CANON_STATE1_FOCUS_MODE_2=Focus mode 2 -TAG_CANON_STATE1_FOCUS_TYPE=Focus type -TAG_CANON_STATE1_IMAGE_SIZE=Image size -TAG_CANON_STATE1_ISO=ISO -TAG_CANON_STATE1_LONG_FOCAL_LENGTH=Long focal length -TAG_CANON_STATE1_MACRO_MODE=Macro mode -TAG_CANON_STATE1_METERING_MODE=Metering methode -TAG_CANON_STATE1_QUALITY=Quality -TAG_CANON_STATE1_SATURATION=Saturation -TAG_CANON_STATE1_SELF_TIMER_DELAY=Self timer delay -TAG_CANON_STATE1_SHARPNESS=Sharpness -TAG_CANON_STATE1_SHORT_FOCAL_LENGTH=Short focal length -TAG_CANON_STATE1_UNKNOWN_12=Unknown 12 -TAG_CANON_STATE1_UNKNOWN_13=Unknown 13 -TAG_CANON_STATE1_UNKNOWN_2=Unknown 2 -TAG_CANON_STATE1_UNKNOWN_3=Unknown 3 -TAG_CANON_STATE1_UNKNOWN_7=Unknown 7 -TAG_CANON_STATE2_AEB_BRACKET_VALUE=AEB bracket value -TAG_CANON_STATE2_AF_POINT_USED=AF point used -TAG_CANON_STATE2_AUTO_EXPOSURE_BRACKETING=Auto exposure bracketing -TAG_CANON_STATE2_FLASH_BIAS=Flash bias -TAG_CANON_STATE2_SEQUENCE_NUMBER=Sequence number -TAG_CANON_STATE2_SUBJECT_DISTANCE=Subject distance -TAG_CANON_STATE2_WHITE_BALANCE=White balance -# -# xb: 15.06.2008 -TAG_CANON_CanonCameraInfo=Canon Camera Info -TAG_CANON_FocalLength=Canon Focal Length -TAG_CANON_STATE1_LensType=Lens type -TAG_CANON_STATE1_RecordMode=Record Mode -TAG_CANON_STATE1_MaxAperture=Max aperture -TAG_CANON_STATE1_MinAperture=Min aperture -TAG_CANON_STATE1_AESetting=AESetting -TAG_CANON_STATE1_ImageStabilization=Image stabilization -TAG_CANON_STATE1_DisplayAperture=Display aperture -TAG_CANON_STATE1_ZoomSourceWidth=Zoom wource width -TAG_CANON_STATE1_ZoomTargetWidth=Zoom target width -TAG_CANON_STATE1_SpotMeteringMode=Spot metering mode -TAG_CANON_STATE1_PhotoEffect=Photo effect -TAG_CANON_STATE1_ManualFlashOutput=Manual flash output -TAG_CANON_STATE1_ColorTone=Color tone -TAG_CANON_FocalLength_FocalType=Focal type -TAG_CANON_FocalLength_FocalLength=Focal length -TAG_CANON_FocalLength_FocalPlaneXSize=Focal plane X-size -TAG_CANON_FocalLength_FocalPlaneYSize=Focal plane Y-size - -TAG_CANON_STATE2_AutoISO=Auto ISO -TAG_CANON_STATE2_BaseISO=Base ISO -TAG_CANON_STATE2_MeasuredEV=Measured EV -TAG_CANON_STATE2_TargetAperture=Target aperture -TAG_CANON_STATE2_TargetExposureTime=Target exposure time -TAG_CANON_STATE2_ExposureCompensation=Exposure compensation -TAG_CANON_STATE2_SlowShutter=Slow shutter -TAG_CANON_STATE2_OpticalZoomCode=Optical zoom code -TAG_CANON_STATE2_FlashGuideNumber=Flash guide number -TAG_CANON_STATE2_ControlMode=Control mode -TAG_CANON_STATE2_FocusDistanceLower=Focus distance lower -TAG_CANON_STATE2_FNumber=FNumber -TAG_CANON_STATE2_ExposureTime=Exposure time -TAG_CANON_STATE2_BulbDuration=Bulb duration -TAG_CANON_STATE2_CameraType=Camera type -TAG_CANON_STATE2_AutoRotate=Auto rotate -TAG_CANON_STATE2_NDFilter=ND filter -TAG_CANON_STATE2_SelfTimer2=Self timer 2 -TAG_CANON_STATE2_FlashOutput=Flash output - -TAG_CANON_CanonModelID=Canon Model ID -TAG_CANON_CanonAFInfo=Canon AF Info -TAG_CANON_SerialNumberFormat=Serial Number Format -TAG_CANON_SuperMacro=Super Macro -TAG_CANON_DateStampMode=Date Stamp Mode -TAG_CANON_MyColors=My Colors -TAG_CANON_FirmwareRevision=Firmware Revision -TAG_CANON_FaceDetect1=Face Detect 1 -TAG_CANON_FaceDetect2=Face Detect 2 -TAG_CANON_CanonAFInfo2=Canon AF Info 2 -TAG_CANON_RawDataOffset=Raw Data Offset -TAG_CANON_OriginalDecisionDataOffset=Original Decision Data Offset -TAG_CANON_CustomFunctions1D=Custom Functions 1D -TAG_CANON_PersonalFunctions=Personal Functions -TAG_CANON_PersonalFunctionValues=Personal Function Values -TAG_CANON_CanonFileInfo=Canon File Info -TAG_CANON_AFPointsInFocus1D=AF Points In Focus 1D -TAG_CANON_LensType=Lens Type -TAG_CANON_InternalSerialNumber=Internal Serial Number -TAG_CANON_DustRemovalData=Dust Removal Data -TAG_CANON_CustomFunctions2=Custom Functions 2 -TAG_CANON_ProcessingInfo=Proccessing Info -TAG_CANON_ToneCurveTable=Tone Curve Table -TAG_CANON_SharpnessTable=Sharpness Table -TAG_CANON_SharpnessFreqTable=Sharpness Freq Table -TAG_CANON_WhiteBalanceTable=White Balance Table -TAG_CANON_ColorBalance=Color Balance -TAG_CANON_ColorTemperature=Color Temperature -TAG_CANON_CanonFlags=Canon Flags -TAG_CANON_ModifiedInfo=Modified Info -TAG_CANON_ToneCurveMatching=Tone Curve Matching -TAG_CANON_WhiteBalanceMatching=White Balance Matching -TAG_CANON_ColorSpace=Color Space -TAG_CANON_PreviewImageInfo=Preview Image Info -TAG_CANON_VRDOffset=VRD Offset -TAG_CANON_SensorInfo=Sensor Info -TAG_CANON_ColorBalance1to4=Color Balance 1 to 4 -TAG_CANON_UnknownBlock1=Unknown Block 1 -TAG_CANON_ColorInfo=Color Info -TAG_CANON_UnknownBlock2=Unknown Block 2 -TAG_CANON_BlackLevel=Black Level - -TAG_CANON_ProcessingInfo_ToneCurve=Tone curve -TAG_CANON_ProcessingInfo_Sharpness=Sharpness -TAG_CANON_ProcessingInfo_SharpnessFrequency=Sharpness frequency -TAG_CANON_ProcessingInfo_SensorRedLevel=Sensor red level -TAG_CANON_ProcessingInfo_SensorBlueLevel=Sensor blue level -TAG_CANON_ProcessingInfo_WhiteBalanceRed=White balance red -TAG_CANON_ProcessingInfo_WhiteBalanceBlue=White balance blue -TAG_CANON_ProcessingInfo_WhiteBalance=White balance -TAG_CANON_ProcessingInfo_ColorTemperature=Color temperature -TAG_CANON_ProcessingInfo_PictureStyle=Picture style -TAG_CANON_ProcessingInfo_DigitalGain=Digital gain -TAG_CANON_ProcessingInfo_WBShiftAB=WB Shift AB -TAG_CANON_ProcessingInfo_WBShiftGM=WB Shift GM - -TAG_CANON_SensorInfo_SensorWidth=Sensor width -TAG_CANON_SensorInfo_SensorHeight=Sensor height -TAG_CANON_SensorInfo_SensorLeftBorder=Sensor left border -TAG_CANON_SensorInfo_SensorTopBorder=Sensor top border -TAG_CANON_SensorInfo_SensorRightBorder=Sensor right border -TAG_CANON_SensorInfo_SensorBottomBorder=Sensor bottom border -TAG_CANON_SensorInfo_BlackMaskLeftBorder=Black mask left border -TAG_CANON_SensorInfo_BlackMaskTopBorder=Black mask top border -TAG_CANON_SensorInfo_BlackMaskRightBorder=Black mask right border -TAG_CANON_SensorInfo_BlackMaskBottomBorder=Black mask bottom border diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/CasioMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/en/CasioMarkernote.txt deleted file mode 100644 index 1b78c403e9..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/CasioMarkernote.txt +++ /dev/null @@ -1,51 +0,0 @@ -# This file contains label of property for MetaDataExtractor -TEST=For testing. Do not remove -MARKER_NOTE_NAME=Casio Makernote -TAG_CASIO_CCD_SENSITIVITY=CCD Sensitivity -TAG_CASIO_CONTRAST=Contrast -TAG_CASIO_DIGITAL_ZOOM=Digital Zoom -TAG_CASIO_FLASH_INTENSITY=Flash Intensity -TAG_CASIO_FLASH_MODE=Flash Mode -TAG_CASIO_FOCUSING_MODE=Focussing Mode -TAG_CASIO_OBJECT_DISTANCE=Object Distance -TAG_CASIO_QUALITY=Quality -TAG_CASIO_RECORDING_MODE=Recording Mode -TAG_CASIO_SATURATION=Saturation -TAG_CASIO_SHARPNESS=Sharpness -TAG_CASIO_TYPE2_BESTSHOT_MODE=Bestshot mode -TAG_CASIO_TYPE2_CASIO_PREVIEW_THUMBNAIL=Preview thumbnail -TAG_CASIO_TYPE2_CCD_ISO_SENSITIVITY=CCD ISO sensitivity -TAG_CASIO_TYPE2_COLOR_MODE=Color mode -TAG_CASIO_TYPE2_CONTRAST=Contrast -TAG_CASIO_TYPE2_ENHANCEMENT=Enhancement -TAG_CASIO_TYPE2_FILTER=Filter -TAG_CASIO_TYPE2_FLASH_DISTANCE=Flash distance -TAG_CASIO_TYPE2_FOCAL_LENGTH=Focal length -TAG_CASIO_TYPE2_FOCUS_MODE_1=Focus mode 1 -TAG_CASIO_TYPE2_FOCUS_MODE_2=Focus mode 2 -TAG_CASIO_TYPE2_IMAGE_SIZE=Image size -TAG_CASIO_TYPE2_ISO_SENSITIVITY=ISO sensitivity -TAG_CASIO_TYPE2_OBJECT_DISTANCE=Object distance -TAG_CASIO_TYPE2_PRINT_IMAGE_MATCHING_INFO=Print image matching info -TAG_CASIO_TYPE2_QUALITY=Quality -TAG_CASIO_TYPE2_QUALITY_MODE=Quality mode -TAG_CASIO_TYPE2_RECORD_MODE=Record mode -TAG_CASIO_TYPE2_SATURATION=Saturation -TAG_CASIO_TYPE2_SELF_TIMER=Self timer -TAG_CASIO_TYPE2_SHARPNESS=Sharpness -TAG_CASIO_TYPE2_THUMBNAIL_DIMENSIONS=Thumbnail dimensions -TAG_CASIO_TYPE2_THUMBNAIL_OFFSET=Thumbnail offset -TAG_CASIO_TYPE2_THUMBNAIL_SIZE=Thumbnail size -TAG_CASIO_TYPE2_TIME_ZONE=Time zone -TAG_CASIO_TYPE2_WHITE_BALANCE_1=White balance 1 -TAG_CASIO_TYPE2_WHITE_BALANCE_2=White balance 2 -TAG_CASIO_TYPE2_WHITE_BALANCE_BIAS=White balance bias -TAG_CASIO_UNKNOWN_1=Makernote Unknown 1 -TAG_CASIO_UNKNOWN_2=Makernote Unknown 2 -TAG_CASIO_UNKNOWN_3=Makernote Unknown 3 -TAG_CASIO_UNKNOWN_4=Makernote Unknown 4 -TAG_CASIO_UNKNOWN_5=Makernote Unknown 5 -TAG_CASIO_UNKNOWN_6=Makernote Unknown 6 -TAG_CASIO_UNKNOWN_7=Makernote Unknown 7 -TAG_CASIO_UNKNOWN_8=Makernote Unknown 8 -TAG_CASIO_WHITE_BALANCE=White Balance diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/Commons.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/en/Commons.txt deleted file mode 100644 index f112e2f4bb..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/Commons.txt +++ /dev/null @@ -1,342 +0,0 @@ -TEST=For testing. Do not remove -0_M_P_DISABLED=0,-,+ / Disabled -0_M_P_ENABLED=0,-,+ / Enabled -1_200_FIXED=1/200 (fixed) -1_2_STOP=1/2 stop -1_3_STOP=1/3 stop -1_CURTAIN_SYNC=1st Curtain Sync -2_CURTAIN_SYNC=2nd Curtain Sync -ADOBE_DEFLATE=Adobe Deflate -AE_AF_LOCK=AF/AF lock -AE_GOOD=AE good -AE_LOCK_AF=AE lock/AF -AE_RELEASE_AE_AF=AE+release/AE+AF -AF_AE_LOCK=AF/AE lock -AF_STOP=AF stop -AI_FOCUS=AI Focus -AI_SERVO=AI Servo -APERTURE=F {0} -APERTURE_PRIORITY=Aperture priority -APERTURE_PRIORITY_AE=Aperture priority AE -AUTO=Auto -AUTOMATIC=Automatic -AUTO_AND_RED_EYE_REDUCTION=Auto and red-eye reduction -AUTO_BRACKET=Auto bracket -AUTO_EXPOSURE=Auto exposure -AUTO_FOCUS=Auto focus -AUTO_FOCUS_GOOD=Auto focus good -AUTO_SELECTED=Auto selected -AUTO_WHITE_BALANCE=Auto white balance -MONOCHROME=Monochrome -AVERAGE=Average -AV_PRIORITY=Av-priority -A_DEP=A-DEP -BEST=Best -BETTER=Better -BITS={0} bits -BITS_COMPONENT_PIXEL={0} bits/component/pixel -BITS_PIXEL={0} bits/pixel -BIT_PIXEL={0} bit/pixel -BLACK_AND_WHITE=Black & White -BLACK_IS_ZERO=Black Is Zero -BLUR_WARNING=Blur warning -BOTTOM=Bottom -BOTTOM_LEFT_SIDE=Bottom, left side (Mirror vertical) -BOTTOM_RIGHT_SIDE=Bottom, right side (Rotate 180) -BOTTOM_TO_TOP_PAN_DIR=Bottom to top panorama direction -BRIGHT_M=Bright - -BRIGHT_P=Bright + -BYTES={0} bytes -BYTES_OF_IMAGE_DATA={0} bytes of image data -CCD_P_1=+1.0 -CCD_P_2=+2.0 -CCD_P_3=+3.0 -CCIRLEW=CCIRLEW -CCITT_1D=CCITT 1D -CENTER=Center -CENTER_OF_PIXEL_ARRAY=Center of pixel array -CENTER_WEIGHTED_AVERAGE=Center weighted average -CENTER_WEIGHTED=Center weighted -CHANGE_ISO_SPEED=Change ISO Speed -CHANGE_QUALITY=Change Quality -CHUNKY=Chunky (contiguous for each subsampling pixel) -CIELAB=CIELab -CLOSE_UP_MACRO=Close-up (Macro) -CLOSE_VIEW=Close view -CLOUDY=Cloudy -CM=cm -CMYK=CMYK -COLOR=Color -COLOR_FILTER_ARRAY=Color Filter Array -COLOR_SEQUENTIAL=Color sequential area sensor -COLOR_SEQUENTIAL_LINEAR=Color sequential linear sensor -COMPONENT_DATA={0} component: Quantization table {1}, Sampling factors {2} horiz/{3} vert -CONTINUOUS=Continuous -CONTRAST_M=Contrast - -CONTRAST_P=Contrast + -CUSTOM=Custom -CUSTOM_PROCESS=Custom process -CUSTOM_WHITE_BALANCE=Custom white balance -D55=D55 -D65=D65 -D75=D75 -DATUM_POINT=Datum point -DAYLIGHT=Daylight -DAYLIGHTCOLOR_FLUORESCENCE=DaylightColor-fluorescence -DAYWHITECOLOR_FLUORESCENCE=DaywhiteColor-fluorescence -DCS=DCS -DEFLATE=Deflate -DEGREES={0} degrees -DIGITAL_STILL_CAMERA=Digital Still Camera (DSC) -DIGITAL_ZOOM={0}x digital zoom -DIGITAL_ZOOM_NOT_USED=Digital zoom not used -DIMENSIONAL_MEASUREMENT={0}-dimensional measurement -DIRECTLY_PHOTOGRAPHED_IMAGE=Directly photographed image -DISABLED=Disabled -DISTANCE_MM={0} mm -DISTANT_VIEW=Distant view -DOTS_PER={0} dots per {1} -EASY_SHOOTING=Easy shooting -ECONOMY=Economy -ENABLED=Enabled -EVALUATIVE=Evaluative -EXTERNAL_E_TTL=External E-TTL -EXTERNAL_FLASH=Extenal flash -FAST_PICTURE_TAKING_MODE=Fast picture taking mode -FAST_SHUTTER=Fast shutter -FINE=Fine -FISHEYE_CONVERTER=Fisheye converter -FIXATION=Fixation -FLASH=Flash -FLASH_BIAS_NEW={0} {1} EV -FLASH_DID_NOT_FIRE=Flash did not fire -FLASH_FIRED=Flash fired -FLASH_OFF=Flash Off -FLASH_ON=Flash On -FLASH_SIMPLE={0} EV -FLASH_STRENGTH={0} eV (Apex) -FLUORESCENT=Fluorescence -FOCAL_LENGTH={0} {1} -FOCAL_PLANE={0} {1} -FP_SYNC_ENABLED=FP sync enabled -FP_SYNC_USED=FP sync used -FULL_AUTO=Full auto -FULL_RESOLUTION_IMAGE=Full-resolution image -GOOD=Good -GPS_TIME_STAMP={0}:{1}:{2} UTC -HARD=Hard -HIGH=High -HIGH_GAIN_DOWN=High gain down -HIGH_GAIN_UP=High gain up -HIGH_HARD=High (HARD) -HIGH_SATURATION=High saturation -HOURS_MINUTES_SECONDS={0}"{1}'{2} -HQ=HQ -ICCLAB=ICCLab -INCANDENSCENSE=Incandenscense -INCANDESCENSE=Incandescense -INCHES=Inches -INFINITE=Infinite -INFINITY=Infinity -INTERNAL_FLASH=Internal flash -ISO=ISO {0} -ISO_NOT_SPECIFIED=Not specified (see ISOSpeedRatings tag) -IT8BL=IT8BL -IT8CTPAD=IT8CTPAD -IT8LW=IT8LW -IT8MP=IT8MP -ITULAB=ITULab -JBIG=JBIG -JBIG_B_W=JBIG B&W -JBIG_COLOR=JBIG Color -JPEG=JPEG -JPEG_2000=JPEG 2000 -JPEG_OLD_STYLE=JPEG (old-style) -KILOMETERS=kilometers -KNOTS=knots -KPH=kph -LANDSCAPE=Landscape -LANDSCAPE_MODE=Landscape mode -LANDSCAPE_SCENE=Landscape scene -LARGE=Large -LEFT=Left -LEFT_SIDE_BOTTOM=Left side, bottom (Rotate 270 CW) -LEFT_SIDE_TOP=Left side, top (Mirror horizontal and rotate 270 CW) -LEFT_TO_RIGHT_PAN_DIR=Left to right panorama direction -LENS={0}-{1}mm f/{2}-{3} -LINEAR_RAW=Linear Raw -LOCKED_PAN_MODE=Locked (Pan Mode) -LOCK_AE_AND_START_TIMER=Lock AE and start timer -LOW=Low -LOW_GAIN_DOWN=Low gain down -LOW_GAIN_UP=Low gain up -LOW_ORG=Low (ORG) -LOW_SATURATION=Low saturation -LZW=LZW -MACRO=Macro -MACRO_CLOSEUP=Macro / Closeup -MAGNETIC_DIRECTION=Magnetic direction -MANUAL=Manual -MANUAL_CONTROL=Manual control -MANUAL_EXPOSURE=Manual exposure -MANUAL_FOCUS=Manual focus -MANUAL_WHITE_BALANCE=Manual white balance -MEASUREMENT_INTEROPERABILITY=Measurement Interoperability -MEASUREMENT_IN_PROGESS=Measurement in progess -MEDIUM=Medium -METRES={0} metres -MF=MF -MILES=miles -MODE_I_SRGB=Mode I (sRGB) -MPH=mph -MULTIPLE=Multiple -MULTI_AREA_FOCUS=Multi-Area Focus -MULTI_SEGMENT=Multi-segment -MULTI_SPOT=Multi-spot -M_0_P_DISABLED=-,0,+ / Disabled -M_0_P_ENABLED=-,0,+ / Enabled -NEXT=Next -NIGHT=Night -NIGHT_SCENE=Night scene -NIKON_NEF_COMPRESSED=Nikon NEF Compressed -NONE=None -NONE_MF=None (MF) -NORMAL=Normal -NORMAL_NO_MACRO=Normal (no macro) -NORMAL_PICTURE_TAKING_MODE=Normal picture taking mode -NORMAL_PROCESS=Normal process -NORMAL_STD=Normal (STD) -NOT_ASSIGNED=Not Assigned -NOT_DEFINED=(Not defined) -NO_BLUR_WARNING=No blur warning -NO_DIGITAL_ZOOM=No digital zoom -NO_DITHERING_OR_HALFTONING=No dithering or halftoning -NO_FLASH_FIRED=No flash fired -NO_UNIT=(No unit) -OFF=Off -ON=On -ONE_CHIP_COLOR=One-chip color area sensor -ONE_SHOT=One-shot -ON_AND_RED_EYE_REDUCTION=On and red-eye reduction -ON_AUTO=On (auto) -OPERATE_AF=Operate AF -ORDERED_DITHER_OR_HALFTONE=Ordered dither or halftone -OTHER=(Other) -OUT_OF_FOCUS=Out of focus -OVER_EXPOSED=Over exposed (>1/1000s @ F11) -PACKBITS=PackBits -PANORAMA=Panorama -PANORAMA_PICTURE_TAKING_MODE=Panorama picture taking mode -PAN_FOCUS=Pan focus -PARTIAL=Partial -PIXARFILM=PixarFilm -PIXARLOG=PixarLog -PIXAR_LOGL=Pixar LogL -PIXAR_LOGLUV=Pixar LogLuv -PIXELS={0} pixels -PIXELS_BI={0} x {1} pixels -PORTRAIT=Portrait -PORTRAIT_MODE=Portrait mode -PORTRAIT_SCENE=Portrait scene -POS=[{0} {1} {2}] [{3} {4} {5}] -PRESET=PreSet -PREVIOUS=Previous -PREVIOUS_VOLATILE=Previous (volatile) -PROGRAM=Program -PROGRAM_ACTION=Program action (high-speed program) -PROGRAM_AE=Program AE -PROGRAM_CREATIVE=Program creative (slow program) -PROGRAM_NORMAL=Program normal -RANDOMIZED_DITHER=Randomized dither -RECOMMENDED_EXIF_INTEROPERABILITY=Recommended Exif Interoperability Rules (ExifR98) -REDUCED_RESOLUTION_IMAGE=Reduced-resolution image -RED_EYE_REDUCTION=Red-eye reduction -RETURN_DETECTED=return detected -RETURN_NOT_DETECTED=return not detected -REVERSED=Reversed -RGB=RGB -RGB_PALETTE=RGB Palette -RIGHT=Right -RIGHT_SIDE_BOTTOM=Right side, bottom (Mirror horizontal and rotate 90 CW) -RIGHT_SIDE_TOP=Right side, top (Rotate 90 CW) -RIGHT_TO_LEFT_PAN_DIR=Right to left panorama direction -ROWS_STRIP={0} rows/strip -SAMPLES_PIXEL={0} samples/pixel -SEA_LEVEL=Sea level -SEC={0} sec -SELECT_PARAMETERS=Select Parameters -SELF_TIMER_DELAY={0} sec -SELF_TIMER_DELAY_NOT_USED=Self timer not used -SEPARATE=Separate (Y-plane/Cb-plane/Cr-plane format) -SEPIA=Sepia -SGILOG24=SGILog24 -SGILOG=SGILog -SHADE=Shade -SHQ=SHQ -SHUTTER_PRIORITY=Shutter priority -SHUTTER_PRIORITY_AE=Shutter priority AE -SHUTTER_SPEED=1/{0} sec -SHUTTER_SPEED_SEC={0} sec -SINGLE=Single -SINGLE_PAGE_OF_MULTI_PAGE_IMAGE=Single page of multi-page image -SINGLE_PAGE_OF_MULTI_PAGE_REDUCED_RESOLUTION_IMAGE=Single page of multi-page reduced-resolution image -SINGLE_SHOT=Single shot -SINGLE_SHOT_WITH_SELF_TIMER=Single shot with self-timer -SINGLE_SHUTTER=Single shutter -SLOW_SHUTTER=Slow shutter -SLOW_SYNCHRO=Slow-synchro -SMALL=Small -SOFT=Soft -SPEEDLIGHT=SpeedLight -SPORTS=Sports -SPORTS_SCENE=Sports scene -SPOT=Spot -SQ=SQ -SRGB=sRGB -STANDARD=Standard -STANDARD_LIGHT=Standard light -STANDARD_LIGHT_B=Standard light (B) -STANDARD_LIGHT_C=Standard light (C) -STRONG=Strong -SUNNY=Sunny -SUPERFINE=Super fine -SXGA_BASIC=SXGA Basic -SXGA_FINE=SXGA Fine -SXGA_NORMAL=SXGA Normal -T4_GROUP_3_FAC=T4/Group 3 Fax -T6_GROUP_4_FAC=T6/Group 4 Fax -THREE_CHIP_COLOR=Three-chip color area sensor -THUMBNAIL_BYTES=[{0} bytes of thumbnail data] -THUNDERSCA=Thunderscan -TOP=Top -TOP_LEFT_SIDE=Top, left side (Horizontal / normal) -TOP_RIGHT_SIDE=Top, right side (Mirror horizontal) -TOP_TO_BOTTOM_PAN_DIR=Top to bottom panorama direction -TRANSPARENCY_MASK=Transparency Mask -TRANSPARENCY_MASK_OF_MULTI_PAGE_IMAGE=Transparency mask of multi-page image -TRANSPARENCY_MASK_OF_REDUCED_RESOLUTION_IMAGE=Transparency mask of reduced-resolution image -TRANSPARENCY_MASK_OF_REDUCED_RESOLUTION_MULTI_PAGE_IMAGE=Transparency mask of reduced-resolution multi-page image -TRILINEAR_SENSOR=Trilinear sensor -TRUE_DIRECTION=True direction -TUNGSTEN=Tungsten -TV_PRIORITY=Tv-priority -TWO_CHIP_COLOR=Two-chip color area sensor -UNCOMPRESSED=Uncompressed -UNDEFINED=Undefined -UNKNOWN=Unknown ("{0}") -UNKNOWN_COLOR_SPACE=Unknown color space -UNKNOWN_COMPRESSION=Unknown compression -UNKNOWN_CONFIGURATION=Unknown configuration -UNKNOWN_PICTURE_TAKING_MODE=Unknown picture taking mode -UNKNOWN_PROGRAM=Unknown program ({0}) -UNKNOWN_SEQUENCE_NUMBER=Unknown sequence number -VGA_BASIC=VGA Basic -VGA_FINE=VGA Fine -VGA_NORMAL=VGA Normal -WEAK=Weak -WHITE_FLUORESCENCE=White-fluorescence -WHITE_IS_ZERO=White Is Zero -X_RD_IN_A_SEQUENCE={0}rd in a sequence -YCBCR=YCbCr -YCBCR_420=YCbCr4:2:0 -YCBCR_422=YCbCr4:2:2 diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/ExifInteropMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/en/ExifInteropMarkernote.txt deleted file mode 100644 index c80a35085b..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/ExifInteropMarkernote.txt +++ /dev/null @@ -1,8 +0,0 @@ -TEST=For testing. Do not remove -# This file contains label of property for MetaDataExtractor -MARKER_NOTE_NAME=Exif Interoperability Makernote -TAG_INTEROP_INDEX=Interoperability Index -TAG_INTEROP_VERSION=Interoperability Version -TAG_RELATED_IMAGE_FILE_FORMAT=Related Image File Format -TAG_RELATED_IMAGE_LENGTH=Related Image Length -TAG_RELATED_IMAGE_WIDTH=Related Image Width diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/ExifMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/en/ExifMarkernote.txt deleted file mode 100644 index 70454d3e63..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/ExifMarkernote.txt +++ /dev/null @@ -1,135 +0,0 @@ -# This file contains label of property for MetaDataExtractor -TEST=For testing. Do not remove -MARKER_NOTE_NAME=Exif Makernote -TAG_APERTURE=Aperture Value -TAG_ARTIST=Artist -TAG_BATTERY_LEVEL=Battery Level -TAG_BITS_PER_SAMPLE=Bits Per Sample -TAG_BRIGHTNESS_VALUE=Brightness Value -TAG_CFA_PATTERN=CFA Pattern -TAG_CFA_PATTERN_2=CFA Pattern -TAG_CFA_REPEAT_PATTERN_DIM=CFA Repeat Pattern Dim -TAG_COLOR_SPACE=Color Space -TAG_COMPONENTS_CONFIGURATION=Components Configuration -TAG_COMPRESSION=Compression -TAG_COMPRESSION_LEVEL=Compressed Bits Per Pixel -TAG_CONTRAST=Contrast -TAG_COPYRIGHT=Copyright -TAG_CUSTOM_RENDERED=Custom Rendered -TAG_DATETIME=Date/Time -TAG_DATETIME_DIGITIZED=Date/Time Digitized -TAG_DATETIME_ORIGINAL=Date/Time Original -TAG_DEVICE_SETTING_DESCRIPTION=Device Setting Description -TAG_DIGITAL_ZOOM_RATIO=Digital Zoom Ratio -TAG_DOCUMENT_NAME=Document Name -TAG_EXIF_IMAGE_HEIGHT=Exif Image Height -TAG_EXIF_IMAGE_WIDTH=Exif Image Width -TAG_EXIF_OFFSET=Exif Offset -TAG_EXIF_VERSION=Exif Version -TAG_EXPOSURE_BIAS=Exposure Bias Value -TAG_EXPOSURE_INDEX=Exposure Index -TAG_EXPOSURE_INDEX_2=Exposure Index -TAG_EXPOSURE_MODE=Exposure Mode -TAG_EXPOSURE_PROGRAM=Exposure Program -TAG_EXPOSURE_TIME=Exposure Time -TAG_FILE_SOURCE=File Source -TAG_FILL_ORDER=Fill Order -TAG_FLASH=Flash -TAG_FLASHPIX_VERSION=FlashPix Version -TAG_FLASH_ENERGY=Flash Energy -TAG_FLASH_ENERGY_2=Flash Energy -TAG_FNUMBER=F-Number -TAG_FOCAL_LENGTH=Focal Length -TAG_FOCAL_LENGTH_IN_35MM_FILM=Focal Length in 35mm Film -TAG_FOCAL_PLANE_UNIT=Focal Plane Resolution Unit -TAG_FOCAL_PLANE_X_RES=Focal Plane X Resolution -TAG_FOCAL_PLANE_Y_RES=Focal Plane Y Resolution -TAG_GAIN_CONTROL=Gain Control -TAG_GPS_INFO=GPS Info -TAG_IMAGE_DESCRIPTION=Image Description -TAG_IMAGE_HISTORY=Image History -TAG_IMAGE_NUMBER=Image Number -TAG_IMAGE_UNIQUE_ID=Image Unique ID -TAG_INTERLACE=Interlace -TAG_INTEROPERABILITY_OFFSET=Interoperability Offset -TAG_INTER_COLOR_PROFILE=Inter Color Profile -TAG_IPTC_NAA=IPTC/NAA -TAG_ISO_EQUIVALENT=ISO Speed Ratings -TAG_JPEG_PROC=JPEG Proc -TAG_JPEG_TABLES=JPEG Tables -TAG_MAKE=Make -TAG_MARKER_NOTE=Maker Note -TAG_MAX_APERTURE=Max Aperture Value -TAG_MAX_SAMPLE_VALUE=Maximum sample value -TAG_METERING_MODE=Metering Mode -TAG_MIN_SAMPLE_VALUE=Minimum sample value -TAG_MODEL=Model -TAG_NEW_SUBFILE_TYPE=New Subfile Type -TAG_NOISE=Noise -TAG_OECF=OECF -TAG_ORIENTATION=Orientation -TAG_PAGE_NAME=Page name -TAG_PHOTOMETRIC_INTERPRETATION=Photometric Interpretation -TAG_PLANAR_CONFIGURATION=Planar Configuration -TAG_PREDICTOR=Predictor -TAG_PRIMARY_CHROMATICITIES=Primary Chromaticities -TAG_REFERENCE_BLACK_WHITE=Reference Black/White -TAG_RELATED_IMAGE_FILE_FORMAT=Related Image File Format -TAG_RELATED_IMAGE_LENGTH=Related Image Length -TAG_RELATED_IMAGE_WIDTH=Related Image Width -TAG_RELATED_SOUND_FILE=Related Sound File -TAG_RESOLUTION_UNIT=Resolution Unit -TAG_ROWS_PER_STRIP=Rows Per Strip -TAG_SAMPLES_PER_PIXEL=Samples Per Pixel -TAG_SATURATION=Saturation -TAG_SCENE_CAPTURE_TYPE=Scene Capture Type -TAG_SCENE_TYPE=Scene Type -TAG_SECURITY_CLASSIFICATION=Security Classification -TAG_SELF_TIMER_MODE=Self Timer Mode -TAG_SENSING_METHOD=Sensing Method -TAG_SHARPNESS=Sharpness -TAG_SHUTTER_SPEED=Shutter Speed Value -TAG_SOFTWARE=Software -TAG_SPATIAL_FREQ_RESPONSE=Spatial Frequency Response -TAG_SPATIAL_FREQ_RESPONSE_2=Spatial Frequency Response -TAG_SPECTRAL_SENSITIVITY=Spectral Sensitivity -TAG_STRIP_BYTE_COUNTS=Strip Byte Counts -TAG_STRIP_OFFSETS=Strip Offsets -TAG_SUBFILE_TYPE=Subfile Type -TAG_SUBJECT_DISTANCE=Subject Distance -TAG_SUBJECT_DISTANCE_RANGE=Subject Distance -TAG_SUBJECT_LOCATION=Subject Location -TAG_SUBJECT_LOCATION_2=Subject Location -TAG_SUBSECOND_TIME=Sub-Sec Time -TAG_SUBSECOND_TIME_DIGITIZED=Sub-Sec Time Digitized -TAG_SUBSECOND_TIME_ORIGINAL=Sub-Sec Time Original -TAG_SUB_IFDS=Sub IFDs -TAG_THRESHOLDING=Thresholding -TAG_THUMBNAIL_DATA=Thumbnail Data -TAG_THUMBNAIL_IMAGE_HEIGHT=Thumbnail Image Height -TAG_THUMBNAIL_IMAGE_WIDTH=Thumbnail Image Width -TAG_THUMBNAIL_LENGTH=Thumbnail Length -TAG_THUMBNAIL_OFFSET=Thumbnail Offset -TAG_TIFF_EP_STANDARD_ID=TIFF/EP Standard ID -TAG_TILE_BYTE_COUNTS=Tile Byte Counts -TAG_TILE_LENGTH=Tile Length -TAG_TILE_OFFSETS=Tile Offsets -TAG_TILE_WIDTH=Tile Width -TAG_TIME_ZONE_OFFSET=Time Zone Offset -TAG_TRANSFER_FUNCTION=Transfer Function -TAG_TRANSFER_RANGE=Transfer Range -TAG_USER_COMMENT=User Comment -TAG_WHITE_BALANCE=Light Source -TAG_WHITE_BALANCE_MODE=White balance mode -TAG_WHITE_POINT=White Point -TAG_XP_AUTHOR=Author (Win) -TAG_XP_COMMENTS=Comments (Win) -TAG_XP_KEYWORDS=Keyword (Win) -TAG_XP_SUBJECT=Subject (Win) -TAG_XP_TITLE=Title (Win) -TAG_X_RESOLUTION=X Resolution -TAG_YCBCR_COEFFICIENTS=YCbCr Coefficients -TAG_YCBCR_POSITIONING=YCbCr Positioning -TAG_YCBCR_SUBSAMPLING=YCbCr Sub-Sampling -TAG_Y_RESOLUTION=Y Resolution -TAG_LIGHT_SOURCE=Light source \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/FujiFilmMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/en/FujiFilmMarkernote.txt deleted file mode 100644 index 5bbb8e3a9f..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/FujiFilmMarkernote.txt +++ /dev/null @@ -1,21 +0,0 @@ -# This file contains label of property for MetaDataExtractor -TEST=For testing. Do not remove -MARKER_NOTE_NAME=FujiFilm Makernote -TAG_FUJIFILM_AE_WARNING=AE Warning -TAG_FUJIFILM_BLUR_WARNING=Blur Warning -TAG_FUJIFILM_COLOR=Color -TAG_FUJIFILM_CONTINUOUS_TAKING_OR_AUTO_BRACKETTING=Continuous Taking Or Auto Bracketting -TAG_FUJIFILM_FLASH_MODE=Flash Mode -TAG_FUJIFILM_FLASH_STRENGTH=Flash Strength -TAG_FUJIFILM_FOCUS_MODE=Focus Mode -TAG_FUJIFILM_FOCUS_WARNING=Focus Warning -TAG_FUJIFILM_MACRO=Macro -TAG_FUJIFILM_MAKERNOTE_VERSION=Makernote Version -TAG_FUJIFILM_PICTURE_MODE=Picture Mode -TAG_FUJIFILM_QUALITY=Quality -TAG_FUJIFILM_SHARPNESS=Sharpness -TAG_FUJIFILM_SLOW_SYNCHRO=Slow Synchro -TAG_FUJIFILM_TONE=Tone -TAG_FUJIFILM_UNKNOWN_1=Makernote Unknown 1 -TAG_FUJIFILM_UNKNOWN_2=Makernote Unknown 2 -TAG_FUJIFILM_WHITE_BALANCE=White Balance diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/GpsMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/en/GpsMarkernote.txt deleted file mode 100644 index 8ad755d036..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/GpsMarkernote.txt +++ /dev/null @@ -1,30 +0,0 @@ -# This file contains label of property for MetaDataExtractor -TEST=For testing. Do not remove -MARKER_NOTE_NAME=GPS Makernote -TAG_GPS_ALTITUDE=GPS Altitude -TAG_GPS_ALTITUDE_REF=GPS Altitude Ref -TAG_GPS_DEST_BEARING=GPS Dest Bearing -TAG_GPS_DEST_BEARING_REF=GPS Dest Bearing Ref -TAG_GPS_DEST_DISTANCE=GPS Dest Distance -TAG_GPS_DEST_DISTANCE_REF=GPS Dest Distance Ref -TAG_GPS_DEST_LATITUDE=GPS Dest Latitude -TAG_GPS_DEST_LATITUDE_REF=GPS Dest Latitude Ref -TAG_GPS_DEST_LONGITUDE=GPS Dest Longitude -TAG_GPS_DEST_LONGITUDE_REF=GPS Dest Longitude Ref -TAG_GPS_DOP=GPS DOP -TAG_GPS_IMG_DIRECTION=GPS Img Direction -TAG_GPS_IMG_DIRECTION_REF=GPS Img Direction Ref -TAG_GPS_LATITUDE=GPS Latitude -TAG_GPS_LATITUDE_REF=GPS Latitude Ref -TAG_GPS_LONGITUDE=GPS Longitude -TAG_GPS_LONGITUDE_REF=GPS Longitude Ref -TAG_GPS_MAP_DATUM=GPS Map Datum -TAG_GPS_MEASURE_MODE=GPS Measure Mode -TAG_GPS_SATELLITES=GPS Satellites -TAG_GPS_SPEED=GPS Speed -TAG_GPS_SPEED_REF=GPS Speed Ref -TAG_GPS_STATUS=GPS Status -TAG_GPS_TIME_STAMP=GPS Time-Stamp -TAG_GPS_TRACK=GPS Track -TAG_GPS_TRACK_REF=GPS Track Ref -TAG_GPS_VERSION_ID=GPS Version ID diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/IptcMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/en/IptcMarkernote.txt deleted file mode 100644 index 318584f0cd..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/IptcMarkernote.txt +++ /dev/null @@ -1,27 +0,0 @@ -# This file contains label of property for MetaDataExtractor -TEST=For testing. Do not remove -MARKER_NOTE_NAME=Iptc Makernote -TAG_BY_LINE=By-line -TAG_BY_LINE_TITLE=By-line Title -TAG_CAPTION=Caption/Abstract -TAG_CATEGORY=Category -TAG_CITY=City -TAG_COPYRIGHT_NOTICE=Copyright Notice -TAG_COUNTRY_OR_PRIMARY_LOCATION=Country/Primary Location -TAG_CREDIT=Credit -TAG_DATE_CREATED=Date Created -TAG_HEADLINE=Headline -TAG_KEYWORDS=Keywords -TAG_OBJECT_NAME=Object Name -TAG_ORIGINAL_TRANSMISSION_REFERENCE=Original Transmission Reference -TAG_ORIGINATING_PROGRAM=Originating Program -TAG_PROVINCE_OR_STATE=Province/State -TAG_RECORD_VERSION=Directory Version -TAG_RELEASE_DATE=Release Date -TAG_RELEASE_TIME=Release Time -TAG_SOURCE=Source -TAG_SPECIAL_INSTRUCTIONS=Special Instructions -TAG_SUPPLEMENTAL_CATEGORIES=Supplemental Category(s) -TAG_TIME_CREATED=Time Created -TAG_URGENCY=Urgency -TAG_WRITER=Writer/Editor diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/JpegMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/en/JpegMarkernote.txt deleted file mode 100644 index 826070ddcf..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/JpegMarkernote.txt +++ /dev/null @@ -1,12 +0,0 @@ -# This file contains label of property for MetaDataExtractor -TEST=For testing. Do not remove -MARKER_NOTE_NAME=Jpeg Makernote -TAG_JPEG_COMMENT=Jpeg Comment -TAG_JPEG_COMPONENT_DATA_1=Component 1 -TAG_JPEG_COMPONENT_DATA_2=Component 2 -TAG_JPEG_COMPONENT_DATA_3=Component 3 -TAG_JPEG_COMPONENT_DATA_4=Component 4 -TAG_JPEG_DATA_PRECISION=Data Precision -TAG_JPEG_IMAGE_HEIGHT=Image Height -TAG_JPEG_IMAGE_WIDTH=Image Width -TAG_JPEG_NUMBER_OF_COMPONENTS=Number of Components diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/KodakMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/en/KodakMarkernote.txt deleted file mode 100644 index 90775151db..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/KodakMarkernote.txt +++ /dev/null @@ -1,3 +0,0 @@ -# This file contains label of property for MetaDataExtractor -TEST=For testing. Do not remove -MARKER_NOTE_NAME=Kodak Makernote diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/KyoceraMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/en/KyoceraMarkernote.txt deleted file mode 100644 index a81a04bad0..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/KyoceraMarkernote.txt +++ /dev/null @@ -1,5 +0,0 @@ -# This file contains label of property for MetaDataExtractor -TEST=For testing. Do not remove -MARKER_NOTE_NAME=Kyocera Makernote -TAG_KYOCERA_PRINT_IMAGE_MATCHING_INFO=Print Image Matching (PIM) Info -TAG_KYOCERA_PROPRIETARY_THUMBNAIL=Proprietary Thumbnail Format Data diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/NikonTypeMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/en/NikonTypeMarkernote.txt deleted file mode 100644 index e6a6a2c427..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/NikonTypeMarkernote.txt +++ /dev/null @@ -1,69 +0,0 @@ -# This file contains label of property for MetaDataExtractor -TEST=For testing. Do not remove -MARKER_NOTE_NAME=Nikon Makernote -TAG_NIKON_TYPE1_CCD_SENSITIVITY=CCD Sensitivity -TAG_NIKON_TYPE1_COLOR_MODE=Color Mode -TAG_NIKON_TYPE1_CONVERTER=Fisheye Converter -TAG_NIKON_TYPE1_DIGITAL_ZOOM=Digital Zoom -TAG_NIKON_TYPE1_FOCUS=Focus -TAG_NIKON_TYPE1_IMAGE_ADJUSTMENT=Image Adjustment -TAG_NIKON_TYPE1_QUALITY=Quality -TAG_NIKON_TYPE1_UNKNOWN_1=Makernote Unknown 1 -TAG_NIKON_TYPE1_UNKNOWN_2=Makernote Unknown 2 -TAG_NIKON_TYPE1_UNKNOWN_3=Makernote Unknown 3 -TAG_NIKON_TYPE1_WHITE_BALANCE=White Balance -TAG_NIKON_TYPE2_ADAPTER=Adapter -TAG_NIKON_TYPE2_AF_FOCUS_POSITION=AF Focus Position -TAG_NIKON_TYPE2_AF_TYPE=AF Type -TAG_NIKON_TYPE2_AUTO_FLASH_COMPENSATION=Auto Flash Compensation -TAG_NIKON_TYPE2_AUTO_FLASH_MODE=Auto Flash Mode -TAG_NIKON_TYPE2_CAMERA_COLOR_MODE=Colour Mode -TAG_NIKON_TYPE2_CAMERA_HUE_ADJUSTMENT=Camera Hue Adjustment -TAG_NIKON_TYPE2_CAMERA_SHARPENING=Sharpening -TAG_NIKON_TYPE2_CAMERA_TONE_COMPENSATION=Tone Compensation -TAG_NIKON_TYPE2_CAMERA_WHITE_BALANCE=White Balance -TAG_NIKON_TYPE2_CAMERA_WHITE_BALANCE_FINE=White Balance Fine -TAG_NIKON_TYPE2_CAMERA_WHITE_BALANCE_RB_COEFF=White Balance RB Coefficients -TAG_NIKON_TYPE2_CAPTURE_EDITOR_DATA=Capture Editor Data -TAG_NIKON_TYPE2_COLOR_MODE=Color Mode -TAG_NIKON_TYPE2_DATA_DUMP=Data Dump -TAG_NIKON_TYPE2_DIGITAL_ZOOM=Digital Zoom -TAG_NIKON_TYPE2_EXPOSURE_SEQUENCE_NUMBER=Exposure Sequence Number -TAG_NIKON_TYPE2_FIRMWARE_VERSION=Firmware Version -TAG_NIKON_TYPE2_FLASH_SYNC_MODE=Flash Sync Mode -TAG_NIKON_TYPE2_IMAGE_ADJUSTMENT=Image Adjustment -TAG_NIKON_TYPE2_ISO_1=ISO -TAG_NIKON_TYPE2_ISO_2=ISO -TAG_NIKON_TYPE2_ISO_SELECTION=ISO Selection -TAG_NIKON_TYPE2_LENS=Lens -TAG_NIKON_TYPE2_LIGHT_SOURCE=Light source -TAG_NIKON_TYPE2_MANUAL_FOCUS_DISTANCE=Manual Focus Distance -TAG_NIKON_TYPE2_NOISE_REDUCTION=Noise Reduction -TAG_NIKON_TYPE2_QUALITY_AND_FILE_FORMAT=Quality & File Format -TAG_NIKON_TYPE2_UNKNOWN_11=Unknown 11 -TAG_NIKON_TYPE2_UNKNOWN_12=Unknown 12 -TAG_NIKON_TYPE2_UNKNOWN_13=Unknown 13 -TAG_NIKON_TYPE2_UNKNOWN_14=Unknown 14 -TAG_NIKON_TYPE2_UNKNOWN_15=Unknown 15 -TAG_NIKON_TYPE2_UNKNOWN_16=Unknown 16 -TAG_NIKON_TYPE2_UNKNOWN_1=Unknown 01 -TAG_NIKON_TYPE2_UNKNOWN_20=Unknown 20 -TAG_NIKON_TYPE2_UNKNOWN_21=Unknown 21 -TAG_NIKON_TYPE2_UNKNOWN_22=Unknown 22 -TAG_NIKON_TYPE2_UNKNOWN_23=Unknown 23 -TAG_NIKON_TYPE2_UNKNOWN_24=Unknown 24 -TAG_NIKON_TYPE2_UNKNOWN_25=Unknown 25 -TAG_NIKON_TYPE2_UNKNOWN_26=Unknown 26 -TAG_NIKON_TYPE2_UNKNOWN_27=Unknown 27 -TAG_NIKON_TYPE2_UNKNOWN_29=Unknown 29 -TAG_NIKON_TYPE2_UNKNOWN_2=Unknown 02 -TAG_NIKON_TYPE2_UNKNOWN_30=Unknown 30 -TAG_NIKON_TYPE2_UNKNOWN_32=Unknown 32 -TAG_NIKON_TYPE2_UNKNOWN_33=Unknown 33 -TAG_NIKON_TYPE2_UNKNOWN_34=Unknown 34 -TAG_NIKON_TYPE2_UNKNOWN_3=Unknown 03 -TAG_NIKON_TYPE2_UNKNOWN_4=Unknown 04 -TAG_NIKON_TYPE2_UNKNOWN_5=Unknown 05 -TAG_NIKON_TYPE2_UNKNOWN_7=Unknown 07 -TAG_NIKON_TYPE2_UNKNOWN_8=Unknown 08 -TAG_NIKON_TYPE2_UNKNOWN_9=Unknown 09 diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/OlympusMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/en/OlympusMarkernote.txt deleted file mode 100644 index 74ed29afe5..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/OlympusMarkernote.txt +++ /dev/null @@ -1,50 +0,0 @@ -# This file contains label of property for MetaDataExtractor -TEST=For testing. Do not remove -MARKER_NOTE_NAME=Olympus Makernote -TAG_OLYMPUS_BLACK_LEVEL=Black Level -TAG_OLYMPUS_BLUE_BIAS=Blue Bias -TAG_OLYMPUS_BRACKET=Bracket -TAG_OLYMPUS_CAMERA_ID=Camera Id -TAG_OLYMPUS_CAMERA_SETTINGS_1=Camera Settings (1) -TAG_OLYMPUS_CAMERA_SETTINGS_2=Camera Settings (2) -TAG_OLYMPUS_COLOR_CONTROL=Color Control -TAG_OLYMPUS_COLOR_MATRIX=Color Matrix -TAG_OLYMPUS_COLOR_MODE=Color Mode -TAG_OLYMPUS_COMPRESSED_IMAGE_SIZE=Compressed Image Size -TAG_OLYMPUS_COMPRESSION_RATIO=Compression Ratio -TAG_OLYMPUS_CONTRAST=Contrast -TAG_OLYMPUS_CORING_FILTER=Coring Filter -TAG_OLYMPUS_DATA_DUMP=Data Dump -TAG_OLYMPUS_DIGI_ZOOM_RATIO=Digital Zoom Ratio -TAG_OLYMPUS_FINAL_HEIGHT=Final Height -TAG_OLYMPUS_FINAL_WIDTH=Final Width -TAG_OLYMPUS_FIRMWARE_VERSION=Firmware Version -TAG_OLYMPUS_FLASH_BIAS=Flash Bias -TAG_OLYMPUS_FLASH_MODE=Flash Mode -TAG_OLYMPUS_FOCUS_DISTANCE=Focus Distance -TAG_OLYMPUS_FOCUS_MODE=Focus Mode -TAG_OLYMPUS_IMAGE_HEIGHT=Image Height -TAG_OLYMPUS_IMAGE_WIDTH=Image Width -TAG_OLYMPUS_IMAGE_QUALITY_1=Image Quality (1) -TAG_OLYMPUS_IMAGE_QUALITY_2=Image Quality (2) -TAG_OLYMPUS_JPEG_QUALITY=Jpeg Quality -TAG_OLYMPUS_MACRO_FOCUS=Macro Focus -TAG_OLYMPUS_MACRO_MODE=Macro -TAG_OLYMPUS_MAKERNOTE_VERSION=Makernote Version -TAG_OLYMPUS_MINOLTA_THUMBNAIL_LENGTH=Thumbnail Length -TAG_OLYMPUS_MINOLTA_THUMBNAIL_OFFSET_1=Thumbnail Offset (1) -TAG_OLYMPUS_MINOLTA_THUMBNAIL_OFFSET_2=Thumbnail Offset (2) -TAG_OLYMPUS_ORIGINAL_MANUFACTURER_MODEL=Original Manufacturer Model -TAG_OLYMPUS_PICT_INFO=Pict Info -TAG_OLYMPUS_PRINT_IMAGE_MATCHING_INFO=Print Image Matching (PIM) Info -TAG_OLYMPUS_RED_BIAS=Red Bias -TAG_OLYMPUS_SERIAL_NUMBER=Serial Number -TAG_OLYMPUS_SHARPNESS=Sharpness -TAG_OLYMPUS_SHARPNESS_FACTOR=Sharpness Factor -TAG_OLYMPUS_SPECIAL_MODE=Special Mode -TAG_OLYMPUS_UNKNOWN_1=Unknown 1 -TAG_OLYMPUS_UNKNOWN_2=Unknown 2 -TAG_OLYMPUS_UNKNOWN_3=Unknown 3 -TAG_OLYMPUS_VALID_BITS=Valid Bits -TAG_OLYMPUS_WHITE_BALANCE=White Balance -TAG_OLYMPUS_ZOOM=Zoom \ No newline at end of file diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/PanasonicMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/en/PanasonicMarkernote.txt deleted file mode 100644 index effa56f3ec..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/PanasonicMarkernote.txt +++ /dev/null @@ -1,8 +0,0 @@ -# This file contains label of property for MetaDataExtractor -TEST=For testing. Do not remove -MARKER_NOTE_NAME=Panasonic Makernote -TAG_PANASONIC_MACRO_MODE=Macro Mode -TAG_PANASONIC_PRINT_IMAGE_MATCHING_INFO=Print Image Matching (PIM) Info -TAG_PANASONIC_QUALITY_MODE=Quality Mode -TAG_PANASONIC_RECORD_MODE=Record Mode -TAG_PANASONIC_VERSION=Version diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/PentaxMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/en/PentaxMarkernote.txt deleted file mode 100644 index 0c5ea88713..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/PentaxMarkernote.txt +++ /dev/null @@ -1,17 +0,0 @@ -# This file contains label of property for MetaDataExtractor -TEST=For testing. Do not remove -MARKER_NOTE_NAME=Pentax Makernote -TAG_PENTAX_CAPTURE_MODE=Capture Mode -TAG_PENTAX_COLOR=Color -TAG_PENTAX_CONTRAST=Contrast -TAG_PENTAX_DAYLIGHT_SAVINGS=Daylight Savings -TAG_PENTAX_DIGITAL_ZOOM=Digital Zoom -TAG_PENTAX_FLASH_MODE=Flash Mode -TAG_PENTAX_FOCUS_MODE=Focus Mode -TAG_PENTAX_ISO_SPEED=ISO Speed -TAG_PENTAX_PRINT_IMAGE_MATCHING_INFO=Print Image Matching (PIM) Info -TAG_PENTAX_QUALITY_LEVEL=Quality Level -TAG_PENTAX_SATURATION=Saturation -TAG_PENTAX_SHARPNESS=Sharpness -TAG_PENTAX_TIME_ZONE=Time Zone -TAG_PENTAX_WHITE_BALANCE=White Balance diff --git a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/SonyMarkernote.txt b/ExtLibs/MetaDataExtractorCSharp240d/resources/en/SonyMarkernote.txt deleted file mode 100644 index 97df917464..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/resources/en/SonyMarkernote.txt +++ /dev/null @@ -1,3 +0,0 @@ -# This file contains label of property for MetaDataExtractor -TEST=For testing. Do not remove -MARKER_NOTE_NAME=Sony Makernote diff --git a/ExtLibs/MetaDataExtractorCSharp240d/sampleFile.xml b/ExtLibs/MetaDataExtractorCSharp240d/sampleFile.xml deleted file mode 100644 index 0c105ae518..0000000000 --- a/ExtLibs/MetaDataExtractorCSharp240d/sampleFile.xml +++ /dev/null @@ -1,1044 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - -]> - - - - - Make - Canon - - - Model - Canon EOS 10D - - - Orientation - Top, left side (Horizontal / normal) - - - X Resolution - 180 dots per inches - - - Y Resolution - 180 dots per inches - - - Resolution Unit - Inches - - - Date/Time - 2003:06:21 12:38:51 - - - YCbCr Positioning - Center of pixel array - - - Exposure Time - 1/180 sec - - - F-Number - F 6,7 - - - ISO Speed Ratings - 100 - - - Exif Version - 2.20 - - - Date/Time Original - 2003:06:21 12:38:51 - - - Date/Time Digitized - 2003:06:21 12:38:51 - - - Components Configuration - YCbCr - - - Compressed Bits Per Pixel - 3 bits/pixel - - - Shutter Speed Value - 1/179 sec - - - Aperture Value - F 6,7 - - - Exposure Bias Value - 0 - - - Max Aperture Value - F 4 - - - Metering Mode - Multi-segment - - - Flash - Flash did not fire, Auto - - - Focal Length - 70,0 mm - - - User Comment - - - - FlashPix Version - 1.00 - - - Color Space - sRGB - - - Exif Image Width - 3072 pixels - - - Exif Image Height - 2048 pixels - - - Focal Plane X Resolution - 446/1536000 inches - - - Focal Plane Y Resolution - 119/409600 inches - - - Focal Plane Resolution Unit - Inches - - - Sensing Method - One-chip color area sensor - - - File Source - Digital Still Camera (DSC) - - - Custom Rendered - 0 - - - Exposure Mode - Auto exposure - - - White balance mode - Auto white balance - - - Scene Capture Type - Standard - - - Compression - JPEG (old-style) - - - Thumbnail Offset - 2548 bytes - - - Thumbnail Length - 10752 bytes - - - Thumbnail Data - [10752 bytes of thumbnail data] - - - - - Macro mode - Off - - - Self timer delay - Self timer not used - - - Quality - Fine - - - Flash mode - Auto - - - Continuous drive mode - Single shot - - - Focus mode 1 - AI Focus - - - Image size - Large - - - Easy shooting mode - Full auto - - - Digital zoom - No digital zoom - - - Contrast - Normal - - - Saturation - Normal - - - Sharpness - Normal - - - ISO - Not specified (see ISOSpeedRatings tag) - - - Metering methode - Evaluative - - - Focus type - Auto - - - Exposure mode - Easy shooting - - - Long focal length - 200 1 - - - Short focal length - 70 1 - - - Focal units per mm - 1 - - - Flash activity - Flash did not fire - - - Camera State 1 - 92 0 0 3 1 0 0 2 0 1 0 0 0 0 0 0 0 3 2 16385 0 32767 65535 200 70 1 128 320 0 0 0 0 65535 65535 65535 0 3072 3072 0 65535 65535 0 0 32767 65535 65535 - - - White balance - Auto - - - Sequence number - 0 - - - AF point used - Right - - - Flash bias - 0 EV - - - Auto exposure bracketing - 0 - - - AEB bracket value - 0 - - - Subject distance - 233 - - - Camera State 2 - 66 0 160 248 176 240 0 0 3 0 8 8 0 0 0 0 0 0 1 233 194 172 236 150 0 0 252 0 65535 0 0 0 0 - - - Image type - IMG:EOS 10D JPEG - - - Firware version - Firmware Version 1.0.0 - - - Serial number - 430205259 - - - Image number - 1080891 - - - Owner name - FERRET - - - Custom functions shutter auto exposure - AF/AE lock - - - Custom functions mirror lockup - Disabled - - - Custom functions TV AV and exposure level - 1/2 stop - - - Custom functions AF assist light - On (auto) - - - Custom functions speed in AV mode - Automatic - - - Custom functions bracketting - 0,-,+ / Enabled - - - Custom functions shutter curtain sync - 1st Curtain Sync - - - Custom functions AF stop - AF stop - - - Custom functions fill flash reduction - Enabled - - - Custom functions menu button return - Top - - - Custom functions set button function - Not Assigned - - - Custom functions sensor cleaning - Disabled - - - - - Interoperability Index - Recommended Exif Interoperability Rules (ExifR98) - - - Interoperability Version - 1.00 - - - Related Image Width - 3072 - - - Related Image Length - 2048 - - - - - Caption/Abstract - Iptc caption - - - Writer/Editor - Iptc caption writer - - - Headline - Iptc Headline - - - Special Instructions - Iptc special instruction - - - By-line - Iptc credits - - - By-line Title - Iptc byline title - - - Credit - Iptc credits - - - Source - Iptc source - - - Object Name - Iptc obj name - - - Date Created - 04/03/2006 00:00:00 - - - City - iptc city - - - Province/State - iptc province - - - Country/Primary Location - iptc country - - - Original Transmission Reference - iptc org tr ref - - - Category - Iptc categ - - - Supplemental Category(s) - Iptc sup categ - - - Urgency - High - - - Keywords - keyone, keytwo, keyTree, - - - Copyright Notice - Iptc copyright - - - - - Data Precision - 8 bits - - - Image Height - 2048 pixels - - - Image Width - 3072 pixels - - - Number of Components - 3 - - - Component 1 - Y component: Quantization table 0, Sampling factors 1 horiz/2 vert - - - Component 2 - Cb component: Quantization table 1, Sampling factors 1 horiz/1 vert - - - Component 3 - Cr component: Quantization table 1, Sampling factors 1 horiz/1 vert - - - - - Jpeg Comment - I like to see a dog in action. Relay I like that - - - - - - - - Image Description - OLYMPUS DIGITAL CAMERA - - - Make - OLYMPUS OPTICAL CO.,LTD - - - Model - C3000Z - - - Orientation - Top, left side (Horizontal / normal) - - - X Resolution - 72 dots per inches - - - Y Resolution - 72 dots per inches - - - Resolution Unit - Inches - - - Software - v353p-73 - - - Date/Time - 2002:07:12 16:27:42 - - - YCbCr Positioning - Datum point - - - Exposure Time - 1/30 sec - - - F-Number - F 2,8 - - - Exposure Program - Program normal - - - ISO Speed Ratings - 200 - - - Exif Version - 2.10 - - - Date/Time Original - 2002:07:12 16:27:42 - - - Date/Time Digitized - 2002:07:12 16:27:42 - - - Components Configuration - YCbCr - - - Compressed Bits Per Pixel - 1 bit/pixel - - - Exposure Bias Value - 0 - - - Max Aperture Value - F 2,8 - - - Metering Mode - Multi-segment - - - Flash - Flash did not fire - - - Focal Length - 8,8 mm - - - User Comment - - - - FlashPix Version - 1.00 - - - Color Space - sRGB - - - Exif Image Width - 2048 pixels - - - Exif Image Height - 1536 pixels - - - File Source - Digital Still Camera (DSC) - - - Scene Type - Directly photographed image - - - Compression - JPEG (old-style) - - - Thumbnail Offset - 4084 bytes - - - Thumbnail Length - 4539 bytes - - - Thumbnail Data - [4539 bytes of thumbnail data] - - - - - Special Mode - Normal picture taking mode - Unknown sequence number - - - Jpeg Quality - SQ - - - Macro - Normal (no macro) - - - Digital Zoom Ratio - 1x digital zoom - - - Firmware Version - SX351 - - - Pict Info - [pictureInfo] Resolution=1 [Camera Info] Type=SX351 - - - Camera Id - - - - Data Dump - - - - - - Interoperability Index - Recommended Exif Interoperability Rules (ExifR98) - - - Interoperability Version - 1.00 - - - - - Data Precision - 8 bits - - - Image Height - 1536 pixels - - - Image Width - 2048 pixels - - - Number of Components - 3 - - - Component 1 - Y component: Quantization table 0, Sampling factors 1 horiz/2 vert - - - Component 2 - Cb component: Quantization table 1, Sampling factors 1 horiz/1 vert - - - Component 3 - Cr component: Quantization table 1, Sampling factors 1 horiz/1 vert - - - - - - - - Make - NIKON CORPORATION - - - Model - NIKON D70 - - - Orientation - Top, left side (Horizontal / normal) - - - X Resolution - 300 dots per inches - - - Y Resolution - 300 dots per inches - - - Resolution Unit - Inches - - - Software - Ver.1.03 - - - Date/Time - 2005:06:08 20:17:06 - - - YCbCr Positioning - Datum point - - - Exposure Time - 1/1000 sec - - - F-Number - F 4,5 - - - Exposure Program - Aperture priority - - - Exif Version - 2.21 - - - Date/Time Original - 2005:06:08 20:17:06 - - - Date/Time Digitized - 2005:06:08 20:17:06 - - - Components Configuration - YCbCr - - - Compressed Bits Per Pixel - 1 bit/pixel - - - Exposure Bias Value - 0 - - - Max Aperture Value - F 3,5 - - - Metering Mode - Multi-segment - - - Flash - Flash did not fire - - - Focal Length - 18,0 mm - - - User Comment - - - - Sub-Sec Time - 80 - - - Sub-Sec Time Original - 80 - - - Sub-Sec Time Digitized - 80 - - - FlashPix Version - 1.00 - - - Color Space - sRGB - - - Exif Image Width - 3008 pixels - - - Exif Image Height - 2000 pixels - - - Sensing Method - One-chip color area sensor - - - File Source - Digital Still Camera (DSC) - - - Scene Type - Directly photographed image - - - CFA Pattern - - - - Custom Rendered - 0 - - - Exposure Mode - Auto exposure - - - White balance mode - Auto white balance - - - Digital Zoom Ratio - 1 - - - Focal Length in 35mm Film - 27 mm - - - Scene Capture Type - Standard - - - Gain Control - None - - - Contrast - Soft - - - Saturation - None - - - Sharpness - None - - - Compression - JPEG (old-style) - - - Thumbnail Offset - 28612 bytes - - - Thumbnail Length - 8412 bytes - - - Thumbnail Data - [8412 bytes of thumbnail data] - - - - - Firmware Version - 2.10 - - - ISO - ISO 400 - - - Quality & File Format - BASIC - - - White Balance - AUTO - - - Sharpening - AUTO - - - AF Type - AF-S - - - Flash Sync Mode - NORMAL - - - Auto Flash Mode - - - - White Balance Fine - 0 - - - ISO - 0 400 - - - Tone Compensation - AUTO - - - Lens - 18-70mm f/3-4 - - - Colour Mode - Mode I (sRGB) - - - Light source - NATURAL - - - Camera Hue Adjustment - 0 degrees - - - Noise Reduction - OFF - - - Exposure Sequence Number - 25 - - - - - Interoperability Index - Recommended Exif Interoperability Rules (ExifR98) - - - Interoperability Version - 1.00 - - - - - Data Precision - 8 bits - - - Image Height - 2000 pixels - - - Image Width - 3008 pixels - - - Number of Components - 3 - - - Component 1 - Y component: Quantization table 0, Sampling factors 1 horiz/2 vert - - - Component 2 - Cb component: Quantization table 1, Sampling factors 1 horiz/1 vert - - - Component 3 - Cr component: Quantization table 1, Sampling factors 1 horiz/1 vert - - - - - - diff --git a/ExtLibs/Utilities/CaptureMJPEG.cs b/ExtLibs/Utilities/CaptureMJPEG.cs index 9c68864c50..19ec7eab52 100644 --- a/ExtLibs/Utilities/CaptureMJPEG.cs +++ b/ExtLibs/Utilities/CaptureMJPEG.cs @@ -1,27 +1,32 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Net; +using System.Drawing; +using System.Globalization; using System.IO; +using System.Net; +using System.Text; using System.Threading; using log4net; -using System.Drawing; namespace MissionPlanner.Utilities { public class CaptureMJPEG { private static readonly ILog log = - LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + private static readonly object Sync = new object(); + private static readonly object LifecycleSync = new object(); + + private static Thread asyncthread; + private static HttpWebRequest activeRequest; + private static volatile bool running; - static Thread asyncthread; - static bool running = false; public static string URL = @"http://127.0.0.1:56781/map.jpg"; - static DateTime lastimage = DateTime.Now; - static int fps = 0; + private static DateTime lastimage = DateTime.Now; + private static int fps; private static event EventHandler _onNewImage; + public static event EventHandler onNewImage { add { _onNewImage += value; } @@ -30,200 +35,438 @@ public static event EventHandler onNewImage public static void runAsync() { - while (asyncthread != null && asyncthread.IsAlive) + lock (LifecycleSync) { - running = false; - Thread.Sleep(1); - } + Thread previous; + HttpWebRequest request; + lock (Sync) + { + running = false; + previous = asyncthread; + request = activeRequest; + } - asyncthread = new Thread(new ThreadStart(getUrl)) - { - IsBackground = true, - Priority = ThreadPriority.BelowNormal, - Name = "mjpg stream reader" - }; - - asyncthread.Start(); + AbortRequest(request); + if (previous != null && previous != Thread.CurrentThread && + previous.IsAlive && !previous.Join(TimeSpan.FromSeconds(2))) + { + log.Warn("The previous MJPEG reader did not stop; refusing to start a duplicate reader."); + return; + } + + lock (Sync) + { + running = true; + asyncthread = new Thread(getUrl) + { + IsBackground = true, + Priority = ThreadPriority.BelowNormal, + Name = "mjpg stream reader" + }; + asyncthread.Start(); + } + } } public static void Stop() { - running = false; + HttpWebRequest request; + lock (Sync) + { + running = false; + request = activeRequest; + } + AbortRequest(request); } public static string ReadLine(BinaryReader br) { - StringBuilder sb = new StringBuilder(); + if (br == null) + throw new ArgumentNullException(nameof(br)); - DateTime deadline = DateTime.Now.AddSeconds(5); + return MjpegMultipartReader.ReadAsciiLine(br, MjpegMultipartReader.MaxHeaderLineBytes) + ?? string.Empty; + } - while (DateTime.Now < deadline) { + private static void getUrl() + { + while (running) + { + HttpWebRequest request = null; try { - byte by = br.ReadByte(); - deadline = DateTime.Now.AddSeconds(5); - sb.Append((char) by); - if (by == '\n') - break; - } - catch { } - } +#pragma warning disable SYSLIB0014 + request = (HttpWebRequest)WebRequest.Create(URL); +#pragma warning restore SYSLIB0014 + request.Method = "GET"; + request.KeepAlive = true; + request.AllowReadStreamBuffering = false; + request.AutomaticDecompression = + DecompressionMethods.GZip | DecompressionMethods.Deflate; + request.Headers.Add("Accept-Encoding", "gzip,deflate"); + request.Accept = "multipart/x-mixed-replace"; + request.Timeout = 10000; + request.ReadWriteTimeout = 10000; + + lock (Sync) + { + if (!running) + return; + activeRequest = request; + } - sb = sb.Replace("\r\n", ""); + using (var response = (HttpWebResponse)request.GetResponse()) + using (var dataStream = response.GetResponseStream()) + { + log.Debug(response.StatusDescription); + if (dataStream == null) + throw new InvalidDataException("MJPEG response does not contain a stream."); + + try { dataStream.ReadTimeout = 10000; } + catch (InvalidOperationException) { } - log.Debug(sb.ToString()); + using (var reader = new BinaryReader(dataStream)) + { + var multipart = new MjpegMultipartReader( + reader, response.Headers["Content-Type"] ?? response.ContentType); + byte[] jpeg; + while (running && multipart.TryReadFrame(out jpeg)) + PublishJpeg(jpeg); + } + } + } + catch (WebException ex) + { + if (running) + log.Error(ex); + } + catch (Exception ex) + { + if (running) + log.Error(ex); + } + finally + { + lock (Sync) + { + if (ReferenceEquals(activeRequest, request)) + activeRequest = null; + } + Publish(null); + } - return sb.ToString(); + if (running) + Thread.Sleep(250); + } } - static void getUrl() + private static void PublishJpeg(byte[] jpeg) { - running = true; - - start: + if (jpeg == null || jpeg.Length == 0) + return; try { - // Create a request using a URL that can receive a post. - WebRequest request = HttpWebRequest.Create(URL); - // Set the Method property of the request to POST. - request.Method = "GET"; + using (var stream = new MemoryStream(jpeg, false)) + using (var bitmap = new Bitmap(stream)) + { + fps++; + if (lastimage.Second != DateTime.Now.Second) + { + log.Debug("MJPEG " + fps); + fps = 0; + lastimage = DateTime.Now; + } - ((HttpWebRequest)request).AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; + Publish((Bitmap)bitmap.Clone()); + } + } + catch (Exception ex) + { + log.Info(ex); + } + } - request.Headers.Add("Accept-Encoding", "gzip,deflate"); + private static void Publish(Bitmap bitmap) + { + EventHandler handlers = _onNewImage; + if (handlers == null) + return; - // Get the response. - WebResponse response = request.GetResponse(); - // Display the status. - log.Debug(((HttpWebResponse)response).StatusDescription); - // Get the stream containing content returned by the server. - Stream dataStream = response.GetResponseStream(); + foreach (EventHandler handler in handlers.GetInvocationList()) + { + try { handler(null, bitmap); } + catch (Exception ex) { log.Warn("MJPEG frame subscriber failed", ex); } + } + } - BinaryReader br = new BinaryReader(dataStream); + private static void AbortRequest(HttpWebRequest request) + { + if (request == null) + return; - // get boundary header + try { request.Abort(); } + catch (Exception ex) { log.Debug("Unable to abort MJPEG request", ex); } + } + } - string mpheader = response.Headers["Content-Type"]; - if (mpheader.IndexOf("boundary=") == -1) - { - ReadLine(br); // this is a blank line - string line = "proxyline"; - do - { - line = ReadLine(br); - if (line.StartsWith("--")) - { - mpheader = line; - break; - } - } while (line.Length > 2); - } - else - { - int startboundary = mpheader.IndexOf("boundary=") + 9; - int endboundary = mpheader.Length; + internal sealed class MjpegMultipartReader + { + internal const int MaxHeaderLineBytes = 16 * 1024; + internal const int DefaultMaxFrameBytes = 32 * 1024 * 1024; + private const int MaxHeaderBytes = 64 * 1024; + private const int MaxBoundaryBytes = 256; + + private readonly BinaryReader _reader; + private readonly string _boundary; + private readonly int _maxFrameBytes; + private bool _atHeaders; + private bool _completed; + + internal MjpegMultipartReader(BinaryReader reader, string contentType, + int maxFrameBytes = DefaultMaxFrameBytes) + { + _reader = reader ?? throw new ArgumentNullException(nameof(reader)); + if (maxFrameBytes <= 0) + throw new ArgumentOutOfRangeException(nameof(maxFrameBytes)); + _maxFrameBytes = maxFrameBytes; - mpheader = mpheader.Substring(startboundary, endboundary - startboundary); - } + _boundary = ExtractBoundary(contentType); + if (string.IsNullOrEmpty(_boundary)) + { + _boundary = DetectBoundaryFromBody(reader); + _atHeaders = true; + } + } - dataStream.ReadTimeout = 10000; // 10 seconds - br.BaseStream.ReadTimeout = 10000; + internal bool TryReadFrame(out byte[] frame) + { + frame = null; + if (_completed) + return false; + + if (!_atHeaders && !SeekToBoundary()) + { + _completed = true; + return false; + } + _atHeaders = false; - while (running) + Dictionary headers = ReadHeaders(); + string lengthText; + if (headers.TryGetValue("Content-Length", out lengthText)) + { + int length; + if (!int.TryParse(lengthText, NumberStyles.None, CultureInfo.InvariantCulture, + out length) || length <= 0) { - try - { - // get the multipart start header - int length = int.Parse(getHeader(br)["Content-Length"]); + throw new InvalidDataException("Invalid MJPEG Content-Length: " + lengthText); + } + if (length > _maxFrameBytes) + throw new InvalidDataException("MJPEG frame exceeds the configured size limit."); - // read boundary header - if (length > 0) - { - byte[] buf1 = new byte[length]; + frame = ReadExact(length); + return true; + } - dataStream.ReadTimeout = 3000; + frame = ReadUntilNextBoundary(); + return true; + } - int offset = 0; - int len = 0; + internal static string ExtractBoundary(string contentType) + { + if (string.IsNullOrWhiteSpace(contentType)) + return null; - while (length > 0 && (len = br.Read(buf1, offset, length)) >= 0) - { - offset += len; - length -= len; - } - /* - BinaryWriter sw = new BinaryWriter(File.OpenWrite("test.jpg")); + string[] parts = contentType.Split(';'); + for (int index = 1; index < parts.Length; index++) + { + string part = parts[index].Trim(); + int equals = part.IndexOf('='); + if (equals <= 0 || !part.Substring(0, equals).Trim().Equals( + "boundary", StringComparison.OrdinalIgnoreCase)) + continue; + + string value = part.Substring(equals + 1).Trim(); + if (value.Length >= 2 && + ((value[0] == '"' && value[value.Length - 1] == '"') || + (value[0] == '\'' && value[value.Length - 1] == '\''))) + { + value = value.Substring(1, value.Length - 2); + } - sw.Write(buf1,0,buf1.Length); + if (value.Length == 0 || value.IndexOfAny(new[] { '\r', '\n' }) >= 0) + throw new InvalidDataException("Invalid MJPEG boundary."); + return ValidateBoundary(value); + } - sw.Close(); - */ - try - { - System.Drawing.Bitmap frame = new System.Drawing.Bitmap(new MemoryStream(buf1)); + return null; + } - fps++; + internal static string DetectBoundaryFromBody(BinaryReader reader) + { + string line; + while ((line = ReadAsciiLine(reader, MaxHeaderLineBytes)) != null) + { + if (!line.StartsWith("--", StringComparison.Ordinal) || line.Length <= 2) + continue; + + string token = line.Substring(2); + if (token.EndsWith("--", StringComparison.Ordinal)) + token = token.Substring(0, token.Length - 2); + if (token.Length > 0) + return ValidateBoundary(token); + } - if (lastimage.Second != DateTime.Now.Second) - { - Console.WriteLine("MJPEG " + fps); - fps = 0; - lastimage = DateTime.Now; - } + throw new EndOfStreamException("Could not detect an MJPEG boundary in the response."); + } - _onNewImage?.Invoke(null, frame); - } - catch { } - } - else - { - throw new Exception("No mjpeg length header"); - } + private static string ValidateBoundary(string boundary) + { + if (Encoding.ASCII.GetByteCount(boundary) > MaxBoundaryBytes) + throw new InvalidDataException("MJPEG boundary exceeds the configured size limit."); + for (int index = 0; index < boundary.Length; index++) + { + if (boundary[index] < 0x20 || boundary[index] > 0x7e) + throw new InvalidDataException("MJPEG boundary contains invalid characters."); + } + return boundary; + } - // blank line at end of data - System.Threading.Thread.Sleep(1); - ReadLine(br); - } - catch (Exception ex) { log.Info(ex); break; } - } + internal static string ReadAsciiLine(BinaryReader reader, int maxBytes) + { + var bytes = new List(); + while (bytes.Count <= maxBytes) + { + int value; + try { value = reader.ReadByte(); } + catch (EndOfStreamException) { value = -1; } - // clear last image - _onNewImage?.Invoke(null, null); + if (value < 0) + return bytes.Count == 0 ? null : Encoding.ASCII.GetString(bytes.ToArray()); + if (value == '\n') + { + if (bytes.Count > 0 && bytes[bytes.Count - 1] == '\r') + bytes.RemoveAt(bytes.Count - 1); + return Encoding.ASCII.GetString(bytes.ToArray()); + } + bytes.Add((byte)value); + } - dataStream.Close(); - response.Close(); + throw new InvalidDataException("MJPEG header line exceeds the configured size limit."); + } + private bool SeekToBoundary() + { + string delimiter = "--" + _boundary; + string line; + while ((line = ReadAsciiLine(_reader, MaxHeaderLineBytes)) != null) + { + if (line.Equals(delimiter, StringComparison.Ordinal)) + return true; + if (line.Equals(delimiter + "--", StringComparison.Ordinal)) + return false; } - catch (Exception ex) { log.Error(ex); } + return false; + } - // dont stop trying until we are told to stop - if (running) - goto start; + private Dictionary ReadHeaders() + { + var headers = new Dictionary(StringComparer.OrdinalIgnoreCase); + int totalBytes = 0; + string line; + while ((line = ReadAsciiLine(_reader, MaxHeaderLineBytes)) != null) + { + totalBytes += line.Length + 2; + if (totalBytes > MaxHeaderBytes) + throw new InvalidDataException("MJPEG headers exceed the configured size limit."); + if (line.Length == 0) + return headers; + + int colon = line.IndexOf(':'); + if (colon <= 0) + continue; + headers[line.Substring(0, colon).Trim()] = line.Substring(colon + 1).Trim(); + } - running = false; + throw new EndOfStreamException("MJPEG stream ended while reading part headers."); } - static Dictionary getHeader(BinaryReader stream) + private byte[] ReadExact(int length) { - Dictionary answer = new Dictionary(); + var bytes = new byte[length]; + int offset = 0; + while (offset < length) + { + int read = _reader.Read(bytes, offset, length - offset); + if (read <= 0) + throw new EndOfStreamException( + "MJPEG stream ended before the Content-Length body was complete."); + offset += read; + } + return bytes; + } - string line; + private byte[] ReadUntilNextBoundary() + { + byte[] separator = Encoding.ASCII.GetBytes("\n--" + _boundary); + int[] failure = BuildFailureTable(separator); + int matched = 0; - do + using (var frame = new MemoryStream()) { - line = ReadLine(stream); - - string[] items = line.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries); + while (true) + { + int value; + try { value = _reader.ReadByte(); } + catch (EndOfStreamException) + { + throw new EndOfStreamException( + "MJPEG stream ended before the next multipart boundary."); + } + byte current = (byte)value; + frame.WriteByte(current); + while (matched > 0 && current != separator[matched]) + matched = failure[matched - 1]; + if (current == separator[matched]) + matched++; - if (items.Length == 2) - answer.Add(items[0].Trim(), items[1].Trim()); + if (matched == separator.Length) + { + frame.SetLength(frame.Length - separator.Length); + if (frame.Length > 0) + { + byte[] buffer = frame.GetBuffer(); + if (buffer[frame.Length - 1] == '\r') + frame.SetLength(frame.Length - 1); + } - } while (line != ""); + string suffix = ReadAsciiLine(_reader, MaxHeaderLineBytes) ?? string.Empty; + _completed = suffix.Trim().Equals("--", StringComparison.Ordinal); + _atHeaders = !_completed; + return frame.ToArray(); + } - return answer; + if (frame.Length > _maxFrameBytes + separator.Length) + throw new InvalidDataException("MJPEG frame exceeds the configured size limit."); + } + } } + private static int[] BuildFailureTable(byte[] pattern) + { + var table = new int[pattern.Length]; + int matched = 0; + for (int index = 1; index < pattern.Length; index++) + { + while (matched > 0 && pattern[index] != pattern[matched]) + matched = table[matched - 1]; + if (pattern[index] == pattern[matched]) + matched++; + table[index] = matched; + } + return table; + } } -} \ No newline at end of file +} diff --git a/ExtLibs/Utilities/Crypto.cs b/ExtLibs/Utilities/Crypto.cs index 6cf27259c2..d7475fdb3c 100644 --- a/ExtLibs/Utilities/Crypto.cs +++ b/ExtLibs/Utilities/Crypto.cs @@ -10,7 +10,7 @@ namespace MissionPlanner.Utilities { public sealed class Crypto : IDisposable { - private static readonly byte[] Key = + private static readonly byte[] DefaultKey = { 0xd1, 0x3c, 0x35, 0x6f, 0xb5, 0xd, 0x87, 0xf0, 0x92, 0x07, 0x6d, 0xab, 0x76, 0x82, 0x36, 0xa, @@ -18,7 +18,7 @@ public sealed class Crypto : IDisposable 0xa4, 0x04, 0x11, 0x46, 0x68, 0x2d, 0x48, 0xa1 }; - private static readonly byte[] IV = + private static readonly byte[] DefaultIV = { 0x6d, 0x2d, 0xf5, 0x34, 0xc7, 0x60, 0xc5, 0x33, 0xe2, 0xa3, 0xd7, 0xc3, 0xf3, 0x39, 0xf2, 0x16 @@ -33,31 +33,99 @@ public sealed class Crypto : IDisposable /// Default constructor ///
public Crypto() + : this(CreateLegacyMaterial(FirstPhysicalAddress())) { + } + + private Crypto(KeyMaterial material) + : this(material.Key, material.IV) + { + } + + internal Crypto(byte[] key, byte[] iv) + { + if (key == null || key.Length != 32) + throw new ArgumentException("A 256-bit key is required.", nameof(key)); + if (iv == null || iv.Length != 16) + throw new ArgumentException("A 128-bit IV is required.", nameof(iv)); + + this.algorithm = new RijndaelManaged(); + this.algorithm.Mode = CipherMode.CBC; + this.algorithm.Padding = PaddingMode.PKCS7; + this.algorithm.Key = (byte[]) key.Clone(); + this.algorithm.IV = (byte[]) iv.Clone(); + } + + internal static IReadOnlyList CreateLegacyCandidates() + { + var candidates = new List(); + var seen = new HashSet(StringComparer.Ordinal); + try { - var macAddr = ( - from nic in NetworkInterface.GetAllNetworkInterfaces() - // where nic.OperationalStatus == OperationalStatus.Up - select nic.GetPhysicalAddress() - ).FirstOrDefault(); + foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces()) + { + byte[] address = nic.GetPhysicalAddress()?.GetAddressBytes(); + AddLegacyCandidate(candidates, seen, address); + } + } + catch + { + // The historical implementation silently used the built-in material when network + // adapter enumeration failed, so retain that as a migration candidate. + } - var bytes = macAddr.GetAddressBytes(); + AddLegacyCandidate(candidates, seen, null); + return candidates; + } - Array.Copy(bytes, IV, bytes.Length); + private static void AddLegacyCandidate( + ICollection candidates, ISet seen, byte[] address) + { + KeyMaterial material = CreateLegacyMaterial(address); + string identity = Convert.ToBase64String(material.Key) + ":" + + Convert.ToBase64String(material.IV); + if (seen.Add(identity)) + candidates.Add(new Crypto(material)); + } - Array.Copy(bytes, Key, bytes.Length); + private static byte[] FirstPhysicalAddress() + { + try + { + PhysicalAddress address = NetworkInterface.GetAllNetworkInterfaces() + .Select(nic => nic.GetPhysicalAddress()).FirstOrDefault(); + return address?.GetAddressBytes(); } catch { + return null; } + } + private static KeyMaterial CreateLegacyMaterial(byte[] address) + { + byte[] key = (byte[]) DefaultKey.Clone(); + byte[] iv = (byte[]) DefaultIV.Clone(); + if (address != null) + { + Array.Copy(address, 0, key, 0, Math.Min(address.Length, key.Length)); + Array.Copy(address, 0, iv, 0, Math.Min(address.Length, iv.Length)); + } - this.algorithm = new RijndaelManaged(); - this.algorithm.Mode = CipherMode.CBC; - this.algorithm.Padding = PaddingMode.PKCS7; - this.algorithm.Key = Key; - this.algorithm.IV = IV; + return new KeyMaterial(key, iv); + } + + private sealed class KeyMaterial + { + public KeyMaterial(byte[] key, byte[] iv) + { + Key = key; + IV = iv; + } + + public byte[] Key { get; } + public byte[] IV { get; } } /// @@ -183,4 +251,4 @@ public string DecryptString(string encyptedText) return Encoding.UTF8.GetString(DecryptBuffer(Convert.FromBase64String(encyptedText))); } } -} \ No newline at end of file +} diff --git a/ExtLibs/Utilities/Download.cs b/ExtLibs/Utilities/Download.cs index 4b1318221e..b2b006f231 100644 --- a/ExtLibs/Utilities/Download.cs +++ b/ExtLibs/Utilities/Download.cs @@ -38,8 +38,6 @@ public class DownloadStream : Stream string _uri = ""; public int chunksize { get; set; } = 1000 * 250; - static HttpClient client = new HttpClient(); - private static object _lock = new object(); /// /// static global cache of instance cache @@ -94,8 +92,6 @@ static void expireCache() static DownloadStream() { _timer = new Timer(a => { expireCache(); }, null, 1000 * 30, 1000 * 30); - if (!String.IsNullOrEmpty(Settings.Instance.UserAgent)) - client.DefaultRequestHeaders.Add("User-Agent", Settings.Instance.UserAgent); } public DownloadStream(string uri) @@ -240,19 +236,35 @@ private void GetChunk(long start) var end = Math.Min(Length, start + chunksize); // cache it - var request = new HttpRequestMessage() {RequestUri = new Uri(_uri)}; - request.Headers.Range = new RangeHeaderValue(start, end); + using (var request = new HttpRequestMessage(HttpMethod.Get, _uri)) + { + request.Headers.Range = new RangeHeaderValue(start, end); - Console.WriteLine("{0}: {1} - {2} {3}", _uri, start, end, end-start); + Console.WriteLine("{0}: {1} - {2} {3}", _uri, start, end, end-start); - MemoryStream ms = new MemoryStream(); - using (Stream stream = client.SendAsync(request).GetAwaiter().GetResult().Content.ReadAsStreamAsync().GetAwaiter().GetResult()) - { - stream.CopyTo(ms); + MemoryStream ms = null; + try + { + using (HttpResponseMessage response = Download.SharedClient.SendAsync( + request, HttpCompletionOption.ResponseHeadersRead).GetAwaiter().GetResult()) + { + response.EnsureSuccessStatusCode(); + using (Stream stream = response.Content.ReadAsStreamAsync().GetAwaiter().GetResult()) + { + ms = new MemoryStream(); + stream.CopyTo(ms); + } - lock (_lock) + lock (_lock) + { + _chunks[start] = ms; + ms = null; + } + } + } + finally { - _chunks[start] = ms; + ms?.Dispose(); } } } @@ -303,22 +315,54 @@ public class Download private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - public static async Task PostAsync(string uri, string data) + internal static readonly HttpClient SharedClient = CreateSharedClient(); + + private static HttpClient CreateSharedClient() { - var httpClient = new HttpClient(); - var response = await httpClient.PostAsync(uri, new StringContent(data)); + var httpClient = new HttpClient {Timeout = TimeSpan.FromSeconds(30)}; + if (!String.IsNullOrWhiteSpace(Settings.Instance.UserAgent)) + httpClient.DefaultRequestHeaders.TryAddWithoutValidation( + "User-Agent", Settings.Instance.UserAgent); + return httpClient; + } - response.EnsureSuccessStatusCode(); + public static async Task PostAsync(string uri, string data) + { + return await PostAsync(SharedClient, uri, data).ConfigureAwait(false); + } - string content = await response.Content.ReadAsStringAsync(); - return await Task.Run(() => (content)); + internal static async Task PostAsync(HttpClient httpClient, string uri, string data) + { + if (httpClient == null) + throw new ArgumentNullException(nameof(httpClient)); + using (var request = new HttpRequestMessage(HttpMethod.Post, uri)) + { + request.Content = new StringContent(data ?? ""); + using (HttpResponseMessage response = + await httpClient.SendAsync(request).ConfigureAwait(false)) + { + response.EnsureSuccessStatusCode(); + return await response.Content.ReadAsStringAsync().ConfigureAwait(false); + } + } } public static async Task GetAsync(string uri) { - var httpClient = new HttpClient(); - var content = await httpClient.GetStringAsync(uri); - return await Task.Run(() => (content)); + return await GetAsync(SharedClient, uri).ConfigureAwait(false); + } + + internal static async Task GetAsync(HttpClient httpClient, string uri) + { + if (httpClient == null) + throw new ArgumentNullException(nameof(httpClient)); + using (var request = new HttpRequestMessage(HttpMethod.Get, uri)) + using (HttpResponseMessage response = + await httpClient.SendAsync(request).ConfigureAwait(false)) + { + response.EnsureSuccessStatusCode(); + return await response.Content.ReadAsStringAsync().ConfigureAwait(false); + } } public struct HTTPResult @@ -332,104 +376,159 @@ public struct HTTPResult /// public static async Task GetAsyncWithStatus(string uri) { - var httpClient = new HttpClient(); - var response = await httpClient.GetAsync(uri); - var content = await response.Content.ReadAsStringAsync(); - return await Task.Run(() => (new HTTPResult() { content = content, status = response.StatusCode })); + return await GetAsyncWithStatus(SharedClient, uri, null).ConfigureAwait(false); + } + + internal static async Task GetAsyncWithStatus( + string uri, Action configureRequest) + { + return await GetAsyncWithStatus( + SharedClient, uri, configureRequest).ConfigureAwait(false); + } + + internal static async Task GetAsyncWithStatus( + HttpClient httpClient, string uri, Action configureRequest = null) + { + if (httpClient == null) + throw new ArgumentNullException(nameof(httpClient)); + using (var request = new HttpRequestMessage(HttpMethod.Get, uri)) + { + configureRequest?.Invoke(request); + using (HttpResponseMessage response = + await httpClient.SendAsync(request).ConfigureAwait(false)) + { + string content = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + return new HTTPResult {content = content, status = response.StatusCode}; + } + } } public static event EventHandler RequestModification; public static async Task getFilefromNetAsync(string url, string saveto, Action status = null) { + string temporaryPath = saveto + ".new"; + bool completed = false; + try { log.Info("Get " + url); - var request = new HttpRequestMessage(HttpMethod.Get, url); + string parent = Path.GetDirectoryName(Path.GetFullPath(saveto)); + if (!Directory.Exists(parent)) + Directory.CreateDirectory(parent); - RequestModification?.Invoke(url, request); + if (File.Exists(temporaryPath)) + File.Delete(temporaryPath); - using (var response = await client.SendAsync(request, completionOption: HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false)) + using (var request = new HttpRequestMessage(HttpMethod.Get, url)) { - lock (log) - log.Info(url + " " +(response).StatusCode.ToString()); - if ((response).StatusCode != HttpStatusCode.OK) - return false; + RequestModification?.Invoke(url, request); - if (File.Exists(saveto)) + using (var response = await SharedClient.SendAsync( + request, completionOption: HttpCompletionOption.ResponseHeadersRead) + .ConfigureAwait(false)) { - DateTime lastfilewrite = new FileInfo(saveto).LastWriteTime; - DateTime lasthttpmod = response.Content.Headers.LastModified.HasValue - ? response.Content.Headers.LastModified.Value.DateTime - : DateTime.MinValue; + lock (log) + log.Info(url + " " + response.StatusCode); + if (!response.IsSuccessStatusCode) + return false; - if (lasthttpmod < lastfilewrite) + if (File.Exists(saveto)) { - if ((response).Content.Headers.ContentLength == new FileInfo(saveto).Length) + FileInfo existingFile = new FileInfo(saveto); + DateTime lastHttpModification = response.Content.Headers.LastModified.HasValue + ? response.Content.Headers.LastModified.Value.DateTime + : DateTime.MinValue; + + if (lastHttpModification < existingFile.LastWriteTime && + response.Content.Headers.ContentLength == existingFile.Length) { lock (log) log.Info(url + " " + "got LastModified " + saveto + " " + - (response).Content.Headers.LastModified + - " vs " + new FileInfo(saveto).LastWriteTime); - response.Dispose(); + response.Content.Headers.LastModified + + " vs " + existingFile.LastWriteTime); + completed = true; return true; } } - } - - int size = 0; - using (Stream resstream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) - using (FileStream fs = new FileStream(saveto + ".new", FileMode.Create)) - { - byte[] buf1 = new byte[1024]; - DateTime lastupdate = DateTime.MinValue; - DateTime starttime = DateTime.Now; - var contlen = response.Content.Headers.ContentLength; - - while (resstream.CanRead) + long size = 0; + long? contentLength = response.Content.Headers.ContentLength; + using (Stream responseStream = + await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) + using (FileStream fileStream = new FileStream( + temporaryPath, FileMode.Create, FileAccess.Write, FileShare.None, + bufferSize: 81920, useAsync: true)) { - int len = await resstream.ReadAsync(buf1, 0, 1024).ConfigureAwait(false); - if (len == 0) - break; - fs.Write(buf1, 0, len); - - size += len; + byte[] buffer = new byte[81920]; + DateTime lastUpdate = DateTime.MinValue; + DateTime startTime = DateTime.UtcNow; - var elapsed = (DateTime.Now - starttime).TotalSeconds; - var percent = ((size / (float) contlen) * 100.0f); - if (lastupdate.Second != DateTime.Now.Second) + while (true) { - lastupdate = DateTime.Now; - log.InfoFormat("{0} bps {1} {2}s {3}% of {4} \r", size / elapsed, size, elapsed, - percent, contlen); - var timeleft = TimeSpan.FromSeconds(((elapsed / percent) * (100 - percent))); - status?.Invoke((int) percent, - "Downloading.. ETA: " + - //DateTime.Now.AddSeconds(((elapsed / percent) * (100 - percent))).ToShortTimeString() - formatTimeSpan(timeleft) - ); + int length = await responseStream.ReadAsync( + buffer, 0, buffer.Length).ConfigureAwait(false); + if (length == 0) + break; + + await fileStream.WriteAsync( + buffer, 0, length).ConfigureAwait(false); + size += length; + + DateTime now = DateTime.UtcNow; + if ((now - lastUpdate).TotalSeconds < 1) + continue; + + lastUpdate = now; + double elapsedSeconds = Math.Max( + (now - startTime).TotalSeconds, 0.001); + if (contentLength.GetValueOrDefault() > 0) + { + double percent = Math.Min( + 100.0, size * 100.0 / contentLength.Value); + double remainingSeconds = percent > 0 + ? elapsedSeconds / percent * (100 - percent) + : 0; + log.InfoFormat( + "{0} bps {1} {2}s {3}% of {4} \r", + size / elapsedSeconds, size, elapsedSeconds, percent, + contentLength.Value); + status?.Invoke((int)percent, + "Downloading.. ETA: " + + formatTimeSpan(TimeSpan.FromSeconds(remainingSeconds))); + } + else + { + log.InfoFormat( + "{0} bps {1} {2}s (unknown length) \r", + size / elapsedSeconds, size, elapsedSeconds); + status?.Invoke(-1, "Downloading.. " + size + " bytes"); + } } } - fs.Flush(); - fs.Close(); - } + if (contentLength.HasValue && size != contentLength.Value) + { + log.Info("getFilefromNetAsync(): File size mismatch " + size + + " vs " + contentLength.Value); + return false; + } - log.Info("Got " + url + " " + size); + log.Info("Got " + url + " " + size); - if (File.Exists(saveto)) - { - // try prevent System.UnauthorizedAccessException: Access to the path - GC.Collect(); - File.SetAttributes(saveto, FileAttributes.Normal); - File.Delete(saveto); - } + if (File.Exists(saveto)) + { + File.SetAttributes(saveto, FileAttributes.Normal); + File.Delete(saveto); + } - File.Move(saveto + ".new", saveto); + File.Move(temporaryPath, saveto); + status?.Invoke(100, "Complete"); + completed = true; - return true; + return true; + } } } catch (Exception ex) @@ -438,139 +537,51 @@ public static async Task getFilefromNetAsync(string url, string saveto, Ac log.Info("getFilefromNetAsync(): " + ex.ToString()); return false; } - } - - static Download() - { - if (!String.IsNullOrEmpty(Settings.Instance.UserAgent)) - client.DefaultRequestHeaders.Add("User-Agent", Settings.Instance.UserAgent); - } - - static HttpClient client = new HttpClient(); - public static bool getFilefromNet(string url, string saveto, Action status = null) - { - try + finally { - lock (log) - log.Info(url); - var client = new HttpClient(); - client.DefaultRequestHeaders.Add("User-Agent", Settings.Instance.UserAgent); - client.Timeout = TimeSpan.FromSeconds(30); - - // Get the response. - var response = client.GetAsync(url, completionOption: HttpCompletionOption.ResponseHeadersRead).Result; - // Display the status. - lock (log) - log.Info(response.ReasonPhrase); - if (!response.IsSuccessStatusCode) - return false; - - if (File.Exists(saveto)) + if (!completed && File.Exists(temporaryPath)) { - DateTime lastfilewrite = new FileInfo(saveto).LastWriteTime; - DateTime lasthttpmod = response.Content.Headers.LastModified(); - - if (lasthttpmod < lastfilewrite) + try { - if (response.Content.Headers.ContentLength() == new FileInfo(saveto).Length) - { - lock (log) - log.Info("got LastModified " + saveto + " " + (response.Content.Headers).LastModified() + - " vs " + new FileInfo(saveto).LastWriteTime); - return true; - } + File.Delete(temporaryPath); } - } - - // Get the stream containing content returned by the server. - Stream dataStream = response.Content.ReadAsStreamAsync().Result; - - long bytes = response.Content.Headers.ContentLength(); - long contlen = bytes; - - byte[] buf1 = new byte[1024]; - - if (!Directory.Exists(Path.GetDirectoryName(saveto))) - Directory.CreateDirectory(Path.GetDirectoryName(saveto)); - - FileStream fs = new FileStream(saveto + ".new", FileMode.Create); - - DateTime lastupdate = DateTime.MinValue; - DateTime starttime = DateTime.Now; - int got = 0; - - while (dataStream.CanRead && bytes > 0) - { - int len = dataStream.Read(buf1, 0, buf1.Length); - bytes -= len; - got += len; - fs.Write(buf1, 0, len); - - var elapsed = (DateTime.Now - starttime).TotalSeconds; - var percent = ((got / (float)contlen) * 100.0f); - if (lastupdate.Second != DateTime.Now.Second) + catch (Exception ex) { - lastupdate = DateTime.Now; - Console.WriteLine("{0} bps {1} {2}s {3}% of {4} \r", got / elapsed, got, elapsed, - percent, contlen); - var timeleft = TimeSpan.FromSeconds(((elapsed / percent) * (100 - percent))); - status?.Invoke((int)percent, - "Downloading.. ETA: " + - //DateTime.Now.AddSeconds(((elapsed / percent) * (100 - percent))).ToShortTimeString() - formatTimeSpan(timeleft) - ); + log.Debug("Unable to remove incomplete download " + temporaryPath, ex); } } - - if (fs.Length != contlen) - { - lock (log) - log.Info("getFilefromNet(): " + "File size mismatch " + fs.Length + " vs " + contlen); - fs.Close(); - dataStream.Close(); - return false; - } - else - { - fs.Close(); - dataStream.Close(); - } - - if (File.Exists(saveto)) - { - File.Delete(saveto); - } - File.Move(saveto + ".new", saveto); - - return true; - } - catch (Exception ex) - { - lock (log) - log.Info("getFilefromNet(): " + ex.ToString()); - return false; } } - public static Task CheckHTTPFileExistsAsync(string url) + public static bool getFilefromNet(string url, string saveto, Action status = null) { - return Task.Run(() => CheckHTTPFileExists(url)); + return getFilefromNetAsync(url, saveto, status).GetAwaiter().GetResult(); } - public static bool CheckHTTPFileExists(string url) + public static async Task CheckHTTPFileExistsAsync(string url) { Uri uri; - Uri.TryCreate(url, UriKind.Absolute, out uri); - - if (url == null || url == "" || uri == null) + if (String.IsNullOrWhiteSpace(url) || + !Uri.TryCreate(url, UriKind.Absolute, out uri)) return false; - var client = new HttpClient(); - client.DefaultRequestHeaders.Add("User-Agent", Settings.Instance.UserAgent); - client.Timeout = TimeSpan.FromSeconds(30); - var resp = client.SendAsync(new HttpRequestMessage(HttpMethod.Head, url)).Result; - return resp.IsSuccessStatusCode; + try + { + using (var request = new HttpRequestMessage(HttpMethod.Head, uri)) + using (HttpResponseMessage response = + await SharedClient.SendAsync(request).ConfigureAwait(false)) + return response.IsSuccessStatusCode; + } + catch (Exception ex) + { + log.Debug("HTTP existence check failed for " + url, ex); + return false; + } + } + public static bool CheckHTTPFileExists(string url) + { + return CheckHTTPFileExistsAsync(url).GetAwaiter().GetResult(); } //https://stackoverflow.com/questions/13606523/retrieving-partial-content-using-multiple-http-requsets-to-fetch-data-via-parlle @@ -672,11 +683,15 @@ public static long GetFileSize(string uri) if (fileSizeCache.ContainsKey(uri) && fileSizeCache[uri] > 0) return fileSizeCache[uri]; - var responce = client.GetAsync(uri); - var len = responce.GetAwaiter().GetResult().Content.Headers.ContentLength(); - fileSizeCache[uri] = len; - responce.Result.Dispose(); - return len; + using (var request = new HttpRequestMessage(HttpMethod.Get, uri)) + using (HttpResponseMessage response = SharedClient.SendAsync( + request, HttpCompletionOption.ResponseHeadersRead).GetAwaiter().GetResult()) + { + response.EnsureSuccessStatusCode(); + long len = response.Content.Headers.ContentLength(); + fileSizeCache[uri] = len; + return len; + } } } diff --git a/ExtLibs/Utilities/MissionPlanner.Utilities.csproj b/ExtLibs/Utilities/MissionPlanner.Utilities.csproj index 8dafa6582c..0c853a52a6 100644 --- a/ExtLibs/Utilities/MissionPlanner.Utilities.csproj +++ b/ExtLibs/Utilities/MissionPlanner.Utilities.csproj @@ -38,17 +38,17 @@ - + - + - + - + @@ -90,6 +90,11 @@ + + + + + diff --git a/ExtLibs/Utilities/Septentrio.cs b/ExtLibs/Utilities/Septentrio.cs index 089acc5ef1..bbe22cb07e 100644 --- a/ExtLibs/Utilities/Septentrio.cs +++ b/ExtLibs/Utilities/Septentrio.cs @@ -3,6 +3,9 @@ using System; using System.Diagnostics; using System.IO; +using System.Runtime.CompilerServices; +using System.Text; +using System.Text.RegularExpressions; using System.Threading.Tasks; namespace MissionPlanner.Utilities @@ -12,6 +15,18 @@ namespace MissionPlanner.Utilities /// public class Septentrio { + private sealed class ReceiverState + { + internal string ActivePort = DefaultOutputPorts; + } + + private static readonly object ReceiverStatesSync = new object(); + private static readonly ConditionalWeakTable ReceiverStates = + new ConditionalWeakTable(); + private static readonly Regex ReceiverPrompt = new Regex( + @"(?:^|[\r\n])\s*(COM\d+|USB\d+)\s*>", + RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase); + /// /// An exception representing a missing acknowledgement. /// @@ -77,16 +92,22 @@ public enum RTCMSignals /// public static async Task ConfigureBaseReceiver(ICommsSerial receiverPort) { + if (receiverPort == null) + throw new ArgumentNullException(nameof(receiverPort)); + + ResetReceiverState(receiverPort); await receiverPort.BaseStream.FlushAsync(); receiverPort.BaudRate = 115200; receiverPort.ReadTimeout = 200; receiverPort.WriteTimeout = 200; - await ConfigureBaud(receiverPort); + string activePort = await ConfigureBaudAndDetectPort(receiverPort); + log.Info("Detected active Septentrio port: " + activePort); await SendAck(receiverPort, "setPVTMode,Static,All,Auto\n"); - await SendAck(receiverPort, "setDataInOut,USB1+USB2+COM1+COM2+COM3,Auto,RTCMv3\n"); + await SendAck(receiverPort, + $"setDataInOut,{activePort},Auto,+RTCMv3\n"); } /// @@ -116,9 +137,10 @@ public static async Task SetAutoBasePosition(ICommsSerial receiverPort) /// Configure the baud rate of the serial port. In case the receiver is connected over serial, this automatically sets the correct baud rate. /// /// - private static async Task ConfigureBaud(ICommsSerial receiverPort) + private static async Task ConfigureBaudAndDetectPort(ICommsSerial receiverPort) { bool receiverAcknowledged = false; + string activePort = DefaultOutputPorts; // All the baud rates we expect the receiver could be running at var bauds = new[] { receiverPort.BaudRate, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800 }; @@ -130,7 +152,22 @@ private static async Task ConfigureBaud(ICommsSerial receiverPort) // Try to set the port settings on a best effort basis try { - await SendAck(receiverPort, "setCOMSettings,COM1+COM2+COM3,baud"+DefaultBaudrate+",bits8,No,bit1,none\n"); + string detectedPort = await TryDetectPort(receiverPort); + if (detectedPort != null) + { + activePort = detectedPort; + SetActivePort(receiverPort, activePort); + if (activePort.StartsWith("COM", StringComparison.Ordinal)) + { + await SendAck(receiverPort, + $"setCOMSettings,{activePort},baud{DefaultBaudrate},bits8,No,bit1,none\n"); + } + } + else + { + await SendAck(receiverPort, + $"setCOMSettings,{DefaultOutputPorts},baud{DefaultBaudrate},bits8,No,bit1,none\n"); + } receiverAcknowledged = true; break; } catch { } @@ -140,6 +177,7 @@ private static async Task ConfigureBaud(ICommsSerial receiverPort) throw new FailedAckException(); receiverPort.BaudRate = DefaultBaudrate; + return activePort; } /// @@ -148,6 +186,9 @@ private static async Task ConfigureBaud(ICommsSerial receiverPort) /// public static Task SetEnabledRTCM(ICommsSerial receiverPort, RTCMLevel level, RTCMSignals signals) { + if (receiverPort == null) + throw new ArgumentNullException(nameof(receiverPort)); + int messageLevel; string messages = "RTCM1006+RTCM1033+RTCM1230"; @@ -174,7 +215,70 @@ public static Task SetEnabledRTCM(ICommsSerial receiverPort, RTCMLevel level, RT if ((signals & RTCMSignals.Beidou) == RTCMSignals.Beidou) messages += "+RTCM112" + messageLevel; - return SendAck(receiverPort, $"setRTCMv3Output,COM1+COM2+COM3+USB1+USB2,{messages}\n"); + return SendAck(receiverPort, + $"setRTCMv3Output,{GetActivePort(receiverPort)},{messages}\n"); + } + + /// + /// Detect the receiver-side port represented by the current serial connection. + /// The result is cached only for this connection object. + /// + public static async Task DetectPort(ICommsSerial receiverPort) + { + if (receiverPort == null) + throw new ArgumentNullException(nameof(receiverPort)); + + string detectedPort = await TryDetectPort(receiverPort); + if (detectedPort == null) + return GetActivePort(receiverPort); + + SetActivePort(receiverPort, detectedPort); + return detectedPort; + } + + internal static string TryParseActivePort(string response) + { + if (string.IsNullOrEmpty(response)) + return null; + + Match match = ReceiverPrompt.Match(response); + return match.Success ? match.Groups[1].Value.ToUpperInvariant() : null; + } + + private static async Task TryDetectPort(ICommsSerial receiverPort) + { + if (receiverPort.BytesToRead > 0) + receiverPort.DiscardInBuffer(); + + await receiverPort.BaseStream.FlushAsync(); + byte[] command = Encoding.ASCII.GetBytes("gecm\n"); + receiverPort.Write(command, 0, command.Length); + + var response = new StringBuilder(); + byte[] buffer = new byte[256]; + Stopwatch stopwatch = Stopwatch.StartNew(); + while (stopwatch.ElapsedMilliseconds < AckTimeout) + { + int available = receiverPort.BytesToRead; + if (available > 0) + { + int read = receiverPort.Read(buffer, 0, Math.Min(available, buffer.Length)); + if (read > 0) + { + response.Append(Encoding.ASCII.GetString(buffer, 0, read)); + string detectedPort = TryParseActivePort(response.ToString()); + if (detectedPort != null) + return detectedPort; + + if (response.Length > MaxResponseBytes) + response.Remove(0, response.Length - MaxResponseBytes); + } + } + + await Task.Delay(PollIntervalMilliseconds); + } + + return null; } /// @@ -192,33 +296,60 @@ public static Task SetRTCMInterval(ICommsSerial receiverPort, float interval) /// private static async Task SendAck(ICommsSerial receiverPort, String command) { - Stopwatch sw = new Stopwatch(); - string line; - StreamReader reader = new StreamReader(receiverPort.BaseStream, System.Text.Encoding.ASCII); - await receiverPort.BaseStream.FlushAsync(); - await receiverPort.BaseStream.WriteAsync(System.Text.Encoding.ASCII.GetBytes(command), 0, command.Length); - - // From https://stackoverflow.com/questions/45756279/how-to-set-a-timeout-for-a-streamreader-operation-that-reads-a-file - sw.Start(); - while (((line = await reader.ReadLineAsync()) != null)) + byte[] commandBytes = Encoding.ASCII.GetBytes(command); + receiverPort.Write(commandBytes, 0, commandBytes.Length); + + string acknowledgement = command.TrimEnd('\r', '\n'); + var response = new StringBuilder(); + byte[] buffer = new byte[256]; + Stopwatch stopwatch = Stopwatch.StartNew(); + while (stopwatch.ElapsedMilliseconds < AckTimeout) { - if (line.Contains(command.Remove(command.Length - 1))) + int available = receiverPort.BytesToRead; + if (available > 0) { - return; + int read = receiverPort.Read(buffer, 0, Math.Min(available, buffer.Length)); + if (read > 0) + { + response.Append(Encoding.ASCII.GetString(buffer, 0, read)); + if (response.ToString().IndexOf( + acknowledgement, StringComparison.OrdinalIgnoreCase) >= 0) + return; + + if (response.Length > MaxResponseBytes) + response.Remove(0, response.Length - MaxResponseBytes); + } } - // If the receiver never properly acknowledges the command, we need to manually time out - if (sw.ElapsedMilliseconds > AckTimeout) - { - log.Error("Waiting for command acknowledgement timed out"); - break; - } + await Task.Delay(PollIntervalMilliseconds); } + log.Error("Waiting for command acknowledgement timed out"); throw new FailedAckException(); } + private static string GetActivePort(ICommsSerial receiverPort) + { + lock (ReceiverStatesSync) + return ReceiverStates.GetOrCreateValue(receiverPort).ActivePort; + } + + private static void SetActivePort(ICommsSerial receiverPort, string activePort) + { + lock (ReceiverStatesSync) + ReceiverStates.GetOrCreateValue(receiverPort).ActivePort = activePort; + } + + private static void ResetReceiverState(ICommsSerial receiverPort) + { + lock (ReceiverStatesSync) + { + ReceiverStates.Remove(receiverPort); + ReceiverStates.Add(receiverPort, new ReceiverState()); + } + } + private static readonly ILog log = LogManager.GetLogger(typeof(Septentrio)); /// @@ -226,6 +357,9 @@ private static async Task SendAck(ICommsSerial receiverPort, String command) /// If the receiver didn't acknowledge a message in this time, we assume it wasn't received correctly. /// private const int AckTimeout = 1000; + private const int PollIntervalMilliseconds = 20; + private const int MaxResponseBytes = 4096; + private const string DefaultOutputPorts = "USB1+USB2+COM1+COM2"; /// /// The default baud rate for Septentrio receivers. diff --git a/ExtLibs/Utilities/Tracking.cs b/ExtLibs/Utilities/Tracking.cs index e5f5a2e146..e97243deeb 100644 --- a/ExtLibs/Utilities/Tracking.cs +++ b/ExtLibs/Utilities/Tracking.cs @@ -54,13 +54,14 @@ public static Guid cid static bool sessionstart = false; - private static readonly Uri trackingEndpoint = new Uri("http://www.google-analytics.com/collect"); private static readonly Uri secureTrackingEndpoint = new Uri("https://ssl.google-analytics.com/collect"); - private static Guid _cid = new Guid(); - - static Tracking() + private static readonly HttpClient client = new HttpClient { - } + Timeout = TimeSpan.FromSeconds(30) + }; + private static readonly System.Threading.SemaphoreSlim trackingGate = + new System.Threading.SemaphoreSlim(1, 1); + private static Guid _cid = new Guid(); public static void AddEvent(string cat, string action, string label, string value) { @@ -295,12 +296,13 @@ static void track(object temp) if (OptOut) return; + // Analytics is best-effort. Do not let a slow endpoint accumulate queued requests + // and ThreadPool workers while the operator is using the application. + if (!trackingGate.Wait(0)) + return; + try { - var client = new HttpClient(); - client.DefaultRequestHeaders.Add("User-Agent", productName + " " + productVersion + " (" + Environment.OSVersion.VersionString + ")"); - client.Timeout = TimeSpan.FromSeconds(30); - string data = ""; List> data1 = (List>)temp; @@ -321,9 +323,24 @@ static void track(object temp) log.Debug(data); - client.PostAsync(secureTrackingEndpoint, new StringContent(data)); + using (var request = new HttpRequestMessage(HttpMethod.Post, secureTrackingEndpoint)) + { + request.Content = new StringContent(data); + request.Headers.TryAddWithoutValidation("User-Agent", + productName + " " + productVersion + " (" + Environment.OSVersion.VersionString + ")"); + using (HttpResponseMessage response = + client.SendAsync(request).GetAwaiter().GetResult()) + { + if (!response.IsSuccessStatusCode) + log.Debug("Tracking endpoint returned " + response.StatusCode); + } + } } catch { } + finally + { + trackingGate.Release(); + } } } } diff --git a/ExtLibs/Utilities/adsb.cs b/ExtLibs/Utilities/adsb.cs index 221bb2cd49..56b710e660 100644 --- a/ExtLibs/Utilities/adsb.cs +++ b/ExtLibs/Utilities/adsb.cs @@ -142,10 +142,6 @@ void TryConnect() { // ADSB Exchange API format - see https://api.adsb.lol/docs string url = "{0}/v2/point/{1}/{2}/{3}"; - Download.RequestModification += (u, request) => { - // for future use if necessary: request.Headers.Add("X-API-Auth", "example"); - request.SetHeader("User-Agent", "Mission-Planner/" + ApplicationVersion); - }; var delay = API_LOOP_DELAY_MILLISECONDS; while (true) @@ -154,7 +150,9 @@ void TryConnect() var timer = Stopwatch.StartNew(); string formattedUrl = string.Format(CultureInfo.InvariantCulture, url, server, CurrentPosition.Lat, CurrentPosition.Lng, httpRequestRadius); - var t = Download.GetAsyncWithStatus(formattedUrl); + var t = Download.GetAsyncWithStatus(formattedUrl, request => + request.Headers.TryAddWithoutValidation( + "User-Agent", "Mission-Planner/" + ApplicationVersion)); t.Wait(); // Check for long running requests diff --git a/ExtLibs/px4uploader/Program.cs b/ExtLibs/px4uploader/Program.cs index 2356e26ad1..88d68e1f15 100644 --- a/ExtLibs/px4uploader/Program.cs +++ b/ExtLibs/px4uploader/Program.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; @@ -118,49 +117,10 @@ public static bool Uploader(string fn) public static string[] GetPortNames() { - List allPorts = new List(); - - if (Directory.Exists("/dev/")) - { - // cleanup now - GC.Collect(); - // mono is failing in here on linux "too many open files" - try - { - if (Directory.Exists("/dev/serial/by-id/")) - allPorts.AddRange(Directory.GetFiles("/dev/serial/by-id/", "*")); - } - catch { } - try - { - allPorts.AddRange(Directory.GetFiles("/dev/", "ttyACM*")); - } - catch { } - try - { - allPorts.AddRange(Directory.GetFiles("/dev/", "ttyUSB*")); - } - catch { } - try - { - allPorts.AddRange(Directory.GetFiles("/dev/", "rfcomm*")); - } - catch { } - try - { - allPorts.AddRange(Directory.GetFiles("/dev/", "*usb*")); - } - catch { } - } - - - string[] ports = System.IO.Ports.SerialPort.GetPortNames(); - - ports = ports.Select(p => trimcomportname(p.TrimEnd())).ToArray(); - - allPorts.AddRange(ports); - - return allPorts.ToArray(); + return MissionPlanner.Comms.SerialPort.GetPortNames() + .Select(p => trimcomportname(p.TrimEnd())) + .Distinct(StringComparer.OrdinalIgnoreCase) + .ToArray(); } static string trimcomportname(string input) diff --git a/GCSViews/Setup/InstallFirmwareView.axaml.cs b/GCSViews/Setup/InstallFirmwareView.axaml.cs index a20bacc7b2..45a4e5c426 100644 --- a/GCSViews/Setup/InstallFirmwareView.axaml.cs +++ b/GCSViews/Setup/InstallFirmwareView.axaml.cs @@ -46,7 +46,7 @@ private async void OnLoadCustomFirmware(object? sender, RoutedEventArgs e) { string? portName = null; if (LegacyFirmwareUploader.RequiresSerialPort(target.Value)) { - var ports = System.IO.Ports.SerialPort.GetPortNames() + var ports = MissionPlanner.Comms.SerialPort.GetPortNames() .OrderBy(value => value, System.StringComparer.OrdinalIgnoreCase) .ToArray(); var selected = await Dialogs.Select( diff --git a/MissionPlannerTests/Avalonia/MissionPlanner.Tests/DownloadHttpClientTests.cs b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/DownloadHttpClientTests.cs new file mode 100644 index 0000000000..a84eb4f774 --- /dev/null +++ b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/DownloadHttpClientTests.cs @@ -0,0 +1,71 @@ +using System.Net; +using System.Net.Http; +using System.Text; +using MissionPlanner.Utilities; + +namespace MissionPlanner.Tests; + +public sealed class DownloadHttpClientTests { + [Fact] + public async Task Helpers_reuse_the_supplied_client_and_dispose_every_response() { + var contents = new List(); + var requests = new List<(HttpMethod Method, string Body, bool Configured)>(); + using var client = new HttpClient(new StubHandler(async request => { + string body = request.Content == null + ? "" + : await request.Content.ReadAsStringAsync(); + bool configured = request.Headers.TryGetValues("X-Test", out IEnumerable? values) + && values.Contains("value", StringComparer.Ordinal); + requests.Add((request.Method, body, configured)); + var content = new TrackingContent("reply-" + requests.Count); + contents.Add(content); + return new HttpResponseMessage( + requests.Count == 3 ? HttpStatusCode.NotFound : HttpStatusCode.OK) { + Content = content, + }; + })); + + Assert.Equal("reply-1", await Download.PostAsync(client, "https://example.test/post", "data")); + Assert.Equal("reply-2", await Download.GetAsync(client, "https://example.test/get")); + Download.HTTPResult status = await Download.GetAsyncWithStatus( + client, "https://example.test/status", + request => request.Headers.TryAddWithoutValidation("X-Test", "value")); + + Assert.Equal(HttpStatusCode.NotFound, status.status); + Assert.Equal("reply-3", status.content); + Assert.Equal([ + (HttpMethod.Post, "data", false), + (HttpMethod.Get, "", false), + (HttpMethod.Get, "", true), + ], requests); + Assert.All(contents, content => Assert.True(content.Disposed)); + } + + [Fact] + public async Task Successful_content_is_disposed_even_when_status_validation_throws() { + var content = new TrackingContent("failure"); + using var client = new HttpClient(new StubHandler(_ => Task.FromResult( + new HttpResponseMessage(HttpStatusCode.InternalServerError) {Content = content}))); + + await Assert.ThrowsAsync(() => + Download.GetAsync(client, "https://example.test/failure")); + + Assert.True(content.Disposed); + } + + private sealed class StubHandler( + Func> send) : HttpMessageHandler { + protected override Task SendAsync( + HttpRequestMessage request, CancellationToken cancellationToken) => send(request); + } + + private sealed class TrackingContent(string value) + : ByteArrayContent(Encoding.UTF8.GetBytes(value)) { + internal bool Disposed { get; private set; } + + protected override void Dispose(bool disposing) { + Disposed = true; + base.Dispose(disposing); + } + } +} diff --git a/MissionPlannerTests/Avalonia/MissionPlanner.Tests/ExternalGuidedTests.cs b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/ExternalGuidedTests.cs index 28642856d7..1d996f7ac8 100644 --- a/MissionPlannerTests/Avalonia/MissionPlanner.Tests/ExternalGuidedTests.cs +++ b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/ExternalGuidedTests.cs @@ -80,6 +80,7 @@ public async Task Requires_confirmation_and_sends_only_to_the_bound_target() { Assert.Equal(12.5, last.Value.lat, 7); Assert.Equal(23.5, last.Value.lng, 7); Assert.Equal(45, last.Value.alt, 7); + Assert.Equal((byte)MAVLink.MAV_FRAME.GLOBAL_RELATIVE_ALT, last.Value.frame); current = new NmeaVehicleTarget(secondLink, 42, 7); viewModel.SynchronizeActiveTarget(); diff --git a/MissionPlannerTests/Avalonia/MissionPlanner.Tests/GuidedCommandPayloadTests.cs b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/GuidedCommandPayloadTests.cs new file mode 100644 index 0000000000..85188ad310 --- /dev/null +++ b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/GuidedCommandPayloadTests.cs @@ -0,0 +1,50 @@ +using MissionPlanner.Utilities; + +namespace MissionPlanner.Tests; + +public sealed class GuidedCommandPayloadTests { + [Theory] + [InlineData(true, (float)MAVLink.MAV_DO_REPOSITION_FLAGS.CHANGE_MODE)] + [InlineData(false, 0f)] + public void Reposition_payload_preserves_target_frame_coordinates_and_yaw( + bool changeMode, float expectedFlags) { + var target = new Locationwp { + lat = 34.1234567, + lng = 32.7654321, + alt = 123.5f, + frame = (byte)MAVLink.MAV_FRAME.GLOBAL_TERRAIN_ALT, + }; + + MAVLink.mavlink_command_int_t command = + MAVLinkInterface.BuildGuidedRepositionCommand(42, 190, target, changeMode); + + Assert.Equal((ushort)MAVLink.MAV_CMD.DO_REPOSITION, command.command); + Assert.Equal((byte)42, command.target_system); + Assert.Equal((byte)190, command.target_component); + Assert.Equal((byte)MAVLink.MAV_FRAME.GLOBAL_TERRAIN_ALT, command.frame); + Assert.Equal(-1, command.param1); + Assert.Equal(expectedFlags, command.param2); + Assert.Equal(0, command.param3); + Assert.True(float.IsNaN(command.param4)); + Assert.Equal(341234567, command.x); + Assert.Equal(327654321, command.y); + Assert.Equal(123.5f, command.z); + } + + [Fact] + public void Altitude_payload_uses_relative_home_frame_and_requested_metres() { + MAVLink.mavlink_command_long_t command = + MAVLinkInterface.BuildAltitudeChangeCommand(17, 3, 87.25f); + + Assert.Equal((ushort)MAVLink.MAV_CMD.DO_CHANGE_ALTITUDE, command.command); + Assert.Equal((byte)17, command.target_system); + Assert.Equal((byte)3, command.target_component); + Assert.Equal(87.25f, command.param1); + Assert.Equal((float)MAVLink.MAV_FRAME.GLOBAL_RELATIVE_ALT, command.param2); + Assert.Equal(0, command.param3); + Assert.Equal(0, command.param4); + Assert.Equal(0, command.param5); + Assert.Equal(0, command.param6); + Assert.Equal(0, command.param7); + } +} diff --git a/MissionPlannerTests/Avalonia/MissionPlanner.Tests/LogDownloadTests.cs b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/LogDownloadTests.cs index 14e4ccca8f..5bd3ae1b33 100644 --- a/MissionPlannerTests/Avalonia/MissionPlanner.Tests/LogDownloadTests.cs +++ b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/LogDownloadTests.cs @@ -19,4 +19,69 @@ public void Timed_log_filename_is_cross_platform_and_collision_resistant() { Assert.Equal("2026-08-21 10-11-12_7.bin", name); Assert.DoesNotContain(':', name); } + + [Fact] + public void Tracker_counts_out_of_order_and_duplicate_data_only_once() { + var tracker = new LogDownloadTracker(); + + Assert.True(tracker.Add(90, 90, true)); + Assert.True(tracker.Add(0, 90, true)); + Assert.True(tracker.Add(90, 90, true)); + + Assert.Equal(180UL, tracker.CoveredBytes); + Assert.Null(tracker.TotalLength); + LogDownloadRequest next = tracker.NextRequest(4500); + Assert.Equal(180U, next.Offset); + Assert.Equal(uint.MaxValue, next.Count); + } + + [Fact] + public void Tracker_requests_only_the_first_missing_range_after_finding_end() { + var tracker = new LogDownloadTracker(); + tracker.Add(0, 90, true); + tracker.Add(180, 20, true); + + Assert.Equal(200U, tracker.TotalLength); + Assert.Equal(110UL, tracker.CoveredBytes); + Assert.False(tracker.IsComplete); + + LogDownloadRequest missing = tracker.NextRequest(4500); + Assert.Equal(90U, missing.Offset); + Assert.Equal(90U, missing.Count); + + tracker.Add(90, 90, false); + Assert.True(tracker.IsComplete); + Assert.Equal(200UL, tracker.CoveredBytes); + } + + [Fact] + public void Tracker_accepts_zero_length_terminator_for_packet_aligned_log() { + var tracker = new LogDownloadTracker(); + tracker.Add(0, 90, true); + tracker.Add(90, 90, true); + tracker.Add(180, 0, true); + + Assert.Equal(180U, tracker.TotalLength); + Assert.True(tracker.IsComplete); + Assert.Equal(180UL, tracker.CoveredBytes); + } + + [Fact] + public void Tracker_merges_partially_overlapping_ranges() { + var tracker = new LogDownloadTracker(); + tracker.Add(30, 90, true); + tracker.Add(0, 90, true); + + Assert.Equal(120UL, tracker.CoveredBytes); + Assert.Equal(120U, tracker.NextRequest(4500).Offset); + } + + [Fact] + public void Tracker_rejects_a_block_that_overflows_the_protocol_offset() { + var tracker = new LogDownloadTracker(); + + Assert.False(tracker.Add(uint.MaxValue - 10, 90, true)); + Assert.Equal(0UL, tracker.CoveredBytes); + Assert.Null(tracker.TotalLength); + } } diff --git a/MissionPlannerTests/Avalonia/MissionPlanner.Tests/MagCalStatusTests.cs b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/MagCalStatusTests.cs new file mode 100644 index 0000000000..fd673e4ff4 --- /dev/null +++ b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/MagCalStatusTests.cs @@ -0,0 +1,45 @@ +using System.Reflection; +using MissionPlanner.ViewModels.GCSViews.ConfigurationView; + +namespace MissionPlanner.Tests; + +public sealed class MagCalStatusTests { + [Theory] + [InlineData(MAVLink.MAG_CAL_STATUS.MAG_CAL_FAILED_ORIENTATION, 6, "orientation")] + [InlineData(MAVLink.MAG_CAL_STATUS.MAG_CAL_FAILED_RADIUS, 7, "radius")] + [InlineData(MAVLink.MAG_CAL_STATUS.MAG_CAL_FAILED_OFFSETS, 8, "offset")] + [InlineData(MAVLink.MAG_CAL_STATUS.MAG_CAL_FAILED_DIAG_SCALING, 9, "scaling")] + [InlineData(MAVLink.MAG_CAL_STATUS.MAG_CAL_FAILED_RESIDUALS_HIGH, 10, "fitness")] + public void Failure_wire_values_and_descriptions_match_mavlink( + MAVLink.MAG_CAL_STATUS status, byte wireValue, string diagnostic) { + Assert.Equal(wireValue, (byte)status); + MAVLink.Description? description = typeof(MAVLink.MAG_CAL_STATUS) + .GetField(status.ToString())?.GetCustomAttribute(); + Assert.NotNull(description); + Assert.Contains(diagnostic, description.Text, StringComparison.OrdinalIgnoreCase); + Assert.Contains(diagnostic, MagCalStatusFormatter.Describe(wireValue), + StringComparison.OrdinalIgnoreCase); + } + + [Theory] + [InlineData(0, false)] + [InlineData(1, false)] + [InlineData(2, false)] + [InlineData(3, false)] + [InlineData(4, false)] + [InlineData(5, true)] + [InlineData(6, true)] + [InlineData(7, true)] + [InlineData(8, true)] + [InlineData(9, true)] + [InlineData(10, true)] + public void Failure_partition_and_report_progress_are_stable(byte status, bool failed) { + Assert.Equal(failed, MagCalStatusFormatter.IsFailure(status)); + Assert.Equal(failed ? 0 : 100, MagCalStatusFormatter.ProgressForReport(status)); + } + + [Fact] + public void Unknown_future_status_has_an_unambiguous_fallback() { + Assert.Equal("MAG_CAL_STATUS(42)", MagCalStatusFormatter.Describe(42)); + } +} diff --git a/MissionPlannerTests/Avalonia/MissionPlanner.Tests/MavAuthKeyStoreTests.cs b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/MavAuthKeyStoreTests.cs new file mode 100644 index 0000000000..5e391fc311 --- /dev/null +++ b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/MavAuthKeyStoreTests.cs @@ -0,0 +1,133 @@ +using System.Runtime.Serialization; +using System.Security.Cryptography; +using MissionPlanner.Mavlink; +using MissionPlanner.Utilities; + +namespace MissionPlanner.Tests; + +public sealed class MavAuthKeyStoreTests : IDisposable { + private readonly string _directory = + Path.Combine(Path.GetTempPath(), "mp-authkeys-" + Guid.NewGuid().ToString("N")); + + public MavAuthKeyStoreTests() => Directory.CreateDirectory(_directory); + + [Fact] + public void New_store_round_trips_keys_with_persisted_material() { + string keyFile = Path.Combine(_directory, "authkeys.xml"); + string materialFile = Path.Combine(_directory, "authkeys.key"); + var keys = Keys(("alpha", 17)); + + using (var store = new MavAuthKeyStore(keyFile, materialFile, NoLegacyCandidates)) { + Assert.Empty(store.Load()); + store.Save(keys); + } + + Assert.True(File.Exists(keyFile)); + Assert.True(File.Exists(materialFile)); + using var reopened = new MavAuthKeyStore(keyFile, materialFile, NoLegacyCandidates); + MAVAuthKeys.AuthKeys loaded = reopened.Load(); + Assert.Equal(keys["alpha"].Key, loaded["alpha"].Key); + } + + [Fact] + public void Legacy_mac_encrypted_store_is_migrated_without_changing_its_keys() { + string keyFile = Path.Combine(_directory, "authkeys.xml"); + string materialFile = Path.Combine(_directory, "authkeys.key"); + byte[] legacyKey = Enumerable.Range(1, 32).Select(value => (byte)value).ToArray(); + byte[] legacyIv = Enumerable.Range(101, 16).Select(value => (byte)value).ToArray(); + var expected = Keys(("legacy", 42)); + WriteEncrypted(keyFile, expected, legacyKey, legacyIv); + + using (var store = new MavAuthKeyStore( + keyFile, materialFile, + () => [new Crypto(legacyKey, legacyIv)])) { + MAVAuthKeys.AuthKeys loaded = store.Load(); + Assert.Equal(expected["legacy"].Key, loaded["legacy"].Key); + } + + Assert.True(File.Exists(materialFile)); + using var reopened = new MavAuthKeyStore(keyFile, materialFile, NoLegacyCandidates); + Assert.Equal(expected["legacy"].Key, reopened.Load()["legacy"].Key); + } + + [Fact] + public void Unreadable_existing_store_is_preserved_and_cannot_be_overwritten() { + string keyFile = Path.Combine(_directory, "authkeys.xml"); + string materialFile = Path.Combine(_directory, "authkeys.key"); + byte[] original = Enumerable.Range(0, 128).Select(value => (byte)value).ToArray(); + File.WriteAllBytes(keyFile, original); + + using var store = new MavAuthKeyStore(keyFile, materialFile, NoLegacyCandidates); + InvalidDataException error = Assert.Throws(() => store.Load()); + + Assert.Contains("left unchanged", error.Message); + Assert.Equal(original, File.ReadAllBytes(keyFile)); + Assert.Throws(() => store.Save(Keys(("new", 1)))); + Assert.Equal(original, File.ReadAllBytes(keyFile)); + } + + [Fact] + public void Replacing_a_store_keeps_a_readable_backup() { + string keyFile = Path.Combine(_directory, "authkeys.xml"); + string materialFile = Path.Combine(_directory, "authkeys.key"); + using (var store = new MavAuthKeyStore(keyFile, materialFile, NoLegacyCandidates)) { + store.Load(); + store.Save(Keys(("first", 1))); + store.Save(Keys(("first", 1), ("second", 2))); + store.Save(Keys(("first", 1), ("second", 2), ("third", 3))); + } + + string backup = keyFile + ".bak"; + Assert.True(File.Exists(backup)); + using var backupStore = new MavAuthKeyStore(backup, materialFile, NoLegacyCandidates); + MAVAuthKeys.AuthKeys loaded = backupStore.Load(); + Assert.True(loaded.ContainsKey("first")); + Assert.True(loaded.ContainsKey("second")); + Assert.False(loaded.ContainsKey("third")); + } + + [Fact] + public void Crypto_instances_do_not_mutate_the_legacy_defaults() { + byte[] replacementKey = Enumerable.Repeat((byte)0x55, 32).ToArray(); + byte[] replacementIv = Enumerable.Repeat((byte)0x66, 16).ToArray(); + using (var changed = new Crypto()) { + changed.SetBinaryKeys(replacementKey, replacementIv); + } + + using var fresh = new Crypto(); + fresh.ExtractBinaryKeys(out byte[] freshKey, out byte[] freshIv); + Assert.NotEqual(replacementKey, freshKey); + Assert.NotEqual(replacementIv, freshIv); + } + + private static IReadOnlyList NoLegacyCandidates() => Array.Empty(); + + private static MAVAuthKeys.AuthKeys Keys(params (string Name, byte Fill)[] definitions) { + var keys = new MAVAuthKeys.AuthKeys(); + foreach ((string name, byte fill) in definitions) { + keys[name] = new MAVAuthKeys.AuthKey { + Name = name, + Key = Enumerable.Repeat(fill, 32).ToArray(), + }; + } + return keys; + } + + private static void WriteEncrypted(string path, MAVAuthKeys.AuthKeys keys, + byte[] key, byte[] iv) { + var serializer = new DataContractSerializer( + typeof(MAVAuthKeys.AuthKeys), [typeof(MAVAuthKeys.AuthKey)]); + using var crypto = new Crypto(key, iv); + using var file = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None); + using var encrypted = new CryptoStream( + file, crypto.algorithm.CreateEncryptor(), CryptoStreamMode.Write); + serializer.WriteObject(encrypted, keys); + } + + public void Dispose() { + try { + Directory.Delete(_directory, recursive: true); + } catch { + } + } +} diff --git a/MissionPlannerTests/Avalonia/MissionPlanner.Tests/MavFtpDirectoryParsingTests.cs b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/MavFtpDirectoryParsingTests.cs new file mode 100644 index 0000000000..6288f15990 --- /dev/null +++ b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/MavFtpDirectoryParsingTests.cs @@ -0,0 +1,76 @@ +using System.Text; +using MissionPlanner.ArduPilot.Mavlink; + +namespace MissionPlanner.Tests; + +public sealed class MavFtpDirectoryParsingTests { + [Fact] + public void Directory_packet_decodes_utf8_names_and_invariant_file_sizes() { + byte[] payload = BuildPayload( + (byte)'F', "полёт-飞行.bin\t18446744073709551615", + (byte)'D', "данные-資料", + (byte)'S', "ignored"); + + bool parsed = MAVFtp.TryParseDirectoryEntries( + payload, payload.Length, "/APM", out List entries, out string error); + + Assert.True(parsed, error); + Assert.Collection(entries, + file => { + Assert.Equal("полёт-飞行.bin", file.Name); + Assert.False(file.isDirectory); + Assert.Equal(ulong.MaxValue, file.Size); + Assert.Equal("/APM/полёт-飞行.bin", file.FullName); + }, + directory => { + Assert.Equal("данные-資料", directory.Name); + Assert.True(directory.isDirectory); + }, + skipped => { + Assert.Equal("", skipped.Name); + Assert.True(skipped.isDirectory); + }); + } + + [Theory] + [MemberData(nameof(MalformedPackets))] + public void Malformed_directory_packet_is_rejected_without_partial_results( + byte[] payload, int count, string expectedError) { + bool parsed = MAVFtp.TryParseDirectoryEntries( + payload, count, "/", out List entries, out string error); + + Assert.False(parsed); + Assert.Empty(entries); + Assert.Contains(expectedError, error, StringComparison.OrdinalIgnoreCase); + } + + public static IEnumerable MalformedPackets() { + byte[] unterminated = Encoding.UTF8.GetBytes("Fname\t12"); + byte[] missingSize = BuildPayload((byte)'F', "name-without-size"); + byte[] validDirectory = BuildPayload((byte)'D', "ok"); + yield return [unterminated, unterminated.Length, "null terminated"]; + yield return [missingSize, missingSize.Length, "size"]; + yield return [new byte[] { (byte)'D', 0xc3, 0x28, 0 }, 4, "UTF-8"]; + yield return [validDirectory, validDirectory.Length + 1, "exceeds"]; + } + + [Fact] + public void String_decoder_respects_packet_limit_not_backing_array_length() { + byte[] data = [.. Encoding.UTF8.GetBytes("name"), 0, (byte)'x', 0]; + + Assert.False(MAVFtp.TryExtractNullTerminatedUtf8( + data, 0, 4, out _, out int nextOffset, out string error)); + Assert.Equal(0, nextOffset); + Assert.Contains("null terminated", error, StringComparison.OrdinalIgnoreCase); + } + + private static byte[] BuildPayload(params object[] entries) { + var bytes = new List(); + for (int index = 0; index < entries.Length; index += 2) { + bytes.Add((byte)entries[index]); + bytes.AddRange(Encoding.UTF8.GetBytes((string)entries[index + 1])); + bytes.Add(0); + } + return bytes.ToArray(); + } +} diff --git a/MissionPlannerTests/Avalonia/MissionPlanner.Tests/MessageRateManagerTests.cs b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/MessageRateManagerTests.cs new file mode 100644 index 0000000000..458e03355a --- /dev/null +++ b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/MessageRateManagerTests.cs @@ -0,0 +1,148 @@ +using MissionPlanner.ArduPilot.Mavlink; + +namespace MissionPlanner.Tests; + +public sealed class MessageRateManagerTests { + [Theory] + [InlineData(2, 500_000)] + [InlineData(3, 333_333)] + [InlineData(2_000_000, 1)] + [InlineData(0.000001, int.MaxValue)] + public void Hertz_conversion_is_bounded_and_rounded( + double hertz, int expectedMicroseconds) { + Assert.Equal(expectedMicroseconds, + MessageRateManager.HertzToIntervalMicroseconds(hertz)); + } + + [Theory] + [InlineData(0)] + [InlineData(-1)] + [InlineData(double.NaN)] + [InlineData(double.PositiveInfinity)] + public void Invalid_rates_are_rejected(double hertz) { + using var manager = new MessageRateManager( + new FakeTransport(), TimeSpan.FromHours(1)); + + Assert.Throws(() => + manager.Subscribe(1, 1, MAVLink.MAVLINK_MSG_ID.CAMERA_FOV_STATUS, hertz)); + } + + [Fact] + public async Task Fastest_lease_wins_and_last_release_restores_default_once() { + var transport = new FakeTransport(); + using var manager = new MessageRateManager(transport, TimeSpan.FromHours(1)); + + MessageRateLease slow = manager.Subscribe( + 7, 100, MAVLink.MAVLINK_MSG_ID.CAMERA_FOV_STATUS, 2, "slow"); + MessageRateLease fast = manager.Subscribe( + 7, 100, MAVLink.MAVLINK_MSG_ID.CAMERA_FOV_STATUS, 5, "fast"); + + Assert.Equal([500_000, 200_000], + transport.SetRequests.Select(request => request.Interval).ToArray()); + Assert.All(transport.SetRequests, request => Assert.False(request.RequireAck)); + + fast.Dispose(); + Assert.Equal(500_000, transport.SetRequests.Last().Interval); + + slow.Dispose(); + await WaitUntil(() => transport.SetRequests.Any(request => + request.Interval == 0 && request.RequireAck)); + int restoreCount = transport.SetRequests.Count(request => + request.Interval == 0 && request.RequireAck); + + slow.Dispose(); + await Task.Delay(25); + Assert.Equal(restoreCount, transport.SetRequests.Count(request => + request.Interval == 0 && request.RequireAck)); + } + + [Fact] + public void Disposal_is_idempotent_and_rejects_new_leases() { + var manager = new MessageRateManager( + new FakeTransport(), TimeSpan.FromHours(1)); + + manager.Dispose(); + manager.Dispose(); + + Assert.Throws(() => manager.Subscribe( + 1, 1, MAVLink.MAVLINK_MSG_ID.CAMERA_SETTINGS, 1)); + } + + [Fact] + public void Camera_streaming_leases_follow_reported_capabilities() { + uint flags = (uint)(MAVLink.CAMERA_CAP_FLAGS.HAS_BASIC_ZOOM + | MAVLink.CAMERA_CAP_FLAGS.CAPTURE_VIDEO); + + Assert.Equal([ + MAVLink.MAVLINK_MSG_ID.CAMERA_FOV_STATUS, + MAVLink.MAVLINK_MSG_ID.CAMERA_SETTINGS, + MAVLink.MAVLINK_MSG_ID.CAMERA_CAPTURE_STATUS, + ], CameraProtocol.StreamingMessageIds(flags)); + Assert.Equal([MAVLink.MAVLINK_MSG_ID.CAMERA_FOV_STATUS], + CameraProtocol.StreamingMessageIds(0)); + } + + [Theory] + [InlineData(0, true)] + [InlineData((uint)MAVLink.GIMBAL_DEVICE_FLAGS.YAW_LOCK, false)] + [InlineData((uint)MAVLink.GIMBAL_DEVICE_FLAGS.YAW_IN_EARTH_FRAME, false)] + [InlineData((uint)MAVLink.GIMBAL_DEVICE_FLAGS.YAW_IN_VEHICLE_FRAME, true)] + public void Gimbal_yaw_frame_comes_from_device_attitude_flags( + uint flags, bool expectedVehicleFrame) { + Assert.Equal(expectedVehicleFrame, + GimbalManagerProtocol.YawIsInVehicleFrame(flags)); + } + + private static async Task WaitUntil(Func condition) { + DateTime deadline = DateTime.UtcNow.AddSeconds(2); + while (!condition()) { + if (DateTime.UtcNow >= deadline) { + throw new TimeoutException("Expected asynchronous rate-manager operation did not complete."); + } + await Task.Delay(10); + } + } + + private sealed class FakeTransport : IMessageRateTransport { + private readonly object _gate = new(); + private readonly List _setRequests = []; + private int _nextSubscription; + + internal readonly record struct SetRequest( + uint MessageId, byte SystemId, byte ComponentId, + int Interval, bool RequireAck); + + internal IReadOnlyList SetRequests { + get { + lock (_gate) { + return _setRequests.ToArray(); + } + } + } + + public bool IsCommandChannelBusy { get; set; } + + public int Subscribe(MAVLink.MAVLINK_MSG_ID messageId, + Func handler, byte sysid, byte compid) => + Interlocked.Increment(ref _nextSubscription); + + public void Unsubscribe(int subscriptionId) { + } + + public bool HasEverReceived(uint messageId, byte sysid, byte compid) => false; + + public int GetLinkQualityPercent(byte sysid, byte compid) => 100; + + public Task SetIntervalAsync(uint messageId, byte sysid, byte compid, + int intervalMicroseconds, bool requireAcknowledgement) { + lock (_gate) { + _setRequests.Add(new SetRequest( + messageId, sysid, compid, intervalMicroseconds, requireAcknowledgement)); + } + return Task.FromResult(true); + } + + public Task GetIntervalAsync(uint messageId, byte sysid, byte compid) => + Task.FromResult(true); + } +} diff --git a/MissionPlannerTests/Avalonia/MissionPlanner.Tests/MissionUploadProtocolTests.cs b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/MissionUploadProtocolTests.cs new file mode 100644 index 0000000000..a2c84bdc09 --- /dev/null +++ b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/MissionUploadProtocolTests.cs @@ -0,0 +1,74 @@ +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.CompilerServices; +using MissionPlanner.ArduPilot; + +namespace MissionPlanner.Tests; + +public sealed class MissionUploadProtocolTests { + [Theory] + [InlineData(nameof(mav_mission.upload))] + [InlineData(nameof(mav_mission.uploadPartial))] + public void Upload_does_not_acknowledge_the_vehicle_mission_ack(string methodName) { + MethodInfo method = typeof(mav_mission).GetMethods(BindingFlags.Public | BindingFlags.Static) + .Single(candidate => candidate.Name == methodName); + Type stateMachine = method.GetCustomAttribute()! + .StateMachineType; + MethodInfo moveNext = stateMachine.GetMethod( + "MoveNext", BindingFlags.Instance | BindingFlags.NonPublic)!; + + Assert.DoesNotContain(CalledMethods(moveNext), called => + called.DeclaringType == typeof(MAVLinkInterface) + && called.Name == nameof(MAVLinkInterface.setWPACK)); + } + + private static IEnumerable CalledMethods(MethodInfo method) { + byte[] bytes = method.GetMethodBody()!.GetILAsByteArray()!; + Module module = method.Module; + Type[] typeArguments = method.DeclaringType?.GetGenericArguments() ?? []; + Type[] methodArguments = method.GetGenericArguments(); + int offset = 0; + while (offset < bytes.Length) { + OpCode opcode = ReadOpcode(bytes, ref offset); + if (opcode.OperandType is OperandType.InlineMethod) { + int token = BitConverter.ToInt32(bytes, offset); + MethodBase? called = null; + try { + called = module.ResolveMethod(token, typeArguments, methodArguments); + } catch (ArgumentException) { + } + if (called != null) { + yield return called; + } + } + offset += OperandSize(opcode.OperandType, bytes, offset); + } + } + + private static OpCode ReadOpcode(byte[] bytes, ref int offset) { + ushort value = bytes[offset++]; + if (value == 0xfe) { + value = (ushort)(0xfe00 | bytes[offset++]); + } + return Opcodes[value]; + } + + private static int OperandSize(OperandType type, byte[] bytes, int offset) => type switch { + OperandType.InlineNone => 0, + OperandType.ShortInlineBrTarget or OperandType.ShortInlineI + or OperandType.ShortInlineVar => 1, + OperandType.InlineVar => 2, + OperandType.InlineI or OperandType.InlineBrTarget or OperandType.InlineField + or OperandType.InlineMethod or OperandType.InlineSig or OperandType.InlineString + or OperandType.InlineTok or OperandType.InlineType or OperandType.ShortInlineR => 4, + OperandType.InlineI8 or OperandType.InlineR => 8, + OperandType.InlineSwitch => 4 + BitConverter.ToInt32(bytes, offset) * 4, + _ => throw new InvalidOperationException("Unsupported IL operand: " + type), + }; + + private static readonly IReadOnlyDictionary Opcodes = + typeof(OpCodes).GetFields(BindingFlags.Public | BindingFlags.Static) + .Where(field => field.FieldType == typeof(OpCode)) + .Select(field => (OpCode)field.GetValue(null)!) + .ToDictionary(opcode => unchecked((ushort)opcode.Value)); +} diff --git a/MissionPlannerTests/Avalonia/MissionPlanner.Tests/MjpegMultipartReaderTests.cs b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/MjpegMultipartReaderTests.cs new file mode 100644 index 0000000000..1b56802fa6 --- /dev/null +++ b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/MjpegMultipartReaderTests.cs @@ -0,0 +1,66 @@ +using System.Text; +using MissionPlanner.Utilities; + +namespace MissionPlanner.Tests; + +public sealed class MjpegMultipartReaderTests { + [Fact] + public void Reads_length_delimited_frames_with_case_insensitive_headers() { + byte[] body = Encoding.ASCII.GetBytes( + "--frame\r\ncontent-type: image/jpeg\r\ncontent-length: 4\r\n\r\nABCD\r\n" + + "--frame\r\nContent-Length: 3\r\n\r\nXYZ\r\n--frame--\r\n"); + + using var binary = Reader(body); + var reader = new MjpegMultipartReader(binary, + "multipart/x-mixed-replace; charset=utf-8; BOUNDARY=\"frame\""); + + Assert.True(reader.TryReadFrame(out byte[] first)); + Assert.Equal("ABCD", Encoding.ASCII.GetString(first)); + Assert.True(reader.TryReadFrame(out byte[] second)); + Assert.Equal("XYZ", Encoding.ASCII.GetString(second)); + Assert.False(reader.TryReadFrame(out _)); + } + + [Fact] + public void Sniffs_boundary_and_does_not_skip_lengthless_frames() { + byte[] body = Encoding.ASCII.GetBytes( + "camera preamble\n--cam\nContent-Type: image/jpeg\n\nONE\n" + + "--cam\nContent-Type: image/jpeg\n\nTWO\n--cam--\n"); + + using var binary = Reader(body); + var reader = new MjpegMultipartReader(binary, null); + + Assert.True(reader.TryReadFrame(out byte[] first)); + Assert.Equal("ONE", Encoding.ASCII.GetString(first)); + Assert.True(reader.TryReadFrame(out byte[] second)); + Assert.Equal("TWO", Encoding.ASCII.GetString(second)); + Assert.False(reader.TryReadFrame(out _)); + } + + [Fact] + public void Rejects_invalid_or_oversized_content_length() { + byte[] body = Encoding.ASCII.GetBytes( + "--safe\r\nContent-Length: 12\r\n\r\nsmall"); + using var binary = Reader(body); + var reader = new MjpegMultipartReader(binary, + "multipart/x-mixed-replace; boundary=safe", maxFrameBytes: 8); + + InvalidDataException error = Assert.Throws( + () => reader.TryReadFrame(out _)); + Assert.Contains("size limit", error.Message); + } + + [Fact] + public void Rejects_truncated_length_delimited_frames() { + byte[] body = Encoding.ASCII.GetBytes( + "--frame\r\nContent-Length: 8\r\n\r\nshort"); + using var binary = Reader(body); + var reader = new MjpegMultipartReader(binary, + "multipart/x-mixed-replace; boundary=frame"); + + Assert.Throws(() => reader.TryReadFrame(out _)); + } + + private static BinaryReader Reader(byte[] bytes) => + new(new MemoryStream(bytes, writable: false), Encoding.ASCII, leaveOpen: false); +} diff --git a/MissionPlannerTests/Avalonia/MissionPlanner.Tests/NmeaFollowSessionTests.cs b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/NmeaFollowSessionTests.cs index 65b0518835..61e8fd4017 100644 --- a/MissionPlannerTests/Avalonia/MissionPlanner.Tests/NmeaFollowSessionTests.cs +++ b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/NmeaFollowSessionTests.cs @@ -101,6 +101,7 @@ public async Task Follow_me_accepts_zero_coordinates_but_stops_on_modem_switch() Assert.Equal(0, sent.lat); Assert.Equal(0, sent.lng); Assert.Equal(30, sent.alt); + Assert.Equal((byte)MAVLink.MAV_FRAME.GLOBAL_RELATIVE_ALT, sent.frame); current = new NmeaVehicleTarget(secondLink, 1, 1); viewModel.SynchronizeActiveTarget(); diff --git a/MissionPlannerTests/Avalonia/MissionPlanner.Tests/PluginRuntimeTests.cs b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/PluginRuntimeTests.cs index f69a5ffac8..a71074077b 100644 --- a/MissionPlannerTests/Avalonia/MissionPlanner.Tests/PluginRuntimeTests.cs +++ b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/PluginRuntimeTests.cs @@ -154,6 +154,42 @@ public async Task DisabledPluginIsDiscoveredWithoutExecutingCode() { Assert.Equal(0, hostCalls); } + [Fact] + public async Task Windows_internet_zone_plugin_is_reported_without_executing_code() { + string root = CreateTempRoot(); + string plugins = Path.Combine(root, "plugins"); + Directory.CreateDirectory(plugins); + CopyFixturePlugin(plugins); + int hostCalls = 0; + await using var runtime = new PluginRuntime( + [plugins], + [], + (_, type) => { + Interlocked.Increment(ref hostCalls); + return new FakePluginHost(Path.Combine(root, type.Name)); + }, + zoneIdentifier: _ => 3); + + await runtime.RefreshAsync(); + + IReadOnlyList snapshots = runtime.Snapshot(); + Assert.NotEmpty(snapshots); + Assert.All(snapshots, snapshot => { + Assert.Equal(PluginFileState.Blocked, snapshot.State); + Assert.Contains("blocked by Windows", snapshot.Error, StringComparison.OrdinalIgnoreCase); + }); + Assert.Equal(0, hostCalls); + } + + [Theory] + [InlineData("[ZoneTransfer]\r\nZoneId=3\r\n", 3)] + [InlineData("[ZoneTransfer]\n zoneid = 4 \nHostUrl=https://example.test", 4)] + [InlineData("[ZoneTransfer]\r\nHostUrl=https://example.test\r\n", null)] + public void Windows_zone_identifier_parser_is_bounded_to_the_zone_field( + string content, int? expected) { + Assert.Equal(expected, PluginRuntime.ParseZoneIdentifier(content)); + } + [Fact] public async Task InvalidDllProducesVisibleFailureWithoutEscapingRefresh() { string root = CreateTempRoot(); diff --git a/MissionPlannerTests/Avalonia/MissionPlanner.Tests/PrearmFailureTrackerTests.cs b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/PrearmFailureTrackerTests.cs new file mode 100644 index 0000000000..9c640453ff --- /dev/null +++ b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/PrearmFailureTrackerTests.cs @@ -0,0 +1,52 @@ +using System.Reflection; +using MissionPlanner.ArduPilot; + +namespace MissionPlanner.Tests; + +public sealed class PrearmFailureTrackerTests { + [Fact] + public void Ignores_stale_messages_and_returns_latest_failure_since_last_healthy_state() { + var tracker = new PrearmFailureTracker(); + DateTime now = DateTime.UtcNow; + var messages = new List<(DateTime time, string message)> { + (now.AddMinutes(-2), "PreArm: stale GPS failure"), + }; + + Assert.Null(tracker.Update(healthy: false, enabled: true, present: true, messages, now)); + messages.Add((now.AddSeconds(1), "PreArm: Compass not calibrated")); + messages.Add((now.AddSeconds(2), "unrelated status")); + messages.Add((now.AddSeconds(3), "PREARM: RC not found")); + + Assert.Equal("PREARM: RC not found", tracker.Update( + healthy: false, enabled: true, present: true, messages, now.AddSeconds(4))); + } + + [Fact] + public void Healthy_state_resets_the_failure_window() { + var tracker = new PrearmFailureTracker(); + DateTime now = DateTime.UtcNow; + var messages = new List<(DateTime time, string message)>(); + tracker.Update(healthy: true, enabled: true, present: true, messages, now); + messages.Add((now.AddSeconds(1), "PreArm: first")); + Assert.Equal("PreArm: first", tracker.Update( + healthy: false, enabled: true, present: true, messages, now.AddSeconds(2))); + + tracker.Update(healthy: true, enabled: true, present: true, messages, now.AddSeconds(3)); + Assert.Null(tracker.Update( + healthy: false, enabled: true, present: true, messages, now.AddSeconds(4))); + } + + [Fact] + public void Repeated_high_priority_message_refreshes_its_display_timeout() { + var state = new CurrentState(); + state.messageHigh = "Bad GPS Health"; + FieldInfo timestamp = typeof(CurrentState).GetField( + "_messageHighTime", BindingFlags.Instance | BindingFlags.NonPublic)!; + timestamp.SetValue(state, DateTime.MinValue); + Assert.Equal("", state.messageHigh); + + state.messageHigh = "Bad GPS Health"; + + Assert.Equal("Bad GPS Health", state.messageHigh); + } +} diff --git a/MissionPlannerTests/Avalonia/MissionPlanner.Tests/ProximityConcurrencyTests.cs b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/ProximityConcurrencyTests.cs new file mode 100644 index 0000000000..fc8c0c3344 --- /dev/null +++ b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/ProximityConcurrencyTests.cs @@ -0,0 +1,53 @@ +using MissionPlanner.Utilities; + +namespace MissionPlanner.Tests; + +public sealed class ProximityConcurrencyTests { + [Fact] + public void Raw_samples_are_detached_snapshots() { + var state = new Proximity.directionState(); + state.Add(1, MAVLink.MAV_SENSOR_ORIENTATION.MAV_SENSOR_ROTATION_NONE, + 10, DateTime.Now, age: 60); + + List snapshot = state.GetRaw(); + state.Add(2, MAVLink.MAV_SENSOR_ORIENTATION.MAV_SENSOR_ROTATION_YAW_45, + 20, DateTime.Now, age: 60); + + Assert.Single(snapshot); + Assert.Equal(2, state.GetRaw().Count); + } + + [Fact] + public void Readers_and_packet_updates_can_run_concurrently() { + var state = new Proximity.directionState(); + Exception? failure = null; + + Parallel.For(0, 5_000, (index, loop) => { + try { + if ((index & 1) == 0) { + state.Add((uint)(index % 32), index % 360, 5, index, + DateTime.Now, age: 60); + } else { + _ = state.GetRaw().Sum(sample => sample.Distance); + _ = state.GetClosest(); + _ = state.GetWarnings(index); + } + } catch (Exception ex) { + Interlocked.CompareExchange(ref failure, ex, null); + loop.Stop(); + } + }); + + Assert.Null(failure); + } + + [Fact] + public void Expired_samples_are_removed_from_every_snapshot() { + var state = new Proximity.directionState(); + state.Add(1, MAVLink.MAV_SENSOR_ORIENTATION.MAV_SENSOR_ROTATION_NONE, + 10, DateTime.Now.AddMinutes(-1), age: 1); + + Assert.Empty(state.GetRaw()); + Assert.Equal(double.MaxValue, state.GetClosest()); + } +} diff --git a/MissionPlannerTests/Avalonia/MissionPlanner.Tests/SeptentrioPortDetectionTests.cs b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/SeptentrioPortDetectionTests.cs new file mode 100644 index 0000000000..748d3adccb --- /dev/null +++ b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/SeptentrioPortDetectionTests.cs @@ -0,0 +1,127 @@ +using System.Text; +using MissionPlanner.Comms; +using MissionPlanner.Utilities; + +namespace MissionPlanner.Tests; + +public sealed class SeptentrioPortDetectionTests { + [Theory] + [InlineData("$R: gecm\r\n EchoMessage [...]\r\nUSB1>\r\n", "USB1")] + [InlineData("noise\n com10 >\n", "COM10")] + [InlineData("USB2>\r\n", "USB2")] + public void Parses_receiver_prompt_ports(string response, string expected) { + Assert.Equal(expected, Septentrio.TryParseActivePort(response)); + } + + [Fact] + public void Does_not_accept_port_like_text_outside_a_receiver_prompt() { + Assert.Null(Septentrio.TryParseActivePort("status: connected to COM3 but no prompt")); + Assert.Null(Septentrio.TryParseActivePort("XCOM3>")); + } + + [Fact] + public async Task Detected_ports_are_scoped_to_each_receiver_connection() { + using var first = new SeptentrioSerial("USB2"); + using var second = new SeptentrioSerial("COM10"); + + Assert.Equal("USB2", await Septentrio.DetectPort(first)); + Assert.Equal("COM10", await Septentrio.DetectPort(second)); + + await Septentrio.SetEnabledRTCM( + first, Septentrio.RTCMLevel.Basic, Septentrio.RTCMSignals.Gps); + await Septentrio.SetEnabledRTCM( + second, Septentrio.RTCMLevel.Full, Septentrio.RTCMSignals.Galileo); + + Assert.Contains(first.Commands, + command => command.StartsWith("setRTCMv3Output,USB2,", StringComparison.Ordinal)); + Assert.Contains(second.Commands, + command => command.StartsWith("setRTCMv3Output,COM10,", StringComparison.Ordinal)); + } + + [Fact] + public async Task Missing_acknowledgement_uses_a_bounded_timeout() { + using var serial = new SeptentrioSerial("USB1", respondToCommands: false); + var stopwatch = System.Diagnostics.Stopwatch.StartNew(); + + await Assert.ThrowsAsync(() => + Septentrio.SetEnabledRTCM( + serial, Septentrio.RTCMLevel.Basic, Septentrio.RTCMSignals.Gps)); + + Assert.InRange(stopwatch.Elapsed, TimeSpan.FromMilliseconds(800), TimeSpan.FromSeconds(3)); + } + + private sealed class SeptentrioSerial( + string promptPort, bool respondToCommands = true) : ICommsSerial { + private readonly Queue _incoming = new(); + private readonly object _sync = new(); + + internal List Commands { get; } = []; + + public Stream BaseStream { get; } = new MemoryStream(); + public int BaudRate { get; set; } = Septentrio.DefaultBaudrate; + public int BytesToRead { + get { + lock (_sync) { + return _incoming.Count; + } + } + } + public int BytesToWrite => 0; + public int DataBits { get; set; } = 8; + public bool DtrEnable { get; set; } + public bool IsOpen { get; private set; } = true; + public string PortName { get; set; } = "TEST"; + public int ReadBufferSize { get; set; } + public int ReadTimeout { get; set; } + public bool RtsEnable { get; set; } + public int WriteBufferSize { get; set; } + public int WriteTimeout { get; set; } + + public void Write(byte[] buffer, int offset, int count) { + string command = Encoding.ASCII.GetString(buffer, offset, count); + Commands.Add(command); + if (!respondToCommands) { + return; + } + string response = command == "gecm\n" + ? "$R: gecm\r\n EchoMessage [...]\r\n" + promptPort + ">\r\n" + : "$R: " + command.TrimEnd('\r', '\n') + "\r\n" + promptPort + ">\r\n"; + lock (_sync) { + foreach (byte value in Encoding.ASCII.GetBytes(response)) { + _incoming.Enqueue(value); + } + } + } + + public int Read(byte[] buffer, int offset, int count) { + lock (_sync) { + int read = Math.Min(count, _incoming.Count); + for (int index = 0; index < read; index++) { + buffer[offset + index] = _incoming.Dequeue(); + } + return read; + } + } + + public void DiscardInBuffer() { + lock (_sync) { + _incoming.Clear(); + } + } + + public void Close() => IsOpen = false; + public void Open() => IsOpen = true; + public int ReadByte() => -1; + public int ReadChar() => -1; + public string ReadExisting() => ""; + public string ReadLine() => ""; + public void Write(string text) => Write(Encoding.ASCII.GetBytes(text), 0, text.Length); + public void WriteLine(string text) => Write(text + "\n"); + public void toggleDTR() { } + + public void Dispose() { + IsOpen = false; + BaseStream.Dispose(); + } + } +} diff --git a/MissionPlannerTests/Avalonia/MissionPlanner.Tests/SerialPortEnumerationTests.cs b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/SerialPortEnumerationTests.cs new file mode 100644 index 0000000000..988025190e --- /dev/null +++ b/MissionPlannerTests/Avalonia/MissionPlanner.Tests/SerialPortEnumerationTests.cs @@ -0,0 +1,75 @@ +using System.Diagnostics; +using MissionPlanner.Comms; + +namespace MissionPlanner.Tests; + +public sealed class SerialPortEnumerationTests { + [Fact] + public void Successful_probe_returns_an_independent_snapshot() { + string[] source = ["COM1", "COM2"]; + var enumerator = new BoundedPortNameEnumerator(() => source); + + PortNameEnumerationResult result = enumerator.TryEnumerate(1000); + source[0] = "changed"; + + Assert.True(result.Succeeded); + Assert.False(result.TimedOut); + Assert.Null(result.Error); + Assert.Equal(["COM1", "COM2"], result.Ports); + } + + [Fact] + public void Provider_failure_is_contained_and_a_later_probe_can_retry() { + int calls = 0; + var enumerator = new BoundedPortNameEnumerator(() => { + if (Interlocked.Increment(ref calls) == 1) { + throw new InvalidOperationException("driver failed"); + } + return ["COM7"]; + }); + + PortNameEnumerationResult failed = enumerator.TryEnumerate(1000); + PortNameEnumerationResult recovered = enumerator.TryEnumerate(1000); + + Assert.False(failed.Succeeded); + Assert.False(failed.TimedOut); + Assert.IsType(failed.Error); + Assert.True(recovered.Succeeded); + Assert.Equal(["COM7"], recovered.Ports); + Assert.Equal(2, calls); + } + + [Fact] + public void Timed_out_probe_is_single_flight_and_recovers_when_driver_returns() { + using var entered = new ManualResetEventSlim(); + using var release = new ManualResetEventSlim(); + int calls = 0; + var enumerator = new BoundedPortNameEnumerator(() => { + Interlocked.Increment(ref calls); + entered.Set(); + release.Wait(); + return ["COM9"]; + }); + + PortNameEnumerationResult first = enumerator.TryEnumerate(25); + Assert.True(entered.Wait(TimeSpan.FromSeconds(1))); + var stopwatch = Stopwatch.StartNew(); + PortNameEnumerationResult second = enumerator.TryEnumerate(1000); + stopwatch.Stop(); + + Assert.True(first.TimedOut); + Assert.True(second.TimedOut); + Assert.Equal(1, Volatile.Read(ref calls)); + Assert.True(stopwatch.Elapsed < TimeSpan.FromMilliseconds(250), + $"Repeated timed-out probe took {stopwatch.Elapsed}."); + + release.Set(); + PortNameEnumerationResult recovered = default!; + Assert.True(SpinWait.SpinUntil(() => { + recovered = enumerator.TryEnumerate(1000); + return recovered.Succeeded; + }, TimeSpan.FromSeconds(2))); + Assert.Equal(["COM9"], recovered.Ports); + Assert.Equal(1, Volatile.Read(ref calls)); + } +} diff --git a/Porting/KEY_ARTIFACT_AUDIT.tsv b/Porting/KEY_ARTIFACT_AUDIT.tsv index dd32000a43..3828eb14bb 100644 --- a/Porting/KEY_ARTIFACT_AUDIT.tsv +++ b/Porting/KEY_ARTIFACT_AUDIT.tsv @@ -11,7 +11,7 @@ ExtLibs/GeoUtility/mykey.snk remove ExtLibs/GeoUtility/GeoUtility.csproj Unrefer ExtLibs/KMLib/mykey.pfx remove ExtLibs/KMLib/KMLib.csproj Unreferenced duplicate PFX container; it is not a release/update signing key or build input. ExtLibs/KMLib/mykey.snk remove ExtLibs/KMLib/KMLib.csproj Unreferenced inherited strong-name key. ExtLibs/LibVLC.NET/mykey.snk remove ExtLibs/LibVLC.NET/LibVLC.NET.csproj Unreferenced inherited strong-name key. -ExtLibs/MetaDataExtractorCSharp240d/dontcare.snk remove ExtLibs/MetaDataExtractorCSharp240d/MetaDataExtractor.csproj Unreferenced legacy placeholder strong-name key. +ExtLibs/MetaDataExtractorCSharp240d/dontcare.snk remove MissionPlanner.csproj Unreferenced placeholder key from the retired legacy EXIF project; active metadata reading uses the maintained package. ExtLibs/MissionPlanner.Drawing/Open.snk remove ExtLibs/MissionPlanner.Drawing/MissionPlanner.Drawing.csproj Unreferenced inherited strong-name key. ExtLibs/MissionPlanner.Drawing/ecma.pub remove ExtLibs/MissionPlanner.Drawing/MissionPlanner.Drawing.csproj Unused public-key stub referenced only by a commented assembly attribute. ExtLibs/SharpKml/dont care.snk remove ExtLibs/SharpKml/SharpKml.csproj Unreferenced legacy placeholder strong-name key. diff --git a/Porting/PROJECT_ARTIFACT_AUDIT.tsv b/Porting/PROJECT_ARTIFACT_AUDIT.tsv index 77dab13194..1a1b1880e4 100644 --- a/Porting/PROJECT_ARTIFACT_AUDIT.tsv +++ b/Porting/PROJECT_ARTIFACT_AUDIT.tsv @@ -47,7 +47,8 @@ ExtLibs/tlogThumbnailHandler remove Services/LogIndexService.cs Windows shell ex ExtLibs/zlib.net remove MissionPlanner.slnx Unreferenced legacy zlib snapshot; active compression paths use current framework/SharpZipLib implementations. LogAnalyzer remove Services/LogAnalyzer.cs Python 2/py2exe analyzer replaced by the in-process cross-platform implementation of all 17 enabled checks and regression tests. ExtLibs/px4uploader/android.bat remove ExtLibs/px4uploader/px4uploader.csproj Obsolete netcoreapp3.1 Android publish command; the retained uploader is a net10 desktop library in the active graph. -ExtLibs/MetaDataExtractorCSharp240d/AssemblyInfo.cs remove ExtLibs/MetaDataExtractorCSharp240d/MetaDataExtractor.csproj Empty source file with no attributes or generated-build role. +ExtLibs/MetaDataExtractorCSharp240d remove MissionPlanner.csproj Unreferenced 2004-era EXIF project; active GeoRef and Survey workflows use the maintained MetadataExtractor package. +ExtLibs/MetaDataExtractorCSharp240d/AssemblyInfo.cs remove MissionPlanner.csproj Empty source file from the retired legacy EXIF project. MissionPlanner.GCSViews.ConfigurationView.ConfigGPSOrder+GPSCAN.datasource remove GCSViews/ConfigurationView/ConfigGPSOrderView.axaml Generated WinForms object-data-source metadata; the current GPS-order editor is native Avalonia. MissionPlanner.GCSViews.ConfigurationView.ConfigHWCompass2+CompassDeviceInfo.datasource remove GCSViews/ConfigurationView/ConfigCompassView.axaml Generated WinForms object-data-source metadata; the current compass editor is native Avalonia. MissionPlanner.GCSViews.ConfigurationView.DeviceInfo.datasource remove GCSViews/ConfigurationView/ConfigDroneCanView.axaml Generated WinForms object-data-source metadata; current device information is rendered by native views. diff --git a/Porting/STATUS.md b/Porting/STATUS.md index 7a1396cf8a..307e69b9d2 100644 --- a/Porting/STATUS.md +++ b/Porting/STATUS.md @@ -33,7 +33,7 @@ Updated: **2026-08-24**. migration evidence, not a copied source tree. - A clean Release build of the complete test graph succeeds with zero warnings and zero errors after resolving all 156 inherited `ExtLibs` diagnostics without a repository-wide `NoWarn`; the - decisions and reproduction commands are recorded in `WARNING_AUDIT.md`. All **1266/1266** + decisions and reproduction commands are recorded in `WARNING_AUDIT.md`. All **1344/1344** Avalonia tests pass on Linux. A 12-second Xvfb launch reaches the normal Avalonia event loop with no console errors. - Informational version is derived from the current native Mission Planner version and formatted as @@ -121,6 +121,39 @@ Updated: **2026-08-24**. silently into the working directory. - Claude remains temporarily disabled by user instruction. +## Upstream safety and issue audit + +- Branch `fix/upstream-safety-reliability` adapts the applicable parts of upstream PRs #3728, + #3740, #3710, #3715, #3724, #3679, #3705, #3222, #3603, #3752, #3750/#3722, #3250 and #3646. + The changes preserve guided altitude frames, bound serial enumeration, harden MAVFTP/MJPEG/HTTP + parsing and resource ownership, use current guided commands, lease camera/gimbal message rates, + correct mission ACK behavior, snapshot proximity state safely, detect Septentrio ports, expose + compass-calibration failures, expire stale pre-arm failures and report Windows-blocked plugins. + Each adaptation is native to the Avalonia/CoreCLR architecture and has focused regression tests; + obsolete WinForms-only implementation details were not copied. +- The 59 open bug-labelled upstream issues and the 100 most recently updated open issues were + triaged against the live port, including linked commits and PRs. Two additional reports were + confirmed in current code and fixed: #3461 now tracks actual DataFlash byte ranges, keeps progress + monotonic, repairs bounded gaps, times out cleanly and always ends the MAVLink log session; #3694 + atomically preserves MAVLink signing keys, migrates every available legacy MAC-derived identity + to persistent `authkeys.key` material and refuses to overwrite an unreadable `authkeys.xml`. +- Rejected transfers are recorded by reason rather than silently copied. Examples: #3736 targets + the retired ZedGraph/WinForms viewer; #3658 and #3601 target Mono RESX/GStreamer paths absent from + Avalonia; #3516 targets the retired WinForms internet firmware picker; #3472/#3391 target old + MAVFTP rename/drag-drop UI not exposed by the port; #3734 is already stricter because the current + server is loopback-only and has no guided/raw endpoints. #3746 must be corrected in ArduPilot's + parameter metadata itself: its current `AC_AttitudeControl_Heli.cpp` still declares + `HOVR_ROL_TRM` as `0 1000`, so overriding it only in Mission Planner would create conflicting + safety metadata. +- The project audit exposed an incomplete earlier cleanup: only the placeholder key and empty + assembly file had been removed from `ExtLibs/MetaDataExtractorCSharp240d`. The remaining 117-file, + 2004-era source project had no solution, source or runtime consumer; GeoRef/Survey use the pinned + maintained `MetadataExtractor` package. The complete obsolete tree is now removed and the project + and key audits record that decision. +- Current local verification: Release solution build **0 warnings / 0 errors**, **1344/1344** tests, + all six porting/inventory checks pass, the native manifest has **0 blockers**, and every active + project reports no known vulnerable direct or transitive NuGet package. + ## GTU synchronization checkpoint - NV modem behavior was last compared with `/home/alex/src/AgroSky/GTU` at clean local and fetched @@ -176,14 +209,15 @@ Updated: **2026-08-24**. ## Immediate next step -The software build, automated test, security-scan and package gates are complete. The remaining -acceptance work requires representative physical NV4/NV5 hardware: repeat UDP/TCP/UART switching, -disconnect and key-programming checks, and recheck GTU `NV5Settings` changes newer than clean -checkpoint `6c2a4b04` before declaring hardware acceptance complete. +Push `fix/upstream-safety-reliability`, run its full CI/package and CodeQL gates, review the draft +PR, then merge only after those checks pass. After merge, the remaining acceptance work requires +representative physical NV4/NV5 hardware: repeat UDP/TCP/UART switching, disconnect and +key-programming checks, and recheck GTU `NV5Settings` changes newer than clean checkpoint +`6c2a4b04` before declaring hardware acceptance complete. ## Acceptance baseline -- At least 1266 port tests retained and passing. +- At least 1344 port tests retained and passing. - Clean Release build has zero errors and zero warnings. - `linux-x64`, `win-x64`, `osx-x64`, and `osx-arm64` publish gates pass. - Linux `.deb`/portable archive, Windows ZIP/MSI and both macOS ZIP/DMG pairs build and pass their diff --git a/Services/PluginRuntime.cs b/Services/PluginRuntime.cs index dd9b18a356..e4d643aa0c 100644 --- a/Services/PluginRuntime.cs +++ b/Services/PluginRuntime.cs @@ -25,6 +25,7 @@ internal enum PluginFileState { Loaded, Declined, Dependency, + Blocked, Failed, } @@ -53,6 +54,7 @@ internal sealed class PluginRuntime : IAsyncDisposable { private readonly string[] _pluginDirectories; private readonly Func _hostFactory; private readonly Func, Task> _loadedInvoker; + private readonly Func _zoneIdentifier; private readonly Action? _diagnostic; private readonly SemaphoreSlim _loadGate = new(1, 1); private readonly CancellationTokenSource _shutdown = new(); @@ -66,7 +68,8 @@ public PluginRuntime( IEnumerable disabledPluginNames, Func hostFactory, Func, Task>? loadedInvoker = null, - Action? diagnostic = null) { + Action? diagnostic = null, + Func? zoneIdentifier = null) { ArgumentNullException.ThrowIfNull(pluginDirectories); ArgumentNullException.ThrowIfNull(disabledPluginNames); ArgumentNullException.ThrowIfNull(hostFactory); @@ -83,6 +86,7 @@ public PluginRuntime( _hostFactory = hostFactory; _loadedInvoker = loadedInvoker ?? (callback => Task.FromResult(callback())); _diagnostic = diagnostic; + _zoneIdentifier = zoneIdentifier ?? ReadWindowsZoneIdentifier; _files = new Dictionary(_pathComparer); } @@ -182,6 +186,19 @@ private void DiscoverFiles() { private async Task LoadFileAsync(PluginFileEntry file, CancellationToken cancellationToken) { SetState(file, PluginFileState.Loading, ""); + try { + int? zone = _zoneIdentifier(file.Path); + if (zone >= 3) { + const string guidance = + "Plugin is blocked by Windows because it came from the Internet. " + + "Review it, then use the file Properties dialog to unblock it if you trust it."; + SetState(file, PluginFileState.Blocked, guidance); + Report($"Blocked plugin {file.FileName}: Windows Zone.Identifier={zone}."); + return; + } + } catch (Exception ex) { + Report($"Cannot inspect Windows Zone.Identifier for {file.FileName}: {ex.Message}"); + } if (IsNativePortableExecutable(file.Path)) { SetState(file, PluginFileState.Dependency, ""); return; @@ -483,6 +500,35 @@ private static bool IsNativePortableExecutable(string path) { } } + internal static int? ParseZoneIdentifier(string content) { + if (string.IsNullOrWhiteSpace(content)) { + return null; + } + foreach (string rawLine in content.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries)) { + string line = rawLine.Trim(); + int equals = line.IndexOf('='); + if (equals <= 0 || !line[..equals].Trim().Equals( + "ZoneId", StringComparison.OrdinalIgnoreCase)) { + continue; + } + return int.TryParse(line[(equals + 1)..].Trim(), out int zone) ? zone : null; + } + return null; + } + + private static int? ReadWindowsZoneIdentifier(string path) { + if (!OperatingSystem.IsWindows()) { + return null; + } + try { + return ParseZoneIdentifier(File.ReadAllText(path + ":Zone.Identifier")); + } catch (FileNotFoundException) { + return null; + } catch (DirectoryNotFoundException) { + return null; + } + } + private sealed class PluginFileEntry(string path, string fileName) { public string Path { get; } = path; public string FileName { get; } = fileName; diff --git a/ViewModels/ExternalGuidedViewModel.cs b/ViewModels/ExternalGuidedViewModel.cs index e1fb18f774..93ca769a8b 100644 --- a/ViewModels/ExternalGuidedViewModel.cs +++ b/ViewModels/ExternalGuidedViewModel.cs @@ -226,6 +226,7 @@ private async Task SendLoop( } else { var location = new Locationwp { id = (ushort)MAVLink.MAV_CMD.WAYPOINT, + frame = (byte)MAVLink.MAV_FRAME.GLOBAL_RELATIVE_ALT, lat = waypoint.Latitude, lng = waypoint.Longitude, alt = (float)waypoint.RelativeAltitudeM, diff --git a/ViewModels/FlightDataViewModel.cs b/ViewModels/FlightDataViewModel.cs index ae7b07475f..2a651ed097 100644 --- a/ViewModels/FlightDataViewModel.cs +++ b/ViewModels/FlightDataViewModel.cs @@ -1856,9 +1856,9 @@ private async Task ChangeAlt() { int newalt = (int)ChangeAltValue; try { await Task.Run(() => - _comPort.setNewWPAlt(new MissionPlanner.Utilities.Locationwp { - alt = newalt / MissionPlanner.CurrentState.multiplieralt, - })); + _comPort.setNewAlt(Sysid, Compid, + (float)DisplayToVehicleAltitude( + newalt, MissionPlanner.CurrentState.multiplieralt))); Log($"Change alt {newalt}"); } catch (Exception ex) { await Services.Dialogs.Alert("Change Altitude", "Command failed: " + ex.Message); @@ -3749,12 +3749,12 @@ internal async Task HandleGimbalVideoPointerCommand( bool accepted; switch (command.Action) { case GimbalVideoPointerAction.TrackPoint: - camera.RequestTrackingMessageInterval(5); + camera.SubscribeTracking(5); accepted = await camera.SetTrackingPointAsync( (float)command.End.X, (float)command.End.Y); break; case GimbalVideoPointerAction.TrackRectangle: - camera.RequestTrackingMessageInterval(5); + camera.SubscribeTracking(5); accepted = await camera.SetTrackingRectangleAsync( (float)command.Start.X, (float)command.Start.Y, diff --git a/ViewModels/FollowMeViewModel.cs b/ViewModels/FollowMeViewModel.cs index efdea2f213..5844ecd622 100644 --- a/ViewModels/FollowMeViewModel.cs +++ b/ViewModels/FollowMeViewModel.cs @@ -309,6 +309,7 @@ private async Task SendLoop( } else { var waypoint = new Locationwp { id = (ushort)MAVLink.MAV_CMD.WAYPOINT, + frame = (byte)MAVLink.MAV_FRAME.GLOBAL_RELATIVE_ALT, alt = (float)position.AltitudeM, lat = position.Latitude, lng = position.Longitude, diff --git a/ViewModels/GCSViews/ConfigurationView/ConfigAdvancedViewModel.cs b/ViewModels/GCSViews/ConfigurationView/ConfigAdvancedViewModel.cs index feea1c1779..473f01dd35 100644 --- a/ViewModels/GCSViews/ConfigurationView/ConfigAdvancedViewModel.cs +++ b/ViewModels/GCSViews/ConfigurationView/ConfigAdvancedViewModel.cs @@ -77,6 +77,15 @@ await Task.Run(() => { } private async Task ManageSigningAsync() { + if (!MAVAuthKeys.IsAvailable) { + await Dialogs.Alert( + "MAVLink Signing", + "Stored signing keys could not be decrypted. The existing authkeys.xml file was " + + "preserved and changes are disabled to prevent data loss.\n\n" + + MAVAuthKeys.LoadFailure.Message); + return; + } + while (true) { var current = CurrentSigningKeyName(); var choice = await Dialogs.Choice( diff --git a/ViewModels/GCSViews/ConfigurationView/ConfigCalibrationPages.cs b/ViewModels/GCSViews/ConfigurationView/ConfigCalibrationPages.cs index 82aa9e4e63..7eb346da05 100644 --- a/ViewModels/GCSViews/ConfigurationView/ConfigCalibrationPages.cs +++ b/ViewModels/GCSViews/ConfigurationView/ConfigCalibrationPages.cs @@ -3,6 +3,7 @@ using System.Collections.ObjectModel; using System.IO; using System.Linq; +using System.Reflection; using System.Text; using System.Text.Json; using System.Threading.Tasks; @@ -692,21 +693,22 @@ private bool ReceivedPacket(MAVLink.MAVLinkMessage packet) { } Dispatcher.UIThread.Post(() => { + int reportProgress = MagCalStatusFormatter.ProgressForReport(obj.cal_status); if (obj.compass_id == 0) { - Prog1 = 100; + Prog1 = reportProgress; } if (obj.compass_id == 1) { - Prog2 = 100; + Prog2 = reportProgress; } if (obj.compass_id == 2) { - Prog3 = 100; + Prog3 = reportProgress; } MagResult += $"id:{obj.compass_id} x:{obj.ofs_x:0.0} y:{obj.ofs_y:0.0} z:{obj.ofs_z:0.0} " - + $"fit:{obj.fitness:0.0} {(MAVLink.MAG_CAL_STATUS)obj.cal_status}\n"; + + $"fit:{obj.fitness:0.0} {MagCalStatusFormatter.Describe(obj.cal_status)}\n"; if (obj.autosaved == 1) { MagResult += "Calibration saved. Please reboot the autopilot.\n"; @@ -825,6 +827,22 @@ public string DevType { } } +internal static class MagCalStatusFormatter { + internal static bool IsFailure(byte wireValue) => + wireValue > (byte)MAVLink.MAG_CAL_STATUS.MAG_CAL_SUCCESS; + + internal static int ProgressForReport(byte wireValue) => IsFailure(wireValue) ? 0 : 100; + + internal static string Describe(byte wireValue) { + var status = (MAVLink.MAG_CAL_STATUS)wireValue; + string name = Enum.GetName(typeof(MAVLink.MAG_CAL_STATUS), status) + ?? $"MAG_CAL_STATUS({wireValue})"; + FieldInfo? field = typeof(MAVLink.MAG_CAL_STATUS).GetField(name); + string? description = field?.GetCustomAttribute()?.Text; + return string.IsNullOrWhiteSpace(description) ? name : description; + } +} + public partial class ConfigESCCalibrationViewModel : ParamPageBase { public ConfigESCCalibrationViewModel() { Title = "ESC Calibration (AC3.3+)"; diff --git a/ViewModels/GCSViews/ConfigurationView/ConfigCompassLegacyViewModel.cs b/ViewModels/GCSViews/ConfigurationView/ConfigCompassLegacyViewModel.cs index 285d1f3dee..066a7034c0 100644 --- a/ViewModels/GCSViews/ConfigurationView/ConfigCompassLegacyViewModel.cs +++ b/ViewModels/GCSViews/ConfigurationView/ConfigCompassLegacyViewModel.cs @@ -440,21 +440,22 @@ private bool ReceivedPacket(MAVLink.MAVLinkMessage packet) { } Dispatcher.UIThread.Post(() => { + int reportProgress = MagCalStatusFormatter.ProgressForReport(obj.cal_status); if (obj.compass_id == 0) { - Prog1 = 100; + Prog1 = reportProgress; } if (obj.compass_id == 1) { - Prog2 = 100; + Prog2 = reportProgress; } if (obj.compass_id == 2) { - Prog3 = 100; + Prog3 = reportProgress; } MagResult += $"id:{obj.compass_id} x:{obj.ofs_x:0.0} y:{obj.ofs_y:0.0} z:{obj.ofs_z:0.0} " - + $"fit:{obj.fitness:0.0} {(MAVLink.MAG_CAL_STATUS)obj.cal_status}\n"; + + $"fit:{obj.fitness:0.0} {MagCalStatusFormatter.Describe(obj.cal_status)}\n"; if (obj.autosaved == 1) { MagResult += "Calibration saved. Please reboot the autopilot.\n"; diff --git a/ViewModels/OpenDroneIdViewModel.cs b/ViewModels/OpenDroneIdViewModel.cs index ab7dcc4551..2e5b5ebfeb 100644 --- a/ViewModels/OpenDroneIdViewModel.cs +++ b/ViewModels/OpenDroneIdViewModel.cs @@ -278,7 +278,7 @@ partial void OnSelectedInputChanged(string? value) { private void RefreshInputs() { string? selected = SelectedInput; Inputs.Clear(); - foreach (string port in System.IO.Ports.SerialPort.GetPortNames() + foreach (string port in MissionPlanner.Comms.SerialPort.GetPortNames() .Distinct().OrderBy(item => item)) { Inputs.Add(port); } diff --git a/ViewModels/TrackerHomeModuleViewModel.cs b/ViewModels/TrackerHomeModuleViewModel.cs index faa8a832b4..7d3cbb2c21 100644 --- a/ViewModels/TrackerHomeModuleViewModel.cs +++ b/ViewModels/TrackerHomeModuleViewModel.cs @@ -97,7 +97,7 @@ partial void OnSelectedInputChanged(string? value) { private void RefreshInputs() { string? selected = SelectedInput; Inputs.Clear(); - foreach (string port in System.IO.Ports.SerialPort.GetPortNames() + foreach (string port in MissionPlanner.Comms.SerialPort.GetPortNames() .Distinct(StringComparer.Ordinal).OrderBy(item => item, StringComparer.Ordinal)) { Inputs.Add(port); }