Exemple #1
0
        private bool EnsureBuffersCompatible(PipeFrame frame)
        {
            if (_mappedFile1 != null && _mapView1 != null &&
                _mappedFile2 != null && _mapView2 != null &&
                _buffer1 != null && _buffer2 != null &&
                _buffersSize.Width == frame.Width && _buffersSize.Height == frame.Height)
            {
                return(true);
            }

            try {
                ReleaseHandles();

                lock (mapViewLock) {
                    _mappedFile1 = MemoryMappedFile.OpenExisting("cnc_buffer_spy1", MemoryMappedFileRights.Read);
                    _mapView1    = _mappedFile1.CreateViewAccessor(0, 0, MemoryMappedFileAccess.Read);

                    _mappedFile2 = MemoryMappedFile.OpenExisting("cnc_buffer_spy2", MemoryMappedFileRights.Read);
                    _mapView2    = _mappedFile2.CreateViewAccessor(0, 0, MemoryMappedFileAccess.Read);
                }

                lock (canvas.ImageLock) {
                    canvas.Image = null;
                    _buffer1     = new Bitmap((int)frame.Width, (int)frame.Height, PixelFormat.Format24bppRgb);
                    _buffer2     = new Bitmap((int)frame.Width, (int)frame.Height, PixelFormat.Format24bppRgb);
                }

                _buffersSize = new Size((int)frame.Width, (int)frame.Height);
                return(true);
            }
            catch {
                return(false);
            }
        }
Exemple #2
0
        private unsafe Bitmap ImageFromMappedFileView(PipeFrame frame)
        {
            if (!EnsureBuffersCompatible(frame))
            {
                return(null);
            }

            var view = frame.DestBuffer == DestinationBuffer.Buffer1 ? _mapView1 : _mapView2;
            var bm   = frame.DestBuffer == DestinationBuffer.Buffer1 ? _buffer1 : _buffer2;
            // Debug.Assert(bm != canvas.Image); // this assert would only work under a lock {}

            byte *ptr = null;

            view.SafeMemoryMappedViewHandle.AcquirePointer(ref ptr);
            var bmd = bm.LockBits(new Rectangle(0, 0, bm.Width, bm.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

            bool jet     = ckbJetColormap.Checked;
            int  anchorX = (int)((frame.SourceBufferAnchor / 2) % frame.Width);
            int  anchorY = (int)((frame.SourceBufferAnchor / 2) / frame.Width);

            if (frame.PixelFormat == BufferPixelFormat.Format16bppGrayscale)
            {
                Blit16bppGrayscale(frame, ptr, bmd, anchorY, anchorX, jet);
            }
            if (frame.PixelFormat == BufferPixelFormat.Format16bppRGB)
            {
                Blit16bppRGB(frame, ptr, bmd, anchorY, anchorX);
            }
            else if (frame.PixelFormat == BufferPixelFormat.Format8bpp)
            {
                Blit8bpp(frame, ptr, bmd, anchorX, anchorY);
            }

            view.SafeMemoryMappedViewHandle.ReleasePointer();
            bm.UnlockBits(bmd);

            lock (mapViewLock)
                _mapViewOfShownImage = view;
            _lastFrame = frame;

            return(bm);
        }
Exemple #3
0
        private unsafe void Blit8bpp(PipeFrame frame, byte *ptr, BitmapData bmd, int anchorX, int anchorY)
        {
            for (int row = 0; row < bmd.Height; row++)
            {
                byte *w      = (byte *)bmd.Scan0.ToPointer() + row * bmd.Stride;
                byte *r      = ptr + ((row + anchorY) % frame.Height) * frame.Width;
                int   endCol = (int)((anchorX + frame.Width - 1) % frame.Width);
                for (int col = anchorX; col != endCol;)
                {
                    // low byte
                    *w++ = r[col];
                    *w++ = r[col];
                    *w++ = r[col];

                    col++;
                    if (col == frame.Width)
                    {
                        col = 0;
                    }
                }
            }
        }
Exemple #4
0
        private static unsafe void Blit16bppRGB(PipeFrame frame, byte *ptr, BitmapData bmd, int anchorY, int anchorX)
        {
            for (int row = 0; row < bmd.Height; row++)
            {
                byte *  w    = (byte *)bmd.Scan0.ToPointer() + row * bmd.Stride;
                ushort *scan = (ushort *)(ptr + 2 * ((row + anchorY) % frame.Height) * frame.Width);

                int endCol = (int)((anchorX + frame.Width - 1) % frame.Width);
                for (int col = anchorX; col != endCol;)
                {
                    ushort bgr565 = scan[col];
                    *      w++    = (byte)((bgr565 & 0x001F) << 3);            // b
                    *      w++    = (byte)((bgr565 & 0x07E0) >> 3);            // g
                    *      w++    = (byte)((bgr565 & 0xF800) >> 8);            // r

                    col++;
                    if (col == frame.Width)
                    {
                        col = 0;
                    }
                }
            }
        }
Exemple #5
0
        private static unsafe void Blit16bppGrayscale(PipeFrame frame, byte *ptr, BitmapData bmd, int anchorY, int anchorX, bool jet)
        {
            // determine range
            ushort *p   = (ushort *)ptr;
            ushort  min = 65535;
            ushort  max = 0;

            if (jet)
            {
                ushort *end = p + frame.Width * frame.Height;
                while (p != end)
                {
                    if (min > *p)
                    {
                        min = *p;
                    }
                    if (max < *p)
                    {
                        max = *p;
                    }
                    ++p;
                }
            }

            float range = max - min;

            for (int row = 0; row < bmd.Height; row++)
            {
                byte *w    = (byte *)bmd.Scan0.ToPointer() + row * bmd.Stride;
                byte *scan = ptr + 2 * ((row + anchorY) % frame.Height) * frame.Width;

                int endCol = (int)((anchorX + frame.Width - 1) % frame.Width);
                for (int col = anchorX; col != endCol;)
                {
                    if (jet)
                    {
                        ushort u   = (ushort)((scan[col * 2 + 1] << 8) | scan[col * 2]);
                        float  v   = 2 * (u - min) / range;
                        byte   b   = (byte)Math.Max(0, 255 * (1 - v));
                        byte   r   = (byte)Math.Max(0, 255 * (v - 1));
                        byte   g   = (byte)(255 - b - r);
                        *      w++ = g;
                        *      w++ = b;
                        *      w++ = r;
                    }
                    else
                    {
                        // low byte
                        *w++ = scan[col * 2 + 0];
                        *w++ = scan[col * 2 + 0];
                        *w++ = scan[col * 2 + 0];
                    }

                    col++;
                    if (col == frame.Width)
                    {
                        col = 0;
                    }
                }
            }
        }