コード例 #1
0
            private void ParseChannelValue(Debugger debugger, string type,
                                           out ChannelValueKind channelValueKind,
                                           out int channelValueSize)
            {
                channelValueKind = ChannelValueKind.Unknown;
                channelValueSize = 0;

                string rawType = type;

                if (type == "unsigned char" ||
                    type == "unsigned short" ||
                    type == "unsigned int" ||
                    type == "unsigned long" ||
                    type == "unsigned __int64")
                {
                    channelValueKind = ChannelValueKind.UnsignedIntegral;
                }
                else if (type == "char" || // TODO: this could actually depend on compiler flags
                         type == "signed char" ||
                         type == "short" ||
                         type == "signed short" ||
                         type == "int" ||
                         type == "signed int" ||
                         type == "long" ||
                         type == "signed long" ||
                         type == "__int64" ||
                         type == "signed __int64")
                {
                    channelValueKind = ChannelValueKind.SignedIntegral;
                }
                else if (type == "float" ||
                         type == "double")
                {
                    channelValueKind = ChannelValueKind.FloatingPoint;
                }
                else if (Util.TypeId(type) == "boost::gil::scoped_channel_value")
                {
                    List <string> tparams = Util.Tparams(type);
                    if (tparams.Count >= 1)
                    {
                        rawType = tparams[0];
                        if (rawType == "float" ||
                            rawType == "double")
                        {
                            // NOTE: Assuming scope [0, 1]
                            channelValueKind = ChannelValueKind.ScopedFloatingPoint;
                        }
                    }
                }

                channelValueSize = channelValueKind != ChannelValueKind.Unknown
                                 ? GetSizeOfType(debugger, rawType)
                                 : 0;
            }
コード例 #2
0
            byte[] GetChannelsInterleaved(byte[] memory, int pixelIndex, ChannelValueKind channelValueKind, int channelSize, int channelsCount)
            {
                byte[] result = new byte[channelsCount];

                int offset = pixelIndex * channelSize * channelsCount;

                if (channelSize == 1)
                {
                    Buffer.BlockCopy(memory, offset, result, 0, channelsCount);
                    if (channelValueKind == ChannelValueKind.SignedIntegral)
                    {
                        SignedToUnsigned(result);
                    }
                }
                else if (channelSize == 2)
                {
                    ushort[] tmp = new ushort[channelsCount];
                    Buffer.BlockCopy(memory, offset, tmp, 0, 2 * channelsCount);
                    if (channelValueKind == ChannelValueKind.SignedIntegral)
                    {
                        SignedToUnsigned(tmp);
                    }
                    ConvertChannels(tmp, result);
                }
                else if (channelSize == 4)
                {
                    if (channelValueKind == ChannelValueKind.UnsignedIntegral ||
                        channelValueKind == ChannelValueKind.SignedIntegral)
                    {
                        uint[] tmp = new uint[channelsCount];
                        Buffer.BlockCopy(memory, offset, tmp, 0, 4 * channelsCount);
                        if (channelValueKind == ChannelValueKind.SignedIntegral)
                        {
                            SignedToUnsigned(tmp);
                        }
                        ConvertChannels(tmp, result);
                    }
                    else
                    {
                        float[] tmp = new float[channelsCount];
                        Buffer.BlockCopy(memory, offset, tmp, 0, 4 * channelsCount);
                        if (channelValueKind == ChannelValueKind.FloatingPoint)
                        {
                            ConvertChannels(tmp, result);
                        }
                        else // ScopedFloatingPoint
                        {
                            ConvertChannelsScoped(tmp, result);
                        }
                    }
                }
                else if (channelSize == 8)
                {
                    if (channelValueKind == ChannelValueKind.UnsignedIntegral ||
                        channelValueKind == ChannelValueKind.SignedIntegral)
                    {
                        ulong[] tmp = new ulong[channelsCount];
                        Buffer.BlockCopy(memory, offset, tmp, 0, 8 * channelsCount);
                        if (channelValueKind == ChannelValueKind.SignedIntegral)
                        {
                            SignedToUnsigned(tmp);
                        }
                        ConvertChannels(tmp, result);
                    }
                    else
                    {
                        double[] tmp = new double[channelsCount];
                        Buffer.BlockCopy(memory, offset, tmp, 0, 8 * channelsCount);
                        if (channelValueKind == ChannelValueKind.FloatingPoint)
                        {
                            ConvertChannels(tmp, result);
                        }
                        else // ScopedFloatingPoint
                        {
                            ConvertChannelsScoped(tmp, result);
                        }
                    }
                }
                else
                {
                    result = null;
                }
                return(result);
            }
コード例 #3
0
            public override ExpressionDrawer.IDrawable Load(MemoryReader mreader, Debugger debugger,
                                                            string name, string type,
                                                            LoadCallback callback)
            {
                // NOTE: If the image is not created at the point of debugging, so the variable is
                // uninitialized, the size may be out of bounds of int32 range. In this case the
                // exception is thrown here and this is ok. However if there is some garbage in
                // memory random size could be loaded here. Then also the memory probably points
                // to some random place in memory (maybe protected?) so the result will probably
                // be another exception which is fine or an image containing noise from memory.
                int width  = ExpressionParser.LoadSize(debugger, name + "._view._dimensions.x");
                int height = ExpressionParser.LoadSize(debugger, name + "._view._dimensions.y");

                if (width < 1 || height < 1)
                {
                    return(null);
                }

                string pixelType, isPlanarStr;

                if (!Util.Tparams(type, out pixelType, out isPlanarStr))
                {
                    return(null);
                }

                string pixelId = Util.TypeId(pixelType);

                if (pixelId != "boost::gil::pixel")
                {
                    return(null);
                }

                bool isPlanar = (isPlanarStr == "1");

                string channelValueType, layoutType;

                if (!Util.Tparams(pixelType, out channelValueType, out layoutType))
                {
                    return(null);
                }

                string layoutId = Util.TypeId(layoutType);

                if (layoutId != "boost::gil::layout")
                {
                    return(null);
                }

                string colorSpaceType, channelMappingType;

                if (!Util.Tparams(layoutType, out colorSpaceType, out channelMappingType))
                {
                    return(null);
                }

                ChannelValueKind channelValueKind = ChannelValueKind.Unknown;
                int channelValueSize = 0;

                ParseChannelValue(debugger, channelValueType, out channelValueKind, out channelValueSize);
                if (channelValueKind == ChannelValueKind.Unknown || channelValueSize == 0)
                {
                    return(null);
                }

                string     colorSpaceId   = Util.TypeId(colorSpaceType);
                ColorSpace colorSpace     = ParseColorSpace(colorSpaceType);
                int        colorSpaceSize = ColorSpaceSize(colorSpace);

                if (colorSpace == ColorSpace.Unknown || colorSpaceSize == 0)
                {
                    return(null);
                }

                Layout layout = ParseChannelMapping(colorSpace, channelMappingType);

                if (layout == Layout.Unknown)
                {
                    return(null);
                }

                if (channelValueSize != 1 &&
                    channelValueSize != 2 &&
                    channelValueSize != 4 &&
                    channelValueSize != 8)
                {
                    return(null);
                }

                // TODO: size_t? ulong?
                int bytesCount = width * height * colorSpaceSize * channelValueSize;

                byte[] memory   = new byte[bytesCount];
                bool   isLoaded = false;

                if (mreader != null)
                {
                    ulong address = ExpressionParser.GetValueAddress(debugger, name + "._memory[0]");
                    if (address == 0)
                    {
                        return(null);
                    }

                    isLoaded = mreader.ReadBytes(address, memory);
                }

                if (!isLoaded)
                {
                    // Parsing the memory byte by byte may take very long time
                    // even for small images. So don't do it.
                    return(null);
                }

                LayoutMapper layoutMapper = GetLayoutMapper(layout);

                if (layoutMapper == null)
                {
                    return(null);
                }

                // Use Pixel format native to Gil Image?
                System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(width, height);
                for (int j = 0; j < height; ++j)
                {
                    for (int i = 0; i < width; ++i)
                    {
                        int pixelIndex = (j * width + i);

                        // The raw bytes are converted into channel values pixel by pixel.
                        //  It could be more efficient to convert all channel values at once first
                        //  and only create pixels from array of channels in this loop.
                        // Another thing is that when channels are always converted to byte
                        //  the information is lost. This information could be used during potential
                        //  conversion in GetColor() below (cmyk->rgb). Channels could be returned
                        //  as float[]. In practice the eye will probably not notice the difference.
                        byte[] channels = isPlanar
                                        ? GetChannelsPlanar(memory,
                                                            pixelIndex,
                                                            channelValueKind, channelValueSize, colorSpaceSize)
                                        : GetChannelsInterleaved(memory,
                                                                 pixelIndex,
                                                                 channelValueKind, channelValueSize, colorSpaceSize);
                        if (channels == null)
                        {
                            return(null);
                        }

                        System.Drawing.Color c = layoutMapper.GetColor(channels);
                        bmp.SetPixel(i, j, c);

                        // TODO: Checked per pixel. Too often?
                        //   But it's the same for geometries (ForEachMemoryBlock).
                        if (!callback())
                        {
                            return(null);
                        }
                    }
                }

                return(new ExpressionDrawer.Image(bmp));
            }
コード例 #4
0
            byte[] GetChannelsPlanar(byte[] memory, int pixelIndex, ChannelValueKind channelValueKind, int channelSize, int channelsCount)
            {
                byte[] result = new byte[channelsCount];

                int rowSize = memory.Length / channelsCount;
                int offset  = pixelIndex * channelSize;

                if (channelSize == 1)
                {
                    for (int i = 0; i < channelsCount; ++i)
                    {
                        //Buffer.BlockCopy(memory, i * rowSize + offset, result, i, 1);
                        result[i] = memory[i * rowSize + offset];
                    }
                    if (channelValueKind == ChannelValueKind.SignedIntegral)
                    {
                        SignedToUnsigned(result);
                    }
                }
                else if (channelSize == 2)
                {
                    ushort[] tmp = new ushort[channelsCount];
                    for (int i = 0; i < channelsCount; ++i)
                    {
                        Buffer.BlockCopy(memory, i * rowSize + offset, tmp, 2 * i, 2);
                    }
                    if (channelValueKind == ChannelValueKind.SignedIntegral)
                    {
                        SignedToUnsigned(tmp);
                    }
                    ConvertChannels(tmp, result);
                }
                else if (channelSize == 4)
                {
                    if (channelValueKind == ChannelValueKind.UnsignedIntegral ||
                        channelValueKind == ChannelValueKind.SignedIntegral)
                    {
                        uint[] tmp = new uint[channelsCount];
                        for (int i = 0; i < channelsCount; ++i)
                        {
                            Buffer.BlockCopy(memory, i * rowSize + offset, tmp, 4 * i, 4);
                        }
                        if (channelValueKind == ChannelValueKind.SignedIntegral)
                        {
                            SignedToUnsigned(tmp);
                        }
                        ConvertChannels(tmp, result);
                    }
                    else
                    {
                        float[] tmp = new float[channelsCount];
                        for (int i = 0; i < channelsCount; ++i)
                        {
                            Buffer.BlockCopy(memory, i * rowSize + offset, tmp, 4 * i, 4);
                        }
                        if (channelValueKind == ChannelValueKind.FloatingPoint)
                        {
                            ConvertChannels(tmp, result);
                        }
                        else // ScopedFloatingPoint
                        {
                            ConvertChannelsScoped(tmp, result);
                        }
                    }
                }
                else if (channelSize == 8)
                {
                    if (channelValueKind == ChannelValueKind.UnsignedIntegral ||
                        channelValueKind == ChannelValueKind.SignedIntegral)
                    {
                        ulong[] tmp = new ulong[channelsCount];
                        for (int i = 0; i < channelsCount; ++i)
                        {
                            Buffer.BlockCopy(memory, i * rowSize + offset, tmp, 8 * i, 8);
                        }
                        if (channelValueKind == ChannelValueKind.SignedIntegral)
                        {
                            SignedToUnsigned(tmp);
                        }
                        ConvertChannels(tmp, result);
                    }
                    else
                    {
                        double[] tmp = new double[channelsCount];
                        for (int i = 0; i < channelsCount; ++i)
                        {
                            Buffer.BlockCopy(memory, i * rowSize + offset, tmp, 8 * i, 8);
                        }
                        if (channelValueKind == ChannelValueKind.FloatingPoint)
                        {
                            ConvertChannels(tmp, result);
                        }
                        else // ScopedFloatingPoint
                        {
                            ConvertChannelsScoped(tmp, result);
                        }
                    }
                }
                else
                {
                    result = null;
                }
                return(result);
            }