public void OnMprDone(ImageDataContract idc, DateTime requestTime)
    {
        ResponseContext responseContext =
            OperationContext.Current.IncomingMessageHeaders.GetHeader<ResponseContext>(
                "ResponseContext", "ServiceModelEx");
        string methodID = responseContext.MethodId;

        MprGenerationDoneEvent(methodID, idc, requestTime);
    }
 /// <summary>
 /// create for the series containing a single image
 /// </summary>
 /// <param name="idc">the data contract for the image</param>
 /// <returns>the new view model</returns>
 public static ImageSeriesViewModel Create(ImageDataContract idc)
 {
     var isvm = new ImageSeriesViewModel()
     {
         SeriesInstanceUID = idc.SeriesInstanceUID,
         FrameOfReferenceUID = idc.FrameOfReferenceUID,
         SeriesLabel = idc.Label,
     };
     return isvm;
 }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="pixelType"></param>
        /// <param name="label"></param>
        /// <returns></returns>
        public ImageDataContract AddImage(ImageDataContract idc)
        {
            // assert that GUID was not already assigned
            System.Diagnostics.Trace.Assert(idc.ImageId.CompareTo(Guid.Empty) == 0);

            idc.ImageId = Guid.NewGuid();
            idc.PixelBuffer =
                BufferRepository.CreateBuffer(idc.ImageId, typeof(ushort), idc.Width * idc.Height);

            _cacheImages.TryAdd(idc.ImageId, idc);

            return idc;
        }
        public void GenerateMpr(MprGenerationRequestV1 request)
        {
            var responseContext =
                OperationContext.Current.IncomingMessageHeaders.GetHeader<ResponseContext>(
                    "ResponseContext", "ServiceModelEx");
            System.Diagnostics.Trace.Assert(responseContext.MethodId.CompareTo(Guid.Empty.ToString()) != 0);

            LocalImageResourceManagerClient lirm =
                new LocalImageResourceManagerClient();
            lirm.Open();

            UniformImageVolumeDataContract ivdc = null;
            ivdc = lirm.GetImageVolume(request.ImageVolumeId);

            int[] size = CalculateSize(ivdc, request.Orientation);

            ImageDataContract idc = null;
            _cacheResultImages.TryGetValue(responseContext.MethodId, out idc);
            if (idc == null
                || idc.Width != size[0]
                || idc.Height != size[1])
            {
                idc = new ImageDataContract();
                idc.Width = size[0];
                idc.Height = size[1];
                idc = lirm.AddImage(idc);
                _cacheResultImages.TryAdd(responseContext.MethodId, idc);
            }

            lirm.Close();

            UpdatePixelsFromVolumeResampled(ivdc,
                request.Orientation, request.SlicePosition,
                request.WindowCenter, request.WindowWidth,
                idc);

            MessageHeader<ResponseContext> responseHeader = new MessageHeader<ResponseContext>(responseContext);
            NetMsmqBinding binding = new NetMsmqBinding("NoMsmqSecurity");
            MprGenerationResponseProxy proxy = new MprGenerationResponseProxy(binding,
                new EndpointAddress(responseContext.ResponseAddress));

            using (OperationContextScope scope = new OperationContextScope(proxy.InnerChannel))
            {
                OperationContext.Current.OutgoingMessageHeaders.Add(
                    responseHeader.GetUntypedHeader("ResponseContext", "ServiceModelEx"));

                proxy.OnMprDone(idc, request.RequestTime);
            }

            proxy.Close();
        }
        void StoreImage(DicomDataset ds, string modality)
        {
            DicomImage di = new DicomImage(ds);

            // store in cached resource
            var idc = new ImageDataContract();
            idc.PatientId = ds.Get<string>(DicomTag.PatientID);

            if (ds.Contains(DicomTag.PixelSpacing))
            {
                idc.PixelSpacing = new VoxelSize()
                {
                    X = Convert.ToSingle(ds.Get<double>(DicomTag.PixelSpacing, 0)),
                    Y = Convert.ToSingle(ds.Get<double>(DicomTag.PixelSpacing, 1)),
                };
            }
            else
            {
                idc.PixelSpacing = new VoxelSize() 
                { 
                    X = 1.0f, 
                    Y = 1.0f, 
                };
            }

            idc.ImagePosition = new ImagePosition()
            {
                X = Convert.ToSingle(ds.Get<double>(DicomTag.ImagePositionPatient, 0)),
                Y = Convert.ToSingle(ds.Get<double>(DicomTag.ImagePositionPatient, 1)),
                Z = Convert.ToSingle(ds.Get<double>(DicomTag.ImagePositionPatient, 2)),
            };

            idc.ImageOrientation = new ImageOrientation();
            idc.ImageOrientation.Row = new DirectionCosine()
            {
                X = Convert.ToSingle(ds.Get<double>(DicomTag.ImageOrientationPatient, 0)),
                Y = Convert.ToSingle(ds.Get<double>(DicomTag.ImageOrientationPatient, 1)),
                Z = Convert.ToSingle(ds.Get<double>(DicomTag.ImageOrientationPatient, 2)),
            };

            idc.ImageOrientation.Column = new DirectionCosine()
            {
                X = Convert.ToSingle(ds.Get<double>(DicomTag.ImageOrientationPatient, 3)),
                Y = Convert.ToSingle(ds.Get<double>(DicomTag.ImageOrientationPatient, 4)),
                Z = Convert.ToSingle(ds.Get<double>(DicomTag.ImageOrientationPatient, 5)),
            };

            idc.Width = di.Width;
            idc.Height = di.Height;
            idc.Label = string.Format("{0} {1}",
                modality,
                ds.GetDateTime(DicomTag.SeriesDate, DicomTag.SeriesTime).ToString());
            idc.SeriesInstanceUID = ds.Get<string>(DicomTag.SeriesInstanceUID);

            // store for association closed event
            _seriesInstanceUIDs.Add(idc.SeriesInstanceUID);

            string for_uid = ds.Get<string>(DicomTag.FrameOfReferenceUID);
            idc.FrameOfReferenceUID = for_uid;

            LocalImageResourceManagerClient
                cache1 = new LocalImageResourceManagerClient();

            idc = cache1.AddImage(idc);
            double repoGb = cache1.GetRepositorySizeGB();

            cache1.Close();

            if (di.PhotometricInterpretation == PhotometricInterpretation.Monochrome1
                || di.PhotometricInterpretation == PhotometricInterpretation.Monochrome2)
            {
                var dsForWl = di.Dataset;
                if (_firstImageIn.ContainsKey(idc.SeriesInstanceUID))
                {
                    dsForWl = _firstImageIn[idc.SeriesInstanceUID].Dataset;
                }
                else
                {
                    _firstImageIn.TryAdd(idc.SeriesInstanceUID, di);
                }

                var gro = GrayscaleRenderOptions.FromDataset(dsForWl);
                var voilut = VOILUT.Create(gro);

                var ipd = PixelDataFactory.Create(di.PixelData, 0);

                int[] outPixelsInt = new int[di.Width * di.Height];
                ipd.Render(voilut, outPixelsInt);

                ushort[] outPixelsUshort = Array.ConvertAll(outPixelsInt,
                    new Converter<int, ushort>(inInt => (ushort)(inInt)));
                var handle = idc.PixelBuffer.GetHandle();
                handle.WriteArray<ushort>(0, outPixelsUshort, 0, outPixelsUshort.Length);
                idc.PixelBuffer.ReleaseHandle();
                idc.PixelBuffer.CloseMapping();

                // inform of found image
                ImageResponseClient proxy = ImageResponseClient.CreateProxy();
                proxy.OnImageStored(idc.ImageId, repoGb);
                proxy.Close();
            }
        }
        void UpdatePixelsFromVolumeResampled(UniformImageVolumeDataContract ivdc, 
            Orientation orientation, int slice, 
            int windowCenter, int windowWidth, 
            ImageDataContract idc)
        {
            var inHandle = ivdc.PixelBuffer.GetHandle();
            var outHandle = idc.PixelBuffer.GetHandle();
            for (int nAtRow = 0; nAtRow < idc.Height; nAtRow++)
            {
                for (int nAtCol = 0; nAtCol < idc.Width; nAtCol++)
                {
                    int srcOffset = 0;
                    switch (orientation)
                    {
                        case Orientation.Transverse:
                            srcOffset = slice;
                            srcOffset *= ivdc.Height;
                            srcOffset += nAtRow;
                            srcOffset *= ivdc.Width;
                            srcOffset += nAtCol;
                            break;

                        case Orientation.Coronal:
                            srcOffset = nAtRow;
                            srcOffset *= ivdc.Height;
                            srcOffset += slice;
                            srcOffset *= ivdc.Width;
                            srcOffset += nAtCol;
                            break;

                        case Orientation.Sagittal:
                            srcOffset = nAtRow;
                            srcOffset *= ivdc.Height;
                            srcOffset += nAtCol;
                            srcOffset *= ivdc.Width;
                            srcOffset += slice;
                            break;
                    }

                    ulong byteOffset = (ulong)srcOffset * sizeof(ushort);
                    if (byteOffset < inHandle.ByteLength)
                    {
                        int dstOffset = nAtRow;
                        dstOffset *= idc.Width;
                        dstOffset += nAtCol;

                        int val = inHandle.Read<ushort>(byteOffset);
                        val = (val - windowCenter) * (int)ushort.MaxValue/2 
                            / windowWidth + (int)ushort.MaxValue/4;
                        val *= 2;
                        val = Math.Max(0, val);
                        val = Math.Min(ushort.MaxValue, val);
                        outHandle.Write<ushort>((ulong)(dstOffset*sizeof(ushort)), (ushort)val);
                    }
                }
            }
            idc.PixelBuffer.ReleaseHandle();
            ivdc.PixelBuffer.ReleaseHandle();
        }
        /// <summary>
        /// updates the image source for the given IDC return
        /// </summary>
        /// <param name="idc">the IDC representing the updated MPR</param>
        /// <param name="requestTime">the time of request, for calculating lapsed</param>
        void UpdateImageSourceFromImageDataContract(ImageDataContract idc, DateTime requestTime)
        {
            // now update with the result to the writeable bitmap
            var wb = GetWriteableBitmap();

            var handle = idc.PixelBuffer.GetHandle();
            wb.WritePixels(new Int32Rect(0, 0, _bm.PixelWidth, _bm.PixelHeight),
                handle.DangerousGetHandle(), (int)handle.ByteLength, _bm.PixelWidth * sizeof(ushort));
            idc.PixelBuffer.ReleaseHandle();

            // update the ImageSource (which should trigger re-binding)
            MprImageSource = wb;

            // called to update the scale for the image element (presumably bound to the image element)
            UpdateImageElementScale();
            
            // update the time lapsed text
            LapsedText = (DateTime.Now - requestTime).Milliseconds.ToString("0 msec");
        }
        /// <summary>
        /// on a generation event, update the relevent properties
        /// </summary>
        /// <param name="methodID">the invoking methodID</param>
        /// <param name="idc">the image data contract that was generated</param>
        /// <param name="requestTime">when was the MPR requested</param>
        void MprGenerationDone_MprGenerationDoneEvent(string methodID, ImageDataContract idc, DateTime requestTime)
        {
            // get the request from the queue
            MprGenerationRequestV1 request;
            if (_queueWaiting.TryRemove(new Guid(methodID), out request))
            {
                // make sure the request matches the volume
                System.Diagnostics.Trace.Assert(_ivdc.Identity.Guid.CompareTo(request.ImageVolumeId) == 0);

                // update the bitmap (must occur on the UI thread)
                Dispatcher.CurrentDispatcher.Invoke(() => UpdateImageSourceFromImageDataContract(idc, requestTime));

                // and remove the generated image
                LocalImageResourceManagerClient lirm =
                    new LocalImageResourceManagerClient();
                lirm.RemoveImage(idc.ImageId);
                lirm.Close();
            }
        }