Passing Data To and From WiT Engine

This example (demoPrograms\engine\VC#\data or demoPrograms\engine\VB\data) demonstrates how data can be passed between WiT Engine and a user application.


Data Passing

In this example, when you click Run, data is sent from the user application to WiT Engine and processed by WiT Engine. Then the result data is sent from WiT Engine to the user application and processed further by the user application.

Data is passed from the user application to WiT Engine by using the readObj operator. Data is passed from WiT Engine to the user application by using the display operator.


Data Passing Igraph

The display window is mapped to the name ‘data’ as usual. SetOutputCallback is used to tell WiT Engine to call the dataChanged event procedure whenever the display operator named dataFromWiT is created. The data format is set to WIT_DATA_FORMAT_HYBRID, because we are going to send image data from WiT Engine to the user-application, and the hybrid type is most efficient for images. Hybrid format means the image header is sent as text, but the pixel values are sent as binary data. SetInputCallback is used to tell WiT Engine to call needData whenever any readObj operator with its filename parameter set to ‘sample’ is executed.

[C#]
WiT.engine.SetDisplayWnd("data", PictureBox1.Handle);
myOutCallback = new WiT.engine.outputCB(dataChanged);
WiT.engine.SetOutputCallback("dataFromWiT", myOutCallback,
    (int)WiT.DataFormat.WIT_DATA_FORMAT_HYBRID);

[Visual Basic]
WiT.engine.SetDisplayWnd("data", PictureBox1.Handle)
myOutCallback = New WiT.engine.outputCB(AddressOf dataChanged)
WiT.engine.SetOutputCallback("dataFromWiT", myOutCallback, _
    CType(WiT.DataFormat.WIT_DATA_FORMAT_HYBRID, Integer))

The function dataChanged processes the data it receives from WiT:

[C#]
public void dataChanged(string name, string buf, IntPtr rawData)
{
    if (buf == null) return;
    string delimStr = " ";
    char [] delimiter = delimStr.ToCharArray();
    string [] split = null;
    split = buf.Split(delimiter);
    if (split.Length != 10)
    {
        imgLabel.Text = "Wrong format";
    }
    else if (split[2] != "CorImage")
    {
        imgLabel.Text = "Not WiT image";
    }
    else if (split[3] != "CorUByte")
    {
        imgLabel.Text = "Not WiT 8-bit image";
    }
    else
    {
        int width = Convert.ToInt32(split[4]);
        int height = Convert.ToInt32(split[5]);
        int size = width * height;
        float total = 0;
        unsafe
        {
            byte *p = (byte *)(void *)rawData;
            for (int i = 0;i < size;i++, p++) total += (float)(*p);
        }
        total /= (float)size;
        imgLabel.Text = String.Format("{0} x {1}, mean: {2:f2}",
            width, height, total);
    }
}

[Visual Basic]
Public Sub dataChanged(ByVal name As String, ByVal buf As String, _
                       ByVal rawData As IntPtr)
    If buf Is Nothing Then
        Return
    End If
    Dim delimStr As String = " "
    Dim delimiter() As Char = delimStr.ToCharArray()
    Dim split() As String = Nothing
    split = buf.Split(delimiter)
    If split.Length <> 10 Then
        imgLabel.Text = "Wrong format"
    ElseIf split(2) <> "CorImage" Then
        imgLabel.Text = "Not WiT image"
    ElseIf split(3) <> "CorUByte" Then
        imgLabel.Text = "Not WiT 8-bit image"
    Else
        Dim width As Integer = Convert.ToInt32(split(4))
        Dim height As Integer = Convert.ToInt32(split(5))
        Dim size As Integer = width * height
        Dim total As Single = 0
        Dim i As Integer
        Dim val(size) As Byte
        Marshal.Copy(rawData, val, 0, size)
        For i = 0 To size - 1 Step 1
            total += val(i)
        Next
        total /= size
        imgLabel.Text = String.Format("{0} x {1}, mean: {2:f2}", _
            width, height, total)
    End If
End Sub

Because the data format was specified as HYBRID when SetOutputCallback was called, the data for the image is split into two sections. The header, which contains information about the image size and type, is stored as text (ASCII). WiT Engine sends multi-line data with only a line-feed character between lines. But a .Net edit control requires both a line-feed and carriage return character for each new line, so carriage return characters are added to the text before it is displayed. The actual image data is stored in raw format in rawData. The raw data is processed by dataChanged to compute the mean value of all the pixels.

The WIC contains a readObj operator with the filename set to ‘sample’. Because this file name has been mapped with SetInputCallback, when the readObj operator is executed, needData will be called. In the event procedure, if the value of DataToWiT is TRUE it means the user wants to send an image, so a simple grayscale ramp image is prepared and passed to WiT Engine using SetInputData. If DataToWiT is FALSE, the data in the text window on the right of the application is sent to WiT Engine. The format of the data should be the same as the text format supported by the writeObj operator (see the WiT User's Manual for details about this format).

[C#]
public void needData(string name)
{
    if (d2wImg.Checked)
    {
        unsafe
        {
            int width = 256;
            int height = 256;
            byte * data = (byte *)Marshal.AllocHGlobal(width * height);
            for (int i = 0;i < width;++i)
                for (int j = 0;j < height;++j)
                    data[i *width + j] = (byte)j;
            string header = String.Format(
                "OBJ_B H CorImage CorUByte {0} {1}", width, height);
            WiT.engine.SetInputData(name, header, header.Length,
                (IntPtr)data, width * height);
            Marshal.FreeHGlobal((IntPtr)data);
        }
    }
    else
    {
        WiT.engine.SetInputData(name, textWin.Text, textWin.Text.Length,
            IntPtr.Zero, 0);
    }
}

[Visual Basic]
Public Sub needData(ByVal name As String)
    If d2wImg.Checked Then
        Dim width As Integer = 256
        Dim height As Integer = 256
        Dim size As Integer = width * height
        Dim data As IntPtr = Marshal.AllocHGlobal(size)
        Dim i As Integer
        Dim j As Integer
        Dim val(size) As Byte
        Dim pos As Integer = 0
        For i = 0 To width - 1 Step 1
           For j = 0 To height - 1 Step 1
               val(pos) = CType(j, Byte)
               pos += 1
           Next
        Next
        Marshal.Copy(val, 0, data, size)
        Dim header As String = String.Format(_
            "OBJ_B H CorImage CorUByte {0} {1}", width, height)
        WiT.engine.SetInputData(name, header, header.Length, _
            CType(data, IntPtr), size)
        Marshal.FreeHGlobal(CType(data, IntPtr))
    Else
        WiT.engine.SetInputData(name, textWin.Text, _
            textWin.Text.Length, IntPtr.Zero, 0)
    End If
End Sub

A mapping for readObj can be unregistered at any time by calling SetInputCallback with a value of 0 for the onOff parameter. In this example, if Data from this application is unchecked, the event is unregistered and the readObj operator will read from file ‘sample2’ instead.

Previous 

Up 

Next