aboutsummaryrefslogtreecommitdiffstats
path: root/Software
diff options
context:
space:
mode:
authorRoy Ben-Shabat <Roy@Twine-s.com>2019-03-28 19:05:42 +0200
committerRoy Ben-Shabat <Roy@Twine-s.com>2019-03-28 19:05:42 +0200
commite07ebe48156313899ab6f4a06928aac6ef818f0d (patch)
tree83ba728e58ee242f60790fa9285c453fbaa3a06d /Software
parentb62c4b8b67b3103c691564df80f65423a9c315a0 (diff)
downloadTango-e07ebe48156313899ab6f4a06928aac6ef818f0d.tar.gz
Tango-e07ebe48156313899ab6f4a06928aac6ef818f0d.zip
Working on real-time card detection...
Diffstat (limited to 'Software')
-rw-r--r--Software/PMR/Messages/TCC/DetectionInput.proto5
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Controls/ColorMatrixControl.cs55
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Controls/IndexedUniformGrid.cs47
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Graph/WpfGraphController.cs36
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Images/bottomLeft.bmpbin0 -> 3678 bytes
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Images/bottomRight.bmpbin0 -> 3678 bytes
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Images/topRight.bmpbin0 -> 3678 bytes
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Images/topleft.bmpbin0 -> 3678 bytes
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Tango.MachineStudio.ColorCapture.csproj25
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Themes/Generic.xaml40
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/ViewModels/MainViewVM.cs113
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Views/MainView.xaml236
-rw-r--r--Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Views/MainView.xaml.cs8
-rw-r--r--Software/Visual_Studio/SideChains/RealTimeGraphX.WPF/Surfaces/WpfGraphSurface.cs2
-rw-r--r--Software/Visual_Studio/SideChains/RealTimeGraphX/GraphPainterBase.cs4
-rw-r--r--Software/Visual_Studio/TCC/Tango.TCC.BL/CardDetectionResult.cs17
-rw-r--r--Software/Visual_Studio/TCC/Tango.TCC.BL/CardDetector.cs74
-rw-r--r--Software/Visual_Studio/TCC/Tango.TCC.BL/Tango.TCC.BL.csproj11
-rw-r--r--Software/Visual_Studio/TCC/Tango.TCC.CardDetector/ArucoUtils.cpp89
-rw-r--r--Software/Visual_Studio/TCC/Tango.TCC.CardDetector/ArucoUtils.h25
-rw-r--r--Software/Visual_Studio/TCC/Tango.TCC.CardDetector/AssemblyInfo.cppbin0 -> 1512 bytes
-rw-r--r--Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetection.cppbin0 -> 2730 bytes
-rw-r--r--Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetection.hbin0 -> 776 bytes
-rw-r--r--Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetectionConfig.cpp7
-rw-r--r--Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetectionConfig.h18
-rw-r--r--Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetectionResult.cpp7
-rw-r--r--Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetectionResult.h21
-rw-r--r--Software/Visual_Studio/TCC/Tango.TCC.CardDetector/Tango.TCC.CardDetector.vcxproj158
-rw-r--r--Software/Visual_Studio/TCC/Tango.TCC.CardDetector/Tango.TCC.CardDetector.vcxproj.filters47
-rw-r--r--Software/Visual_Studio/TCC/Tango.TCC.CardDetector/app.icobin0 -> 41395 bytes
-rw-r--r--Software/Visual_Studio/TCC/Tango.TCC.CardDetector/app.rcbin0 -> 2558 bytes
-rw-r--r--Software/Visual_Studio/TCC/Tango.TCC.CardDetector/bitmap_image.hpp5105
-rw-r--r--Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorDetection.cpp18
-rw-r--r--Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/PMR/TCC/DetectionInput.pb-c.c35
-rw-r--r--Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/PMR/TCC/DetectionInput.pb-c.h8
-rw-r--r--Software/Visual_Studio/TCC/Tango.TCC.OpenCV/CardProcessor.cpp (renamed from Software/Visual_Studio/TCC/Tango.TCC.OpenCV/CardDetector.cpp)46
-rw-r--r--Software/Visual_Studio/TCC/Tango.TCC.OpenCV/CardProcessor.h (renamed from Software/Visual_Studio/TCC/Tango.TCC.OpenCV/CardDetector.h)8
-rw-r--r--Software/Visual_Studio/TCC/Tango.TCC.OpenCV/Tango.TCC.OpenCV.vcxproj4
-rw-r--r--Software/Visual_Studio/TCC/Tango.TCC.OpenCV/Tango.TCC.OpenCV.vcxproj.filters8
-rw-r--r--Software/Visual_Studio/Tango.PMR/TCC/DetectionInput.cs76
-rw-r--r--Software/Visual_Studio/Tango.UnitTesting/TCC/TCC_TST.cs55
-rw-r--r--Software/Visual_Studio/Tango.sln49
42 files changed, 6265 insertions, 192 deletions
diff --git a/Software/PMR/Messages/TCC/DetectionInput.proto b/Software/PMR/Messages/TCC/DetectionInput.proto
index 30dbacab4..d9332bbd4 100644
--- a/Software/PMR/Messages/TCC/DetectionInput.proto
+++ b/Software/PMR/Messages/TCC/DetectionInput.proto
@@ -11,7 +11,8 @@ message DetectionInput
int32 Columns = 2;
int32 Rows = 3;
int32 TargetIndex = 4;
- bool DebugMode = 5;
- repeated DetectionBenchmark Benchmarks = 6;
+ bool RequestDebugImage = 5;
+ bool RequestColorMatrix = 6;
+ repeated DetectionBenchmark Benchmarks = 7;
double number = 10;
} \ No newline at end of file
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Controls/ColorMatrixControl.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Controls/ColorMatrixControl.cs
new file mode 100644
index 000000000..7ea8681ab
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Controls/ColorMatrixControl.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace Tango.MachineStudio.ColorCapture.Controls
+{
+ public class ColorMatrixControl : Control
+ {
+ public ObservableCollection<Color> Colors
+ {
+ get { return (ObservableCollection<Color>)GetValue(ColorsProperty); }
+ set { SetValue(ColorsProperty, value); }
+ }
+ public static readonly DependencyProperty ColorsProperty =
+ DependencyProperty.Register("Colors", typeof(ObservableCollection<Color>), typeof(ColorMatrixControl), new PropertyMetadata(null));
+
+ public int Columns
+ {
+ get { return (int)GetValue(ColumnsProperty); }
+ set { SetValue(ColumnsProperty, value); }
+ }
+ public static readonly DependencyProperty ColumnsProperty =
+ DependencyProperty.Register("Columns", typeof(int), typeof(ColorMatrixControl), new PropertyMetadata(10));
+
+ public int Rows
+ {
+ get { return (int)GetValue(RowsProperty); }
+ set { SetValue(RowsProperty, value); }
+ }
+ public static readonly DependencyProperty RowsProperty =
+ DependencyProperty.Register("Rows", typeof(int), typeof(ColorMatrixControl), new PropertyMetadata(11));
+
+ public ColorMatrixControl()
+ {
+ Colors = new ObservableCollection<Color>();
+ }
+
+ static ColorMatrixControl()
+ {
+ DefaultStyleKeyProperty.OverrideMetadata(typeof(ColorMatrixControl), new FrameworkPropertyMetadata(typeof(ColorMatrixControl)));
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Controls/IndexedUniformGrid.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Controls/IndexedUniformGrid.cs
new file mode 100644
index 000000000..af34e038d
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Controls/IndexedUniformGrid.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace Tango.MachineStudio.ColorCapture.Controls
+{
+ public class IndexedUniformGrid : Grid
+ {
+ public int Columns
+ {
+ get { return (int)GetValue(ColumnsProperty); }
+ set { SetValue(ColumnsProperty, value); }
+ }
+ public static readonly DependencyProperty ColumnsProperty =
+ DependencyProperty.Register("Columns", typeof(int), typeof(IndexedUniformGrid), new PropertyMetadata(0));
+
+ public int Rows
+ {
+ get { return (int)GetValue(RowsProperty); }
+ set { SetValue(RowsProperty, value); }
+ }
+ public static readonly DependencyProperty RowsProperty =
+ DependencyProperty.Register("Rows", typeof(int), typeof(IndexedUniformGrid), new PropertyMetadata(0));
+
+ public IndexedUniformGrid()
+ {
+ Loaded += IndexedUniformGrid_Loaded;
+ }
+
+ private void IndexedUniformGrid_Loaded(object sender, RoutedEventArgs e)
+ {
+ for (int i = 0; i < Columns; i++)
+ {
+ ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) });
+ }
+
+ for (int i = 0; i < Rows; i++)
+ {
+ RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
+ }
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Graph/WpfGraphController.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Graph/WpfGraphController.cs
new file mode 100644
index 000000000..dd32cde93
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Graph/WpfGraphController.cs
@@ -0,0 +1,36 @@
+using RealTimeGraphX;
+using RealTimeGraphX.DataPoints;
+using RealTimeGraphX.Renderers;
+using RealTimeGraphX.WPF.DataSeries;
+using RealTimeGraphX.WPF.Painters;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Media;
+
+namespace Tango.MachineStudio.ColorCapture.Graph
+{
+ public class WpfGraphController : GraphControllerBase<WpfDataSeries, DoubleDataPoint, DoubleDataPoint>
+ {
+ public WpfGraphController(int refreshRate = 50)
+ {
+ AddDataSeries(new WpfDataSeries()
+ {
+ StrokeThickness = 1,
+ Stroke = Colors.Black,
+ });
+
+ var renderer = new GraphScrollingRenderer<WpfDataSeries, DoubleDataPoint, DoubleDataPoint>()
+ {
+ RefreshRate = TimeSpan.FromMilliseconds(refreshRate)
+ };
+
+ var painter = new WpfScrollingGraphPainter();
+
+ ConnectOutput(renderer);
+ renderer.ConnectOutput(painter);
+ }
+ }
+}
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Images/bottomLeft.bmp b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Images/bottomLeft.bmp
new file mode 100644
index 000000000..13b33704b
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Images/bottomLeft.bmp
Binary files differ
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Images/bottomRight.bmp b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Images/bottomRight.bmp
new file mode 100644
index 000000000..d2116fad2
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Images/bottomRight.bmp
Binary files differ
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Images/topRight.bmp b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Images/topRight.bmp
new file mode 100644
index 000000000..f008d454d
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Images/topRight.bmp
Binary files differ
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Images/topleft.bmp b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Images/topleft.bmp
new file mode 100644
index 000000000..8115cf359
--- /dev/null
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Images/topleft.bmp
Binary files differ
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Tango.MachineStudio.ColorCapture.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Tango.MachineStudio.ColorCapture.csproj
index 2422cec2a..4d0c0fae5 100644
--- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Tango.MachineStudio.ColorCapture.csproj
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Tango.MachineStudio.ColorCapture.csproj
@@ -88,6 +88,9 @@
<Link>GlobalVersionInfo.cs</Link>
</Compile>
<Compile Include="ColorLabModule.cs" />
+ <Compile Include="Controls\ColorMatrixControl.cs" />
+ <Compile Include="Controls\IndexedUniformGrid.cs" />
+ <Compile Include="Graph\WpfGraphController.cs" />
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
@@ -117,6 +120,18 @@
</None>
</ItemGroup>
<ItemGroup>
+ <ProjectReference Include="..\..\..\SideChains\ColorMine\ColorMine.csproj">
+ <Project>{37e4ceab-b54b-451f-b535-04cf7da9c459}</Project>
+ <Name>ColorMine</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\SideChains\RealTimeGraphX.WPF\RealTimeGraphX.WPF.csproj">
+ <Project>{99d233c5-fee7-418e-9c25-d4584cb52e28}</Project>
+ <Name>RealTimeGraphX.WPF</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\SideChains\RealTimeGraphX\RealTimeGraphX.csproj">
+ <Project>{6d55a3b8-46d3-493a-a143-aebd2b98d683}</Project>
+ <Name>RealTimeGraphX</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\..\Tango.BL\Tango.BL.csproj">
<Project>{f441feee-322a-4943-b566-110e12fd3b72}</Project>
<Name>Tango.BL</Name>
@@ -145,6 +160,10 @@
<Project>{f209fae8-73f9-441b-97f4-0844a0279390}</Project>
<Name>Tango.TCC.BL</Name>
</ProjectReference>
+ <ProjectReference Include="..\..\..\TCC\Tango.TCC.OpenCV.DLL\Tango.TCC.OpenCV.DLL.csproj">
+ <Project>{5d0d4053-cab3-4a4a-929e-37a76483bc22}</Project>
+ <Name>Tango.TCC.OpenCV.DLL</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\Tango.MachineStudio.Common\Tango.MachineStudio.Common.csproj">
<Project>{cb0b0aa2-bb24-4bca-a720-45e397684e12}</Project>
<Name>Tango.MachineStudio.Common</Name>
@@ -156,5 +175,11 @@
<ItemGroup>
<Resource Include="Images\colorcapture_module.png" />
</ItemGroup>
+ <ItemGroup>
+ <Resource Include="Images\bottomLeft.bmp" />
+ <Resource Include="Images\bottomRight.bmp" />
+ <Resource Include="Images\topleft.bmp" />
+ <Resource Include="Images\topRight.bmp" />
+ </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Themes/Generic.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Themes/Generic.xaml
index 968c541b3..0a2ebbca8 100644
--- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Themes/Generic.xaml
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Themes/Generic.xaml
@@ -1,6 +1,44 @@
-<ResourceDictionary
+<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:controls="clr-namespace:Tango.MachineStudio.ColorCapture.Controls"
xmlns:local="clr-namespace:Tango.MachineStudio.ColorCapture">
+
+ <Style TargetType="{x:Type controls:ColorMatrixControl}">
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="{x:Type controls:ColorMatrixControl}">
+ <Border Background="{TemplateBinding Background}"
+ BorderBrush="{TemplateBinding BorderBrush}"
+ BorderThickness="{TemplateBinding BorderThickness}">
+ <Grid>
+ <ItemsControl ItemsSource="{TemplateBinding Colors}">
+ <ItemsControl.ItemsPanel>
+ <ItemsPanelTemplate>
+ <UniformGrid Columns="{Binding RelativeSource={RelativeSource AncestorType=controls:ColorMatrixControl},Path=Columns}" Rows="{Binding RelativeSource={RelativeSource AncestorType=controls:ColorMatrixControl},Path=Rows}" />
+ </ItemsPanelTemplate>
+ </ItemsControl.ItemsPanel>
+ <ItemsControl.ItemTemplate>
+ <DataTemplate>
+ <Rectangle>
+ <Rectangle.Fill>
+ <SolidColorBrush Color="{Binding}"></SolidColorBrush>
+ </Rectangle.Fill>
+ </Rectangle>
+ </DataTemplate>
+ </ItemsControl.ItemTemplate>
+ </ItemsControl>
+ <controls:IndexedUniformGrid Columns="{TemplateBinding Columns}" Rows="{TemplateBinding Rows}">
+ <Image Source="Images/topLeft.bmp" Stretch="Fill" Grid.Column="0" Grid.Row="0" />
+ <Image Source="Images/topRight.bmp" Stretch="Fill" Grid.Column="{TemplateBinding Columns}" Grid.Row="0" />
+ <Image Source="Images/bottomLeft.bmp" Stretch="Fill" Grid.Column="0" Grid.Row="{TemplateBinding Rows}" />
+ <Image Source="Images/bottomRight.bmp" Stretch="Fill" Grid.Column="{TemplateBinding Columns}" Grid.Row="{TemplateBinding Rows}" />
+ </controls:IndexedUniformGrid>
+ </Grid>
+ </Border>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ </Style>
</ResourceDictionary>
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/ViewModels/MainViewVM.cs
index 298b862fb..f21c403de 100644
--- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/ViewModels/MainViewVM.cs
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/ViewModels/MainViewVM.cs
@@ -1,14 +1,20 @@
-using System;
+using ColorMine.ColorSpaces;
+using ColorMine.ColorSpaces.Comparisons;
+using System;
using System.Collections.Generic;
-using System.Drawing;
+using System.Collections.ObjectModel;
+using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
+using System.Windows.Media.Imaging;
using Tango.Core.Commands;
+using Tango.MachineStudio.ColorCapture.Graph;
using Tango.MachineStudio.Common;
using Tango.MachineStudio.Common.Notifications;
using Tango.MachineStudio.Common.Video;
+using Tango.TCC.BL;
using Tango.Video.DirectCapture;
namespace Tango.MachineStudio.ColorCapture.ViewModels
@@ -16,6 +22,8 @@ namespace Tango.MachineStudio.ColorCapture.ViewModels
public class MainViewVM : StudioViewModel
{
private INotificationProvider _notification;
+ private CardDetector _cardDetector;
+ private int _sampleCounter;
public IVideoCaptureProvider VideoProvider { get; set; }
@@ -32,14 +40,74 @@ namespace Tango.MachineStudio.ColorCapture.ViewModels
}
}
+ private BitmapSource _detectedSource;
+ public BitmapSource DetectedSource
+ {
+ get { return _detectedSource; }
+ set { _detectedSource = value; RaisePropertyChangedAuto(); }
+ }
+
+ private ObservableCollection<Color> _colors;
+ public ObservableCollection<Color> Colors
+ {
+ get { return _colors; }
+ set { _colors = value; RaisePropertyChangedAuto(); RaisePropertyChangedAuto(); }
+ }
+
+ private Color _processedColor;
+ public Color ProcessedColor
+ {
+ get { return _processedColor; }
+ set { _processedColor = value; RaisePropertyChangedAuto(); }
+ }
+
+ private Color _capturedColor;
+ public Color CapturedColor
+ {
+ get { return _capturedColor; }
+ set { _capturedColor = value; RaisePropertyChangedAuto(); }
+ }
+
+ private double _measureL;
+ public double MeasureL
+ {
+ get { return _measureL; }
+ set { _measureL = value; RaisePropertyChangedAuto(); }
+ }
+
+ private double _measureA;
+ public double MeasureA
+ {
+ get { return _measureA; }
+ set { _measureA = value; RaisePropertyChangedAuto(); }
+ }
+
+ private double _measureB;
+ public double MeasureB
+ {
+ get { return _measureB; }
+ set { _measureB = value; RaisePropertyChangedAuto(); }
+ }
+
+
+ public WpfGraphController CaptureDeltaEController { get; set; }
+
public RelayCommand ToggleCameraCommand { get; set; }
- public MainViewVM(IVideoCaptureProvider videoProvider, INotificationProvider notificationProvider)
+ public MainViewVM()
+ {
+ _cardDetector = new CardDetector();
+ ToggleCameraCommand = new RelayCommand(ToggleCamera);
+ CaptureDeltaEController = new WpfGraphController();
+ CaptureDeltaEController.Range.AutoY = true;
+ CaptureDeltaEController.Range.MaximumX = 1000;
+ }
+
+ public MainViewVM(IVideoCaptureProvider videoProvider, INotificationProvider notificationProvider) : this()
{
_notification = notificationProvider;
VideoProvider = videoProvider;
SelectedVideoDevice = videoProvider.AvailableCaptureDevices.FirstOrDefault();
- ToggleCameraCommand = new RelayCommand(ToggleCamera);
}
private void ToggleCamera()
@@ -52,6 +120,7 @@ namespace Tango.MachineStudio.ColorCapture.ViewModels
}
else
{
+ SelectedVideoDevice.Resolution = new Resolution(1280, 720);
SelectedVideoDevice.Start();
}
}
@@ -71,11 +140,41 @@ namespace Tango.MachineStudio.ColorCapture.ViewModels
}
}
- private void OnVideoFrameReceived(object sender, Video.DirectShow.EventArguments.FrameReceivedEventArgs args)
+ double deltaE = 0;
+ private async void OnVideoFrameReceived(object sender, Video.DirectShow.EventArguments.FrameReceivedEventArgs args)
{
- Bitmap bmp = args.BitmapSource.ConvertFormat(PixelFormats.Rgb24).ToGDIBitmap();
+ if (_cardDetector.CanDetect)
+ {
+ var result = await _cardDetector.Detect(args.BitmapSource);
+
+ if (result.IsDetected)
+ {
+ DetectedSource = result.DetectedBitmap;
+
+ if (Colors == null)
+ {
+ Colors = new ObservableCollection<Color>(Enumerable.Range(0, result.ColorDetectionOutput.ColorMatrix.Count).Select(x => new Color()));
+ }
+
+ InvokeUI(() =>
+ {
+ for (int i = 0; i < result.ColorDetectionOutput.ColorMatrix.Count; i++)
+ {
+ var detectedColor = result.ColorDetectionOutput.ColorMatrix[i];
+ Colors[i] = Color.FromArgb(255, (byte)detectedColor.R, (byte)detectedColor.G, (byte)detectedColor.B);
+ }
+
+ CapturedColor = Color.FromArgb(255, (byte)result.ColorDetectionOutput.RawColor.R, (byte)result.ColorDetectionOutput.RawColor.G, (byte)result.ColorDetectionOutput.RawColor.B);
+ ProcessedColor = Color.FromArgb(255, (byte)result.ColorDetectionOutput.ProcessedColor.R, (byte)result.ColorDetectionOutput.ProcessedColor.G, (byte)result.ColorDetectionOutput.ProcessedColor.B);
+ });
+
+ //calculate delta E.
+ Lab measureLab = new Lab(MeasureL, MeasureA, MeasureB);
+ deltaE = measureLab.Compare(new Rgb(ProcessedColor.R, ProcessedColor.G, ProcessedColor.B), new CieDe2000Comparison());
+ }
+ }
- bmp.Dispose();
+ CaptureDeltaEController.PushData(_sampleCounter++, deltaE);
}
public override void OnApplicationReady()
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Views/MainView.xaml
index cd619d0a0..259e3160e 100644
--- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Views/MainView.xaml
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Views/MainView.xaml
@@ -6,11 +6,16 @@
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI"
xmlns:vm="clr-namespace:Tango.MachineStudio.ColorCapture.ViewModels"
+ xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls"
+ xmlns:graphX="clr-namespace:RealTimeGraphX.WPF.Surfaces;assembly=RealTimeGraphX.WPF"
+ xmlns:componentsX="clr-namespace:RealTimeGraphX.WPF.Components;assembly=RealTimeGraphX.WPF"
+ xmlns:controls="clr-namespace:Tango.MachineStudio.ColorCapture.Controls"
+ xmlns:realtimeGraphX="clr-namespace:RealTimeGraphX.WPF.Surfaces;assembly=RealTimeGraphX.WPF"
xmlns:global="clr-namespace:Tango.MachineStudio.ColorCapture"
xmlns:local="clr-namespace:Tango.MachineStudio.ColorCapture.Views"
mc:Ignorable="d"
d:DesignHeight="1080" d:DesignWidth="1920" Background="Transparent" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}">
- <Grid Background="White">
+ <Grid Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="247*"/>
<RowDefinition Height="113*"/>
@@ -25,83 +30,170 @@
<Grid>
<DockPanel>
<DockPanel DockPanel.Dock="Bottom" Margin="60 0" TextElement.FontSize="25">
- <TextBlock VerticalAlignment="Center">Selected Capture Device</TextBlock>
- <ComboBox Foreground="DodgerBlue" Margin="20 0 0 0" ItemsSource="{Binding VideoProvider.AvailableCaptureDevices}" SelectedItem="{Binding SelectedVideoDevice}" DisplayMemberPath="Device"></ComboBox>
+ <TextBlock VerticalAlignment="Center">Capture Device</TextBlock>
+ <Button DockPanel.Dock="Right" Command="{Binding ToggleCameraCommand}" CommandParameter="{Binding}" Style="{StaticResource MaterialDesignFloatingActionMiniButton}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Width="60" Height="60" Padding="0">
+ <materialDesign:PackIcon Width="40" Height="40">
+ <materialDesign:PackIcon.Style>
+ <Style TargetType="materialDesign:PackIcon">
+ <Setter Property="Kind" Value="Play"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding SelectedVideoDevice.IsStarted}" Value="True">
+ <Setter Property="Kind" Value="Stop"></Setter>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding SelectedVideoDevice.IsStarted}" Value="False">
+ <Setter Property="Kind" Value="Play"></Setter>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </materialDesign:PackIcon.Style>
+ </materialDesign:PackIcon>
+ </Button>
+ <ComboBox FontWeight="SemiBold" Margin="20 0 20 0" ItemsSource="{Binding VideoProvider.AvailableCaptureDevices}" SelectedItem="{Binding SelectedVideoDevice}" DisplayMemberPath="Device"></ComboBox>
</DockPanel>
- <Viewbox Stretch="Fill">
- <Border Width="1280" Height="900">
- <Border.Background>
- <ImageBrush ImageSource="../Images/video-frame.png" Stretch="Fill"></ImageBrush>
- </Border.Background>
- <Grid>
- <Image Source="{Binding SelectedVideoDevice.VideoSource,Mode=OneWay,IsAsync=True}" Stretch="Fill" Margin="86 76 87 133">
- <Image.Style>
- <Style TargetType="Image">
+ <Border BorderThickness="3" BorderBrush="#202020" Margin="40">
+ <Image Source="{Binding SelectedVideoDevice.VideoSource,Mode=OneWay,IsAsync=True}" Stretch="Fill">
+ <Image.Style>
+ <Style TargetType="Image">
+ <Setter Property="Visibility" Value="Hidden"></Setter>
+ <Style.Triggers>
+ <DataTrigger Binding="{Binding SelectedVideoDevice.IsStarted}" Value="True">
+ <Setter Property="Visibility" Value="Visible"></Setter>
+ </DataTrigger>
+ <DataTrigger Binding="{Binding SelectedVideoDevice.IsStarted}" Value="False">
<Setter Property="Visibility" Value="Hidden"></Setter>
- <Style.Triggers>
- <DataTrigger Binding="{Binding SelectedVideoDevice.IsStarted}" Value="True">
- <Setter Property="Visibility" Value="Visible"></Setter>
- </DataTrigger>
- <DataTrigger Binding="{Binding SelectedVideoDevice.IsStarted}" Value="False">
- <Setter Property="Visibility" Value="Hidden"></Setter>
- </DataTrigger>
- </Style.Triggers>
- </Style>
- </Image.Style>
- </Image>
-
- <Grid Background="#83000000" Cursor="Hand" Margin="87 75 86 135">
- <Grid.Style>
- <Style TargetType="Grid">
- <Setter Property="Opacity" Value="0"></Setter>
- <Style.Triggers>
- <EventTrigger RoutedEvent="MouseEnter">
- <EventTrigger.Actions>
- <BeginStoryboard>
- <Storyboard>
- <DoubleAnimation Storyboard.TargetProperty="Opacity" To="1" Duration="00:00:0.2"></DoubleAnimation>
- </Storyboard>
- </BeginStoryboard>
- </EventTrigger.Actions>
- </EventTrigger>
- <EventTrigger RoutedEvent="MouseLeave">
- <EventTrigger.Actions>
- <BeginStoryboard>
- <Storyboard>
- <DoubleAnimation Storyboard.TargetProperty="Opacity" To="0" Duration="00:00:0.2"></DoubleAnimation>
- </Storyboard>
- </BeginStoryboard>
- </EventTrigger.Actions>
- </EventTrigger>
- </Style.Triggers>
- </Style>
- </Grid.Style>
-
- <Button Command="{Binding ToggleCameraCommand}" CommandParameter="{Binding}" Style="{StaticResource MaterialDesignFloatingActionMiniButton}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Width="80" Height="80" Padding="0">
- <materialDesign:PackIcon Width="40" Height="40">
- <materialDesign:PackIcon.Style>
- <Style TargetType="materialDesign:PackIcon">
- <Setter Property="Kind" Value="Play"></Setter>
- <Style.Triggers>
- <DataTrigger Binding="{Binding SelectedVideoDevice.IsStarted}" Value="True">
- <Setter Property="Kind" Value="Stop"></Setter>
- </DataTrigger>
- <DataTrigger Binding="{Binding SelectedVideoDevice.IsStarted}" Value="False">
- <Setter Property="Kind" Value="Play"></Setter>
- </DataTrigger>
- </Style.Triggers>
- </Style>
- </materialDesign:PackIcon.Style>
- </materialDesign:PackIcon>
- </Button>
- </Grid>
- </Grid>
- </Border>
- </Viewbox>
+ </DataTrigger>
+ </Style.Triggers>
+ </Style>
+ </Image.Style>
+ </Image>
+ </Border>
</DockPanel>
</Grid>
</Border>
+
+ <Grid Grid.Column="1">
+ <Grid.RowDefinitions>
+ <RowDefinition Height="180*"/>
+ <RowDefinition Height="130*"/>
+ </Grid.RowDefinitions>
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="1*"/>
+ <ColumnDefinition Width="1*"/>
+ </Grid.ColumnDefinitions>
+
+ <Border Margin="0 40 0 0" VerticalAlignment="Top" Width="300" Height="310" BorderThickness="3" BorderBrush="#202020">
+ <Image Source="{Binding DetectedSource,Mode=OneWay,IsAsync=True}" Stretch="Fill"></Image>
+ </Border>
+
+ <Border Margin="0 40 0 0" VerticalAlignment="Top" Width="300" Height="310" BorderThickness="3" BorderBrush="#202020" Grid.Column="1">
+ <controls:ColorMatrixControl Colors="{Binding Colors,Mode=OneWay}" Columns="10" Rows="11" />
+ </Border>
+ </Grid>
+
+ <Grid Grid.Row="1">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="1*"/>
+ <ColumnDefinition Width="1*"/>
+ </Grid.ColumnDefinitions>
+
+ <Grid Width="300" Height="190" VerticalAlignment="Top">
+ <DockPanel>
+ <TextBlock DockPanel.Dock="Top" FontSize="20">Captured Color</TextBlock>
+ <DockPanel Margin="0 10 0 0" TextElement.FontSize="20">
+ <UniformGrid DockPanel.Dock="Right" Rows="3" Margin="10 0 0 0" Width="55">
+ <TextBlock><Run Text="R:"></Run> <Run FontWeight="SemiBold" FontStyle="Italic" Text="{Binding CapturedColor.R,Mode=OneWay}"></Run></TextBlock>
+ <TextBlock><Run Text="G:"></Run> <Run FontWeight="SemiBold" FontStyle="Italic" Text="{Binding CapturedColor.G,Mode=OneWay}"></Run></TextBlock>
+ <TextBlock><Run Text="B:"></Run> <Run FontWeight="SemiBold" FontStyle="Italic" Text="{Binding CapturedColor.B,Mode=OneWay}"></Run></TextBlock>
+ </UniformGrid>
+ <Border BorderThickness="1" BorderBrush="#202020">
+ <Border.Background>
+ <SolidColorBrush Color="{Binding CapturedColor,Mode=OneWay}" />
+ </Border.Background>
+ </Border>
+ </DockPanel>
+ </DockPanel>
+ </Grid>
+
+ <Grid Width="300" Height="190" VerticalAlignment="Top" Grid.Column="1">
+ <DockPanel>
+ <TextBlock DockPanel.Dock="Top" FontSize="20">Processed Color</TextBlock>
+ <DockPanel Margin="0 10 0 0" TextElement.FontSize="20">
+ <UniformGrid DockPanel.Dock="Right" Rows="3" Margin="10 0 0 0" Width="55">
+ <TextBlock><Run Text="R:"></Run> <Run FontWeight="SemiBold" FontStyle="Italic" Text="{Binding ProcessedColor.R,Mode=OneWay}"></Run></TextBlock>
+ <TextBlock><Run Text="G:"></Run> <Run FontWeight="SemiBold" FontStyle="Italic" Text="{Binding ProcessedColor.G,Mode=OneWay}"></Run></TextBlock>
+ <TextBlock><Run Text="B:"></Run> <Run FontWeight="SemiBold" FontStyle="Italic" Text="{Binding ProcessedColor.B,Mode=OneWay}"></Run></TextBlock>
+ </UniformGrid>
+ <Border BorderThickness="1" BorderBrush="#202020">
+ <Border.Background>
+ <SolidColorBrush Color="{Binding ProcessedColor,Mode=OneWay}" />
+ </Border.Background>
+ </Border>
+ </DockPanel>
+ </DockPanel>
+ </Grid>
+ </Grid>
+ </Grid>
+ </Grid>
+
+ <Grid Grid.Row="1" Margin="0 10 0 0">
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="1*"/>
+ <ColumnDefinition Width="1*"/>
+ </Grid.ColumnDefinitions>
+ <DockPanel>
+ <TextBlock DockPanel.Dock="Top">HISTORY</TextBlock>
+ <DataGrid Margin="0 10 0 0" Background="Transparent" Grid.ColumnSpan="2">
+ <DataGrid.Columns>
+ <DataGridTextColumn Header="TIME" />
+ <DataGridTextColumn Header="CAPTURED COLOR" />
+ <DataGridTextColumn Header="PROCESSED COLOR" />
+ </DataGrid.Columns>
+ </DataGrid>
+ </DockPanel>
+
+ <DockPanel Grid.Column="1" Margin="75 0 110 0">
+ <Grid DockPanel.Dock="Top" TextElement.FontSize="20" Margin="0 0 0 10">
+ <DockPanel>
+ <TextBlock HorizontalAlignment="Center">Delta E Reference Point</TextBlock>
+ <StackPanel Orientation="Horizontal" Margin="20 0 0 0">
+ <TextBlock FontWeight="SemiBold">L:</TextBlock>
+ <mahapps:NumericUpDown MinWidth="120" HorizontalContentAlignment="Left" Value="{Binding MeasureL,UpdateSourceTrigger=PropertyChanged}" Minimum="0" Maximum="100" Margin="5 0 0 0" HasDecimals="True" HideUpDownButtons="True" Background="Transparent" BorderThickness="1" />
+
+ <TextBlock Margin="20 0 0 0" FontWeight="SemiBold">A:</TextBlock>
+ <mahapps:NumericUpDown MinWidth="120" HorizontalContentAlignment="Left" Value="{Binding MeasureA,UpdateSourceTrigger=PropertyChanged}" Minimum="-127" Maximum="128" Margin="5 0 0 0" HasDecimals="True" HideUpDownButtons="True" Background="Transparent" BorderThickness="1" />
+
+ <TextBlock Margin="20 0 0 0" FontWeight="SemiBold">B:</TextBlock>
+ <mahapps:NumericUpDown MinWidth="120" HorizontalContentAlignment="Left" Value="{Binding MeasureB,UpdateSourceTrigger=PropertyChanged}" Minimum="-127" Maximum="128" Margin="5 0 0 0" HasDecimals="True" HideUpDownButtons="True" Background="Transparent" BorderThickness="1" />
+ </StackPanel>
+ </DockPanel>
+ </Grid>
+ <Grid>
+ <Border Padding="20" BorderThickness="1" BorderBrush="#202020">
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="55"/>
+ <ColumnDefinition Width="438*"/>
+ </Grid.ColumnDefinitions>
+
+ <Border Margin="0 1 0 2">
+ <componentsX:GraphAxisControl Orientation="Vertical" FontSize="10" Surface="{Binding ElementName=Graph}" StringFormat="Δ 0.00;-#" />
+ </Border>
+ <Border Grid.Column="1" BorderThickness="1" BorderBrush="Silver" Margin="1 0 0 0">
+ <Grid>
+
+ <componentsX:GraphGridLines Foreground="Silver" />
+
+ <graphX:WpfGraphSurface x:Name="Graph"></graphX:WpfGraphSurface>
+ </Grid>
+ </Border>
+ </Grid>
+ </Border>
+ </Grid>
+ </DockPanel>
+ </Grid>
</Grid>
</Grid>
</UserControl>
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Views/MainView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Views/MainView.xaml.cs
index 4f890bfe1..05b5daf7e 100644
--- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Views/MainView.xaml.cs
+++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.ColorCapture/Views/MainView.xaml.cs
@@ -12,6 +12,7 @@ using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
+using Tango.MachineStudio.ColorCapture.ViewModels;
namespace Tango.MachineStudio.ColorCapture.Views
{
@@ -20,9 +21,16 @@ namespace Tango.MachineStudio.ColorCapture.Views
/// </summary>
public partial class MainView : UserControl
{
+ private MainViewVM _vm;
+
public MainView()
{
InitializeComponent();
+ Loaded += (_, __) =>
+ {
+ _vm = DataContext as MainViewVM;
+ _vm.CaptureDeltaEController.Output.Output.ConnectOutput(Graph);
+ };
}
}
}
diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX.WPF/Surfaces/WpfGraphSurface.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX.WPF/Surfaces/WpfGraphSurface.cs
index b9e425282..5057949f0 100644
--- a/Software/Visual_Studio/SideChains/RealTimeGraphX.WPF/Surfaces/WpfGraphSurface.cs
+++ b/Software/Visual_Studio/SideChains/RealTimeGraphX.WPF/Surfaces/WpfGraphSurface.cs
@@ -398,6 +398,8 @@ namespace RealTimeGraphX.WPF.Surfaces
{
Input.ConnectOutput(this, true);
}
+
+ OnSurfaceSizeChanged(_grid.ActualWidth, _grid.ActualHeight);
}
/// <summary>
diff --git a/Software/Visual_Studio/SideChains/RealTimeGraphX/GraphPainterBase.cs b/Software/Visual_Studio/SideChains/RealTimeGraphX/GraphPainterBase.cs
index c9af5858d..12f6143fc 100644
--- a/Software/Visual_Studio/SideChains/RealTimeGraphX/GraphPainterBase.cs
+++ b/Software/Visual_Studio/SideChains/RealTimeGraphX/GraphPainterBase.cs
@@ -396,13 +396,13 @@ namespace RealTimeGraphX
Output = surface;
+ Output.SurfaceSizeChanged += _surface_SurfaceSizeChanged;
+
if (!fromOutput)
{
Output.ConnectInput(this, true);
}
- Output.SurfaceSizeChanged += _surface_SurfaceSizeChanged;
-
_size_changed = true;
}
diff --git a/Software/Visual_Studio/TCC/Tango.TCC.BL/CardDetectionResult.cs b/Software/Visual_Studio/TCC/Tango.TCC.BL/CardDetectionResult.cs
new file mode 100644
index 000000000..821d19330
--- /dev/null
+++ b/Software/Visual_Studio/TCC/Tango.TCC.BL/CardDetectionResult.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Media.Imaging;
+using Tango.PMR.TCC;
+
+namespace Tango.TCC.BL
+{
+ public class CardDetectionResult
+ {
+ public bool IsDetected { get; set; }
+ public BitmapSource DetectedBitmap { get; set; }
+ public DetectionOutput ColorDetectionOutput { get; set; }
+ }
+}
diff --git a/Software/Visual_Studio/TCC/Tango.TCC.BL/CardDetector.cs b/Software/Visual_Studio/TCC/Tango.TCC.BL/CardDetector.cs
new file mode 100644
index 000000000..d10e99b81
--- /dev/null
+++ b/Software/Visual_Studio/TCC/Tango.TCC.BL/CardDetector.cs
@@ -0,0 +1,74 @@
+using Google.Protobuf;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using Tango.PMR.TCC;
+
+namespace Tango.TCC.BL
+{
+ public class CardDetector
+ {
+ private ColorDetector _colorDetector;
+
+ private bool _canDetect;
+ public bool CanDetect
+ {
+ get { return _canDetect; }
+ private set { _canDetect = value; }
+ }
+
+ public CardDetector()
+ {
+ CanDetect = true;
+ _colorDetector = new ColorDetector();
+ }
+
+ public Task<CardDetectionResult> Detect(BitmapSource source)
+ {
+ if (!CanDetect)
+ {
+ throw new InvalidOperationException("Cannot detect the card at this moment. Please wait for CanDetect to be true.");
+ }
+
+ CanDetect = false;
+
+ var cloned = source.Clone();
+ cloned.Freeze();
+
+ return Task.Factory.StartNew<CardDetectionResult>(() =>
+ {
+ CardDetectionResult detectionResult = new CardDetectionResult();
+
+ Tango.TCC.CardDetector.CardDetection detector = new TCC.CardDetector.CardDetection();
+ var result = detector.Detect(cloned.ToBytes(PixelFormats.Rgb24), new TCC.CardDetector.CardDetectionConfig()
+ {
+ DesiredBitmapWidth = 300,
+ DesiredBitmapHeight = 310,
+ });
+
+ if (result.IsDetected)
+ {
+ detectionResult.IsDetected = true;
+ detectionResult.DetectedBitmap = result.DetectedBitmap.ToBitmapSource();
+
+ detectionResult.ColorDetectionOutput = _colorDetector.Detect(new DetectionInput()
+ {
+ Bitmap = ByteString.CopyFrom(detectionResult.DetectedBitmap.ToBmpBytes()),
+ Columns = 10,
+ Rows = 11,
+ TargetIndex = 89,
+ RequestColorMatrix = true,
+ });
+ }
+
+ CanDetect = true;
+
+ return detectionResult;
+ });
+ }
+ }
+}
diff --git a/Software/Visual_Studio/TCC/Tango.TCC.BL/Tango.TCC.BL.csproj b/Software/Visual_Studio/TCC/Tango.TCC.BL/Tango.TCC.BL.csproj
index 39aa7e8b2..bb82e8c5d 100644
--- a/Software/Visual_Studio/TCC/Tango.TCC.BL/Tango.TCC.BL.csproj
+++ b/Software/Visual_Studio/TCC/Tango.TCC.BL/Tango.TCC.BL.csproj
@@ -34,18 +34,25 @@
<Reference Include="Google.Protobuf, Version=3.4.1.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
<HintPath>..\..\packages\Google.Protobuf.3.4.1\lib\net45\Google.Protobuf.dll</HintPath>
</Reference>
+ <Reference Include="PresentationCore" />
+ <Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Web" />
+ <Reference Include="System.Windows" />
+ <Reference Include="System.Xaml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
+ <Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="CardDetectionResult.cs" />
+ <Compile Include="CardDetector.cs" />
<Compile Include="ColorDetector.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Web\ColorDetectionRequest.cs" />
@@ -71,6 +78,10 @@
<Project>{5001990f-977b-48ff-b217-0236a5022ad8}</Project>
<Name>Tango.Web</Name>
</ProjectReference>
+ <ProjectReference Include="..\Tango.TCC.CardDetector\Tango.TCC.CardDetector.vcxproj">
+ <Project>{bb268536-9e03-46a4-9b11-6025211d87f0}</Project>
+ <Name>Tango.TCC.CardDetector</Name>
+ </ProjectReference>
<ProjectReference Include="..\Tango.TCC.OpenCV.DLL\Tango.TCC.OpenCV.DLL.csproj">
<Project>{5d0d4053-cab3-4a4a-929e-37a76483bc22}</Project>
<Name>Tango.TCC.OpenCV.DLL</Name>
diff --git a/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/ArucoUtils.cpp b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/ArucoUtils.cpp
new file mode 100644
index 000000000..76923a5c6
--- /dev/null
+++ b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/ArucoUtils.cpp
@@ -0,0 +1,89 @@
+#include "ArucoUtils.h"
+
+using namespace Tango::TCC::CardDetector;
+
+Ptr<Dictionary> dictionary;
+
+ArucoUtils::ArucoUtils()
+{
+ dictionary = getPredefinedDictionary(aruco::DICT_4X4_50);
+}
+
+
+ArucoUtils::~ArucoUtils()
+{
+}
+
+vector<Point> ArucoUtils::getArcusVertices(Mat image)
+{
+ vector<Point> vertices;
+
+ vector<int> ids;
+ vector<vector<Point2f>> corners;
+
+ aruco::DetectorParameters* params = new aruco::DetectorParameters();
+ params->cornerRefinementMethod = aruco::CORNER_REFINE_SUBPIX;
+ params->perspectiveRemovePixelPerCell = 50;
+
+
+ aruco::detectMarkers(image, dictionary, corners, ids, &(*params));
+ if (corners.size() == 4)
+ {
+ //aruco::drawDetectedMarkers(image, corners, ids);
+
+ vertices =
+ {
+ Point(0,0),
+ Point(0,0),
+ Point(0,0),
+ Point(0,0)
+ };
+
+ InputArrayOfArrays _corners = corners;
+ InputArray _ids = ids;
+
+ int nMarkers = (int)_corners.total();
+
+ for (int i = 0; i < nMarkers; i++) {
+
+ Mat currentMarker = _corners.getMat(i);
+ int id = _ids.getMat().ptr< int >(0)[i] - 1;
+
+ switch (id)
+ {
+ case 0:
+ vertices[0] = currentMarker.ptr< Point2f >(0)[0];
+ break;
+ case 1:
+ vertices[1] = currentMarker.ptr< Point2f >(0)[1];
+ break;
+ case 2:
+ vertices[2] = currentMarker.ptr< Point2f >(0)[2];
+ break;
+ case 3:
+ vertices[3] = currentMarker.ptr< Point2f >(0)[3];
+ break;
+ }
+ }
+ }
+
+ return vertices;
+}
+
+Mat ArucoUtils::applyHomography(Mat image, vector<cv::Point> vertices, Size destination_size)
+{
+ Mat im_dst = Mat::zeros(destination_size, CV_8UC3);
+
+ vector<Point2f> pts_dst;
+
+ pts_dst.push_back(Point2f(0, 0));
+ pts_dst.push_back(Point2f(destination_size.width - 1, 0));
+ pts_dst.push_back(Point2f(destination_size.width - 1, destination_size.height - 1));
+ pts_dst.push_back(Point2f(0, destination_size.height - 1));
+
+ Mat im_temp = image.clone();
+
+ Mat tform = findHomography(vertices, pts_dst);
+ warpPerspective(image, im_dst, tform, destination_size);
+ return im_dst;
+}
diff --git a/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/ArucoUtils.h b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/ArucoUtils.h
new file mode 100644
index 000000000..382adf635
--- /dev/null
+++ b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/ArucoUtils.h
@@ -0,0 +1,25 @@
+#include <opencv2/opencv.hpp>
+#include <opencv2/aruco.hpp>
+
+using namespace cv;
+using namespace std;
+using namespace aruco;
+
+#pragma once
+namespace Tango
+{
+ namespace TCC
+ {
+ namespace CardDetector {
+ class ArucoUtils
+ {
+ public:
+ ArucoUtils();
+ ~ArucoUtils();
+ vector<cv::Point> getArcusVertices(Mat image);
+ Mat applyHomography(Mat image, vector<cv::Point> vertices, cv::Size destination_size);
+ };
+ }
+ }
+}
+
diff --git a/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/AssemblyInfo.cpp b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/AssemblyInfo.cpp
new file mode 100644
index 000000000..6cc770937
--- /dev/null
+++ b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/AssemblyInfo.cpp
Binary files differ
diff --git a/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetection.cpp b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetection.cpp
new file mode 100644
index 000000000..546c228db
--- /dev/null
+++ b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetection.cpp
Binary files differ
diff --git a/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetection.h b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetection.h
new file mode 100644
index 000000000..db8f51406
--- /dev/null
+++ b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetection.h
Binary files differ
diff --git a/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetectionConfig.cpp b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetectionConfig.cpp
new file mode 100644
index 000000000..12aed5597
--- /dev/null
+++ b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetectionConfig.cpp
@@ -0,0 +1,7 @@
+#include "CardDetectionConfig.h"
+
+using namespace Tango::TCC::CardDetector;
+
+CardDetectionConfig::CardDetectionConfig()
+{
+}
diff --git a/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetectionConfig.h b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetectionConfig.h
new file mode 100644
index 000000000..f014c2159
--- /dev/null
+++ b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetectionConfig.h
@@ -0,0 +1,18 @@
+#pragma once
+
+namespace Tango
+{
+ namespace TCC
+ {
+ namespace CardDetector {
+ public ref class CardDetectionConfig
+ {
+ public:
+ CardDetectionConfig();
+ property double DesiredBitmapWidth;
+ property double DesiredBitmapHeight;
+ };
+ }
+ }
+}
+
diff --git a/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetectionResult.cpp b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetectionResult.cpp
new file mode 100644
index 000000000..4d0596f0e
--- /dev/null
+++ b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetectionResult.cpp
@@ -0,0 +1,7 @@
+#include "CardDetectionResult.h"
+
+using namespace Tango::TCC::CardDetector;
+
+CardDetectionResult::CardDetectionResult()
+{
+}
diff --git a/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetectionResult.h b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetectionResult.h
new file mode 100644
index 000000000..68507e1f4
--- /dev/null
+++ b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/CardDetectionResult.h
@@ -0,0 +1,21 @@
+#pragma once
+
+using namespace System;
+using namespace System::Drawing;
+
+namespace Tango
+{
+ namespace TCC
+ {
+ namespace CardDetector {
+ public ref class CardDetectionResult
+ {
+ public:
+ CardDetectionResult();
+ property bool IsDetected;
+ property cli::array<Byte>^ DetectedBitmap;
+ };
+ }
+ }
+}
+
diff --git a/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/Tango.TCC.CardDetector.vcxproj b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/Tango.TCC.CardDetector.vcxproj
new file mode 100644
index 000000000..2ee6e7a2d
--- /dev/null
+++ b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/Tango.TCC.CardDetector.vcxproj
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>15.0</VCProjectVersion>
+ <ProjectGuid>{BB268536-9E03-46A4-9B11-6025211D87F0}</ProjectGuid>
+ <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+ <Keyword>ManagedCProj</Keyword>
+ <RootNamespace>TangoTCCCardDetector</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <CLRSupport>true</CLRSupport>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <CLRSupport>true</CLRSupport>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <CLRSupport>true</CLRSupport>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <CLRSupport>true</CLRSupport>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>$(SolutionDir)Build\TCC\Debug</OutDir>
+ <IncludePath>$(ProjectDir);$(IncludePath)</IncludePath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(SolutionDir)Build\TCC\Release</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>$(ProjectDir)..\Tango.TCC.OpenCV;$(SolutionDir)..\External_Repositories\OpenCV;$(SolutionDir)..\External_Repositories\OpenCV\opencv_contrib-master\modules\aruco\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>opencv_calib3d330d.lib;opencv_core330d.lib;opencv_features2d330d.lib;opencv_flann330d.lib;opencv_highgui330d.lib;opencv_imgproc330d.lib;opencv_imgcodecs330d.lib;opencv_ml330d.lib;opencv_objdetect330d.lib;opencv_photo330d.lib;opencv_stitching330d.lib;opencv_superres330d.lib;opencv_video330d.lib;opencv_videostab330d.lib;opencv_videoio330d.lib;opencv_aruco330d.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>$(SolutionDir)..\External_Repositories\OpenCV\bin;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies />
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies />
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies />
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="ArucoUtils.h" />
+ <ClInclude Include="bitmap_image.hpp" />
+ <ClInclude Include="CardDetection.h" />
+ <ClInclude Include="CardDetectionConfig.h" />
+ <ClInclude Include="CardDetectionResult.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="ArucoUtils.cpp" />
+ <ClCompile Include="AssemblyInfo.cpp" />
+ <ClCompile Include="CardDetection.cpp" />
+ <ClCompile Include="CardDetectionConfig.cpp" />
+ <ClCompile Include="CardDetectionResult.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/Tango.TCC.CardDetector.vcxproj.filters b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/Tango.TCC.CardDetector.vcxproj.filters
new file mode 100644
index 000000000..4e7e00d7b
--- /dev/null
+++ b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/Tango.TCC.CardDetector.vcxproj.filters
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="CardDetection.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="ArucoUtils.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="CardDetectionResult.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="CardDetectionConfig.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="bitmap_image.hpp">
+ <Filter>Source Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="AssemblyInfo.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="CardDetection.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ArucoUtils.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="CardDetectionResult.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="CardDetectionConfig.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/app.ico b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/app.ico
new file mode 100644
index 000000000..789d7ccbb
--- /dev/null
+++ b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/app.ico
Binary files differ
diff --git a/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/app.rc b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/app.rc
new file mode 100644
index 000000000..eab43064f
--- /dev/null
+++ b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/app.rc
Binary files differ
diff --git a/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/bitmap_image.hpp b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/bitmap_image.hpp
new file mode 100644
index 000000000..cd4b450ee
--- /dev/null
+++ b/Software/Visual_Studio/TCC/Tango.TCC.CardDetector/bitmap_image.hpp
@@ -0,0 +1,5105 @@
+/*
+ *****************************************************************************
+ * *
+ * Platform Independent *
+ * Bitmap Image Reader Writer Library *
+ * *
+ * Author: Arash Partow - 2002 *
+ * URL: http://partow.net/programming/bitmap/index.html *
+ * *
+ * Note: This library only supports 24-bits per pixel bitmap format files. *
+ * *
+ * Copyright notice: *
+ * Free use of the Platform Independent Bitmap Image Reader Writer Library *
+ * is permitted under the guidelines and in accordance with the most current *
+ * version of the MIT License. *
+ * http://www.opensource.org/licenses/MIT *
+ * *
+ *****************************************************************************
+*/
+
+
+#ifndef INCLUDE_BITMAP_IMAGE_HPP
+#define INCLUDE_BITMAP_IMAGE_HPP
+
+#include <algorithm>
+#include <cmath>
+#include <cstdlib>
+#include <cstring>
+#include <fstream>
+#include <iostream>
+#include <iterator>
+#include <limits>
+#include <string>
+#include <vector>
+#include <sstream>
+
+
+class bitmap_image
+{
+public:
+
+ enum channel_mode {
+ rgb_mode = 0,
+ bgr_mode = 1
+ };
+
+ enum color_plane {
+ blue_plane = 0,
+ green_plane = 1,
+ red_plane = 2
+ };
+
+ struct rgb_t
+ {
+ unsigned char red;
+ unsigned char green;
+ unsigned char blue;
+ };
+
+ bitmap_image()
+ : file_name_(""),
+ width_(0),
+ height_(0),
+ row_increment_(0),
+ bytes_per_pixel_(3),
+ channel_mode_(bgr_mode)
+ {}
+
+ bitmap_image(const std::string& filename)
+ : file_name_(filename),
+ width_(0),
+ height_(0),
+ row_increment_(0),
+ bytes_per_pixel_(0),
+ channel_mode_(bgr_mode)
+ {
+ load_bitmap();
+ }
+
+ bitmap_image(unsigned char* data, size_t length)
+ : file_name_(""),
+ width_(0),
+ height_(0),
+ row_increment_(0),
+ bytes_per_pixel_(0),
+ channel_mode_(bgr_mode)
+ {
+ load_bitmap_from_memory(data, length);
+ }
+
+ bitmap_image(const unsigned int width, const unsigned int height)
+ : file_name_(""),
+ width_(width),
+ height_(height),
+ row_increment_(0),
+ bytes_per_pixel_(3),
+ channel_mode_(bgr_mode)
+ {
+ create_bitmap();
+ }
+
+ bitmap_image(const bitmap_image& image)
+ : file_name_(image.file_name_),
+ width_(image.width_),
+ height_(image.height_),
+ row_increment_(0),
+ bytes_per_pixel_(3),
+ channel_mode_(bgr_mode)
+ {
+ create_bitmap();
+ data_ = image.data_;
+ }
+
+ bitmap_image& operator=(const bitmap_image& image)
+ {
+ if (this != &image)
+ {
+ file_name_ = image.file_name_;
+ bytes_per_pixel_ = image.bytes_per_pixel_;
+ width_ = image.width_;
+ height_ = image.height_;
+ row_increment_ = 0;
+ channel_mode_ = image.channel_mode_;
+ create_bitmap();
+ data_ = image.data_;
+ }
+
+ return *this;
+ }
+
+ inline bool operator!()
+ {
+ return (data_.size() == 0) ||
+ (width_ == 0) ||
+ (height_ == 0) ||
+ (row_increment_ == 0);
+ }
+
+ inline void clear(const unsigned char v = 0x00)
+ {
+ std::fill(data_.begin(), data_.end(), v);
+ }
+
+ inline unsigned char red_channel(const unsigned int x, const unsigned int y) const
+ {
+ return data_[(y * row_increment_) + (x * bytes_per_pixel_ + 2)];
+ }
+
+ inline unsigned char green_channel(const unsigned int x, const unsigned int y) const
+ {
+ return data_[(y * row_increment_) + (x * bytes_per_pixel_ + 1)];
+ }
+
+ inline unsigned char blue_channel(const unsigned int x, const unsigned int y) const
+ {
+ return data_[(y * row_increment_) + (x * bytes_per_pixel_ + 0)];
+ }
+
+ inline void red_channel(const unsigned int x, const unsigned int y, const unsigned char value)
+ {
+ data_[(y * row_increment_) + (x * bytes_per_pixel_ + 2)] = value;
+ }
+
+ inline void green_channel(const unsigned int x, const unsigned int y, const unsigned char value)
+ {
+ data_[(y * row_increment_) + (x * bytes_per_pixel_ + 1)] = value;
+ }
+
+ inline void blue_channel(const unsigned int x, const unsigned int y, const unsigned char value)
+ {
+ data_[(y * row_increment_) + (x * bytes_per_pixel_ + 0)] = value;
+ }
+
+ inline unsigned char* row(unsigned int row_index) const
+ {
+ return const_cast<unsigned char*>(&data_[(row_index * row_increment_)]);
+ }
+
+ inline void get_pixel(const unsigned int x, const unsigned int y,
+ unsigned char& red,
+ unsigned char& green,
+ unsigned char& blue) const
+ {
+ const unsigned int y_offset = y * row_increment_;
+ const unsigned int x_offset = x * bytes_per_pixel_;
+ const unsigned int offset = y_offset + x_offset;
+
+ blue = data_[offset + 0];
+ green = data_[offset + 1];
+ red = data_[offset + 2];
+ }
+
+ template <typename RGB>
+ inline void get_pixel(const unsigned int x, const unsigned int y, RGB& colour) const
+ {
+ get_pixel(x, y, colour.red, colour.green, colour.blue);
+ }
+
+ inline rgb_t get_pixel(const unsigned int x, const unsigned int y) const
+ {
+ rgb_t colour;
+ get_pixel(x, y, colour.red, colour.green, colour.blue);
+ return colour;
+ }
+
+ inline void set_pixel(const unsigned int x, const unsigned int y,
+ const unsigned char red,
+ const unsigned char green,
+ const unsigned char blue)
+ {
+ const unsigned int y_offset = y * row_increment_;
+ const unsigned int x_offset = x * bytes_per_pixel_;
+ const unsigned int offset = y_offset + x_offset;
+
+ data_[offset + 0] = blue;
+ data_[offset + 1] = green;
+ data_[offset + 2] = red;
+ }
+
+ template <typename RGB>
+ inline void set_pixel(const unsigned int x, const unsigned int y, const RGB& colour)
+ {
+ set_pixel(x, y, colour.red, colour.green, colour.blue);
+ }
+
+ inline bool copy_from(const bitmap_image& image)
+ {
+ if (
+ (image.height_ != height_) ||
+ (image.width_ != width_)
+ )
+ {
+ return false;
+ }
+
+ data_ = image.data_;
+
+ return true;
+ }
+
+ inline bool copy_from(const bitmap_image& source_image,
+ const unsigned int& x_offset,
+ const unsigned int& y_offset)
+ {
+ if ((x_offset + source_image.width_) > width_) { return false; }
+ if ((y_offset + source_image.height_) > height_) { return false; }
+
+ for (unsigned int y = 0; y < source_image.height_; ++y)
+ {
+ unsigned char* itr1 = row(y + y_offset) + x_offset * bytes_per_pixel_;
+ const unsigned char* itr2 = source_image.row(y);
+ const unsigned char* itr2_end = itr2 + source_image.width_ * bytes_per_pixel_;
+
+ std::copy(itr2, itr2_end, itr1);
+ }
+
+ return true;
+ }
+
+ inline bool region(const unsigned int& x,
+ const unsigned int& y,
+ const unsigned int& width,
+ const unsigned int& height,
+ bitmap_image& dest_image) const
+ {
+ if ((x + width) > width_) { return false; }
+ if ((y + height) > height_) { return false; }
+
+ if (
+ (dest_image.width_ < width_) ||
+ (dest_image.height_ < height_)
+ )
+ {
+ dest_image.setwidth_height(width, height);
+ }
+
+ for (unsigned int r = 0; r < height; ++r)
+ {
+ unsigned char* itr1 = row(r + y) + x * bytes_per_pixel_;
+ unsigned char* itr1_end = itr1 + (width * bytes_per_pixel_);
+ unsigned char* itr2 = dest_image.row(r);
+
+ std::copy(itr1, itr1_end, itr2);
+ }
+
+ return true;
+ }
+
+ inline bool roi_from_center(const unsigned int& cx,
+ const unsigned int& cy,
+ const unsigned int& width,
+ const unsigned int& height,
+ bitmap_image& dest_image) const
+ {
+ return region(cx - (width / 2), cy - (height / 2),
+ width, height,
+ dest_image);
+ }
+
+ inline bool set_region(const unsigned int& x,
+ const unsigned int& y,
+ const unsigned int& width,
+ const unsigned int& height,
+ const unsigned char& value)
+ {
+ if ((x + width) > width_) { return false; }
+ if ((y + height) > height_) { return false; }
+
+ for (unsigned int r = 0; r < height; ++r)
+ {
+ unsigned char* itr = row(r + y) + x * bytes_per_pixel_;
+ unsigned char* itr_end = itr + (width * bytes_per_pixel_);
+
+ std::fill(itr, itr_end, value);
+ }
+
+ return true;
+ }
+
+ inline bool set_region(const unsigned int& x,
+ const unsigned int& y,
+ const unsigned int& width,
+ const unsigned int& height,
+ const color_plane color,
+ const unsigned char& value)
+ {
+ if ((x + width) > width_) { return false; }
+ if ((y + height) > height_) { return false; }
+
+ const unsigned int color_plane_offset = offset(color);
+
+ for (unsigned int r = 0; r < height; ++r)
+ {
+ unsigned char* itr = row(r + y) + x * bytes_per_pixel_ + color_plane_offset;
+ unsigned char* itr_end = itr + (width * bytes_per_pixel_);
+
+ while (itr != itr_end)
+ {
+ *itr = value;
+ itr += bytes_per_pixel_;
+ }
+ }
+
+ return true;
+ }
+
+ inline bool set_region(const unsigned int& x,
+ const unsigned int& y,
+ const unsigned int& width,
+ const unsigned int& height,
+ const unsigned char& red,
+ const unsigned char& green,
+ const unsigned char& blue)
+ {
+ if ((x + width) > width_) { return false; }
+ if ((y + height) > height_) { return false; }
+
+ for (unsigned int r = 0; r < height; ++r)
+ {
+ unsigned char* itr = row(r + y) + x * bytes_per_pixel_;
+ unsigned char* itr_end = itr + (width * bytes_per_pixel_);
+
+ while (itr != itr_end)
+ {
+ *(itr++) = blue;
+ *(itr++) = green;
+ *(itr++) = red;
+ }
+ }
+
+ return true;
+ }
+
+ void reflective_image(bitmap_image& image, const bool include_diagnols = false)
+ {
+ image.setwidth_height(3 * width_, 3 * height_, true);
+
+ image.copy_from(*this, width_, height_);
+
+ vertical_flip();
+
+ image.copy_from(*this, width_, 0);
+ image.copy_from(*this, width_, 2 * height_);
+
+ vertical_flip();
+ horizontal_flip();
+
+ image.copy_from(*this, 0, height_);
+ image.copy_from(*this, 2 * width_, height_);
+
+ horizontal_flip();
+
+ if (include_diagnols)
+ {
+ bitmap_image tile = *this;
+
+ tile.vertical_flip();
+ tile.horizontal_flip();
+
+ image.copy_from(tile, 0, 0);
+ image.copy_from(tile, 2 * width_, 0);
+ image.copy_from(tile, 2 * width_, 2 * height_);
+ image.copy_from(tile, 0, 2 * height_);
+ }
+ }
+
+ inline unsigned int width() const
+ {
+ return width_;
+ }
+
+ inline unsigned int height() const
+ {
+ return height_;
+ }
+
+ inline unsigned int bytes_per_pixel() const
+ {
+ return bytes_per_pixel_;
+ }
+
+ inline unsigned int pixel_count() const
+ {
+ return width_ * height_;
+ }
+
+ inline void setwidth_height(const unsigned int width,
+ const unsigned int height,
+ const bool clear = false)
+ {
+ data_.clear();
+ width_ = width;
+ height_ = height;
+
+ create_bitmap();
+
+ if (clear)
+ {
+ std::fill(data_.begin(), data_.end(), static_cast<unsigned char>(0x00));
+ }
+ }
+
+ void save_image(const std::string& file_name) const
+ {
+ std::ofstream stream(file_name.c_str(), std::ios::binary);
+
+ if (!stream)
+ {
+ std::cerr << "bitmap_image::save_image(): Error - Could not open file " << file_name << " for writing!" << std::endl;
+ return;
+ }
+
+ bitmap_information_header bih;
+
+ bih.width = width_;
+ bih.height = height_;
+ bih.bit_count = static_cast<unsigned short>(bytes_per_pixel_ << 3);
+ bih.clr_important = 0;
+ bih.clr_used = 0;
+ bih.compression = 0;
+ bih.planes = 1;
+ bih.size = bih.struct_size();
+ bih.x_pels_per_meter = 0;
+ bih.y_pels_per_meter = 0;
+ bih.size_image = (((bih.width * bytes_per_pixel_) + 3) & 0x0000FFFC) * bih.height;
+
+ bitmap_file_header bfh;
+
+ bfh.type = 19778;
+ bfh.size = bfh.struct_size() + bih.struct_size() + bih.size_image;
+ bfh.reserved1 = 0;
+ bfh.reserved2 = 0;
+ bfh.off_bits = bih.struct_size() + bfh.struct_size();
+
+ write_bfh(stream, bfh);
+ write_bih(stream, bih);
+
+ unsigned int padding = (4 - ((3 * width_) % 4)) % 4;
+ char padding_data[4] = { 0x00, 0x00, 0x00, 0x00 };
+
+ for (unsigned int i = 0; i < height_; ++i)
+ {
+ const unsigned char* data_ptr = &data_[(row_increment_ * (height_ - i - 1))];
+
+ stream.write(reinterpret_cast<const char*>(data_ptr), sizeof(unsigned char) * bytes_per_pixel_ * width_);
+ stream.write(padding_data, padding);
+ }
+
+ stream.close();
+ }
+
+ inline void set_all_ith_bits_low(const unsigned int bitr_index)
+ {
+ unsigned char mask = static_cast<unsigned char>(~(1 << bitr_index));
+
+ for (unsigned char* itr = data(); itr != end(); ++itr)
+ {
+ *itr &= mask;
+ }
+ }
+
+ inline void set_all_ith_bits_high(const unsigned int bitr_index)
+ {
+ unsigned char mask = static_cast<unsigned char>(1 << bitr_index);
+
+ for (unsigned char* itr = data(); itr != end(); ++itr)
+ {
+ *itr |= mask;
+ }
+ }
+
+ inline void set_all_ith_channels(const unsigned int& channel, const unsigned char& value)
+ {
+ for (unsigned char* itr = (data() + channel); itr < end(); itr += bytes_per_pixel_)
+ {
+ *itr = value;
+ }
+ }
+
+ inline void set_channel(const color_plane color, const unsigned char& value)
+ {
+ for (unsigned char* itr = (data() + offset(color)); itr < end(); itr += bytes_per_pixel_)
+ {
+ *itr = value;
+ }
+ }
+
+ inline void ror_channel(const color_plane color, const unsigned int& ror)
+ {
+ for (unsigned char* itr = (data() + offset(color)); itr < end(); itr += bytes_per_pixel_)
+ {
+ *itr = static_cast<unsigned char>(((*itr) >> ror) | ((*itr) << (8 - ror)));
+ }
+ }
+
+ inline void set_all_channels(const unsigned char& value)
+ {
+ for (unsigned char* itr = data(); itr < end(); )
+ {
+ *(itr++) = value;
+ }
+ }
+
+ inline void set_all_channels(const unsigned char& r_value,
+ const unsigned char& g_value,
+ const unsigned char& b_value)
+ {
+ for (unsigned char* itr = (data() + 0); itr < end(); itr += bytes_per_pixel_)
+ {
+ *(itr + 0) = b_value;
+ *(itr + 1) = g_value;
+ *(itr + 2) = r_value;
+ }
+ }
+
+ inline void invert_color_planes()
+ {
+ for (unsigned char* itr = data(); itr < end(); *itr = ~(*itr), ++itr);
+ }
+
+ inline void add_to_color_plane(const color_plane color, const unsigned char& value)
+ {
+ for (unsigned char* itr = (data() + offset(color)); itr < end(); itr += bytes_per_pixel_)
+ {
+ (*itr) += value;
+ }
+ }
+
+ inline void convert_to_grayscale()
+ {
+ double r_scaler = 0.299;
+ double g_scaler = 0.587;
+ double b_scaler = 0.114;
+
+ if (rgb_mode == channel_mode_)
+ {
+ std::swap(r_scaler, b_scaler);
+ }
+
+ for (unsigned char* itr = data(); itr < end(); )
+ {
+ unsigned char gray_value = static_cast<unsigned char>
+ (
+ (r_scaler * (*(itr + 2))) +
+ (g_scaler * (*(itr + 1))) +
+ (b_scaler * (*(itr + 0)))
+ );
+
+ *(itr++) = gray_value;
+ *(itr++) = gray_value;
+ *(itr++) = gray_value;
+ }
+ }
+
+ inline const unsigned char* data() const
+ {
+ return data_.data();
+ }
+
+ inline unsigned char* data()
+ {
+ return const_cast<unsigned char*>(data_.data());
+ }
+
+ inline void bgr_to_rgb()
+ {
+ if ((bgr_mode == channel_mode_) && (3 == bytes_per_pixel_))
+ {
+ reverse_channels();
+ channel_mode_ = rgb_mode;
+ }
+ }
+
+ inline void rgb_to_bgr()
+ {
+ if ((rgb_mode == channel_mode_) && (3 == bytes_per_pixel_))
+ {
+ reverse_channels();
+ channel_mode_ = bgr_mode;
+ }
+ }
+
+ inline void reverse()
+ {
+ unsigned char* itr1 = data();
+ unsigned char* itr2 = end() - bytes_per_pixel_;
+
+ while (itr1 < itr2)
+ {
+ for (std::size_t i = 0; i < bytes_per_pixel_; ++i)
+ {
+ unsigned char* citr1 = itr1 + i;
+ unsigned char* citr2 = itr2 + i;
+
+ std::swap(*citr1, *citr2);
+ }
+
+ itr1 += bytes_per_pixel_;
+ itr2 -= bytes_per_pixel_;
+ }
+ }
+
+ inline void horizontal_flip()
+ {
+ for (unsigned int y = 0; y < height_; ++y)
+ {
+ unsigned char* itr1 = row(y);
+ unsigned char* itr2 = itr1 + row_increment_ - bytes_per_pixel_;
+
+ while (itr1 < itr2)
+ {
+ for (unsigned int i = 0; i < bytes_per_pixel_; ++i)
+ {
+ unsigned char* p1 = (itr1 + i);
+ unsigned char* p2 = (itr2 + i);
+
+ std::swap(*p1, *p2);
+ }
+
+ itr1 += bytes_per_pixel_;
+ itr2 -= bytes_per_pixel_;
+ }
+ }
+ }
+
+ inline void vertical_flip()
+ {
+ for (unsigned int y = 0; y < (height_ / 2); ++y)
+ {
+ unsigned char* itr1 = row(y);
+ unsigned char* itr2 = row(height_ - y - 1);
+
+ for (std::size_t x = 0; x < row_increment_; ++x)
+ {
+ std::swap(*(itr1 + x), *(itr2 + x));
+ }
+ }
+ }
+
+ inline void export_color_plane(const color_plane color, unsigned char* image)
+ {
+ for (unsigned char* itr = (data() + offset(color)); itr < end(); ++image, itr += bytes_per_pixel_)
+ {
+ (*image) = (*itr);
+ }
+ }
+
+ inline void export_color_plane(const color_plane color, bitmap_image& image)
+ {
+ if (
+ (width_ != image.width_) ||
+ (height_ != image.height_)
+ )
+ {
+ image.setwidth_height(width_, height_);
+ }
+
+ image.clear();
+
+ unsigned char* itr1 = (data() + offset(color));
+ unsigned char* itr1_end = end();
+ unsigned char* itr2 = (image.data() + offset(color));
+
+ while (itr1 < itr1_end)
+ {
+ (*itr2) = (*itr1);
+
+ itr1 += bytes_per_pixel_;
+ itr2 += bytes_per_pixel_;
+ }
+ }
+
+ inline void export_response_image(const color_plane color, double* response_image)
+ {
+ double* resp_itr = response_image;
+
+ for (unsigned char* itr = (data() + offset(color)); itr < end(); ++response_image, itr += bytes_per_pixel_)
+ {
+ *(resp_itr++) = (1.0 * (*itr)) / 256.0;
+ }
+ }
+
+ inline void export_gray_scale_response_image(double* response_image) const
+ {
+ double* resp_itr = response_image;
+
+ for (const unsigned char* itr = data(); itr < end(); itr += bytes_per_pixel_)
+ {
+ unsigned char gray_value = static_cast<unsigned char>
+ (
+ (0.299 * (*(itr + 2))) +
+ (0.587 * (*(itr + 1))) +
+ (0.114 * (*(itr + 0)))
+ );
+
+ *(resp_itr++) = (1.0 * gray_value) / 256.0;
+ }
+ }
+
+ inline void export_rgb(double* red, double* green, double* blue) const
+ {
+ if (bgr_mode != channel_mode_)
+ return;
+
+ for (const unsigned char* itr = data(); itr < end(); ++red, ++green, ++blue)
+ {
+ (*blue) = (1.0 * (*(itr++))) / 256.0;
+ (*green) = (1.0 * (*(itr++))) / 256.0;
+ (*red) = (1.0 * (*(itr++))) / 256.0;
+ }
+ }
+
+ inline void export_rgb(float* red, float* green, float* blue) const
+ {
+ if (bgr_mode != channel_mode_)
+ return;
+
+ for (const unsigned char* itr = data(); itr < end(); ++red, ++green, ++blue)
+ {
+ (*blue) = (1.0f * (*(itr++))) / 256.0f;
+ (*green) = (1.0f * (*(itr++))) / 256.0f;
+ (*red) = (1.0f * (*(itr++))) / 256.0f;
+ }
+ }
+
+ inline void export_rgb(unsigned char* red, unsigned char* green, unsigned char* blue) const
+ {
+ if (bgr_mode != channel_mode_)
+ return;
+
+ for (const unsigned char* itr = data(); itr < end(); ++red, ++green, ++blue)
+ {
+ (*blue) = *(itr++);
+ (*green) = *(itr++);
+ (*red) = *(itr++);
+ }
+ }
+
+ inline void export_ycbcr(double* y, double* cb, double* cr) const
+ {
+ if (bgr_mode != channel_mode_)
+ return;
+
+ for (const unsigned char* itr = data(); itr < end(); ++y, ++cb, ++cr)
+ {
+ const double blue = (1.0 * (*(itr++)));
+ const double green = (1.0 * (*(itr++)));
+ const double red = (1.0 * (*(itr++)));
+
+ (*y) = clamp<double>(16.0 + (1.0 / 256.0) * (65.738 * red + 129.057 * green + 25.064 * blue), 1.0, 254);
+ (*cb) = clamp<double>(128.0 + (1.0 / 256.0) * (-37.945 * red - 74.494 * green + 112.439 * blue), 1.0, 254);
+ (*cr) = clamp<double>(128.0 + (1.0 / 256.0) * (112.439 * red - 94.154 * green - 18.285 * blue), 1.0, 254);
+ }
+ }
+
+ inline void export_rgb_normal(double* red, double* green, double* blue) const
+ {
+ if (bgr_mode != channel_mode_)
+ return;
+
+ for (const unsigned char* itr = data(); itr < end(); ++red, ++green, ++blue)
+ {
+ (*blue) = (1.0 * (*(itr++)));
+ (*green) = (1.0 * (*(itr++)));
+ (*red) = (1.0 * (*(itr++)));
+ }
+ }
+
+ inline void export_rgb_normal(float* red, float* green, float* blue) const
+ {
+ if (bgr_mode != channel_mode_)
+ return;
+
+ for (const unsigned char* itr = data(); itr < end(); ++red, ++green, ++blue)
+ {
+ (*blue) = (1.0f * (*(itr++)));
+ (*green) = (1.0f * (*(itr++)));
+ (*red) = (1.0f * (*(itr++)));
+ }
+ }
+
+ inline void import_rgb(double* red, double* green, double* blue)
+ {
+ if (bgr_mode != channel_mode_)
+ return;
+
+ for (unsigned char* itr = data(); itr < end(); ++red, ++green, ++blue)
+ {
+ *(itr++) = static_cast<unsigned char>(256.0 * (*blue));
+ *(itr++) = static_cast<unsigned char>(256.0 * (*green));
+ *(itr++) = static_cast<unsigned char>(256.0 * (*red));
+ }
+ }
+
+ inline void import_rgb(float* red, float* green, float* blue)
+ {
+ if (bgr_mode != channel_mode_)
+ return;
+
+ for (unsigned char* itr = data(); itr < end(); ++red, ++green, ++blue)
+ {
+ *(itr++) = static_cast<unsigned char>(256.0f * (*blue));
+ *(itr++) = static_cast<unsigned char>(256.0f * (*green));
+ *(itr++) = static_cast<unsigned char>(256.0f * (*red));
+ }
+ }
+
+ inline void import_rgb(unsigned char* red, unsigned char* green, unsigned char* blue)
+ {
+ if (bgr_mode != channel_mode_)
+ return;
+
+ for (unsigned char* itr = data(); itr < end(); ++red, ++green, ++blue)
+ {
+ *(itr++) = (*blue);
+ *(itr++) = (*green);
+ *(itr++) = (*red);
+ }
+ }
+
+ inline void import_ycbcr(double* y, double* cb, double* cr)
+ {
+ if (bgr_mode != channel_mode_)
+ return;
+
+ for (unsigned char* itr = data(); itr < end(); ++y, ++cb, ++cr)
+ {
+ double y_ = (*y);
+ double cb_ = (*cb);
+ double cr_ = (*cr);
+
+ *(itr++) = static_cast<unsigned char>(clamp((298.082 * y_ + 516.412 * cb_) / 256.0 - 276.836, 0.0, 255.0));
+ *(itr++) = static_cast<unsigned char>(clamp((298.082 * y_ - 100.291 * cb_ - 208.120 * cr_) / 256.0 + 135.576, 0.0, 255.0));
+ *(itr++) = static_cast<unsigned char>(clamp((298.082 * y_ + 408.583 * cr_) / 256.0 - 222.921, 0.0, 255.0));
+ }
+ }
+
+ inline void import_gray_scale_clamped(double* gray)
+ {
+ if (bgr_mode != channel_mode_)
+ return;
+
+ for (unsigned char* itr = data(); itr < end(); ++gray)
+ {
+ unsigned char c = static_cast<unsigned char>(clamp<double>(256.0 * (*gray), 0.0, 255.0));
+
+ *(itr + 0) = c;
+ *(itr + 1) = c;
+ *(itr + 2) = c;
+
+ itr += 3;
+ }
+ }
+
+ inline void import_rgb_clamped(double* red, double* green, double* blue)
+ {
+ if (bgr_mode != channel_mode_)
+ return;
+
+ for (unsigned char* itr = data(); itr < end(); ++red, ++green, ++blue)
+ {
+ *(itr++) = static_cast<unsigned char>(clamp<double>(256.0 * (*blue), 0.0, 255.0));
+ *(itr++) = static_cast<unsigned char>(clamp<double>(256.0 * (*green), 0.0, 255.0));
+ *(itr++) = static_cast<unsigned char>(clamp<double>(256.0 * (*red), 0.0, 255.0));
+ }
+ }
+
+ inline void import_rgb_clamped(float* red, float* green, float* blue)
+ {
+ if (bgr_mode != channel_mode_)
+ return;
+
+ for (unsigned char* itr = data(); itr < end(); ++red, ++green, ++blue)
+ {
+ *(itr++) = static_cast<unsigned char>(clamp<double>(256.0f * (*blue), 0.0, 255.0));
+ *(itr++) = static_cast<unsigned char>(clamp<double>(256.0f * (*green), 0.0, 255.0));
+ *(itr++) = static_cast<unsigned char>(clamp<double>(256.0f * (*red), 0.0, 255.0));
+ }
+ }
+
+ inline void import_rgb_normal(double* red, double* green, double* blue)
+ {
+ if (bgr_mode != channel_mode_)
+ return;
+
+ for (unsigned char* itr = data(); itr < end(); ++red, ++green, ++blue)
+ {
+ *(itr++) = static_cast<unsigned char>(*blue);
+ *(itr++) = static_cast<unsigned char>(*green);
+ *(itr++) = static_cast<unsigned char>(*red);
+ }
+ }
+
+ inline void import_rgb_normal(float* red, float* green, float* blue)
+ {
+ if (bgr_mode != channel_mode_)
+ return;
+
+ for (unsigned char* itr = data(); itr < end(); ++red, ++green, ++blue)
+ {
+ *(itr++) = static_cast<unsigned char>(*blue);
+ *(itr++) = static_cast<unsigned char>(*green);
+ *(itr++) = static_cast<unsigned char>(*red);
+ }
+ }
+
+ inline void subsample(bitmap_image& dest) const
+ {
+ /*
+ Half sub-sample of original image.
+ */
+ unsigned int w = 0;
+ unsigned int h = 0;
+
+ bool odd_width = false;
+ bool odd_height = false;
+
+ if (0 == (width_ % 2))
+ w = width_ / 2;
+ else
+ {
+ w = 1 + (width_ / 2);
+ odd_width = true;
+ }
+
+ if (0 == (height_ % 2))
+ h = height_ / 2;
+ else
+ {
+ h = 1 + (height_ / 2);
+ odd_height = true;
+ }
+
+ unsigned int horizontal_upper = (odd_width) ? (w - 1) : w;
+ unsigned int vertical_upper = (odd_height) ? (h - 1) : h;
+
+ dest.setwidth_height(w, h);
+ dest.clear();
+
+ unsigned char* s_itr[3];
+ const unsigned char* itr1[3];
+ const unsigned char* itr2[3];
+
+ s_itr[0] = dest.data() + 0;
+ s_itr[1] = dest.data() + 1;
+ s_itr[2] = dest.data() + 2;
+
+ itr1[0] = data() + 0;
+ itr1[1] = data() + 1;
+ itr1[2] = data() + 2;
+
+ itr2[0] = data() + row_increment_ + 0;
+ itr2[1] = data() + row_increment_ + 1;
+ itr2[2] = data() + row_increment_ + 2;
+
+ unsigned int total = 0;
+
+ for (unsigned int j = 0; j < vertical_upper; ++j)
+ {
+ for (unsigned int i = 0; i < horizontal_upper; ++i)
+ {
+ for (unsigned int k = 0; k < bytes_per_pixel_; s_itr[k] += bytes_per_pixel_, ++k)
+ {
+ total = 0;
+ total += *(itr1[k]);
+ total += *(itr1[k]);
+ total += *(itr2[k]);
+ total += *(itr2[k]);
+
+ itr1[k] += bytes_per_pixel_;
+ itr1[k] += bytes_per_pixel_;
+ itr2[k] += bytes_per_pixel_;
+ itr2[k] += bytes_per_pixel_;
+
+ *(s_itr[k]) = static_cast<unsigned char>(total >> 2);
+ }
+ }
+
+ if (odd_width)
+ {
+ for (unsigned int k = 0; k < bytes_per_pixel_; s_itr[k] += bytes_per_pixel_, ++k)
+ {
+ total = 0;
+ total += *(itr1[k]);
+ total += *(itr2[k]);
+
+ itr1[k] += bytes_per_pixel_;
+ itr2[k] += bytes_per_pixel_;
+
+ *(s_itr[k]) = static_cast<unsigned char>(total >> 1);
+ }
+ }
+
+ for (unsigned int k = 0; k < bytes_per_pixel_; ++k)
+ {
+ itr1[k] += row_increment_;
+ }
+
+ if (j != (vertical_upper - 1))
+ {
+ for (unsigned int k = 0; k < bytes_per_pixel_; ++k)
+ {
+ itr2[k] += row_increment_;
+ }
+ }
+ }
+
+ if (odd_height)
+ {
+ for (unsigned int i = 0; i < horizontal_upper; ++i)
+ {
+ for (unsigned int k = 0; k < bytes_per_pixel_; s_itr[k] += bytes_per_pixel_, ++k)
+ {
+ total = 0;
+ total += *(itr1[k]);
+ total += *(itr2[k]);
+
+ itr1[k] += bytes_per_pixel_;
+ itr2[k] += bytes_per_pixel_;
+
+ *(s_itr[k]) = static_cast<unsigned char>(total >> 1);
+ }
+ }
+
+ if (odd_width)
+ {
+ for (unsigned int k = 0; k < bytes_per_pixel_; ++k)
+ {
+ (*(s_itr[k])) = *(itr1[k]);
+ }
+ }
+ }
+ }
+
+ inline void upsample(bitmap_image& dest) const
+ {
+ /*
+ 2x up-sample of original image.
+ */
+
+ dest.setwidth_height(2 * width_, 2 * height_);
+ dest.clear();
+
+ const unsigned char* s_itr[3];
+ unsigned char* itr1[3];
+ unsigned char* itr2[3];
+
+ s_itr[0] = data() + 0;
+ s_itr[1] = data() + 1;
+ s_itr[2] = data() + 2;
+
+ itr1[0] = dest.data() + 0;
+ itr1[1] = dest.data() + 1;
+ itr1[2] = dest.data() + 2;
+
+ itr2[0] = dest.data() + dest.row_increment_ + 0;
+ itr2[1] = dest.data() + dest.row_increment_ + 1;
+ itr2[2] = dest.data() + dest.row_increment_ + 2;
+
+ for (unsigned int j = 0; j < height_; ++j)
+ {
+ for (unsigned int i = 0; i < width_; ++i)
+ {
+ for (unsigned int k = 0; k < bytes_per_pixel_; s_itr[k] += bytes_per_pixel_, ++k)
+ {
+ *(itr1[k]) = *(s_itr[k]); itr1[k] += bytes_per_pixel_;
+ *(itr1[k]) = *(s_itr[k]); itr1[k] += bytes_per_pixel_;
+
+ *(itr2[k]) = *(s_itr[k]); itr2[k] += bytes_per_pixel_;
+ *(itr2[k]) = *(s_itr[k]); itr2[k] += bytes_per_pixel_;
+ }
+ }
+
+ for (unsigned int k = 0; k < bytes_per_pixel_; ++k)
+ {
+ itr1[k] += dest.row_increment_;
+ itr2[k] += dest.row_increment_;
+ }
+ }
+ }
+
+ inline void alpha_blend(const double& alpha, const bitmap_image& image)
+ {
+ if (
+ (image.width_ != width_) ||
+ (image.height_ != height_)
+ )
+ {
+ return;
+ }
+
+ if ((alpha < 0.0) || (alpha > 1.0))
+ {
+ return;
+ }
+
+ unsigned char* itr1 = data();
+ const unsigned char* itr1_end = end();
+ const unsigned char* itr2 = image.data();
+
+ double alpha_compliment = 1.0 - alpha;
+
+ while (itr1 != itr1_end)
+ {
+ *(itr1) = static_cast<unsigned char>((alpha * (*itr2)) + (alpha_compliment * (*itr1)));
+ ++itr1;
+ ++itr2;
+ }
+ }
+
+ inline double psnr(const bitmap_image& image)
+ {
+ if (
+ (image.width_ != width_) ||
+ (image.height_ != height_)
+ )
+ {
+ return 0.0;
+ }
+
+ const unsigned char* itr1 = data();
+ const unsigned char* itr2 = image.data();
+
+ double mse = 0.0;
+
+ while (itr1 != end())
+ {
+ const double v = (static_cast<double>(*itr1) - static_cast<double>(*itr2));
+
+ mse += v * v;
+ ++itr1;
+ ++itr2;
+ }
+
+ if (mse <= 0.0000001)
+ {
+ return 1000000.0;
+ }
+ else
+ {
+ mse /= (3.0 * width_ * height_);
+
+ return 20.0 * std::log10(255.0 / std::sqrt(mse));
+ }
+ }
+
+ inline double psnr(const unsigned int& x,
+ const unsigned int& y,
+ const bitmap_image& image)
+ {
+ if ((x + image.width()) > width_) { return 0.0; }
+ if ((y + image.height()) > height_) { return 0.0; }
+
+ double mse = 0.0;
+
+ const unsigned int height = image.height();
+ const unsigned int width = image.width();
+
+ for (unsigned int r = 0; r < height; ++r)
+ {
+ const unsigned char* itr1 = row(r + y) + x * bytes_per_pixel_;
+ const unsigned char* itr1_end = itr1 + (width * bytes_per_pixel_);
+ const unsigned char* itr2 = image.row(r);
+
+ while (itr1 != itr1_end)
+ {
+ double v = (static_cast<double>(*itr1) - static_cast<double>(*itr2));
+ mse += v * v;
+ ++itr1;
+ ++itr2;
+ }
+ }
+
+ if (mse <= 0.0000001)
+ {
+ return 1000000.0;
+ }
+ else
+ {
+ mse /= (3.0 * image.width() * image.height());
+ return 20.0 * std::log10(255.0 / std::sqrt(mse));
+ }
+ }
+
+ inline void histogram(const color_plane color, double hist[256]) const
+ {
+ std::fill(hist, hist + 256, 0.0);
+
+ for (const unsigned char* itr = (data() + offset(color)); itr < end(); itr += bytes_per_pixel_)
+ {
+ ++hist[(*itr)];
+ }
+ }
+
+ inline void histogram_normalized(const color_plane color, double hist[256]) const
+ {
+ histogram(color, hist);
+
+ double* h_itr = hist;
+ const double* h_end = hist + 256;
+ const double pixel_count = static_cast<double>(width_ * height_);
+
+ while (h_end != h_itr)
+ {
+ *(h_itr++) /= pixel_count;
+ }
+ }
+
+ inline unsigned int offset(const color_plane color) const
+ {
+ switch (channel_mode_)
+ {
+ case rgb_mode: {
+ switch (color)
+ {
+ case red_plane: return 0;
+ case green_plane: return 1;
+ case blue_plane: return 2;
+ default: return std::numeric_limits<unsigned int>::max();
+ }
+ }
+
+ case bgr_mode: {
+ switch (color)
+ {
+ case red_plane: return 2;
+ case green_plane: return 1;
+ case blue_plane: return 0;
+ default: return std::numeric_limits<unsigned int>::max();
+ }
+ }
+
+ default: return std::numeric_limits<unsigned int>::max();
+ }
+ }
+
+ inline void incremental()
+ {
+ unsigned char current_color = 0;
+
+ for (unsigned char* itr = data(); itr < end();)
+ {
+ (*itr++) = (current_color);
+ (*itr++) = (current_color);
+ (*itr++) = (current_color);
+
+ ++current_color;
+ }
+ }
+
+ inline void reverse_channels()
+ {
+ if (3 != bytes_per_pixel_)
+ return;
+
+ for (unsigned char* itr = data(); itr < end(); itr += bytes_per_pixel_)
+ {
+ std::swap(*(itr + 0), *(itr + 2));
+ }
+ }
+
+private:
+
+ inline const unsigned char* end() const
+ {
+ return data_.data() + data_.size();
+ }
+
+ inline unsigned char* end()
+ {
+ return const_cast<unsigned char*>(data() + data_.size());
+ }
+
+ struct bitmap_file_header
+ {
+ unsigned short type;
+ unsigned int size;
+ unsigned short reserved1;
+ unsigned short reserved2;
+ unsigned int off_bits;
+
+ unsigned int struct_size() const
+ {
+ return sizeof(type) +
+ sizeof(size) +
+ sizeof(reserved1) +
+ sizeof(reserved2) +
+ sizeof(off_bits);
+ }
+
+ void clear()
+ {
+ std::memset(this, 0x00, sizeof(bitmap_file_header));
+ }
+ };
+
+ struct bitmap_information_header
+ {
+ unsigned int size;
+ unsigned int width;
+ unsigned int height;
+ unsigned short planes;
+ unsigned short bit_count;
+ unsigned int compression;
+ unsigned int size_image;
+ unsigned int x_pels_per_meter;
+ unsigned int y_pels_per_meter;
+ unsigned int clr_used;
+ unsigned int clr_important;
+
+ unsigned int struct_size() const
+ {
+ return sizeof(size) +
+ sizeof(width) +
+ sizeof(height) +
+ sizeof(planes) +
+ sizeof(bit_count) +
+ sizeof(compression) +
+ sizeof(size_image) +
+ sizeof(x_pels_per_meter) +
+ sizeof(y_pels_per_meter) +
+ sizeof(clr_used) +
+ sizeof(clr_important);
+ }
+
+ void clear()
+ {
+ std::memset(this, 0x00, sizeof(bitmap_information_header));
+ }
+ };
+
+ inline bool big_endian() const
+ {
+ unsigned int v = 0x01;
+
+ return (1 != reinterpret_cast<char*>(&v)[0]);
+ }
+
+ inline unsigned short flip(const unsigned short& v) const
+ {
+ return ((v >> 8) | (v << 8));
+ }
+
+ inline unsigned int flip(const unsigned int& v) const
+ {
+ return (
+ ((v & 0xFF000000) >> 0x18) |
+ ((v & 0x000000FF) << 0x18) |
+ ((v & 0x00FF0000) >> 0x08) |
+ ((v & 0x0000FF00) << 0x08)
+ );
+ }
+
+ template <typename T>
+ inline void read_from_stream(std::istream& stream, T& t)
+ {
+ stream.read(reinterpret_cast<char*>(&t), sizeof(T));
+ }
+
+ template <typename T>
+ inline void write_to_stream(std::ofstream& stream, const T& t) const
+ {
+ stream.write(reinterpret_cast<const char*>(&t), sizeof(T));
+ }
+
+ inline void read_bfh(std::istream& stream, bitmap_file_header& bfh)
+ {
+ read_from_stream(stream, bfh.type);
+ read_from_stream(stream, bfh.size);
+ read_from_stream(stream, bfh.reserved1);
+ read_from_stream(stream, bfh.reserved2);
+ read_from_stream(stream, bfh.off_bits);
+
+ if (big_endian())
+ {
+ bfh.type = flip(bfh.type);
+ bfh.size = flip(bfh.size);
+ bfh.reserved1 = flip(bfh.reserved1);
+ bfh.reserved2 = flip(bfh.reserved2);
+ bfh.off_bits = flip(bfh.off_bits);
+ }
+ }
+
+ inline void write_bfh(std::ofstream& stream, const bitmap_file_header& bfh) const
+ {
+ if (big_endian())
+ {
+ write_to_stream(stream, flip(bfh.type));
+ write_to_stream(stream, flip(bfh.size));
+ write_to_stream(stream, flip(bfh.reserved1));
+ write_to_stream(stream, flip(bfh.reserved2));
+ write_to_stream(stream, flip(bfh.off_bits));
+ }
+ else
+ {
+ write_to_stream(stream, bfh.type);
+ write_to_stream(stream, bfh.size);
+ write_to_stream(stream, bfh.reserved1);
+ write_to_stream(stream, bfh.reserved2);
+ write_to_stream(stream, bfh.off_bits);
+ }
+ }
+
+ inline void read_bih(std::istream& stream, bitmap_information_header& bih)
+ {
+ read_from_stream(stream, bih.size);
+ read_from_stream(stream, bih.width);
+ read_from_stream(stream, bih.height);
+ read_from_stream(stream, bih.planes);
+ read_from_stream(stream, bih.bit_count);
+ read_from_stream(stream, bih.compression);
+ read_from_stream(stream, bih.size_image);
+ read_from_stream(stream, bih.x_pels_per_meter);
+ read_from_stream(stream, bih.y_pels_per_meter);
+ read_from_stream(stream, bih.clr_used);
+ read_from_stream(stream, bih.clr_important);
+
+ if (big_endian())
+ {
+ bih.size = flip(bih.size);
+ bih.width = flip(bih.width);
+ bih.height = flip(bih.height);
+ bih.planes = flip(bih.planes);
+ bih.bit_count = flip(bih.bit_count);
+ bih.compression = flip(bih.compression);
+ bih.size_image = flip(bih.size_image);
+ bih.x_pels_per_meter = flip(bih.x_pels_per_meter);
+ bih.y_pels_per_meter = flip(bih.y_pels_per_meter);
+ bih.clr_used = flip(bih.clr_used);
+ bih.clr_important = flip(bih.clr_important);
+ }
+ }
+
+ inline void write_bih(std::ofstream& stream, const bitmap_information_header& bih) const
+ {
+ if (big_endian())
+ {
+ write_to_stream(stream, flip(bih.size));
+ write_to_stream(stream, flip(bih.width));
+ write_to_stream(stream, flip(bih.height));
+ write_to_stream(stream, flip(bih.planes));
+ write_to_stream(stream, flip(bih.bit_count));
+ write_to_stream(stream, flip(bih.compression));
+ write_to_stream(stream, flip(bih.size_image));
+ write_to_stream(stream, flip(bih.x_pels_per_meter));
+ write_to_stream(stream, flip(bih.y_pels_per_meter));
+ write_to_stream(stream, flip(bih.clr_used));
+ write_to_stream(stream, flip(bih.clr_important));
+ }
+ else
+ {
+ write_to_stream(stream, bih.size);
+ write_to_stream(stream, bih.width);
+ write_to_stream(stream, bih.height);
+ write_to_stream(stream, bih.planes);
+ write_to_stream(stream, bih.bit_count);
+ write_to_stream(stream, bih.compression);
+ write_to_stream(stream, bih.size_image);
+ write_to_stream(stream, bih.x_pels_per_meter);
+ write_to_stream(stream, bih.y_pels_per_meter);
+ write_to_stream(stream, bih.clr_used);
+ write_to_stream(stream, bih.clr_important);
+ }
+ }
+
+ inline std::size_t file_size(const std::string& file_name) const
+ {
+ std::ifstream file(file_name.c_str(), std::ios::in | std::ios::binary);
+ if (!file) return 0;
+ file.seekg(0, std::ios::end);
+ return static_cast<std::size_t>(file.tellg());
+ }
+
+ void create_bitmap()
+ {
+ row_increment_ = width_ * bytes_per_pixel_;
+ data_.resize(height_ * row_increment_);
+ }
+
+ void load_bitmap()
+ {
+ std::ifstream stream(file_name_.c_str(), std::ios::binary);
+
+ if (!stream)
+ {
+ std::cerr << "bitmap_image::load_bitmap() ERROR: bitmap_image - file " << file_name_ << " not found!" << std::endl;
+ return;
+ }
+
+ width_ = 0;
+ height_ = 0;
+
+ bitmap_file_header bfh;
+ bitmap_information_header bih;
+
+ bfh.clear();
+ bih.clear();
+
+ read_bfh(stream, bfh);
+ read_bih(stream, bih);
+
+ if (bfh.type != 19778)
+ {
+ bfh.clear();
+ bih.clear();
+
+ stream.close();
+
+ std::cerr << "bitmap_image::load_bitmap() ERROR: bitmap_image - Invalid type value " << bfh.type << " expected 19778." << std::endl;
+ return;
+ }
+
+ if (bih.bit_count != 24)
+ {
+ bfh.clear();
+ bih.clear();
+
+ stream.close();
+
+ std::cerr << "bitmap_image::load_bitmap() ERROR: bitmap_image - Invalid bit depth " << bih.bit_count << " expected 24." << std::endl;
+
+ return;
+ }
+
+ if (bih.size != bih.struct_size())
+ {
+ bfh.clear();
+ bih.clear();
+
+ stream.close();
+
+ std::cerr << "bitmap_image::load_bitmap() ERROR: bitmap_image - Invalid BIH size " << bih.size << " expected " << bih.struct_size() << std::endl;
+
+ return;
+ }
+
+ width_ = bih.width;
+ height_ = bih.height;
+
+ bytes_per_pixel_ = bih.bit_count >> 3;
+
+ unsigned int padding = (4 - ((3 * width_) % 4)) % 4;
+ char padding_data[4] = { 0,0,0,0 };
+
+ std::size_t bitmap_file_size = file_size(file_name_);
+
+ std::size_t bitmap_logical_size = (height_ * width_ * bytes_per_pixel_) +
+ (height_ * padding) +
+ bih.struct_size() +
+ bfh.struct_size();
+
+ if (bitmap_file_size != bitmap_logical_size)
+ {
+ bfh.clear();
+ bih.clear();
+
+ stream.close();
+
+ std::cerr << "bitmap_image::load_bitmap() ERROR: bitmap_image - Mismatch between logical and physical sizes of bitmap. " <<
+ "Logical: " << bitmap_logical_size << " " <<
+ "Physical: " << bitmap_file_size << std::endl;
+
+ return;
+ }
+
+ create_bitmap();
+
+ for (unsigned int i = 0; i < height_; ++i)
+ {
+ unsigned char* data_ptr = row(height_ - i - 1); // read in inverted row order
+
+ stream.read(reinterpret_cast<char*>(data_ptr), sizeof(char) * bytes_per_pixel_ * width_);
+ stream.read(padding_data, padding);
+ }
+ }
+
+ void load_bitmap_from_memory(unsigned char* data, size_t length)
+ {
+ std::string str((char*)data, length);
+ std::stringstream s(str);
+
+ std::istream& stream = s;
+
+ if (!stream)
+ {
+ std::cerr << "bitmap_image::load_bitmap() ERROR: bitmap_image - file " << file_name_ << " not found!" << std::endl;
+ return;
+ }
+
+ width_ = 0;
+ height_ = 0;
+
+ bitmap_file_header bfh;
+ bitmap_information_header bih;
+
+ bfh.clear();
+ bih.clear();
+
+ read_bfh(stream, bfh);
+ read_bih(stream, bih);
+
+ if (bfh.type != 19778)
+ {
+ bfh.clear();
+ bih.clear();
+
+ //stream.close();
+
+ std::cerr << "bitmap_image::load_bitmap() ERROR: bitmap_image - Invalid type value " << bfh.type << " expected 19778." << std::endl;
+ return;
+ }
+
+ if (bih.bit_count != 24)
+ {
+ bfh.clear();
+ bih.clear();
+
+ //stream.close();
+
+ std::cerr << "bitmap_image::load_bitmap() ERROR: bitmap_image - Invalid bit depth " << bih.bit_count << " expected 24." << std::endl;
+
+ return;
+ }
+
+ if (bih.size != bih.struct_size())
+ {
+ bfh.clear();
+ bih.clear();
+
+ //stream.close();
+
+ std::cerr << "bitmap_image::load_bitmap() ERROR: bitmap_image - Invalid BIH size " << bih.size << " expected " << bih.struct_size() << std::endl;
+
+ return;
+ }
+
+ width_ = bih.width;
+ height_ = bih.height;
+
+ bytes_per_pixel_ = bih.bit_count >> 3;
+
+ unsigned int padding = (4 - ((3 * width_) % 4)) % 4;
+ char padding_data[4] = { 0,0,0,0 };
+
+ std::size_t bitmap_file_size = length;
+
+ std::size_t bitmap_logical_size = (height_ * width_ * bytes_per_pixel_) +
+ (height_ * padding) +
+ bih.struct_size() +
+ bfh.struct_size();
+
+ if (bitmap_file_size != bitmap_logical_size)
+ {
+ bfh.clear();
+ bih.clear();
+
+ //stream.close();
+
+ std::cerr << "bitmap_image::load_bitmap() ERROR: bitmap_image - Mismatch between logical and physical sizes of bitmap. " <<
+ "Logical: " << bitmap_logical_size << " " <<
+ "Physical: " << bitmap_file_size << std::endl;
+
+ return;
+ }
+
+ create_bitmap();
+
+ for (unsigned int i = 0; i < height_; ++i)
+ {
+ unsigned char* data_ptr = row(height_ - i - 1); // read in inverted row order
+
+ stream.read(reinterpret_cast<char*>(data_ptr), sizeof(char) * bytes_per_pixel_ * width_);
+ stream.read(padding_data, padding);
+ }
+ }
+
+ template <typename T>
+ inline T clamp(const T& v, const T& lower_range, const T& upper_range) const
+ {
+ if (v < lower_range)
+ return lower_range;
+ else if (v > upper_range)
+ return upper_range;
+ else
+ return v;
+ }
+
+ std::string file_name_;
+ unsigned int width_;
+ unsigned int height_;
+ unsigned int row_increment_;
+ unsigned int bytes_per_pixel_;
+ channel_mode channel_mode_;
+ std::vector<unsigned char> data_;
+};
+
+typedef bitmap_image::rgb_t rgb_t;
+
+inline bool operator==(const rgb_t& c0, const rgb_t& c1)
+{
+ return (c0.red == c1.red) &&
+ (c0.green == c1.green) &&
+ (c0.blue == c1.blue);
+}
+
+inline bool operator!=(const rgb_t& c0, const rgb_t& c1)
+{
+ return (c0.red != c1.red) ||
+ (c0.green != c1.green) ||
+ (c0.blue != c1.blue);
+}
+
+inline std::size_t hamming_distance(const rgb_t& c0, const rgb_t& c1)
+{
+ std::size_t result = 0;
+
+ if (c0.red != c1.red) ++result;
+ if (c0.green != c1.green) ++result;
+ if (c0.blue != c1.blue) ++result;
+
+ return result;
+}
+
+inline rgb_t make_colour(const unsigned int& red, const unsigned int& green, const unsigned int& blue)
+{
+ rgb_t result;
+
+ result.red = static_cast<unsigned char>(red);
+ result.green = static_cast<unsigned char>(green);
+ result.blue = static_cast<unsigned char>(blue);
+
+ return result;
+}
+
+template <typename OutputIterator>
+inline void generate_colours(const std::size_t& steps, const rgb_t c0, const rgb_t& c1, OutputIterator out)
+{
+ double dr = ((double)c1.red - (double)c0.red) / steps;
+ double dg = ((double)c1.green - (double)c0.green) / steps;
+ double db = ((double)c1.blue - (double)c0.blue) / steps;
+
+ for (std::size_t i = 0; i < steps; ++i)
+ {
+ rgb_t c;
+
+ c.red = static_cast<unsigned char>(c0.red + (i * dr));
+ c.green = static_cast<unsigned char>(c0.green + (i * dg));
+ c.blue = static_cast<unsigned char>(c0.blue + (i * db));
+
+ *(out++) = c;
+ }
+}
+
+template <typename ResponseImage, typename Palette>
+inline std::size_t convert_rsp_to_image(const ResponseImage& resp_image, const Palette& palette, bitmap_image& image)
+{
+ if (
+ (resp_image.width() > image.width()) ||
+ (resp_image.height() > image.height())
+ )
+ return 0;
+
+ for (std::size_t y = 0; y < resp_image.height(); ++y)
+ {
+ for (std::size_t x = 0; x < resp_image.width(); ++x)
+ {
+ const double v = resp_image(x, y);
+
+ unsigned int index = static_cast<unsigned int>((v < 0) ? 0 : v > (palette.size()) ? (palette.size() - 1) : v);
+
+ image.set_pixel(x, y, palette[index]);
+ }
+ }
+
+ return (resp_image.width() * resp_image.height());
+}
+
+inline void rgb_to_ycbcr(const unsigned int& length, double* red, double* green, double* blue,
+ double* y, double* cb, double* cr)
+{
+ unsigned int i = 0;
+
+ while (i < length)
+ {
+ (*y) = 16.0 + (65.481 * (*red) + 128.553 * (*green) + 24.966 * (*blue));
+ (*cb) = 128.0 + (-37.797 * (*red) + -74.203 * (*green) + 112.000 * (*blue));
+ (*cr) = 128.0 + (112.000 * (*red) + -93.786 * (*green) - 18.214 * (*blue));
+
+ ++i;
+ ++red; ++green; ++blue;
+ ++y; ++cb; ++cr;
+ }
+}
+
+inline void ycbcr_to_rgb(const unsigned int& length, double* y, double* cb, double* cr,
+ double* red, double* green, double* blue)
+{
+ unsigned int i = 0;
+
+ while (i < length)
+ {
+ double y_ = (*y) - 16.0;
+ double cb_ = (*cb) - 128.0;
+ double cr_ = (*cr) - 128.0;
+
+ (*red) = 0.000456621 * y_ + 0.00625893 * cr_;
+ (*green) = 0.000456621 * y_ - 0.00153632 * cb_ - 0.00318811 * cr_;
+ (*blue) = 0.000456621 * y_ + 0.00791071 * cb_;
+
+ ++i;
+ ++red; ++green; ++blue;
+ ++y; ++cb; ++cr;
+ }
+}
+
+inline void subsample(const unsigned int& width,
+ const unsigned int& height,
+ const double* source,
+ unsigned int& w,
+ unsigned int& h,
+ double*& dest)
+{
+ /* Single channel. */
+
+ w = 0;
+ h = 0;
+
+ bool odd_width = false;
+ bool odd_height = false;
+
+ if (0 == (width % 2))
+ w = width / 2;
+ else
+ {
+ w = 1 + (width / 2);
+ odd_width = true;
+ }
+
+ if (0 == (height % 2))
+ h = height / 2;
+ else
+ {
+ h = 1 + (height / 2);
+ odd_height = true;
+ }
+
+ unsigned int horizontal_upper = (odd_width) ? w - 1 : w;
+ unsigned int vertical_upper = (odd_height) ? h - 1 : h;
+
+ dest = new double[w * h];
+
+ double* s_itr = dest;
+ const double* itr1 = source;
+ const double* itr2 = source + width;
+
+ for (unsigned int j = 0; j < vertical_upper; ++j)
+ {
+ for (unsigned int i = 0; i < horizontal_upper; ++i, ++s_itr)
+ {
+ (*s_itr) = *(itr1++);
+ (*s_itr) += *(itr1++);
+ (*s_itr) += *(itr2++);
+ (*s_itr) += *(itr2++);
+ (*s_itr) /= 4.0;
+ }
+
+ if (odd_width)
+ {
+ (*(s_itr++)) = ((*itr1++) + (*itr2++)) / 2.0;
+ }
+
+ itr1 += width;
+
+ if (j != (vertical_upper - 1))
+ {
+ itr2 += width;
+ }
+ }
+
+ if (odd_height)
+ {
+ for (unsigned int i = 0; i < horizontal_upper; ++i, ++s_itr)
+ {
+ (*s_itr) += (*(itr1++));
+ (*s_itr) += (*(itr1++));
+ (*s_itr) /= 2.0;
+ }
+
+ if (odd_width)
+ {
+ (*(s_itr++)) = (*itr1);
+ }
+ }
+}
+
+inline void upsample(const unsigned int& width,
+ const unsigned int& height,
+ const double* source,
+ unsigned int& w,
+ unsigned int& h,
+ double*& dest)
+{
+ /* Single channel. */
+
+ w = 2 * width;
+ h = 2 * height;
+
+ dest = new double[w * h];
+
+ const double* s_itr = source;
+ double* itr1 = dest;
+ double* itr2 = dest + w;
+
+ for (unsigned int j = 0; j < height; ++j)
+ {
+ for (unsigned int i = 0; i < width; ++i, ++s_itr)
+ {
+ *(itr1++) = (*s_itr);
+ *(itr1++) = (*s_itr);
+ *(itr2++) = (*s_itr);
+ *(itr2++) = (*s_itr);
+ }
+
+ itr1 += w;
+ itr2 += w;
+ }
+}
+
+inline void checkered_pattern(const unsigned int x_width,
+ const unsigned int y_width,
+ const unsigned char value,
+ const bitmap_image::color_plane color,
+ bitmap_image& image)
+{
+ if (
+ (x_width >= image.width()) ||
+ (y_width >= image.height())
+ )
+ {
+ return;
+ }
+
+ bool setter_x = false;
+ bool setter_y = true;
+
+ const unsigned int color_plane_offset = image.offset(color);
+ const unsigned int height = image.height();
+ const unsigned int width = image.width();
+
+ for (unsigned int y = 0; y < height; ++y)
+ {
+ if (0 == (y % y_width))
+ {
+ setter_y = !setter_y;
+ }
+
+ unsigned char* row = image.row(y) + color_plane_offset;
+
+ for (unsigned int x = 0; x < width; ++x, row += image.bytes_per_pixel())
+ {
+ if (0 == (x % x_width))
+ {
+ setter_x = !setter_x;
+ }
+
+ if (setter_x ^ setter_y)
+ {
+ *row = value;
+ }
+ }
+ }
+}
+
+inline void checkered_pattern(const unsigned int x_width,
+ const unsigned int y_width,
+ const unsigned char red,
+ const unsigned char green,
+ const unsigned char blue,
+ bitmap_image& image)
+{
+ if (
+ (x_width >= image.width()) ||
+ (y_width >= image.height())
+ )
+ {
+ return;
+ }
+
+ bool setter_x = false;
+ bool setter_y = true;
+
+ const unsigned int height = image.height();
+ const unsigned int width = image.width();
+
+ for (unsigned int y = 0; y < height; ++y)
+ {
+ if (0 == (y % y_width))
+ {
+ setter_y = !setter_y;
+ }
+
+ unsigned char* row = image.row(y);
+
+ for (unsigned int x = 0; x < width; ++x, row += image.bytes_per_pixel())
+ {
+ if (0 == (x % x_width))
+ {
+ setter_x = !setter_x;
+ }
+
+ if (setter_x ^ setter_y)
+ {
+ *(row + 0) = blue;
+ *(row + 1) = green;
+ *(row + 2) = red;
+ }
+ }
+ }
+}
+
+inline void plasma(bitmap_image& image,
+ const double& x, const double& y,
+ const double& width, const double& height,
+ const double& c1, const double& c2,
+ const double& c3, const double& c4,
+ const double& roughness = 3.0,
+ const rgb_t colormap[] = 0)
+{
+ // Note: c1,c2,c3,c4 -> [0.0,1.0]
+
+ const double half_width = (width / 2.0);
+ const double half_height = (height / 2.0);
+
+ if ((width >= 1.0) || (height >= 1.0))
+ {
+ const double corner1 = (c1 + c2) / 2.0;
+ const double corner2 = (c2 + c3) / 2.0;
+ const double corner3 = (c3 + c4) / 2.0;
+ const double corner4 = (c4 + c1) / 2.0;
+ double center = (c1 + c2 + c3 + c4) / 4.0 +
+ ((1.0 * ::rand() / (1.0 * RAND_MAX)) - 0.5) * // should use a better rng
+ ((1.0 * half_width + half_height) / (image.width() + image.height()) * roughness);
+
+ center = std::min<double>(std::max<double>(0.0, center), 1.0);
+
+ plasma(image, x, y, half_width, half_height, c1, corner1, center, corner4, roughness, colormap);
+ plasma(image, x + half_width, y, half_width, half_height, corner1, c2, corner2, center, roughness, colormap);
+ plasma(image, x + half_width, y + half_height, half_width, half_height, center, corner2, c3, corner3, roughness, colormap);
+ plasma(image, x, y + half_height, half_width, half_height, corner4, center, corner3, c4, roughness, colormap);
+ }
+ else
+ {
+ rgb_t color = colormap[static_cast<unsigned int>(1000.0 * ((c1 + c2 + c3 + c4) / 4.0)) % 1000];
+
+ image.set_pixel(static_cast<unsigned int>(x), static_cast<unsigned int>(y), color);
+ }
+}
+
+inline void plasma(bitmap_image& image,
+ const double& c1, const double& c2,
+ const double& c3, const double& c4,
+ const double& roughness = 3.0,
+ const rgb_t colormap[] = 0)
+{
+ plasma
+ (
+ image, 0, 0, image.width(), image.height(),
+ c1, c2, c3, c4,
+ roughness, colormap
+ );
+}
+
+inline double psnr_region(const unsigned int& x, const unsigned int& y,
+ const unsigned int& width, const unsigned int& height,
+ const bitmap_image& image1, const bitmap_image& image2)
+{
+ if (
+ (image1.width() != image2.width()) ||
+ (image1.height() != image2.height())
+ )
+ {
+ return 0.0;
+ }
+
+ if ((x + width) > image1.width()) { return 0.0; }
+ if ((y + height) > image1.height()) { return 0.0; }
+
+ double mse = 0.0;
+
+ for (unsigned int r = 0; r < height; ++r)
+ {
+ const unsigned char* itr1 = image1.row(r + y) + x * image1.bytes_per_pixel();
+ const unsigned char* itr1_end = itr1 + (width * image1.bytes_per_pixel());
+ const unsigned char* itr2 = image2.row(r + y) + x * image2.bytes_per_pixel();
+
+ while (itr1 != itr1_end)
+ {
+ double v = (static_cast<double>(*itr1) - static_cast<double>(*itr2));
+ mse += v * v;
+ ++itr1;
+ ++itr2;
+ }
+ }
+
+ if (mse <= 0.0000001)
+ {
+ return 1000000.0;
+ }
+ else
+ {
+ mse /= (3.0 * width * height);
+ return 20.0 * std::log10(255.0 / std::sqrt(mse));
+ }
+}
+
+inline void hierarchical_psnr_r(const double& x, const double& y,
+ const double& width, const double& height,
+ const bitmap_image& image1,
+ bitmap_image& image2,
+ const double& threshold,
+ const rgb_t colormap[])
+{
+ if ((width <= 4.0) || (height <= 4.0))
+ {
+ const double psnr = psnr_region
+ (
+ static_cast<unsigned int>(x),
+ static_cast<unsigned int>(y),
+ static_cast<unsigned int>(width),
+ static_cast<unsigned int>(height),
+ image1, image2
+ );
+
+ if (psnr < threshold)
+ {
+ rgb_t c = colormap[static_cast<unsigned int>(1000.0 * (1.0 - (psnr / threshold)))];
+
+ image2.set_region
+ (
+ static_cast<unsigned int>(x),
+ static_cast<unsigned int>(y),
+ static_cast<unsigned int>(width + 1),
+ static_cast<unsigned int>(height + 1),
+ c.red, c.green, c.blue
+ );
+ }
+ }
+ else
+ {
+ const double half_width = (width / 2.0);
+ const double half_height = (height / 2.0);
+
+ hierarchical_psnr_r(x, y, half_width, half_height, image1, image2, threshold, colormap);
+ hierarchical_psnr_r(x + half_width, y, half_width, half_height, image1, image2, threshold, colormap);
+ hierarchical_psnr_r(x + half_width, y + half_height, half_width, half_height, image1, image2, threshold, colormap);
+ hierarchical_psnr_r(x, y + half_height, half_width, half_height, image1, image2, threshold, colormap);
+ }
+}
+
+inline void hierarchical_psnr(bitmap_image& image1, bitmap_image& image2, const double threshold, const rgb_t colormap[])
+{
+ if (
+ (image1.width() != image2.width()) ||
+ (image1.height() != image2.height())
+ )
+ {
+ return;
+ }
+
+ const double psnr = psnr_region
+ (
+ 0, 0, image1.width(), image1.height(),
+ image1, image2
+ );
+
+ if (psnr < threshold)
+ {
+ hierarchical_psnr_r
+ (
+ 0, 0, image1.width(), image1.height(),
+ image1, image2,
+ threshold,
+ colormap
+ );
+ }
+}
+
+class image_drawer
+{
+public:
+
+ image_drawer(bitmap_image& image)
+ : image_(image),
+ pen_width_(1),
+ pen_color_red_(0),
+ pen_color_green_(0),
+ pen_color_blue_(0)
+ {}
+
+ void rectangle(int x1, int y1, int x2, int y2)
+ {
+ line_segment(x1, y1, x2, y1);
+ line_segment(x2, y1, x2, y2);
+ line_segment(x2, y2, x1, y2);
+ line_segment(x1, y2, x1, y1);
+ }
+
+ void triangle(int x1, int y1, int x2, int y2, int x3, int y3)
+ {
+ line_segment(x1, y1, x2, y2);
+ line_segment(x2, y2, x3, y3);
+ line_segment(x3, y3, x1, y1);
+ }
+
+ void quadix(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
+ {
+ line_segment(x1, y1, x2, y2);
+ line_segment(x2, y2, x3, y3);
+ line_segment(x3, y3, x4, y4);
+ line_segment(x4, y4, x1, y1);
+ }
+
+ void line_segment(int x1, int y1, int x2, int y2)
+ {
+ int steep = 0;
+ int sx = ((x2 - x1) > 0) ? 1 : -1;
+ int sy = ((y2 - y1) > 0) ? 1 : -1;
+ int dx = abs(x2 - x1);
+ int dy = abs(y2 - y1);
+
+ if (dy > dx)
+ {
+ std::swap(x1, y1);
+ std::swap(dx, dy);
+ std::swap(sx, sy);
+
+ steep = 1;
+ }
+
+ int e = 2 * dy - dx;
+
+ for (int i = 0; i < dx; ++i)
+ {
+ if (steep)
+ plot_pen_pixel(y1, x1);
+ else
+ plot_pen_pixel(x1, y1);
+
+ while (e >= 0)
+ {
+ y1 += sy;
+ e -= (dx << 1);
+ }
+
+ x1 += sx;
+ e += (dy << 1);
+ }
+
+ plot_pen_pixel(x2, y2);
+ }
+
+ void horiztonal_line_segment(int x1, int x2, int y)
+ {
+ if (x1 > x2)
+ {
+ std::swap(x1, x2);
+ }
+
+ for (int i = 0; i < (x2 - x1); ++i)
+ {
+ plot_pen_pixel(x1 + i, y);
+ }
+ }
+
+ void vertical_line_segment(int y1, int y2, int x)
+ {
+ if (y1 > y2)
+ {
+ std::swap(y1, y2);
+ }
+
+ for (int i = 0; i < (y2 - y1); ++i)
+ {
+ plot_pen_pixel(x, y1 + i);
+ }
+ }
+
+ void ellipse(int centerx, int centery, int a, int b)
+ {
+ int t1 = a * a;
+ int t2 = t1 << 1;
+ int t3 = t2 << 1;
+ int t4 = b * b;
+ int t5 = t4 << 1;
+ int t6 = t5 << 1;
+ int t7 = a * t5;
+ int t8 = t7 << 1;
+ int t9 = 0;
+
+ int d1 = t2 - t7 + (t4 >> 1);
+ int d2 = (t1 >> 1) - t8 + t5;
+ int x = a;
+ int y = 0;
+
+ int negative_tx = centerx - x;
+ int positive_tx = centerx + x;
+ int negative_ty = centery - y;
+ int positive_ty = centery + y;
+
+ while (d2 < 0)
+ {
+ plot_pen_pixel(positive_tx, positive_ty);
+ plot_pen_pixel(positive_tx, negative_ty);
+ plot_pen_pixel(negative_tx, positive_ty);
+ plot_pen_pixel(negative_tx, negative_ty);
+
+ ++y;
+
+ t9 = t9 + t3;
+
+ if (d1 < 0)
+ {
+ d1 = d1 + t9 + t2;
+ d2 = d2 + t9;
+ }
+ else
+ {
+ x--;
+ t8 = t8 - t6;
+ d1 = d1 + (t9 + t2 - t8);
+ d2 = d2 + (t9 + t5 - t8);
+ negative_tx = centerx - x;
+ positive_tx = centerx + x;
+ }
+
+ negative_ty = centery - y;
+ positive_ty = centery + y;
+ }
+
+ do
+ {
+ plot_pen_pixel(positive_tx, positive_ty);
+ plot_pen_pixel(positive_tx, negative_ty);
+ plot_pen_pixel(negative_tx, positive_ty);
+ plot_pen_pixel(negative_tx, negative_ty);
+
+ x--;
+ t8 = t8 - t6;
+
+ if (d2 < 0)
+ {
+ ++y;
+ t9 = t9 + t3;
+ d2 = d2 + (t9 + t5 - t8);
+ negative_ty = centery - y;
+ positive_ty = centery + y;
+ }
+ else
+ d2 = d2 + (t5 - t8);
+
+ negative_tx = centerx - x;
+ positive_tx = centerx + x;
+ } while (x >= 0);
+ }
+
+ void circle(int centerx, int centery, int radius)
+ {
+ int x = 0;
+ int d = (1 - radius) << 1;
+
+ while (radius >= 0)
+ {
+ plot_pen_pixel(centerx + x, centery + radius);
+ plot_pen_pixel(centerx + x, centery - radius);
+ plot_pen_pixel(centerx - x, centery + radius);
+ plot_pen_pixel(centerx - x, centery - radius);
+
+ if ((d + radius) > 0)
+ d -= ((--radius) << 1) - 1;
+ if (x > d)
+ d += ((++x) << 1) + 1;
+ }
+ }
+
+ void plot_pen_pixel(int x, int y)
+ {
+ switch (pen_width_)
+ {
+ case 1: plot_pixel(x, y);
+ break;
+
+ case 2: {
+ plot_pixel(x, y);
+ plot_pixel(x + 1, y);
+ plot_pixel(x + 1, y + 1);
+ plot_pixel(x, y + 1);
+ }
+ break;
+
+ case 3: {
+ plot_pixel(x, y - 1);
+ plot_pixel(x - 1, y - 1);
+ plot_pixel(x + 1, y - 1);
+
+ plot_pixel(x, y);
+ plot_pixel(x - 1, y);
+ plot_pixel(x + 1, y);
+
+ plot_pixel(x, y + 1);
+ plot_pixel(x - 1, y + 1);
+ plot_pixel(x + 1, y + 1);
+ }
+ break;
+
+ default: plot_pixel(x, y);
+ break;
+ }
+ }
+
+ void plot_pixel(int x, int y)
+ {
+ if (
+ (x < 0) ||
+ (y < 0) ||
+ (x >= static_cast<int>(image_.width())) ||
+ (y >= static_cast<int>(image_.height()))
+ )
+ return;
+
+ image_.set_pixel(x, y, pen_color_red_, pen_color_green_, pen_color_blue_);
+ }
+
+ void pen_width(const unsigned int& width)
+ {
+ if ((width > 0) && (width < 4))
+ {
+ pen_width_ = width;
+ }
+ }
+
+ void pen_color(const unsigned char& red,
+ const unsigned char& green,
+ const unsigned char& blue)
+ {
+ pen_color_red_ = red;
+ pen_color_green_ = green;
+ pen_color_blue_ = blue;
+ }
+
+ template <typename RGB>
+ void pen_color(const RGB colour)
+ {
+ pen_color_red_ = colour.red;
+ pen_color_green_ = colour.green;
+ pen_color_blue_ = colour.blue;
+ }
+
+private:
+
+ image_drawer(const image_drawer& id);
+ image_drawer& operator =(const image_drawer& id);
+
+ bitmap_image& image_;
+ unsigned int pen_width_;
+ unsigned char pen_color_red_;
+ unsigned char pen_color_green_;
+ unsigned char pen_color_blue_;
+};
+
+class cartesian_canvas
+{
+public:
+
+ cartesian_canvas(const double x_length, const double y_length)
+ : width_div2_(0.0),
+ height_div2_(0.0),
+ min_x_(0.0),
+ min_y_(0.0),
+ max_x_(0.0),
+ max_y_(0.0),
+ draw_(image_)
+ {
+ setup_canvas(x_length, y_length);
+ }
+
+ inline bool operator!()
+ {
+ return !image_;
+ }
+
+ void rectangle(double x1, double y1, double x2, double y2)
+ {
+ line_segment(x1, y1, x2, y1);
+ line_segment(x2, y1, x2, y2);
+ line_segment(x2, y2, x1, y2);
+ line_segment(x1, y2, x1, y1);
+ }
+
+ void triangle(double x1, double y1, double x2, double y2, double x3, double y3)
+ {
+ line_segment(x1, y1, x2, y2);
+ line_segment(x2, y2, x3, y3);
+ line_segment(x3, y3, x1, y1);
+ }
+
+ void quadix(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
+ {
+ line_segment(x1, y1, x2, y2);
+ line_segment(x2, y2, x3, y3);
+ line_segment(x3, y3, x4, y4);
+ line_segment(x4, y4, x1, y1);
+ }
+
+ void line_segment(double x1, double y1, double x2, double y2)
+ {
+ if (clip(x1, y1, x2, y2))
+ {
+ const int sc_x1 = static_cast<int>(cart_to_screen_x(x1));
+ const int sc_x2 = static_cast<int>(cart_to_screen_x(x2));
+ const int sc_y1 = static_cast<int>(cart_to_screen_y(y1));
+ const int sc_y2 = static_cast<int>(cart_to_screen_y(y2));
+
+ draw_.line_segment(sc_x1, sc_y1, sc_x2, sc_y2);
+ }
+ }
+
+ void horiztonal_line_segment(double x1, double x2, double y)
+ {
+ x1 = clamp_x(x1);
+ x2 = clamp_x(x2);
+ y = clamp_y(y);
+
+ const int sc_x1 = static_cast<int>(cart_to_screen_x(x1));
+ const int sc_x2 = static_cast<int>(cart_to_screen_x(x2));
+ const int sc_y = static_cast<int>(cart_to_screen_y(y));
+
+ draw_.horiztonal_line_segment(sc_x1, sc_x2, sc_y);
+ }
+
+ void vertical_line_segment(double y1, double y2, double x)
+ {
+ y1 = clamp_y(y1);
+ y2 = clamp_y(y2);
+ x = clamp_x(x);
+
+ const int sc_y1 = static_cast<int>(cart_to_screen_y(y1));
+ const int sc_y2 = static_cast<int>(cart_to_screen_y(y2));
+ const int sc_x = static_cast<int>(cart_to_screen_x(x));
+
+ draw_.vertical_line_segment(sc_y1, sc_y2, sc_x);
+ }
+
+ void ellipse(double centerx, double centery, double a, double b)
+ {
+
+ const int sc_cx = static_cast<int>(cart_to_screen_x(centerx));
+ const int sc_cy = static_cast<int>(cart_to_screen_y(centery));
+
+ draw_.ellipse(sc_cx, sc_cy, static_cast<int>(a), static_cast<int>(b));
+ }
+
+ void circle(double centerx, double centery, double radius)
+ {
+ const int sc_cx = static_cast<int>(cart_to_screen_x(centerx));
+ const int sc_cy = static_cast<int>(cart_to_screen_y(centery));
+
+ draw_.circle(sc_cx, sc_cy, static_cast<int>(radius));
+ }
+
+ void fill_rectangle(double x1, double y1, double x2, double y2)
+ {
+ if (y1 > y2)
+ std::swap(y1, y2);
+
+ for (double y = y1; y <= y2; y += 0.5)
+ {
+ line_segment(x1, y, x2, y);
+ }
+ }
+
+ void fill_triangle(double x1, double y1, double x2, double y2, double x3, double y3)
+ {
+ typedef std::pair<double, double> point_t;
+
+ std::vector<point_t> p;
+
+ p.push_back(std::make_pair(x1, y1));
+ p.push_back(std::make_pair(x2, y2));
+ p.push_back(std::make_pair(x3, y3));
+
+ if (p[0].second > p[1].second)
+ std::swap(p[0], p[1]);
+ if (p[0].second > p[2].second)
+ std::swap(p[0], p[2]);
+ if (p[1].second > p[2].second)
+ std::swap(p[1], p[2]);
+
+ class draw_modes
+ {
+ private:
+
+ cartesian_canvas& canvas;
+
+ // Needed for incompetent and broken msvc compiler versions
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4822)
+#endif
+ draw_modes& operator=(const draw_modes&);
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+ public:
+
+ draw_modes(cartesian_canvas& c)
+ : canvas(c)
+ {}
+
+ void bottom(const point_t& p0, const point_t& p1, const point_t& p2)
+ {
+ const double m0 = (p1.first - p0.first) / (2.0 * (p1.second - p0.second));
+ const double m1 = (p2.first - p0.first) / (2.0 * (p2.second - p0.second));
+
+ double x0 = p0.first;
+ double x1 = p0.first;
+
+ for (double y = p0.second; y <= p1.second; y += 0.5)
+ {
+ canvas.horiztonal_line_segment(x0, x1, y);
+
+ x0 += m0;
+ x1 += m1;
+ }
+ }
+
+ void top(const point_t& p0, const point_t& p1, const point_t& p2)
+ {
+ const double m0 = (p2.first - p0.first) / (2.0 * (p2.second - p0.second));
+ const double m1 = (p2.first - p1.first) / (2.0 * (p2.second - p1.second));
+
+ double x0 = p2.first;
+ double x1 = p2.first;
+
+ for (double y = p2.second; y >= p0.second; y -= 0.5)
+ {
+ canvas.horiztonal_line_segment(x0, x1, y);
+
+ x0 -= m0;
+ x1 -= m1;
+ }
+ }
+ };
+
+ draw_modes dm(*this);
+
+ const double eps = 0.00001;
+
+ if (std::abs(p[1].second - p[2].second) < eps)
+ dm.bottom(p[0], p[1], p[2]);
+ else if (std::abs(p[0].second - p[1].second) < eps)
+ dm.top(p[0], p[1], p[2]);
+ else
+ {
+ point_t p3;
+
+ p3.first = (p[0].first + ((p[1].second - p[0].second) / (p[2].second - p[0].second)) * (p[2].first - p[0].first));
+ p3.second = p[1].second;
+
+ dm.bottom(p[0], p[1], p3);
+ dm.top(p[1], p3, p[2]);
+ }
+ }
+
+ void fill_quadix(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
+ {
+ fill_triangle(x1, y1, x2, y2, x3, y3);
+ fill_triangle(x1, y1, x3, y3, x4, y4);
+ }
+
+ void fill_circle(double cx, double cy, double radius)
+ {
+ const double delta = 1.0;
+ double x = radius;
+ double y = 0.0;
+ double dx = delta - (2.0 * delta * radius);
+ double dy = 0.0;
+ double dr = 0.0;
+
+ while (x >= y)
+ {
+ for (double i = cx - x; i <= cx + x; i += delta)
+ {
+ horiztonal_line_segment(cx - x, cx + x, cy + y);
+ horiztonal_line_segment(cx - x, cx + x, cy - y);
+ }
+
+ for (double i = cx - y; i <= cx + y; i += delta)
+ {
+ horiztonal_line_segment(cx - y, cx + y, cy + x);
+ horiztonal_line_segment(cx - y, cx + y, cy - x);
+ }
+
+ y += delta;
+
+ dr += dy;
+ dy += 2.0 * delta;
+
+ if ((2.0 * delta * dr + dx) > 0)
+ {
+ x -= delta;
+ dr += dx;
+ dx += 2.0 * delta;
+ }
+ }
+ }
+
+ void plot_pen_pixel(double x, double y)
+ {
+ if ((x < min_x_) || (x > max_x_)) return;
+ if ((y < min_y_) || (y > max_y_)) return;
+
+ const int sc_x = static_cast<int>(cart_to_screen_x(x));
+ const int sc_y = static_cast<int>(cart_to_screen_y(y));
+
+ draw_.plot_pen_pixel(sc_x, sc_y);
+ }
+
+ void plot_pixel(double x, double y)
+ {
+ if ((x < min_x_) || (x > max_x_)) return;
+ if ((y < min_y_) || (y > max_y_)) return;
+
+ const int sc_x = static_cast<int>(cart_to_screen_x(x));
+ const int sc_y = static_cast<int>(cart_to_screen_y(y));
+
+ draw_.plot_pixel(sc_x, sc_y);
+ }
+
+ void pen_width(const unsigned int& width)
+ {
+ draw_.pen_width(width);
+ }
+
+ void pen_color(const unsigned char& red,
+ const unsigned char& green,
+ const unsigned char& blue)
+ {
+ draw_.pen_color(red, green, blue);
+ }
+
+ template <typename RGB>
+ void pen_color(const RGB colour)
+ {
+ draw_.pen_color(colour);
+ }
+
+ const bitmap_image& image() const
+ {
+ return image_;
+ }
+
+ bitmap_image& image()
+ {
+ return image_;
+ }
+
+ void set_widthheight(const double x_length, const double y_length)
+ {
+ setup_canvas(x_length, y_length);
+ }
+
+ double min_x() const { return min_x_; }
+ double min_y() const { return min_y_; }
+ double max_x() const { return max_x_; }
+ double max_y() const { return max_y_; }
+
+private:
+
+ void setup_canvas(const double x_length, const double y_length)
+ {
+ if ((x_length < 2.0) || (y_length < 2.0))
+ return;
+
+ width_div2_ = x_length / 2.0;
+ height_div2_ = y_length / 2.0;
+
+ min_x_ = -width_div2_;
+ min_y_ = -height_div2_;
+ max_x_ = width_div2_;
+ max_y_ = height_div2_;
+
+ image_.setwidth_height(static_cast<unsigned int>(x_length) + 1, static_cast<unsigned int>(y_length) + 1);
+
+ image_.clear(0xFF);
+ }
+
+ double clamp_x(const double& x)
+ {
+ if (x < min_x_) return min_x_;
+ else if (x > max_x_) return max_x_;
+ else return x;
+ }
+
+ double clamp_y(const double& y)
+ {
+ if (y < min_y_) return min_y_;
+ else if (y > max_y_) return max_y_;
+ else return y;
+ }
+
+ double cart_to_screen_x(const double& x)
+ {
+ return x + width_div2_;
+ }
+
+ double cart_to_screen_y(const double& y)
+ {
+ return height_div2_ - y;
+ }
+
+ enum clip_code
+ {
+ e_clip_bottom = 1,
+ e_clip_top = 2,
+ e_clip_left = 4,
+ e_clip_right = 8
+ };
+
+ int out_code(
+ const double& x, const double& y,
+ const double& x1, const double& y1,
+ const double& x2, const double& y2
+ )
+ {
+ int result = 0;
+ if (y < y1) result |= e_clip_bottom;
+ else if (y > y2) result |= e_clip_top;
+
+ if (x < x1) result |= e_clip_left;
+ else if (x > x2) result |= e_clip_right;
+
+ return result;
+ }
+
+ bool clip(double& x1, double& y1, double& x2, double& y2)
+ {
+ bool result = false;
+ double x = 0.0;
+ double y = 0.0;
+
+ int outcode0 = out_code(x1, y1, min_x_, min_y_, max_x_, max_y_);
+ int outcode1 = out_code(x2, y2, min_x_, min_y_, max_x_, max_y_);
+ int outcodeout = 0;
+
+ while ((outcode0 != 0) || (outcode1 != 0))
+ {
+ if ((outcode0 & outcode1) != 0)
+ return result;
+ else
+ {
+ if (outcode0 != 0)
+ outcodeout = outcode0;
+ else
+ outcodeout = outcode1;
+
+ double dx = (x2 - x1);
+ double dy = (y2 - y1);
+
+ if ((outcodeout & e_clip_bottom) == e_clip_bottom)
+ {
+ x = x1 + dx * (min_y_ - y1) / dy;
+ y = min_y_;
+ }
+ else if ((outcodeout & e_clip_top) == e_clip_top)
+ {
+ x = x1 + dx * (max_y_ - y1) / dy;
+ y = max_y_;
+ }
+ else if ((outcodeout & e_clip_right) == e_clip_right)
+ {
+ y = y1 + dy * (max_x_ - x1) / dx;
+ x = max_x_;
+ }
+ else if ((outcodeout & e_clip_left) == e_clip_left)
+ {
+ y = y1 + dy * (min_x_ - x1) / dx;
+ x = min_x_;
+ }
+
+ if (outcodeout == outcode0)
+ {
+ x1 = x;
+ y1 = y;
+ outcode0 = out_code(x1, y1, min_x_, min_y_, max_x_, max_y_);
+ }
+ else
+ {
+ x2 = x;
+ y2 = y;
+ outcode1 = out_code(x2, y2, min_x_, min_y_, max_x_, max_y_);
+ }
+ }
+ }
+
+ return true;
+ }
+
+ cartesian_canvas(const cartesian_canvas&);
+ cartesian_canvas operator=(const cartesian_canvas&);
+
+ double width_div2_;
+ double height_div2_;
+ double min_x_;
+ double min_y_;
+ double max_x_;
+ double max_y_;
+ bitmap_image image_;
+ image_drawer draw_;
+};
+
+inline rgb_t convert_wave_length_nm_to_rgb(const double wave_length_nm)
+{
+ // Credits: Dan Bruton http://www.physics.sfasu.edu/astro/color.html
+ double red = 0.0;
+ double green = 0.0;
+ double blue = 0.0;
+
+ if ((380.0 <= wave_length_nm) && (wave_length_nm <= 439.0))
+ {
+ red = -(wave_length_nm - 440.0) / (440.0 - 380.0);
+ green = 0.0;
+ blue = 1.0;
+ }
+ else if ((440.0 <= wave_length_nm) && (wave_length_nm <= 489.0))
+ {
+ red = 0.0;
+ green = (wave_length_nm - 440.0) / (490.0 - 440.0);
+ blue = 1.0;
+ }
+ else if ((490.0 <= wave_length_nm) && (wave_length_nm <= 509.0))
+ {
+ red = 0.0;
+ green = 1.0;
+ blue = -(wave_length_nm - 510.0) / (510.0 - 490.0);
+ }
+ else if ((510.0 <= wave_length_nm) && (wave_length_nm <= 579.0))
+ {
+ red = (wave_length_nm - 510.0) / (580.0 - 510.0);
+ green = 1.0;
+ blue = 0.0;
+ }
+ else if ((580.0 <= wave_length_nm) && (wave_length_nm <= 644.0))
+ {
+ red = 1.0;
+ green = -(wave_length_nm - 645.0) / (645.0 - 580.0);
+ blue = 0.0;
+ }
+ else if ((645.0 <= wave_length_nm) && (wave_length_nm <= 780.0))
+ {
+ red = 1.0;
+ green = 0.0;
+ blue = 0.0;
+ }
+
+ double factor = 0.0;
+
+ if ((380.0 <= wave_length_nm) && (wave_length_nm <= 419.0))
+ factor = 0.3 + 0.7 * (wave_length_nm - 380.0) / (420.0 - 380.0);
+ else if ((420.0 <= wave_length_nm) && (wave_length_nm <= 700.0))
+ factor = 1.0;
+ else if ((701.0 <= wave_length_nm) && (wave_length_nm <= 780.0))
+ factor = 0.3 + 0.7 * (780.0 - wave_length_nm) / (780.0 - 700.0);
+ else
+ factor = 0.0;
+
+ rgb_t result;
+
+ const double gamma = 0.8;
+ const double intensity_max = 255.0;
+
+#define round(d) std::floor(d + 0.5)
+
+ result.red = static_cast<unsigned char>((red == 0.0) ? red : round(intensity_max * std::pow(red * factor, gamma)));
+ result.green = static_cast<unsigned char>((green == 0.0) ? green : round(intensity_max * std::pow(green * factor, gamma)));
+ result.blue = static_cast<unsigned char>((blue == 0.0) ? blue : round(intensity_max * std::pow(blue * factor, gamma)));
+
+#undef round
+
+ return result;
+}
+
+inline double weighted_distance(const unsigned char r0, const unsigned char g0, const unsigned char b0,
+ const unsigned char r1, const unsigned char g1, const unsigned char b1)
+{
+ const double diff_r = /*0.30 */ (r0 - r1);
+ const double diff_g = /*0.59 */ (g0 - g1);
+ const double diff_b = /*0.11 */ (b0 - b1);
+
+ return std::sqrt((diff_r * diff_r) + (diff_g * diff_g) + (diff_b * diff_b));
+}
+
+inline double weighted_distance(const rgb_t c0, const rgb_t c1)
+{
+ return weighted_distance(c0.red, c0.green, c0.blue,
+ c1.red, c1.green, c1.blue);
+}
+
+template <typename Iterator>
+inline rgb_t find_nearest_color(const rgb_t& c, const Iterator begin, const Iterator end)
+{
+ if (0 == std::distance(begin, end))
+ return c;
+
+ double min_d = std::numeric_limits<double>::max();
+ rgb_t result = *begin;
+
+ for (Iterator itr = begin; itr != end; ++itr)
+ {
+ if (c == (*itr))
+ {
+ return (*itr);
+ }
+
+ double curr_d = weighted_distance(c, *itr);
+
+ if (curr_d < min_d)
+ {
+ min_d = curr_d;
+ result = *itr;
+ }
+ }
+
+ return result;
+}
+
+template <template <typename, typename> class Sequence,
+ typename Allocator>
+ inline rgb_t find_nearest_color(const rgb_t& c, const Sequence<rgb_t, Allocator>& seq)
+{
+ return find_nearest_color(c, seq.begin(), seq.end());
+}
+
+template <std::size_t N>
+inline rgb_t find_nearest_color(const rgb_t& c, const rgb_t(&colors)[N])
+{
+ return find_nearest_color(c, colors, colors + N);
+}
+
+inline double find_nearest_wave_length(const rgb_t& c, const double increment = 0.001)
+{
+ const double max_wave_length = 800.0; //800nm
+
+ double min_wave_length = 0.0;
+ double min_d = std::numeric_limits<double>::max();
+
+ for (double i = 0.0; i < max_wave_length; i += increment)
+ {
+ const rgb_t curr_rgb = convert_wave_length_nm_to_rgb(i);
+
+ if (c == curr_rgb)
+ {
+ return i;
+ }
+
+ const double curr_d = weighted_distance(c, curr_rgb);
+
+ if (curr_d <= min_d)
+ {
+ min_wave_length = i;
+ min_d = curr_d;
+ }
+ }
+
+ return min_wave_length;
+}
+
+template <typename T>
+class response_image
+{
+public:
+
+ response_image(const std::size_t& width, const std::size_t& height, const T null = T(0))
+ : width_(width),
+ height_(height),
+ null_(null)
+ {
+ data_.resize(width_ * height_);
+ }
+
+ std::size_t width() const { return width_; }
+ std::size_t height() const { return height_; }
+
+ void set_all(const T& t)
+ {
+ std::fill_n(data_.begin(), data_.size(), t);
+ }
+
+ const T& operator()(const std::size_t& x, const std::size_t& y) const
+ {
+ if (y >= height_) return null_;
+ if (x >= width_) return null_;
+
+ return data_[width_ * y + x];
+ }
+
+ T& operator()(const std::size_t& x, const std::size_t& y)
+ {
+ if (y >= height_) return null_;
+ if (x >= width_) return null_;
+
+ return data_[width_ * y + x];
+ }
+
+ bool valid(const std::size_t& x, const std::size_t& y)
+ {
+ return ((x < width_) || (y < height_));
+ }
+
+ void inc_all(const T& v)
+ {
+ for (std::size_t i = 0; i < data_.size(); ++i)
+ {
+ data_[i] += v;
+ }
+ }
+
+ void mul_all(const T& v)
+ {
+ for (std::size_t i = 0; i < data_.size(); ++i)
+ {
+ data_[i] *= v;
+ }
+ }
+
+ T* row(const std::size_t& row_index)
+ {
+ if (row_index < height_)
+ return &data_[width_ * row_index];
+ else
+ return reinterpret_cast<T*>(0);
+ }
+
+ const T* row(const std::size_t& row_index) const
+ {
+ if (row_index < height_)
+ return data_[width_ * row_index];
+ else
+ return reinterpret_cast<T*>(0);
+ }
+
+private:
+
+ std::size_t width_;
+ std::size_t height_;
+ std::vector<T> data_;
+ T null_;
+};
+
+inline void sobel_operator(const bitmap_image& src_image,
+ bitmap_image& dst_image,
+ const double threshold = 0.0)
+{
+ typedef double T;
+
+ response_image<T> im0(src_image.width(), src_image.height(), 0.0);
+ response_image<T> im1(src_image.width(), src_image.height(), 0.0);
+
+ src_image.export_gray_scale_response_image(&im0(0, 0));
+
+ for (std::size_t y = 1; y < im0.height() - 1; ++y)
+ {
+ const T* itr0 = im0.row(y - 1);
+ const T* itr1 = im0.row(y);
+ const T* itr2 = im0.row(y + 1);
+ T* out = im1.row(y) + 1;
+
+ for (std::size_t x = 1; x < im0.width() - 1; ++x)
+ {
+ const T c0 = *(itr0 + x - 1); const T c1 = *(itr0 + x); const T c2 = *(itr0 + x + 1);
+ const T c3 = *(itr1 + x - 1); /*const T c4 = *(itr1 + x);*/ const T c5 = *(itr1 + x + 1);
+ const T c6 = *(itr2 + x - 1); const T c7 = *(itr2 + x); const T c8 = *(itr2 + x + 1);
+
+ const T gx = (2.0 * (c5 - c3)) + (c2 - c0) + (c8 - c6);
+ const T gy = (2.0 * (c1 - c7)) + (c0 - c6) + (c2 - c8);
+
+ *(out++) = std::sqrt((gx * gx) + (gy * gy));
+ }
+ }
+
+ if (threshold > 0.0)
+ {
+ const T* end = im1.row(0) + (im1.width() * im1.height());
+
+ for (T* itr = im1.row(0); itr != end; ++itr)
+ {
+ T& v = *itr;
+ if (v <= threshold) v = 0;
+ }
+ }
+
+ dst_image.setwidth_height
+ (
+ static_cast<unsigned int>(im1.width()),
+ static_cast<unsigned int>(im1.height())
+ );
+
+ dst_image.import_gray_scale_clamped(&im1(0, 0));
+}
+
+enum palette_name
+{
+ e_red, e_scarlet, e_vermilion, e_tangelo, e_orange,
+ e_gamboge, e_amber, e_gold, e_yellow, e_apple_green,
+ e_lime_green, e_spring_bud, e_chartreuse_green, e_pistachio, e_harlequin,
+ e_sap_green, e_green, e_emerald_green, e_malachite_green, e_sea_green,
+ e_spring_green, e_aquamarine, e_turquoise, e_opal, e_cyan,
+ e_arctic_blue, e_cerulean, e_cornflower_blue, e_azure, e_cobalt_blue,
+ e_sapphire_blue, e_phthalo_blue, e_blue, e_persian_blue, e_indigo,
+ e_blue_violet, e_violet, e_purple, e_mulberry, e_heliotrope,
+ e_magenta, e_orchid, e_fuchsia, e_cerise, e_rose,
+ e_raspberry, e_crimson, e_amaranth, e_white, e_black
+};
+
+const rgb_t palette_colormap[] = {
+ {255, 0, 0}, {255, 31, 0}, {255, 63, 0}, {255, 95, 0}, {255, 127, 0},
+ {255, 159, 0}, {255, 191, 0}, {255, 223, 0}, {255, 255, 0}, {223, 255, 0},
+ {191, 255, 0}, {159, 255, 0}, {127, 255, 0}, { 95, 255, 0}, { 63, 255, 0},
+ { 31, 255, 0}, { 0, 255, 0}, { 0, 255, 31}, { 0, 255, 63}, { 0, 255, 95},
+ { 0, 255, 127}, { 0, 255, 159}, { 0, 255, 191}, { 0, 255, 223}, { 0, 255, 255},
+ { 0, 223, 255}, { 0, 191, 255}, { 0, 159, 255}, { 0, 127, 255}, { 0, 95, 255},
+ { 0, 63, 255}, { 0, 31, 255}, { 0, 0, 255}, { 31, 0, 255}, { 63, 0, 255},
+ { 95, 0, 255}, {127, 0, 255}, {159, 0, 255}, {191, 0, 255}, {223, 0, 255},
+ {255, 0, 255}, {255, 0, 223}, {255, 0, 191}, {255, 0, 159}, {255, 0, 127},
+ {255, 0, 95}, {255, 0, 63}, {255, 0, 31}, {255, 255, 255}, { 0, 0, 0}
+};
+
+const rgb_t autumn_colormap[1000] = {
+ {255, 0, 0}, {255, 0, 0}, {255, 1, 0}, {255, 1, 0}, {255, 1, 0},
+ {255, 1, 0}, {255, 2, 0}, {255, 2, 0}, {255, 2, 0}, {255, 2, 0},
+ {255, 3, 0}, {255, 3, 0}, {255, 3, 0}, {255, 3, 0}, {255, 4, 0},
+ {255, 4, 0}, {255, 4, 0}, {255, 4, 0}, {255, 5, 0}, {255, 5, 0},
+ {255, 5, 0}, {255, 5, 0}, {255, 6, 0}, {255, 6, 0}, {255, 6, 0},
+ {255, 6, 0}, {255, 7, 0}, {255, 7, 0}, {255, 7, 0}, {255, 7, 0},
+ {255, 8, 0}, {255, 8, 0}, {255, 8, 0}, {255, 8, 0}, {255, 9, 0},
+ {255, 9, 0}, {255, 9, 0}, {255, 9, 0}, {255, 10, 0}, {255, 10, 0},
+ {255, 10, 0}, {255, 10, 0}, {255, 11, 0}, {255, 11, 0}, {255, 11, 0},
+ {255, 11, 0}, {255, 12, 0}, {255, 12, 0}, {255, 12, 0}, {255, 13, 0},
+ {255, 13, 0}, {255, 13, 0}, {255, 13, 0}, {255, 14, 0}, {255, 14, 0},
+ {255, 14, 0}, {255, 14, 0}, {255, 15, 0}, {255, 15, 0}, {255, 15, 0},
+ {255, 15, 0}, {255, 16, 0}, {255, 16, 0}, {255, 16, 0}, {255, 16, 0},
+ {255, 17, 0}, {255, 17, 0}, {255, 17, 0}, {255, 17, 0}, {255, 18, 0},
+ {255, 18, 0}, {255, 18, 0}, {255, 18, 0}, {255, 19, 0}, {255, 19, 0},
+ {255, 19, 0}, {255, 19, 0}, {255, 20, 0}, {255, 20, 0}, {255, 20, 0},
+ {255, 20, 0}, {255, 21, 0}, {255, 21, 0}, {255, 21, 0}, {255, 21, 0},
+ {255, 22, 0}, {255, 22, 0}, {255, 22, 0}, {255, 22, 0}, {255, 23, 0},
+ {255, 23, 0}, {255, 23, 0}, {255, 23, 0}, {255, 24, 0}, {255, 24, 0},
+ {255, 24, 0}, {255, 25, 0}, {255, 25, 0}, {255, 25, 0}, {255, 25, 0},
+ {255, 26, 0}, {255, 26, 0}, {255, 26, 0}, {255, 26, 0}, {255, 27, 0},
+ {255, 27, 0}, {255, 27, 0}, {255, 27, 0}, {255, 28, 0}, {255, 28, 0},
+ {255, 28, 0}, {255, 28, 0}, {255, 29, 0}, {255, 29, 0}, {255, 29, 0},
+ {255, 29, 0}, {255, 30, 0}, {255, 30, 0}, {255, 30, 0}, {255, 30, 0},
+ {255, 31, 0}, {255, 31, 0}, {255, 31, 0}, {255, 31, 0}, {255, 32, 0},
+ {255, 32, 0}, {255, 32, 0}, {255, 32, 0}, {255, 33, 0}, {255, 33, 0},
+ {255, 33, 0}, {255, 33, 0}, {255, 34, 0}, {255, 34, 0}, {255, 34, 0},
+ {255, 34, 0}, {255, 35, 0}, {255, 35, 0}, {255, 35, 0}, {255, 35, 0},
+ {255, 36, 0}, {255, 36, 0}, {255, 36, 0}, {255, 37, 0}, {255, 37, 0},
+ {255, 37, 0}, {255, 37, 0}, {255, 38, 0}, {255, 38, 0}, {255, 38, 0},
+ {255, 38, 0}, {255, 39, 0}, {255, 39, 0}, {255, 39, 0}, {255, 39, 0},
+ {255, 40, 0}, {255, 40, 0}, {255, 40, 0}, {255, 40, 0}, {255, 41, 0},
+ {255, 41, 0}, {255, 41, 0}, {255, 41, 0}, {255, 42, 0}, {255, 42, 0},
+ {255, 42, 0}, {255, 42, 0}, {255, 43, 0}, {255, 43, 0}, {255, 43, 0},
+ {255, 43, 0}, {255, 44, 0}, {255, 44, 0}, {255, 44, 0}, {255, 44, 0},
+ {255, 45, 0}, {255, 45, 0}, {255, 45, 0}, {255, 45, 0}, {255, 46, 0},
+ {255, 46, 0}, {255, 46, 0}, {255, 46, 0}, {255, 47, 0}, {255, 47, 0},
+ {255, 47, 0}, {255, 47, 0}, {255, 48, 0}, {255, 48, 0}, {255, 48, 0},
+ {255, 48, 0}, {255, 49, 0}, {255, 49, 0}, {255, 49, 0}, {255, 50, 0},
+ {255, 50, 0}, {255, 50, 0}, {255, 50, 0}, {255, 51, 0}, {255, 51, 0},
+ {255, 51, 0}, {255, 51, 0}, {255, 52, 0}, {255, 52, 0}, {255, 52, 0},
+ {255, 52, 0}, {255, 53, 0}, {255, 53, 0}, {255, 53, 0}, {255, 53, 0},
+ {255, 54, 0}, {255, 54, 0}, {255, 54, 0}, {255, 54, 0}, {255, 55, 0},
+ {255, 55, 0}, {255, 55, 0}, {255, 55, 0}, {255, 56, 0}, {255, 56, 0},
+ {255, 56, 0}, {255, 56, 0}, {255, 57, 0}, {255, 57, 0}, {255, 57, 0},
+ {255, 57, 0}, {255, 58, 0}, {255, 58, 0}, {255, 58, 0}, {255, 58, 0},
+ {255, 59, 0}, {255, 59, 0}, {255, 59, 0}, {255, 59, 0}, {255, 60, 0},
+ {255, 60, 0}, {255, 60, 0}, {255, 60, 0}, {255, 61, 0}, {255, 61, 0},
+ {255, 61, 0}, {255, 62, 0}, {255, 62, 0}, {255, 62, 0}, {255, 62, 0},
+ {255, 63, 0}, {255, 63, 0}, {255, 63, 0}, {255, 63, 0}, {255, 64, 0},
+ {255, 64, 0}, {255, 64, 0}, {255, 64, 0}, {255, 65, 0}, {255, 65, 0},
+ {255, 65, 0}, {255, 65, 0}, {255, 66, 0}, {255, 66, 0}, {255, 66, 0},
+ {255, 66, 0}, {255, 67, 0}, {255, 67, 0}, {255, 67, 0}, {255, 67, 0},
+ {255, 68, 0}, {255, 68, 0}, {255, 68, 0}, {255, 68, 0}, {255, 69, 0},
+ {255, 69, 0}, {255, 69, 0}, {255, 69, 0}, {255, 70, 0}, {255, 70, 0},
+ {255, 70, 0}, {255, 70, 0}, {255, 71, 0}, {255, 71, 0}, {255, 71, 0},
+ {255, 71, 0}, {255, 72, 0}, {255, 72, 0}, {255, 72, 0}, {255, 72, 0},
+ {255, 73, 0}, {255, 73, 0}, {255, 73, 0}, {255, 74, 0}, {255, 74, 0},
+ {255, 74, 0}, {255, 74, 0}, {255, 75, 0}, {255, 75, 0}, {255, 75, 0},
+ {255, 75, 0}, {255, 76, 0}, {255, 76, 0}, {255, 76, 0}, {255, 76, 0},
+ {255, 77, 0}, {255, 77, 0}, {255, 77, 0}, {255, 77, 0}, {255, 78, 0},
+ {255, 78, 0}, {255, 78, 0}, {255, 78, 0}, {255, 79, 0}, {255, 79, 0},
+ {255, 79, 0}, {255, 79, 0}, {255, 80, 0}, {255, 80, 0}, {255, 80, 0},
+ {255, 80, 0}, {255, 81, 0}, {255, 81, 0}, {255, 81, 0}, {255, 81, 0},
+ {255, 82, 0}, {255, 82, 0}, {255, 82, 0}, {255, 82, 0}, {255, 83, 0},
+ {255, 83, 0}, {255, 83, 0}, {255, 83, 0}, {255, 84, 0}, {255, 84, 0},
+ {255, 84, 0}, {255, 84, 0}, {255, 85, 0}, {255, 85, 0}, {255, 85, 0},
+ {255, 86, 0}, {255, 86, 0}, {255, 86, 0}, {255, 86, 0}, {255, 87, 0},
+ {255, 87, 0}, {255, 87, 0}, {255, 87, 0}, {255, 88, 0}, {255, 88, 0},
+ {255, 88, 0}, {255, 88, 0}, {255, 89, 0}, {255, 89, 0}, {255, 89, 0},
+ {255, 89, 0}, {255, 90, 0}, {255, 90, 0}, {255, 90, 0}, {255, 90, 0},
+ {255, 91, 0}, {255, 91, 0}, {255, 91, 0}, {255, 91, 0}, {255, 92, 0},
+ {255, 92, 0}, {255, 92, 0}, {255, 92, 0}, {255, 93, 0}, {255, 93, 0},
+ {255, 93, 0}, {255, 93, 0}, {255, 94, 0}, {255, 94, 0}, {255, 94, 0},
+ {255, 94, 0}, {255, 95, 0}, {255, 95, 0}, {255, 95, 0}, {255, 95, 0},
+ {255, 96, 0}, {255, 96, 0}, {255, 96, 0}, {255, 96, 0}, {255, 97, 0},
+ {255, 97, 0}, {255, 97, 0}, {255, 98, 0}, {255, 98, 0}, {255, 98, 0},
+ {255, 98, 0}, {255, 99, 0}, {255, 99, 0}, {255, 99, 0}, {255, 99, 0},
+ {255, 100, 0}, {255, 100, 0}, {255, 100, 0}, {255, 100, 0}, {255, 101, 0},
+ {255, 101, 0}, {255, 101, 0}, {255, 101, 0}, {255, 102, 0}, {255, 102, 0},
+ {255, 102, 0}, {255, 102, 0}, {255, 103, 0}, {255, 103, 0}, {255, 103, 0},
+ {255, 103, 0}, {255, 104, 0}, {255, 104, 0}, {255, 104, 0}, {255, 104, 0},
+ {255, 105, 0}, {255, 105, 0}, {255, 105, 0}, {255, 105, 0}, {255, 106, 0},
+ {255, 106, 0}, {255, 106, 0}, {255, 106, 0}, {255, 107, 0}, {255, 107, 0},
+ {255, 107, 0}, {255, 107, 0}, {255, 108, 0}, {255, 108, 0}, {255, 108, 0},
+ {255, 108, 0}, {255, 109, 0}, {255, 109, 0}, {255, 109, 0}, {255, 110, 0},
+ {255, 110, 0}, {255, 110, 0}, {255, 110, 0}, {255, 111, 0}, {255, 111, 0},
+ {255, 111, 0}, {255, 111, 0}, {255, 112, 0}, {255, 112, 0}, {255, 112, 0},
+ {255, 112, 0}, {255, 113, 0}, {255, 113, 0}, {255, 113, 0}, {255, 113, 0},
+ {255, 114, 0}, {255, 114, 0}, {255, 114, 0}, {255, 114, 0}, {255, 115, 0},
+ {255, 115, 0}, {255, 115, 0}, {255, 115, 0}, {255, 116, 0}, {255, 116, 0},
+ {255, 116, 0}, {255, 116, 0}, {255, 117, 0}, {255, 117, 0}, {255, 117, 0},
+ {255, 117, 0}, {255, 118, 0}, {255, 118, 0}, {255, 118, 0}, {255, 118, 0},
+ {255, 119, 0}, {255, 119, 0}, {255, 119, 0}, {255, 119, 0}, {255, 120, 0},
+ {255, 120, 0}, {255, 120, 0}, {255, 120, 0}, {255, 121, 0}, {255, 121, 0},
+ {255, 121, 0}, {255, 122, 0}, {255, 122, 0}, {255, 122, 0}, {255, 122, 0},
+ {255, 123, 0}, {255, 123, 0}, {255, 123, 0}, {255, 123, 0}, {255, 124, 0},
+ {255, 124, 0}, {255, 124, 0}, {255, 124, 0}, {255, 125, 0}, {255, 125, 0},
+ {255, 125, 0}, {255, 125, 0}, {255, 126, 0}, {255, 126, 0}, {255, 126, 0},
+ {255, 126, 0}, {255, 127, 0}, {255, 127, 0}, {255, 127, 0}, {255, 127, 0},
+ {255, 128, 0}, {255, 128, 0}, {255, 128, 0}, {255, 128, 0}, {255, 129, 0},
+ {255, 129, 0}, {255, 129, 0}, {255, 129, 0}, {255, 130, 0}, {255, 130, 0},
+ {255, 130, 0}, {255, 130, 0}, {255, 131, 0}, {255, 131, 0}, {255, 131, 0},
+ {255, 131, 0}, {255, 132, 0}, {255, 132, 0}, {255, 132, 0}, {255, 132, 0},
+ {255, 133, 0}, {255, 133, 0}, {255, 133, 0}, {255, 133, 0}, {255, 134, 0},
+ {255, 134, 0}, {255, 134, 0}, {255, 135, 0}, {255, 135, 0}, {255, 135, 0},
+ {255, 135, 0}, {255, 136, 0}, {255, 136, 0}, {255, 136, 0}, {255, 136, 0},
+ {255, 137, 0}, {255, 137, 0}, {255, 137, 0}, {255, 137, 0}, {255, 138, 0},
+ {255, 138, 0}, {255, 138, 0}, {255, 138, 0}, {255, 139, 0}, {255, 139, 0},
+ {255, 139, 0}, {255, 139, 0}, {255, 140, 0}, {255, 140, 0}, {255, 140, 0},
+ {255, 140, 0}, {255, 141, 0}, {255, 141, 0}, {255, 141, 0}, {255, 141, 0},
+ {255, 142, 0}, {255, 142, 0}, {255, 142, 0}, {255, 142, 0}, {255, 143, 0},
+ {255, 143, 0}, {255, 143, 0}, {255, 143, 0}, {255, 144, 0}, {255, 144, 0},
+ {255, 144, 0}, {255, 144, 0}, {255, 145, 0}, {255, 145, 0}, {255, 145, 0},
+ {255, 145, 0}, {255, 146, 0}, {255, 146, 0}, {255, 146, 0}, {255, 147, 0},
+ {255, 147, 0}, {255, 147, 0}, {255, 147, 0}, {255, 148, 0}, {255, 148, 0},
+ {255, 148, 0}, {255, 148, 0}, {255, 149, 0}, {255, 149, 0}, {255, 149, 0},
+ {255, 149, 0}, {255, 150, 0}, {255, 150, 0}, {255, 150, 0}, {255, 150, 0},
+ {255, 151, 0}, {255, 151, 0}, {255, 151, 0}, {255, 151, 0}, {255, 152, 0},
+ {255, 152, 0}, {255, 152, 0}, {255, 152, 0}, {255, 153, 0}, {255, 153, 0},
+ {255, 153, 0}, {255, 153, 0}, {255, 154, 0}, {255, 154, 0}, {255, 154, 0},
+ {255, 154, 0}, {255, 155, 0}, {255, 155, 0}, {255, 155, 0}, {255, 155, 0},
+ {255, 156, 0}, {255, 156, 0}, {255, 156, 0}, {255, 156, 0}, {255, 157, 0},
+ {255, 157, 0}, {255, 157, 0}, {255, 157, 0}, {255, 158, 0}, {255, 158, 0},
+ {255, 158, 0}, {255, 159, 0}, {255, 159, 0}, {255, 159, 0}, {255, 159, 0},
+ {255, 160, 0}, {255, 160, 0}, {255, 160, 0}, {255, 160, 0}, {255, 161, 0},
+ {255, 161, 0}, {255, 161, 0}, {255, 161, 0}, {255, 162, 0}, {255, 162, 0},
+ {255, 162, 0}, {255, 162, 0}, {255, 163, 0}, {255, 163, 0}, {255, 163, 0},
+ {255, 163, 0}, {255, 164, 0}, {255, 164, 0}, {255, 164, 0}, {255, 164, 0},
+ {255, 165, 0}, {255, 165, 0}, {255, 165, 0}, {255, 165, 0}, {255, 166, 0},
+ {255, 166, 0}, {255, 166, 0}, {255, 166, 0}, {255, 167, 0}, {255, 167, 0},
+ {255, 167, 0}, {255, 167, 0}, {255, 168, 0}, {255, 168, 0}, {255, 168, 0},
+ {255, 168, 0}, {255, 169, 0}, {255, 169, 0}, {255, 169, 0}, {255, 169, 0},
+ {255, 170, 0}, {255, 170, 0}, {255, 170, 0}, {255, 171, 0}, {255, 171, 0},
+ {255, 171, 0}, {255, 171, 0}, {255, 172, 0}, {255, 172, 0}, {255, 172, 0},
+ {255, 172, 0}, {255, 173, 0}, {255, 173, 0}, {255, 173, 0}, {255, 173, 0},
+ {255, 174, 0}, {255, 174, 0}, {255, 174, 0}, {255, 174, 0}, {255, 175, 0},
+ {255, 175, 0}, {255, 175, 0}, {255, 175, 0}, {255, 176, 0}, {255, 176, 0},
+ {255, 176, 0}, {255, 176, 0}, {255, 177, 0}, {255, 177, 0}, {255, 177, 0},
+ {255, 177, 0}, {255, 178, 0}, {255, 178, 0}, {255, 178, 0}, {255, 178, 0},
+ {255, 179, 0}, {255, 179, 0}, {255, 179, 0}, {255, 179, 0}, {255, 180, 0},
+ {255, 180, 0}, {255, 180, 0}, {255, 180, 0}, {255, 181, 0}, {255, 181, 0},
+ {255, 181, 0}, {255, 181, 0}, {255, 182, 0}, {255, 182, 0}, {255, 182, 0},
+ {255, 183, 0}, {255, 183, 0}, {255, 183, 0}, {255, 183, 0}, {255, 184, 0},
+ {255, 184, 0}, {255, 184, 0}, {255, 184, 0}, {255, 185, 0}, {255, 185, 0},
+ {255, 185, 0}, {255, 185, 0}, {255, 186, 0}, {255, 186, 0}, {255, 186, 0},
+ {255, 186, 0}, {255, 187, 0}, {255, 187, 0}, {255, 187, 0}, {255, 187, 0},
+ {255, 188, 0}, {255, 188, 0}, {255, 188, 0}, {255, 188, 0}, {255, 189, 0},
+ {255, 189, 0}, {255, 189, 0}, {255, 189, 0}, {255, 190, 0}, {255, 190, 0},
+ {255, 190, 0}, {255, 190, 0}, {255, 191, 0}, {255, 191, 0}, {255, 191, 0},
+ {255, 191, 0}, {255, 192, 0}, {255, 192, 0}, {255, 192, 0}, {255, 192, 0},
+ {255, 193, 0}, {255, 193, 0}, {255, 193, 0}, {255, 193, 0}, {255, 194, 0},
+ {255, 194, 0}, {255, 194, 0}, {255, 195, 0}, {255, 195, 0}, {255, 195, 0},
+ {255, 195, 0}, {255, 196, 0}, {255, 196, 0}, {255, 196, 0}, {255, 196, 0},
+ {255, 197, 0}, {255, 197, 0}, {255, 197, 0}, {255, 197, 0}, {255, 198, 0},
+ {255, 198, 0}, {255, 198, 0}, {255, 198, 0}, {255, 199, 0}, {255, 199, 0},
+ {255, 199, 0}, {255, 199, 0}, {255, 200, 0}, {255, 200, 0}, {255, 200, 0},
+ {255, 200, 0}, {255, 201, 0}, {255, 201, 0}, {255, 201, 0}, {255, 201, 0},
+ {255, 202, 0}, {255, 202, 0}, {255, 202, 0}, {255, 202, 0}, {255, 203, 0},
+ {255, 203, 0}, {255, 203, 0}, {255, 203, 0}, {255, 204, 0}, {255, 204, 0},
+ {255, 204, 0}, {255, 204, 0}, {255, 205, 0}, {255, 205, 0}, {255, 205, 0},
+ {255, 205, 0}, {255, 206, 0}, {255, 206, 0}, {255, 206, 0}, {255, 207, 0},
+ {255, 207, 0}, {255, 207, 0}, {255, 207, 0}, {255, 208, 0}, {255, 208, 0},
+ {255, 208, 0}, {255, 208, 0}, {255, 209, 0}, {255, 209, 0}, {255, 209, 0},
+ {255, 209, 0}, {255, 210, 0}, {255, 210, 0}, {255, 210, 0}, {255, 210, 0},
+ {255, 211, 0}, {255, 211, 0}, {255, 211, 0}, {255, 211, 0}, {255, 212, 0},
+ {255, 212, 0}, {255, 212, 0}, {255, 212, 0}, {255, 213, 0}, {255, 213, 0},
+ {255, 213, 0}, {255, 213, 0}, {255, 214, 0}, {255, 214, 0}, {255, 214, 0},
+ {255, 214, 0}, {255, 215, 0}, {255, 215, 0}, {255, 215, 0}, {255, 215, 0},
+ {255, 216, 0}, {255, 216, 0}, {255, 216, 0}, {255, 216, 0}, {255, 217, 0},
+ {255, 217, 0}, {255, 217, 0}, {255, 217, 0}, {255, 218, 0}, {255, 218, 0},
+ {255, 218, 0}, {255, 218, 0}, {255, 219, 0}, {255, 219, 0}, {255, 219, 0},
+ {255, 220, 0}, {255, 220, 0}, {255, 220, 0}, {255, 220, 0}, {255, 221, 0},
+ {255, 221, 0}, {255, 221, 0}, {255, 221, 0}, {255, 222, 0}, {255, 222, 0},
+ {255, 222, 0}, {255, 222, 0}, {255, 223, 0}, {255, 223, 0}, {255, 223, 0},
+ {255, 223, 0}, {255, 224, 0}, {255, 224, 0}, {255, 224, 0}, {255, 224, 0},
+ {255, 225, 0}, {255, 225, 0}, {255, 225, 0}, {255, 225, 0}, {255, 226, 0},
+ {255, 226, 0}, {255, 226, 0}, {255, 226, 0}, {255, 227, 0}, {255, 227, 0},
+ {255, 227, 0}, {255, 227, 0}, {255, 228, 0}, {255, 228, 0}, {255, 228, 0},
+ {255, 228, 0}, {255, 229, 0}, {255, 229, 0}, {255, 229, 0}, {255, 229, 0},
+ {255, 230, 0}, {255, 230, 0}, {255, 230, 0}, {255, 230, 0}, {255, 231, 0},
+ {255, 231, 0}, {255, 231, 0}, {255, 232, 0}, {255, 232, 0}, {255, 232, 0},
+ {255, 232, 0}, {255, 233, 0}, {255, 233, 0}, {255, 233, 0}, {255, 233, 0},
+ {255, 234, 0}, {255, 234, 0}, {255, 234, 0}, {255, 234, 0}, {255, 235, 0},
+ {255, 235, 0}, {255, 235, 0}, {255, 235, 0}, {255, 236, 0}, {255, 236, 0},
+ {255, 236, 0}, {255, 236, 0}, {255, 237, 0}, {255, 237, 0}, {255, 237, 0},
+ {255, 237, 0}, {255, 238, 0}, {255, 238, 0}, {255, 238, 0}, {255, 238, 0},
+ {255, 239, 0}, {255, 239, 0}, {255, 239, 0}, {255, 239, 0}, {255, 240, 0},
+ {255, 240, 0}, {255, 240, 0}, {255, 240, 0}, {255, 241, 0}, {255, 241, 0},
+ {255, 241, 0}, {255, 241, 0}, {255, 242, 0}, {255, 242, 0}, {255, 242, 0},
+ {255, 242, 0}, {255, 243, 0}, {255, 243, 0}, {255, 243, 0}, {255, 244, 0},
+ {255, 244, 0}, {255, 244, 0}, {255, 244, 0}, {255, 245, 0}, {255, 245, 0},
+ {255, 245, 0}, {255, 245, 0}, {255, 246, 0}, {255, 246, 0}, {255, 246, 0},
+ {255, 246, 0}, {255, 247, 0}, {255, 247, 0}, {255, 247, 0}, {255, 247, 0},
+ {255, 248, 0}, {255, 248, 0}, {255, 248, 0}, {255, 248, 0}, {255, 249, 0},
+ {255, 249, 0}, {255, 249, 0}, {255, 249, 0}, {255, 250, 0}, {255, 250, 0},
+ {255, 250, 0}, {255, 250, 0}, {255, 251, 0}, {255, 251, 0}, {255, 251, 0},
+ {255, 251, 0}, {255, 252, 0}, {255, 252, 0}, {255, 252, 0}, {255, 252, 0},
+ {255, 253, 0}, {255, 253, 0}, {255, 253, 0}, {255, 253, 0}, {255, 254, 0},
+ {255, 254, 0}, {255, 254, 0}, {255, 254, 0}, {255, 255, 0}, {255, 255, 0}
+};
+
+const rgb_t copper_colormap[1000] = {
+ { 0, 0, 0}, { 0, 0, 0}, { 1, 0, 0}, { 1, 1, 0}, { 1, 1, 1},
+ { 2, 1, 1}, { 2, 1, 1}, { 2, 1, 1}, { 3, 2, 1}, { 3, 2, 1},
+ { 3, 2, 1}, { 4, 2, 1}, { 4, 2, 2}, { 4, 3, 2}, { 4, 3, 2},
+ { 5, 3, 2}, { 5, 3, 2}, { 5, 3, 2}, { 6, 4, 2}, { 6, 4, 2},
+ { 6, 4, 3}, { 7, 4, 3}, { 7, 4, 3}, { 7, 5, 3}, { 8, 5, 3},
+ { 8, 5, 3}, { 8, 5, 3}, { 9, 5, 3}, { 9, 6, 4}, { 9, 6, 4},
+ { 10, 6, 4}, { 10, 6, 4}, { 10, 6, 4}, { 11, 7, 4}, { 11, 7, 4},
+ { 11, 7, 4}, { 11, 7, 5}, { 12, 7, 5}, { 12, 8, 5}, { 12, 8, 5},
+ { 13, 8, 5}, { 13, 8, 5}, { 13, 8, 5}, { 14, 9, 5}, { 14, 9, 6},
+ { 14, 9, 6}, { 15, 9, 6}, { 15, 9, 6}, { 15, 10, 6}, { 16, 10, 6},
+ { 16, 10, 6}, { 16, 10, 6}, { 17, 10, 7}, { 17, 11, 7}, { 17, 11, 7},
+ { 18, 11, 7}, { 18, 11, 7}, { 18, 11, 7}, { 19, 12, 7}, { 19, 12, 7},
+ { 19, 12, 8}, { 19, 12, 8}, { 20, 12, 8}, { 20, 13, 8}, { 20, 13, 8},
+ { 21, 13, 8}, { 21, 13, 8}, { 21, 13, 9}, { 22, 14, 9}, { 22, 14, 9},
+ { 22, 14, 9}, { 23, 14, 9}, { 23, 14, 9}, { 23, 15, 9}, { 24, 15, 9},
+ { 24, 15, 10}, { 24, 15, 10}, { 25, 15, 10}, { 25, 16, 10}, { 25, 16, 10},
+ { 26, 16, 10}, { 26, 16, 10}, { 26, 16, 10}, { 26, 17, 11}, { 27, 17, 11},
+ { 27, 17, 11}, { 27, 17, 11}, { 28, 17, 11}, { 28, 18, 11}, { 28, 18, 11},
+ { 29, 18, 11}, { 29, 18, 12}, { 29, 18, 12}, { 30, 19, 12}, { 30, 19, 12},
+ { 30, 19, 12}, { 31, 19, 12}, { 31, 19, 12}, { 31, 20, 12}, { 32, 20, 13},
+ { 32, 20, 13}, { 32, 20, 13}, { 33, 20, 13}, { 33, 21, 13}, { 33, 21, 13},
+ { 34, 21, 13}, { 34, 21, 13}, { 34, 21, 14}, { 34, 22, 14}, { 35, 22, 14},
+ { 35, 22, 14}, { 35, 22, 14}, { 36, 22, 14}, { 36, 23, 14}, { 36, 23, 14},
+ { 37, 23, 15}, { 37, 23, 15}, { 37, 23, 15}, { 38, 24, 15}, { 38, 24, 15},
+ { 38, 24, 15}, { 39, 24, 15}, { 39, 24, 15}, { 39, 25, 16}, { 40, 25, 16},
+ { 40, 25, 16}, { 40, 25, 16}, { 41, 25, 16}, { 41, 26, 16}, { 41, 26, 16},
+ { 41, 26, 17}, { 42, 26, 17}, { 42, 26, 17}, { 42, 27, 17}, { 43, 27, 17},
+ { 43, 27, 17}, { 43, 27, 17}, { 44, 27, 17}, { 44, 28, 18}, { 44, 28, 18},
+ { 45, 28, 18}, { 45, 28, 18}, { 45, 28, 18}, { 46, 29, 18}, { 46, 29, 18},
+ { 46, 29, 18}, { 47, 29, 19}, { 47, 29, 19}, { 47, 30, 19}, { 48, 30, 19},
+ { 48, 30, 19}, { 48, 30, 19}, { 48, 30, 19}, { 49, 31, 19}, { 49, 31, 20},
+ { 49, 31, 20}, { 50, 31, 20}, { 50, 31, 20}, { 50, 32, 20}, { 51, 32, 20},
+ { 51, 32, 20}, { 51, 32, 20}, { 52, 32, 21}, { 52, 33, 21}, { 52, 33, 21},
+ { 53, 33, 21}, { 53, 33, 21}, { 53, 33, 21}, { 54, 34, 21}, { 54, 34, 21},
+ { 54, 34, 22}, { 55, 34, 22}, { 55, 34, 22}, { 55, 34, 22}, { 56, 35, 22},
+ { 56, 35, 22}, { 56, 35, 22}, { 56, 35, 22}, { 57, 35, 23}, { 57, 36, 23},
+ { 57, 36, 23}, { 58, 36, 23}, { 58, 36, 23}, { 58, 36, 23}, { 59, 37, 23},
+ { 59, 37, 23}, { 59, 37, 24}, { 60, 37, 24}, { 60, 37, 24}, { 60, 38, 24},
+ { 61, 38, 24}, { 61, 38, 24}, { 61, 38, 24}, { 62, 38, 25}, { 62, 39, 25},
+ { 62, 39, 25}, { 63, 39, 25}, { 63, 39, 25}, { 63, 39, 25}, { 63, 40, 25},
+ { 64, 40, 25}, { 64, 40, 26}, { 64, 40, 26}, { 65, 40, 26}, { 65, 41, 26},
+ { 65, 41, 26}, { 66, 41, 26}, { 66, 41, 26}, { 66, 41, 26}, { 67, 42, 27},
+ { 67, 42, 27}, { 67, 42, 27}, { 68, 42, 27}, { 68, 42, 27}, { 68, 43, 27},
+ { 69, 43, 27}, { 69, 43, 27}, { 69, 43, 28}, { 70, 43, 28}, { 70, 44, 28},
+ { 70, 44, 28}, { 71, 44, 28}, { 71, 44, 28}, { 71, 44, 28}, { 71, 45, 28},
+ { 72, 45, 29}, { 72, 45, 29}, { 72, 45, 29}, { 73, 45, 29}, { 73, 46, 29},
+ { 73, 46, 29}, { 74, 46, 29}, { 74, 46, 29}, { 74, 46, 30}, { 75, 47, 30},
+ { 75, 47, 30}, { 75, 47, 30}, { 76, 47, 30}, { 76, 47, 30}, { 76, 48, 30},
+ { 77, 48, 30}, { 77, 48, 31}, { 77, 48, 31}, { 78, 48, 31}, { 78, 49, 31},
+ { 78, 49, 31}, { 78, 49, 31}, { 79, 49, 31}, { 79, 49, 31}, { 79, 50, 32},
+ { 80, 50, 32}, { 80, 50, 32}, { 80, 50, 32}, { 81, 50, 32}, { 81, 51, 32},
+ { 81, 51, 32}, { 82, 51, 33}, { 82, 51, 33}, { 82, 51, 33}, { 83, 52, 33},
+ { 83, 52, 33}, { 83, 52, 33}, { 84, 52, 33}, { 84, 52, 33}, { 84, 53, 34},
+ { 85, 53, 34}, { 85, 53, 34}, { 85, 53, 34}, { 86, 53, 34}, { 86, 54, 34},
+ { 86, 54, 34}, { 86, 54, 34}, { 87, 54, 35}, { 87, 54, 35}, { 87, 55, 35},
+ { 88, 55, 35}, { 88, 55, 35}, { 88, 55, 35}, { 89, 55, 35}, { 89, 56, 35},
+ { 89, 56, 36}, { 90, 56, 36}, { 90, 56, 36}, { 90, 56, 36}, { 91, 57, 36},
+ { 91, 57, 36}, { 91, 57, 36}, { 92, 57, 36}, { 92, 57, 37}, { 92, 58, 37},
+ { 93, 58, 37}, { 93, 58, 37}, { 93, 58, 37}, { 93, 58, 37}, { 94, 59, 37},
+ { 94, 59, 37}, { 94, 59, 38}, { 95, 59, 38}, { 95, 59, 38}, { 95, 60, 38},
+ { 96, 60, 38}, { 96, 60, 38}, { 96, 60, 38}, { 97, 60, 38}, { 97, 61, 39},
+ { 97, 61, 39}, { 98, 61, 39}, { 98, 61, 39}, { 98, 61, 39}, { 99, 62, 39},
+ { 99, 62, 39}, { 99, 62, 39}, {100, 62, 40}, {100, 62, 40}, {100, 63, 40},
+ {101, 63, 40}, {101, 63, 40}, {101, 63, 40}, {101, 63, 40}, {102, 64, 41},
+ {102, 64, 41}, {102, 64, 41}, {103, 64, 41}, {103, 64, 41}, {103, 65, 41},
+ {104, 65, 41}, {104, 65, 41}, {104, 65, 42}, {105, 65, 42}, {105, 66, 42},
+ {105, 66, 42}, {106, 66, 42}, {106, 66, 42}, {106, 66, 42}, {107, 67, 42},
+ {107, 67, 43}, {107, 67, 43}, {108, 67, 43}, {108, 67, 43}, {108, 68, 43},
+ {108, 68, 43}, {109, 68, 43}, {109, 68, 43}, {109, 68, 44}, {110, 69, 44},
+ {110, 69, 44}, {110, 69, 44}, {111, 69, 44}, {111, 69, 44}, {111, 70, 44},
+ {112, 70, 44}, {112, 70, 45}, {112, 70, 45}, {113, 70, 45}, {113, 71, 45},
+ {113, 71, 45}, {114, 71, 45}, {114, 71, 45}, {114, 71, 45}, {115, 72, 46},
+ {115, 72, 46}, {115, 72, 46}, {116, 72, 46}, {116, 72, 46}, {116, 73, 46},
+ {116, 73, 46}, {117, 73, 46}, {117, 73, 47}, {117, 73, 47}, {118, 74, 47},
+ {118, 74, 47}, {118, 74, 47}, {119, 74, 47}, {119, 74, 47}, {119, 75, 47},
+ {120, 75, 48}, {120, 75, 48}, {120, 75, 48}, {121, 75, 48}, {121, 76, 48},
+ {121, 76, 48}, {122, 76, 48}, {122, 76, 49}, {122, 76, 49}, {123, 77, 49},
+ {123, 77, 49}, {123, 77, 49}, {123, 77, 49}, {124, 77, 49}, {124, 78, 49},
+ {124, 78, 50}, {125, 78, 50}, {125, 78, 50}, {125, 78, 50}, {126, 79, 50},
+ {126, 79, 50}, {126, 79, 50}, {127, 79, 50}, {127, 79, 51}, {127, 80, 51},
+ {128, 80, 51}, {128, 80, 51}, {128, 80, 51}, {129, 80, 51}, {129, 81, 51},
+ {129, 81, 51}, {130, 81, 52}, {130, 81, 52}, {130, 81, 52}, {130, 82, 52},
+ {131, 82, 52}, {131, 82, 52}, {131, 82, 52}, {132, 82, 52}, {132, 83, 53},
+ {132, 83, 53}, {133, 83, 53}, {133, 83, 53}, {133, 83, 53}, {134, 84, 53},
+ {134, 84, 53}, {134, 84, 53}, {135, 84, 54}, {135, 84, 54}, {135, 85, 54},
+ {136, 85, 54}, {136, 85, 54}, {136, 85, 54}, {137, 85, 54}, {137, 86, 54},
+ {137, 86, 55}, {138, 86, 55}, {138, 86, 55}, {138, 86, 55}, {138, 87, 55},
+ {139, 87, 55}, {139, 87, 55}, {139, 87, 55}, {140, 87, 56}, {140, 88, 56},
+ {140, 88, 56}, {141, 88, 56}, {141, 88, 56}, {141, 88, 56}, {142, 89, 56},
+ {142, 89, 57}, {142, 89, 57}, {143, 89, 57}, {143, 89, 57}, {143, 90, 57},
+ {144, 90, 57}, {144, 90, 57}, {144, 90, 57}, {145, 90, 58}, {145, 91, 58},
+ {145, 91, 58}, {145, 91, 58}, {146, 91, 58}, {146, 91, 58}, {146, 92, 58},
+ {147, 92, 58}, {147, 92, 59}, {147, 92, 59}, {148, 92, 59}, {148, 93, 59},
+ {148, 93, 59}, {149, 93, 59}, {149, 93, 59}, {149, 93, 59}, {150, 94, 60},
+ {150, 94, 60}, {150, 94, 60}, {151, 94, 60}, {151, 94, 60}, {151, 95, 60},
+ {152, 95, 60}, {152, 95, 60}, {152, 95, 61}, {153, 95, 61}, {153, 96, 61},
+ {153, 96, 61}, {153, 96, 61}, {154, 96, 61}, {154, 96, 61}, {154, 97, 61},
+ {155, 97, 62}, {155, 97, 62}, {155, 97, 62}, {156, 97, 62}, {156, 98, 62},
+ {156, 98, 62}, {157, 98, 62}, {157, 98, 62}, {157, 98, 63}, {158, 99, 63},
+ {158, 99, 63}, {158, 99, 63}, {159, 99, 63}, {159, 99, 63}, {159, 100, 63},
+ {160, 100, 63}, {160, 100, 64}, {160, 100, 64}, {160, 100, 64}, {161, 101, 64},
+ {161, 101, 64}, {161, 101, 64}, {162, 101, 64}, {162, 101, 65}, {162, 101, 65},
+ {163, 102, 65}, {163, 102, 65}, {163, 102, 65}, {164, 102, 65}, {164, 102, 65},
+ {164, 103, 65}, {165, 103, 66}, {165, 103, 66}, {165, 103, 66}, {166, 103, 66},
+ {166, 104, 66}, {166, 104, 66}, {167, 104, 66}, {167, 104, 66}, {167, 104, 67},
+ {168, 105, 67}, {168, 105, 67}, {168, 105, 67}, {168, 105, 67}, {169, 105, 67},
+ {169, 106, 67}, {169, 106, 67}, {170, 106, 68}, {170, 106, 68}, {170, 106, 68},
+ {171, 107, 68}, {171, 107, 68}, {171, 107, 68}, {172, 107, 68}, {172, 107, 68},
+ {172, 108, 69}, {173, 108, 69}, {173, 108, 69}, {173, 108, 69}, {174, 108, 69},
+ {174, 109, 69}, {174, 109, 69}, {175, 109, 69}, {175, 109, 70}, {175, 109, 70},
+ {175, 110, 70}, {176, 110, 70}, {176, 110, 70}, {176, 110, 70}, {177, 110, 70},
+ {177, 111, 70}, {177, 111, 71}, {178, 111, 71}, {178, 111, 71}, {178, 111, 71},
+ {179, 112, 71}, {179, 112, 71}, {179, 112, 71}, {180, 112, 71}, {180, 112, 72},
+ {180, 113, 72}, {181, 113, 72}, {181, 113, 72}, {181, 113, 72}, {182, 113, 72},
+ {182, 114, 72}, {182, 114, 73}, {183, 114, 73}, {183, 114, 73}, {183, 114, 73},
+ {183, 115, 73}, {184, 115, 73}, {184, 115, 73}, {184, 115, 73}, {185, 115, 74},
+ {185, 116, 74}, {185, 116, 74}, {186, 116, 74}, {186, 116, 74}, {186, 116, 74},
+ {187, 117, 74}, {187, 117, 74}, {187, 117, 75}, {188, 117, 75}, {188, 117, 75},
+ {188, 118, 75}, {189, 118, 75}, {189, 118, 75}, {189, 118, 75}, {190, 118, 75},
+ {190, 119, 76}, {190, 119, 76}, {190, 119, 76}, {191, 119, 76}, {191, 119, 76},
+ {191, 120, 76}, {192, 120, 76}, {192, 120, 76}, {192, 120, 77}, {193, 120, 77},
+ {193, 121, 77}, {193, 121, 77}, {194, 121, 77}, {194, 121, 77}, {194, 121, 77},
+ {195, 122, 77}, {195, 122, 78}, {195, 122, 78}, {196, 122, 78}, {196, 122, 78},
+ {196, 123, 78}, {197, 123, 78}, {197, 123, 78}, {197, 123, 78}, {198, 123, 79},
+ {198, 124, 79}, {198, 124, 79}, {198, 124, 79}, {199, 124, 79}, {199, 124, 79},
+ {199, 125, 79}, {200, 125, 79}, {200, 125, 80}, {200, 125, 80}, {201, 125, 80},
+ {201, 126, 80}, {201, 126, 80}, {202, 126, 80}, {202, 126, 80}, {202, 126, 81},
+ {203, 127, 81}, {203, 127, 81}, {203, 127, 81}, {204, 127, 81}, {204, 127, 81},
+ {204, 128, 81}, {205, 128, 81}, {205, 128, 82}, {205, 128, 82}, {205, 128, 82},
+ {206, 129, 82}, {206, 129, 82}, {206, 129, 82}, {207, 129, 82}, {207, 129, 82},
+ {207, 130, 83}, {208, 130, 83}, {208, 130, 83}, {208, 130, 83}, {209, 130, 83},
+ {209, 131, 83}, {209, 131, 83}, {210, 131, 83}, {210, 131, 84}, {210, 131, 84},
+ {211, 132, 84}, {211, 132, 84}, {211, 132, 84}, {212, 132, 84}, {212, 132, 84},
+ {212, 133, 84}, {212, 133, 85}, {213, 133, 85}, {213, 133, 85}, {213, 133, 85},
+ {214, 134, 85}, {214, 134, 85}, {214, 134, 85}, {215, 134, 85}, {215, 134, 86},
+ {215, 135, 86}, {216, 135, 86}, {216, 135, 86}, {216, 135, 86}, {217, 135, 86},
+ {217, 136, 86}, {217, 136, 86}, {218, 136, 87}, {218, 136, 87}, {218, 136, 87},
+ {219, 137, 87}, {219, 137, 87}, {219, 137, 87}, {220, 137, 87}, {220, 137, 87},
+ {220, 138, 88}, {220, 138, 88}, {221, 138, 88}, {221, 138, 88}, {221, 138, 88},
+ {222, 139, 88}, {222, 139, 88}, {222, 139, 89}, {223, 139, 89}, {223, 139, 89},
+ {223, 140, 89}, {224, 140, 89}, {224, 140, 89}, {224, 140, 89}, {225, 140, 89},
+ {225, 141, 90}, {225, 141, 90}, {226, 141, 90}, {226, 141, 90}, {226, 141, 90},
+ {227, 142, 90}, {227, 142, 90}, {227, 142, 90}, {227, 142, 91}, {228, 142, 91},
+ {228, 143, 91}, {228, 143, 91}, {229, 143, 91}, {229, 143, 91}, {229, 143, 91},
+ {230, 144, 91}, {230, 144, 92}, {230, 144, 92}, {231, 144, 92}, {231, 144, 92},
+ {231, 145, 92}, {232, 145, 92}, {232, 145, 92}, {232, 145, 92}, {233, 145, 93},
+ {233, 146, 93}, {233, 146, 93}, {234, 146, 93}, {234, 146, 93}, {234, 146, 93},
+ {235, 147, 93}, {235, 147, 93}, {235, 147, 94}, {235, 147, 94}, {236, 147, 94},
+ {236, 148, 94}, {236, 148, 94}, {237, 148, 94}, {237, 148, 94}, {237, 148, 94},
+ {238, 149, 95}, {238, 149, 95}, {238, 149, 95}, {239, 149, 95}, {239, 149, 95},
+ {239, 150, 95}, {240, 150, 95}, {240, 150, 95}, {240, 150, 96}, {241, 150, 96},
+ {241, 151, 96}, {241, 151, 96}, {242, 151, 96}, {242, 151, 96}, {242, 151, 96},
+ {242, 152, 97}, {243, 152, 97}, {243, 152, 97}, {243, 152, 97}, {244, 152, 97},
+ {244, 153, 97}, {244, 153, 97}, {245, 153, 97}, {245, 153, 98}, {245, 153, 98},
+ {246, 154, 98}, {246, 154, 98}, {246, 154, 98}, {247, 154, 98}, {247, 154, 98},
+ {247, 155, 98}, {248, 155, 99}, {248, 155, 99}, {248, 155, 99}, {249, 155, 99},
+ {249, 156, 99}, {249, 156, 99}, {250, 156, 99}, {250, 156, 99}, {250, 156, 100},
+ {250, 157, 100}, {251, 157, 100}, {251, 157, 100}, {251, 157, 100}, {252, 157, 100},
+ {252, 158, 100}, {252, 158, 100}, {253, 158, 101}, {253, 158, 101}, {253, 158, 101},
+ {253, 159, 101}, {253, 159, 101}, {254, 159, 101}, {254, 159, 101}, {254, 159, 101},
+ {254, 160, 102}, {254, 160, 102}, {254, 160, 102}, {254, 160, 102}, {254, 160, 102},
+ {255, 161, 102}, {255, 161, 102}, {255, 161, 102}, {255, 161, 103}, {255, 161, 103},
+ {255, 162, 103}, {255, 162, 103}, {255, 162, 103}, {255, 162, 103}, {255, 162, 103},
+ {255, 163, 103}, {255, 163, 104}, {255, 163, 104}, {255, 163, 104}, {255, 163, 104},
+ {255, 164, 104}, {255, 164, 104}, {255, 164, 104}, {255, 164, 105}, {255, 164, 105},
+ {255, 165, 105}, {255, 165, 105}, {255, 165, 105}, {255, 165, 105}, {255, 165, 105},
+ {255, 166, 105}, {255, 166, 106}, {255, 166, 106}, {255, 166, 106}, {255, 166, 106},
+ {255, 167, 106}, {255, 167, 106}, {255, 167, 106}, {255, 167, 106}, {255, 167, 107},
+ {255, 168, 107}, {255, 168, 107}, {255, 168, 107}, {255, 168, 107}, {255, 168, 107},
+ {255, 168, 107}, {255, 169, 107}, {255, 169, 108}, {255, 169, 108}, {255, 169, 108},
+ {255, 169, 108}, {255, 170, 108}, {255, 170, 108}, {255, 170, 108}, {255, 170, 108},
+ {255, 170, 109}, {255, 171, 109}, {255, 171, 109}, {255, 171, 109}, {255, 171, 109},
+ {255, 171, 109}, {255, 172, 109}, {255, 172, 109}, {255, 172, 110}, {255, 172, 110},
+ {255, 172, 110}, {255, 173, 110}, {255, 173, 110}, {255, 173, 110}, {255, 173, 110},
+ {255, 173, 110}, {255, 174, 111}, {255, 174, 111}, {255, 174, 111}, {255, 174, 111},
+ {255, 174, 111}, {255, 175, 111}, {255, 175, 111}, {255, 175, 111}, {255, 175, 112},
+ {255, 175, 112}, {255, 176, 112}, {255, 176, 112}, {255, 176, 112}, {255, 176, 112},
+ {255, 176, 112}, {255, 177, 113}, {255, 177, 113}, {255, 177, 113}, {255, 177, 113},
+ {255, 177, 113}, {255, 178, 113}, {255, 178, 113}, {255, 178, 113}, {255, 178, 114},
+ {255, 178, 114}, {255, 179, 114}, {255, 179, 114}, {255, 179, 114}, {255, 179, 114},
+ {255, 179, 114}, {255, 180, 114}, {255, 180, 115}, {255, 180, 115}, {255, 180, 115},
+ {255, 180, 115}, {255, 181, 115}, {255, 181, 115}, {255, 181, 115}, {255, 181, 115},
+ {255, 181, 116}, {255, 182, 116}, {255, 182, 116}, {255, 182, 116}, {255, 182, 116},
+ {255, 182, 116}, {255, 183, 116}, {255, 183, 116}, {255, 183, 117}, {255, 183, 117},
+ {255, 183, 117}, {255, 184, 117}, {255, 184, 117}, {255, 184, 117}, {255, 184, 117},
+ {255, 184, 117}, {255, 185, 118}, {255, 185, 118}, {255, 185, 118}, {255, 185, 118},
+ {255, 185, 118}, {255, 186, 118}, {255, 186, 118}, {255, 186, 118}, {255, 186, 119},
+ {255, 186, 119}, {255, 187, 119}, {255, 187, 119}, {255, 187, 119}, {255, 187, 119},
+ {255, 187, 119}, {255, 188, 119}, {255, 188, 120}, {255, 188, 120}, {255, 188, 120},
+ {255, 188, 120}, {255, 189, 120}, {255, 189, 120}, {255, 189, 120}, {255, 189, 121},
+ {255, 189, 121}, {255, 190, 121}, {255, 190, 121}, {255, 190, 121}, {255, 190, 121},
+ {255, 190, 121}, {255, 191, 121}, {255, 191, 122}, {255, 191, 122}, {255, 191, 122},
+ {255, 191, 122}, {255, 192, 122}, {255, 192, 122}, {255, 192, 122}, {255, 192, 122},
+ {255, 192, 123}, {255, 193, 123}, {255, 193, 123}, {255, 193, 123}, {255, 193, 123},
+ {255, 193, 123}, {255, 194, 123}, {255, 194, 123}, {255, 194, 124}, {255, 194, 124},
+ {255, 194, 124}, {255, 195, 124}, {255, 195, 124}, {255, 195, 124}, {255, 195, 124},
+ {255, 195, 124}, {255, 196, 125}, {255, 196, 125}, {255, 196, 125}, {255, 196, 125},
+ {255, 196, 125}, {255, 197, 125}, {255, 197, 125}, {255, 197, 125}, {255, 197, 126},
+ {255, 197, 126}, {255, 198, 126}, {255, 198, 126}, {255, 198, 126}, {255, 198, 126},
+ {255, 198, 126}, {255, 199, 126}, {255, 199, 127}, {255, 199, 127}, {255, 199, 127}
+};
+
+const rgb_t gray_colormap[1000] = {
+ {255, 255, 255}, {255, 255, 255}, {254, 254, 254}, {254, 254, 254}, {254, 254, 254},
+ {254, 254, 254}, {253, 253, 253}, {253, 253, 253}, {253, 253, 253}, {253, 253, 253},
+ {252, 252, 252}, {252, 252, 252}, {252, 252, 252}, {252, 252, 252}, {251, 251, 251},
+ {251, 251, 251}, {251, 251, 251}, {251, 251, 251}, {250, 250, 250}, {250, 250, 250},
+ {250, 250, 250}, {250, 250, 250}, {249, 249, 249}, {249, 249, 249}, {249, 249, 249},
+ {249, 249, 249}, {248, 248, 248}, {248, 248, 248}, {248, 248, 248}, {248, 248, 248},
+ {247, 247, 247}, {247, 247, 247}, {247, 247, 247}, {247, 247, 247}, {246, 246, 246},
+ {246, 246, 246}, {246, 246, 246}, {246, 246, 246}, {245, 245, 245}, {245, 245, 245},
+ {245, 245, 245}, {245, 245, 245}, {244, 244, 244}, {244, 244, 244}, {244, 244, 244},
+ {244, 244, 244}, {243, 243, 243}, {243, 243, 243}, {243, 243, 243}, {242, 242, 242},
+ {242, 242, 242}, {242, 242, 242}, {242, 242, 242}, {241, 241, 241}, {241, 241, 241},
+ {241, 241, 241}, {241, 241, 241}, {240, 240, 240}, {240, 240, 240}, {240, 240, 240},
+ {240, 240, 240}, {239, 239, 239}, {239, 239, 239}, {239, 239, 239}, {239, 239, 239},
+ {238, 238, 238}, {238, 238, 238}, {238, 238, 238}, {238, 238, 238}, {237, 237, 237},
+ {237, 237, 237}, {237, 237, 237}, {237, 237, 237}, {236, 236, 236}, {236, 236, 236},
+ {236, 236, 236}, {236, 236, 236}, {235, 235, 235}, {235, 235, 235}, {235, 235, 235},
+ {235, 235, 235}, {234, 234, 234}, {234, 234, 234}, {234, 234, 234}, {234, 234, 234},
+ {233, 233, 233}, {233, 233, 233}, {233, 233, 233}, {233, 233, 233}, {232, 232, 232},
+ {232, 232, 232}, {232, 232, 232}, {232, 232, 232}, {231, 231, 231}, {231, 231, 231},
+ {231, 231, 231}, {230, 230, 230}, {230, 230, 230}, {230, 230, 230}, {230, 230, 230},
+ {229, 229, 229}, {229, 229, 229}, {229, 229, 229}, {229, 229, 229}, {228, 228, 228},
+ {228, 228, 228}, {228, 228, 228}, {228, 228, 228}, {227, 227, 227}, {227, 227, 227},
+ {227, 227, 227}, {227, 227, 227}, {226, 226, 226}, {226, 226, 226}, {226, 226, 226},
+ {226, 226, 226}, {225, 225, 225}, {225, 225, 225}, {225, 225, 225}, {225, 225, 225},
+ {224, 224, 224}, {224, 224, 224}, {224, 224, 224}, {224, 224, 224}, {223, 223, 223},
+ {223, 223, 223}, {223, 223, 223}, {223, 223, 223}, {222, 222, 222}, {222, 222, 222},
+ {222, 222, 222}, {222, 222, 222}, {221, 221, 221}, {221, 221, 221}, {221, 221, 221},
+ {221, 221, 221}, {220, 220, 220}, {220, 220, 220}, {220, 220, 220}, {220, 220, 220},
+ {219, 219, 219}, {219, 219, 219}, {219, 219, 219}, {218, 218, 218}, {218, 218, 218},
+ {218, 218, 218}, {218, 218, 218}, {217, 217, 217}, {217, 217, 217}, {217, 217, 217},
+ {217, 217, 217}, {216, 216, 216}, {216, 216, 216}, {216, 216, 216}, {216, 216, 216},
+ {215, 215, 215}, {215, 215, 215}, {215, 215, 215}, {215, 215, 215}, {214, 214, 214},
+ {214, 214, 214}, {214, 214, 214}, {214, 214, 214}, {213, 213, 213}, {213, 213, 213},
+ {213, 213, 213}, {213, 213, 213}, {212, 212, 212}, {212, 212, 212}, {212, 212, 212},
+ {212, 212, 212}, {211, 211, 211}, {211, 211, 211}, {211, 211, 211}, {211, 211, 211},
+ {210, 210, 210}, {210, 210, 210}, {210, 210, 210}, {210, 210, 210}, {209, 209, 209},
+ {209, 209, 209}, {209, 209, 209}, {209, 209, 209}, {208, 208, 208}, {208, 208, 208},
+ {208, 208, 208}, {208, 208, 208}, {207, 207, 207}, {207, 207, 207}, {207, 207, 207},
+ {207, 207, 207}, {206, 206, 206}, {206, 206, 206}, {206, 206, 206}, {205, 205, 205},
+ {205, 205, 205}, {205, 205, 205}, {205, 205, 205}, {204, 204, 204}, {204, 204, 204},
+ {204, 204, 204}, {204, 204, 204}, {203, 203, 203}, {203, 203, 203}, {203, 203, 203},
+ {203, 203, 203}, {202, 202, 202}, {202, 202, 202}, {202, 202, 202}, {202, 202, 202},
+ {201, 201, 201}, {201, 201, 201}, {201, 201, 201}, {201, 201, 201}, {200, 200, 200},
+ {200, 200, 200}, {200, 200, 200}, {200, 200, 200}, {199, 199, 199}, {199, 199, 199},
+ {199, 199, 199}, {199, 199, 199}, {198, 198, 198}, {198, 198, 198}, {198, 198, 198},
+ {198, 198, 198}, {197, 197, 197}, {197, 197, 197}, {197, 197, 197}, {197, 197, 197},
+ {196, 196, 196}, {196, 196, 196}, {196, 196, 196}, {196, 196, 196}, {195, 195, 195},
+ {195, 195, 195}, {195, 195, 195}, {195, 195, 195}, {194, 194, 194}, {194, 194, 194},
+ {194, 194, 194}, {193, 193, 193}, {193, 193, 193}, {193, 193, 193}, {193, 193, 193},
+ {192, 192, 192}, {192, 192, 192}, {192, 192, 192}, {192, 192, 192}, {191, 191, 191},
+ {191, 191, 191}, {191, 191, 191}, {191, 191, 191}, {190, 190, 190}, {190, 190, 190},
+ {190, 190, 190}, {190, 190, 190}, {189, 189, 189}, {189, 189, 189}, {189, 189, 189},
+ {189, 189, 189}, {188, 188, 188}, {188, 188, 188}, {188, 188, 188}, {188, 188, 188},
+ {187, 187, 187}, {187, 187, 187}, {187, 187, 187}, {187, 187, 187}, {186, 186, 186},
+ {186, 186, 186}, {186, 186, 186}, {186, 186, 186}, {185, 185, 185}, {185, 185, 185},
+ {185, 185, 185}, {185, 185, 185}, {184, 184, 184}, {184, 184, 184}, {184, 184, 184},
+ {184, 184, 184}, {183, 183, 183}, {183, 183, 183}, {183, 183, 183}, {183, 183, 183},
+ {182, 182, 182}, {182, 182, 182}, {182, 182, 182}, {181, 181, 181}, {181, 181, 181},
+ {181, 181, 181}, {181, 181, 181}, {180, 180, 180}, {180, 180, 180}, {180, 180, 180},
+ {180, 180, 180}, {179, 179, 179}, {179, 179, 179}, {179, 179, 179}, {179, 179, 179},
+ {178, 178, 178}, {178, 178, 178}, {178, 178, 178}, {178, 178, 178}, {177, 177, 177},
+ {177, 177, 177}, {177, 177, 177}, {177, 177, 177}, {176, 176, 176}, {176, 176, 176},
+ {176, 176, 176}, {176, 176, 176}, {175, 175, 175}, {175, 175, 175}, {175, 175, 175},
+ {175, 175, 175}, {174, 174, 174}, {174, 174, 174}, {174, 174, 174}, {174, 174, 174},
+ {173, 173, 173}, {173, 173, 173}, {173, 173, 173}, {173, 173, 173}, {172, 172, 172},
+ {172, 172, 172}, {172, 172, 172}, {172, 172, 172}, {171, 171, 171}, {171, 171, 171},
+ {171, 171, 171}, {171, 171, 171}, {170, 170, 170}, {170, 170, 170}, {170, 170, 170},
+ {169, 169, 169}, {169, 169, 169}, {169, 169, 169}, {169, 169, 169}, {168, 168, 168},
+ {168, 168, 168}, {168, 168, 168}, {168, 168, 168}, {167, 167, 167}, {167, 167, 167},
+ {167, 167, 167}, {167, 167, 167}, {166, 166, 166}, {166, 166, 166}, {166, 166, 166},
+ {166, 166, 166}, {165, 165, 165}, {165, 165, 165}, {165, 165, 165}, {165, 165, 165},
+ {164, 164, 164}, {164, 164, 164}, {164, 164, 164}, {164, 164, 164}, {163, 163, 163},
+ {163, 163, 163}, {163, 163, 163}, {163, 163, 163}, {162, 162, 162}, {162, 162, 162},
+ {162, 162, 162}, {162, 162, 162}, {161, 161, 161}, {161, 161, 161}, {161, 161, 161},
+ {161, 161, 161}, {160, 160, 160}, {160, 160, 160}, {160, 160, 160}, {160, 160, 160},
+ {159, 159, 159}, {159, 159, 159}, {159, 159, 159}, {159, 159, 159}, {158, 158, 158},
+ {158, 158, 158}, {158, 158, 158}, {157, 157, 157}, {157, 157, 157}, {157, 157, 157},
+ {157, 157, 157}, {156, 156, 156}, {156, 156, 156}, {156, 156, 156}, {156, 156, 156},
+ {155, 155, 155}, {155, 155, 155}, {155, 155, 155}, {155, 155, 155}, {154, 154, 154},
+ {154, 154, 154}, {154, 154, 154}, {154, 154, 154}, {153, 153, 153}, {153, 153, 153},
+ {153, 153, 153}, {153, 153, 153}, {152, 152, 152}, {152, 152, 152}, {152, 152, 152},
+ {152, 152, 152}, {151, 151, 151}, {151, 151, 151}, {151, 151, 151}, {151, 151, 151},
+ {150, 150, 150}, {150, 150, 150}, {150, 150, 150}, {150, 150, 150}, {149, 149, 149},
+ {149, 149, 149}, {149, 149, 149}, {149, 149, 149}, {148, 148, 148}, {148, 148, 148},
+ {148, 148, 148}, {148, 148, 148}, {147, 147, 147}, {147, 147, 147}, {147, 147, 147},
+ {147, 147, 147}, {146, 146, 146}, {146, 146, 146}, {146, 146, 146}, {145, 145, 145},
+ {145, 145, 145}, {145, 145, 145}, {145, 145, 145}, {144, 144, 144}, {144, 144, 144},
+ {144, 144, 144}, {144, 144, 144}, {143, 143, 143}, {143, 143, 143}, {143, 143, 143},
+ {143, 143, 143}, {142, 142, 142}, {142, 142, 142}, {142, 142, 142}, {142, 142, 142},
+ {141, 141, 141}, {141, 141, 141}, {141, 141, 141}, {141, 141, 141}, {140, 140, 140},
+ {140, 140, 140}, {140, 140, 140}, {140, 140, 140}, {139, 139, 139}, {139, 139, 139},
+ {139, 139, 139}, {139, 139, 139}, {138, 138, 138}, {138, 138, 138}, {138, 138, 138},
+ {138, 138, 138}, {137, 137, 137}, {137, 137, 137}, {137, 137, 137}, {137, 137, 137},
+ {136, 136, 136}, {136, 136, 136}, {136, 136, 136}, {136, 136, 136}, {135, 135, 135},
+ {135, 135, 135}, {135, 135, 135}, {135, 135, 135}, {134, 134, 134}, {134, 134, 134},
+ {134, 134, 134}, {133, 133, 133}, {133, 133, 133}, {133, 133, 133}, {133, 133, 133},
+ {132, 132, 132}, {132, 132, 132}, {132, 132, 132}, {132, 132, 132}, {131, 131, 131},
+ {131, 131, 131}, {131, 131, 131}, {131, 131, 131}, {130, 130, 130}, {130, 130, 130},
+ {130, 130, 130}, {130, 130, 130}, {129, 129, 129}, {129, 129, 129}, {129, 129, 129},
+ {129, 129, 129}, {128, 128, 128}, {128, 128, 128}, {128, 128, 128}, {128, 128, 128},
+ {127, 127, 127}, {127, 127, 127}, {127, 127, 127}, {127, 127, 127}, {126, 126, 126},
+ {126, 126, 126}, {126, 126, 126}, {126, 126, 126}, {125, 125, 125}, {125, 125, 125},
+ {125, 125, 125}, {125, 125, 125}, {124, 124, 124}, {124, 124, 124}, {124, 124, 124},
+ {124, 124, 124}, {123, 123, 123}, {123, 123, 123}, {123, 123, 123}, {123, 123, 123},
+ {122, 122, 122}, {122, 122, 122}, {122, 122, 122}, {122, 122, 122}, {121, 121, 121},
+ {121, 121, 121}, {121, 121, 121}, {120, 120, 120}, {120, 120, 120}, {120, 120, 120},
+ {120, 120, 120}, {119, 119, 119}, {119, 119, 119}, {119, 119, 119}, {119, 119, 119},
+ {118, 118, 118}, {118, 118, 118}, {118, 118, 118}, {118, 118, 118}, {117, 117, 117},
+ {117, 117, 117}, {117, 117, 117}, {117, 117, 117}, {116, 116, 116}, {116, 116, 116},
+ {116, 116, 116}, {116, 116, 116}, {115, 115, 115}, {115, 115, 115}, {115, 115, 115},
+ {115, 115, 115}, {114, 114, 114}, {114, 114, 114}, {114, 114, 114}, {114, 114, 114},
+ {113, 113, 113}, {113, 113, 113}, {113, 113, 113}, {113, 113, 113}, {112, 112, 112},
+ {112, 112, 112}, {112, 112, 112}, {112, 112, 112}, {111, 111, 111}, {111, 111, 111},
+ {111, 111, 111}, {111, 111, 111}, {110, 110, 110}, {110, 110, 110}, {110, 110, 110},
+ {110, 110, 110}, {109, 109, 109}, {109, 109, 109}, {109, 109, 109}, {108, 108, 108},
+ {108, 108, 108}, {108, 108, 108}, {108, 108, 108}, {107, 107, 107}, {107, 107, 107},
+ {107, 107, 107}, {107, 107, 107}, {106, 106, 106}, {106, 106, 106}, {106, 106, 106},
+ {106, 106, 106}, {105, 105, 105}, {105, 105, 105}, {105, 105, 105}, {105, 105, 105},
+ {104, 104, 104}, {104, 104, 104}, {104, 104, 104}, {104, 104, 104}, {103, 103, 103},
+ {103, 103, 103}, {103, 103, 103}, {103, 103, 103}, {102, 102, 102}, {102, 102, 102},
+ {102, 102, 102}, {102, 102, 102}, {101, 101, 101}, {101, 101, 101}, {101, 101, 101},
+ {101, 101, 101}, {100, 100, 100}, {100, 100, 100}, {100, 100, 100}, {100, 100, 100},
+ { 99, 99, 99}, { 99, 99, 99}, { 99, 99, 99}, { 99, 99, 99}, { 98, 98, 98},
+ { 98, 98, 98}, { 98, 98, 98}, { 98, 98, 98}, { 97, 97, 97}, { 97, 97, 97},
+ { 97, 97, 97}, { 96, 96, 96}, { 96, 96, 96}, { 96, 96, 96}, { 96, 96, 96},
+ { 95, 95, 95}, { 95, 95, 95}, { 95, 95, 95}, { 95, 95, 95}, { 94, 94, 94},
+ { 94, 94, 94}, { 94, 94, 94}, { 94, 94, 94}, { 93, 93, 93}, { 93, 93, 93},
+ { 93, 93, 93}, { 93, 93, 93}, { 92, 92, 92}, { 92, 92, 92}, { 92, 92, 92},
+ { 92, 92, 92}, { 91, 91, 91}, { 91, 91, 91}, { 91, 91, 91}, { 91, 91, 91},
+ { 90, 90, 90}, { 90, 90, 90}, { 90, 90, 90}, { 90, 90, 90}, { 89, 89, 89},
+ { 89, 89, 89}, { 89, 89, 89}, { 89, 89, 89}, { 88, 88, 88}, { 88, 88, 88},
+ { 88, 88, 88}, { 88, 88, 88}, { 87, 87, 87}, { 87, 87, 87}, { 87, 87, 87},
+ { 87, 87, 87}, { 86, 86, 86}, { 86, 86, 86}, { 86, 86, 86}, { 86, 86, 86},
+ { 85, 85, 85}, { 85, 85, 85}, { 85, 85, 85}, { 84, 84, 84}, { 84, 84, 84},
+ { 84, 84, 84}, { 84, 84, 84}, { 83, 83, 83}, { 83, 83, 83}, { 83, 83, 83},
+ { 83, 83, 83}, { 82, 82, 82}, { 82, 82, 82}, { 82, 82, 82}, { 82, 82, 82},
+ { 81, 81, 81}, { 81, 81, 81}, { 81, 81, 81}, { 81, 81, 81}, { 80, 80, 80},
+ { 80, 80, 80}, { 80, 80, 80}, { 80, 80, 80}, { 79, 79, 79}, { 79, 79, 79},
+ { 79, 79, 79}, { 79, 79, 79}, { 78, 78, 78}, { 78, 78, 78}, { 78, 78, 78},
+ { 78, 78, 78}, { 77, 77, 77}, { 77, 77, 77}, { 77, 77, 77}, { 77, 77, 77},
+ { 76, 76, 76}, { 76, 76, 76}, { 76, 76, 76}, { 76, 76, 76}, { 75, 75, 75},
+ { 75, 75, 75}, { 75, 75, 75}, { 75, 75, 75}, { 74, 74, 74}, { 74, 74, 74},
+ { 74, 74, 74}, { 74, 74, 74}, { 73, 73, 73}, { 73, 73, 73}, { 73, 73, 73},
+ { 72, 72, 72}, { 72, 72, 72}, { 72, 72, 72}, { 72, 72, 72}, { 71, 71, 71},
+ { 71, 71, 71}, { 71, 71, 71}, { 71, 71, 71}, { 70, 70, 70}, { 70, 70, 70},
+ { 70, 70, 70}, { 70, 70, 70}, { 69, 69, 69}, { 69, 69, 69}, { 69, 69, 69},
+ { 69, 69, 69}, { 68, 68, 68}, { 68, 68, 68}, { 68, 68, 68}, { 68, 68, 68},
+ { 67, 67, 67}, { 67, 67, 67}, { 67, 67, 67}, { 67, 67, 67}, { 66, 66, 66},
+ { 66, 66, 66}, { 66, 66, 66}, { 66, 66, 66}, { 65, 65, 65}, { 65, 65, 65},
+ { 65, 65, 65}, { 65, 65, 65}, { 64, 64, 64}, { 64, 64, 64}, { 64, 64, 64},
+ { 64, 64, 64}, { 63, 63, 63}, { 63, 63, 63}, { 63, 63, 63}, { 63, 63, 63},
+ { 62, 62, 62}, { 62, 62, 62}, { 62, 62, 62}, { 62, 62, 62}, { 61, 61, 61},
+ { 61, 61, 61}, { 61, 61, 61}, { 60, 60, 60}, { 60, 60, 60}, { 60, 60, 60},
+ { 60, 60, 60}, { 59, 59, 59}, { 59, 59, 59}, { 59, 59, 59}, { 59, 59, 59},
+ { 58, 58, 58}, { 58, 58, 58}, { 58, 58, 58}, { 58, 58, 58}, { 57, 57, 57},
+ { 57, 57, 57}, { 57, 57, 57}, { 57, 57, 57}, { 56, 56, 56}, { 56, 56, 56},
+ { 56, 56, 56}, { 56, 56, 56}, { 55, 55, 55}, { 55, 55, 55}, { 55, 55, 55},
+ { 55, 55, 55}, { 54, 54, 54}, { 54, 54, 54}, { 54, 54, 54}, { 54, 54, 54},
+ { 53, 53, 53}, { 53, 53, 53}, { 53, 53, 53}, { 53, 53, 53}, { 52, 52, 52},
+ { 52, 52, 52}, { 52, 52, 52}, { 52, 52, 52}, { 51, 51, 51}, { 51, 51, 51},
+ { 51, 51, 51}, { 51, 51, 51}, { 50, 50, 50}, { 50, 50, 50}, { 50, 50, 50},
+ { 50, 50, 50}, { 49, 49, 49}, { 49, 49, 49}, { 49, 49, 49}, { 48, 48, 48},
+ { 48, 48, 48}, { 48, 48, 48}, { 48, 48, 48}, { 47, 47, 47}, { 47, 47, 47},
+ { 47, 47, 47}, { 47, 47, 47}, { 46, 46, 46}, { 46, 46, 46}, { 46, 46, 46},
+ { 46, 46, 46}, { 45, 45, 45}, { 45, 45, 45}, { 45, 45, 45}, { 45, 45, 45},
+ { 44, 44, 44}, { 44, 44, 44}, { 44, 44, 44}, { 44, 44, 44}, { 43, 43, 43},
+ { 43, 43, 43}, { 43, 43, 43}, { 43, 43, 43}, { 42, 42, 42}, { 42, 42, 42},
+ { 42, 42, 42}, { 42, 42, 42}, { 41, 41, 41}, { 41, 41, 41}, { 41, 41, 41},
+ { 41, 41, 41}, { 40, 40, 40}, { 40, 40, 40}, { 40, 40, 40}, { 40, 40, 40},
+ { 39, 39, 39}, { 39, 39, 39}, { 39, 39, 39}, { 39, 39, 39}, { 38, 38, 38},
+ { 38, 38, 38}, { 38, 38, 38}, { 38, 38, 38}, { 37, 37, 37}, { 37, 37, 37},
+ { 37, 37, 37}, { 37, 37, 37}, { 36, 36, 36}, { 36, 36, 36}, { 36, 36, 36},
+ { 35, 35, 35}, { 35, 35, 35}, { 35, 35, 35}, { 35, 35, 35}, { 34, 34, 34},
+ { 34, 34, 34}, { 34, 34, 34}, { 34, 34, 34}, { 33, 33, 33}, { 33, 33, 33},
+ { 33, 33, 33}, { 33, 33, 33}, { 32, 32, 32}, { 32, 32, 32}, { 32, 32, 32},
+ { 32, 32, 32}, { 31, 31, 31}, { 31, 31, 31}, { 31, 31, 31}, { 31, 31, 31},
+ { 30, 30, 30}, { 30, 30, 30}, { 30, 30, 30}, { 30, 30, 30}, { 29, 29, 29},
+ { 29, 29, 29}, { 29, 29, 29}, { 29, 29, 29}, { 28, 28, 28}, { 28, 28, 28},
+ { 28, 28, 28}, { 28, 28, 28}, { 27, 27, 27}, { 27, 27, 27}, { 27, 27, 27},
+ { 27, 27, 27}, { 26, 26, 26}, { 26, 26, 26}, { 26, 26, 26}, { 26, 26, 26},
+ { 25, 25, 25}, { 25, 25, 25}, { 25, 25, 25}, { 25, 25, 25}, { 24, 24, 24},
+ { 24, 24, 24}, { 24, 24, 24}, { 23, 23, 23}, { 23, 23, 23}, { 23, 23, 23},
+ { 23, 23, 23}, { 22, 22, 22}, { 22, 22, 22}, { 22, 22, 22}, { 22, 22, 22},
+ { 21, 21, 21}, { 21, 21, 21}, { 21, 21, 21}, { 21, 21, 21}, { 20, 20, 20},
+ { 20, 20, 20}, { 20, 20, 20}, { 20, 20, 20}, { 19, 19, 19}, { 19, 19, 19},
+ { 19, 19, 19}, { 19, 19, 19}, { 18, 18, 18}, { 18, 18, 18}, { 18, 18, 18},
+ { 18, 18, 18}, { 17, 17, 17}, { 17, 17, 17}, { 17, 17, 17}, { 17, 17, 17},
+ { 16, 16, 16}, { 16, 16, 16}, { 16, 16, 16}, { 16, 16, 16}, { 15, 15, 15},
+ { 15, 15, 15}, { 15, 15, 15}, { 15, 15, 15}, { 14, 14, 14}, { 14, 14, 14},
+ { 14, 14, 14}, { 14, 14, 14}, { 13, 13, 13}, { 13, 13, 13}, { 13, 13, 13},
+ { 13, 13, 13}, { 12, 12, 12}, { 12, 12, 12}, { 12, 12, 12}, { 11, 11, 11},
+ { 11, 11, 11}, { 11, 11, 11}, { 11, 11, 11}, { 10, 10, 10}, { 10, 10, 10},
+ { 10, 10, 10}, { 10, 10, 10}, { 9, 9, 9}, { 9, 9, 9}, { 9, 9, 9},
+ { 9, 9, 9}, { 8, 8, 8}, { 8, 8, 8}, { 8, 8, 8}, { 8, 8, 8},
+ { 7, 7, 7}, { 7, 7, 7}, { 7, 7, 7}, { 7, 7, 7}, { 6, 6, 6},
+ { 6, 6, 6}, { 6, 6, 6}, { 6, 6, 6}, { 5, 5, 5}, { 5, 5, 5},
+ { 5, 5, 5}, { 5, 5, 5}, { 4, 4, 4}, { 4, 4, 4}, { 4, 4, 4},
+ { 4, 4, 4}, { 3, 3, 3}, { 3, 3, 3}, { 3, 3, 3}, { 3, 3, 3},
+ { 2, 2, 2}, { 2, 2, 2}, { 2, 2, 2}, { 2, 2, 2}, { 1, 1, 1},
+ { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 0, 0, 0}, { 0, 0, 0}
+};
+
+const rgb_t hot_colormap[1000] = {
+ { 11, 0, 0}, { 11, 0, 0}, { 12, 0, 0}, { 13, 0, 0}, { 13, 0, 0},
+ { 14, 0, 0}, { 15, 0, 0}, { 15, 0, 0}, { 16, 0, 0}, { 17, 0, 0},
+ { 17, 0, 0}, { 18, 0, 0}, { 19, 0, 0}, { 19, 0, 0}, { 20, 0, 0},
+ { 21, 0, 0}, { 21, 0, 0}, { 22, 0, 0}, { 23, 0, 0}, { 23, 0, 0},
+ { 24, 0, 0}, { 25, 0, 0}, { 25, 0, 0}, { 26, 0, 0}, { 27, 0, 0},
+ { 27, 0, 0}, { 28, 0, 0}, { 29, 0, 0}, { 29, 0, 0}, { 30, 0, 0},
+ { 31, 0, 0}, { 31, 0, 0}, { 32, 0, 0}, { 33, 0, 0}, { 33, 0, 0},
+ { 34, 0, 0}, { 35, 0, 0}, { 35, 0, 0}, { 36, 0, 0}, { 37, 0, 0},
+ { 37, 0, 0}, { 38, 0, 0}, { 39, 0, 0}, { 39, 0, 0}, { 40, 0, 0},
+ { 41, 0, 0}, { 41, 0, 0}, { 42, 0, 0}, { 43, 0, 0}, { 43, 0, 0},
+ { 44, 0, 0}, { 45, 0, 0}, { 45, 0, 0}, { 46, 0, 0}, { 47, 0, 0},
+ { 47, 0, 0}, { 48, 0, 0}, { 49, 0, 0}, { 49, 0, 0}, { 50, 0, 0},
+ { 51, 0, 0}, { 51, 0, 0}, { 52, 0, 0}, { 53, 0, 0}, { 54, 0, 0},
+ { 54, 0, 0}, { 55, 0, 0}, { 56, 0, 0}, { 56, 0, 0}, { 57, 0, 0},
+ { 58, 0, 0}, { 58, 0, 0}, { 59, 0, 0}, { 60, 0, 0}, { 60, 0, 0},
+ { 61, 0, 0}, { 62, 0, 0}, { 62, 0, 0}, { 63, 0, 0}, { 64, 0, 0},
+ { 64, 0, 0}, { 65, 0, 0}, { 66, 0, 0}, { 66, 0, 0}, { 67, 0, 0},
+ { 68, 0, 0}, { 68, 0, 0}, { 69, 0, 0}, { 70, 0, 0}, { 70, 0, 0},
+ { 71, 0, 0}, { 72, 0, 0}, { 72, 0, 0}, { 73, 0, 0}, { 74, 0, 0},
+ { 74, 0, 0}, { 75, 0, 0}, { 76, 0, 0}, { 76, 0, 0}, { 77, 0, 0},
+ { 78, 0, 0}, { 78, 0, 0}, { 79, 0, 0}, { 80, 0, 0}, { 80, 0, 0},
+ { 81, 0, 0}, { 82, 0, 0}, { 82, 0, 0}, { 83, 0, 0}, { 84, 0, 0},
+ { 84, 0, 0}, { 85, 0, 0}, { 86, 0, 0}, { 86, 0, 0}, { 87, 0, 0},
+ { 88, 0, 0}, { 88, 0, 0}, { 89, 0, 0}, { 90, 0, 0}, { 90, 0, 0},
+ { 91, 0, 0}, { 92, 0, 0}, { 92, 0, 0}, { 93, 0, 0}, { 94, 0, 0},
+ { 94, 0, 0}, { 95, 0, 0}, { 96, 0, 0}, { 96, 0, 0}, { 97, 0, 0},
+ { 98, 0, 0}, { 98, 0, 0}, { 99, 0, 0}, {100, 0, 0}, {100, 0, 0},
+ {101, 0, 0}, {102, 0, 0}, {102, 0, 0}, {103, 0, 0}, {104, 0, 0},
+ {104, 0, 0}, {105, 0, 0}, {106, 0, 0}, {106, 0, 0}, {107, 0, 0},
+ {108, 0, 0}, {108, 0, 0}, {109, 0, 0}, {110, 0, 0}, {110, 0, 0},
+ {111, 0, 0}, {112, 0, 0}, {112, 0, 0}, {113, 0, 0}, {114, 0, 0},
+ {114, 0, 0}, {115, 0, 0}, {116, 0, 0}, {116, 0, 0}, {117, 0, 0},
+ {118, 0, 0}, {119, 0, 0}, {119, 0, 0}, {120, 0, 0}, {121, 0, 0},
+ {121, 0, 0}, {122, 0, 0}, {123, 0, 0}, {123, 0, 0}, {124, 0, 0},
+ {125, 0, 0}, {125, 0, 0}, {126, 0, 0}, {127, 0, 0}, {127, 0, 0},
+ {128, 0, 0}, {129, 0, 0}, {129, 0, 0}, {130, 0, 0}, {131, 0, 0},
+ {131, 0, 0}, {132, 0, 0}, {133, 0, 0}, {133, 0, 0}, {134, 0, 0},
+ {135, 0, 0}, {135, 0, 0}, {136, 0, 0}, {137, 0, 0}, {137, 0, 0},
+ {138, 0, 0}, {139, 0, 0}, {139, 0, 0}, {140, 0, 0}, {141, 0, 0},
+ {141, 0, 0}, {142, 0, 0}, {143, 0, 0}, {143, 0, 0}, {144, 0, 0},
+ {145, 0, 0}, {145, 0, 0}, {146, 0, 0}, {147, 0, 0}, {147, 0, 0},
+ {148, 0, 0}, {149, 0, 0}, {149, 0, 0}, {150, 0, 0}, {151, 0, 0},
+ {151, 0, 0}, {152, 0, 0}, {153, 0, 0}, {153, 0, 0}, {154, 0, 0},
+ {155, 0, 0}, {155, 0, 0}, {156, 0, 0}, {157, 0, 0}, {157, 0, 0},
+ {158, 0, 0}, {159, 0, 0}, {159, 0, 0}, {160, 0, 0}, {161, 0, 0},
+ {161, 0, 0}, {162, 0, 0}, {163, 0, 0}, {163, 0, 0}, {164, 0, 0},
+ {165, 0, 0}, {165, 0, 0}, {166, 0, 0}, {167, 0, 0}, {167, 0, 0},
+ {168, 0, 0}, {169, 0, 0}, {169, 0, 0}, {170, 0, 0}, {171, 0, 0},
+ {171, 0, 0}, {172, 0, 0}, {173, 0, 0}, {173, 0, 0}, {174, 0, 0},
+ {175, 0, 0}, {175, 0, 0}, {176, 0, 0}, {177, 0, 0}, {177, 0, 0},
+ {178, 0, 0}, {179, 0, 0}, {179, 0, 0}, {180, 0, 0}, {181, 0, 0},
+ {181, 0, 0}, {182, 0, 0}, {183, 0, 0}, {183, 0, 0}, {184, 0, 0},
+ {185, 0, 0}, {186, 0, 0}, {186, 0, 0}, {187, 0, 0}, {188, 0, 0},
+ {188, 0, 0}, {189, 0, 0}, {190, 0, 0}, {190, 0, 0}, {191, 0, 0},
+ {192, 0, 0}, {192, 0, 0}, {193, 0, 0}, {194, 0, 0}, {194, 0, 0},
+ {195, 0, 0}, {196, 0, 0}, {196, 0, 0}, {197, 0, 0}, {198, 0, 0},
+ {198, 0, 0}, {199, 0, 0}, {200, 0, 0}, {200, 0, 0}, {201, 0, 0},
+ {202, 0, 0}, {202, 0, 0}, {203, 0, 0}, {204, 0, 0}, {204, 0, 0},
+ {205, 0, 0}, {206, 0, 0}, {206, 0, 0}, {207, 0, 0}, {208, 0, 0},
+ {208, 0, 0}, {209, 0, 0}, {210, 0, 0}, {210, 0, 0}, {211, 0, 0},
+ {212, 0, 0}, {212, 0, 0}, {213, 0, 0}, {214, 0, 0}, {214, 0, 0},
+ {215, 0, 0}, {216, 0, 0}, {216, 0, 0}, {217, 0, 0}, {218, 0, 0},
+ {218, 0, 0}, {219, 0, 0}, {220, 0, 0}, {220, 0, 0}, {221, 0, 0},
+ {222, 0, 0}, {222, 0, 0}, {223, 0, 0}, {224, 0, 0}, {224, 0, 0},
+ {225, 0, 0}, {226, 0, 0}, {226, 0, 0}, {227, 0, 0}, {228, 0, 0},
+ {228, 0, 0}, {229, 0, 0}, {230, 0, 0}, {230, 0, 0}, {231, 0, 0},
+ {232, 0, 0}, {232, 0, 0}, {233, 0, 0}, {234, 0, 0}, {234, 0, 0},
+ {235, 0, 0}, {236, 0, 0}, {236, 0, 0}, {237, 0, 0}, {238, 0, 0},
+ {238, 0, 0}, {239, 0, 0}, {240, 0, 0}, {240, 0, 0}, {241, 0, 0},
+ {242, 0, 0}, {242, 0, 0}, {243, 0, 0}, {244, 0, 0}, {244, 0, 0},
+ {245, 0, 0}, {246, 0, 0}, {246, 0, 0}, {247, 0, 0}, {248, 0, 0},
+ {248, 0, 0}, {249, 0, 0}, {250, 0, 0}, {251, 0, 0}, {251, 0, 0},
+ {252, 0, 0}, {253, 0, 0}, {253, 0, 0}, {254, 0, 0}, {255, 0, 0},
+ {255, 0, 0}, {255, 1, 0}, {255, 2, 0}, {255, 2, 0}, {255, 3, 0},
+ {255, 4, 0}, {255, 4, 0}, {255, 5, 0}, {255, 6, 0}, {255, 6, 0},
+ {255, 7, 0}, {255, 8, 0}, {255, 8, 0}, {255, 9, 0}, {255, 10, 0},
+ {255, 10, 0}, {255, 11, 0}, {255, 12, 0}, {255, 12, 0}, {255, 13, 0},
+ {255, 14, 0}, {255, 14, 0}, {255, 15, 0}, {255, 16, 0}, {255, 16, 0},
+ {255, 17, 0}, {255, 18, 0}, {255, 18, 0}, {255, 19, 0}, {255, 20, 0},
+ {255, 20, 0}, {255, 21, 0}, {255, 22, 0}, {255, 22, 0}, {255, 23, 0},
+ {255, 24, 0}, {255, 24, 0}, {255, 25, 0}, {255, 26, 0}, {255, 26, 0},
+ {255, 27, 0}, {255, 28, 0}, {255, 28, 0}, {255, 29, 0}, {255, 30, 0},
+ {255, 30, 0}, {255, 31, 0}, {255, 32, 0}, {255, 32, 0}, {255, 33, 0},
+ {255, 34, 0}, {255, 34, 0}, {255, 35, 0}, {255, 36, 0}, {255, 36, 0},
+ {255, 37, 0}, {255, 38, 0}, {255, 38, 0}, {255, 39, 0}, {255, 40, 0},
+ {255, 40, 0}, {255, 41, 0}, {255, 42, 0}, {255, 42, 0}, {255, 43, 0},
+ {255, 44, 0}, {255, 44, 0}, {255, 45, 0}, {255, 46, 0}, {255, 46, 0},
+ {255, 47, 0}, {255, 48, 0}, {255, 48, 0}, {255, 49, 0}, {255, 50, 0},
+ {255, 50, 0}, {255, 51, 0}, {255, 52, 0}, {255, 52, 0}, {255, 53, 0},
+ {255, 54, 0}, {255, 54, 0}, {255, 55, 0}, {255, 56, 0}, {255, 56, 0},
+ {255, 57, 0}, {255, 58, 0}, {255, 58, 0}, {255, 59, 0}, {255, 60, 0},
+ {255, 60, 0}, {255, 61, 0}, {255, 62, 0}, {255, 63, 0}, {255, 63, 0},
+ {255, 64, 0}, {255, 65, 0}, {255, 65, 0}, {255, 66, 0}, {255, 67, 0},
+ {255, 67, 0}, {255, 68, 0}, {255, 69, 0}, {255, 69, 0}, {255, 70, 0},
+ {255, 71, 0}, {255, 71, 0}, {255, 72, 0}, {255, 73, 0}, {255, 73, 0},
+ {255, 74, 0}, {255, 75, 0}, {255, 75, 0}, {255, 76, 0}, {255, 77, 0},
+ {255, 77, 0}, {255, 78, 0}, {255, 79, 0}, {255, 79, 0}, {255, 80, 0},
+ {255, 81, 0}, {255, 81, 0}, {255, 82, 0}, {255, 83, 0}, {255, 83, 0},
+ {255, 84, 0}, {255, 85, 0}, {255, 85, 0}, {255, 86, 0}, {255, 87, 0},
+ {255, 87, 0}, {255, 88, 0}, {255, 89, 0}, {255, 89, 0}, {255, 90, 0},
+ {255, 91, 0}, {255, 91, 0}, {255, 92, 0}, {255, 93, 0}, {255, 93, 0},
+ {255, 94, 0}, {255, 95, 0}, {255, 95, 0}, {255, 96, 0}, {255, 97, 0},
+ {255, 97, 0}, {255, 98, 0}, {255, 99, 0}, {255, 99, 0}, {255, 100, 0},
+ {255, 101, 0}, {255, 101, 0}, {255, 102, 0}, {255, 103, 0}, {255, 103, 0},
+ {255, 104, 0}, {255, 105, 0}, {255, 105, 0}, {255, 106, 0}, {255, 107, 0},
+ {255, 107, 0}, {255, 108, 0}, {255, 109, 0}, {255, 109, 0}, {255, 110, 0},
+ {255, 111, 0}, {255, 111, 0}, {255, 112, 0}, {255, 113, 0}, {255, 113, 0},
+ {255, 114, 0}, {255, 115, 0}, {255, 115, 0}, {255, 116, 0}, {255, 117, 0},
+ {255, 117, 0}, {255, 118, 0}, {255, 119, 0}, {255, 119, 0}, {255, 120, 0},
+ {255, 121, 0}, {255, 121, 0}, {255, 122, 0}, {255, 123, 0}, {255, 123, 0},
+ {255, 124, 0}, {255, 125, 0}, {255, 125, 0}, {255, 126, 0}, {255, 127, 0},
+ {255, 128, 0}, {255, 128, 0}, {255, 129, 0}, {255, 130, 0}, {255, 130, 0},
+ {255, 131, 0}, {255, 132, 0}, {255, 132, 0}, {255, 133, 0}, {255, 134, 0},
+ {255, 134, 0}, {255, 135, 0}, {255, 136, 0}, {255, 136, 0}, {255, 137, 0},
+ {255, 138, 0}, {255, 138, 0}, {255, 139, 0}, {255, 140, 0}, {255, 140, 0},
+ {255, 141, 0}, {255, 142, 0}, {255, 142, 0}, {255, 143, 0}, {255, 144, 0},
+ {255, 144, 0}, {255, 145, 0}, {255, 146, 0}, {255, 146, 0}, {255, 147, 0},
+ {255, 148, 0}, {255, 148, 0}, {255, 149, 0}, {255, 150, 0}, {255, 150, 0},
+ {255, 151, 0}, {255, 152, 0}, {255, 152, 0}, {255, 153, 0}, {255, 154, 0},
+ {255, 154, 0}, {255, 155, 0}, {255, 156, 0}, {255, 156, 0}, {255, 157, 0},
+ {255, 158, 0}, {255, 158, 0}, {255, 159, 0}, {255, 160, 0}, {255, 160, 0},
+ {255, 161, 0}, {255, 162, 0}, {255, 162, 0}, {255, 163, 0}, {255, 164, 0},
+ {255, 164, 0}, {255, 165, 0}, {255, 166, 0}, {255, 166, 0}, {255, 167, 0},
+ {255, 168, 0}, {255, 168, 0}, {255, 169, 0}, {255, 170, 0}, {255, 170, 0},
+ {255, 171, 0}, {255, 172, 0}, {255, 172, 0}, {255, 173, 0}, {255, 174, 0},
+ {255, 174, 0}, {255, 175, 0}, {255, 176, 0}, {255, 176, 0}, {255, 177, 0},
+ {255, 178, 0}, {255, 178, 0}, {255, 179, 0}, {255, 180, 0}, {255, 180, 0},
+ {255, 181, 0}, {255, 182, 0}, {255, 182, 0}, {255, 183, 0}, {255, 184, 0},
+ {255, 184, 0}, {255, 185, 0}, {255, 186, 0}, {255, 186, 0}, {255, 187, 0},
+ {255, 188, 0}, {255, 188, 0}, {255, 189, 0}, {255, 190, 0}, {255, 190, 0},
+ {255, 191, 0}, {255, 192, 0}, {255, 192, 0}, {255, 193, 0}, {255, 194, 0},
+ {255, 195, 0}, {255, 195, 0}, {255, 196, 0}, {255, 197, 0}, {255, 197, 0},
+ {255, 198, 0}, {255, 199, 0}, {255, 199, 0}, {255, 200, 0}, {255, 201, 0},
+ {255, 201, 0}, {255, 202, 0}, {255, 203, 0}, {255, 203, 0}, {255, 204, 0},
+ {255, 205, 0}, {255, 205, 0}, {255, 206, 0}, {255, 207, 0}, {255, 207, 0},
+ {255, 208, 0}, {255, 209, 0}, {255, 209, 0}, {255, 210, 0}, {255, 211, 0},
+ {255, 211, 0}, {255, 212, 0}, {255, 213, 0}, {255, 213, 0}, {255, 214, 0},
+ {255, 215, 0}, {255, 215, 0}, {255, 216, 0}, {255, 217, 0}, {255, 217, 0},
+ {255, 218, 0}, {255, 219, 0}, {255, 219, 0}, {255, 220, 0}, {255, 221, 0},
+ {255, 221, 0}, {255, 222, 0}, {255, 223, 0}, {255, 223, 0}, {255, 224, 0},
+ {255, 225, 0}, {255, 225, 0}, {255, 226, 0}, {255, 227, 0}, {255, 227, 0},
+ {255, 228, 0}, {255, 229, 0}, {255, 229, 0}, {255, 230, 0}, {255, 231, 0},
+ {255, 231, 0}, {255, 232, 0}, {255, 233, 0}, {255, 233, 0}, {255, 234, 0},
+ {255, 235, 0}, {255, 235, 0}, {255, 236, 0}, {255, 237, 0}, {255, 237, 0},
+ {255, 238, 0}, {255, 239, 0}, {255, 239, 0}, {255, 240, 0}, {255, 241, 0},
+ {255, 241, 0}, {255, 242, 0}, {255, 243, 0}, {255, 243, 0}, {255, 244, 0},
+ {255, 245, 0}, {255, 245, 0}, {255, 246, 0}, {255, 247, 0}, {255, 247, 0},
+ {255, 248, 0}, {255, 249, 0}, {255, 249, 0}, {255, 250, 0}, {255, 251, 0},
+ {255, 251, 0}, {255, 252, 0}, {255, 253, 0}, {255, 253, 0}, {255, 254, 0},
+ {255, 255, 0}, {255, 255, 1}, {255, 255, 2}, {255, 255, 3}, {255, 255, 4},
+ {255, 255, 5}, {255, 255, 6}, {255, 255, 7}, {255, 255, 8}, {255, 255, 9},
+ {255, 255, 10}, {255, 255, 11}, {255, 255, 12}, {255, 255, 13}, {255, 255, 14},
+ {255, 255, 15}, {255, 255, 16}, {255, 255, 17}, {255, 255, 18}, {255, 255, 19},
+ {255, 255, 20}, {255, 255, 21}, {255, 255, 22}, {255, 255, 23}, {255, 255, 24},
+ {255, 255, 25}, {255, 255, 26}, {255, 255, 27}, {255, 255, 28}, {255, 255, 29},
+ {255, 255, 30}, {255, 255, 31}, {255, 255, 32}, {255, 255, 33}, {255, 255, 34},
+ {255, 255, 35}, {255, 255, 36}, {255, 255, 37}, {255, 255, 38}, {255, 255, 39},
+ {255, 255, 40}, {255, 255, 41}, {255, 255, 42}, {255, 255, 43}, {255, 255, 44},
+ {255, 255, 45}, {255, 255, 46}, {255, 255, 47}, {255, 255, 48}, {255, 255, 49},
+ {255, 255, 50}, {255, 255, 51}, {255, 255, 52}, {255, 255, 53}, {255, 255, 54},
+ {255, 255, 55}, {255, 255, 56}, {255, 255, 57}, {255, 255, 58}, {255, 255, 59},
+ {255, 255, 60}, {255, 255, 61}, {255, 255, 62}, {255, 255, 63}, {255, 255, 64},
+ {255, 255, 65}, {255, 255, 66}, {255, 255, 67}, {255, 255, 68}, {255, 255, 69},
+ {255, 255, 70}, {255, 255, 71}, {255, 255, 72}, {255, 255, 73}, {255, 255, 74},
+ {255, 255, 75}, {255, 255, 76}, {255, 255, 77}, {255, 255, 78}, {255, 255, 79},
+ {255, 255, 80}, {255, 255, 81}, {255, 255, 82}, {255, 255, 83}, {255, 255, 84},
+ {255, 255, 85}, {255, 255, 86}, {255, 255, 87}, {255, 255, 88}, {255, 255, 89},
+ {255, 255, 90}, {255, 255, 91}, {255, 255, 92}, {255, 255, 93}, {255, 255, 94},
+ {255, 255, 95}, {255, 255, 96}, {255, 255, 97}, {255, 255, 98}, {255, 255, 99},
+ {255, 255, 100}, {255, 255, 101}, {255, 255, 102}, {255, 255, 103}, {255, 255, 104},
+ {255, 255, 105}, {255, 255, 106}, {255, 255, 107}, {255, 255, 108}, {255, 255, 109},
+ {255, 255, 110}, {255, 255, 111}, {255, 255, 112}, {255, 255, 113}, {255, 255, 114},
+ {255, 255, 115}, {255, 255, 116}, {255, 255, 117}, {255, 255, 118}, {255, 255, 119},
+ {255, 255, 120}, {255, 255, 121}, {255, 255, 122}, {255, 255, 123}, {255, 255, 124},
+ {255, 255, 125}, {255, 255, 126}, {255, 255, 127}, {255, 255, 128}, {255, 255, 129},
+ {255, 255, 130}, {255, 255, 131}, {255, 255, 132}, {255, 255, 133}, {255, 255, 134},
+ {255, 255, 135}, {255, 255, 136}, {255, 255, 137}, {255, 255, 138}, {255, 255, 139},
+ {255, 255, 140}, {255, 255, 141}, {255, 255, 142}, {255, 255, 143}, {255, 255, 144},
+ {255, 255, 145}, {255, 255, 146}, {255, 255, 147}, {255, 255, 148}, {255, 255, 149},
+ {255, 255, 150}, {255, 255, 151}, {255, 255, 152}, {255, 255, 153}, {255, 255, 154},
+ {255, 255, 155}, {255, 255, 157}, {255, 255, 158}, {255, 255, 159}, {255, 255, 160},
+ {255, 255, 161}, {255, 255, 162}, {255, 255, 163}, {255, 255, 164}, {255, 255, 165},
+ {255, 255, 166}, {255, 255, 167}, {255, 255, 168}, {255, 255, 169}, {255, 255, 170},
+ {255, 255, 171}, {255, 255, 172}, {255, 255, 173}, {255, 255, 174}, {255, 255, 175},
+ {255, 255, 176}, {255, 255, 177}, {255, 255, 178}, {255, 255, 179}, {255, 255, 180},
+ {255, 255, 181}, {255, 255, 182}, {255, 255, 183}, {255, 255, 184}, {255, 255, 185},
+ {255, 255, 186}, {255, 255, 187}, {255, 255, 188}, {255, 255, 189}, {255, 255, 190},
+ {255, 255, 191}, {255, 255, 192}, {255, 255, 193}, {255, 255, 194}, {255, 255, 195},
+ {255, 255, 196}, {255, 255, 197}, {255, 255, 198}, {255, 255, 199}, {255, 255, 200},
+ {255, 255, 201}, {255, 255, 202}, {255, 255, 203}, {255, 255, 204}, {255, 255, 205},
+ {255, 255, 206}, {255, 255, 207}, {255, 255, 208}, {255, 255, 209}, {255, 255, 210},
+ {255, 255, 211}, {255, 255, 212}, {255, 255, 213}, {255, 255, 214}, {255, 255, 215},
+ {255, 255, 216}, {255, 255, 217}, {255, 255, 218}, {255, 255, 219}, {255, 255, 220},
+ {255, 255, 221}, {255, 255, 222}, {255, 255, 223}, {255, 255, 224}, {255, 255, 225},
+ {255, 255, 226}, {255, 255, 227}, {255, 255, 228}, {255, 255, 229}, {255, 255, 230},
+ {255, 255, 231}, {255, 255, 232}, {255, 255, 233}, {255, 255, 234}, {255, 255, 235},
+ {255, 255, 236}, {255, 255, 237}, {255, 255, 238}, {255, 255, 239}, {255, 255, 240},
+ {255, 255, 241}, {255, 255, 242}, {255, 255, 243}, {255, 255, 244}, {255, 255, 245},
+ {255, 255, 246}, {255, 255, 247}, {255, 255, 248}, {255, 255, 249}, {255, 255, 250},
+ {255, 255, 251}, {255, 255, 252}, {255, 255, 253}, {255, 255, 254}, {255, 255, 255}
+};
+
+const rgb_t hsv_colormap[1000] = {
+ {255, 0, 0}, {255, 2, 0}, {255, 3, 0}, {255, 5, 0}, {255, 6, 0},
+ {255, 8, 0}, {255, 9, 0}, {255, 11, 0}, {255, 12, 0}, {255, 14, 0},
+ {255, 15, 0}, {255, 17, 0}, {255, 18, 0}, {255, 20, 0}, {255, 21, 0},
+ {255, 23, 0}, {255, 24, 0}, {255, 26, 0}, {255, 27, 0}, {255, 29, 0},
+ {255, 30, 0}, {255, 32, 0}, {255, 33, 0}, {255, 35, 0}, {255, 36, 0},
+ {255, 38, 0}, {255, 39, 0}, {255, 41, 0}, {255, 42, 0}, {255, 44, 0},
+ {255, 45, 0}, {255, 47, 0}, {255, 48, 0}, {255, 50, 0}, {255, 51, 0},
+ {255, 53, 0}, {255, 54, 0}, {255, 56, 0}, {255, 57, 0}, {255, 59, 0},
+ {255, 60, 0}, {255, 62, 0}, {255, 63, 0}, {255, 65, 0}, {255, 66, 0},
+ {255, 68, 0}, {255, 69, 0}, {255, 71, 0}, {255, 72, 0}, {255, 74, 0},
+ {255, 75, 0}, {255, 77, 0}, {255, 78, 0}, {255, 80, 0}, {255, 81, 0},
+ {255, 83, 0}, {255, 84, 0}, {255, 86, 0}, {255, 87, 0}, {255, 89, 0},
+ {255, 90, 0}, {255, 92, 0}, {255, 93, 0}, {255, 95, 0}, {255, 96, 0},
+ {255, 98, 0}, {255, 100, 0}, {255, 101, 0}, {255, 103, 0}, {255, 104, 0},
+ {255, 106, 0}, {255, 107, 0}, {255, 109, 0}, {255, 110, 0}, {255, 112, 0},
+ {255, 113, 0}, {255, 115, 0}, {255, 116, 0}, {255, 118, 0}, {255, 119, 0},
+ {255, 121, 0}, {255, 122, 0}, {255, 124, 0}, {255, 125, 0}, {255, 127, 0},
+ {255, 128, 0}, {255, 130, 0}, {255, 131, 0}, {255, 133, 0}, {255, 134, 0},
+ {255, 136, 0}, {255, 137, 0}, {255, 139, 0}, {255, 140, 0}, {255, 142, 0},
+ {255, 143, 0}, {255, 145, 0}, {255, 146, 0}, {255, 148, 0}, {255, 149, 0},
+ {255, 151, 0}, {255, 152, 0}, {255, 154, 0}, {255, 155, 0}, {255, 157, 0},
+ {255, 158, 0}, {255, 160, 0}, {255, 161, 0}, {255, 163, 0}, {255, 164, 0},
+ {255, 166, 0}, {255, 167, 0}, {255, 169, 0}, {255, 170, 0}, {255, 172, 0},
+ {255, 173, 0}, {255, 175, 0}, {255, 176, 0}, {255, 178, 0}, {255, 179, 0},
+ {255, 181, 0}, {255, 182, 0}, {255, 184, 0}, {255, 185, 0}, {255, 187, 0},
+ {255, 188, 0}, {255, 190, 0}, {255, 191, 0}, {255, 193, 0}, {255, 194, 0},
+ {255, 196, 0}, {255, 197, 0}, {255, 199, 0}, {255, 201, 0}, {255, 202, 0},
+ {255, 204, 0}, {255, 205, 0}, {255, 207, 0}, {255, 208, 0}, {255, 210, 0},
+ {255, 211, 0}, {255, 213, 0}, {255, 214, 0}, {255, 216, 0}, {255, 217, 0},
+ {255, 219, 0}, {255, 220, 0}, {255, 222, 0}, {255, 223, 0}, {255, 225, 0},
+ {255, 226, 0}, {255, 228, 0}, {255, 229, 0}, {255, 231, 0}, {255, 232, 0},
+ {255, 234, 0}, {255, 235, 0}, {255, 237, 0}, {255, 238, 0}, {255, 239, 0},
+ {254, 240, 0}, {254, 242, 0}, {253, 243, 0}, {253, 244, 0}, {252, 245, 0},
+ {252, 246, 0}, {251, 247, 0}, {251, 248, 0}, {250, 249, 0}, {250, 250, 0},
+ {249, 251, 0}, {249, 252, 0}, {248, 253, 0}, {248, 254, 0}, {247, 255, 0},
+ {246, 255, 0}, {245, 255, 0}, {243, 255, 0}, {242, 255, 0}, {240, 255, 0},
+ {239, 255, 0}, {237, 255, 0}, {236, 255, 0}, {234, 255, 0}, {233, 255, 0},
+ {231, 255, 0}, {230, 255, 0}, {228, 255, 0}, {227, 255, 0}, {225, 255, 0},
+ {224, 255, 0}, {222, 255, 0}, {221, 255, 0}, {219, 255, 0}, {218, 255, 0},
+ {216, 255, 0}, {215, 255, 0}, {213, 255, 0}, {211, 255, 0}, {210, 255, 0},
+ {208, 255, 0}, {207, 255, 0}, {205, 255, 0}, {204, 255, 0}, {202, 255, 0},
+ {201, 255, 0}, {199, 255, 0}, {198, 255, 0}, {196, 255, 0}, {195, 255, 0},
+ {193, 255, 0}, {192, 255, 0}, {190, 255, 0}, {189, 255, 0}, {187, 255, 0},
+ {186, 255, 0}, {184, 255, 0}, {183, 255, 0}, {181, 255, 0}, {180, 255, 0},
+ {178, 255, 0}, {177, 255, 0}, {175, 255, 0}, {174, 255, 0}, {172, 255, 0},
+ {171, 255, 0}, {169, 255, 0}, {168, 255, 0}, {166, 255, 0}, {165, 255, 0},
+ {163, 255, 0}, {162, 255, 0}, {160, 255, 0}, {159, 255, 0}, {157, 255, 0},
+ {156, 255, 0}, {154, 255, 0}, {153, 255, 0}, {151, 255, 0}, {150, 255, 0},
+ {148, 255, 0}, {147, 255, 0}, {145, 255, 0}, {144, 255, 0}, {142, 255, 0},
+ {141, 255, 0}, {139, 255, 0}, {138, 255, 0}, {136, 255, 0}, {135, 255, 0},
+ {133, 255, 0}, {132, 255, 0}, {130, 255, 0}, {129, 255, 0}, {127, 255, 0},
+ {126, 255, 0}, {124, 255, 0}, {123, 255, 0}, {121, 255, 0}, {120, 255, 0},
+ {118, 255, 0}, {117, 255, 0}, {115, 255, 0}, {114, 255, 0}, {112, 255, 0},
+ {110, 255, 0}, {109, 255, 0}, {107, 255, 0}, {106, 255, 0}, {104, 255, 0},
+ {103, 255, 0}, {101, 255, 0}, {100, 255, 0}, { 98, 255, 0}, { 97, 255, 0},
+ { 95, 255, 0}, { 94, 255, 0}, { 92, 255, 0}, { 91, 255, 0}, { 89, 255, 0},
+ { 88, 255, 0}, { 86, 255, 0}, { 85, 255, 0}, { 83, 255, 0}, { 82, 255, 0},
+ { 80, 255, 0}, { 79, 255, 0}, { 77, 255, 0}, { 76, 255, 0}, { 74, 255, 0},
+ { 73, 255, 0}, { 71, 255, 0}, { 70, 255, 0}, { 68, 255, 0}, { 67, 255, 0},
+ { 65, 255, 0}, { 64, 255, 0}, { 62, 255, 0}, { 61, 255, 0}, { 59, 255, 0},
+ { 58, 255, 0}, { 56, 255, 0}, { 55, 255, 0}, { 53, 255, 0}, { 52, 255, 0},
+ { 50, 255, 0}, { 49, 255, 0}, { 47, 255, 0}, { 46, 255, 0}, { 44, 255, 0},
+ { 43, 255, 0}, { 41, 255, 0}, { 40, 255, 0}, { 38, 255, 0}, { 37, 255, 0},
+ { 35, 255, 0}, { 34, 255, 0}, { 32, 255, 0}, { 31, 255, 0}, { 29, 255, 0},
+ { 28, 255, 0}, { 26, 255, 0}, { 25, 255, 0}, { 23, 255, 0}, { 22, 255, 0},
+ { 20, 255, 0}, { 19, 255, 0}, { 17, 255, 0}, { 16, 255, 0}, { 14, 255, 0},
+ { 12, 255, 0}, { 11, 255, 0}, { 9, 255, 0}, { 8, 255, 0}, { 7, 255, 1},
+ { 7, 255, 2}, { 6, 255, 3}, { 6, 255, 4}, { 5, 255, 5}, { 5, 255, 6},
+ { 4, 255, 7}, { 4, 255, 8}, { 3, 255, 9}, { 3, 255, 10}, { 2, 255, 11},
+ { 2, 255, 12}, { 1, 255, 13}, { 1, 255, 14}, { 0, 255, 15}, { 0, 255, 16},
+ { 0, 255, 18}, { 0, 255, 19}, { 0, 255, 21}, { 0, 255, 22}, { 0, 255, 24},
+ { 0, 255, 25}, { 0, 255, 27}, { 0, 255, 28}, { 0, 255, 30}, { 0, 255, 31},
+ { 0, 255, 33}, { 0, 255, 34}, { 0, 255, 36}, { 0, 255, 37}, { 0, 255, 39},
+ { 0, 255, 40}, { 0, 255, 42}, { 0, 255, 43}, { 0, 255, 45}, { 0, 255, 46},
+ { 0, 255, 48}, { 0, 255, 49}, { 0, 255, 51}, { 0, 255, 52}, { 0, 255, 54},
+ { 0, 255, 55}, { 0, 255, 57}, { 0, 255, 58}, { 0, 255, 60}, { 0, 255, 61},
+ { 0, 255, 63}, { 0, 255, 64}, { 0, 255, 66}, { 0, 255, 67}, { 0, 255, 69},
+ { 0, 255, 70}, { 0, 255, 72}, { 0, 255, 73}, { 0, 255, 75}, { 0, 255, 76},
+ { 0, 255, 78}, { 0, 255, 79}, { 0, 255, 81}, { 0, 255, 82}, { 0, 255, 84},
+ { 0, 255, 86}, { 0, 255, 87}, { 0, 255, 89}, { 0, 255, 90}, { 0, 255, 92},
+ { 0, 255, 93}, { 0, 255, 95}, { 0, 255, 96}, { 0, 255, 98}, { 0, 255, 99},
+ { 0, 255, 101}, { 0, 255, 102}, { 0, 255, 104}, { 0, 255, 105}, { 0, 255, 107},
+ { 0, 255, 108}, { 0, 255, 110}, { 0, 255, 111}, { 0, 255, 113}, { 0, 255, 114},
+ { 0, 255, 116}, { 0, 255, 117}, { 0, 255, 119}, { 0, 255, 120}, { 0, 255, 122},
+ { 0, 255, 123}, { 0, 255, 125}, { 0, 255, 126}, { 0, 255, 128}, { 0, 255, 129},
+ { 0, 255, 131}, { 0, 255, 132}, { 0, 255, 134}, { 0, 255, 135}, { 0, 255, 137},
+ { 0, 255, 138}, { 0, 255, 140}, { 0, 255, 141}, { 0, 255, 143}, { 0, 255, 144},
+ { 0, 255, 146}, { 0, 255, 147}, { 0, 255, 149}, { 0, 255, 150}, { 0, 255, 152},
+ { 0, 255, 153}, { 0, 255, 155}, { 0, 255, 156}, { 0, 255, 158}, { 0, 255, 159},
+ { 0, 255, 161}, { 0, 255, 162}, { 0, 255, 164}, { 0, 255, 165}, { 0, 255, 167},
+ { 0, 255, 168}, { 0, 255, 170}, { 0, 255, 171}, { 0, 255, 173}, { 0, 255, 174},
+ { 0, 255, 176}, { 0, 255, 177}, { 0, 255, 179}, { 0, 255, 180}, { 0, 255, 182},
+ { 0, 255, 183}, { 0, 255, 185}, { 0, 255, 187}, { 0, 255, 188}, { 0, 255, 190},
+ { 0, 255, 191}, { 0, 255, 193}, { 0, 255, 194}, { 0, 255, 196}, { 0, 255, 197},
+ { 0, 255, 199}, { 0, 255, 200}, { 0, 255, 202}, { 0, 255, 203}, { 0, 255, 205},
+ { 0, 255, 206}, { 0, 255, 208}, { 0, 255, 209}, { 0, 255, 211}, { 0, 255, 212},
+ { 0, 255, 214}, { 0, 255, 215}, { 0, 255, 217}, { 0, 255, 218}, { 0, 255, 220},
+ { 0, 255, 221}, { 0, 255, 223}, { 0, 255, 224}, { 0, 255, 226}, { 0, 255, 227},
+ { 0, 255, 229}, { 0, 255, 230}, { 0, 255, 232}, { 0, 255, 233}, { 0, 255, 235},
+ { 0, 255, 236}, { 0, 255, 238}, { 0, 255, 239}, { 0, 255, 241}, { 0, 255, 242},
+ { 0, 255, 244}, { 0, 255, 245}, { 0, 255, 247}, { 0, 255, 248}, { 0, 255, 250},
+ { 0, 255, 251}, { 0, 255, 253}, { 0, 255, 254}, { 0, 254, 255}, { 0, 253, 255},
+ { 0, 251, 255}, { 0, 250, 255}, { 0, 248, 255}, { 0, 247, 255}, { 0, 245, 255},
+ { 0, 244, 255}, { 0, 242, 255}, { 0, 241, 255}, { 0, 239, 255}, { 0, 238, 255},
+ { 0, 236, 255}, { 0, 235, 255}, { 0, 233, 255}, { 0, 232, 255}, { 0, 230, 255},
+ { 0, 229, 255}, { 0, 227, 255}, { 0, 225, 255}, { 0, 224, 255}, { 0, 222, 255},
+ { 0, 221, 255}, { 0, 219, 255}, { 0, 218, 255}, { 0, 216, 255}, { 0, 215, 255},
+ { 0, 213, 255}, { 0, 212, 255}, { 0, 210, 255}, { 0, 209, 255}, { 0, 207, 255},
+ { 0, 206, 255}, { 0, 204, 255}, { 0, 203, 255}, { 0, 201, 255}, { 0, 200, 255},
+ { 0, 198, 255}, { 0, 197, 255}, { 0, 195, 255}, { 0, 194, 255}, { 0, 192, 255},
+ { 0, 191, 255}, { 0, 189, 255}, { 0, 188, 255}, { 0, 186, 255}, { 0, 185, 255},
+ { 0, 183, 255}, { 0, 182, 255}, { 0, 180, 255}, { 0, 179, 255}, { 0, 177, 255},
+ { 0, 176, 255}, { 0, 174, 255}, { 0, 173, 255}, { 0, 171, 255}, { 0, 170, 255},
+ { 0, 168, 255}, { 0, 167, 255}, { 0, 165, 255}, { 0, 164, 255}, { 0, 162, 255},
+ { 0, 161, 255}, { 0, 159, 255}, { 0, 158, 255}, { 0, 156, 255}, { 0, 155, 255},
+ { 0, 153, 255}, { 0, 152, 255}, { 0, 150, 255}, { 0, 149, 255}, { 0, 147, 255},
+ { 0, 146, 255}, { 0, 144, 255}, { 0, 143, 255}, { 0, 141, 255}, { 0, 140, 255},
+ { 0, 138, 255}, { 0, 137, 255}, { 0, 135, 255}, { 0, 134, 255}, { 0, 132, 255},
+ { 0, 131, 255}, { 0, 129, 255}, { 0, 128, 255}, { 0, 126, 255}, { 0, 124, 255},
+ { 0, 123, 255}, { 0, 121, 255}, { 0, 120, 255}, { 0, 118, 255}, { 0, 117, 255},
+ { 0, 115, 255}, { 0, 114, 255}, { 0, 112, 255}, { 0, 111, 255}, { 0, 109, 255},
+ { 0, 108, 255}, { 0, 106, 255}, { 0, 105, 255}, { 0, 103, 255}, { 0, 102, 255},
+ { 0, 100, 255}, { 0, 99, 255}, { 0, 97, 255}, { 0, 96, 255}, { 0, 94, 255},
+ { 0, 93, 255}, { 0, 91, 255}, { 0, 90, 255}, { 0, 88, 255}, { 0, 87, 255},
+ { 0, 85, 255}, { 0, 84, 255}, { 0, 82, 255}, { 0, 81, 255}, { 0, 79, 255},
+ { 0, 78, 255}, { 0, 76, 255}, { 0, 75, 255}, { 0, 73, 255}, { 0, 72, 255},
+ { 0, 70, 255}, { 0, 69, 255}, { 0, 67, 255}, { 0, 66, 255}, { 0, 64, 255},
+ { 0, 63, 255}, { 0, 61, 255}, { 0, 60, 255}, { 0, 58, 255}, { 0, 57, 255},
+ { 0, 55, 255}, { 0, 54, 255}, { 0, 52, 255}, { 0, 51, 255}, { 0, 49, 255},
+ { 0, 48, 255}, { 0, 46, 255}, { 0, 45, 255}, { 0, 43, 255}, { 0, 42, 255},
+ { 0, 40, 255}, { 0, 39, 255}, { 0, 37, 255}, { 0, 36, 255}, { 0, 34, 255},
+ { 0, 33, 255}, { 0, 31, 255}, { 0, 30, 255}, { 0, 28, 255}, { 0, 26, 255},
+ { 0, 25, 255}, { 0, 23, 255}, { 0, 22, 255}, { 0, 20, 255}, { 0, 19, 255},
+ { 0, 17, 255}, { 0, 16, 255}, { 1, 15, 255}, { 1, 14, 255}, { 2, 13, 255},
+ { 2, 12, 255}, { 3, 11, 255}, { 3, 10, 255}, { 4, 9, 255}, { 4, 8, 255},
+ { 5, 7, 255}, { 5, 6, 255}, { 6, 5, 255}, { 6, 4, 255}, { 7, 3, 255},
+ { 7, 2, 255}, { 8, 1, 255}, { 8, 0, 255}, { 10, 0, 255}, { 11, 0, 255},
+ { 13, 0, 255}, { 14, 0, 255}, { 16, 0, 255}, { 17, 0, 255}, { 19, 0, 255},
+ { 20, 0, 255}, { 22, 0, 255}, { 23, 0, 255}, { 25, 0, 255}, { 26, 0, 255},
+ { 28, 0, 255}, { 29, 0, 255}, { 31, 0, 255}, { 32, 0, 255}, { 34, 0, 255},
+ { 35, 0, 255}, { 37, 0, 255}, { 38, 0, 255}, { 40, 0, 255}, { 41, 0, 255},
+ { 43, 0, 255}, { 44, 0, 255}, { 46, 0, 255}, { 47, 0, 255}, { 49, 0, 255},
+ { 50, 0, 255}, { 52, 0, 255}, { 53, 0, 255}, { 55, 0, 255}, { 56, 0, 255},
+ { 58, 0, 255}, { 59, 0, 255}, { 61, 0, 255}, { 62, 0, 255}, { 64, 0, 255},
+ { 65, 0, 255}, { 67, 0, 255}, { 68, 0, 255}, { 70, 0, 255}, { 72, 0, 255},
+ { 73, 0, 255}, { 75, 0, 255}, { 76, 0, 255}, { 78, 0, 255}, { 79, 0, 255},
+ { 81, 0, 255}, { 82, 0, 255}, { 84, 0, 255}, { 85, 0, 255}, { 87, 0, 255},
+ { 88, 0, 255}, { 90, 0, 255}, { 91, 0, 255}, { 93, 0, 255}, { 94, 0, 255},
+ { 96, 0, 255}, { 97, 0, 255}, { 99, 0, 255}, {100, 0, 255}, {102, 0, 255},
+ {103, 0, 255}, {105, 0, 255}, {106, 0, 255}, {108, 0, 255}, {109, 0, 255},
+ {111, 0, 255}, {112, 0, 255}, {114, 0, 255}, {115, 0, 255}, {117, 0, 255},
+ {118, 0, 255}, {120, 0, 255}, {121, 0, 255}, {123, 0, 255}, {124, 0, 255},
+ {126, 0, 255}, {127, 0, 255}, {129, 0, 255}, {130, 0, 255}, {132, 0, 255},
+ {133, 0, 255}, {135, 0, 255}, {136, 0, 255}, {138, 0, 255}, {139, 0, 255},
+ {141, 0, 255}, {142, 0, 255}, {144, 0, 255}, {145, 0, 255}, {147, 0, 255},
+ {148, 0, 255}, {150, 0, 255}, {151, 0, 255}, {153, 0, 255}, {154, 0, 255},
+ {156, 0, 255}, {157, 0, 255}, {159, 0, 255}, {160, 0, 255}, {162, 0, 255},
+ {163, 0, 255}, {165, 0, 255}, {166, 0, 255}, {168, 0, 255}, {169, 0, 255},
+ {171, 0, 255}, {173, 0, 255}, {174, 0, 255}, {176, 0, 255}, {177, 0, 255},
+ {179, 0, 255}, {180, 0, 255}, {182, 0, 255}, {183, 0, 255}, {185, 0, 255},
+ {186, 0, 255}, {188, 0, 255}, {189, 0, 255}, {191, 0, 255}, {192, 0, 255},
+ {194, 0, 255}, {195, 0, 255}, {197, 0, 255}, {198, 0, 255}, {200, 0, 255},
+ {201, 0, 255}, {203, 0, 255}, {204, 0, 255}, {206, 0, 255}, {207, 0, 255},
+ {209, 0, 255}, {210, 0, 255}, {212, 0, 255}, {213, 0, 255}, {215, 0, 255},
+ {216, 0, 255}, {218, 0, 255}, {219, 0, 255}, {221, 0, 255}, {222, 0, 255},
+ {224, 0, 255}, {225, 0, 255}, {227, 0, 255}, {228, 0, 255}, {230, 0, 255},
+ {231, 0, 255}, {233, 0, 255}, {234, 0, 255}, {236, 0, 255}, {237, 0, 255},
+ {239, 0, 255}, {240, 0, 255}, {242, 0, 255}, {243, 0, 255}, {245, 0, 255},
+ {246, 0, 255}, {247, 0, 254}, {248, 0, 253}, {248, 0, 252}, {249, 0, 251},
+ {249, 0, 250}, {250, 0, 249}, {250, 0, 248}, {251, 0, 247}, {251, 0, 246},
+ {252, 0, 245}, {252, 0, 244}, {253, 0, 243}, {253, 0, 242}, {254, 0, 241},
+ {254, 0, 240}, {255, 0, 239}, {255, 0, 238}, {255, 0, 236}, {255, 0, 235},
+ {255, 0, 233}, {255, 0, 232}, {255, 0, 230}, {255, 0, 229}, {255, 0, 227},
+ {255, 0, 226}, {255, 0, 224}, {255, 0, 223}, {255, 0, 221}, {255, 0, 220},
+ {255, 0, 218}, {255, 0, 217}, {255, 0, 215}, {255, 0, 214}, {255, 0, 212},
+ {255, 0, 211}, {255, 0, 209}, {255, 0, 208}, {255, 0, 206}, {255, 0, 205},
+ {255, 0, 203}, {255, 0, 202}, {255, 0, 200}, {255, 0, 199}, {255, 0, 197},
+ {255, 0, 196}, {255, 0, 194}, {255, 0, 193}, {255, 0, 191}, {255, 0, 190},
+ {255, 0, 188}, {255, 0, 187}, {255, 0, 185}, {255, 0, 184}, {255, 0, 182},
+ {255, 0, 181}, {255, 0, 179}, {255, 0, 178}, {255, 0, 176}, {255, 0, 175},
+ {255, 0, 173}, {255, 0, 172}, {255, 0, 170}, {255, 0, 169}, {255, 0, 167},
+ {255, 0, 166}, {255, 0, 164}, {255, 0, 163}, {255, 0, 161}, {255, 0, 160},
+ {255, 0, 158}, {255, 0, 157}, {255, 0, 155}, {255, 0, 154}, {255, 0, 152},
+ {255, 0, 151}, {255, 0, 149}, {255, 0, 148}, {255, 0, 146}, {255, 0, 145},
+ {255, 0, 143}, {255, 0, 141}, {255, 0, 140}, {255, 0, 138}, {255, 0, 137},
+ {255, 0, 135}, {255, 0, 134}, {255, 0, 132}, {255, 0, 131}, {255, 0, 129},
+ {255, 0, 128}, {255, 0, 126}, {255, 0, 125}, {255, 0, 123}, {255, 0, 122},
+ {255, 0, 120}, {255, 0, 119}, {255, 0, 117}, {255, 0, 116}, {255, 0, 114},
+ {255, 0, 113}, {255, 0, 111}, {255, 0, 110}, {255, 0, 108}, {255, 0, 107},
+ {255, 0, 105}, {255, 0, 104}, {255, 0, 102}, {255, 0, 101}, {255, 0, 99},
+ {255, 0, 98}, {255, 0, 96}, {255, 0, 95}, {255, 0, 93}, {255, 0, 92},
+ {255, 0, 90}, {255, 0, 89}, {255, 0, 87}, {255, 0, 86}, {255, 0, 84},
+ {255, 0, 83}, {255, 0, 81}, {255, 0, 80}, {255, 0, 78}, {255, 0, 77},
+ {255, 0, 75}, {255, 0, 74}, {255, 0, 72}, {255, 0, 71}, {255, 0, 69},
+ {255, 0, 68}, {255, 0, 66}, {255, 0, 65}, {255, 0, 63}, {255, 0, 62},
+ {255, 0, 60}, {255, 0, 59}, {255, 0, 57}, {255, 0, 56}, {255, 0, 54},
+ {255, 0, 53}, {255, 0, 51}, {255, 0, 50}, {255, 0, 48}, {255, 0, 47},
+ {255, 0, 45}, {255, 0, 44}, {255, 0, 42}, {255, 0, 40}, {255, 0, 39},
+ {255, 0, 37}, {255, 0, 36}, {255, 0, 34}, {255, 0, 33}, {255, 0, 31},
+ {255, 0, 30}, {255, 0, 28}, {255, 0, 27}, {255, 0, 25}, {255, 0, 24}
+};
+
+const rgb_t jet_colormap[1000] = {
+ { 29, 0, 102}, { 23, 0, 107}, { 17, 0, 112}, { 12, 0, 117}, { 6, 0, 122},
+ { 0, 0, 127}, { 0, 0, 128}, { 0, 0, 129}, { 0, 0, 129}, { 0, 0, 130},
+ { 0, 0, 131}, { 0, 0, 132}, { 0, 0, 133}, { 0, 0, 133}, { 0, 0, 134},
+ { 0, 0, 135}, { 0, 0, 136}, { 0, 0, 137}, { 0, 0, 138}, { 0, 0, 140},
+ { 0, 0, 141}, { 0, 0, 142}, { 0, 0, 143}, { 0, 0, 145}, { 0, 0, 146},
+ { 0, 0, 147}, { 0, 0, 148}, { 0, 0, 150}, { 0, 0, 151}, { 0, 0, 152},
+ { 0, 0, 153}, { 0, 0, 154}, { 0, 0, 156}, { 0, 0, 157}, { 0, 0, 158},
+ { 0, 0, 159}, { 0, 0, 160}, { 0, 0, 161}, { 0, 0, 163}, { 0, 0, 164},
+ { 0, 0, 165}, { 0, 0, 166}, { 0, 0, 168}, { 0, 0, 169}, { 0, 0, 170},
+ { 0, 0, 171}, { 0, 0, 173}, { 0, 0, 174}, { 0, 0, 175}, { 0, 0, 176},
+ { 0, 0, 178}, { 0, 0, 179}, { 0, 0, 180}, { 0, 0, 181}, { 0, 0, 183},
+ { 0, 0, 184}, { 0, 0, 185}, { 0, 0, 186}, { 0, 0, 188}, { 0, 0, 189},
+ { 0, 0, 190}, { 0, 0, 191}, { 0, 0, 193}, { 0, 0, 194}, { 0, 0, 195},
+ { 0, 0, 196}, { 0, 0, 197}, { 0, 0, 198}, { 0, 0, 200}, { 0, 0, 201},
+ { 0, 0, 202}, { 0, 0, 203}, { 0, 0, 204}, { 0, 0, 206}, { 0, 0, 207},
+ { 0, 0, 208}, { 0, 0, 209}, { 0, 0, 211}, { 0, 0, 212}, { 0, 0, 213},
+ { 0, 0, 214}, { 0, 0, 216}, { 0, 0, 217}, { 0, 0, 218}, { 0, 0, 219},
+ { 0, 0, 221}, { 0, 0, 222}, { 0, 0, 223}, { 0, 0, 225}, { 0, 0, 226},
+ { 0, 0, 227}, { 0, 0, 228}, { 0, 0, 230}, { 0, 0, 231}, { 0, 0, 232},
+ { 0, 0, 233}, { 0, 0, 234}, { 0, 0, 234}, { 0, 0, 235}, { 0, 0, 236},
+ { 0, 0, 237}, { 0, 0, 238}, { 0, 0, 239}, { 0, 0, 239}, { 0, 0, 240},
+ { 0, 0, 241}, { 0, 0, 242}, { 0, 0, 243}, { 0, 0, 244}, { 0, 0, 246},
+ { 0, 0, 247}, { 0, 0, 248}, { 0, 0, 249}, { 0, 0, 250}, { 0, 0, 251},
+ { 0, 0, 253}, { 0, 0, 254}, { 0, 0, 254}, { 0, 0, 254}, { 0, 0, 254},
+ { 0, 0, 254}, { 0, 0, 254}, { 0, 0, 255}, { 0, 0, 255}, { 0, 0, 255},
+ { 0, 0, 255}, { 0, 0, 255}, { 0, 0, 255}, { 0, 1, 255}, { 0, 1, 255},
+ { 0, 2, 255}, { 0, 3, 255}, { 0, 3, 255}, { 0, 4, 255}, { 0, 5, 255},
+ { 0, 6, 255}, { 0, 6, 255}, { 0, 7, 255}, { 0, 8, 255}, { 0, 9, 255},
+ { 0, 10, 255}, { 0, 11, 255}, { 0, 12, 255}, { 0, 13, 255}, { 0, 14, 255},
+ { 0, 15, 255}, { 0, 16, 255}, { 0, 17, 255}, { 0, 18, 255}, { 0, 19, 255},
+ { 0, 21, 255}, { 0, 22, 255}, { 0, 23, 255}, { 0, 24, 255}, { 0, 25, 255},
+ { 0, 26, 255}, { 0, 27, 255}, { 0, 28, 255}, { 0, 29, 255}, { 0, 30, 255},
+ { 0, 31, 255}, { 0, 32, 255}, { 0, 34, 255}, { 0, 35, 255}, { 0, 36, 255},
+ { 0, 37, 255}, { 0, 38, 255}, { 0, 39, 255}, { 0, 40, 255}, { 0, 41, 255},
+ { 0, 42, 255}, { 0, 43, 255}, { 0, 44, 255}, { 0, 45, 255}, { 0, 46, 255},
+ { 0, 48, 255}, { 0, 49, 255}, { 0, 50, 255}, { 0, 51, 255}, { 0, 52, 255},
+ { 0, 53, 255}, { 0, 54, 255}, { 0, 55, 255}, { 0, 56, 255}, { 0, 57, 255},
+ { 0, 58, 255}, { 0, 58, 255}, { 0, 59, 255}, { 0, 60, 255}, { 0, 60, 255},
+ { 0, 61, 255}, { 0, 62, 255}, { 0, 63, 255}, { 0, 63, 255}, { 0, 64, 255},
+ { 0, 65, 255}, { 0, 66, 255}, { 0, 67, 255}, { 0, 68, 255}, { 0, 69, 255},
+ { 0, 71, 255}, { 0, 72, 255}, { 0, 73, 255}, { 0, 74, 255}, { 0, 75, 255},
+ { 0, 76, 255}, { 0, 77, 255}, { 0, 78, 255}, { 0, 79, 255}, { 0, 80, 255},
+ { 0, 81, 255}, { 0, 82, 255}, { 0, 84, 255}, { 0, 85, 255}, { 0, 86, 255},
+ { 0, 87, 255}, { 0, 88, 255}, { 0, 89, 255}, { 0, 90, 255}, { 0, 91, 255},
+ { 0, 92, 255}, { 0, 93, 255}, { 0, 94, 255}, { 0, 95, 255}, { 0, 96, 255},
+ { 0, 98, 255}, { 0, 99, 255}, { 0, 100, 255}, { 0, 101, 255}, { 0, 102, 255},
+ { 0, 103, 255}, { 0, 104, 255}, { 0, 105, 255}, { 0, 106, 255}, { 0, 107, 255},
+ { 0, 108, 255}, { 0, 109, 255}, { 0, 111, 255}, { 0, 112, 255}, { 0, 113, 255},
+ { 0, 114, 255}, { 0, 115, 255}, { 0, 116, 255}, { 0, 117, 255}, { 0, 118, 255},
+ { 0, 119, 255}, { 0, 120, 255}, { 0, 121, 255}, { 0, 122, 255}, { 0, 123, 255},
+ { 0, 125, 255}, { 0, 126, 255}, { 0, 127, 255}, { 0, 128, 255}, { 0, 129, 255},
+ { 0, 130, 255}, { 0, 131, 255}, { 0, 132, 255}, { 0, 133, 255}, { 0, 134, 255},
+ { 0, 135, 255}, { 0, 136, 255}, { 0, 138, 255}, { 0, 139, 255}, { 0, 140, 255},
+ { 0, 141, 255}, { 0, 142, 255}, { 0, 143, 255}, { 0, 144, 255}, { 0, 145, 255},
+ { 0, 146, 255}, { 0, 147, 255}, { 0, 148, 255}, { 0, 149, 255}, { 0, 150, 255},
+ { 0, 150, 255}, { 0, 151, 255}, { 0, 152, 255}, { 0, 153, 255}, { 0, 153, 255},
+ { 0, 154, 255}, { 0, 155, 255}, { 0, 155, 255}, { 0, 156, 255}, { 0, 157, 255},
+ { 0, 158, 255}, { 0, 159, 255}, { 0, 161, 255}, { 0, 162, 255}, { 0, 163, 255},
+ { 0, 164, 255}, { 0, 165, 255}, { 0, 166, 255}, { 0, 167, 255}, { 0, 168, 255},
+ { 0, 169, 255}, { 0, 170, 255}, { 0, 171, 255}, { 0, 172, 255}, { 0, 173, 255},
+ { 0, 175, 255}, { 0, 176, 255}, { 0, 177, 255}, { 0, 178, 255}, { 0, 179, 255},
+ { 0, 180, 255}, { 0, 181, 255}, { 0, 182, 255}, { 0, 183, 255}, { 0, 184, 255},
+ { 0, 185, 255}, { 0, 186, 255}, { 0, 188, 255}, { 0, 189, 255}, { 0, 190, 255},
+ { 0, 191, 255}, { 0, 192, 255}, { 0, 193, 255}, { 0, 194, 255}, { 0, 195, 255},
+ { 0, 196, 255}, { 0, 197, 255}, { 0, 198, 255}, { 0, 199, 255}, { 0, 200, 255},
+ { 0, 202, 255}, { 0, 203, 255}, { 0, 204, 255}, { 0, 205, 255}, { 0, 206, 255},
+ { 0, 207, 255}, { 0, 208, 255}, { 0, 209, 255}, { 0, 210, 255}, { 0, 211, 255},
+ { 0, 212, 255}, { 0, 213, 255}, { 0, 215, 255}, { 0, 216, 255}, { 0, 217, 255},
+ { 0, 218, 254}, { 0, 219, 253}, { 0, 220, 252}, { 0, 221, 252}, { 0, 222, 251},
+ { 0, 223, 250}, { 0, 224, 250}, { 0, 225, 249}, { 0, 226, 248}, { 0, 227, 247},
+ { 0, 229, 247}, { 1, 230, 246}, { 2, 231, 245}, { 3, 232, 244}, { 3, 233, 243},
+ { 4, 234, 242}, { 5, 235, 241}, { 5, 236, 240}, { 6, 237, 239}, { 7, 238, 238},
+ { 8, 239, 238}, { 8, 240, 237}, { 9, 241, 236}, { 10, 242, 236}, { 10, 242, 235},
+ { 11, 243, 235}, { 11, 244, 234}, { 12, 245, 234}, { 13, 245, 233}, { 13, 246, 232},
+ { 14, 247, 232}, { 15, 247, 231}, { 15, 248, 231}, { 16, 249, 230}, { 17, 249, 229},
+ { 18, 250, 228}, { 18, 251, 227}, { 19, 251, 226}, { 20, 252, 225}, { 21, 253, 224},
+ { 22, 253, 224}, { 23, 254, 223}, { 23, 254, 222}, { 24, 255, 221}, { 25, 255, 220},
+ { 26, 255, 219}, { 27, 255, 218}, { 28, 255, 218}, { 29, 255, 217}, { 30, 255, 216},
+ { 30, 255, 215}, { 31, 255, 214}, { 32, 255, 214}, { 33, 255, 213}, { 34, 255, 212},
+ { 35, 255, 211}, { 36, 255, 210}, { 37, 255, 209}, { 38, 255, 208}, { 39, 255, 207},
+ { 39, 255, 207}, { 40, 255, 206}, { 41, 255, 205}, { 42, 255, 204}, { 43, 255, 203},
+ { 44, 255, 202}, { 45, 255, 201}, { 46, 255, 200}, { 47, 255, 199}, { 48, 255, 198},
+ { 48, 255, 198}, { 49, 255, 197}, { 50, 255, 196}, { 51, 255, 195}, { 52, 255, 194},
+ { 53, 255, 193}, { 54, 255, 192}, { 55, 255, 191}, { 55, 255, 191}, { 56, 255, 190},
+ { 57, 255, 189}, { 58, 255, 188}, { 59, 255, 187}, { 60, 255, 186}, { 60, 255, 186},
+ { 61, 255, 185}, { 62, 255, 184}, { 63, 255, 183}, { 64, 255, 182}, { 65, 255, 181},
+ { 65, 255, 181}, { 66, 255, 180}, { 67, 255, 179}, { 68, 255, 178}, { 69, 255, 177},
+ { 70, 255, 176}, { 71, 255, 175}, { 72, 255, 174}, { 73, 255, 173}, { 74, 255, 172},
+ { 74, 255, 172}, { 75, 255, 171}, { 76, 255, 170}, { 77, 255, 169}, { 78, 255, 168},
+ { 79, 255, 167}, { 80, 255, 166}, { 81, 255, 165}, { 82, 255, 164}, { 83, 255, 163},
+ { 83, 255, 163}, { 84, 255, 162}, { 84, 255, 162}, { 85, 255, 161}, { 85, 255, 161},
+ { 86, 255, 160}, { 87, 255, 159}, { 87, 255, 159}, { 88, 255, 158}, { 88, 255, 158},
+ { 89, 255, 157}, { 89, 255, 157}, { 90, 255, 156}, { 91, 255, 155}, { 92, 255, 154},
+ { 93, 255, 153}, { 94, 255, 152}, { 95, 255, 151}, { 96, 255, 150}, { 97, 255, 149},
+ { 97, 255, 149}, { 98, 255, 148}, { 99, 255, 147}, {100, 255, 146}, {101, 255, 145},
+ {102, 255, 144}, {102, 255, 143}, {103, 255, 142}, {104, 255, 141}, {105, 255, 140},
+ {106, 255, 140}, {107, 255, 139}, {107, 255, 138}, {108, 255, 137}, {109, 255, 136},
+ {110, 255, 135}, {111, 255, 134}, {112, 255, 134}, {113, 255, 133}, {114, 255, 132},
+ {114, 255, 131}, {115, 255, 130}, {116, 255, 130}, {117, 255, 129}, {118, 255, 128},
+ {119, 255, 127}, {120, 255, 126}, {121, 255, 125}, {122, 255, 124}, {123, 255, 123},
+ {123, 255, 123}, {124, 255, 122}, {125, 255, 121}, {126, 255, 120}, {127, 255, 119},
+ {128, 255, 118}, {129, 255, 117}, {130, 255, 116}, {130, 255, 115}, {131, 255, 114},
+ {132, 255, 114}, {133, 255, 113}, {134, 255, 112}, {134, 255, 111}, {135, 255, 110},
+ {136, 255, 109}, {137, 255, 108}, {138, 255, 107}, {139, 255, 107}, {140, 255, 106},
+ {140, 255, 105}, {141, 255, 104}, {142, 255, 103}, {143, 255, 102}, {144, 255, 102},
+ {145, 255, 101}, {146, 255, 100}, {147, 255, 99}, {148, 255, 98}, {149, 255, 97},
+ {149, 255, 97}, {150, 255, 96}, {151, 255, 95}, {152, 255, 94}, {153, 255, 93},
+ {154, 255, 92}, {155, 255, 91}, {156, 255, 90}, {157, 255, 89}, {157, 255, 89},
+ {158, 255, 88}, {158, 255, 88}, {159, 255, 87}, {159, 255, 87}, {160, 255, 86},
+ {161, 255, 85}, {161, 255, 85}, {162, 255, 84}, {162, 255, 84}, {163, 255, 83},
+ {163, 255, 83}, {164, 255, 82}, {165, 255, 81}, {166, 255, 80}, {167, 255, 79},
+ {168, 255, 78}, {169, 255, 77}, {170, 255, 76}, {171, 255, 75}, {172, 255, 74},
+ {172, 255, 74}, {173, 255, 73}, {174, 255, 72}, {175, 255, 71}, {176, 255, 70},
+ {177, 255, 69}, {178, 255, 68}, {179, 255, 67}, {180, 255, 66}, {181, 255, 65},
+ {181, 255, 65}, {182, 255, 64}, {183, 255, 63}, {184, 255, 62}, {185, 255, 61},
+ {186, 255, 60}, {186, 255, 60}, {187, 255, 59}, {188, 255, 58}, {189, 255, 57},
+ {190, 255, 56}, {191, 255, 55}, {191, 255, 55}, {192, 255, 54}, {193, 255, 53},
+ {194, 255, 52}, {195, 255, 51}, {196, 255, 50}, {197, 255, 49}, {198, 255, 48},
+ {198, 255, 48}, {199, 255, 47}, {200, 255, 46}, {201, 255, 45}, {202, 255, 44},
+ {203, 255, 43}, {204, 255, 42}, {205, 255, 41}, {206, 255, 40}, {207, 255, 39},
+ {207, 255, 39}, {208, 255, 38}, {209, 255, 37}, {210, 255, 36}, {211, 255, 35},
+ {212, 255, 34}, {213, 255, 33}, {214, 255, 32}, {214, 255, 31}, {215, 255, 30},
+ {216, 255, 30}, {217, 255, 29}, {218, 255, 28}, {218, 255, 27}, {219, 255, 26},
+ {220, 255, 25}, {221, 255, 24}, {222, 255, 23}, {223, 255, 23}, {224, 255, 22},
+ {224, 255, 21}, {225, 255, 20}, {226, 255, 19}, {227, 255, 18}, {228, 255, 18},
+ {229, 255, 17}, {230, 255, 16}, {231, 255, 15}, {231, 255, 15}, {232, 255, 14},
+ {232, 255, 13}, {233, 255, 13}, {234, 255, 12}, {234, 255, 11}, {235, 255, 11},
+ {235, 255, 10}, {236, 255, 10}, {236, 255, 9}, {237, 255, 8}, {238, 254, 8},
+ {238, 253, 7}, {239, 252, 6}, {240, 251, 5}, {241, 250, 5}, {242, 249, 4},
+ {243, 248, 3}, {244, 247, 3}, {245, 246, 2}, {246, 246, 1}, {247, 245, 0},
+ {247, 243, 0}, {248, 242, 0}, {249, 242, 0}, {250, 241, 0}, {250, 240, 0},
+ {251, 239, 0}, {252, 238, 0}, {252, 237, 0}, {253, 236, 0}, {254, 235, 0},
+ {255, 234, 0}, {255, 233, 0}, {255, 232, 0}, {255, 231, 0}, {255, 230, 0},
+ {255, 229, 0}, {255, 228, 0}, {255, 227, 0}, {255, 226, 0}, {255, 225, 0},
+ {255, 224, 0}, {255, 223, 0}, {255, 222, 0}, {255, 221, 0}, {255, 220, 0},
+ {255, 219, 0}, {255, 218, 0}, {255, 217, 0}, {255, 216, 0}, {255, 215, 0},
+ {255, 214, 0}, {255, 213, 0}, {255, 212, 0}, {255, 211, 0}, {255, 210, 0},
+ {255, 209, 0}, {255, 208, 0}, {255, 207, 0}, {255, 206, 0}, {255, 205, 0},
+ {255, 204, 0}, {255, 203, 0}, {255, 202, 0}, {255, 201, 0}, {255, 200, 0},
+ {255, 199, 0}, {255, 198, 0}, {255, 197, 0}, {255, 196, 0}, {255, 195, 0},
+ {255, 194, 0}, {255, 193, 0}, {255, 192, 0}, {255, 191, 0}, {255, 190, 0},
+ {255, 189, 0}, {255, 188, 0}, {255, 187, 0}, {255, 186, 0}, {255, 185, 0},
+ {255, 184, 0}, {255, 183, 0}, {255, 182, 0}, {255, 180, 0}, {255, 179, 0},
+ {255, 178, 0}, {255, 177, 0}, {255, 176, 0}, {255, 176, 0}, {255, 175, 0},
+ {255, 175, 0}, {255, 174, 0}, {255, 173, 0}, {255, 173, 0}, {255, 172, 0},
+ {255, 171, 0}, {255, 171, 0}, {255, 170, 0}, {255, 169, 0}, {255, 168, 0},
+ {255, 167, 0}, {255, 166, 0}, {255, 165, 0}, {255, 164, 0}, {255, 163, 0},
+ {255, 162, 0}, {255, 161, 0}, {255, 160, 0}, {255, 159, 0}, {255, 158, 0},
+ {255, 157, 0}, {255, 156, 0}, {255, 155, 0}, {255, 154, 0}, {255, 153, 0},
+ {255, 152, 0}, {255, 151, 0}, {255, 150, 0}, {255, 150, 0}, {255, 149, 0},
+ {255, 147, 0}, {255, 146, 0}, {255, 146, 0}, {255, 145, 0}, {255, 144, 0},
+ {255, 143, 0}, {255, 142, 0}, {255, 141, 0}, {255, 140, 0}, {255, 139, 0},
+ {255, 138, 0}, {255, 137, 0}, {255, 136, 0}, {255, 135, 0}, {255, 134, 0},
+ {255, 133, 0}, {255, 132, 0}, {255, 131, 0}, {255, 130, 0}, {255, 129, 0},
+ {255, 128, 0}, {255, 127, 0}, {255, 126, 0}, {255, 125, 0}, {255, 124, 0},
+ {255, 123, 0}, {255, 122, 0}, {255, 121, 0}, {255, 120, 0}, {255, 119, 0},
+ {255, 118, 0}, {255, 117, 0}, {255, 116, 0}, {255, 115, 0}, {255, 114, 0},
+ {255, 113, 0}, {255, 112, 0}, {255, 111, 0}, {255, 109, 0}, {255, 108, 0},
+ {255, 107, 0}, {255, 106, 0}, {255, 105, 0}, {255, 104, 0}, {255, 103, 0},
+ {255, 102, 0}, {255, 101, 0}, {255, 100, 0}, {255, 99, 0}, {255, 98, 0},
+ {255, 97, 0}, {255, 96, 0}, {255, 95, 0}, {255, 94, 0}, {255, 93, 0},
+ {255, 92, 0}, {255, 91, 0}, {255, 91, 0}, {255, 90, 0}, {255, 90, 0},
+ {255, 89, 0}, {255, 88, 0}, {255, 88, 0}, {255, 87, 0}, {255, 86, 0},
+ {255, 86, 0}, {255, 85, 0}, {255, 84, 0}, {255, 83, 0}, {255, 82, 0},
+ {255, 81, 0}, {255, 80, 0}, {255, 79, 0}, {255, 78, 0}, {255, 77, 0},
+ {255, 76, 0}, {255, 75, 0}, {255, 74, 0}, {255, 73, 0}, {255, 72, 0},
+ {255, 71, 0}, {255, 70, 0}, {255, 69, 0}, {255, 68, 0}, {255, 67, 0},
+ {255, 66, 0}, {255, 65, 0}, {255, 64, 0}, {255, 63, 0}, {255, 62, 0},
+ {255, 61, 0}, {255, 60, 0}, {255, 59, 0}, {255, 58, 0}, {255, 57, 0},
+ {255, 56, 0}, {255, 55, 0}, {255, 54, 0}, {255, 54, 0}, {255, 53, 0},
+ {255, 51, 0}, {255, 50, 0}, {255, 49, 0}, {255, 48, 0}, {255, 47, 0},
+ {255, 46, 0}, {255, 45, 0}, {255, 44, 0}, {255, 43, 0}, {255, 42, 0},
+ {255, 41, 0}, {255, 40, 0}, {255, 39, 0}, {255, 38, 0}, {255, 37, 0},
+ {255, 36, 0}, {255, 35, 0}, {255, 34, 0}, {255, 33, 0}, {255, 32, 0},
+ {255, 31, 0}, {255, 30, 0}, {255, 29, 0}, {255, 28, 0}, {255, 27, 0},
+ {255, 26, 0}, {255, 25, 0}, {255, 24, 0}, {254, 23, 0}, {254, 22, 0},
+ {254, 21, 0}, {254, 20, 0}, {254, 19, 0}, {254, 18, 0}, {253, 17, 0},
+ {251, 16, 0}, {250, 15, 0}, {249, 14, 0}, {248, 13, 0}, {247, 12, 0},
+ {246, 11, 0}, {244, 10, 0}, {243, 9, 0}, {242, 8, 0}, {241, 7, 0},
+ {240, 6, 0}, {239, 6, 0}, {239, 5, 0}, {238, 4, 0}, {237, 4, 0},
+ {236, 3, 0}, {235, 3, 0}, {234, 2, 0}, {234, 1, 0}, {233, 1, 0},
+ {232, 0, 0}, {231, 0, 0}, {230, 0, 0}, {228, 0, 0}, {227, 0, 0},
+ {226, 0, 0}, {225, 0, 0}, {223, 0, 0}, {222, 0, 0}, {221, 0, 0},
+ {219, 0, 0}, {218, 0, 0}, {217, 0, 0}, {216, 0, 0}, {214, 0, 0},
+ {213, 0, 0}, {212, 0, 0}, {211, 0, 0}, {209, 0, 0}, {208, 0, 0},
+ {207, 0, 0}, {206, 0, 0}, {204, 0, 0}, {203, 0, 0}, {202, 0, 0},
+ {201, 0, 0}, {200, 0, 0}, {198, 0, 0}, {197, 0, 0}, {196, 0, 0},
+ {195, 0, 0}, {194, 0, 0}, {193, 0, 0}, {191, 0, 0}, {190, 0, 0},
+ {189, 0, 0}, {188, 0, 0}, {186, 0, 0}, {185, 0, 0}, {184, 0, 0},
+ {183, 0, 0}, {181, 0, 0}, {180, 0, 0}, {179, 0, 0}, {178, 0, 0},
+ {176, 0, 0}, {175, 0, 0}, {174, 0, 0}, {173, 0, 0}, {171, 0, 0},
+ {170, 0, 0}, {169, 0, 0}, {168, 0, 0}, {166, 0, 0}, {165, 0, 0},
+ {164, 0, 0}, {163, 0, 0}, {161, 0, 0}, {160, 0, 0}, {159, 0, 0},
+ {158, 0, 0}, {157, 0, 0}, {156, 0, 0}, {154, 0, 0}, {153, 0, 0},
+ {152, 0, 0}, {151, 0, 0}, {150, 0, 0}, {148, 0, 0}, {147, 0, 0},
+ {146, 0, 0}, {145, 0, 0}, {143, 0, 0}, {142, 0, 0}, {141, 0, 0},
+ {140, 0, 0}, {138, 0, 0}, {137, 0, 0}, {136, 0, 0}, {135, 0, 0},
+ {134, 0, 0}, {133, 0, 0}, {133, 0, 0}, {132, 0, 0}, {131, 0, 0},
+ {130, 0, 0}, {129, 0, 0}, {129, 0, 0}, {128, 0, 0}, {127, 0, 0},
+ {122, 0, 9}, {117, 0, 18}, {112, 0, 27}, {107, 0, 36}, {102, 0, 45}
+};
+
+const rgb_t prism_colormap[1000] = {
+ {255, 0, 0}, {255, 2, 0}, {255, 4, 0}, {255, 6, 0}, {255, 8, 0},
+ {255, 10, 0}, {255, 11, 0}, {255, 13, 0}, {255, 15, 0}, {255, 17, 0},
+ {255, 19, 0}, {255, 21, 0}, {255, 23, 0}, {255, 25, 0}, {255, 27, 0},
+ {255, 29, 0}, {255, 31, 0}, {255, 33, 0}, {255, 34, 0}, {255, 36, 0},
+ {255, 38, 0}, {255, 40, 0}, {255, 42, 0}, {255, 44, 0}, {255, 46, 0},
+ {255, 48, 0}, {255, 50, 0}, {255, 52, 0}, {255, 54, 0}, {255, 56, 0},
+ {255, 57, 0}, {255, 59, 0}, {255, 61, 0}, {255, 63, 0}, {255, 65, 0},
+ {255, 67, 0}, {255, 69, 0}, {255, 71, 0}, {255, 73, 0}, {255, 75, 0},
+ {255, 77, 0}, {255, 78, 0}, {255, 80, 0}, {255, 82, 0}, {255, 84, 0},
+ {255, 86, 0}, {255, 88, 0}, {255, 90, 0}, {255, 92, 0}, {255, 94, 0},
+ {255, 96, 0}, {255, 98, 0}, {255, 100, 0}, {255, 101, 0}, {255, 103, 0},
+ {255, 105, 0}, {255, 107, 0}, {255, 109, 0}, {255, 111, 0}, {255, 113, 0},
+ {255, 115, 0}, {255, 117, 0}, {255, 119, 0}, {255, 121, 0}, {255, 123, 0},
+ {255, 124, 0}, {255, 126, 0}, {255, 128, 0}, {255, 130, 0}, {255, 132, 0},
+ {255, 134, 0}, {255, 136, 0}, {255, 138, 0}, {255, 140, 0}, {255, 142, 0},
+ {255, 144, 0}, {255, 145, 0}, {255, 147, 0}, {255, 149, 0}, {255, 151, 0},
+ {255, 153, 0}, {255, 155, 0}, {255, 157, 0}, {255, 159, 0}, {255, 161, 0},
+ {255, 163, 0}, {255, 165, 0}, {255, 167, 0}, {255, 168, 0}, {255, 170, 0},
+ {255, 172, 0}, {255, 174, 0}, {255, 176, 0}, {255, 178, 0}, {255, 180, 0},
+ {255, 182, 0}, {255, 184, 0}, {255, 186, 0}, {255, 188, 0}, {255, 190, 0},
+ {255, 191, 0}, {255, 193, 0}, {255, 195, 0}, {255, 197, 0}, {255, 199, 0},
+ {255, 201, 0}, {255, 203, 0}, {255, 205, 0}, {255, 207, 0}, {255, 209, 0},
+ {255, 211, 0}, {255, 212, 0}, {255, 214, 0}, {255, 216, 0}, {255, 218, 0},
+ {255, 220, 0}, {255, 222, 0}, {255, 224, 0}, {255, 226, 0}, {255, 228, 0},
+ {255, 230, 0}, {255, 232, 0}, {255, 234, 0}, {255, 235, 0}, {255, 237, 0},
+ {255, 239, 0}, {255, 241, 0}, {255, 243, 0}, {255, 245, 0}, {255, 247, 0},
+ {255, 249, 0}, {255, 251, 0}, {255, 253, 0}, {255, 255, 0}, {252, 255, 0},
+ {248, 255, 0}, {244, 255, 0}, {240, 255, 0}, {237, 255, 0}, {233, 255, 0},
+ {229, 255, 0}, {225, 255, 0}, {221, 255, 0}, {217, 255, 0}, {214, 255, 0},
+ {210, 255, 0}, {206, 255, 0}, {202, 255, 0}, {198, 255, 0}, {195, 255, 0},
+ {191, 255, 0}, {187, 255, 0}, {183, 255, 0}, {179, 255, 0}, {175, 255, 0},
+ {172, 255, 0}, {168, 255, 0}, {164, 255, 0}, {160, 255, 0}, {156, 255, 0},
+ {152, 255, 0}, {149, 255, 0}, {145, 255, 0}, {141, 255, 0}, {137, 255, 0},
+ {133, 255, 0}, {129, 255, 0}, {126, 255, 0}, {122, 255, 0}, {118, 255, 0},
+ {114, 255, 0}, {110, 255, 0}, {106, 255, 0}, {103, 255, 0}, { 99, 255, 0},
+ { 95, 255, 0}, { 91, 255, 0}, { 87, 255, 0}, { 83, 255, 0}, { 80, 255, 0},
+ { 76, 255, 0}, { 72, 255, 0}, { 68, 255, 0}, { 64, 255, 0}, { 60, 255, 0},
+ { 57, 255, 0}, { 53, 255, 0}, { 49, 255, 0}, { 45, 255, 0}, { 41, 255, 0},
+ { 38, 255, 0}, { 34, 255, 0}, { 30, 255, 0}, { 26, 255, 0}, { 22, 255, 0},
+ { 18, 255, 0}, { 15, 255, 0}, { 11, 255, 0}, { 7, 255, 0}, { 3, 255, 0},
+ { 0, 254, 1}, { 0, 250, 5}, { 0, 247, 8}, { 0, 243, 12}, { 0, 239, 16},
+ { 0, 235, 20}, { 0, 231, 24}, { 0, 227, 28}, { 0, 224, 31}, { 0, 220, 35},
+ { 0, 216, 39}, { 0, 212, 43}, { 0, 208, 47}, { 0, 204, 51}, { 0, 201, 54},
+ { 0, 197, 58}, { 0, 193, 62}, { 0, 189, 66}, { 0, 185, 70}, { 0, 181, 74},
+ { 0, 178, 77}, { 0, 174, 81}, { 0, 170, 85}, { 0, 166, 89}, { 0, 162, 93},
+ { 0, 159, 96}, { 0, 155, 100}, { 0, 151, 104}, { 0, 147, 108}, { 0, 143, 112},
+ { 0, 139, 116}, { 0, 136, 119}, { 0, 132, 123}, { 0, 128, 127}, { 0, 124, 131},
+ { 0, 120, 135}, { 0, 116, 139}, { 0, 113, 142}, { 0, 109, 146}, { 0, 105, 150},
+ { 0, 101, 154}, { 0, 97, 158}, { 0, 93, 162}, { 0, 90, 165}, { 0, 86, 169},
+ { 0, 82, 173}, { 0, 78, 177}, { 0, 74, 181}, { 0, 70, 185}, { 0, 67, 188},
+ { 0, 63, 192}, { 0, 59, 196}, { 0, 55, 200}, { 0, 51, 204}, { 0, 47, 208},
+ { 0, 44, 211}, { 0, 40, 215}, { 0, 36, 219}, { 0, 32, 223}, { 0, 28, 227},
+ { 0, 25, 230}, { 0, 21, 234}, { 0, 17, 238}, { 0, 13, 242}, { 0, 9, 246},
+ { 0, 5, 250}, { 0, 2, 253}, { 2, 0, 255}, { 4, 0, 255}, { 7, 0, 255},
+ { 9, 0, 255}, { 12, 0, 255}, { 14, 0, 255}, { 17, 0, 255}, { 19, 0, 255},
+ { 22, 0, 255}, { 25, 0, 255}, { 27, 0, 255}, { 30, 0, 255}, { 32, 0, 255},
+ { 35, 0, 255}, { 37, 0, 255}, { 40, 0, 255}, { 42, 0, 255}, { 45, 0, 255},
+ { 47, 0, 255}, { 50, 0, 255}, { 53, 0, 255}, { 55, 0, 255}, { 58, 0, 255},
+ { 60, 0, 255}, { 63, 0, 255}, { 65, 0, 255}, { 68, 0, 255}, { 70, 0, 255},
+ { 73, 0, 255}, { 76, 0, 255}, { 78, 0, 255}, { 81, 0, 255}, { 83, 0, 255},
+ { 86, 0, 255}, { 88, 0, 255}, { 91, 0, 255}, { 93, 0, 255}, { 96, 0, 255},
+ { 99, 0, 255}, {101, 0, 255}, {104, 0, 255}, {106, 0, 255}, {109, 0, 255},
+ {111, 0, 255}, {114, 0, 255}, {116, 0, 255}, {119, 0, 255}, {122, 0, 255},
+ {124, 0, 255}, {127, 0, 255}, {129, 0, 255}, {132, 0, 255}, {134, 0, 255},
+ {137, 0, 255}, {139, 0, 255}, {142, 0, 255}, {144, 0, 255}, {147, 0, 255},
+ {150, 0, 255}, {152, 0, 255}, {155, 0, 255}, {157, 0, 255}, {160, 0, 255},
+ {162, 0, 255}, {165, 0, 255}, {167, 0, 255}, {170, 0, 255}, {171, 0, 251},
+ {173, 0, 247}, {174, 0, 244}, {175, 0, 240}, {176, 0, 236}, {178, 0, 232},
+ {179, 0, 228}, {180, 0, 224}, {181, 0, 221}, {183, 0, 217}, {184, 0, 213},
+ {185, 0, 209}, {187, 0, 205}, {188, 0, 201}, {189, 0, 198}, {190, 0, 194},
+ {192, 0, 190}, {193, 0, 186}, {194, 0, 182}, {196, 0, 178}, {197, 0, 175},
+ {198, 0, 171}, {199, 0, 167}, {201, 0, 163}, {202, 0, 159}, {203, 0, 155},
+ {204, 0, 152}, {206, 0, 148}, {207, 0, 144}, {208, 0, 140}, {210, 0, 136},
+ {211, 0, 132}, {212, 0, 129}, {213, 0, 125}, {215, 0, 121}, {216, 0, 117},
+ {217, 0, 113}, {218, 0, 110}, {220, 0, 106}, {221, 0, 102}, {222, 0, 98},
+ {224, 0, 94}, {225, 0, 90}, {226, 0, 87}, {227, 0, 83}, {229, 0, 79},
+ {230, 0, 75}, {231, 0, 71}, {233, 0, 67}, {234, 0, 64}, {235, 0, 60},
+ {236, 0, 56}, {238, 0, 52}, {239, 0, 48}, {240, 0, 44}, {241, 0, 41},
+ {243, 0, 37}, {244, 0, 33}, {245, 0, 29}, {247, 0, 25}, {248, 0, 21},
+ {249, 0, 18}, {250, 0, 14}, {252, 0, 10}, {253, 0, 6}, {254, 0, 2},
+ {255, 1, 0}, {255, 3, 0}, {255, 5, 0}, {255, 7, 0}, {255, 8, 0},
+ {255, 10, 0}, {255, 12, 0}, {255, 14, 0}, {255, 16, 0}, {255, 18, 0},
+ {255, 20, 0}, {255, 22, 0}, {255, 24, 0}, {255, 26, 0}, {255, 28, 0},
+ {255, 29, 0}, {255, 31, 0}, {255, 33, 0}, {255, 35, 0}, {255, 37, 0},
+ {255, 39, 0}, {255, 41, 0}, {255, 43, 0}, {255, 45, 0}, {255, 47, 0},
+ {255, 49, 0}, {255, 51, 0}, {255, 52, 0}, {255, 54, 0}, {255, 56, 0},
+ {255, 58, 0}, {255, 60, 0}, {255, 62, 0}, {255, 64, 0}, {255, 66, 0},
+ {255, 68, 0}, {255, 70, 0}, {255, 72, 0}, {255, 74, 0}, {255, 75, 0},
+ {255, 77, 0}, {255, 79, 0}, {255, 81, 0}, {255, 83, 0}, {255, 85, 0},
+ {255, 87, 0}, {255, 89, 0}, {255, 91, 0}, {255, 93, 0}, {255, 95, 0},
+ {255, 96, 0}, {255, 98, 0}, {255, 100, 0}, {255, 102, 0}, {255, 104, 0},
+ {255, 106, 0}, {255, 108, 0}, {255, 110, 0}, {255, 112, 0}, {255, 114, 0},
+ {255, 116, 0}, {255, 118, 0}, {255, 119, 0}, {255, 121, 0}, {255, 123, 0},
+ {255, 125, 0}, {255, 127, 0}, {255, 129, 0}, {255, 131, 0}, {255, 133, 0},
+ {255, 135, 0}, {255, 137, 0}, {255, 139, 0}, {255, 141, 0}, {255, 142, 0},
+ {255, 144, 0}, {255, 146, 0}, {255, 148, 0}, {255, 150, 0}, {255, 152, 0},
+ {255, 154, 0}, {255, 156, 0}, {255, 158, 0}, {255, 160, 0}, {255, 162, 0},
+ {255, 163, 0}, {255, 165, 0}, {255, 167, 0}, {255, 169, 0}, {255, 171, 0},
+ {255, 173, 0}, {255, 175, 0}, {255, 177, 0}, {255, 179, 0}, {255, 181, 0},
+ {255, 183, 0}, {255, 185, 0}, {255, 186, 0}, {255, 188, 0}, {255, 190, 0},
+ {255, 192, 0}, {255, 194, 0}, {255, 196, 0}, {255, 198, 0}, {255, 200, 0},
+ {255, 202, 0}, {255, 204, 0}, {255, 206, 0}, {255, 208, 0}, {255, 209, 0},
+ {255, 211, 0}, {255, 213, 0}, {255, 215, 0}, {255, 217, 0}, {255, 219, 0},
+ {255, 221, 0}, {255, 223, 0}, {255, 225, 0}, {255, 227, 0}, {255, 229, 0},
+ {255, 230, 0}, {255, 232, 0}, {255, 234, 0}, {255, 236, 0}, {255, 238, 0},
+ {255, 240, 0}, {255, 242, 0}, {255, 244, 0}, {255, 246, 0}, {255, 248, 0},
+ {255, 250, 0}, {255, 252, 0}, {255, 253, 0}, {254, 255, 0}, {250, 255, 0},
+ {247, 255, 0}, {243, 255, 0}, {239, 255, 0}, {235, 255, 0}, {231, 255, 0},
+ {227, 255, 0}, {224, 255, 0}, {220, 255, 0}, {216, 255, 0}, {212, 255, 0},
+ {208, 255, 0}, {204, 255, 0}, {201, 255, 0}, {197, 255, 0}, {193, 255, 0},
+ {189, 255, 0}, {185, 255, 0}, {181, 255, 0}, {178, 255, 0}, {174, 255, 0},
+ {170, 255, 0}, {166, 255, 0}, {162, 255, 0}, {159, 255, 0}, {155, 255, 0},
+ {151, 255, 0}, {147, 255, 0}, {143, 255, 0}, {139, 255, 0}, {136, 255, 0},
+ {132, 255, 0}, {128, 255, 0}, {124, 255, 0}, {120, 255, 0}, {116, 255, 0},
+ {113, 255, 0}, {109, 255, 0}, {105, 255, 0}, {101, 255, 0}, { 97, 255, 0},
+ { 93, 255, 0}, { 90, 255, 0}, { 86, 255, 0}, { 82, 255, 0}, { 78, 255, 0},
+ { 74, 255, 0}, { 70, 255, 0}, { 67, 255, 0}, { 63, 255, 0}, { 59, 255, 0},
+ { 55, 255, 0}, { 51, 255, 0}, { 47, 255, 0}, { 44, 255, 0}, { 40, 255, 0},
+ { 36, 255, 0}, { 32, 255, 0}, { 28, 255, 0}, { 25, 255, 0}, { 21, 255, 0},
+ { 17, 255, 0}, { 13, 255, 0}, { 9, 255, 0}, { 5, 255, 0}, { 2, 255, 0},
+ { 0, 253, 2}, { 0, 249, 6}, { 0, 245, 10}, { 0, 241, 14}, { 0, 237, 18},
+ { 0, 234, 21}, { 0, 230, 25}, { 0, 226, 29}, { 0, 222, 33}, { 0, 218, 37},
+ { 0, 214, 41}, { 0, 211, 44}, { 0, 207, 48}, { 0, 203, 52}, { 0, 199, 56},
+ { 0, 195, 60}, { 0, 191, 64}, { 0, 188, 67}, { 0, 184, 71}, { 0, 180, 75},
+ { 0, 176, 79}, { 0, 172, 83}, { 0, 168, 87}, { 0, 165, 90}, { 0, 161, 94},
+ { 0, 157, 98}, { 0, 153, 102}, { 0, 149, 106}, { 0, 145, 110}, { 0, 142, 113},
+ { 0, 138, 117}, { 0, 134, 121}, { 0, 130, 125}, { 0, 126, 129}, { 0, 123, 132},
+ { 0, 119, 136}, { 0, 115, 140}, { 0, 111, 144}, { 0, 107, 148}, { 0, 103, 152},
+ { 0, 100, 155}, { 0, 96, 159}, { 0, 92, 163}, { 0, 88, 167}, { 0, 84, 171},
+ { 0, 80, 175}, { 0, 77, 178}, { 0, 73, 182}, { 0, 69, 186}, { 0, 65, 190},
+ { 0, 61, 194}, { 0, 57, 198}, { 0, 54, 201}, { 0, 50, 205}, { 0, 46, 209},
+ { 0, 42, 213}, { 0, 38, 217}, { 0, 34, 221}, { 0, 31, 224}, { 0, 27, 228},
+ { 0, 23, 232}, { 0, 19, 236}, { 0, 15, 240}, { 0, 11, 244}, { 0, 8, 247},
+ { 0, 4, 251}, { 0, 0, 255}, { 3, 0, 255}, { 5, 0, 255}, { 8, 0, 255},
+ { 10, 0, 255}, { 13, 0, 255}, { 15, 0, 255}, { 18, 0, 255}, { 20, 0, 255},
+ { 23, 0, 255}, { 26, 0, 255}, { 28, 0, 255}, { 31, 0, 255}, { 33, 0, 255},
+ { 36, 0, 255}, { 38, 0, 255}, { 41, 0, 255}, { 43, 0, 255}, { 46, 0, 255},
+ { 48, 0, 255}, { 51, 0, 255}, { 54, 0, 255}, { 56, 0, 255}, { 59, 0, 255},
+ { 61, 0, 255}, { 64, 0, 255}, { 66, 0, 255}, { 69, 0, 255}, { 71, 0, 255},
+ { 74, 0, 255}, { 77, 0, 255}, { 79, 0, 255}, { 82, 0, 255}, { 84, 0, 255},
+ { 87, 0, 255}, { 89, 0, 255}, { 92, 0, 255}, { 94, 0, 255}, { 97, 0, 255},
+ {100, 0, 255}, {102, 0, 255}, {105, 0, 255}, {107, 0, 255}, {110, 0, 255},
+ {112, 0, 255}, {115, 0, 255}, {117, 0, 255}, {120, 0, 255}, {123, 0, 255},
+ {125, 0, 255}, {128, 0, 255}, {130, 0, 255}, {133, 0, 255}, {135, 0, 255},
+ {138, 0, 255}, {140, 0, 255}, {143, 0, 255}, {145, 0, 255}, {148, 0, 255},
+ {151, 0, 255}, {153, 0, 255}, {156, 0, 255}, {158, 0, 255}, {161, 0, 255},
+ {163, 0, 255}, {166, 0, 255}, {168, 0, 255}, {171, 0, 253}, {172, 0, 250},
+ {173, 0, 246}, {174, 0, 242}, {176, 0, 238}, {177, 0, 234}, {178, 0, 230},
+ {179, 0, 227}, {181, 0, 223}, {182, 0, 219}, {183, 0, 215}, {185, 0, 211},
+ {186, 0, 208}, {187, 0, 204}, {188, 0, 200}, {190, 0, 196}, {191, 0, 192},
+ {192, 0, 188}, {193, 0, 185}, {195, 0, 181}, {196, 0, 177}, {197, 0, 173},
+ {199, 0, 169}, {200, 0, 165}, {201, 0, 162}, {202, 0, 158}, {204, 0, 154},
+ {205, 0, 150}, {206, 0, 146}, {208, 0, 142}, {209, 0, 139}, {210, 0, 135},
+ {211, 0, 131}, {213, 0, 127}, {214, 0, 123}, {215, 0, 119}, {216, 0, 116},
+ {218, 0, 112}, {219, 0, 108}, {220, 0, 104}, {222, 0, 100}, {223, 0, 96},
+ {224, 0, 93}, {225, 0, 89}, {227, 0, 85}, {228, 0, 81}, {229, 0, 77},
+ {230, 0, 74}, {232, 0, 70}, {233, 0, 66}, {234, 0, 62}, {236, 0, 58},
+ {237, 0, 54}, {238, 0, 51}, {239, 0, 47}, {241, 0, 43}, {242, 0, 39},
+ {243, 0, 35}, {245, 0, 31}, {246, 0, 28}, {247, 0, 24}, {248, 0, 20},
+ {250, 0, 16}, {251, 0, 12}, {252, 0, 8}, {253, 0, 5}, {255, 0, 1},
+ {255, 2, 0}, {255, 3, 0}, {255, 5, 0}, {255, 7, 0}, {255, 9, 0},
+ {255, 11, 0}, {255, 13, 0}, {255, 15, 0}, {255, 17, 0}, {255, 19, 0},
+ {255, 21, 0}, {255, 23, 0}, {255, 25, 0}, {255, 26, 0}, {255, 28, 0},
+ {255, 30, 0}, {255, 32, 0}, {255, 34, 0}, {255, 36, 0}, {255, 38, 0},
+ {255, 40, 0}, {255, 42, 0}, {255, 44, 0}, {255, 46, 0}, {255, 47, 0},
+ {255, 49, 0}, {255, 51, 0}, {255, 53, 0}, {255, 55, 0}, {255, 57, 0},
+ {255, 59, 0}, {255, 61, 0}, {255, 63, 0}, {255, 65, 0}, {255, 67, 0},
+ {255, 69, 0}, {255, 70, 0}, {255, 72, 0}, {255, 74, 0}, {255, 76, 0},
+ {255, 78, 0}, {255, 80, 0}, {255, 82, 0}, {255, 84, 0}, {255, 86, 0},
+ {255, 88, 0}, {255, 90, 0}, {255, 92, 0}, {255, 93, 0}, {255, 95, 0},
+ {255, 97, 0}, {255, 99, 0}, {255, 101, 0}, {255, 103, 0}, {255, 105, 0},
+ {255, 107, 0}, {255, 109, 0}, {255, 111, 0}, {255, 113, 0}, {255, 114, 0},
+ {255, 116, 0}, {255, 118, 0}, {255, 120, 0}, {255, 122, 0}, {255, 124, 0},
+ {255, 126, 0}, {255, 128, 0}, {255, 130, 0}, {255, 132, 0}, {255, 134, 0},
+ {255, 136, 0}, {255, 137, 0}, {255, 139, 0}, {255, 141, 0}, {255, 143, 0},
+ {255, 145, 0}, {255, 147, 0}, {255, 149, 0}, {255, 151, 0}, {255, 153, 0},
+ {255, 155, 0}, {255, 157, 0}, {255, 159, 0}, {255, 160, 0}, {255, 162, 0},
+ {255, 164, 0}, {255, 166, 0}, {255, 168, 0}, {255, 170, 0}, {255, 172, 0},
+ {255, 174, 0}, {255, 176, 0}, {255, 178, 0}, {255, 180, 0}, {255, 181, 0},
+ {255, 183, 0}, {255, 185, 0}, {255, 187, 0}, {255, 189, 0}, {255, 191, 0},
+ {255, 193, 0}, {255, 195, 0}, {255, 197, 0}, {255, 199, 0}, {255, 201, 0},
+ {255, 203, 0}, {255, 204, 0}, {255, 206, 0}, {255, 208, 0}, {255, 210, 0},
+ {255, 212, 0}, {255, 214, 0}, {255, 216, 0}, {255, 218, 0}, {255, 220, 0},
+ {255, 222, 0}, {255, 224, 0}, {255, 226, 0}, {255, 227, 0}, {255, 229, 0},
+ {255, 231, 0}, {255, 233, 0}, {255, 235, 0}, {255, 237, 0}, {255, 239, 0},
+ {255, 241, 0}, {255, 243, 0}, {255, 245, 0}, {255, 247, 0}, {255, 248, 0},
+ {255, 250, 0}, {255, 252, 0}, {255, 254, 0}, {253, 255, 0}, {249, 255, 0},
+ {245, 255, 0}, {241, 255, 0}, {237, 255, 0}, {234, 255, 0}, {230, 255, 0},
+ {226, 255, 0}, {222, 255, 0}, {218, 255, 0}, {214, 255, 0}, {211, 255, 0},
+ {207, 255, 0}, {203, 255, 0}, {199, 255, 0}, {195, 255, 0}, {191, 255, 0},
+ {188, 255, 0}, {184, 255, 0}, {180, 255, 0}, {176, 255, 0}, {172, 255, 0},
+ {168, 255, 0}, {165, 255, 0}, {161, 255, 0}, {157, 255, 0}, {153, 255, 0},
+ {149, 255, 0}, {145, 255, 0}, {142, 255, 0}, {138, 255, 0}, {134, 255, 0},
+ {130, 255, 0}, {126, 255, 0}, {123, 255, 0}, {119, 255, 0}, {115, 255, 0},
+ {111, 255, 0}, {107, 255, 0}, {103, 255, 0}, {100, 255, 0}, { 96, 255, 0},
+ { 92, 255, 0}, { 88, 255, 0}, { 84, 255, 0}, { 80, 255, 0}, { 77, 255, 0},
+ { 73, 255, 0}, { 69, 255, 0}, { 65, 255, 0}, { 61, 255, 0}, { 57, 255, 0},
+ { 54, 255, 0}, { 50, 255, 0}, { 46, 255, 0}, { 42, 255, 0}, { 38, 255, 0},
+ { 34, 255, 0}, { 31, 255, 0}, { 27, 255, 0}, { 23, 255, 0}, { 19, 255, 0},
+ { 15, 255, 0}, { 11, 255, 0}, { 8, 255, 0}, { 4, 255, 0}, { 0, 255, 0}
+};
+
+const rgb_t vga_colormap[1000] = {
+ {255, 255, 255}, {254, 254, 254}, {253, 253, 253}, {252, 252, 252}, {251, 251, 251},
+ {250, 250, 250}, {249, 249, 249}, {248, 248, 248}, {247, 247, 247}, {246, 246, 246},
+ {245, 245, 245}, {244, 244, 244}, {244, 244, 244}, {243, 243, 243}, {242, 242, 242},
+ {241, 241, 241}, {240, 240, 240}, {239, 239, 239}, {238, 238, 238}, {237, 237, 237},
+ {236, 236, 236}, {235, 235, 235}, {234, 234, 234}, {233, 233, 233}, {232, 232, 232},
+ {231, 231, 231}, {230, 230, 230}, {229, 229, 229}, {228, 228, 228}, {227, 227, 227},
+ {226, 226, 226}, {225, 225, 225}, {224, 224, 224}, {223, 223, 223}, {222, 222, 222},
+ {221, 221, 221}, {221, 221, 221}, {220, 220, 220}, {219, 219, 219}, {218, 218, 218},
+ {217, 217, 217}, {216, 216, 216}, {215, 215, 215}, {214, 214, 214}, {213, 213, 213},
+ {212, 212, 212}, {211, 211, 211}, {210, 210, 210}, {209, 209, 209}, {208, 208, 208},
+ {207, 207, 207}, {206, 206, 206}, {205, 205, 205}, {204, 204, 204}, {203, 203, 203},
+ {202, 202, 202}, {201, 201, 201}, {200, 200, 200}, {199, 199, 199}, {199, 199, 199},
+ {198, 198, 198}, {197, 197, 197}, {196, 196, 196}, {195, 195, 195}, {194, 194, 194},
+ {193, 193, 193}, {192, 192, 192}, {192, 190, 190}, {193, 187, 187}, {194, 184, 184},
+ {195, 181, 181}, {195, 179, 179}, {196, 176, 176}, {197, 173, 173}, {198, 170, 170},
+ {199, 167, 167}, {200, 164, 164}, {201, 161, 161}, {202, 159, 159}, {203, 156, 156},
+ {204, 153, 153}, {205, 150, 150}, {206, 147, 147}, {207, 144, 144}, {208, 141, 141},
+ {209, 138, 138}, {210, 136, 136}, {211, 133, 133}, {212, 130, 130}, {213, 127, 127},
+ {214, 124, 124}, {215, 121, 121}, {216, 118, 118}, {217, 115, 115}, {217, 113, 113},
+ {218, 110, 110}, {219, 107, 107}, {220, 104, 104}, {221, 101, 101}, {222, 98, 98},
+ {223, 95, 95}, {224, 92, 92}, {225, 90, 90}, {226, 87, 87}, {227, 84, 84},
+ {228, 81, 81}, {229, 78, 78}, {230, 75, 75}, {231, 72, 72}, {232, 69, 69},
+ {233, 67, 67}, {234, 64, 64}, {235, 61, 61}, {236, 58, 58}, {237, 55, 55},
+ {238, 52, 52}, {239, 49, 49}, {239, 47, 47}, {240, 44, 44}, {241, 41, 41},
+ {242, 38, 38}, {243, 35, 35}, {244, 32, 32}, {245, 29, 29}, {246, 26, 26},
+ {247, 24, 24}, {248, 21, 21}, {249, 18, 18}, {250, 15, 15}, {251, 12, 12},
+ {252, 9, 9}, {253, 6, 6}, {254, 3, 3}, {255, 1, 1}, {255, 3, 0},
+ {255, 7, 0}, {255, 11, 0}, {255, 15, 0}, {255, 18, 0}, {255, 22, 0},
+ {255, 26, 0}, {255, 30, 0}, {255, 34, 0}, {255, 38, 0}, {255, 41, 0},
+ {255, 45, 0}, {255, 49, 0}, {255, 53, 0}, {255, 57, 0}, {255, 60, 0},
+ {255, 64, 0}, {255, 68, 0}, {255, 72, 0}, {255, 76, 0}, {255, 80, 0},
+ {255, 83, 0}, {255, 87, 0}, {255, 91, 0}, {255, 95, 0}, {255, 99, 0},
+ {255, 103, 0}, {255, 106, 0}, {255, 110, 0}, {255, 114, 0}, {255, 118, 0},
+ {255, 122, 0}, {255, 126, 0}, {255, 129, 0}, {255, 133, 0}, {255, 137, 0},
+ {255, 141, 0}, {255, 145, 0}, {255, 149, 0}, {255, 152, 0}, {255, 156, 0},
+ {255, 160, 0}, {255, 164, 0}, {255, 168, 0}, {255, 172, 0}, {255, 175, 0},
+ {255, 179, 0}, {255, 183, 0}, {255, 187, 0}, {255, 191, 0}, {255, 195, 0},
+ {255, 198, 0}, {255, 202, 0}, {255, 206, 0}, {255, 210, 0}, {255, 214, 0},
+ {255, 217, 0}, {255, 221, 0}, {255, 225, 0}, {255, 229, 0}, {255, 233, 0},
+ {255, 237, 0}, {255, 240, 0}, {255, 244, 0}, {255, 248, 0}, {255, 252, 0},
+ {254, 255, 0}, {250, 255, 0}, {247, 255, 0}, {243, 255, 0}, {239, 255, 0},
+ {235, 255, 0}, {231, 255, 0}, {227, 255, 0}, {224, 255, 0}, {220, 255, 0},
+ {216, 255, 0}, {212, 255, 0}, {208, 255, 0}, {204, 255, 0}, {201, 255, 0},
+ {197, 255, 0}, {193, 255, 0}, {189, 255, 0}, {185, 255, 0}, {181, 255, 0},
+ {178, 255, 0}, {174, 255, 0}, {170, 255, 0}, {166, 255, 0}, {162, 255, 0},
+ {159, 255, 0}, {155, 255, 0}, {151, 255, 0}, {147, 255, 0}, {143, 255, 0},
+ {139, 255, 0}, {136, 255, 0}, {132, 255, 0}, {128, 255, 0}, {124, 255, 0},
+ {120, 255, 0}, {116, 255, 0}, {113, 255, 0}, {109, 255, 0}, {105, 255, 0},
+ {101, 255, 0}, { 97, 255, 0}, { 93, 255, 0}, { 90, 255, 0}, { 86, 255, 0},
+ { 82, 255, 0}, { 78, 255, 0}, { 74, 255, 0}, { 70, 255, 0}, { 67, 255, 0},
+ { 63, 255, 0}, { 59, 255, 0}, { 55, 255, 0}, { 51, 255, 0}, { 47, 255, 0},
+ { 44, 255, 0}, { 40, 255, 0}, { 36, 255, 0}, { 32, 255, 0}, { 28, 255, 0},
+ { 25, 255, 0}, { 21, 255, 0}, { 17, 255, 0}, { 13, 255, 0}, { 9, 255, 0},
+ { 5, 255, 0}, { 2, 255, 0}, { 0, 255, 2}, { 0, 255, 6}, { 0, 255, 10},
+ { 0, 255, 14}, { 0, 255, 18}, { 0, 255, 21}, { 0, 255, 25}, { 0, 255, 29},
+ { 0, 255, 33}, { 0, 255, 37}, { 0, 255, 41}, { 0, 255, 44}, { 0, 255, 48},
+ { 0, 255, 52}, { 0, 255, 56}, { 0, 255, 60}, { 0, 255, 64}, { 0, 255, 67},
+ { 0, 255, 71}, { 0, 255, 75}, { 0, 255, 79}, { 0, 255, 83}, { 0, 255, 87},
+ { 0, 255, 90}, { 0, 255, 94}, { 0, 255, 98}, { 0, 255, 102}, { 0, 255, 106},
+ { 0, 255, 110}, { 0, 255, 113}, { 0, 255, 117}, { 0, 255, 121}, { 0, 255, 125},
+ { 0, 255, 129}, { 0, 255, 132}, { 0, 255, 136}, { 0, 255, 140}, { 0, 255, 144},
+ { 0, 255, 148}, { 0, 255, 152}, { 0, 255, 155}, { 0, 255, 159}, { 0, 255, 163},
+ { 0, 255, 167}, { 0, 255, 171}, { 0, 255, 175}, { 0, 255, 178}, { 0, 255, 182},
+ { 0, 255, 186}, { 0, 255, 190}, { 0, 255, 194}, { 0, 255, 198}, { 0, 255, 201},
+ { 0, 255, 205}, { 0, 255, 209}, { 0, 255, 213}, { 0, 255, 217}, { 0, 255, 221},
+ { 0, 255, 224}, { 0, 255, 228}, { 0, 255, 232}, { 0, 255, 236}, { 0, 255, 240},
+ { 0, 255, 244}, { 0, 255, 247}, { 0, 255, 251}, { 0, 255, 255}, { 0, 251, 255},
+ { 0, 247, 255}, { 0, 244, 255}, { 0, 240, 255}, { 0, 236, 255}, { 0, 232, 255},
+ { 0, 228, 255}, { 0, 224, 255}, { 0, 221, 255}, { 0, 217, 255}, { 0, 213, 255},
+ { 0, 209, 255}, { 0, 205, 255}, { 0, 201, 255}, { 0, 198, 255}, { 0, 194, 255},
+ { 0, 190, 255}, { 0, 186, 255}, { 0, 182, 255}, { 0, 178, 255}, { 0, 175, 255},
+ { 0, 171, 255}, { 0, 167, 255}, { 0, 163, 255}, { 0, 159, 255}, { 0, 155, 255},
+ { 0, 152, 255}, { 0, 148, 255}, { 0, 144, 255}, { 0, 140, 255}, { 0, 136, 255},
+ { 0, 132, 255}, { 0, 129, 255}, { 0, 125, 255}, { 0, 121, 255}, { 0, 117, 255},
+ { 0, 113, 255}, { 0, 110, 255}, { 0, 106, 255}, { 0, 102, 255}, { 0, 98, 255},
+ { 0, 94, 255}, { 0, 90, 255}, { 0, 87, 255}, { 0, 83, 255}, { 0, 79, 255},
+ { 0, 75, 255}, { 0, 71, 255}, { 0, 67, 255}, { 0, 64, 255}, { 0, 60, 255},
+ { 0, 56, 255}, { 0, 52, 255}, { 0, 48, 255}, { 0, 44, 255}, { 0, 41, 255},
+ { 0, 37, 255}, { 0, 33, 255}, { 0, 29, 255}, { 0, 25, 255}, { 0, 21, 255},
+ { 0, 18, 255}, { 0, 14, 255}, { 0, 10, 255}, { 0, 6, 255}, { 0, 2, 255},
+ { 2, 0, 255}, { 5, 0, 255}, { 9, 0, 255}, { 13, 0, 255}, { 17, 0, 255},
+ { 21, 0, 255}, { 25, 0, 255}, { 28, 0, 255}, { 32, 0, 255}, { 36, 0, 255},
+ { 40, 0, 255}, { 44, 0, 255}, { 47, 0, 255}, { 51, 0, 255}, { 55, 0, 255},
+ { 59, 0, 255}, { 63, 0, 255}, { 67, 0, 255}, { 70, 0, 255}, { 74, 0, 255},
+ { 78, 0, 255}, { 82, 0, 255}, { 86, 0, 255}, { 90, 0, 255}, { 93, 0, 255},
+ { 97, 0, 255}, {101, 0, 255}, {105, 0, 255}, {109, 0, 255}, {113, 0, 255},
+ {116, 0, 255}, {120, 0, 255}, {124, 0, 255}, {128, 0, 255}, {132, 0, 255},
+ {136, 0, 255}, {139, 0, 255}, {143, 0, 255}, {147, 0, 255}, {151, 0, 255},
+ {155, 0, 255}, {159, 0, 255}, {162, 0, 255}, {166, 0, 255}, {170, 0, 255},
+ {174, 0, 255}, {178, 0, 255}, {181, 0, 255}, {185, 0, 255}, {189, 0, 255},
+ {193, 0, 255}, {197, 0, 255}, {201, 0, 255}, {204, 0, 255}, {208, 0, 255},
+ {212, 0, 255}, {216, 0, 255}, {220, 0, 255}, {224, 0, 255}, {227, 0, 255},
+ {231, 0, 255}, {235, 0, 255}, {239, 0, 255}, {243, 0, 255}, {247, 0, 255},
+ {250, 0, 255}, {254, 0, 255}, {252, 0, 252}, {248, 0, 248}, {244, 0, 244},
+ {240, 0, 240}, {237, 0, 237}, {233, 0, 233}, {229, 0, 229}, {225, 0, 225},
+ {221, 0, 221}, {217, 0, 217}, {214, 0, 214}, {210, 0, 210}, {206, 0, 206},
+ {202, 0, 202}, {198, 0, 198}, {195, 0, 195}, {191, 0, 191}, {187, 0, 187},
+ {183, 0, 183}, {179, 0, 179}, {175, 0, 175}, {172, 0, 172}, {168, 0, 168},
+ {164, 0, 164}, {160, 0, 160}, {156, 0, 156}, {152, 0, 152}, {149, 0, 149},
+ {145, 0, 145}, {141, 0, 141}, {137, 0, 137}, {133, 0, 133}, {129, 0, 129},
+ {126, 0, 126}, {122, 0, 122}, {118, 0, 118}, {114, 0, 114}, {110, 0, 110},
+ {106, 0, 106}, {103, 0, 103}, { 99, 0, 99}, { 95, 0, 95}, { 91, 0, 91},
+ { 87, 0, 87}, { 83, 0, 83}, { 80, 0, 80}, { 76, 0, 76}, { 72, 0, 72},
+ { 68, 0, 68}, { 64, 0, 64}, { 60, 0, 60}, { 57, 0, 57}, { 53, 0, 53},
+ { 49, 0, 49}, { 45, 0, 45}, { 41, 0, 41}, { 38, 0, 38}, { 34, 0, 34},
+ { 30, 0, 30}, { 26, 0, 26}, { 22, 0, 22}, { 18, 0, 18}, { 15, 0, 15},
+ { 11, 0, 11}, { 7, 0, 7}, { 3, 0, 3}, { 0, 0, 0}, { 2, 2, 2},
+ { 4, 4, 4}, { 6, 6, 6}, { 8, 8, 8}, { 10, 10, 10}, { 12, 12, 12},
+ { 14, 14, 14}, { 16, 16, 16}, { 18, 18, 18}, { 20, 20, 20}, { 21, 21, 21},
+ { 23, 23, 23}, { 25, 25, 25}, { 27, 27, 27}, { 29, 29, 29}, { 31, 31, 31},
+ { 33, 33, 33}, { 35, 35, 35}, { 37, 37, 37}, { 39, 39, 39}, { 41, 41, 41},
+ { 43, 43, 43}, { 44, 44, 44}, { 46, 46, 46}, { 48, 48, 48}, { 50, 50, 50},
+ { 52, 52, 52}, { 54, 54, 54}, { 56, 56, 56}, { 58, 58, 58}, { 60, 60, 60},
+ { 62, 62, 62}, { 64, 64, 64}, { 65, 65, 65}, { 67, 67, 67}, { 69, 69, 69},
+ { 71, 71, 71}, { 73, 73, 73}, { 75, 75, 75}, { 77, 77, 77}, { 79, 79, 79},
+ { 81, 81, 81}, { 83, 83, 83}, { 85, 85, 85}, { 87, 87, 87}, { 88, 88, 88},
+ { 90, 90, 90}, { 92, 92, 92}, { 94, 94, 94}, { 96, 96, 96}, { 98, 98, 98},
+ {100, 100, 100}, {102, 102, 102}, {104, 104, 104}, {106, 106, 106}, {108, 108, 108},
+ {110, 110, 110}, {111, 111, 111}, {113, 113, 113}, {115, 115, 115}, {117, 117, 117},
+ {119, 119, 119}, {121, 121, 121}, {123, 123, 123}, {125, 125, 125}, {127, 127, 127},
+ {128, 126, 126}, {128, 124, 124}, {128, 123, 123}, {128, 121, 121}, {128, 119, 119},
+ {128, 117, 117}, {128, 115, 115}, {128, 113, 113}, {128, 111, 111}, {128, 109, 109},
+ {128, 107, 107}, {128, 105, 105}, {128, 103, 103}, {128, 101, 101}, {128, 100, 100},
+ {128, 98, 98}, {128, 96, 96}, {128, 94, 94}, {128, 92, 92}, {128, 90, 90},
+ {128, 88, 88}, {128, 86, 86}, {128, 84, 84}, {128, 82, 82}, {128, 80, 80},
+ {128, 78, 78}, {128, 77, 77}, {128, 75, 75}, {128, 73, 73}, {128, 71, 71},
+ {128, 69, 69}, {128, 67, 67}, {128, 65, 65}, {128, 63, 63}, {128, 61, 61},
+ {128, 59, 59}, {128, 57, 57}, {128, 56, 56}, {128, 54, 54}, {128, 52, 52},
+ {128, 50, 50}, {128, 48, 48}, {128, 46, 46}, {128, 44, 44}, {128, 42, 42},
+ {128, 40, 40}, {128, 38, 38}, {128, 36, 36}, {128, 34, 34}, {128, 33, 33},
+ {128, 31, 31}, {128, 29, 29}, {128, 27, 27}, {128, 25, 25}, {128, 23, 23},
+ {128, 21, 21}, {128, 19, 19}, {128, 17, 17}, {128, 15, 15}, {128, 13, 13},
+ {128, 11, 11}, {128, 10, 10}, {128, 8, 8}, {128, 6, 6}, {128, 4, 4},
+ {128, 2, 2}, {128, 0, 0}, {128, 2, 0}, {128, 4, 0}, {128, 6, 0},
+ {128, 8, 0}, {128, 10, 0}, {128, 11, 0}, {128, 13, 0}, {128, 15, 0},
+ {128, 17, 0}, {128, 19, 0}, {128, 21, 0}, {128, 23, 0}, {128, 25, 0},
+ {128, 27, 0}, {128, 29, 0}, {128, 31, 0}, {128, 33, 0}, {128, 34, 0},
+ {128, 36, 0}, {128, 38, 0}, {128, 40, 0}, {128, 42, 0}, {128, 44, 0},
+ {128, 46, 0}, {128, 48, 0}, {128, 50, 0}, {128, 52, 0}, {128, 54, 0},
+ {128, 56, 0}, {128, 57, 0}, {128, 59, 0}, {128, 61, 0}, {128, 63, 0},
+ {128, 65, 0}, {128, 67, 0}, {128, 69, 0}, {128, 71, 0}, {128, 73, 0},
+ {128, 75, 0}, {128, 77, 0}, {128, 78, 0}, {128, 80, 0}, {128, 82, 0},
+ {128, 84, 0}, {128, 86, 0}, {128, 88, 0}, {128, 90, 0}, {128, 92, 0},
+ {128, 94, 0}, {128, 96, 0}, {128, 98, 0}, {128, 100, 0}, {128, 101, 0},
+ {128, 103, 0}, {128, 105, 0}, {128, 107, 0}, {128, 109, 0}, {128, 111, 0},
+ {128, 113, 0}, {128, 115, 0}, {128, 117, 0}, {128, 119, 0}, {128, 121, 0},
+ {128, 123, 0}, {128, 124, 0}, {128, 126, 0}, {127, 128, 0}, {125, 128, 0},
+ {123, 128, 0}, {121, 128, 0}, {119, 128, 0}, {117, 128, 0}, {115, 128, 0},
+ {113, 128, 0}, {111, 128, 0}, {110, 128, 0}, {108, 128, 0}, {106, 128, 0},
+ {104, 128, 0}, {102, 128, 0}, {100, 128, 0}, { 98, 128, 0}, { 96, 128, 0},
+ { 94, 128, 0}, { 92, 128, 0}, { 90, 128, 0}, { 88, 128, 0}, { 87, 128, 0},
+ { 85, 128, 0}, { 83, 128, 0}, { 81, 128, 0}, { 79, 128, 0}, { 77, 128, 0},
+ { 75, 128, 0}, { 73, 128, 0}, { 71, 128, 0}, { 69, 128, 0}, { 67, 128, 0},
+ { 65, 128, 0}, { 64, 128, 0}, { 62, 128, 0}, { 60, 128, 0}, { 58, 128, 0},
+ { 56, 128, 0}, { 54, 128, 0}, { 52, 128, 0}, { 50, 128, 0}, { 48, 128, 0},
+ { 46, 128, 0}, { 44, 128, 0}, { 43, 128, 0}, { 41, 128, 0}, { 39, 128, 0},
+ { 37, 128, 0}, { 35, 128, 0}, { 33, 128, 0}, { 31, 128, 0}, { 29, 128, 0},
+ { 27, 128, 0}, { 25, 128, 0}, { 23, 128, 0}, { 21, 128, 0}, { 20, 128, 0},
+ { 18, 128, 0}, { 16, 128, 0}, { 14, 128, 0}, { 12, 128, 0}, { 10, 128, 0},
+ { 8, 128, 0}, { 6, 128, 0}, { 4, 128, 0}, { 2, 128, 0}, { 0, 128, 0},
+ { 0, 128, 2}, { 0, 128, 3}, { 0, 128, 5}, { 0, 128, 7}, { 0, 128, 9},
+ { 0, 128, 11}, { 0, 128, 13}, { 0, 128, 15}, { 0, 128, 17}, { 0, 128, 19},
+ { 0, 128, 21}, { 0, 128, 23}, { 0, 128, 25}, { 0, 128, 26}, { 0, 128, 28},
+ { 0, 128, 30}, { 0, 128, 32}, { 0, 128, 34}, { 0, 128, 36}, { 0, 128, 38},
+ { 0, 128, 40}, { 0, 128, 42}, { 0, 128, 44}, { 0, 128, 46}, { 0, 128, 47},
+ { 0, 128, 49}, { 0, 128, 51}, { 0, 128, 53}, { 0, 128, 55}, { 0, 128, 57},
+ { 0, 128, 59}, { 0, 128, 61}, { 0, 128, 63}, { 0, 128, 65}, { 0, 128, 67},
+ { 0, 128, 69}, { 0, 128, 70}, { 0, 128, 72}, { 0, 128, 74}, { 0, 128, 76},
+ { 0, 128, 78}, { 0, 128, 80}, { 0, 128, 82}, { 0, 128, 84}, { 0, 128, 86},
+ { 0, 128, 88}, { 0, 128, 90}, { 0, 128, 92}, { 0, 128, 93}, { 0, 128, 95},
+ { 0, 128, 97}, { 0, 128, 99}, { 0, 128, 101}, { 0, 128, 103}, { 0, 128, 105},
+ { 0, 128, 107}, { 0, 128, 109}, { 0, 128, 111}, { 0, 128, 113}, { 0, 128, 114},
+ { 0, 128, 116}, { 0, 128, 118}, { 0, 128, 120}, { 0, 128, 122}, { 0, 128, 124},
+ { 0, 128, 126}, { 0, 127, 128}, { 0, 125, 128}, { 0, 123, 128}, { 0, 121, 128},
+ { 0, 119, 128}, { 0, 118, 128}, { 0, 116, 128}, { 0, 114, 128}, { 0, 112, 128},
+ { 0, 110, 128}, { 0, 108, 128}, { 0, 106, 128}, { 0, 104, 128}, { 0, 102, 128},
+ { 0, 100, 128}, { 0, 98, 128}, { 0, 96, 128}, { 0, 95, 128}, { 0, 93, 128},
+ { 0, 91, 128}, { 0, 89, 128}, { 0, 87, 128}, { 0, 85, 128}, { 0, 83, 128},
+ { 0, 81, 128}, { 0, 79, 128}, { 0, 77, 128}, { 0, 75, 128}, { 0, 74, 128},
+ { 0, 72, 128}, { 0, 70, 128}, { 0, 68, 128}, { 0, 66, 128}, { 0, 64, 128},
+ { 0, 62, 128}, { 0, 60, 128}, { 0, 58, 128}, { 0, 56, 128}, { 0, 54, 128},
+ { 0, 52, 128}, { 0, 51, 128}, { 0, 49, 128}, { 0, 47, 128}, { 0, 45, 128},
+ { 0, 43, 128}, { 0, 41, 128}, { 0, 39, 128}, { 0, 37, 128}, { 0, 35, 128},
+ { 0, 33, 128}, { 0, 31, 128}, { 0, 29, 128}, { 0, 28, 128}, { 0, 26, 128},
+ { 0, 24, 128}, { 0, 22, 128}, { 0, 20, 128}, { 0, 18, 128}, { 0, 16, 128},
+ { 0, 14, 128}, { 0, 12, 128}, { 0, 10, 128}, { 0, 8, 128}, { 0, 7, 128},
+ { 0, 5, 128}, { 0, 3, 128}, { 0, 1, 128}, { 1, 0, 128}, { 3, 0, 128},
+ { 5, 0, 128}, { 7, 0, 128}, { 9, 0, 128}, { 11, 0, 128}, { 13, 0, 128},
+ { 15, 0, 128}, { 16, 0, 128}, { 18, 0, 128}, { 20, 0, 128}, { 22, 0, 128},
+ { 24, 0, 128}, { 26, 0, 128}, { 28, 0, 128}, { 30, 0, 128}, { 32, 0, 128},
+ { 34, 0, 128}, { 36, 0, 128}, { 38, 0, 128}, { 39, 0, 128}, { 41, 0, 128},
+ { 43, 0, 128}, { 45, 0, 128}, { 47, 0, 128}, { 49, 0, 128}, { 51, 0, 128},
+ { 53, 0, 128}, { 55, 0, 128}, { 57, 0, 128}, { 59, 0, 128}, { 60, 0, 128},
+ { 62, 0, 128}, { 64, 0, 128}, { 66, 0, 128}, { 68, 0, 128}, { 70, 0, 128},
+ { 72, 0, 128}, { 74, 0, 128}, { 76, 0, 128}, { 78, 0, 128}, { 80, 0, 128},
+ { 82, 0, 128}, { 83, 0, 128}, { 85, 0, 128}, { 87, 0, 128}, { 89, 0, 128},
+ { 91, 0, 128}, { 93, 0, 128}, { 95, 0, 128}, { 97, 0, 128}, { 99, 0, 128},
+ {101, 0, 128}, {103, 0, 128}, {105, 0, 128}, {106, 0, 128}, {108, 0, 128},
+ {110, 0, 128}, {112, 0, 128}, {114, 0, 128}, {116, 0, 128}, {118, 0, 128},
+ {120, 0, 128}, {122, 0, 128}, {124, 0, 128}, {126, 0, 128}, {128, 0, 128}
+};
+
+const rgb_t yarg_colormap[1000] = {
+ { 0, 0, 0}, { 0, 0, 0}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1},
+ { 1, 1, 1}, { 2, 2, 2}, { 2, 2, 2}, { 2, 2, 2}, { 2, 2, 2},
+ { 3, 3, 3}, { 3, 3, 3}, { 3, 3, 3}, { 3, 3, 3}, { 4, 4, 4},
+ { 4, 4, 4}, { 4, 4, 4}, { 4, 4, 4}, { 5, 5, 5}, { 5, 5, 5},
+ { 5, 5, 5}, { 5, 5, 5}, { 6, 6, 6}, { 6, 6, 6}, { 6, 6, 6},
+ { 6, 6, 6}, { 7, 7, 7}, { 7, 7, 7}, { 7, 7, 7}, { 7, 7, 7},
+ { 8, 8, 8}, { 8, 8, 8}, { 8, 8, 8}, { 8, 8, 8}, { 9, 9, 9},
+ { 9, 9, 9}, { 9, 9, 9}, { 9, 9, 9}, { 10, 10, 10}, { 10, 10, 10},
+ { 10, 10, 10}, { 10, 10, 10}, { 11, 11, 11}, { 11, 11, 11}, { 11, 11, 11},
+ { 11, 11, 11}, { 12, 12, 12}, { 12, 12, 12}, { 12, 12, 12}, { 13, 13, 13},
+ { 13, 13, 13}, { 13, 13, 13}, { 13, 13, 13}, { 14, 14, 14}, { 14, 14, 14},
+ { 14, 14, 14}, { 14, 14, 14}, { 15, 15, 15}, { 15, 15, 15}, { 15, 15, 15},
+ { 15, 15, 15}, { 16, 16, 16}, { 16, 16, 16}, { 16, 16, 16}, { 16, 16, 16},
+ { 17, 17, 17}, { 17, 17, 17}, { 17, 17, 17}, { 17, 17, 17}, { 18, 18, 18},
+ { 18, 18, 18}, { 18, 18, 18}, { 18, 18, 18}, { 19, 19, 19}, { 19, 19, 19},
+ { 19, 19, 19}, { 19, 19, 19}, { 20, 20, 20}, { 20, 20, 20}, { 20, 20, 20},
+ { 20, 20, 20}, { 21, 21, 21}, { 21, 21, 21}, { 21, 21, 21}, { 21, 21, 21},
+ { 22, 22, 22}, { 22, 22, 22}, { 22, 22, 22}, { 22, 22, 22}, { 23, 23, 23},
+ { 23, 23, 23}, { 23, 23, 23}, { 23, 23, 23}, { 24, 24, 24}, { 24, 24, 24},
+ { 24, 24, 24}, { 25, 25, 25}, { 25, 25, 25}, { 25, 25, 25}, { 25, 25, 25},
+ { 26, 26, 26}, { 26, 26, 26}, { 26, 26, 26}, { 26, 26, 26}, { 27, 27, 27},
+ { 27, 27, 27}, { 27, 27, 27}, { 27, 27, 27}, { 28, 28, 28}, { 28, 28, 28},
+ { 28, 28, 28}, { 28, 28, 28}, { 29, 29, 29}, { 29, 29, 29}, { 29, 29, 29},
+ { 29, 29, 29}, { 30, 30, 30}, { 30, 30, 30}, { 30, 30, 30}, { 30, 30, 30},
+ { 31, 31, 31}, { 31, 31, 31}, { 31, 31, 31}, { 31, 31, 31}, { 32, 32, 32},
+ { 32, 32, 32}, { 32, 32, 32}, { 32, 32, 32}, { 33, 33, 33}, { 33, 33, 33},
+ { 33, 33, 33}, { 33, 33, 33}, { 34, 34, 34}, { 34, 34, 34}, { 34, 34, 34},
+ { 34, 34, 34}, { 35, 35, 35}, { 35, 35, 35}, { 35, 35, 35}, { 35, 35, 35},
+ { 36, 36, 36}, { 36, 36, 36}, { 36, 36, 36}, { 37, 37, 37}, { 37, 37, 37},
+ { 37, 37, 37}, { 37, 37, 37}, { 38, 38, 38}, { 38, 38, 38}, { 38, 38, 38},
+ { 38, 38, 38}, { 39, 39, 39}, { 39, 39, 39}, { 39, 39, 39}, { 39, 39, 39},
+ { 40, 40, 40}, { 40, 40, 40}, { 40, 40, 40}, { 40, 40, 40}, { 41, 41, 41},
+ { 41, 41, 41}, { 41, 41, 41}, { 41, 41, 41}, { 42, 42, 42}, { 42, 42, 42},
+ { 42, 42, 42}, { 42, 42, 42}, { 43, 43, 43}, { 43, 43, 43}, { 43, 43, 43},
+ { 43, 43, 43}, { 44, 44, 44}, { 44, 44, 44}, { 44, 44, 44}, { 44, 44, 44},
+ { 45, 45, 45}, { 45, 45, 45}, { 45, 45, 45}, { 45, 45, 45}, { 46, 46, 46},
+ { 46, 46, 46}, { 46, 46, 46}, { 46, 46, 46}, { 47, 47, 47}, { 47, 47, 47},
+ { 47, 47, 47}, { 47, 47, 47}, { 48, 48, 48}, { 48, 48, 48}, { 48, 48, 48},
+ { 48, 48, 48}, { 49, 49, 49}, { 49, 49, 49}, { 49, 49, 49}, { 50, 50, 50},
+ { 50, 50, 50}, { 50, 50, 50}, { 50, 50, 50}, { 51, 51, 51}, { 51, 51, 51},
+ { 51, 51, 51}, { 51, 51, 51}, { 52, 52, 52}, { 52, 52, 52}, { 52, 52, 52},
+ { 52, 52, 52}, { 53, 53, 53}, { 53, 53, 53}, { 53, 53, 53}, { 53, 53, 53},
+ { 54, 54, 54}, { 54, 54, 54}, { 54, 54, 54}, { 54, 54, 54}, { 55, 55, 55},
+ { 55, 55, 55}, { 55, 55, 55}, { 55, 55, 55}, { 56, 56, 56}, { 56, 56, 56},
+ { 56, 56, 56}, { 56, 56, 56}, { 57, 57, 57}, { 57, 57, 57}, { 57, 57, 57},
+ { 57, 57, 57}, { 58, 58, 58}, { 58, 58, 58}, { 58, 58, 58}, { 58, 58, 58},
+ { 59, 59, 59}, { 59, 59, 59}, { 59, 59, 59}, { 59, 59, 59}, { 60, 60, 60},
+ { 60, 60, 60}, { 60, 60, 60}, { 60, 60, 60}, { 61, 61, 61}, { 61, 61, 61},
+ { 61, 61, 61}, { 62, 62, 62}, { 62, 62, 62}, { 62, 62, 62}, { 62, 62, 62},
+ { 63, 63, 63}, { 63, 63, 63}, { 63, 63, 63}, { 63, 63, 63}, { 64, 64, 64},
+ { 64, 64, 64}, { 64, 64, 64}, { 64, 64, 64}, { 65, 65, 65}, { 65, 65, 65},
+ { 65, 65, 65}, { 65, 65, 65}, { 66, 66, 66}, { 66, 66, 66}, { 66, 66, 66},
+ { 66, 66, 66}, { 67, 67, 67}, { 67, 67, 67}, { 67, 67, 67}, { 67, 67, 67},
+ { 68, 68, 68}, { 68, 68, 68}, { 68, 68, 68}, { 68, 68, 68}, { 69, 69, 69},
+ { 69, 69, 69}, { 69, 69, 69}, { 69, 69, 69}, { 70, 70, 70}, { 70, 70, 70},
+ { 70, 70, 70}, { 70, 70, 70}, { 71, 71, 71}, { 71, 71, 71}, { 71, 71, 71},
+ { 71, 71, 71}, { 72, 72, 72}, { 72, 72, 72}, { 72, 72, 72}, { 72, 72, 72},
+ { 73, 73, 73}, { 73, 73, 73}, { 73, 73, 73}, { 74, 74, 74}, { 74, 74, 74},
+ { 74, 74, 74}, { 74, 74, 74}, { 75, 75, 75}, { 75, 75, 75}, { 75, 75, 75},
+ { 75, 75, 75}, { 76, 76, 76}, { 76, 76, 76}, { 76, 76, 76}, { 76, 76, 76},
+ { 77, 77, 77}, { 77, 77, 77}, { 77, 77, 77}, { 77, 77, 77}, { 78, 78, 78},
+ { 78, 78, 78}, { 78, 78, 78}, { 78, 78, 78}, { 79, 79, 79}, { 79, 79, 79},
+ { 79, 79, 79}, { 79, 79, 79}, { 80, 80, 80}, { 80, 80, 80}, { 80, 80, 80},
+ { 80, 80, 80}, { 81, 81, 81}, { 81, 81, 81}, { 81, 81, 81}, { 81, 81, 81},
+ { 82, 82, 82}, { 82, 82, 82}, { 82, 82, 82}, { 82, 82, 82}, { 83, 83, 83},
+ { 83, 83, 83}, { 83, 83, 83}, { 83, 83, 83}, { 84, 84, 84}, { 84, 84, 84},
+ { 84, 84, 84}, { 84, 84, 84}, { 85, 85, 85}, { 85, 85, 85}, { 85, 85, 85},
+ { 86, 86, 86}, { 86, 86, 86}, { 86, 86, 86}, { 86, 86, 86}, { 87, 87, 87},
+ { 87, 87, 87}, { 87, 87, 87}, { 87, 87, 87}, { 88, 88, 88}, { 88, 88, 88},
+ { 88, 88, 88}, { 88, 88, 88}, { 89, 89, 89}, { 89, 89, 89}, { 89, 89, 89},
+ { 89, 89, 89}, { 90, 90, 90}, { 90, 90, 90}, { 90, 90, 90}, { 90, 90, 90},
+ { 91, 91, 91}, { 91, 91, 91}, { 91, 91, 91}, { 91, 91, 91}, { 92, 92, 92},
+ { 92, 92, 92}, { 92, 92, 92}, { 92, 92, 92}, { 93, 93, 93}, { 93, 93, 93},
+ { 93, 93, 93}, { 93, 93, 93}, { 94, 94, 94}, { 94, 94, 94}, { 94, 94, 94},
+ { 94, 94, 94}, { 95, 95, 95}, { 95, 95, 95}, { 95, 95, 95}, { 95, 95, 95},
+ { 96, 96, 96}, { 96, 96, 96}, { 96, 96, 96}, { 96, 96, 96}, { 97, 97, 97},
+ { 97, 97, 97}, { 97, 97, 97}, { 98, 98, 98}, { 98, 98, 98}, { 98, 98, 98},
+ { 98, 98, 98}, { 99, 99, 99}, { 99, 99, 99}, { 99, 99, 99}, { 99, 99, 99},
+ {100, 100, 100}, {100, 100, 100}, {100, 100, 100}, {100, 100, 100}, {101, 101, 101},
+ {101, 101, 101}, {101, 101, 101}, {101, 101, 101}, {102, 102, 102}, {102, 102, 102},
+ {102, 102, 102}, {102, 102, 102}, {103, 103, 103}, {103, 103, 103}, {103, 103, 103},
+ {103, 103, 103}, {104, 104, 104}, {104, 104, 104}, {104, 104, 104}, {104, 104, 104},
+ {105, 105, 105}, {105, 105, 105}, {105, 105, 105}, {105, 105, 105}, {106, 106, 106},
+ {106, 106, 106}, {106, 106, 106}, {106, 106, 106}, {107, 107, 107}, {107, 107, 107},
+ {107, 107, 107}, {107, 107, 107}, {108, 108, 108}, {108, 108, 108}, {108, 108, 108},
+ {108, 108, 108}, {109, 109, 109}, {109, 109, 109}, {109, 109, 109}, {110, 110, 110},
+ {110, 110, 110}, {110, 110, 110}, {110, 110, 110}, {111, 111, 111}, {111, 111, 111},
+ {111, 111, 111}, {111, 111, 111}, {112, 112, 112}, {112, 112, 112}, {112, 112, 112},
+ {112, 112, 112}, {113, 113, 113}, {113, 113, 113}, {113, 113, 113}, {113, 113, 113},
+ {114, 114, 114}, {114, 114, 114}, {114, 114, 114}, {114, 114, 114}, {115, 115, 115},
+ {115, 115, 115}, {115, 115, 115}, {115, 115, 115}, {116, 116, 116}, {116, 116, 116},
+ {116, 116, 116}, {116, 116, 116}, {117, 117, 117}, {117, 117, 117}, {117, 117, 117},
+ {117, 117, 117}, {118, 118, 118}, {118, 118, 118}, {118, 118, 118}, {118, 118, 118},
+ {119, 119, 119}, {119, 119, 119}, {119, 119, 119}, {119, 119, 119}, {120, 120, 120},
+ {120, 120, 120}, {120, 120, 120}, {120, 120, 120}, {121, 121, 121}, {121, 121, 121},
+ {121, 121, 121}, {122, 122, 122}, {122, 122, 122}, {122, 122, 122}, {122, 122, 122},
+ {123, 123, 123}, {123, 123, 123}, {123, 123, 123}, {123, 123, 123}, {124, 124, 124},
+ {124, 124, 124}, {124, 124, 124}, {124, 124, 124}, {125, 125, 125}, {125, 125, 125},
+ {125, 125, 125}, {125, 125, 125}, {126, 126, 126}, {126, 126, 126}, {126, 126, 126},
+ {126, 126, 126}, {127, 127, 127}, {127, 127, 127}, {127, 127, 127}, {127, 127, 127},
+ {128, 128, 128}, {128, 128, 128}, {128, 128, 128}, {128, 128, 128}, {129, 129, 129},
+ {129, 129, 129}, {129, 129, 129}, {129, 129, 129}, {130, 130, 130}, {130, 130, 130},
+ {130, 130, 130}, {130, 130, 130}, {131, 131, 131}, {131, 131, 131}, {131, 131, 131},
+ {131, 131, 131}, {132, 132, 132}, {132, 132, 132}, {132, 132, 132}, {132, 132, 132},
+ {133, 133, 133}, {133, 133, 133}, {133, 133, 133}, {133, 133, 133}, {134, 134, 134},
+ {134, 134, 134}, {134, 134, 134}, {135, 135, 135}, {135, 135, 135}, {135, 135, 135},
+ {135, 135, 135}, {136, 136, 136}, {136, 136, 136}, {136, 136, 136}, {136, 136, 136},
+ {137, 137, 137}, {137, 137, 137}, {137, 137, 137}, {137, 137, 137}, {138, 138, 138},
+ {138, 138, 138}, {138, 138, 138}, {138, 138, 138}, {139, 139, 139}, {139, 139, 139},
+ {139, 139, 139}, {139, 139, 139}, {140, 140, 140}, {140, 140, 140}, {140, 140, 140},
+ {140, 140, 140}, {141, 141, 141}, {141, 141, 141}, {141, 141, 141}, {141, 141, 141},
+ {142, 142, 142}, {142, 142, 142}, {142, 142, 142}, {142, 142, 142}, {143, 143, 143},
+ {143, 143, 143}, {143, 143, 143}, {143, 143, 143}, {144, 144, 144}, {144, 144, 144},
+ {144, 144, 144}, {144, 144, 144}, {145, 145, 145}, {145, 145, 145}, {145, 145, 145},
+ {145, 145, 145}, {146, 146, 146}, {146, 146, 146}, {146, 146, 146}, {147, 147, 147},
+ {147, 147, 147}, {147, 147, 147}, {147, 147, 147}, {148, 148, 148}, {148, 148, 148},
+ {148, 148, 148}, {148, 148, 148}, {149, 149, 149}, {149, 149, 149}, {149, 149, 149},
+ {149, 149, 149}, {150, 150, 150}, {150, 150, 150}, {150, 150, 150}, {150, 150, 150},
+ {151, 151, 151}, {151, 151, 151}, {151, 151, 151}, {151, 151, 151}, {152, 152, 152},
+ {152, 152, 152}, {152, 152, 152}, {152, 152, 152}, {153, 153, 153}, {153, 153, 153},
+ {153, 153, 153}, {153, 153, 153}, {154, 154, 154}, {154, 154, 154}, {154, 154, 154},
+ {154, 154, 154}, {155, 155, 155}, {155, 155, 155}, {155, 155, 155}, {155, 155, 155},
+ {156, 156, 156}, {156, 156, 156}, {156, 156, 156}, {156, 156, 156}, {157, 157, 157},
+ {157, 157, 157}, {157, 157, 157}, {157, 157, 157}, {158, 158, 158}, {158, 158, 158},
+ {158, 158, 158}, {159, 159, 159}, {159, 159, 159}, {159, 159, 159}, {159, 159, 159},
+ {160, 160, 160}, {160, 160, 160}, {160, 160, 160}, {160, 160, 160}, {161, 161, 161},
+ {161, 161, 161}, {161, 161, 161}, {161, 161, 161}, {162, 162, 162}, {162, 162, 162},
+ {162, 162, 162}, {162, 162, 162}, {163, 163, 163}, {163, 163, 163}, {163, 163, 163},
+ {163, 163, 163}, {164, 164, 164}, {164, 164, 164}, {164, 164, 164}, {164, 164, 164},
+ {165, 165, 165}, {165, 165, 165}, {165, 165, 165}, {165, 165, 165}, {166, 166, 166},
+ {166, 166, 166}, {166, 166, 166}, {166, 166, 166}, {167, 167, 167}, {167, 167, 167},
+ {167, 167, 167}, {167, 167, 167}, {168, 168, 168}, {168, 168, 168}, {168, 168, 168},
+ {168, 168, 168}, {169, 169, 169}, {169, 169, 169}, {169, 169, 169}, {169, 169, 169},
+ {170, 170, 170}, {170, 170, 170}, {170, 170, 170}, {171, 171, 171}, {171, 171, 171},
+ {171, 171, 171}, {171, 171, 171}, {172, 172, 172}, {172, 172, 172}, {172, 172, 172},
+ {172, 172, 172}, {173, 173, 173}, {173, 173, 173}, {173, 173, 173}, {173, 173, 173},
+ {174, 174, 174}, {174, 174, 174}, {174, 174, 174}, {174, 174, 174}, {175, 175, 175},
+ {175, 175, 175}, {175, 175, 175}, {175, 175, 175}, {176, 176, 176}, {176, 176, 176},
+ {176, 176, 176}, {176, 176, 176}, {177, 177, 177}, {177, 177, 177}, {177, 177, 177},
+ {177, 177, 177}, {178, 178, 178}, {178, 178, 178}, {178, 178, 178}, {178, 178, 178},
+ {179, 179, 179}, {179, 179, 179}, {179, 179, 179}, {179, 179, 179}, {180, 180, 180},
+ {180, 180, 180}, {180, 180, 180}, {180, 180, 180}, {181, 181, 181}, {181, 181, 181},
+ {181, 181, 181}, {181, 181, 181}, {182, 182, 182}, {182, 182, 182}, {182, 182, 182},
+ {183, 183, 183}, {183, 183, 183}, {183, 183, 183}, {183, 183, 183}, {184, 184, 184},
+ {184, 184, 184}, {184, 184, 184}, {184, 184, 184}, {185, 185, 185}, {185, 185, 185},
+ {185, 185, 185}, {185, 185, 185}, {186, 186, 186}, {186, 186, 186}, {186, 186, 186},
+ {186, 186, 186}, {187, 187, 187}, {187, 187, 187}, {187, 187, 187}, {187, 187, 187},
+ {188, 188, 188}, {188, 188, 188}, {188, 188, 188}, {188, 188, 188}, {189, 189, 189},
+ {189, 189, 189}, {189, 189, 189}, {189, 189, 189}, {190, 190, 190}, {190, 190, 190},
+ {190, 190, 190}, {190, 190, 190}, {191, 191, 191}, {191, 191, 191}, {191, 191, 191},
+ {191, 191, 191}, {192, 192, 192}, {192, 192, 192}, {192, 192, 192}, {192, 192, 192},
+ {193, 193, 193}, {193, 193, 193}, {193, 193, 193}, {193, 193, 193}, {194, 194, 194},
+ {194, 194, 194}, {194, 194, 194}, {195, 195, 195}, {195, 195, 195}, {195, 195, 195},
+ {195, 195, 195}, {196, 196, 196}, {196, 196, 196}, {196, 196, 196}, {196, 196, 196},
+ {197, 197, 197}, {197, 197, 197}, {197, 197, 197}, {197, 197, 197}, {198, 198, 198},
+ {198, 198, 198}, {198, 198, 198}, {198, 198, 198}, {199, 199, 199}, {199, 199, 199},
+ {199, 199, 199}, {199, 199, 199}, {200, 200, 200}, {200, 200, 200}, {200, 200, 200},
+ {200, 200, 200}, {201, 201, 201}, {201, 201, 201}, {201, 201, 201}, {201, 201, 201},
+ {202, 202, 202}, {202, 202, 202}, {202, 202, 202}, {202, 202, 202}, {203, 203, 203},
+ {203, 203, 203}, {203, 203, 203}, {203, 203, 203}, {204, 204, 204}, {204, 204, 204},
+ {204, 204, 204}, {204, 204, 204}, {205, 205, 205}, {205, 205, 205}, {205, 205, 205},
+ {205, 205, 205}, {206, 206, 206}, {206, 206, 206}, {206, 206, 206}, {207, 207, 207},
+ {207, 207, 207}, {207, 207, 207}, {207, 207, 207}, {208, 208, 208}, {208, 208, 208},
+ {208, 208, 208}, {208, 208, 208}, {209, 209, 209}, {209, 209, 209}, {209, 209, 209},
+ {209, 209, 209}, {210, 210, 210}, {210, 210, 210}, {210, 210, 210}, {210, 210, 210},
+ {211, 211, 211}, {211, 211, 211}, {211, 211, 211}, {211, 211, 211}, {212, 212, 212},
+ {212, 212, 212}, {212, 212, 212}, {212, 212, 212}, {213, 213, 213}, {213, 213, 213},
+ {213, 213, 213}, {213, 213, 213}, {214, 214, 214}, {214, 214, 214}, {214, 214, 214},
+ {214, 214, 214}, {215, 215, 215}, {215, 215, 215}, {215, 215, 215}, {215, 215, 215},
+ {216, 216, 216}, {216, 216, 216}, {216, 216, 216}, {216, 216, 216}, {217, 217, 217},
+ {217, 217, 217}, {217, 217, 217}, {217, 217, 217}, {218, 218, 218}, {218, 218, 218},
+ {218, 218, 218}, {218, 218, 218}, {219, 219, 219}, {219, 219, 219}, {219, 219, 219},
+ {220, 220, 220}, {220, 220, 220}, {220, 220, 220}, {220, 220, 220}, {221, 221, 221},
+ {221, 221, 221}, {221, 221, 221}, {221, 221, 221}, {222, 222, 222}, {222, 222, 222},
+ {222, 222, 222}, {222, 222, 222}, {223, 223, 223}, {223, 223, 223}, {223, 223, 223},
+ {223, 223, 223}, {224, 224, 224}, {224, 224, 224}, {224, 224, 224}, {224, 224, 224},
+ {225, 225, 225}, {225, 225, 225}, {225, 225, 225}, {225, 225, 225}, {226, 226, 226},
+ {226, 226, 226}, {226, 226, 226}, {226, 226, 226}, {227, 227, 227}, {227, 227, 227},
+ {227, 227, 227}, {227, 227, 227}, {228, 228, 228}, {228, 228, 228}, {228, 228, 228},
+ {228, 228, 228}, {229, 229, 229}, {229, 229, 229}, {229, 229, 229}, {229, 229, 229},
+ {230, 230, 230}, {230, 230, 230}, {230, 230, 230}, {230, 230, 230}, {231, 231, 231},
+ {231, 231, 231}, {231, 231, 231}, {232, 232, 232}, {232, 232, 232}, {232, 232, 232},
+ {232, 232, 232}, {233, 233, 233}, {233, 233, 233}, {233, 233, 233}, {233, 233, 233},
+ {234, 234, 234}, {234, 234, 234}, {234, 234, 234}, {234, 234, 234}, {235, 235, 235},
+ {235, 235, 235}, {235, 235, 235}, {235, 235, 235}, {236, 236, 236}, {236, 236, 236},
+ {236, 236, 236}, {236, 236, 236}, {237, 237, 237}, {237, 237, 237}, {237, 237, 237},
+ {237, 237, 237}, {238, 238, 238}, {238, 238, 238}, {238, 238, 238}, {238, 238, 238},
+ {239, 239, 239}, {239, 239, 239}, {239, 239, 239}, {239, 239, 239}, {240, 240, 240},
+ {240, 240, 240}, {240, 240, 240}, {240, 240, 240}, {241, 241, 241}, {241, 241, 241},
+ {241, 241, 241}, {241, 241, 241}, {242, 242, 242}, {242, 242, 242}, {242, 242, 242},
+ {242, 242, 242}, {243, 243, 243}, {243, 243, 243}, {243, 243, 243}, {244, 244, 244},
+ {244, 244, 244}, {244, 244, 244}, {244, 244, 244}, {245, 245, 245}, {245, 245, 245},
+ {245, 245, 245}, {245, 245, 245}, {246, 246, 246}, {246, 246, 246}, {246, 246, 246},
+ {246, 246, 246}, {247, 247, 247}, {247, 247, 247}, {247, 247, 247}, {247, 247, 247},
+ {248, 248, 248}, {248, 248, 248}, {248, 248, 248}, {248, 248, 248}, {249, 249, 249},
+ {249, 249, 249}, {249, 249, 249}, {249, 249, 249}, {250, 250, 250}, {250, 250, 250},
+ {250, 250, 250}, {250, 250, 250}, {251, 251, 251}, {251, 251, 251}, {251, 251, 251},
+ {251, 251, 251}, {252, 252, 252}, {252, 252, 252}, {252, 252, 252}, {252, 252, 252},
+ {253, 253, 253}, {253, 253, 253}, {253, 253, 253}, {253, 253, 253}, {254, 254, 254},
+ {254, 254, 254}, {254, 254, 254}, {254, 254, 254}, {255, 255, 255}, {255, 255, 255}
+};
+
+#endif
diff --git a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorDetection.cpp b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorDetection.cpp
index 42f1c8e61..5a7734c0e 100644
--- a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorDetection.cpp
+++ b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/ColorDetection.cpp
@@ -380,8 +380,6 @@ size_t ColorDetection::DetectColorNew(uint8_t * input_buffer, size_t input_buffe
//Process --------------------------------------------------------------------------------------------
- bool debug = detectionInput->debugmode; //Determines whether to perform debug drawing on the image and return that image in the result.
-
//Bitmap bytes to opencv mat.
bitmap_image bitmap(detectionInput->bitmap.data, detectionInput->bitmap.len);
Mat img = Mat(bitmap.height(), bitmap.width(), CV_8UC3, bitmap.data());
@@ -392,7 +390,7 @@ size_t ColorDetection::DetectColorNew(uint8_t * input_buffer, size_t input_buffe
BhBlocks b(img, img.cols / columns, img.rows / rows);
vector<Rect> rects = b.getRects(); //Get card rectangles.
- if (debug)
+ if (detectionInput->requestdebugimage)
{
//Draw card outline.
b.drawBlocks(img, Scalar(0, 0, 0), 0.5);
@@ -409,7 +407,7 @@ size_t ColorDetection::DetectColorNew(uint8_t * input_buffer, size_t input_buffe
Scalar mean = Utils::getRectMeanColor(img, cropped);
means.push_back(mean);
- if (debug)
+ if (detectionInput->requestdebugimage)
{
//Draw rectangle mean except fiducials.
if (!isRectFiducial(i + 1, columns, rows))
@@ -426,7 +424,7 @@ size_t ColorDetection::DetectColorNew(uint8_t * input_buffer, size_t input_buffe
- if (debug)
+ if (detectionInput->requestdebugimage)
{
//Draw target rectangle outline.
rectangle(img, target_rect, Scalar(255, 255, 255), 1);
@@ -434,7 +432,7 @@ size_t ColorDetection::DetectColorNew(uint8_t * input_buffer, size_t input_buffe
ProtobufCBinaryData debugBitmap; //Debug bitmap.
- if (debug)
+ if (detectionInput->requestdebugimage)
{
//Encode the opencv mat to bitmap.
vector<uchar> buf;
@@ -452,7 +450,10 @@ size_t ColorDetection::DetectColorNew(uint8_t * input_buffer, size_t input_buffe
detectionOutput->debugbitmap = debugBitmap;
detectionOutput->has_debugbitmap = true;
+ }
+ if (detectionInput->requestcolormatrix)
+ {
//Fill the full color matrix
detectionOutput->n_colormatrix = means.size();
detectionOutput->colormatrix = (DetectionColor**)malloc(sizeof(DetectionColor*) * means.size());
@@ -486,9 +487,12 @@ size_t ColorDetection::DetectColorNew(uint8_t * input_buffer, size_t input_buffe
img.release();
means.clear();
rects.clear();
- if (debug)
+ if (detectionInput->requestdebugimage)
{
free(debugBitmap.data);
+ }
+ if (detectionInput->requestcolormatrix)
+ {
for (size_t i = 0; i < detectionOutput->n_colormatrix; i++)
{
free(detectionOutput->colormatrix[i]);
diff --git a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/PMR/TCC/DetectionInput.pb-c.c b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/PMR/TCC/DetectionInput.pb-c.c
index ffad8bee4..9fe7f574f 100644
--- a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/PMR/TCC/DetectionInput.pb-c.c
+++ b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/PMR/TCC/DetectionInput.pb-c.c
@@ -52,7 +52,7 @@ void detection_input__free_unpacked
assert(message->base.descriptor == &detection_input__descriptor);
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
}
-static const ProtobufCFieldDescriptor detection_input__field_descriptors[7] =
+static const ProtobufCFieldDescriptor detection_input__field_descriptors[8] =
{
{
"Bitmap",
@@ -103,20 +103,32 @@ static const ProtobufCFieldDescriptor detection_input__field_descriptors[7] =
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
- "DebugMode",
+ "RequestDebugImage",
5,
PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_TYPE_BOOL,
- offsetof(DetectionInput, has_debugmode),
- offsetof(DetectionInput, debugmode),
+ offsetof(DetectionInput, has_requestdebugimage),
+ offsetof(DetectionInput, requestdebugimage),
NULL,
NULL,
0, /* flags */
0,NULL,NULL /* reserved1,reserved2, etc */
},
{
- "Benchmarks",
+ "RequestColorMatrix",
6,
+ PROTOBUF_C_LABEL_OPTIONAL,
+ PROTOBUF_C_TYPE_BOOL,
+ offsetof(DetectionInput, has_requestcolormatrix),
+ offsetof(DetectionInput, requestcolormatrix),
+ NULL,
+ NULL,
+ 0, /* flags */
+ 0,NULL,NULL /* reserved1,reserved2, etc */
+ },
+ {
+ "Benchmarks",
+ 7,
PROTOBUF_C_LABEL_REPEATED,
PROTOBUF_C_TYPE_MESSAGE,
offsetof(DetectionInput, n_benchmarks),
@@ -140,19 +152,20 @@ static const ProtobufCFieldDescriptor detection_input__field_descriptors[7] =
},
};
static const unsigned detection_input__field_indices_by_name[] = {
- 5, /* field[5] = Benchmarks */
+ 6, /* field[6] = Benchmarks */
0, /* field[0] = Bitmap */
1, /* field[1] = Columns */
- 4, /* field[4] = DebugMode */
+ 5, /* field[5] = RequestColorMatrix */
+ 4, /* field[4] = RequestDebugImage */
2, /* field[2] = Rows */
3, /* field[3] = TargetIndex */
- 6, /* field[6] = number */
+ 7, /* field[7] = number */
};
static const ProtobufCIntRange detection_input__number_ranges[2 + 1] =
{
{ 1, 0 },
- { 10, 6 },
- { 0, 7 }
+ { 10, 7 },
+ { 0, 8 }
};
const ProtobufCMessageDescriptor detection_input__descriptor =
{
@@ -162,7 +175,7 @@ const ProtobufCMessageDescriptor detection_input__descriptor =
"DetectionInput",
"",
sizeof(DetectionInput),
- 7,
+ 8,
detection_input__field_descriptors,
detection_input__field_indices_by_name,
2, detection_input__number_ranges,
diff --git a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/PMR/TCC/DetectionInput.pb-c.h b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/PMR/TCC/DetectionInput.pb-c.h
index c919d4c11..7986b70fd 100644
--- a/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/PMR/TCC/DetectionInput.pb-c.h
+++ b/Software/Visual_Studio/TCC/Tango.TCC.ColorDetector/PMR/TCC/DetectionInput.pb-c.h
@@ -35,8 +35,10 @@ struct _DetectionInput
int32_t rows;
protobuf_c_boolean has_targetindex;
int32_t targetindex;
- protobuf_c_boolean has_debugmode;
- protobuf_c_boolean debugmode;
+ protobuf_c_boolean has_requestdebugimage;
+ protobuf_c_boolean requestdebugimage;
+ protobuf_c_boolean has_requestcolormatrix;
+ protobuf_c_boolean requestcolormatrix;
size_t n_benchmarks;
DetectionBenchmark **benchmarks;
protobuf_c_boolean has_number;
@@ -44,7 +46,7 @@ struct _DetectionInput
};
#define DETECTION_INPUT__INIT \
{ PROTOBUF_C_MESSAGE_INIT (&detection_input__descriptor) \
- , 0, {0,NULL}, 0, 0, 0, 0, 0, 0, 0, 0, 0,NULL, 0, 0 }
+ , 0, {0,NULL}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,NULL, 0, 0 }
/* DetectionInput methods */
diff --git a/Software/Visual_Studio/TCC/Tango.TCC.OpenCV/CardDetector.cpp b/Software/Visual_Studio/TCC/Tango.TCC.OpenCV/CardProcessor.cpp
index 620ad41b6..0551c9008 100644
--- a/Software/Visual_Studio/TCC/Tango.TCC.OpenCV/CardDetector.cpp
+++ b/Software/Visual_Studio/TCC/Tango.TCC.OpenCV/CardProcessor.cpp
@@ -1,4 +1,4 @@
-#include "CardDetector.h"
+#include "CardProcessor.h"
using namespace cv;
using namespace std;
@@ -19,16 +19,16 @@ bool isRectChildOf(Rect rect, Rect parent)
Ptr<aruco::Dictionary> dictionary = aruco::getPredefinedDictionary(aruco::DICT_4X4_50);
-CardDetector::CardDetector()
+CardProcessor::CardProcessor()
{
isInitialized = false;
}
-CardDetector::~CardDetector()
+CardProcessor::~CardProcessor()
{
}
-vector<Point> CardDetector::GetQRVertices4(Mat image)
+vector<Point> CardProcessor::GetQRVertices4(Mat image)
{
if (!isInitialized)
{
@@ -325,7 +325,7 @@ vector<Point> CardDetector::GetQRVertices4(Mat image)
return result;
}
-vector<Point> CardDetector::GetQRVertices(Mat image)
+vector<Point> CardProcessor::GetQRVertices(Mat image)
{
if (!isInitialized)
{
@@ -611,7 +611,7 @@ vector<Point> sortPoints(vector<Point> unsorted) {
return sorted;
}
-vector<Point> CardDetector::GetArcusVertices(Mat image)
+vector<Point> CardProcessor::GetArcusVertices(Mat image)
{
vector<Point> vertices;
@@ -683,7 +683,7 @@ Point2f scale_line(Point2f p1, Point2f p2, double newlength)
return Point2f(p1.x + (newlength / length) * (p2.x - p1.x), p1.y + (newlength / length) * (p2.y - p1.y));
}
-Mat CardDetector::ApplyHomography(Mat image, vector<Point> vertices, Size destination_size)
+Mat CardProcessor::ApplyHomography(Mat image, vector<Point> vertices, Size destination_size)
{
Mat im_dst = Mat::zeros(destination_size, CV_8UC3);
@@ -701,7 +701,7 @@ Mat CardDetector::ApplyHomography(Mat image, vector<Point> vertices, Size destin
return im_dst;
}
-Rect CardDetector::CropRect(Rect rect, Size size)
+Rect CardProcessor::CropRect(Rect rect, Size size)
{
Point center = (rect.br() + rect.tl())*0.5;
@@ -716,7 +716,7 @@ Rect CardDetector::CropRect(Rect rect, Size size)
return cropped;
}
-Scalar CardDetector::GetRectMeanColor(Mat image, Rect rect)
+Scalar CardProcessor::GetRectMeanColor(Mat image, Rect rect)
{
Point pts[1][4];
pts[0][0] = Point(rect.x, rect.y);
@@ -738,7 +738,7 @@ Scalar CardDetector::GetRectMeanColor(Mat image, Rect rect)
return average;
}
-Mat CardDetector::GetImageRect(Mat image, Rect rect)
+Mat CardProcessor::GetImageRect(Mat image, Rect rect)
{
Mat rectImage(rect.size(), CV_8UC3);
Rect dst(0, 0, rect.width, rect.height);
@@ -746,7 +746,7 @@ Mat CardDetector::GetImageRect(Mat image, Rect rect)
return rectImage;
}
-Mat CardDetector::Diff(Mat image, int k)
+Mat CardProcessor::Diff(Mat image, int k)
{
int origRows = image.rows;
Mat colVec = image.reshape(1, image.rows*image.cols); // change to a Nx3 column vector
@@ -761,7 +761,7 @@ Mat CardDetector::Diff(Mat image, int k)
return centers;
}
-void CardDetector::DrawImage(Mat image, Mat draw, Rect rect)
+void CardProcessor::DrawImage(Mat image, Mat draw, Rect rect)
{
// Take a sub-view of the large image
cv::Mat subView = image(rect);
@@ -770,7 +770,7 @@ void CardDetector::DrawImage(Mat image, Mat draw, Rect rect)
draw.copyTo(subView);
}
-void CardDetector::DrawHistogram(Mat image)
+void CardProcessor::DrawHistogram(Mat image)
{
/// Separate the image in 3 places ( B, G and R )
vector<Mat> bgr_planes;
@@ -817,13 +817,13 @@ void CardDetector::DrawHistogram(Mat image)
}
}
-Point CardDetector::GetRectCenter(Rect rect)
+Point CardProcessor::GetRectCenter(Rect rect)
{
Point center = (rect.br() + rect.tl())*0.5;
return center;
}
-void CardDetector::Initialize(Mat image)
+void CardProcessor::Initialize(Mat image)
{
// Creation of Intermediate 'Image' Objects required later
Mat gray(image.size(), CV_MAKETYPE(image.depth(), 1)); // To hold Grayscale Image
@@ -838,7 +838,7 @@ void CardDetector::Initialize(Mat image)
// Function: Routine to get Distance between two points
// Description: Given 2 points, the function returns the distance
-float CardDetector::cv_distance(Point2f P, Point2f Q)
+float CardProcessor::cv_distance(Point2f P, Point2f Q)
{
return sqrt(pow(abs(P.x - Q.x), 2) + pow(abs(P.y - Q.y), 2));
}
@@ -846,7 +846,7 @@ float CardDetector::cv_distance(Point2f P, Point2f Q)
// Function: Perpendicular Distance of a Point J from line formed by Points L and M; Equation of the line ax+by+c=0
// Description: Given 3 points, the function derives the line quation of the first two points,
// calculates and returns the perpendicular distance of the the 3rd point from this line.
-float CardDetector::cv_lineEquation(Point2f L, Point2f M, Point2f J)
+float CardProcessor::cv_lineEquation(Point2f L, Point2f M, Point2f J)
{
float a, b, c, pdist;
@@ -863,7 +863,7 @@ float CardDetector::cv_lineEquation(Point2f L, Point2f M, Point2f J)
// Function: Slope of a line by two Points L and M on it; Slope of line, S = (x1 -x2) / (y1- y2)
// Description: Function returns the slope of the line formed by given 2 points, the alignement flag
// indicates the line is vertical and the slope is infinity.
-float CardDetector::cv_lineSlope(Point2f L, Point2f M, int& alignement)
+float CardProcessor::cv_lineSlope(Point2f L, Point2f M, int& alignement)
{
float dx, dy;
dx = M.x - L.x;
@@ -888,7 +888,7 @@ float CardDetector::cv_lineSlope(Point2f L, Point2f M, int& alignement)
// 4 regions equal regions using bounding box. Distance algorithm is applied between the centre of bounding box
// every contour point in that region, the farthest point is deemed as the vertex of that region. Calculating
// for all 4 regions we obtain the 4 corners of the polygon ( - quadrilateral).
-void CardDetector::cv_getVertices(vector<vector<Point> > contours, int c_id, float slope, vector<Point2f>& quad)
+void CardProcessor::cv_getVertices(vector<vector<Point> > contours, int c_id, float slope, vector<Point2f>& quad)
{
Rect box;
box = boundingRect(contours[c_id]);
@@ -988,7 +988,7 @@ void CardDetector::cv_getVertices(vector<vector<Point> > contours, int c_id, flo
// Function: Compare a point if it more far than previously recorded farthest distance
// Description: Farthest Point detection using reference point and baseline distance
-void CardDetector::cv_updateCorner(Point2f P, Point2f ref, float& baseline, Point2f& corner)
+void CardProcessor::cv_updateCorner(Point2f P, Point2f ref, float& baseline, Point2f& corner)
{
float temp_dist;
temp_dist = cv_distance(P, ref);
@@ -1002,7 +1002,7 @@ void CardDetector::cv_updateCorner(Point2f P, Point2f ref, float& baseline, Poin
}
// Function: Sequence the Corners wrt to the orientation of the QR Code
-void CardDetector::cv_updateCornerOr(int orientation, vector<Point2f> IN, vector<Point2f> &OUT)
+void CardProcessor::cv_updateCornerOr(int orientation, vector<Point2f> IN, vector<Point2f> &OUT)
{
Point2f M0, M1, M2, M3;
if (orientation == CV_QR_NORTH)
@@ -1041,7 +1041,7 @@ void CardDetector::cv_updateCornerOr(int orientation, vector<Point2f> IN, vector
}
// Function: Get the Intersection Point of the lines formed by sets of two points
-bool CardDetector::getIntersectionPoint(Point2f a1, Point2f a2, Point2f b1, Point2f b2, Point2f& intersection)
+bool CardProcessor::getIntersectionPoint(Point2f a1, Point2f a2, Point2f b1, Point2f b2, Point2f& intersection)
{
Point2f p = a1;
Point2f q = b1;
@@ -1056,7 +1056,7 @@ bool CardDetector::getIntersectionPoint(Point2f a1, Point2f a2, Point2f b1, Poin
return true;
}
-float CardDetector::cross(Point2f v1, Point2f v2)
+float CardProcessor::cross(Point2f v1, Point2f v2)
{
return v1.x*v2.y - v1.y*v2.x;
} \ No newline at end of file
diff --git a/Software/Visual_Studio/TCC/Tango.TCC.OpenCV/CardDetector.h b/Software/Visual_Studio/TCC/Tango.TCC.OpenCV/CardProcessor.h
index 8ec021d0a..2eda83a1e 100644
--- a/Software/Visual_Studio/TCC/Tango.TCC.OpenCV/CardDetector.h
+++ b/Software/Visual_Studio/TCC/Tango.TCC.OpenCV/CardProcessor.h
@@ -1,13 +1,13 @@
#include <opencv2/opencv.hpp>
#include <opencv2/aruco.hpp>
#include <iostream>
-#include <cmath>
+#include <cmath>
using namespace cv;
using namespace std;
#pragma once
-class CardDetector
+class CardProcessor
{
const int CV_QR_NORTH = 0;
const int CV_QR_EAST = 1;
@@ -40,8 +40,8 @@ private:
bool getIntersectionPoint(Point2f a1, Point2f a2, Point2f b1, Point2f b2, Point2f& intersection);
float cross(Point2f v1, Point2f v2);
public:
- CardDetector();
- ~CardDetector();
+ CardProcessor();
+ ~CardProcessor();
vector<Point> GetQRVertices(Mat image);
vector<Point> GetQRVertices4(Mat image);
vector<Point> GetArcusVertices(Mat image);
diff --git a/Software/Visual_Studio/TCC/Tango.TCC.OpenCV/Tango.TCC.OpenCV.vcxproj b/Software/Visual_Studio/TCC/Tango.TCC.OpenCV/Tango.TCC.OpenCV.vcxproj
index 2bd3b6dab..db00def78 100644
--- a/Software/Visual_Studio/TCC/Tango.TCC.OpenCV/Tango.TCC.OpenCV.vcxproj
+++ b/Software/Visual_Studio/TCC/Tango.TCC.OpenCV/Tango.TCC.OpenCV.vcxproj
@@ -149,12 +149,12 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="BhBlocks.h" />
- <ClInclude Include="CardDetector.h" />
+ <ClInclude Include="CardProcessor.h" />
<ClInclude Include="Utils.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="BhBlocks.cpp" />
- <ClCompile Include="CardDetector.cpp" />
+ <ClCompile Include="CardProcessor.cpp" />
<ClCompile Include="Utils.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
diff --git a/Software/Visual_Studio/TCC/Tango.TCC.OpenCV/Tango.TCC.OpenCV.vcxproj.filters b/Software/Visual_Studio/TCC/Tango.TCC.OpenCV/Tango.TCC.OpenCV.vcxproj.filters
index 028e630f4..76ee35bc4 100644
--- a/Software/Visual_Studio/TCC/Tango.TCC.OpenCV/Tango.TCC.OpenCV.vcxproj.filters
+++ b/Software/Visual_Studio/TCC/Tango.TCC.OpenCV/Tango.TCC.OpenCV.vcxproj.filters
@@ -18,10 +18,10 @@
<ClInclude Include="BhBlocks.h">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="CardDetector.h">
+ <ClInclude Include="Utils.h">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="Utils.h">
+ <ClInclude Include="CardProcessor.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
@@ -29,10 +29,10 @@
<ClCompile Include="BhBlocks.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="CardDetector.cpp">
+ <ClCompile Include="Utils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="Utils.cpp">
+ <ClCompile Include="CardProcessor.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
diff --git a/Software/Visual_Studio/Tango.PMR/TCC/DetectionInput.cs b/Software/Visual_Studio/Tango.PMR/TCC/DetectionInput.cs
index 3f598abb2..8a24008ad 100644
--- a/Software/Visual_Studio/Tango.PMR/TCC/DetectionInput.cs
+++ b/Software/Visual_Studio/Tango.PMR/TCC/DetectionInput.cs
@@ -23,16 +23,16 @@ namespace Tango.PMR.TCC {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"ChREZXRlY3Rpb25JbnB1dC5wcm90bxINVGFuZ28uUE1SLlRDQxoYRGV0ZWN0",
- "aW9uQmVuY2htYXJrLnByb3RvIq4BCg5EZXRlY3Rpb25JbnB1dBIOCgZCaXRt",
+ "aW9uQmVuY2htYXJrLnByb3RvItIBCg5EZXRlY3Rpb25JbnB1dBIOCgZCaXRt",
"YXAYASABKAwSDwoHQ29sdW1ucxgCIAEoBRIMCgRSb3dzGAMgASgFEhMKC1Rh",
- "cmdldEluZGV4GAQgASgFEhEKCURlYnVnTW9kZRgFIAEoCBI1CgpCZW5jaG1h",
- "cmtzGAYgAygLMiEuVGFuZ28uUE1SLlRDQy5EZXRlY3Rpb25CZW5jaG1hcmsS",
- "DgoGbnVtYmVyGAogASgBQhkKF2NvbS50d2luZS50YW5nby5wbXIudGNjYgZw",
- "cm90bzM="));
+ "cmdldEluZGV4GAQgASgFEhkKEVJlcXVlc3REZWJ1Z0ltYWdlGAUgASgIEhoK",
+ "ElJlcXVlc3RDb2xvck1hdHJpeBgGIAEoCBI1CgpCZW5jaG1hcmtzGAcgAygL",
+ "MiEuVGFuZ28uUE1SLlRDQy5EZXRlY3Rpb25CZW5jaG1hcmsSDgoGbnVtYmVy",
+ "GAogASgBQhkKF2NvbS50d2luZS50YW5nby5wbXIudGNjYgZwcm90bzM="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { global::Tango.PMR.TCC.DetectionBenchmarkReflection.Descriptor, },
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
- new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.TCC.DetectionInput), global::Tango.PMR.TCC.DetectionInput.Parser, new[]{ "Bitmap", "Columns", "Rows", "TargetIndex", "DebugMode", "Benchmarks", "Number" }, null, null, null)
+ new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.TCC.DetectionInput), global::Tango.PMR.TCC.DetectionInput.Parser, new[]{ "Bitmap", "Columns", "Rows", "TargetIndex", "RequestDebugImage", "RequestColorMatrix", "Benchmarks", "Number" }, null, null, null)
}));
}
#endregion
@@ -67,7 +67,8 @@ namespace Tango.PMR.TCC {
columns_ = other.columns_;
rows_ = other.rows_;
targetIndex_ = other.targetIndex_;
- debugMode_ = other.debugMode_;
+ requestDebugImage_ = other.requestDebugImage_;
+ requestColorMatrix_ = other.requestColorMatrix_;
benchmarks_ = other.benchmarks_.Clone();
number_ = other.number_;
}
@@ -121,21 +122,32 @@ namespace Tango.PMR.TCC {
}
}
- /// <summary>Field number for the "DebugMode" field.</summary>
- public const int DebugModeFieldNumber = 5;
- private bool debugMode_;
+ /// <summary>Field number for the "RequestDebugImage" field.</summary>
+ public const int RequestDebugImageFieldNumber = 5;
+ private bool requestDebugImage_;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public bool DebugMode {
- get { return debugMode_; }
+ public bool RequestDebugImage {
+ get { return requestDebugImage_; }
set {
- debugMode_ = value;
+ requestDebugImage_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "RequestColorMatrix" field.</summary>
+ public const int RequestColorMatrixFieldNumber = 6;
+ private bool requestColorMatrix_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool RequestColorMatrix {
+ get { return requestColorMatrix_; }
+ set {
+ requestColorMatrix_ = value;
}
}
/// <summary>Field number for the "Benchmarks" field.</summary>
- public const int BenchmarksFieldNumber = 6;
+ public const int BenchmarksFieldNumber = 7;
private static readonly pb::FieldCodec<global::Tango.PMR.TCC.DetectionBenchmark> _repeated_benchmarks_codec
- = pb::FieldCodec.ForMessage(50, global::Tango.PMR.TCC.DetectionBenchmark.Parser);
+ = pb::FieldCodec.ForMessage(58, global::Tango.PMR.TCC.DetectionBenchmark.Parser);
private readonly pbc::RepeatedField<global::Tango.PMR.TCC.DetectionBenchmark> benchmarks_ = new pbc::RepeatedField<global::Tango.PMR.TCC.DetectionBenchmark>();
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::Tango.PMR.TCC.DetectionBenchmark> Benchmarks {
@@ -170,7 +182,8 @@ namespace Tango.PMR.TCC {
if (Columns != other.Columns) return false;
if (Rows != other.Rows) return false;
if (TargetIndex != other.TargetIndex) return false;
- if (DebugMode != other.DebugMode) return false;
+ if (RequestDebugImage != other.RequestDebugImage) return false;
+ if (RequestColorMatrix != other.RequestColorMatrix) return false;
if(!benchmarks_.Equals(other.benchmarks_)) return false;
if (Number != other.Number) return false;
return true;
@@ -183,7 +196,8 @@ namespace Tango.PMR.TCC {
if (Columns != 0) hash ^= Columns.GetHashCode();
if (Rows != 0) hash ^= Rows.GetHashCode();
if (TargetIndex != 0) hash ^= TargetIndex.GetHashCode();
- if (DebugMode != false) hash ^= DebugMode.GetHashCode();
+ if (RequestDebugImage != false) hash ^= RequestDebugImage.GetHashCode();
+ if (RequestColorMatrix != false) hash ^= RequestColorMatrix.GetHashCode();
hash ^= benchmarks_.GetHashCode();
if (Number != 0D) hash ^= Number.GetHashCode();
return hash;
@@ -212,9 +226,13 @@ namespace Tango.PMR.TCC {
output.WriteRawTag(32);
output.WriteInt32(TargetIndex);
}
- if (DebugMode != false) {
+ if (RequestDebugImage != false) {
output.WriteRawTag(40);
- output.WriteBool(DebugMode);
+ output.WriteBool(RequestDebugImage);
+ }
+ if (RequestColorMatrix != false) {
+ output.WriteRawTag(48);
+ output.WriteBool(RequestColorMatrix);
}
benchmarks_.WriteTo(output, _repeated_benchmarks_codec);
if (Number != 0D) {
@@ -238,7 +256,10 @@ namespace Tango.PMR.TCC {
if (TargetIndex != 0) {
size += 1 + pb::CodedOutputStream.ComputeInt32Size(TargetIndex);
}
- if (DebugMode != false) {
+ if (RequestDebugImage != false) {
+ size += 1 + 1;
+ }
+ if (RequestColorMatrix != false) {
size += 1 + 1;
}
size += benchmarks_.CalculateSize(_repeated_benchmarks_codec);
@@ -265,8 +286,11 @@ namespace Tango.PMR.TCC {
if (other.TargetIndex != 0) {
TargetIndex = other.TargetIndex;
}
- if (other.DebugMode != false) {
- DebugMode = other.DebugMode;
+ if (other.RequestDebugImage != false) {
+ RequestDebugImage = other.RequestDebugImage;
+ }
+ if (other.RequestColorMatrix != false) {
+ RequestColorMatrix = other.RequestColorMatrix;
}
benchmarks_.Add(other.benchmarks_);
if (other.Number != 0D) {
@@ -299,10 +323,14 @@ namespace Tango.PMR.TCC {
break;
}
case 40: {
- DebugMode = input.ReadBool();
+ RequestDebugImage = input.ReadBool();
+ break;
+ }
+ case 48: {
+ RequestColorMatrix = input.ReadBool();
break;
}
- case 50: {
+ case 58: {
benchmarks_.AddEntriesFrom(input, _repeated_benchmarks_codec);
break;
}
diff --git a/Software/Visual_Studio/Tango.UnitTesting/TCC/TCC_TST.cs b/Software/Visual_Studio/Tango.UnitTesting/TCC/TCC_TST.cs
index 475bc68fd..ae5c66f6e 100644
--- a/Software/Visual_Studio/Tango.UnitTesting/TCC/TCC_TST.cs
+++ b/Software/Visual_Studio/Tango.UnitTesting/TCC/TCC_TST.cs
@@ -24,7 +24,7 @@ namespace Tango.UnitTesting.TCC
[TestMethod]
public void Detect()
{
- var original_bitmap = Directory.GetCurrentDirectory() + "\\TCC\\TCC Resources\\bitmap_ok.bmp";
+ var original_bitmap = Directory.GetCurrentDirectory() + "\\TCC\\TCC Resources\\bitmap.bmp";
using (ColorDetector detector = new ColorDetector())
{
@@ -35,43 +35,50 @@ namespace Tango.UnitTesting.TCC
Rows = 11,
TargetIndex = 99,
Bitmap = ByteString.CopyFrom(File.ReadAllBytes(original_bitmap)),
- DebugMode = true,
+ RequestColorMatrix = true,
+ RequestDebugImage = true,
};
var output = detector.Detect(input);
- using (MemoryStream ms = new MemoryStream(output.DebugBitmap.ToArray()))
+ if (input.RequestDebugImage)
{
- var outputBitmap = TemporaryManager.Default.CreateFile(".bmp");
- outputBitmap.Persist = true;
- ms.Position = 0;
- Bitmap bmp = new Bitmap(ms);
- bmp.Save(outputBitmap);
- Process.Start(outputBitmap);
+ using (MemoryStream ms = new MemoryStream(output.DebugBitmap.ToArray()))
+ {
+ var outputBitmap = TemporaryManager.Default.CreateFile(".bmp");
+ outputBitmap.Persist = true;
+ ms.Position = 0;
+ Bitmap bmp = new Bitmap(ms);
+ bmp.Save(outputBitmap);
+ Process.Start(outputBitmap);
+ }
}
- using (Bitmap colorMatrixBmp = ColorDetector.DetectionOutputToImage(input, output, 300, 320))
+ if (input.RequestColorMatrix)
{
- var outputBitmap = TemporaryManager.Default.CreateFile(".bmp");
- outputBitmap.Persist = true;
- colorMatrixBmp.Save(outputBitmap);
- Process.Start(outputBitmap);
- }
+ using (Bitmap colorMatrixBmp = ColorDetector.DetectionOutputToImage(input, output, 300, 320))
+ {
+ var outputBitmap = TemporaryManager.Default.CreateFile(".bmp");
+ outputBitmap.Persist = true;
+ colorMatrixBmp.Save(outputBitmap);
+ Process.Start(outputBitmap);
+ }
- var benchmarksCsvFile = TemporaryManager.Default.CreateFile(".csv");
- benchmarksCsvFile.Persist = true;
+ var benchmarksCsvFile = TemporaryManager.Default.CreateFile(".csv");
+ benchmarksCsvFile.Persist = true;
- using (CsvFile<DetectionColor> benchmarksRGB = new CsvFile<DetectionColor>(new CsvDestination(benchmarksCsvFile)))
- {
- foreach (var color in output.ColorMatrix)
+ using (CsvFile<DetectionColor> benchmarksRGB = new CsvFile<DetectionColor>(new CsvDestination(benchmarksCsvFile)))
{
- benchmarksRGB.Append(color);
+ foreach (var color in output.ColorMatrix)
+ {
+ benchmarksRGB.Append(color);
+ }
}
- }
- Helper.ShowInExplorer(benchmarksCsvFile);
+ Helper.ShowInExplorer(benchmarksCsvFile);
- Assert.IsTrue(output.Number == 15);
+ Assert.IsTrue(output.Number == 15);
+ }
}
}
diff --git a/Software/Visual_Studio/Tango.sln b/Software/Visual_Studio/Tango.sln
index efdf1c2ce..ef5d79e33 100644
--- a/Software/Visual_Studio/Tango.sln
+++ b/Software/Visual_Studio/Tango.sln
@@ -285,6 +285,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Tango.TCC.LoadTestLib", "TC
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tango.MachineStudio.ColorCapture", "MachineStudio\Modules\Tango.MachineStudio.ColorCapture\Tango.MachineStudio.ColorCapture.csproj", "{1B87CA53-50BD-4C48-A8C7-FBB9F1419AFF}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Tango.TCC.CardDetector", "TCC\Tango.TCC.CardDetector\Tango.TCC.CardDetector.vcxproj", "{BB268536-9E03-46A4-9B11-6025211D87F0}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
AppVeyor|Any CPU = AppVeyor|Any CPU
@@ -5063,6 +5065,40 @@ Global
{1B87CA53-50BD-4C48-A8C7-FBB9F1419AFF}.Release|x64.Build.0 = Release|Any CPU
{1B87CA53-50BD-4C48-A8C7-FBB9F1419AFF}.Release|x86.ActiveCfg = Release|Any CPU
{1B87CA53-50BD-4C48-A8C7-FBB9F1419AFF}.Release|x86.Build.0 = Release|Any CPU
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.AppVeyor|Any CPU.ActiveCfg = Release|x64
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.AppVeyor|Any CPU.Build.0 = Release|x64
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.AppVeyor|ARM.ActiveCfg = Release|x64
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.AppVeyor|ARM.Build.0 = Release|x64
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.AppVeyor|ARM64.ActiveCfg = Release|x64
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.AppVeyor|ARM64.Build.0 = Release|x64
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.AppVeyor|x64.ActiveCfg = Release|x64
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.AppVeyor|x64.Build.0 = Release|x64
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.AppVeyor|x86.ActiveCfg = Release|Win32
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.AppVeyor|x86.Build.0 = Release|Win32
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.Debug|Any CPU.ActiveCfg = Debug|Win32
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.Debug|ARM.ActiveCfg = Debug|Win32
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.Debug|ARM64.ActiveCfg = Debug|Win32
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.Debug|x64.ActiveCfg = Debug|x64
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.Debug|x64.Build.0 = Debug|x64
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.Debug|x86.ActiveCfg = Debug|Win32
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.Debug|x86.Build.0 = Debug|Win32
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.DefaultBuild|Any CPU.ActiveCfg = Release|x64
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.DefaultBuild|Any CPU.Build.0 = Release|x64
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.DefaultBuild|ARM.ActiveCfg = Release|x64
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.DefaultBuild|ARM.Build.0 = Release|x64
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.DefaultBuild|ARM64.ActiveCfg = Release|x64
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.DefaultBuild|ARM64.Build.0 = Release|x64
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.DefaultBuild|x64.ActiveCfg = Debug|x64
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.DefaultBuild|x64.Build.0 = Debug|x64
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.DefaultBuild|x86.ActiveCfg = Debug|Win32
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.DefaultBuild|x86.Build.0 = Debug|Win32
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.Release|Any CPU.ActiveCfg = Release|Win32
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.Release|ARM.ActiveCfg = Release|Win32
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.Release|ARM64.ActiveCfg = Release|Win32
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.Release|x64.ActiveCfg = Release|x64
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.Release|x64.Build.0 = Release|x64
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.Release|x86.ActiveCfg = Release|Win32
+ {BB268536-9E03-46A4-9B11-6025211D87F0}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -5153,14 +5189,15 @@ Global
{5D0D4053-CAB3-4A4A-929E-37A76483BC22} = {DA2B8F5D-AE3C-4E78-AEEB-FC17D0582690}
{DD19A7B3-E4B0-444E-98D4-D1C346442E63} = {DA2B8F5D-AE3C-4E78-AEEB-FC17D0582690}
{1B87CA53-50BD-4C48-A8C7-FBB9F1419AFF} = {B2AF4F3F-2828-47C3-8F3E-A0EA0BD66FF8}
+ {BB268536-9E03-46A4-9B11-6025211D87F0} = {DA2B8F5D-AE3C-4E78-AEEB-FC17D0582690}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
- BuildVersion_UseGlobalSettings = False
- BuildVersion_AssemblyInfoFilename = Properties\AssemblyInfo.cs
- BuildVersion_StartDate = 2000/1/1
- BuildVersion_UpdateFileVersion = False
- BuildVersion_UpdateAssemblyVersion = True
- BuildVersion_BuildVersioningStyle = None.None.Increment.DeltaBaseYearDayOfYear
SolutionGuid = {7986F7F4-A86A-4994-B1B6-0988D7F057B6}
+ BuildVersion_BuildVersioningStyle = None.None.Increment.DeltaBaseYearDayOfYear
+ BuildVersion_UpdateAssemblyVersion = True
+ BuildVersion_UpdateFileVersion = False
+ BuildVersion_StartDate = 2000/1/1
+ BuildVersion_AssemblyInfoFilename = Properties\AssemblyInfo.cs
+ BuildVersion_UseGlobalSettings = False
EndGlobalSection
EndGlobal