public override void Load(Loaders loaders, MemoryReader mreader, Debugger debugger, string name, string type, out Geometry.Traits traits, out ExpressionDrawer.Image result, LoadCallback callback) { traits = null; result = null; // 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; } string pixelType, isPlanarStr; if (!Util.Tparams(type, out pixelType, out isPlanarStr)) { return; } string pixelId = Util.BaseType(pixelType); if (pixelId != "boost::gil::pixel") { return; } bool isPlanar = (isPlanarStr == "1"); string channelValueType, layoutType; if (!Util.Tparams(pixelType, out channelValueType, out layoutType)) { return; } string layoutId = Util.BaseType(layoutType); if (layoutId != "boost::gil::layout") { return; } string colorSpaceType, channelMappingType; if (!Util.Tparams(layoutType, out colorSpaceType, out channelMappingType)) { return; } ChannelValueKind channelValueKind = ChannelValueKind.Unknown; int channelValueSize = 0; ParseChannelValue(debugger, channelValueType, out channelValueKind, out channelValueSize); if (channelValueKind == ChannelValueKind.Unknown || channelValueSize == 0) { return; } string colorSpaceId = Util.BaseType(colorSpaceType); ColorSpace colorSpace = ParseColorSpace(colorSpaceType); int colorSpaceSize = ColorSpaceSize(colorSpace); if (colorSpace == ColorSpace.Unknown || colorSpaceSize == 0) { return; } Layout layout = ParseChannelMapping(colorSpace, channelMappingType); if (layout == Layout.Unknown) { return; } if (channelValueSize != 1 && channelValueSize != 2 && channelValueSize != 4 && channelValueSize != 8) { return; } // 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; } 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; } LayoutMapper layoutMapper = GetLayoutMapper(layout); if (layoutMapper == null) { return; } // 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; } 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; } } } result = new ExpressionDrawer.Image(bmp); }
public override Geometry.Traits GetTraits(MemoryReader mreader, Debugger debugger, string name) { return(null); }