Example #1
0
        /// <summary>
        /// Get a list of all pointer of the cameras connected to the host
        /// </summary>
        /// <returns>A list of connected cameras as pointer</returns>
        /// <exception cref="ObjectDisposedException">This instance has been disposed already</exception>
        /// <exception cref="SDKException">An SDK call failed</exception>
        protected IEnumerable <IntPtr> GetCameraPointerList()
        {
            if (IsDisposed)
            {
                throw new ObjectDisposedException(nameof(CanonAPI));
            }

            IntPtr camlist;

            //Get camera list
            ErrorHandler.CheckError(this, CanonSDK.EdsGetCameraList(out camlist));

            //Get number of connected cameras
            int camCount;

            ErrorHandler.CheckError(this, CanonSDK.EdsGetChildCount(camlist, out camCount));
            List <IntPtr> ptrList = new List <IntPtr>();

            for (int i = 0; i < camCount; i++)
            {
                //Get camera pointer
                IntPtr cptr;
                ErrorHandler.CheckError(this, CanonSDK.EdsGetChildAtIndex(camlist, i, out cptr));
                ptrList.Add(cptr);
            }
            //Release the list
            ErrorHandler.CheckError(this, CanonSDK.EdsRelease(camlist));
            return(ptrList);
        }
Example #2
0
        /// <summary>
        /// Gets a <see cref="Bitmap"/> from an EDSDK pointer to an image (Jpg or Raw)
        /// </summary>
        /// <param name="imgStream">Stream pointer to the image</param>
        /// <param name="imageSource">The result image type</param>
        /// <returns>A <see cref="Bitmap"/> image from the given stream pointer</returns>
        protected Bitmap GetImage(IntPtr imgStream, ImageSource imageSource)
        {
            IntPtr    imgRef        = IntPtr.Zero;
            IntPtr    streamPointer = IntPtr.Zero;
            ImageInfo imageInfo;

            try
            {
                //create reference and get image info
                ErrorHandler.CheckError(this, CanonSDK.EdsCreateImageRef(imgStream, out imgRef));
                ErrorHandler.CheckError(this, CanonSDK.EdsGetImageInfo(imgRef, imageSource, out imageInfo));

                Size outputSize = new Size();
                outputSize.Width  = imageInfo.EffectiveRect.Width;
                outputSize.Height = imageInfo.EffectiveRect.Height;
                //calculate amount of data
                int datalength = outputSize.Height * outputSize.Width * 3;
                //create buffer that stores the image
                byte[] buffer = new byte[datalength];
                //create a stream to the buffer
                using (var stream = new SDKStream(buffer))
                {
                    //load image into the buffer
                    ErrorHandler.CheckError(this, CanonSDK.EdsGetImage(imgRef, imageSource, TargetImageType.RGB, imageInfo.EffectiveRect, outputSize, stream.Reference));

                    //make BGR from RGB (System.Drawing (i.e. GDI+) uses BGR)
                    unsafe
                    {
                        byte tmp;
                        fixed(byte *pix = buffer)
                        {
                            for (long i = 0; i < datalength; i += 3)
                            {
                                tmp        = pix[i];     //Save B value
                                pix[i]     = pix[i + 2]; //Set B value with R value
                                pix[i + 2] = tmp;        //Set R value with B value
                            }
                        }
                    }

                    //Get pointer to stream data
                    ErrorHandler.CheckError(this, CanonSDK.EdsGetPointer(stream.Reference, out streamPointer));
                    //Create bitmap with the data in the buffer
                    return(new Bitmap(outputSize.Width, outputSize.Height, datalength, PixelFormat.Format24bppRgb, streamPointer));
                }
            }
            finally
            {
                //Release all data
                if (imgStream != IntPtr.Zero)
                {
                    ErrorHandler.CheckError(this, CanonSDK.EdsRelease(imgStream));
                }
                if (imgRef != IntPtr.Zero)
                {
                    ErrorHandler.CheckError(this, CanonSDK.EdsRelease(imgRef));
                }
            }
        }
Example #3
0
 /// <summary>
 /// Creates a new instance of the <see cref="SDKStream"/> class with an underlying SDK file stream
 /// </summary>
 /// <param name="filepath">Path to the file</param>
 /// <param name="createDisposition">State how to create the stream</param>
 /// <param name="access">File access type</param>
 public SDKStream(string filepath, FileCreateDisposition createDisposition, FileAccess access)
 {
     if (filepath == null)
     {
         throw new ArgumentNullException(nameof(filepath));
     }
     ErrorHandler.CheckError(CanonSDK.EdsCreateFileStreamEx(filepath, createDisposition, access, out _Reference));
 }
Example #4
0
        /// <summary>
        /// Creates a new instance of the <see cref="SDKStream"/> class with an underlying SDK memory stream.
        /// This stream will resize itself if the current length is exceeded
        /// </summary>
        /// <param name="length">Initial buffer size of the stream in bytes</param>
        public SDKStream(long length)
        {
            ErrorCode err;

            if (CanonSDK.IsVerGE34)
            {
                err = CanonSDK.EdsCreateMemoryStream(length, out _Reference);
            }
            else
            {
                err = CanonSDK.EdsCreateMemoryStream((int)length, out _Reference);
            }
            ErrorHandler.CheckError(err);
        }
Example #5
0
        /// <summary>
        /// Initializes the SDK
        /// </summary>
        /// <param name="useCallingThread">If true, the calling thread will be used as SDK main thread;
        /// if false, a separate thread will be created</param>
        public CanonAPI(bool useCallingThread)
        {
            try
            {
                //Ensure that only one caller at a time can increase the counter
                lock (InitLock)
                {
                    //If no instance exists yet, initialize everything
                    if (RefCount == 0)
                    {
                        if (useCallingThread)
                        {
                            if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA)
                            {
                                throw new ThreadStateException("Calling thread must be in STA");
                            }
                            ErrorHandler.CheckError(this, CanonSDK.EdsInitializeSDK());
                        }
                        else
                        {
                            //Trying to trigger DllNotFoundException so it's not thrown
                            //in the event loop on a different thread:
                            CanonSDK.EdsRelease(IntPtr.Zero);

                            //Start the main thread where SDK will run on
                            MainThread = new ApiThread();
                            MainThread.Start();
                            //Initialize the SDK on the main thread
                            MainThread.Invoke(() => ErrorHandler.CheckError(this, CanonSDK.EdsInitializeSDK()));
                        }

                        CanonSDK.InitializeVersion();
                        //Subscribe to the CameraAdded event
                        CameraAddedEvent = new SDKCameraAddedHandler(CanonAPI_CameraAddedEvent);
                        ErrorHandler.CheckError(this, CanonSDK.EdsSetCameraAddedHandler(CameraAddedEvent, IntPtr.Zero));
                        _IsSDKInitialized = true;
                    }
                    RefCount++;
                }
            }
            catch (Exception e)
            {
                IsDisposed = true;
                if (MainThread?.IsRunning == true)
                {
                    MainThread.Shutdown();
                }
                throw;
            }
        }
Example #6
0
 /// <summary>
 /// Releases this entry but not the subentries
 /// </summary>
 /// <param name="managed">True if called from Dispose, false if called from the finalizer/destructor</param>
 protected virtual void Dispose(bool managed)
 {
     if (!IsDisposed)
     {
         if (managed)
         {
             DisposeThumb();
         }
         if (Reference != IntPtr.Zero)
         {
             CanonSDK.EdsRelease(Reference);
         }
         IsDisposed = true;
     }
 }
Example #7
0
 protected override void WaitForNotification()
 {
     lock (threadLock1)
     {
         while (block1 && IsRunning)
         {
             Monitor.Wait(threadLock1, 0);
             lock (ExecLock)
             {
                 CanonSDK.EdsGetEvent();
                 Monitor.Wait(ExecLock, 40);
             }
         }
         block1 = true;
     }
 }
Example #8
0
        /// <summary>
        /// Creates a new instance of the <see cref="SDKStream"/> class with an underlying SDK memory stream.
        /// Note that this stream will not resize itself
        /// </summary>
        /// <param name="buffer">Pointer to the memory buffer to use for the stream</param>
        /// <param name="length">The size of the memory buffer in bytes</param>
        public SDKStream(IntPtr buffer, long length)
        {
            if (buffer == IntPtr.Zero)
            {
                throw new ArgumentNullException(nameof(buffer));
            }

            ErrorCode err;

            if (CanonSDK.IsVerGE34)
            {
                err = CanonSDK.EdsCreateMemoryStreamFromPointer(buffer, length, out _Reference);
            }
            else
            {
                err = CanonSDK.EdsCreateMemoryStreamFromPointer(buffer, (int)length, out _Reference);
            }
            ErrorHandler.CheckError(err);
        }
Example #9
0
        /// <summary>
        /// Creates a new instance of the <see cref="SDKStream"/> class with an underlying SDK memory stream.
        /// Note that this stream will not resize itself
        /// </summary>
        /// <param name="buffer">The memory buffer to use for the stream</param>
        public SDKStream(byte[] buffer)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }

            ErrorCode err;

            if (CanonSDK.IsVerGE34)
            {
                err = CanonSDK.EdsCreateMemoryStreamFromPointer(buffer, buffer.LongLength, out _Reference);
            }
            else
            {
                err = CanonSDK.EdsCreateMemoryStreamFromPointer(buffer, (int)buffer.LongLength, out _Reference);
            }
            ErrorHandler.CheckError(err);
        }
Example #10
0
        /// <summary>
        /// Creates a new instance of the <see cref="DownloadInfo"/> class
        /// </summary>
        /// <param name="inRef">Pointer to the downloadable object</param>
        internal protected DownloadInfo(IntPtr inRef)
        {
            if (inRef == IntPtr.Zero)
            {
                throw new ArgumentNullException(nameof(inRef));
            }

            this.inRef = inRef;
            ErrorHandler.CheckError(this, CanonSDK.GetDirectoryItemInfo(inRef, out dirInfo));
            string ext = Path.GetExtension(FileName).ToLower();

            if (ext == ".crw" || ext == ".cr2")
            {
                IsRAW = true;
            }
            else
            {
                IsRAW = false;
            }
        }
Example #11
0
        /// <summary>
        /// Terminates the SDK and disposes resources
        /// </summary>
        /// <param name="managed">True if called from Dispose, false if called from the finalizer/destructor</param>
        protected virtual void Dispose(bool managed)
        {
            //Ensure that only one caller at a time can decrease the counter
            lock (InitLock)
            {
                if (!IsDisposed)
                {
                    //If it's the last instance, release everything
                    if (RefCount == 1)
                    {
                        _IsSDKInitialized = false;//Set beforehand because if an error happens, the SDK will be in an unstable state anyway

                        //Remove event handler for the CameraAdded event
                        ErrorCode err = CanonSDK.EdsSetCameraAddedHandler(null, IntPtr.Zero);
                        if (managed)
                        {
                            ErrorHandler.CheckError(this, err);
                            //Dispose all the connected cameras
                            CurrentCameras.ForEach(t => t.Dispose());
                        }
                        //Terminate the SDK
                        if (MainThread?.IsRunning == true)
                        {
                            err = MainThread.Invoke(() => { return(CanonSDK.EdsTerminateSDK()); });
                        }
                        //Close the main thread
                        if (MainThread?.IsRunning == true)
                        {
                            MainThread.Shutdown();
                        }
                        if (managed)
                        {
                            ErrorHandler.CheckError(this, err);
                        }
                    }
                    RefCount--;
                    IsDisposed = true;
                }
            }
        }
Example #12
0
        /// <summary>
        /// Sets the position within the current stream.
        /// </summary>
        /// <param name="offset">A byte offset relative to the origin parameter.</param>
        /// <param name="origin">A value of type <see cref="SeekOrigin"/> indicating the
        /// reference point used to obtain the new position.</param>
        /// <returns>The new position within the current stream.</returns>
        public override long Seek(long offset, SeekOrigin origin)
        {
            SDK.SeekOrigin sdkOrigin;
            switch (origin)
            {
            case SeekOrigin.Begin:
                sdkOrigin = SDK.SeekOrigin.Begin;
                break;

            case SeekOrigin.Current:
                sdkOrigin = SDK.SeekOrigin.Current;
                break;

            case SeekOrigin.End:
                sdkOrigin = SDK.SeekOrigin.End;
                break;

            default:
                throw new ArgumentException("Not a valid enum value", nameof(origin));
            }

            if (CanonSDK.IsVerGE34)
                ErrorHandler.CheckError(CanonSDK.EdsSeek(_Reference, offset, sdkOrigin)); }
Example #13
0
        /// <summary>
        /// Reads a sequence of bytes from the current stream and advances the position
        /// within the stream by the number of bytes read.
        /// </summary>
        /// <param name="buffer">An array of bytes. When this method returns, the buffer contains the specified
        /// byte array with the values between offset and (offset + count - 1) replaced by
        /// the bytes read from the current source.</param>
        /// <param name="offset">The zero-based byte offset in buffer at which to begin storing the data read
        /// from the current stream.</param>
        /// <param name="count">The maximum number of bytes to be read from the current stream.</param>
        /// <returns>The total number of bytes read into the buffer. This can be less than the number
        /// of bytes requested if that many bytes are not currently available, or zero (0)
        /// if the end of the stream has been reached.</returns>
        public unsafe long Read(byte[] buffer, long offset, long count)
        {
            if (buffer.LongLength < offset + count)
            {
                throw new ArgumentOutOfRangeException();

                fixed(byte *bufferPtr = buffer)
                {
                    byte *offsetBufferPtr = bufferPtr + offset;

                    if (CanonSDK.IsVerGE34)
                    {
                        long read;
                        ErrorHandler.CheckError(CanonSDK.EdsRead(_Reference, count, (IntPtr)offsetBufferPtr, out read));
                        return(read);
                    }
                    else
                    {
                        int read;
                        ErrorHandler.CheckError(CanonSDK.EdsRead(_Reference, (int)count, (IntPtr)offsetBufferPtr, out read));
                        return(read);
                    }
                }
        }