<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Recent changes to Home</title><link>https://sourceforge.net/p/fastimageex/wiki/Home/</link><description>Recent changes to Home</description><atom:link href="https://sourceforge.net/p/fastimageex/wiki/Home/feed" rel="self"/><language>en</language><lastBuildDate>Thu, 02 May 2013 12:26:57 -0000</lastBuildDate><atom:link href="https://sourceforge.net/p/fastimageex/wiki/Home/feed" rel="self" type="application/rss+xml"/><item><title>Home modified by Perrotti</title><link>https://sourceforge.net/p/fastimageex/wiki/Home/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v10
+++ v11
@@ -20,3 +20,5 @@
 **8. [Process methods reference]**

 **9. [Utilities - Miscellaneous]**
+
+**10. [Properties]**
&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Perrotti</dc:creator><pubDate>Thu, 02 May 2013 12:26:57 -0000</pubDate><guid>https://sourceforge.net155e9aab4f035597f138e3895eb12288c97e2b45</guid></item><item><title>Home modified by Perrotti</title><link>https://sourceforge.net/p/fastimageex/wiki/Home/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v9
+++ v10
@@ -19,4 +19,4 @@

 **8. [Process methods reference]**

-**9. [Utilities / Miscellaneous]**
+**9. [Utilities - Miscellaneous]**
&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Perrotti</dc:creator><pubDate>Thu, 02 May 2013 12:25:47 -0000</pubDate><guid>https://sourceforge.net33b362df06fab2dc8cb3f55abaeda3d56a6f8077</guid></item><item><title>Home modified by Perrotti</title><link>https://sourceforge.net/p/fastimageex/wiki/Home/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v8
+++ v9
@@ -8,3 +8,15 @@
 **2. [Basic Structures]**

 **3. [Channels overview]**
+
+**4. [Channel statistics] - TStatsChannel class**
+
+**5. [Using masks]**
+
+**6. [Run Length Encode] - TRunCode class**
+
+**7. [TFastImageEx class]**
+
+**8. [Process methods reference]**
+
+**9. [Utilities / Miscellaneous]**
&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Perrotti</dc:creator><pubDate>Thu, 02 May 2013 12:15:42 -0000</pubDate><guid>https://sourceforge.netd8f2cd9e9287c005c6aba7fe058e0fe0337e4522</guid></item><item><title>Home modified by Perrotti</title><link>https://sourceforge.net/p/fastimageex/wiki/Home/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v7
+++ v8
@@ -6,3 +6,5 @@
 It is a project open to collaborations. Implementations of algorithms, optimizations, suggestions, tips or additions are welcome, feel free to collaborate.

 **2. [Basic Structures]**
+
+**3. [Channels overview]**
&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Perrotti</dc:creator><pubDate>Thu, 02 May 2013 12:07:15 -0000</pubDate><guid>https://sourceforge.netbd8f5e713a2dab9ae98183935dac5a5c783d57d5</guid></item><item><title>Home modified by Perrotti</title><link>https://sourceforge.net/p/fastimageex/wiki/Home/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v6
+++ v7
@@ -4,3 +4,5 @@
 Be sure that you have the last version before use the classes. The last release can be downloaded at .

 It is a project open to collaborations. Implementations of algorithms, optimizations, suggestions, tips or additions are welcome, feel free to collaborate.
+
+**2. [Basic Structures]**
&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Perrotti</dc:creator><pubDate>Thu, 02 May 2013 12:01:35 -0000</pubDate><guid>https://sourceforge.net130bb0e945cbe16b4c900cb0c95d52a6850cbaf5</guid></item><item><title>Home modified by Perrotti</title><link>https://sourceforge.net/p/fastimageex/wiki/Home/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v5
+++ v6
@@ -1 +1,6 @@
-1. Introduction
+**1. Introduction**
+This package defines an image format that was designed to be easily processed and can contain multiple channels. 1, 3 and 4 are common values but any number of channels is possible. This version defines channels with 8, 16 or 32 bits deep and allows mixing different types of channels in same image. Each channel is stored in a map separated from other channels and can be independently processed without requiring any additional manipulation.
+
+Be sure that you have the last version before use the classes. The last release can be downloaded at . 
+
+It is a project open to collaborations. Implementations of algorithms, optimizations, suggestions, tips or additions are welcome, feel free to collaborate.
&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Perrotti</dc:creator><pubDate>Thu, 02 May 2013 12:00:26 -0000</pubDate><guid>https://sourceforge.nete5057012991b5af9f44eadf9c11759b9b1a1c713</guid></item><item><title>Home modified by Perrotti</title><link>https://sourceforge.net/p/fastimageex/wiki/Home/</link><description>&lt;pre&gt;&amp;lt;pre&amp;gt;--- v4
+++ v5
@@ -1,907 +1 @@
-Welcome to your wiki!
-
-This is the default page, edit it as you see fit. To add a new page simply reference it within brackets, e.g.: [SamplePage].
-
-The wiki uses [Markdown](/p/fastimageex/wiki/markdown_syntax/) syntax.
-
-[[project_admins]]
-[[download_button]]
-
-
 1. Introduction
-This package defines an image format that was designed to be easily processed and can contain multiple channels. 1, 3 and 4 are common values but any number of channels is possible. This version defines channels with 8, 16 or 32 bits deep and allows mixing different types of channels in same image. Each channel is stored in a map separated from other channels and can be independently processed without requiring any additional manipulation.
-Be sure that you have the last version before use the classes. The last release can be downloaded at https://sourceforge.net/projects/fastimageex/. 
-It is a project open to collaborations. Implementations of algorithms, optimizations, suggestions, tips or additions are welcome, feel free to collaborate.
-
-2. [[Basic Structures]]
-3. [Channels overview]
-The channels are the core of all processing done on the images in this package. They are part of the images, but also can act as independent entities. All available image processes can be applied to the entire image or a specific channel in the image. In fact, some features are only available (at present) for channels and not for images.
-There is a set of classes to define and manipulate channels. TfiChannel is the abstract base class that defines the main methods and properties of channels. A channel contains a two-dimensional array of the type defined by the depth of channel. The property Map returns a reference to this array. You can also obtain a reference to a single line by the Row property.
-Channel classes
-TfiChannel8U : 8 bits channel (unsigned)
-TfiChannel16S: 16 bits channel (signed)
-TfiChannel32F: 32 bits channel (float)
-Channel construction
-The channels are designed primarily for use by the main class TFastImageEx, but can be manipulated independently. TFastImageEx can create the channels needed for the images, and eventually also create channels to store processes results. But in some cases can be useful to create channels out of images. So far, there are two ways to directly build channels out of images: the default constructor or copy constructor listed below. 
-constructor Create(fSize: TfiSize);
-Constructs an empty channel with the dimensions indicated by fSize. 
-constructor Create(Channel: TfiChannel); 
-Copy constructor. The parameter Channel must be the same type of class of channel that is being constructed.
-Methods
-procedure Assign(Channel: TfiChannel);
-Copy the channel informed. This procedure can change the channel dimensions to match with channel on parameter. The channel informed must be the same type.
-
-procedure FillRow(index: integer; const value: single); 
-procedure FillCol(index: integer; const value: single); 
-procedure FillMap(const value: single); 
-procedure FillRect(const value; Rt: TRect: single); 
-Fill row, column, entire map or rectangle with the value informed. Value must be in the range type of channel map. FillRect do not perform any range check.
-
-procedure CopyRectTo(RtSrc: TRect; Dest: TfiChannel; 
-                     x: integer=0; y: integer=0); 
-Copy a rectangle to an informed destination channel, starting at (x, y) position. Dest channel must be the same type of source channel. No range check is performed.
-
-procedure MinMaxVals(out MinVal: single; out MaxVal: single); 
-Return then minimum and maximum values on channel.
-Properties
-property Row[index: integer]: PRow;
-property Map: PMap;
-Return a reference to row or map. These properties are overridden to return the appropriate type depending of channel depth.
-
-property Width: integer;
-property Height: integer;
-property Depth: integer;
-property iSize: TfiSize;
-property SizeAsRect: TRect;
-
-Read only properties. Depth returns one of constants listed above on Channel maps topic. iSize return the size of channel and SizeAsRect return a TRect with channel dimensions.
-Binary channels
-For this implementation, is not defined any specific binary channel (1 bit depth), however any of the three defined types can be treated as a binary channel. Some processes only exists or only makes sense if applied to binary data. In this case, the general rule used by the package is considered the zero value as zero (!) and any value other than zero as one. Some other processes can be applied both to binary data and 8 or more bits data. For these processes will need to specify how they should work.
-Channels processes
-Most processes available for the images are actually implemented in channel’s classes. The class that manages the images (TFastImageEx) uses these implementations to provide access to these processes. 
-Use the images to run processes offers more options related to input and output. For example, from an image is possible to create new channels to store the process results, or select all the channels of image as input to process. But the process itself, with all options related to its operation mode, can be accessed directly from a channel. Below, the list of processes available form channels. To complete discussion about the processes and the parameters used, look the related topic on TFastImageEx reference (chapter 8).
-
-Threshold
-procedure Threshold(cDest: TfiChannel; ThreshType: integer;
-                    Thresh, MaxValue: single);
-
-Convert
-procedure Convert(cDest: TfiChannel; ScalingMode: integer; 
-                  Param1: single=0; Param2: single=0); 
-
-BinaryInv
-procedure BinaryInv(cDest: TfiChannel; MaxValue: single);
-
-Arithmetic
-procedure Arithmetic(cOper, cDest: TfiChannel; Operation: integer;
-                     Param1: single=1; Param2: single=1);
-
-Convolution
-procedure Convolve(cDst: TfiChannel; Mask: TfiGrayMask); 
-
-Match
-procedure Match(cDst: TfiChannel; Operation: integer; 
-              Mask: TfiGrayMask; ValIfMatch, ValNoMatch: integer); 
-
-Erode
-procedure Erode(cDst: tfiChannel; Iterations: integer; 
-                bMask: TfiBinMask; Binary: boolean);
-Dilate
-procedure Dilate(cDst: tfiChannel; Iterations: integer; 
-                 bMask: TfiBinMask; Binary: boolean);
-Morphology
-procedure Morphology(cDst: tfiChannel; 
-                     Operation, Iterations: integer; 
-                     bMask: TfiBinMask; Binary: boolean);
-
-4. [Channel statistics] – TStatsChannel class
-Some statistics of channels information are very common and useful in image processing. The TStatsChannel class provides a common set of statistics that can be obtained running the channel once. The channel is scanned at the time that the class is instantiated, so the statistics are always available while the instance exists.
-This class calculates the horizontal and vertical projections, the histogram, and other information. All calculated statistics are available through properties. For the moment, only 8-bits channels can be scanned, but future versions will support 16 and 32 bits channels.
-ROI support
-The statistics can be calculated from entire map, or only in specific ROI (Region Of Interest). The ROI can be defined by a rectangle (TRect) or by a mask with any shape. For mask details see specific topic ahead.
-Constructors
-To create an instance of TStatsChannel class you can use one of the three constructors listed below.
-1) No ROI, use the entire channel
-constructor Create(Chn: TfiChannel8U; Calcs: TChannelCalcSet; 
-                   Binary: boolean); 
-
-Chn is a reference to channel that will be scanned. At the moment, only 8 bits channels can be used.
-Calcs inform if the histogram and projections must be created. Histograms and projections are arrays and therefore spend memory to be stored. Because they are not always necessary, creating them is optional. The type TChannelCalcSet is defined as follows: 
-type
-  TChannelCalcs = (ccHist, ccVtProj, ccHzProj);
-
-Binary affects how the projections are be calculated. If is true, the channel will be considered a binary channel and the projections will contain the number of active pixels (with value different from zero) in each row or column. If is false, the projections will contain the sum of values in each row or column.
-2) With rectangular ROI
-constructor Create(Chn: TfiChannel8U; Calcs: TChannelCalcSet; 
-                   Binary: boolean; RtROI: TRect); 
-
-RtROI is a rectangle with the region that will be considered to calc the statistics. Projections are being returned with the rectangle dimensions. If the rectangle exceeds the limits of image, it will be clipped. For safety, whenever run the projections, use the HzSize and VtSize properties to get their actual length.
-3) With mask ROI
-constructor Create(Chn: TfiChannel8U; Calcs: TChannelCalcSet; 
-                   Binary: boolean; MaskROI: TfiBinMask; X, Y: integer); 
-MaskROI is the mask that defines the pixels that will be processed. A mask is essentially a list of points, so there is no shape associated. However, the max and min values of coordinates of points in mask are used to calculate an involving rectangle, and the dimensions of this rectangle are used to create the projections. If the rectangle exceeds the limits of image, it will be clipped. Points out image are ignored. X and Y parameters indicate where the base point of mask will be positioned.
- 
-Properties
-All statistics calculated are available by the properties of class, described below. All properties are read only.
-property ROIrect: TRect;
-Return the involving rectangle of region considered to calculations. If no ROI was defined (constructor 1), region is the entire channel.
-property Width: integer;
-Return the width of region considered to calculations. 
-property Height: integer;
-Return the Height of region considered to calculations. 
-property Histogram: PHistogram;
-Reference to histogram of the region considered to calculations. If the value ccHist was no present in the Calcs parameter, this property returns nil.
-property HzProj: PProjection;
-Reference to horizontal projection of the region considered to calculations. If the value ccHzProj was no present in the Calcs parameter, this property returns nil.
-property HzSize: integer;
-Length of horizontal projection returned by HzProj property. If the value ccHzProj was no present in the Calcs parameter, this property returns zero.
-property HzMax: integer;
-The maximum value on horizontal projection returned by HzProj property. If the value ccHzProj was no present in the Calcs parameter, this property returns zero.
-property VtProj: PProjection;
-Reference to vertical projection of the region considered to calculations. If the value ccVtProj was no present in the Calcs parameter, this property returns nil.
-property VtSize: integer;
-Length of vertical projection returned by VtProj property. If the value ccVtProj was no present in the Calcs parameter, this property returns zero.
-property VtMax: integer;
-The maximum value on vertical projection returned by VtProj property. If the value ccVtProj was no present in the Calcs parameter, this property returns zero.
-property TotalArea: integer;
-Return the total area of region. Area is the number of pixels in the region considered. If region was defined by a rectangle or is the entire channel, area is Width*Height. If region was defined by mask, area is the number of points in the mask.
-property LevelSum: integer;
-Return the sum of values in the region considered.   
-property LevelMax: integer;
-The maximum value found in region.
-property LevelMin: integer;
-The minimum value found in region.
-property ZeroCount: integer;
-The number of pixels with zero value.
-property NonZeroCount: integer;
-The number of pixels with non-zero value.
-property Average: single;
-Average of values in region (LevelSum / TotalArea)
-property Density: single;
-This property makes more sense to binary images. Is the concentration of active pixels in the considered region (NonZeroCount / TotalArea).
-property BinGrav: TFloatPoint;
-Return the gravity center of region considering image as binary. Is an average of X and Y coordinates to all active pixels.
-property GrayGrav: TFloatPoint;
-Return the gravity center of region considering image as gray. Is a weighted average of X and Y coordinates to active pixels. The weight is the gray level of pixel.
-
-Viewing the results
-To view the histogram and projections, TStatsChannel implements the methods below to draw graphics on bitmaps.
-
-function HistToBitmap(bmpHeight: integer; LineWidth: byte; 
-                      Color: TColor): TBitmap;
-Return a bitmap with graphical representation of histogram.
-
-function HzProjToBitmap(bmpWidth: integer; FromLeft: boolean; 
-                        Color: TColor): TBitmap;
-function VtProjToBitmap(bmpHeight: integer; FromTop: boolean; 
-                        Color: TColor): TBitmap;
-Return a bitmap with graphical representation of projection. FromLeft and FromTop inform the origin of graphics. These methods are intended to represent projections of gray images (figure 1).
-
- 
-Figure 1 - Example of graphs generated by the methods HistToBitmap (top right corner), HzProjToBitmap (right of image) and VtProjToBitmap (below image).
-
- 
-procedure DrawHzProj(bitmap: TBitmap; LineWidth: integer;   
-                     FromLeft: boolean; Color: TColor);
-procedure DrawVtProj(bitmap: TBitmap; LineWidth: integer; 
-                     FromTop: boolean; Color: TColor);
-
-Draw the projection on bitmap informed. FromLeft and FromTop inform the origin of graphics. These methods are intended to represent projections of color images.
-
- 
-Figure 2 - Example of graphs generated by the methods HistToBitmap (right), DrawHzProj (right of image) and DrawVtProj (below image).
-
- 
-5. [Using masks]
-Binary mask - TfiBinMask class
-TfiBinMask have a very simple public interface and provide an easy way to produce binary masks. These masks can be used to define a ROI (Region Of Interest) inside a channel, as structuring elements in morphological operations or to perform match operations.
-Creating binary masks
-To create masks using TfiBinMask you can define your mask in a string list and call the method MakeFromStrings.  Parameters BaseX and BaseY informs the base point of mask related to string list. Character ‘1’ on string list means object, or active pixel. Character ‘0’ means background, or inactive pixel. Any other character means ‘don’t care’. Don’t use the character ‘0’ to create masks for morphological operations or to define a ROI. This option is only for match operations. See the example below that creates a 5x5 diamond mask. You also can create masks manually, point by point directly adding points with Add method. In this case you must calculate the offset of points related to base point. See the discussion in next topic for more details.
-var
-  mask: TfiBinMask;
-  sts: TStringList;
-  fImg: TFastImageEx;
-begin
-  […]
-  sts:= TStringList.Create;
-  sts.Add(‘  1’);
-  sts.Add(‘ 111’);
-  sts.Add(‘11111’);
-  sts.Add(‘ 111’);
-  sts.Add(‘  1’);
-
-  mask:= TfiBinMask.Create;
-  mask.MakeFromStrings(sts, 2, 2);
-  sts.Free;
-
-  // mask is ready to use now
-  fImg.Dilate(fi_ALL_CHANNELS, fi_INPLACE_CHN, 1, mask, true);
-  mask.Free;
-  […]
-end;
-
- 
-Public definition of TfiBinMask
-Below, the public methods and properties of TfiBinMask. A mask is basically a list of points in a coordinate system with origin in base point (BaseX and BaseY). So, the points store the offset related to base point. When the points are added, the maximum and minimum values from coordinate’s points are stored. These values are used to calculate the rectangle returned by SizeAsRect property and the dimensions of mask returned by properties Width, Height and iSize. Property Items (default) allow access to point’s list.
-
-type
-TMaskBinPoint = class
-  dx, dy: integer;
-  Value: boolean;
-  constructor Create(adx, ady: integer; aValue: boolean);
-end;
-
-TfiBinMask = class(TList)
-public
-  constructor Create;
-  function Add(Pt: TMaskBinPoint): integer;
-  function Get(index: integer): TMaskBinPoint;
-  procedure AssignChannel(Chn: TfiChannel);
-  procedure ReleaseChannel;
-  function Match(x, y: integer): boolean;
-  function ErodeBin(x,y: integer): single;
-  function ErodeGray(x,y: integer): single;
-  function DilateBin(x,y: integer): single;
-  function DilateGray(x,y: integer): single;  
-  function MakeFromStrings(Sts:TStrings; BaseX, BaseY: integer): boolean;
-  //
-  // properties
-  property Width: integer;
-  property Height: integer;
-  property iSize: TfiSize;
-  property SizeAsRect: TRect;  
-  property Items[index:integer]:TMaskBinPoint; default;
-end; 
-
-Advanced use
-TfiBinMask can be used in basic way to define structuring elements to morphological operations or to define a ROI to statistics calculations. For this is enough creating the mask, passes it in parameters of appropriate methods and then destroy the mask. But is also possible use the mask to perform more advanced functions.
-The mask has an internal mechanism to move through a channel running some predefined operations. Actually, that's how most of morphological functions use the mask. To use this feature, you must first associate the mask with a channel of image. After that, you can call the methods available informing the position on channel were the operations must be performed. All these operations are available from images or channels, and to process an entire channel or all channels on image, is better (and faster) to process from channel or image. But if you need process one or few pixels on channel, you can use this feature directly from mask. See the example below.
-
-var
-  mask: TfiBinMask;
-  sts: TStringList;
-  fImg: TFastImageEx;
-begin
-  […]
-  // Mask to detect top left corners
-  sts:= TStringList.Create;
-  sts.Add(‘000’);
-  sts.Add(‘011’);
-  sts.Add(‘011’);
-
-  mask:= TfiBinMask.Create;
-  mask.MakeFromStrings(sts, 1, 1);
-  sts.Free;
-
-  mask.AssignChannel(fImg[fi_BIN]);
-  if mask.Match(10, 10) then
-  begin
-    // there is a top left corner on (10, 10) position
-    […]
-  end;
-  mask.ReleaseChannel;
-  mask.Free;
-end;
-
-Mask operations
-
-function Match(x, y: integer): boolean;
-Test if every point in mask match with pixels on channel at position informed. Is a binary operation, a pixel is considered active if their value is different of zero or inactive if their value is zero. Return true if each point on mask match with corresponding pixel on image.
-
-function ErodeBin(x,y: integer): single;
-function DilateBin(x,y: integer): single;
-Return the value of binary erosion/dilation on pixel at position informed.
-
-function ErodeGray(x,y: integer): single;
-function DilateGray(x,y: integer): single;  
-Return the value of gray erosion/dilation on pixel at position informed
-Gray mask - TfiGrayMask class
-This class provides a mask with non-binary values. It’s similar with binary mask, but the points can assume any value and mask can have a weight to divide the result. The main purpose of this mask is support filtering operations. To create a gray mask, you also can use a string list with values of points. The values must be separated by spaces and character ‘x’ means ‘don’t care’. The example below creates two masks with Sobel operators:
-var
-  sobHz, sobVt: TfiGrayMask;
-  sts: TStringList;
-  fImg: TFastImageEx;
-begin
-  […]
-  // Sobel vertical operator
-  sts:= TStringList.Create;
-  sts.Add(‘1 x -1’);
-  sts.Add(‘2 x -2’);
-  sts.Add(‘1 x -1’);
-
-  sobVt:= TfiGrayMask.Create;
-  sobVt.MakeFromStrings(sts, 1, 1, 1);
-  sts.Free;
-
-  // Sobel horizontal operator
-  sts:= TStringList.Create;
-  sts.Add(‘ 1  2  1’);
-  sts.Add(‘ x  x  x’);
-  sts.Add(‘-1 -2 -1’);
-
-  sobHz:= TfiGrayMask.Create;
-  sobHz.MakeFromStrings(sts, 1, 1, 1);
-  sts.Free;
-  […]
-end;
-
-Public definition of TfiGrayMask class
-
-type
-
-TMaskGrayPoint = class
-  dx, dy: integer;
-  value: single;
-  constructor Create(adx, ady: integer; aValue: single);
-end;
-
- 
-TfiGrayMaskCustom = class(TfiBaseMask)
-public
-  constructor Create;
-  function CalcPos(x,y: integer): single;
-  function ErodeGray(x,y: integer): single;
-  function DilateGray(x,y: integer): single;
-  function Add(Pt: TMaskGrayPoint): integer;
-  function Get(index: integer): TMaskGrayPoint;
-  function MakeFromStrings(Sts: TStrings; BaseX, BaseY: integer;
-                           Weight: single = 1): boolean;
-  property Items[index:integer]:TMaskGrayPoint; default;
-end;
-
-Gray mask operations
-The gray mask works in a manner very similar to the binary mask. The main difference is that the image is always seen in gray level, never binary. 
-
-function CalcPos(x,y: integer): single;
-The value of each point on the mask is multiplied by the corresponding pixel in the image and the result of the multiplications are summed and then divided by the weight associated with the mask.
-
-function ErodeGray(x,y: integer): single;
-Performs gray erosion at the point indicated. The difference between doing the erosion with gray mask and binary mask is that the result with the mask gray is the minimum value obtained by subtracting the pixel with the corresponding point of the mask. Using binary mask the result is the minimum value of the pixels covered by mask.
-
-function DilateGray(x,y: integer): single;
-Performs gray dilation at the point indicated. The difference between doing the dilation with gray mask and binary mask is that the result with the mask gray is the maximum value obtained by adding the pixel with the corresponding point of the mask. Using binary mask the result is the maximum value of the pixels covered by mask.
-
- 
-6. [Run Length Encode] – TRunCode class
-The Run Length Encode is a powerful way to process binary images. It is a very simple algorithm that has been widely used to compress text and images, but later proved to be a very important tool in image processing, especially for binary images. When converting an image to RLE format is easy to detect connected objects in the image and perform a selective processing of each object.
-TRunCode class can convert a binary image to RLE format and provide some features to process the objects. In the process to detect connected objects the class also extracts some characteristics that can be used to analyze objects. More advanced (and useful) characteristics can be calculated after construction.
-Construction
-All processing required to create the image representation in RLE and to connect the objects in the image is made during the construction of the instance. So, once the instance is created, is ready for use. The only parameter required by the constructor is the channel to be processed. The channel is considered binary. In this implementation, RLE representation of gray images is not supported.
-
-constructor Create(Chn: TfiChannel);
-
-Objects characteristics
-An Object is a connected region of image. To store the object’s data TRunCode uses a list of TRunCodeObj instances. There are two sets of characteristics for objects. The first one is calculated by constructor and is always available. The second set depends of first set calculations and is not available until the method CalcBorderData to be called (see ahead). Below the data available on first set:
-ObjID: integer; 
-Object ID. Each object have an integer number as identifier that don’t change until the object be destroyed. This is not the index of object. Objects are stored in a list and also have an index, but some processes needs sort the objects to be performed and the index can change.
-NPix: integer; 
-Number of active pixels present in object (area).
- 
-Rt: TRect; 
-Involving rectangle of object.
-AreaRt: integer; 
-Area of involving rectangle.
-Dens: single; 
-Density of active pixels in object (NPix/AreaRt).
-cgx, cgy: single; 
-Gravity center of object. Are a coordinate’s averages of all active pixels in object.
-jRed, jGreen, jBlue: byte; 
-Random color used to represent objects in bitmaps.
-
-User data set
-The data below is also available on objects data, but are not used by classes. They are available for user processes: 
-TagI: int64;
-TagR: extended;
-Flag: boolean;
-Ptr: Pointer;
-Very important: If you allocate memory to Ptr pointer, you need assign a function to OnFreeObject event to free the memory when the object is destroyed.
-
-Border characteristics set
-This set of characteristics is related to borders of object and only is available after the method CalcBorderData to be called. 
-geoX, geoY: single;
-Geometric center of object. Is the average of all pixels detected on border of object. 
-DistAvr: single;
-Average of distances from geometric center to border pixels.
- 
-DistDev: single;
-Standard deviation of distances from geometric center to border pixels. This value tells about the circularity of the object. The closer a circle is the object, smaller is this value.
-Points: TPointList;
-Ordered list of pixels in border of object based on TList class. The first point is the left top pixel on object and the others points are in clock-wise sequence. Points are instances of TRCPoint class declared as below:
-TCPoint = class
-  x, y: integer;
-  gDist: single;
-  TagI: integer;
-  TagR: single;
-  constructor Create(ax, ay: integer; agDist, agAng: single);    
-  constructor Create(pt: TCPoint); 
-end;
-x and y are the coordinates of border pixel. gDist is the distance of pixel to geometric center (geoX, geoY). TagI and TagR are not used and are available to user processes.
-
-ptNear, ptFar: integer;
-The indexes of nearest and farthest points of border from geometric center. 
-
-Vectors: TPointList;
-After calculate the border points with CalcBorderData method, you can vectorize the border by calling Vectorize method. This method copies the Points list and deletes the collinear points leaving only the points in the extremes of straight segments that surround the object. The maximum error accepted to segments is informed by parameter.
-Processing objects overview
-TRunCode class maintains a list of objects in ObjList field (based on TList class), so you can run the object list to access data objects and perform the process that you need. There is other list (Lines) that actually contain the RLE structure of image, ObjList only reference this structure grouping the RLE items by objects. So, is very important that you don’t delete objects using the Delete method of TList class directly from ObjList, this will cause inconsistencies on structure. To delete objects safely, TRunCode class offers DeleteObj method.
-To run all objects list deleting objects by some criteria, use the method DelByUserTest. This method runs all objects and uses a call back function to decide which object will be deleted. Optionally, you can add a Single type parameters to call back function. See the example ahead.
-The procedure VisitObjects works in similar way, run all objects and send then to call back function, but no action is done with objects. This is useful to analyze objects and/or assign values to user data (TagI, TagR, Flag and Ptr). 
-To get more information about the objects call the method CalcBorderData that provides the list of border pixels and some statistics about. You also can call method Vectorize to get a list of straight segments around the objects.
-After processing, you maybe need return the RLE representation to image format, for that use the function ToImage to generate a new image or ToChannel to create a new channel. MaxVal parameter is the value used to represent active pixels on image or channel. Also you can transfer the RLE to bitmap with function ToBitmap; in this case, each object is painted with a random color. To draw all or one object in existing channel, use the methods Draw and DrawObj.
-
-Methods reference
-Procedure types
-These types are used to call back functions and events.
-
-TOnFreeObjectEvent = procedure (rcObj: TRunCodeObjData) of object;
-
-TrcUserTestFunction = function (rcObj: TRunCodeObjData; 
-                                Param1: single=0; 
-                                Param2: single=0): boolean;
-
-TrcVisitObjectsProc = procedure (rcObj: TRunCodeObjData; 
-                                 Param1: single=0; 
-                                 Param2: single=0);
-
-To process objects
-
-function DelByUserTest(func: TrcUserTestFunction; 
-                     Param1: single=0; Param2: single=0): integer;
-Run all objects and call the function in parameter to decide which object will be deleted. Param1 and Param2 are sent to call back function.
- 
-procedure VisitObjects(proc: TrcVisitObjectsProc; 
-                       Param1: single=0; Param2: single=0);
-Run all objects runs and sends them to the call back procedure informed in parameter. No action is done with objects.
-
-function MergeObjs(ObjRemain, ObjToMerge: integer): integer;
-Merge two objects. This method don’t change any pixel on image, but change the codes reference of second object to point to first object. The first characteristics set is updated to reflect the total of codes in the new object, but don’t the border data or vectors list. These features don’t support merged objects yet, but this is planned to future releases.
-function MergeInnerObjs(GravCtMaxDist: single): integer;
-This method merges objects whose involving rectangle is contained within the involving rectangle of other object and the distance between theirs gravity centers is less than the value informed in parameter.
-function ObjAtPoint(x, y: integer): integer;
-Return the ID of object at position informed or -1 if the position is background.
-procedure CloseHoles;
-Close the holes of all objects.
-function DeleteObj(ObjID: integer): integer;
-Delete the object informed. This is the only safe way to delete objects. If you use the Delete method derived from TList class, it will cause inconsistencies on run code structure.
-
-Borders
-procedure CalcBorderData;
-Calculate the second set of characteristics based on border points list and generate the border points list of all objects. This feature doesn’t support merged objects in present release.
-procedure Vectorize(MaxError: integer);
-Perform the vectorization of border points list to all objects. This feature is only available after calculation of border points list (CalcBorderData). This method copies the border points list to Vectors field and deletes the collinear points leaving only the points in the extremes of straight segments that surround the object. The maximum error accepted to segments is informed by parameter. 
- 
-Format conversions
-function ToBitmap: TBitmap;
-Create and return a 24 bits bitmap with all objects. Each object is drawn with a different random color.
-function ToImage(Depth: integer; MaxVal: single): TFastImageEx;
-Create and return a single channel image with all objects. MaxVal is the value used to represent active pixels on image.
-function ToChannel(Depth: integer; MaxVal: single): TfiChannel; 
-Create and return a new channel with all objects. MaxVal is the value used to represent active pixels on channel.
-function TaggedToChannel(Depth: integer; MaxVal: single; 
-                         TagIvalue: integer): TfiChannel; 
-Create and return a new channel with all objects with TagI field value equal to value informed at TagIvalue parameter. MaxVal is the value used to represent active pixels on channel.
-procedure DrawObj(Dst: TfiChannel; MaxVal: single; ObjId:integer;
-                  dx: integer=0; dy: integer = 0);
-Draw the object specified at ObjID parameter in existing channel referred by Dst parameter. MaxVal is the value used to represent active pixels on channel. dx and dy is an optional offset to draw the object.
-procedure Draw(Dst: TfiChannel; MaxVal: single; 
-               dx: integer=0; dy: integer = 0);
-Draw all objects in existing channel referred by Dst parameter. MaxVal is the value used to represent active pixels on channel. dx and dy is an optional offset to draw the object.
-
-Properties / Miscellaneous
-function MoveRcObj(Rc: TRunCodeCustom; ObjID: integer): integer;
-Moves the object informed at ObjID parameter from Rc instance to in place instance. If the ID already exists in destination, a new ID will be created. The ID used in destination is returned by method.
-function GetNewID: integer;
-Return the lower unused ID.
- 
-property iSize: TfiSize;
-Return the dimension of original channel that was used to create the run code.
-property OnFreeObject: TOnFreeObjectEvent;
-This event is called when an object is destroyed. It is usually not necessary to capture this event, but if you allocated memory for pointer Ptr (see User data set), this event offer an opportunity to free this memory.
-Example:
-
-
-// Function to provide a criteria to DelByUserTest method
-//
-function SmallArea(rcObj: TRunCodeObjData; 
-                   Param1: single=0; Param2: single=0): boolean;
-begin
-  result:= rcObj.NPix &amp;lt; Param1;
-end;
-
-procedure TForm1.ProcessRunCode;
-var fImg, fOut: TFastImgEx;
-    Rc: TRunCode;
-    bmp: TBitmap;  
-begin
-  […]
-
-  // creates run code from first channel of fImg
-  Rc:= TRunCode.Create(fImg[0]); 
-
-  // Delete all objects with area less than 10
-  Rc.DelByUserTest(SmallArea, 10);
-
-  // Merge the inner objects witch center gravity is close    
-  Rc.MergeInnerObjs(10);
-
-  // Creates a new image to store process result
-  fOut:= Rc.ToImage(fi_8U, 255);
-
-  // Creates a bitmap from Rc
-  bmp := Rc.ToBitmap;
-
-  […]
-
-  Rc.Free;
-end;
-
-
-
- 
-7. [TFastImageEx class]
-TFastImageEx is the main class of package, the image. Its internal structure is quite simple; it’s not much more than a list of channels. It is this structural simplicity that makes it easy to manipulate the image. Well, that and the dozens of methods implemented and planned for the class, though that does not appear in the public part of the class, are there to support three types of channels mixed in the same image. 
-Constructors
-TFastImageEx can be instantiated in several ways: 9 constructors so far. At the moment, there is no way to load or write image on disk, but is provided full support to TBitmap. It is possible to construct an image from and transfer the result to a TBitmap. 
-TBitmap can be read in 1, 8, 24 or 32 bits pixel formats and can be written in 8, 24 or 32 bits pixel formats. Furthermore it is possible to select a rectangle within the TBitmap and/or read the bitmap directly into gray levels.
-List of constructors
-constructor Create(fSize: TfiSize; Depth, nChannels: integer); 
-Empty image constructor. TfiSize is a record with size of image (width and height). All channels are allocated in memory and created using the depth informed. You can add more channels of different types after construction. Is possible create images with 0 channels. It’s useful to create an image whose channels will be added later.
-constructor Create(fi: TFastImageEx); 
-Copy constructor, make a copy of fi.
-constructor Create(fi: TFastImageEx; Rt: TRect); 
-Copy the portion indicated by Rt. All channels of fi are copied with same depth of fi channels. No range check is performed.
-constructor CreateGray(fi: TFastImageEx);
-Construct gray image from color image. Gray image constructors always result in a single channel image. fi must have 8-bit depth in the channels that will be used to calculate the gray levels. If fi have 1 or 2 channels, the first channel is copied to make the new image. If have 3 or more, the first 3 are considered RGB channels (in this order) and used to calculate the gray levels.
-
-constructor Create(ch: TfiChannel); 
-Single channel copy constructor. Create a image with 1 channel.
-
-Bellow the TBitmap constructors. All bitmap constructors create only images with 8 bits depth channels. bmp can have 1, 8, 24 or 32 depth pixel format.
-constructor Create(bmp: TBitmap);
-constructor Create(bmp: TBitmap; Rt: TRect);
-constructor CreateGray(bmp: TBitmap);
-constructor CreateGray(bmp: TBitmap; Rt: TRect); 
-
-Example:
-var 
-  fi, fj: TFastImageEx;
-  bmp: TBitmap;
-begin
-  bmp:= TBitmap.Create;
-  bmp.LoadFromFile(‘image.bmp’);
-  fi:= TFastImageEx.CreateGray(bmp);
-  fj:= TFastImageEx.Create(fi, Rect(100,100,200,200));
-  bmp.Free; 
-  […]
-end;
-Channel’s list
-TFastImgEx have a channel list (based on TList Delphi class) to store the channels of image. All channels references are made throw theirs indexes on list. There is a list of constants with the common values to channel’s index:
-const
-  // Channels/Source channels
-  fi_BIN  = 0;
-  fi_GRAY = 0;
-  fi_RED  = 0;
-  fi_BLUE = 1;
-  fi_GREEN= 2;
-  fi_ALPHA= 3;
-  fi_ALL_CHANNELS= -1;
-Gray and binary images usually have a single channel, so the processes that expect or generate gray or binary images manipulate the first channel (index=0). Color images can have 3 or 4 channels; in this case the first 3 are considered RGB channels (in this order). However, the processes must indicate the source channel using their index.
-You can get a reference to specific channel by Channels property.
-Adding new channels
-Regardless of the number of channels in the image, you can add new channels. The added channels not required to be the same type as the existing channels, but must have the same dimensions. There is two methods to directly add new channels listed below, but is also possible add channels with processes results.
-
-function MakeNewChannel(Depth: integer): integer;
-Create and add a new channel with depth informed. Return the new channel index on list.
-
-function AddChannel(Channel: TfiChannel): integer;
-Add an existing channel at the end of list and return their index. There is no check of channel dimensions, but you will have problems ahead if you try use any process mixing channels with different dimensions.
-Processing the image
-Ok, at the moment there are only few methods to process the images, but the general structure of parameters list of process methods it’s defined, so excuse me for using the term "all" to refer to process methods. And maybe with your help, the list of process methods will grow soon.
-"All" process methods use the following structure:
-
-function NameProcess(ChnSrc, Dst, OperationType: integer; 
-                     Param1, ..., ParamN: single; 
-                     Binary: boolean): pointer;
-
-ChnScr: Is the source channel to process. Can be the index of a specific channel on image, or the const fi_ALL_CHANNELS to indicate all channels on image. 
-
-Dst: Destination of process result. Must be one of constants bellow: 
-fi_NEW_IMAGE: A new image will be created to store the process result. The process method returns a reference to new image. With this constant the new image will be created with same depth of source image. To select other depth, you can use one of constants below to select a specific depth:
-fi_NEW_IMAGE_8B: Create a new image with 8 bits
-fi_NEW_IMAGE_16B: Create a new image with 16 bits
-fi_NEW_IMAGE_32B: Create a new image with 32 bits
-fi_NEW_CHANNEL: A new channel will be created to store the result of process. You can subtract the depth const to specify the depth of new channel (e.g. fi_NEW_CHANNEL-fi_32F). If no depth is specify, the source depth is used. The process method returns a reference to new channel. You also can use one of follow three constants defined to specified new channels. In this case, no subtraction is needed:
-fi_NEW_CHN_8B: Destination is a new channel with 8-bit depth.
-fi_NEW_CHN_16B: Destination is a new channel with 16-bit depth.
-fi_NEW_CHN_32B: Destination is a new channel with 32-bit depth.
-fi_INPLACE_CHN: Use an existing channel on image to store the process results. In this case you can sum the index of channel to fi_INPLACE_CHN constant (e.g. fi_INPLACE_CHN + fi_BLUE). Look the table below for details.
-
-Destination	Source is 1 channel	Source is all channels
-fi_NEW_CHANNEL
-fi_NEW_CHN_8B
-fi_NEW_CHN_16B
-fi_NEW_CHN_32B	A new channel is created to store the results. Method returns a reference to new channel. If the depth is not informed (fi_NEW_CHANNEL) new channel use the source depth, or you can specify the depth with the other constants. The new channel is not added on the source image.	Not allowed
-fi_NEW_IMAGE
-fi_NEW_IMAGE_8B
-fi_NEW_IMAGE_16B
-fi_NEW_IMAGE_32B	A new image with single channel is created to store the result. Method returns a reference to new image. fi_NEW_IMAGE means use the same depth of source, others constants inform the depth of new image.	A new image with same number of channels in source image is created to store the results. All channels are processed and method returns a reference to new image. fi_NEW_IMAGE means use the same depth of source, others constants inform the depth of new image’s channels.
-fi_INPLACE_CHN	An existing channel is used to store the method results, not necessarily the source channel. Sum the index of destination channel to in place constant to indicate were the results will be stored. Method returns a reference to destination channel.	Each channel on image is processed and used to store the method results. The method returns a reference to source image (self).
-Important: Depending of process method some combinations may not be allowed. The process can also add other restrictions, particularly related to the depth of the channels to be processed.
-
-OperationType: most of process methods have variations or different modes to operate. This parameter indicates how the process must work. Eventually, can be omitted if the process has only one operation mode.
-Param1,…,ParamN: List of parameters needed for the process. This list may vary in amount and type of parameters depending of process.
-Binary: Some processes can operate on binary or gray mode, whit different results. This parameter informs how the process must operate. 
- 
-8. Process methods reference
-Here is a complete reference to process methods implemented until now. Well, I can’t imagine how, but if for some reason the process that you need is not here, you can implement and send to me. I'll be pleased to add your implementation in the next release.
-Convert
-function Convert(ChnSrc, Dst, ScalingMode: integer; 
-                 Param1: single=1; Param2: single=0): pointer;
-This is a powerful function that can be used in several ways. Converts one depth channel to another with optional normalization or linear transformation, but can be used to perform transformations in place. ScalingMode can assume one of follow values:
-fi_NO_SCALE: No scaling is done. Conversions from 16 or 32 bits channels to 8 bits channel will be use the absolute value saturated at 255:
-dst(x,y)= Min(255, Abs(Round(src(x,y))))
-Conversions from 32 bits to 16 bits will be saturated at smallint range:
-dst(x,y) = Min(32767, Max(-32768, Round(src(x,y))))
-Param1 and Param2 are ignored.
-fi_SCALE: Param1 and Param2 are used to perform a linear transformation:
-dst(x,y) = src(x,y) * Param1 + Param2
-Results are saturated at destination channel range (if is 8 or 16 bits).
-fi_RANGE_TO_NORMAL: From 8 or 16 bits channels to 32 bits channels only. The source channel range ([0,255] to 8 bits or [-32768, 32767] to 16 bits) are used for mapping values between 0 and 1 on destination channel. Param1 and Param2 are ignored.
-fi_NORMAL_TO_RANGE: From 32 bits channels to 8 or 16 bits channels only. Reverse operation as described above. Param1 and Param2 are ignored.
-fi_PARAMS_TO_NORMAL: Param1 and Param2 are used to maps values between 0 and 1 (Param1 map to 0 and Param2 map to 1), destination channel must be 32 bits.
-fi_NORMAL_TO_PARAMS: Reverse operation as described above. Source channel must be 32 bits and the values on Param1 and Param2 must be in destination channel range.
-fi_MINMAX_TO_RANGE: The minimum and maximum values on source channel are used to map values on destination range channel. At moment, destination must be 8-bits channel. This option is very useful to graphically show 16 and 32 bits channels. Param1 and Param2 are ignored.
-
-The table below resumes the operations allowed with channels combinations:
-Source/Destination	8 bits	16 bits	32 bits
-8 bits	fi_NO_SCALE
-fi_SCALE
-fi_MINMAX_TO_RANGE	fi_NO_SCALE
-fi_SCALE	fi_NO_SCALE
-fi_SCALE
-fi_RANGE_TO_NORMAL
-fi_PARAMS_TO_NORMAL
-16 bits	fi_NO_SCALE
-fi_SCALE
-fi_MINMAX_TO_RANGE	fi_NO_SCALE
-fi_SCALE	fi_NO_SCALE
-fi_SCALE
-fi_RANGE_TO_NORMAL
-fi_PARAMS_TO_NORMAL
-32 bits	fi_NO_SCALE
-fi_SCALE
-fi_NORMAL_TO_RANGE
-fi_NORMAL_TO_PARAMS
-fi_MINMAX_TO_RANGE	fi_NO_SCALE
-fi_SCALE
-fi_NORMAL_TO_RANGE
-fi_NORMAL_TO_PARAMS	fi_NO_SCALE
-fi_SCALE
-fi_PARAMS_TO_NORMAL
-fi_NORMAL_TO_PARAMS
-
-Threshold
-
-function Threshold(ChnSrc, Dst, ThreshType: integer; 
-                   Thresh, MaxVal: single): pointer;
-Fixed threshold. Thresh and MaxVal is single to compatibility, but theirs values must be in the source channel depth range. There are several types of thresholding that the function supports that are determined by ThreshType parameter. This method is inspired on cvThreshold function of OpenCV library and works similarly. MaxValue is the value that be used to represent active pixels.
-
-ThreshType values:
-fi_THRESH_BINARY: 
-dst(x,y)= MaxVal if src(x,y) &amp;gt; Thresh; 0 otherwise
-
-fi_THRESH_BINARY_INV: 
-dst(x,y)= 0 if src(x,y) &amp;gt; Thresh; MaxVal otherwise
-
-
-fi_THRESH_TRUNC: 
-dst(x,y)= Thresh if src(x,y) &amp;gt; Thresh; src(x,y) otherwise
-
-fi_THRESH_TOZERO: 
-dst(x,y)= src(x,y) if src(x,y) &amp;gt; Thresh; 0 otherwise
-
-fi_THRESH_TOZERO_INV: 
-dst(x,y)= 0 if src(x,y) &amp;gt; Thresh; src(x,y) otherwise
-
-BinaryInv
-function BinaryInv(ChnSrc, Dst: integer; 
-                   MaxVal: single): pointer;
-Binary inversion of image. This method considers the image or channel with binary data. In this case, pixels are considered active or inactive depending of their level values. Level equal zero means inactive pixel and any other value means active. MaxVal parameter is used to represent active pixels on destination. The same effect can be obtained with Convert and Threshold methods, but BinaryInv is more efficient and faster.
-
-Mathematical Morphology
-To support operations of mathematical morphology, unit FastImgEx defines the class TfiBinMask to work as a structural element (see chapter 5). At present implementation is only performed with binary structuring elements, but they can also be applied in gray or color images. In the case of color images the operation is performed individually in each color channel.
-Dilate and Erode
-function Dilate(ChnSrc, Dst, Iterations: integer; 
-               bMask: TfiBinMask; Binary: boolean=false): pointer;
-function Erode(ChnSrc, Dst, Iterations: integer; 
-               bMask: TfiBinMask; Binary: boolean=false): pointer;
-Perform morphological dilation/erosion on channel/image. Iterations informs how many times the process will be applied. Mask is the structuring element that will be used (see discussion above). If Mask = nil, a square 3x3 mask will be used. Binary informs if process will be applied in binary mode or gray mode. Gray mode is more generic and works with binary images too, but in binary mode it is possible to make optimizations that make the processing at least three times faster.
-Gray images
-The dilate/erode operations when applied on gray images use structuring elements in gray level as well. In this case, the structuring element values and the values of image pixels are added in pairs keeping the correspondence of position and the result of operation for the pixel being processed is the maximum or minimum of the values obtained, depending on whether the operation is dilation or erosion. Since this implementation only supports binary structural elements, the maximum and minimum are calculated solely on the image pixels, without addition.
-Borders
-It is not very well explained by the definition of mathematical morphology how to treat border pixels when the structuring element is partially outside the image, but this is a problem that any implementation needs to solve. The solution used by this implementation is to consider in the calculation only the points of the structural element that actually are in the image and ignore the others. This solution avoids having to modify the image, adding artificial rows and columns, and allow process, although not exactly, the border pixels. 
-Very important
-Morphological operations, like any operation involving the neighborhood of pixels, do not allow in place processing natively. However, the current implementation allows (or simulated) process in place, but for best performance, does not guarantee that the reference to maps inside the channels used will be maintained, although the references to the channel remain. This means that if you stored a reference to the map on a channel and then made a morphological operation in place with this channel, this reference has become invalid. See the example below:
-
-var
-  fi: TFastImgEx;
-  Mp8: PByteMap;
-begin
-  […]
-  // Mp8 stores a direct reference to map inside the first channel of fi.
-  Mp8:= fi.Map8[fi_BIN]; 
-  […]
-  // in place dilation on first channel of fi
-  fi.Dilate(fi_BIN, fi_INPLACE_CHN+fi_BIN, 3, Mask, true);  
-
-  // Reference stored on Mp8 is invalid now, you need get again
-  Mp8:= fi.Map8[fi_BIN];
-  […]
-end;
-High-level morphological operations
-Erosion and dilation are the basis for a large number of highest level morphological operations. The Open and Close operations are the best known, but there are many others. The method Morphology implements high-level morphological operations based on erosion and dilation operations. 
-
-function Morphology(ChnSrc, Dst, Operation, Iterations: integer; 
-                    Mask: TfiBinMask; Binary: boolean): pointer;
-The Operation parameter can assume the values below. To explanation to other parameters see the Dilate and Erode discussion above.
-
-fi_MPH_OPEN
-Open: dst = Dilate(Erode(src, mask), mask)
-
-fi_MPH_CLOSE
-Close: dst = Erode(Dilate(src, mask), mask)
-
-fi_MPH_GRAD
-Gradient: dst = Dilate(src, mask) – Erode(src, mask)
-
-fi_MPH_TOPHAT
-Top Hat: dst = src – Open(src, mask)
-
-fi_MPH_BLACKHAT
-Black Hat: dst = Close(src, mask) – src
-
-fi_MPH_INBORD
-In Border: dst = src - Erode(src, mask)
-
-fi_MPH_OUTBORD
-Out Border: dst = Dilate(src, mask) – src
-
-Arithmetic operations
-To provide arithmetic operations between images, TFastImageEx implement function Arithmetic. All arithmetic operations require two operands, the first one is a channel in the image that calls the method and the second operand is informed by parameter Operand. At present implementation arithmetic’s operations only can be performed from specific channels, not from entire image. The function returns a reference to destination channel.
-
-function Arithmetic(ChnSrc, Dst, Operation: integer; Operand: TfiChannel; 
-                    Param1: single=1; Param2: single=1): TfiChannel;
-
-ChnSrc:
-The index of the channel to be the first operand. The constant fi_ALL_CHANNELS is not allowed here.
-Dst:
-Destination channel to store the results. Can be a channel on image, the second operand, or a new channel. To specify a channel in image use the constant fi_INPLACE_CHN and add the channel index. To use the second operand to store the result, use the constant fi_OPERAND and to create a new channel use the constant fi_NEW_CHANNEL or one of the constants that specify the depth of new channel: fi_NEW_CHN_8B, fi_NEW_CHN_16B, fi_NEW_CHN_32B.
-Operation:
-There are several operations available. The constants below select witch operation will be executed.
-fi_ARIT_SUM: 
-dst(x,y)= src(x,y) + oper(x,y)
-fi_ARIT_SUB: 
-dst(x,y)= src(x,y) - oper(x,y)
-fi_ARIT_ABSSUB: 
-dst(x,y)= Abs(src(x,y) - oper(x,y))
-fi_ARIT_MULT: 
-dst(x,y)= src(x,y) * oper(x,y)
-fi_ARIT_MAX: 
-dst(x,y)= Max(src(x,y), oper(x,y))
-fi_ARIT_MIN: 
-dst(x,y)= Min(src(x,y), oper(x,y))
-fi_ARIT_AVRG: 
-dst(x,y)= (src(x,y)*Param1 + oper(x,y)*Param2)/(Param1+Param2)
-fi_ARIT_GRAD: 
-dst(x,y)= sqrt(src(x,y)*src(x,y) + oper(x,y)*oper(x,y))
-fi_ARIT_QUADSUM: 
-dst(x,y)= src(x,y)*src(x,y) + oper(x,y)*oper(x,y)
-
-Operand:
-Reference to channel that will be the second operand on operation.
-Param1, Param2:
-Parameters used by operation. Until now, only fi_ARIT_AVRG use these parameters, in other operations they are ignored.
-
-Convolution
-Many common filters in image processing use the convolution of masks over image. To support mask convolutions the package implements method Convolve:
-
-function Convolve(ChnSrc, Dst: integer; gMask: TfiGrayMask): pointer;
-This method performs the convolution of mask informed in parameter. Mask must be grey, binary masks are not allowed. The result of convolution for each pixel is the sum of multiplication of values on mask with pixels on corresponding position and divides by Weight attribute of mask.
-Sobel
-Perform the Sobel algorithm to extract borders of image. The same result can be achieved using the Convolve method with the appropriate masks, but since it is a widely used algorithm, a specific method has created. Sobel algorithm, like many others convolution filters, can produce results out of byte range, including negative values when vertical or horizontal operators are convolved. To avoid data loss, this implementation always use a 32 bits channel as temporary destination and then convert the result to depth of channel informed as final destination.
-
-function Sobel(ChnSrc, Dst, Operation: integer): pointer;
-Operation can be:
-fi_SOBEL_VERT: Vertical operator.
-fi_SOBEL_HOR: Horizontal operator.
-fi_SOBEL_GRAD: Gradient.
- 
-Match
-This function convolves a binary mask over the image and test if every point in mask match with corresponding pixels at position tested. Is a binary operation, a pixel is considered active if their value is different of zero or inactive if their value is zero.
-
-function Match(ChnSrc, Dst, Operation: integer; bMask: TfiBinMask;
-               Param1, Param2: single): pointer; 
-
-Operation can be:
-
-fi_MATCH_VALIFMATCH:
-Destination pixel assume Param1 value if the mask match; no action otherwise. Param2 parameter is ignored.
-
-fi_MATCH_VALNOMATCH:
-Destination pixel assume Param2 value if the mask don’t match; no action otherwise. Param1 parameter is ignored.
-
-fi_MATCH_VALTOBOTH:
-Destination pixel assume Param1 value if the mask match or assume Param2 value if the mask don’t match.
-
-fi_MATCH_STAMP:
-Mask is stamped on destination channel if mask match with pixel on source channel, no action otherwise. There is no check, but this operation makes more sense if the destination is different of source. Param1 value is used to represent active pixels on destination and Param2 value to represent inactive pixels.
-
- 
-9. Utilities / Miscellaneous methods
-
-function ImgRect: TRect;
-Return a TRect record with image size.
-
-procedure Assign(fi: TFastImageEx);
-Copy the informed image. The previous channels on image are released.  
-
-procedure FillRow(const Value: single; index: integer; 
-                  Channel:integer= fi_ALL_CHANNELS);
-Fills the row specified by index in one or all channels with informed value. Value must match with channels depth.
-
-procedure FillCol(const Value: single; index: integer; 
-                  Channel:integer= fi_ALL_CHANNELS);
-Fills the column specified by index in one or all channels with informed value. Value must match with channels depth.
-
-procedure FillMap(const Value: single; 
-                  Channel: integer= fi_ALL_CHANNELS);
-Fills one or all channels with informed value. Value must match with channels depth.
-
-procedure FillRect(const Value: single; Rt: TRect; 
-                   Channel: integer= fi_ALL_CHANNELS); 
-Fills the rectangle specified by Rt in one or all channels with the informed value. Value must match with channels depth.
-
- 
-10. [Properties]
-
-property AsBitmap: TBitmap;
-Read/write property. Provide full bitmap support. Reading property, binary or gray images (1 channel) generate an 8 bits bitmaps with gray palette. RGB or RGBA images (3 or 4 channels) generate 24 or 32 bits bitmaps. To write, bitmap can have pixel format with 1, 8, 24 or 32 bits.
-
-property iSize: TfiSize;
-Return the dimensions of image (Width and Height).
-
-property Channels[index:integer]:TfiChannel; default;
-Read only. Return a reference to channel specified by index. TfiChannel is an abstract base class of all channel’s classes, but declares all channel’s methods, so, you don’t need a typecast to use the methods on TfiChannel. However to send a channel to some methods can be necessary a type cast.
-
-property nChannels: integer;
-Read only. Return then number of channels on image channel’s list.
-
-property Map8 [index:integer]: PByteMap;
-property Map16 [index:integer]: PSIntMap;
-property Map32 [index:integer]: PFloatMap;
-Read only. Return a reference to map inside the channel specified by index. You must be sure to use the right map for the type of channel chosen.
-
-Example:
-var 
-  fi: TFastImageEx;
-  map8: PByteMap;
-begin
-  […]
-  if fi.Channels[fi_GRAY] is TfiChannel8U
-  then begin
-    map8:= fi.Map8[fi_GRAY];
-    // now you can use the map to read or write values
-    […]
-  end;
-  […]
-end;
-
-11. [Conclusion]
-
-This is just the beginning of a project that so far has given me great pleasure in developing. I hope you enjoy and be useful. And I also hope that the next release I do not sign alone. With some collaboration this project can grow well. 
-And please forgive my bad English. It’s not my native language.
-By the way, I would really appreciate some feed back, like bug report, suggestions, tips, etc.
-
-Regards,
-
-Francesco Artur Perrotti
&amp;lt;/pre&amp;gt;&lt;/pre&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Perrotti</dc:creator><pubDate>Thu, 02 May 2013 11:59:02 -0000</pubDate><guid>https://sourceforge.net21667ae82f5fa0d9d22bfe1de89ea99ecaa2dbbc</guid></item><item><title>Home modified by Perrotti</title><link>https://sourceforge.net/p/fastimageex/wiki/Home/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v3
+++ v4
@@ -13,65 +13,7 @@
 Be sure that you have the last version before use the classes. The last release can be downloaded at https://sourceforge.net/projects/fastimageex/. 
 It is a project open to collaborations. Implementations of algorithms, optimizations, suggestions, tips or additions are welcome, feel free to collaborate.

-2. [Basic Structures]
-TfiSize
-Simple record to inform the size of two-dimensional structures. When is relevant the classes return this record by property iSize. 
-type
-  TfiSize = record
-    Width, Height: integer;
-  end;
-
-Function fiSize can be used to make a new record:
-function fiSize(Width, Height: integer): TfiSize;
-TFloatPoint
-Record to store a float point.
-type
-  TFloatPoint = record
-    X, Y: single;
-  end;
-
-Function FloatPoint can be used to make a new float point. Function RoundPoint round X and Y values to make a Delphi TPoint record:
-function FloatPoint(const X: single; const Y: single): TFloatPoint;
-function RoundPoint(const fpt: TFloatPoint): TPoint;
-Channel maps
-The channels can be 8, 16 or 32 bits deep. Each channel is stored in a two-dimensional array which is called 'map' by package. A map is actually an array of rows, so you can access the entire map or one row at a time. Below the declarations of the lines and maps to the types of channels supported at this time.
-type
-  // 8 bits map
-  PByteArray = ^TByteArray;
-  TByteArray = array [0..MaxListSize-1] of byte;
-  PByteMap = ^TByteMap;
-  TByteMap = array [0..MaxListSize-1] of PByteArray;
-
-  // 16 bits map
-  PSIntArray = ^TSIntArray;
-  TSIntArray = array [0..MaxListSize-1] of Smallint;
-  PSIntMap = ^TSIntMap;
-  TSIntMap = array [0..MaxListSize-1] of PSIntArray;
-
-  // 32 bits map
-  PFloatArray = ^TFloatArray;
-  TFloatArray = array [0..MaxListSize-1] of single;
-  PFloatMap = ^TFloatMap;
-  TFloatMap = array [0..MaxListSize-1] of PFloatArray;
-
-When is necessary, the constants below are use to inform the channel depth:
-const
-  // Channel's depth
-  fi_U8  = 1;  // unsigned 8 bits (byte)
-  fi_S16 = 2;  // signed 16 bits (smallint)
-  fi_F32 = 3;  // float 32 bits (single)
-Histograms
-The histogram shows the intensities distribution of the image’s pixels, or in the case of channel, components of channel. This implementation only supports histograms for 8-bit channels. Histograms are discrete by nature; it makes no sense to try to produce a histogram of a float channel where each element can have any value. So, unless someone suggests some criteria (and usefulness), histograms for 32-bit channels are not in plans. In 16-bit channels, histograms are theoretically possible, but still need some practical use for them. Suggestions about it are welcome.
-Below the array type defined to histograms:
-type
-  PHistogram = ^THistogram;
-  THistogram = array[0..255] of integer;
-Projections
-Projections are a simple and powerful way to perform morphological analysis on images. A vertical projection is the sum of columns of the channel or region. A horizontal projection is the sum of rows. To store the vertical and horizontal projections this package defines the array type below:  
-type
-  PProjection = ^TProjection;
-  TProjection = array [0..MaxListSize-1] of integer;
-
+2. [[Basic Structures]]
 3. [Channels overview]
 The channels are the core of all processing done on the images in this package. They are part of the images, but also can act as independent entities. All available image processes can be applied to the entire image or a specific channel in the image. In fact, some features are only available (at present) for channels and not for images.
 There is a set of classes to define and manipulate channels. TfiChannel is the abstract base class that defines the main methods and properties of channels. A channel contains a two-dimensional array of the type defined by the depth of channel. The property Map returns a reference to this array. You can also obtain a reference to a single line by the Row property.
&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Perrotti</dc:creator><pubDate>Thu, 02 May 2013 11:53:39 -0000</pubDate><guid>https://sourceforge.net717a27d0d79a8ea5709c843ed2860cc00daa27d9</guid></item><item><title>Home modified by Perrotti</title><link>https://sourceforge.net/p/fastimageex/wiki/Home/</link><description>&lt;div class="markdown_content"&gt;&lt;pre&gt;--- v2
+++ v3
@@ -13,7 +13,7 @@
 Be sure that you have the last version before use the classes. The last release can be downloaded at https://sourceforge.net/projects/fastimageex/. 
 It is a project open to collaborations. Implementations of algorithms, optimizations, suggestions, tips or additions are welcome, feel free to collaborate.

-2. Basic Structures
+2. [Basic Structures]
 TfiSize
 Simple record to inform the size of two-dimensional structures. When is relevant the classes return this record by property iSize. 
 type
@@ -72,7 +72,7 @@
   PProjection = ^TProjection;
   TProjection = array [0..MaxListSize-1] of integer;

-3. Channels overview
+3. [Channels overview]
 The channels are the core of all processing done on the images in this package. They are part of the images, but also can act as independent entities. All available image processes can be applied to the entire image or a specific channel in the image. In fact, some features are only available (at present) for channels and not for images.
 There is a set of classes to define and manipulate channels. TfiChannel is the abstract base class that defines the main methods and properties of channels. A channel contains a two-dimensional array of the type defined by the depth of channel. The property Map returns a reference to this array. You can also obtain a reference to a single line by the Row property.
 Channel classes
@@ -152,7 +152,7 @@
                      Operation, Iterations: integer; 
                      bMask: TfiBinMask; Binary: boolean);

-4. Channel statistics – TStatsChannel class
+4. [Channel statistics] – TStatsChannel class
 Some statistics of channels information are very common and useful in image processing. The TStatsChannel class provides a common set of statistics that can be obtained running the channel once. The channel is scanned at the time that the class is instantiated, so the statistics are always available while the instance exists.
 This class calculates the horizontal and vertical projections, the histogram, and other information. All calculated statistics are available through properties. For the moment, only 8-bits channels can be scanned, but future versions will support 16 and 32 bits channels.
 ROI support
@@ -250,7 +250,7 @@
 Figure 2 - Example of graphs generated by the methods HistToBitmap (right), DrawHzProj (right of image) and DrawVtProj (below image).

-5. Using masks
+5. [Using masks]
 Binary mask - TfiBinMask class
 TfiBinMask have a very simple public interface and provide an easy way to produce binary masks. These masks can be used to define a ROI (Region Of Interest) inside a channel, as structuring elements in morphological operations or to perform match operations.
 Creating binary masks
@@ -420,7 +420,7 @@
 Performs gray dilation at the point indicated. The difference between doing the dilation with gray mask and binary mask is that the result with the mask gray is the maximum value obtained by adding the pixel with the corresponding point of the mask. Using binary mask the result is the maximum value of the pixels covered by mask.

-6. Run Length Encode – TRunCode class
+6. [Run Length Encode] – TRunCode class
 The Run Length Encode is a powerful way to process binary images. It is a very simple algorithm that has been widely used to compress text and images, but later proved to be a very important tool in image processing, especially for binary images. When converting an image to RLE format is easy to detect connected objects in the image and perform a selective processing of each object.
 TRunCode class can convert a binary image to RLE format and provide some features to process the objects. In the process to detect connected objects the class also extracts some characteristics that can be used to analyze objects. More advanced (and useful) characteristics can be calculated after construction.
 Construction
@@ -596,7 +596,7 @@

-7. TFastImageEx class
+7. [TFastImageEx class]
 TFastImageEx is the main class of package, the image. Its internal structure is quite simple; it’s not much more than a list of channels. It is this structural simplicity that makes it easy to manipulate the image. Well, that and the dozens of methods implemented and planned for the class, though that does not appear in the public part of the class, are there to support three types of channels mixed in the same image. 
 Constructors
 TFastImageEx can be instantiated in several ways: 9 constructors so far. At the moment, there is no way to load or write image on disk, but is provided full support to TBitmap. It is possible to construct an image from and transfer the result to a TBitmap. 
@@ -920,7 +920,7 @@
 Fills the rectangle specified by Rt in one or all channels with the informed value. Value must match with channels depth.

-10. Properties
+10. [Properties]

 property AsBitmap: TBitmap;
 Read/write property. Provide full bitmap support. Reading property, binary or gray images (1 channel) generate an 8 bits bitmaps with gray palette. RGB or RGBA images (3 or 4 channels) generate 24 or 32 bits bitmaps. To write, bitmap can have pixel format with 1, 8, 24 or 32 bits.
@@ -954,7 +954,7 @@
   […]
 end;

-11. Conclusion
+11. [Conclusion]

 This is just the beginning of a project that so far has given me great pleasure in developing. I hope you enjoy and be useful. And I also hope that the next release I do not sign alone. With some collaboration this project can grow well. 
 And please forgive my bad English. It’s not my native language.
&lt;/pre&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Perrotti</dc:creator><pubDate>Thu, 02 May 2013 11:47:11 -0000</pubDate><guid>https://sourceforge.neta5acfdd8c3145ccfd20f60041dac5841397ce246</guid></item><item><title>Home modified by Perrotti</title><link>https://sourceforge.net/p/fastimageex/wiki/Home/</link><description>&lt;pre&gt;&amp;lt;pre&amp;gt;--- v1
+++ v2
@@ -6,3 +6,960 @@
 
 [[project_admins]]
 [[download_button]]
+
+
+1. Introduction
+This package defines an image format that was designed to be easily processed and can contain multiple channels. 1, 3 and 4 are common values but any number of channels is possible. This version defines channels with 8, 16 or 32 bits deep and allows mixing different types of channels in same image. Each channel is stored in a map separated from other channels and can be independently processed without requiring any additional manipulation.
+Be sure that you have the last version before use the classes. The last release can be downloaded at https://sourceforge.net/projects/fastimageex/. 
+It is a project open to collaborations. Implementations of algorithms, optimizations, suggestions, tips or additions are welcome, feel free to collaborate.
+
+2. Basic Structures
+TfiSize
+Simple record to inform the size of two-dimensional structures. When is relevant the classes return this record by property iSize. 
+type
+  TfiSize = record
+    Width, Height: integer;
+  end;
+
+Function fiSize can be used to make a new record:
+function fiSize(Width, Height: integer): TfiSize;
+TFloatPoint
+Record to store a float point.
+type
+  TFloatPoint = record
+    X, Y: single;
+  end;
+
+Function FloatPoint can be used to make a new float point. Function RoundPoint round X and Y values to make a Delphi TPoint record:
+function FloatPoint(const X: single; const Y: single): TFloatPoint;
+function RoundPoint(const fpt: TFloatPoint): TPoint;
+Channel maps
+The channels can be 8, 16 or 32 bits deep. Each channel is stored in a two-dimensional array which is called 'map' by package. A map is actually an array of rows, so you can access the entire map or one row at a time. Below the declarations of the lines and maps to the types of channels supported at this time.
+type
+  // 8 bits map
+  PByteArray = ^TByteArray;
+  TByteArray = array [0..MaxListSize-1] of byte;
+  PByteMap = ^TByteMap;
+  TByteMap = array [0..MaxListSize-1] of PByteArray;
+
+  // 16 bits map
+  PSIntArray = ^TSIntArray;
+  TSIntArray = array [0..MaxListSize-1] of Smallint;
+  PSIntMap = ^TSIntMap;
+  TSIntMap = array [0..MaxListSize-1] of PSIntArray;
+
+  // 32 bits map
+  PFloatArray = ^TFloatArray;
+  TFloatArray = array [0..MaxListSize-1] of single;
+  PFloatMap = ^TFloatMap;
+  TFloatMap = array [0..MaxListSize-1] of PFloatArray;
+
+When is necessary, the constants below are use to inform the channel depth:
+const
+  // Channel's depth
+  fi_U8  = 1;  // unsigned 8 bits (byte)
+  fi_S16 = 2;  // signed 16 bits (smallint)
+  fi_F32 = 3;  // float 32 bits (single)
+Histograms
+The histogram shows the intensities distribution of the image’s pixels, or in the case of channel, components of channel. This implementation only supports histograms for 8-bit channels. Histograms are discrete by nature; it makes no sense to try to produce a histogram of a float channel where each element can have any value. So, unless someone suggests some criteria (and usefulness), histograms for 32-bit channels are not in plans. In 16-bit channels, histograms are theoretically possible, but still need some practical use for them. Suggestions about it are welcome.
+Below the array type defined to histograms:
+type
+  PHistogram = ^THistogram;
+  THistogram = array[0..255] of integer;
+Projections
+Projections are a simple and powerful way to perform morphological analysis on images. A vertical projection is the sum of columns of the channel or region. A horizontal projection is the sum of rows. To store the vertical and horizontal projections this package defines the array type below:  
+type
+  PProjection = ^TProjection;
+  TProjection = array [0..MaxListSize-1] of integer;
+
+3. Channels overview
+The channels are the core of all processing done on the images in this package. They are part of the images, but also can act as independent entities. All available image processes can be applied to the entire image or a specific channel in the image. In fact, some features are only available (at present) for channels and not for images.
+There is a set of classes to define and manipulate channels. TfiChannel is the abstract base class that defines the main methods and properties of channels. A channel contains a two-dimensional array of the type defined by the depth of channel. The property Map returns a reference to this array. You can also obtain a reference to a single line by the Row property.
+Channel classes
+TfiChannel8U : 8 bits channel (unsigned)
+TfiChannel16S: 16 bits channel (signed)
+TfiChannel32F: 32 bits channel (float)
+Channel construction
+The channels are designed primarily for use by the main class TFastImageEx, but can be manipulated independently. TFastImageEx can create the channels needed for the images, and eventually also create channels to store processes results. But in some cases can be useful to create channels out of images. So far, there are two ways to directly build channels out of images: the default constructor or copy constructor listed below. 
+constructor Create(fSize: TfiSize);
+Constructs an empty channel with the dimensions indicated by fSize. 
+constructor Create(Channel: TfiChannel); 
+Copy constructor. The parameter Channel must be the same type of class of channel that is being constructed.
+Methods
+procedure Assign(Channel: TfiChannel);
+Copy the channel informed. This procedure can change the channel dimensions to match with channel on parameter. The channel informed must be the same type.
+
+procedure FillRow(index: integer; const value: single); 
+procedure FillCol(index: integer; const value: single); 
+procedure FillMap(const value: single); 
+procedure FillRect(const value; Rt: TRect: single); 
+Fill row, column, entire map or rectangle with the value informed. Value must be in the range type of channel map. FillRect do not perform any range check.
+
+procedure CopyRectTo(RtSrc: TRect; Dest: TfiChannel; 
+                     x: integer=0; y: integer=0); 
+Copy a rectangle to an informed destination channel, starting at (x, y) position. Dest channel must be the same type of source channel. No range check is performed.
+
+procedure MinMaxVals(out MinVal: single; out MaxVal: single); 
+Return then minimum and maximum values on channel.
+Properties
+property Row[index: integer]: PRow;
+property Map: PMap;
+Return a reference to row or map. These properties are overridden to return the appropriate type depending of channel depth.
+
+property Width: integer;
+property Height: integer;
+property Depth: integer;
+property iSize: TfiSize;
+property SizeAsRect: TRect;
+
+Read only properties. Depth returns one of constants listed above on Channel maps topic. iSize return the size of channel and SizeAsRect return a TRect with channel dimensions.
+Binary channels
+For this implementation, is not defined any specific binary channel (1 bit depth), however any of the three defined types can be treated as a binary channel. Some processes only exists or only makes sense if applied to binary data. In this case, the general rule used by the package is considered the zero value as zero (!) and any value other than zero as one. Some other processes can be applied both to binary data and 8 or more bits data. For these processes will need to specify how they should work.
+Channels processes
+Most processes available for the images are actually implemented in channel’s classes. The class that manages the images (TFastImageEx) uses these implementations to provide access to these processes. 
+Use the images to run processes offers more options related to input and output. For example, from an image is possible to create new channels to store the process results, or select all the channels of image as input to process. But the process itself, with all options related to its operation mode, can be accessed directly from a channel. Below, the list of processes available form channels. To complete discussion about the processes and the parameters used, look the related topic on TFastImageEx reference (chapter 8).
+
+Threshold
+procedure Threshold(cDest: TfiChannel; ThreshType: integer;
+                    Thresh, MaxValue: single);
+
+Convert
+procedure Convert(cDest: TfiChannel; ScalingMode: integer; 
+                  Param1: single=0; Param2: single=0); 
+
+BinaryInv
+procedure BinaryInv(cDest: TfiChannel; MaxValue: single);
+
+Arithmetic
+procedure Arithmetic(cOper, cDest: TfiChannel; Operation: integer;
+                     Param1: single=1; Param2: single=1);
+
+Convolution
+procedure Convolve(cDst: TfiChannel; Mask: TfiGrayMask); 
+
+Match
+procedure Match(cDst: TfiChannel; Operation: integer; 
+              Mask: TfiGrayMask; ValIfMatch, ValNoMatch: integer); 
+
+Erode
+procedure Erode(cDst: tfiChannel; Iterations: integer; 
+                bMask: TfiBinMask; Binary: boolean);
+Dilate
+procedure Dilate(cDst: tfiChannel; Iterations: integer; 
+                 bMask: TfiBinMask; Binary: boolean);
+Morphology
+procedure Morphology(cDst: tfiChannel; 
+                     Operation, Iterations: integer; 
+                     bMask: TfiBinMask; Binary: boolean);
+
+4. Channel statistics – TStatsChannel class
+Some statistics of channels information are very common and useful in image processing. The TStatsChannel class provides a common set of statistics that can be obtained running the channel once. The channel is scanned at the time that the class is instantiated, so the statistics are always available while the instance exists.
+This class calculates the horizontal and vertical projections, the histogram, and other information. All calculated statistics are available through properties. For the moment, only 8-bits channels can be scanned, but future versions will support 16 and 32 bits channels.
+ROI support
+The statistics can be calculated from entire map, or only in specific ROI (Region Of Interest). The ROI can be defined by a rectangle (TRect) or by a mask with any shape. For mask details see specific topic ahead.
+Constructors
+To create an instance of TStatsChannel class you can use one of the three constructors listed below.
+1) No ROI, use the entire channel
+constructor Create(Chn: TfiChannel8U; Calcs: TChannelCalcSet; 
+                   Binary: boolean); 
+
+Chn is a reference to channel that will be scanned. At the moment, only 8 bits channels can be used.
+Calcs inform if the histogram and projections must be created. Histograms and projections are arrays and therefore spend memory to be stored. Because they are not always necessary, creating them is optional. The type TChannelCalcSet is defined as follows: 
+type
+  TChannelCalcs = (ccHist, ccVtProj, ccHzProj);
+
+Binary affects how the projections are be calculated. If is true, the channel will be considered a binary channel and the projections will contain the number of active pixels (with value different from zero) in each row or column. If is false, the projections will contain the sum of values in each row or column.
+2) With rectangular ROI
+constructor Create(Chn: TfiChannel8U; Calcs: TChannelCalcSet; 
+                   Binary: boolean; RtROI: TRect); 
+
+RtROI is a rectangle with the region that will be considered to calc the statistics. Projections are being returned with the rectangle dimensions. If the rectangle exceeds the limits of image, it will be clipped. For safety, whenever run the projections, use the HzSize and VtSize properties to get their actual length.
+3) With mask ROI
+constructor Create(Chn: TfiChannel8U; Calcs: TChannelCalcSet; 
+                   Binary: boolean; MaskROI: TfiBinMask; X, Y: integer); 
+MaskROI is the mask that defines the pixels that will be processed. A mask is essentially a list of points, so there is no shape associated. However, the max and min values of coordinates of points in mask are used to calculate an involving rectangle, and the dimensions of this rectangle are used to create the projections. If the rectangle exceeds the limits of image, it will be clipped. Points out image are ignored. X and Y parameters indicate where the base point of mask will be positioned.
+ 
+Properties
+All statistics calculated are available by the properties of class, described below. All properties are read only.
+property ROIrect: TRect;
+Return the involving rectangle of region considered to calculations. If no ROI was defined (constructor 1), region is the entire channel.
+property Width: integer;
+Return the width of region considered to calculations. 
+property Height: integer;
+Return the Height of region considered to calculations. 
+property Histogram: PHistogram;
+Reference to histogram of the region considered to calculations. If the value ccHist was no present in the Calcs parameter, this property returns nil.
+property HzProj: PProjection;
+Reference to horizontal projection of the region considered to calculations. If the value ccHzProj was no present in the Calcs parameter, this property returns nil.
+property HzSize: integer;
+Length of horizontal projection returned by HzProj property. If the value ccHzProj was no present in the Calcs parameter, this property returns zero.
+property HzMax: integer;
+The maximum value on horizontal projection returned by HzProj property. If the value ccHzProj was no present in the Calcs parameter, this property returns zero.
+property VtProj: PProjection;
+Reference to vertical projection of the region considered to calculations. If the value ccVtProj was no present in the Calcs parameter, this property returns nil.
+property VtSize: integer;
+Length of vertical projection returned by VtProj property. If the value ccVtProj was no present in the Calcs parameter, this property returns zero.
+property VtMax: integer;
+The maximum value on vertical projection returned by VtProj property. If the value ccVtProj was no present in the Calcs parameter, this property returns zero.
+property TotalArea: integer;
+Return the total area of region. Area is the number of pixels in the region considered. If region was defined by a rectangle or is the entire channel, area is Width*Height. If region was defined by mask, area is the number of points in the mask.
+property LevelSum: integer;
+Return the sum of values in the region considered.   
+property LevelMax: integer;
+The maximum value found in region.
+property LevelMin: integer;
+The minimum value found in region.
+property ZeroCount: integer;
+The number of pixels with zero value.
+property NonZeroCount: integer;
+The number of pixels with non-zero value.
+property Average: single;
+Average of values in region (LevelSum / TotalArea)
+property Density: single;
+This property makes more sense to binary images. Is the concentration of active pixels in the considered region (NonZeroCount / TotalArea).
+property BinGrav: TFloatPoint;
+Return the gravity center of region considering image as binary. Is an average of X and Y coordinates to all active pixels.
+property GrayGrav: TFloatPoint;
+Return the gravity center of region considering image as gray. Is a weighted average of X and Y coordinates to active pixels. The weight is the gray level of pixel.
+
+Viewing the results
+To view the histogram and projections, TStatsChannel implements the methods below to draw graphics on bitmaps.
+
+function HistToBitmap(bmpHeight: integer; LineWidth: byte; 
+                      Color: TColor): TBitmap;
+Return a bitmap with graphical representation of histogram.
+
+function HzProjToBitmap(bmpWidth: integer; FromLeft: boolean; 
+                        Color: TColor): TBitmap;
+function VtProjToBitmap(bmpHeight: integer; FromTop: boolean; 
+                        Color: TColor): TBitmap;
+Return a bitmap with graphical representation of projection. FromLeft and FromTop inform the origin of graphics. These methods are intended to represent projections of gray images (figure 1).
+
+ 
+Figure 1 - Example of graphs generated by the methods HistToBitmap (top right corner), HzProjToBitmap (right of image) and VtProjToBitmap (below image).
+
+ 
+procedure DrawHzProj(bitmap: TBitmap; LineWidth: integer;   
+                     FromLeft: boolean; Color: TColor);
+procedure DrawVtProj(bitmap: TBitmap; LineWidth: integer; 
+                     FromTop: boolean; Color: TColor);
+
+Draw the projection on bitmap informed. FromLeft and FromTop inform the origin of graphics. These methods are intended to represent projections of color images.
+
+ 
+Figure 2 - Example of graphs generated by the methods HistToBitmap (right), DrawHzProj (right of image) and DrawVtProj (below image).
+
+ 
+5. Using masks
+Binary mask - TfiBinMask class
+TfiBinMask have a very simple public interface and provide an easy way to produce binary masks. These masks can be used to define a ROI (Region Of Interest) inside a channel, as structuring elements in morphological operations or to perform match operations.
+Creating binary masks
+To create masks using TfiBinMask you can define your mask in a string list and call the method MakeFromStrings.  Parameters BaseX and BaseY informs the base point of mask related to string list. Character ‘1’ on string list means object, or active pixel. Character ‘0’ means background, or inactive pixel. Any other character means ‘don’t care’. Don’t use the character ‘0’ to create masks for morphological operations or to define a ROI. This option is only for match operations. See the example below that creates a 5x5 diamond mask. You also can create masks manually, point by point directly adding points with Add method. In this case you must calculate the offset of points related to base point. See the discussion in next topic for more details.
+var
+  mask: TfiBinMask;
+  sts: TStringList;
+  fImg: TFastImageEx;
+begin
+  […]
+  sts:= TStringList.Create;
+  sts.Add(‘  1’);
+  sts.Add(‘ 111’);
+  sts.Add(‘11111’);
+  sts.Add(‘ 111’);
+  sts.Add(‘  1’);
+
+  mask:= TfiBinMask.Create;
+  mask.MakeFromStrings(sts, 2, 2);
+  sts.Free;
+
+  // mask is ready to use now
+  fImg.Dilate(fi_ALL_CHANNELS, fi_INPLACE_CHN, 1, mask, true);
+  mask.Free;
+  […]
+end;
+
+ 
+Public definition of TfiBinMask
+Below, the public methods and properties of TfiBinMask. A mask is basically a list of points in a coordinate system with origin in base point (BaseX and BaseY). So, the points store the offset related to base point. When the points are added, the maximum and minimum values from coordinate’s points are stored. These values are used to calculate the rectangle returned by SizeAsRect property and the dimensions of mask returned by properties Width, Height and iSize. Property Items (default) allow access to point’s list.
+
+type
+TMaskBinPoint = class
+  dx, dy: integer;
+  Value: boolean;
+  constructor Create(adx, ady: integer; aValue: boolean);
+end;
+
+TfiBinMask = class(TList)
+public
+  constructor Create;
+  function Add(Pt: TMaskBinPoint): integer;
+  function Get(index: integer): TMaskBinPoint;
+  procedure AssignChannel(Chn: TfiChannel);
+  procedure ReleaseChannel;
+  function Match(x, y: integer): boolean;
+  function ErodeBin(x,y: integer): single;
+  function ErodeGray(x,y: integer): single;
+  function DilateBin(x,y: integer): single;
+  function DilateGray(x,y: integer): single;  
+  function MakeFromStrings(Sts:TStrings; BaseX, BaseY: integer): boolean;
+  //
+  // properties
+  property Width: integer;
+  property Height: integer;
+  property iSize: TfiSize;
+  property SizeAsRect: TRect;  
+  property Items[index:integer]:TMaskBinPoint; default;
+end; 
+
+Advanced use
+TfiBinMask can be used in basic way to define structuring elements to morphological operations or to define a ROI to statistics calculations. For this is enough creating the mask, passes it in parameters of appropriate methods and then destroy the mask. But is also possible use the mask to perform more advanced functions.
+The mask has an internal mechanism to move through a channel running some predefined operations. Actually, that's how most of morphological functions use the mask. To use this feature, you must first associate the mask with a channel of image. After that, you can call the methods available informing the position on channel were the operations must be performed. All these operations are available from images or channels, and to process an entire channel or all channels on image, is better (and faster) to process from channel or image. But if you need process one or few pixels on channel, you can use this feature directly from mask. See the example below.
+
+var
+  mask: TfiBinMask;
+  sts: TStringList;
+  fImg: TFastImageEx;
+begin
+  […]
+  // Mask to detect top left corners
+  sts:= TStringList.Create;
+  sts.Add(‘000’);
+  sts.Add(‘011’);
+  sts.Add(‘011’);
+
+  mask:= TfiBinMask.Create;
+  mask.MakeFromStrings(sts, 1, 1);
+  sts.Free;
+
+  mask.AssignChannel(fImg[fi_BIN]);
+  if mask.Match(10, 10) then
+  begin
+    // there is a top left corner on (10, 10) position
+    […]
+  end;
+  mask.ReleaseChannel;
+  mask.Free;
+end;
+
+Mask operations
+
+function Match(x, y: integer): boolean;
+Test if every point in mask match with pixels on channel at position informed. Is a binary operation, a pixel is considered active if their value is different of zero or inactive if their value is zero. Return true if each point on mask match with corresponding pixel on image.
+
+function ErodeBin(x,y: integer): single;
+function DilateBin(x,y: integer): single;
+Return the value of binary erosion/dilation on pixel at position informed.
+
+function ErodeGray(x,y: integer): single;
+function DilateGray(x,y: integer): single;  
+Return the value of gray erosion/dilation on pixel at position informed
+Gray mask - TfiGrayMask class
+This class provides a mask with non-binary values. It’s similar with binary mask, but the points can assume any value and mask can have a weight to divide the result. The main purpose of this mask is support filtering operations. To create a gray mask, you also can use a string list with values of points. The values must be separated by spaces and character ‘x’ means ‘don’t care’. The example below creates two masks with Sobel operators:
+var
+  sobHz, sobVt: TfiGrayMask;
+  sts: TStringList;
+  fImg: TFastImageEx;
+begin
+  […]
+  // Sobel vertical operator
+  sts:= TStringList.Create;
+  sts.Add(‘1 x -1’);
+  sts.Add(‘2 x -2’);
+  sts.Add(‘1 x -1’);
+
+  sobVt:= TfiGrayMask.Create;
+  sobVt.MakeFromStrings(sts, 1, 1, 1);
+  sts.Free;
+
+  // Sobel horizontal operator
+  sts:= TStringList.Create;
+  sts.Add(‘ 1  2  1’);
+  sts.Add(‘ x  x  x’);
+  sts.Add(‘-1 -2 -1’);
+
+  sobHz:= TfiGrayMask.Create;
+  sobHz.MakeFromStrings(sts, 1, 1, 1);
+  sts.Free;
+  […]
+end;
+
+Public definition of TfiGrayMask class
+
+type
+
+TMaskGrayPoint = class
+  dx, dy: integer;
+  value: single;
+  constructor Create(adx, ady: integer; aValue: single);
+end;
+
+ 
+TfiGrayMaskCustom = class(TfiBaseMask)
+public
+  constructor Create;
+  function CalcPos(x,y: integer): single;
+  function ErodeGray(x,y: integer): single;
+  function DilateGray(x,y: integer): single;
+  function Add(Pt: TMaskGrayPoint): integer;
+  function Get(index: integer): TMaskGrayPoint;
+  function MakeFromStrings(Sts: TStrings; BaseX, BaseY: integer;
+                           Weight: single = 1): boolean;
+  property Items[index:integer]:TMaskGrayPoint; default;
+end;
+
+Gray mask operations
+The gray mask works in a manner very similar to the binary mask. The main difference is that the image is always seen in gray level, never binary. 
+
+function CalcPos(x,y: integer): single;
+The value of each point on the mask is multiplied by the corresponding pixel in the image and the result of the multiplications are summed and then divided by the weight associated with the mask.
+
+function ErodeGray(x,y: integer): single;
+Performs gray erosion at the point indicated. The difference between doing the erosion with gray mask and binary mask is that the result with the mask gray is the minimum value obtained by subtracting the pixel with the corresponding point of the mask. Using binary mask the result is the minimum value of the pixels covered by mask.
+
+function DilateGray(x,y: integer): single;
+Performs gray dilation at the point indicated. The difference between doing the dilation with gray mask and binary mask is that the result with the mask gray is the maximum value obtained by adding the pixel with the corresponding point of the mask. Using binary mask the result is the maximum value of the pixels covered by mask.
+
+ 
+6. Run Length Encode – TRunCode class
+The Run Length Encode is a powerful way to process binary images. It is a very simple algorithm that has been widely used to compress text and images, but later proved to be a very important tool in image processing, especially for binary images. When converting an image to RLE format is easy to detect connected objects in the image and perform a selective processing of each object.
+TRunCode class can convert a binary image to RLE format and provide some features to process the objects. In the process to detect connected objects the class also extracts some characteristics that can be used to analyze objects. More advanced (and useful) characteristics can be calculated after construction.
+Construction
+All processing required to create the image representation in RLE and to connect the objects in the image is made during the construction of the instance. So, once the instance is created, is ready for use. The only parameter required by the constructor is the channel to be processed. The channel is considered binary. In this implementation, RLE representation of gray images is not supported.
+
+constructor Create(Chn: TfiChannel);
+
+Objects characteristics
+An Object is a connected region of image. To store the object’s data TRunCode uses a list of TRunCodeObj instances. There are two sets of characteristics for objects. The first one is calculated by constructor and is always available. The second set depends of first set calculations and is not available until the method CalcBorderData to be called (see ahead). Below the data available on first set:
+ObjID: integer; 
+Object ID. Each object have an integer number as identifier that don’t change until the object be destroyed. This is not the index of object. Objects are stored in a list and also have an index, but some processes needs sort the objects to be performed and the index can change.
+NPix: integer; 
+Number of active pixels present in object (area).
+ 
+Rt: TRect; 
+Involving rectangle of object.
+AreaRt: integer; 
+Area of involving rectangle.
+Dens: single; 
+Density of active pixels in object (NPix/AreaRt).
+cgx, cgy: single; 
+Gravity center of object. Are a coordinate’s averages of all active pixels in object.
+jRed, jGreen, jBlue: byte; 
+Random color used to represent objects in bitmaps.
+
+User data set
+The data below is also available on objects data, but are not used by classes. They are available for user processes: 
+TagI: int64;
+TagR: extended;
+Flag: boolean;
+Ptr: Pointer;
+Very important: If you allocate memory to Ptr pointer, you need assign a function to OnFreeObject event to free the memory when the object is destroyed.
+
+Border characteristics set
+This set of characteristics is related to borders of object and only is available after the method CalcBorderData to be called. 
+geoX, geoY: single;
+Geometric center of object. Is the average of all pixels detected on border of object. 
+DistAvr: single;
+Average of distances from geometric center to border pixels.
+ 
+DistDev: single;
+Standard deviation of distances from geometric center to border pixels. This value tells about the circularity of the object. The closer a circle is the object, smaller is this value.
+Points: TPointList;
+Ordered list of pixels in border of object based on TList class. The first point is the left top pixel on object and the others points are in clock-wise sequence. Points are instances of TRCPoint class declared as below:
+TCPoint = class
+  x, y: integer;
+  gDist: single;
+  TagI: integer;
+  TagR: single;
+  constructor Create(ax, ay: integer; agDist, agAng: single);    
+  constructor Create(pt: TCPoint); 
+end;
+x and y are the coordinates of border pixel. gDist is the distance of pixel to geometric center (geoX, geoY). TagI and TagR are not used and are available to user processes.
+
+ptNear, ptFar: integer;
+The indexes of nearest and farthest points of border from geometric center. 
+
+Vectors: TPointList;
+After calculate the border points with CalcBorderData method, you can vectorize the border by calling Vectorize method. This method copies the Points list and deletes the collinear points leaving only the points in the extremes of straight segments that surround the object. The maximum error accepted to segments is informed by parameter.
+Processing objects overview
+TRunCode class maintains a list of objects in ObjList field (based on TList class), so you can run the object list to access data objects and perform the process that you need. There is other list (Lines) that actually contain the RLE structure of image, ObjList only reference this structure grouping the RLE items by objects. So, is very important that you don’t delete objects using the Delete method of TList class directly from ObjList, this will cause inconsistencies on structure. To delete objects safely, TRunCode class offers DeleteObj method.
+To run all objects list deleting objects by some criteria, use the method DelByUserTest. This method runs all objects and uses a call back function to decide which object will be deleted. Optionally, you can add a Single type parameters to call back function. See the example ahead.
+The procedure VisitObjects works in similar way, run all objects and send then to call back function, but no action is done with objects. This is useful to analyze objects and/or assign values to user data (TagI, TagR, Flag and Ptr). 
+To get more information about the objects call the method CalcBorderData that provides the list of border pixels and some statistics about. You also can call method Vectorize to get a list of straight segments around the objects.
+After processing, you maybe need return the RLE representation to image format, for that use the function ToImage to generate a new image or ToChannel to create a new channel. MaxVal parameter is the value used to represent active pixels on image or channel. Also you can transfer the RLE to bitmap with function ToBitmap; in this case, each object is painted with a random color. To draw all or one object in existing channel, use the methods Draw and DrawObj.
+
+Methods reference
+Procedure types
+These types are used to call back functions and events.
+
+TOnFreeObjectEvent = procedure (rcObj: TRunCodeObjData) of object;
+
+TrcUserTestFunction = function (rcObj: TRunCodeObjData; 
+                                Param1: single=0; 
+                                Param2: single=0): boolean;
+
+TrcVisitObjectsProc = procedure (rcObj: TRunCodeObjData; 
+                                 Param1: single=0; 
+                                 Param2: single=0);
+
+To process objects
+
+function DelByUserTest(func: TrcUserTestFunction; 
+                     Param1: single=0; Param2: single=0): integer;
+Run all objects and call the function in parameter to decide which object will be deleted. Param1 and Param2 are sent to call back function.
+ 
+procedure VisitObjects(proc: TrcVisitObjectsProc; 
+                       Param1: single=0; Param2: single=0);
+Run all objects runs and sends them to the call back procedure informed in parameter. No action is done with objects.
+
+function MergeObjs(ObjRemain, ObjToMerge: integer): integer;
+Merge two objects. This method don’t change any pixel on image, but change the codes reference of second object to point to first object. The first characteristics set is updated to reflect the total of codes in the new object, but don’t the border data or vectors list. These features don’t support merged objects yet, but this is planned to future releases.
+function MergeInnerObjs(GravCtMaxDist: single): integer;
+This method merges objects whose involving rectangle is contained within the involving rectangle of other object and the distance between theirs gravity centers is less than the value informed in parameter.
+function ObjAtPoint(x, y: integer): integer;
+Return the ID of object at position informed or -1 if the position is background.
+procedure CloseHoles;
+Close the holes of all objects.
+function DeleteObj(ObjID: integer): integer;
+Delete the object informed. This is the only safe way to delete objects. If you use the Delete method derived from TList class, it will cause inconsistencies on run code structure.
+
+Borders
+procedure CalcBorderData;
+Calculate the second set of characteristics based on border points list and generate the border points list of all objects. This feature doesn’t support merged objects in present release.
+procedure Vectorize(MaxError: integer);
+Perform the vectorization of border points list to all objects. This feature is only available after calculation of border points list (CalcBorderData). This method copies the border points list to Vectors field and deletes the collinear points leaving only the points in the extremes of straight segments that surround the object. The maximum error accepted to segments is informed by parameter. 
+ 
+Format conversions
+function ToBitmap: TBitmap;
+Create and return a 24 bits bitmap with all objects. Each object is drawn with a different random color.
+function ToImage(Depth: integer; MaxVal: single): TFastImageEx;
+Create and return a single channel image with all objects. MaxVal is the value used to represent active pixels on image.
+function ToChannel(Depth: integer; MaxVal: single): TfiChannel; 
+Create and return a new channel with all objects. MaxVal is the value used to represent active pixels on channel.
+function TaggedToChannel(Depth: integer; MaxVal: single; 
+                         TagIvalue: integer): TfiChannel; 
+Create and return a new channel with all objects with TagI field value equal to value informed at TagIvalue parameter. MaxVal is the value used to represent active pixels on channel.
+procedure DrawObj(Dst: TfiChannel; MaxVal: single; ObjId:integer;
+                  dx: integer=0; dy: integer = 0);
+Draw the object specified at ObjID parameter in existing channel referred by Dst parameter. MaxVal is the value used to represent active pixels on channel. dx and dy is an optional offset to draw the object.
+procedure Draw(Dst: TfiChannel; MaxVal: single; 
+               dx: integer=0; dy: integer = 0);
+Draw all objects in existing channel referred by Dst parameter. MaxVal is the value used to represent active pixels on channel. dx and dy is an optional offset to draw the object.
+
+Properties / Miscellaneous
+function MoveRcObj(Rc: TRunCodeCustom; ObjID: integer): integer;
+Moves the object informed at ObjID parameter from Rc instance to in place instance. If the ID already exists in destination, a new ID will be created. The ID used in destination is returned by method.
+function GetNewID: integer;
+Return the lower unused ID.
+ 
+property iSize: TfiSize;
+Return the dimension of original channel that was used to create the run code.
+property OnFreeObject: TOnFreeObjectEvent;
+This event is called when an object is destroyed. It is usually not necessary to capture this event, but if you allocated memory for pointer Ptr (see User data set), this event offer an opportunity to free this memory.
+Example:
+
+
+// Function to provide a criteria to DelByUserTest method
+//
+function SmallArea(rcObj: TRunCodeObjData; 
+                   Param1: single=0; Param2: single=0): boolean;
+begin
+  result:= rcObj.NPix &amp;lt; Param1;
+end;
+
+procedure TForm1.ProcessRunCode;
+var fImg, fOut: TFastImgEx;
+    Rc: TRunCode;
+    bmp: TBitmap;  
+begin
+  […]
+
+  // creates run code from first channel of fImg
+  Rc:= TRunCode.Create(fImg[0]); 
+
+  // Delete all objects with area less than 10
+  Rc.DelByUserTest(SmallArea, 10);
+
+  // Merge the inner objects witch center gravity is close    
+  Rc.MergeInnerObjs(10);
+
+  // Creates a new image to store process result
+  fOut:= Rc.ToImage(fi_8U, 255);
+
+  // Creates a bitmap from Rc
+  bmp := Rc.ToBitmap;
+
+  […]
+
+  Rc.Free;
+end;
+
+
+
+ 
+7. TFastImageEx class
+TFastImageEx is the main class of package, the image. Its internal structure is quite simple; it’s not much more than a list of channels. It is this structural simplicity that makes it easy to manipulate the image. Well, that and the dozens of methods implemented and planned for the class, though that does not appear in the public part of the class, are there to support three types of channels mixed in the same image. 
+Constructors
+TFastImageEx can be instantiated in several ways: 9 constructors so far. At the moment, there is no way to load or write image on disk, but is provided full support to TBitmap. It is possible to construct an image from and transfer the result to a TBitmap. 
+TBitmap can be read in 1, 8, 24 or 32 bits pixel formats and can be written in 8, 24 or 32 bits pixel formats. Furthermore it is possible to select a rectangle within the TBitmap and/or read the bitmap directly into gray levels.
+List of constructors
+constructor Create(fSize: TfiSize; Depth, nChannels: integer); 
+Empty image constructor. TfiSize is a record with size of image (width and height). All channels are allocated in memory and created using the depth informed. You can add more channels of different types after construction. Is possible create images with 0 channels. It’s useful to create an image whose channels will be added later.
+constructor Create(fi: TFastImageEx); 
+Copy constructor, make a copy of fi.
+constructor Create(fi: TFastImageEx; Rt: TRect); 
+Copy the portion indicated by Rt. All channels of fi are copied with same depth of fi channels. No range check is performed.
+constructor CreateGray(fi: TFastImageEx);
+Construct gray image from color image. Gray image constructors always result in a single channel image. fi must have 8-bit depth in the channels that will be used to calculate the gray levels. If fi have 1 or 2 channels, the first channel is copied to make the new image. If have 3 or more, the first 3 are considered RGB channels (in this order) and used to calculate the gray levels.
+
+constructor Create(ch: TfiChannel); 
+Single channel copy constructor. Create a image with 1 channel.
+
+Bellow the TBitmap constructors. All bitmap constructors create only images with 8 bits depth channels. bmp can have 1, 8, 24 or 32 depth pixel format.
+constructor Create(bmp: TBitmap);
+constructor Create(bmp: TBitmap; Rt: TRect);
+constructor CreateGray(bmp: TBitmap);
+constructor CreateGray(bmp: TBitmap; Rt: TRect); 
+
+Example:
+var 
+  fi, fj: TFastImageEx;
+  bmp: TBitmap;
+begin
+  bmp:= TBitmap.Create;
+  bmp.LoadFromFile(‘image.bmp’);
+  fi:= TFastImageEx.CreateGray(bmp);
+  fj:= TFastImageEx.Create(fi, Rect(100,100,200,200));
+  bmp.Free; 
+  […]
+end;
+Channel’s list
+TFastImgEx have a channel list (based on TList Delphi class) to store the channels of image. All channels references are made throw theirs indexes on list. There is a list of constants with the common values to channel’s index:
+const
+  // Channels/Source channels
+  fi_BIN  = 0;
+  fi_GRAY = 0;
+  fi_RED  = 0;
+  fi_BLUE = 1;
+  fi_GREEN= 2;
+  fi_ALPHA= 3;
+  fi_ALL_CHANNELS= -1;
+Gray and binary images usually have a single channel, so the processes that expect or generate gray or binary images manipulate the first channel (index=0). Color images can have 3 or 4 channels; in this case the first 3 are considered RGB channels (in this order). However, the processes must indicate the source channel using their index.
+You can get a reference to specific channel by Channels property.
+Adding new channels
+Regardless of the number of channels in the image, you can add new channels. The added channels not required to be the same type as the existing channels, but must have the same dimensions. There is two methods to directly add new channels listed below, but is also possible add channels with processes results.
+
+function MakeNewChannel(Depth: integer): integer;
+Create and add a new channel with depth informed. Return the new channel index on list.
+
+function AddChannel(Channel: TfiChannel): integer;
+Add an existing channel at the end of list and return their index. There is no check of channel dimensions, but you will have problems ahead if you try use any process mixing channels with different dimensions.
+Processing the image
+Ok, at the moment there are only few methods to process the images, but the general structure of parameters list of process methods it’s defined, so excuse me for using the term "all" to refer to process methods. And maybe with your help, the list of process methods will grow soon.
+"All" process methods use the following structure:
+
+function NameProcess(ChnSrc, Dst, OperationType: integer; 
+                     Param1, ..., ParamN: single; 
+                     Binary: boolean): pointer;
+
+ChnScr: Is the source channel to process. Can be the index of a specific channel on image, or the const fi_ALL_CHANNELS to indicate all channels on image. 
+
+Dst: Destination of process result. Must be one of constants bellow: 
+fi_NEW_IMAGE: A new image will be created to store the process result. The process method returns a reference to new image. With this constant the new image will be created with same depth of source image. To select other depth, you can use one of constants below to select a specific depth:
+fi_NEW_IMAGE_8B: Create a new image with 8 bits
+fi_NEW_IMAGE_16B: Create a new image with 16 bits
+fi_NEW_IMAGE_32B: Create a new image with 32 bits
+fi_NEW_CHANNEL: A new channel will be created to store the result of process. You can subtract the depth const to specify the depth of new channel (e.g. fi_NEW_CHANNEL-fi_32F). If no depth is specify, the source depth is used. The process method returns a reference to new channel. You also can use one of follow three constants defined to specified new channels. In this case, no subtraction is needed:
+fi_NEW_CHN_8B: Destination is a new channel with 8-bit depth.
+fi_NEW_CHN_16B: Destination is a new channel with 16-bit depth.
+fi_NEW_CHN_32B: Destination is a new channel with 32-bit depth.
+fi_INPLACE_CHN: Use an existing channel on image to store the process results. In this case you can sum the index of channel to fi_INPLACE_CHN constant (e.g. fi_INPLACE_CHN + fi_BLUE). Look the table below for details.
+
+Destination	Source is 1 channel	Source is all channels
+fi_NEW_CHANNEL
+fi_NEW_CHN_8B
+fi_NEW_CHN_16B
+fi_NEW_CHN_32B	A new channel is created to store the results. Method returns a reference to new channel. If the depth is not informed (fi_NEW_CHANNEL) new channel use the source depth, or you can specify the depth with the other constants. The new channel is not added on the source image.	Not allowed
+fi_NEW_IMAGE
+fi_NEW_IMAGE_8B
+fi_NEW_IMAGE_16B
+fi_NEW_IMAGE_32B	A new image with single channel is created to store the result. Method returns a reference to new image. fi_NEW_IMAGE means use the same depth of source, others constants inform the depth of new image.	A new image with same number of channels in source image is created to store the results. All channels are processed and method returns a reference to new image. fi_NEW_IMAGE means use the same depth of source, others constants inform the depth of new image’s channels.
+fi_INPLACE_CHN	An existing channel is used to store the method results, not necessarily the source channel. Sum the index of destination channel to in place constant to indicate were the results will be stored. Method returns a reference to destination channel.	Each channel on image is processed and used to store the method results. The method returns a reference to source image (self).
+Important: Depending of process method some combinations may not be allowed. The process can also add other restrictions, particularly related to the depth of the channels to be processed.
+
+OperationType: most of process methods have variations or different modes to operate. This parameter indicates how the process must work. Eventually, can be omitted if the process has only one operation mode.
+Param1,…,ParamN: List of parameters needed for the process. This list may vary in amount and type of parameters depending of process.
+Binary: Some processes can operate on binary or gray mode, whit different results. This parameter informs how the process must operate. 
+ 
+8. Process methods reference
+Here is a complete reference to process methods implemented until now. Well, I can’t imagine how, but if for some reason the process that you need is not here, you can implement and send to me. I'll be pleased to add your implementation in the next release.
+Convert
+function Convert(ChnSrc, Dst, ScalingMode: integer; 
+                 Param1: single=1; Param2: single=0): pointer;
+This is a powerful function that can be used in several ways. Converts one depth channel to another with optional normalization or linear transformation, but can be used to perform transformations in place. ScalingMode can assume one of follow values:
+fi_NO_SCALE: No scaling is done. Conversions from 16 or 32 bits channels to 8 bits channel will be use the absolute value saturated at 255:
+dst(x,y)= Min(255, Abs(Round(src(x,y))))
+Conversions from 32 bits to 16 bits will be saturated at smallint range:
+dst(x,y) = Min(32767, Max(-32768, Round(src(x,y))))
+Param1 and Param2 are ignored.
+fi_SCALE: Param1 and Param2 are used to perform a linear transformation:
+dst(x,y) = src(x,y) * Param1 + Param2
+Results are saturated at destination channel range (if is 8 or 16 bits).
+fi_RANGE_TO_NORMAL: From 8 or 16 bits channels to 32 bits channels only. The source channel range ([0,255] to 8 bits or [-32768, 32767] to 16 bits) are used for mapping values between 0 and 1 on destination channel. Param1 and Param2 are ignored.
+fi_NORMAL_TO_RANGE: From 32 bits channels to 8 or 16 bits channels only. Reverse operation as described above. Param1 and Param2 are ignored.
+fi_PARAMS_TO_NORMAL: Param1 and Param2 are used to maps values between 0 and 1 (Param1 map to 0 and Param2 map to 1), destination channel must be 32 bits.
+fi_NORMAL_TO_PARAMS: Reverse operation as described above. Source channel must be 32 bits and the values on Param1 and Param2 must be in destination channel range.
+fi_MINMAX_TO_RANGE: The minimum and maximum values on source channel are used to map values on destination range channel. At moment, destination must be 8-bits channel. This option is very useful to graphically show 16 and 32 bits channels. Param1 and Param2 are ignored.
+
+The table below resumes the operations allowed with channels combinations:
+Source/Destination	8 bits	16 bits	32 bits
+8 bits	fi_NO_SCALE
+fi_SCALE
+fi_MINMAX_TO_RANGE	fi_NO_SCALE
+fi_SCALE	fi_NO_SCALE
+fi_SCALE
+fi_RANGE_TO_NORMAL
+fi_PARAMS_TO_NORMAL
+16 bits	fi_NO_SCALE
+fi_SCALE
+fi_MINMAX_TO_RANGE	fi_NO_SCALE
+fi_SCALE	fi_NO_SCALE
+fi_SCALE
+fi_RANGE_TO_NORMAL
+fi_PARAMS_TO_NORMAL
+32 bits	fi_NO_SCALE
+fi_SCALE
+fi_NORMAL_TO_RANGE
+fi_NORMAL_TO_PARAMS
+fi_MINMAX_TO_RANGE	fi_NO_SCALE
+fi_SCALE
+fi_NORMAL_TO_RANGE
+fi_NORMAL_TO_PARAMS	fi_NO_SCALE
+fi_SCALE
+fi_PARAMS_TO_NORMAL
+fi_NORMAL_TO_PARAMS
+
+Threshold
+
+function Threshold(ChnSrc, Dst, ThreshType: integer; 
+                   Thresh, MaxVal: single): pointer;
+Fixed threshold. Thresh and MaxVal is single to compatibility, but theirs values must be in the source channel depth range. There are several types of thresholding that the function supports that are determined by ThreshType parameter. This method is inspired on cvThreshold function of OpenCV library and works similarly. MaxValue is the value that be used to represent active pixels.
+
+ThreshType values:
+fi_THRESH_BINARY: 
+dst(x,y)= MaxVal if src(x,y) &amp;gt; Thresh; 0 otherwise
+
+fi_THRESH_BINARY_INV: 
+dst(x,y)= 0 if src(x,y) &amp;gt; Thresh; MaxVal otherwise
+
+
+fi_THRESH_TRUNC: 
+dst(x,y)= Thresh if src(x,y) &amp;gt; Thresh; src(x,y) otherwise
+
+fi_THRESH_TOZERO: 
+dst(x,y)= src(x,y) if src(x,y) &amp;gt; Thresh; 0 otherwise
+
+fi_THRESH_TOZERO_INV: 
+dst(x,y)= 0 if src(x,y) &amp;gt; Thresh; src(x,y) otherwise
+
+BinaryInv
+function BinaryInv(ChnSrc, Dst: integer; 
+                   MaxVal: single): pointer;
+Binary inversion of image. This method considers the image or channel with binary data. In this case, pixels are considered active or inactive depending of their level values. Level equal zero means inactive pixel and any other value means active. MaxVal parameter is used to represent active pixels on destination. The same effect can be obtained with Convert and Threshold methods, but BinaryInv is more efficient and faster.
+
+Mathematical Morphology
+To support operations of mathematical morphology, unit FastImgEx defines the class TfiBinMask to work as a structural element (see chapter 5). At present implementation is only performed with binary structuring elements, but they can also be applied in gray or color images. In the case of color images the operation is performed individually in each color channel.
+Dilate and Erode
+function Dilate(ChnSrc, Dst, Iterations: integer; 
+               bMask: TfiBinMask; Binary: boolean=false): pointer;
+function Erode(ChnSrc, Dst, Iterations: integer; 
+               bMask: TfiBinMask; Binary: boolean=false): pointer;
+Perform morphological dilation/erosion on channel/image. Iterations informs how many times the process will be applied. Mask is the structuring element that will be used (see discussion above). If Mask = nil, a square 3x3 mask will be used. Binary informs if process will be applied in binary mode or gray mode. Gray mode is more generic and works with binary images too, but in binary mode it is possible to make optimizations that make the processing at least three times faster.
+Gray images
+The dilate/erode operations when applied on gray images use structuring elements in gray level as well. In this case, the structuring element values and the values of image pixels are added in pairs keeping the correspondence of position and the result of operation for the pixel being processed is the maximum or minimum of the values obtained, depending on whether the operation is dilation or erosion. Since this implementation only supports binary structural elements, the maximum and minimum are calculated solely on the image pixels, without addition.
+Borders
+It is not very well explained by the definition of mathematical morphology how to treat border pixels when the structuring element is partially outside the image, but this is a problem that any implementation needs to solve. The solution used by this implementation is to consider in the calculation only the points of the structural element that actually are in the image and ignore the others. This solution avoids having to modify the image, adding artificial rows and columns, and allow process, although not exactly, the border pixels. 
+Very important
+Morphological operations, like any operation involving the neighborhood of pixels, do not allow in place processing natively. However, the current implementation allows (or simulated) process in place, but for best performance, does not guarantee that the reference to maps inside the channels used will be maintained, although the references to the channel remain. This means that if you stored a reference to the map on a channel and then made a morphological operation in place with this channel, this reference has become invalid. See the example below:
+
+var
+  fi: TFastImgEx;
+  Mp8: PByteMap;
+begin
+  […]
+  // Mp8 stores a direct reference to map inside the first channel of fi.
+  Mp8:= fi.Map8[fi_BIN]; 
+  […]
+  // in place dilation on first channel of fi
+  fi.Dilate(fi_BIN, fi_INPLACE_CHN+fi_BIN, 3, Mask, true);  
+
+  // Reference stored on Mp8 is invalid now, you need get again
+  Mp8:= fi.Map8[fi_BIN];
+  […]
+end;
+High-level morphological operations
+Erosion and dilation are the basis for a large number of highest level morphological operations. The Open and Close operations are the best known, but there are many others. The method Morphology implements high-level morphological operations based on erosion and dilation operations. 
+
+function Morphology(ChnSrc, Dst, Operation, Iterations: integer; 
+                    Mask: TfiBinMask; Binary: boolean): pointer;
+The Operation parameter can assume the values below. To explanation to other parameters see the Dilate and Erode discussion above.
+
+fi_MPH_OPEN
+Open: dst = Dilate(Erode(src, mask), mask)
+
+fi_MPH_CLOSE
+Close: dst = Erode(Dilate(src, mask), mask)
+
+fi_MPH_GRAD
+Gradient: dst = Dilate(src, mask) – Erode(src, mask)
+
+fi_MPH_TOPHAT
+Top Hat: dst = src – Open(src, mask)
+
+fi_MPH_BLACKHAT
+Black Hat: dst = Close(src, mask) – src
+
+fi_MPH_INBORD
+In Border: dst = src - Erode(src, mask)
+
+fi_MPH_OUTBORD
+Out Border: dst = Dilate(src, mask) – src
+
+Arithmetic operations
+To provide arithmetic operations between images, TFastImageEx implement function Arithmetic. All arithmetic operations require two operands, the first one is a channel in the image that calls the method and the second operand is informed by parameter Operand. At present implementation arithmetic’s operations only can be performed from specific channels, not from entire image. The function returns a reference to destination channel.
+
+function Arithmetic(ChnSrc, Dst, Operation: integer; Operand: TfiChannel; 
+                    Param1: single=1; Param2: single=1): TfiChannel;
+
+ChnSrc:
+The index of the channel to be the first operand. The constant fi_ALL_CHANNELS is not allowed here.
+Dst:
+Destination channel to store the results. Can be a channel on image, the second operand, or a new channel. To specify a channel in image use the constant fi_INPLACE_CHN and add the channel index. To use the second operand to store the result, use the constant fi_OPERAND and to create a new channel use the constant fi_NEW_CHANNEL or one of the constants that specify the depth of new channel: fi_NEW_CHN_8B, fi_NEW_CHN_16B, fi_NEW_CHN_32B.
+Operation:
+There are several operations available. The constants below select witch operation will be executed.
+fi_ARIT_SUM: 
+dst(x,y)= src(x,y) + oper(x,y)
+fi_ARIT_SUB: 
+dst(x,y)= src(x,y) - oper(x,y)
+fi_ARIT_ABSSUB: 
+dst(x,y)= Abs(src(x,y) - oper(x,y))
+fi_ARIT_MULT: 
+dst(x,y)= src(x,y) * oper(x,y)
+fi_ARIT_MAX: 
+dst(x,y)= Max(src(x,y), oper(x,y))
+fi_ARIT_MIN: 
+dst(x,y)= Min(src(x,y), oper(x,y))
+fi_ARIT_AVRG: 
+dst(x,y)= (src(x,y)*Param1 + oper(x,y)*Param2)/(Param1+Param2)
+fi_ARIT_GRAD: 
+dst(x,y)= sqrt(src(x,y)*src(x,y) + oper(x,y)*oper(x,y))
+fi_ARIT_QUADSUM: 
+dst(x,y)= src(x,y)*src(x,y) + oper(x,y)*oper(x,y)
+
+Operand:
+Reference to channel that will be the second operand on operation.
+Param1, Param2:
+Parameters used by operation. Until now, only fi_ARIT_AVRG use these parameters, in other operations they are ignored.
+
+Convolution
+Many common filters in image processing use the convolution of masks over image. To support mask convolutions the package implements method Convolve:
+
+function Convolve(ChnSrc, Dst: integer; gMask: TfiGrayMask): pointer;
+This method performs the convolution of mask informed in parameter. Mask must be grey, binary masks are not allowed. The result of convolution for each pixel is the sum of multiplication of values on mask with pixels on corresponding position and divides by Weight attribute of mask.
+Sobel
+Perform the Sobel algorithm to extract borders of image. The same result can be achieved using the Convolve method with the appropriate masks, but since it is a widely used algorithm, a specific method has created. Sobel algorithm, like many others convolution filters, can produce results out of byte range, including negative values when vertical or horizontal operators are convolved. To avoid data loss, this implementation always use a 32 bits channel as temporary destination and then convert the result to depth of channel informed as final destination.
+
+function Sobel(ChnSrc, Dst, Operation: integer): pointer;
+Operation can be:
+fi_SOBEL_VERT: Vertical operator.
+fi_SOBEL_HOR: Horizontal operator.
+fi_SOBEL_GRAD: Gradient.
+ 
+Match
+This function convolves a binary mask over the image and test if every point in mask match with corresponding pixels at position tested. Is a binary operation, a pixel is considered active if their value is different of zero or inactive if their value is zero.
+
+function Match(ChnSrc, Dst, Operation: integer; bMask: TfiBinMask;
+               Param1, Param2: single): pointer; 
+
+Operation can be:
+
+fi_MATCH_VALIFMATCH:
+Destination pixel assume Param1 value if the mask match; no action otherwise. Param2 parameter is ignored.
+
+fi_MATCH_VALNOMATCH:
+Destination pixel assume Param2 value if the mask don’t match; no action otherwise. Param1 parameter is ignored.
+
+fi_MATCH_VALTOBOTH:
+Destination pixel assume Param1 value if the mask match or assume Param2 value if the mask don’t match.
+
+fi_MATCH_STAMP:
+Mask is stamped on destination channel if mask match with pixel on source channel, no action otherwise. There is no check, but this operation makes more sense if the destination is different of source. Param1 value is used to represent active pixels on destination and Param2 value to represent inactive pixels.
+
+ 
+9. Utilities / Miscellaneous methods
+
+function ImgRect: TRect;
+Return a TRect record with image size.
+
+procedure Assign(fi: TFastImageEx);
+Copy the informed image. The previous channels on image are released.  
+
+procedure FillRow(const Value: single; index: integer; 
+                  Channel:integer= fi_ALL_CHANNELS);
+Fills the row specified by index in one or all channels with informed value. Value must match with channels depth.
+
+procedure FillCol(const Value: single; index: integer; 
+                  Channel:integer= fi_ALL_CHANNELS);
+Fills the column specified by index in one or all channels with informed value. Value must match with channels depth.
+
+procedure FillMap(const Value: single; 
+                  Channel: integer= fi_ALL_CHANNELS);
+Fills one or all channels with informed value. Value must match with channels depth.
+
+procedure FillRect(const Value: single; Rt: TRect; 
+                   Channel: integer= fi_ALL_CHANNELS); 
+Fills the rectangle specified by Rt in one or all channels with the informed value. Value must match with channels depth.
+
+ 
+10. Properties
+
+property AsBitmap: TBitmap;
+Read/write property. Provide full bitmap support. Reading property, binary or gray images (1 channel) generate an 8 bits bitmaps with gray palette. RGB or RGBA images (3 or 4 channels) generate 24 or 32 bits bitmaps. To write, bitmap can have pixel format with 1, 8, 24 or 32 bits.
+
+property iSize: TfiSize;
+Return the dimensions of image (Width and Height).
+
+property Channels[index:integer]:TfiChannel; default;
+Read only. Return a reference to channel specified by index. TfiChannel is an abstract base class of all channel’s classes, but declares all channel’s methods, so, you don’t need a typecast to use the methods on TfiChannel. However to send a channel to some methods can be necessary a type cast.
+
+property nChannels: integer;
+Read only. Return then number of channels on image channel’s list.
+
+property Map8 [index:integer]: PByteMap;
+property Map16 [index:integer]: PSIntMap;
+property Map32 [index:integer]: PFloatMap;
+Read only. Return a reference to map inside the channel specified by index. You must be sure to use the right map for the type of channel chosen.
+
+Example:
+var 
+  fi: TFastImageEx;
+  map8: PByteMap;
+begin
+  […]
+  if fi.Channels[fi_GRAY] is TfiChannel8U
+  then begin
+    map8:= fi.Map8[fi_GRAY];
+    // now you can use the map to read or write values
+    […]
+  end;
+  […]
+end;
+
+11. Conclusion
+
+This is just the beginning of a project that so far has given me great pleasure in developing. I hope you enjoy and be useful. And I also hope that the next release I do not sign alone. With some collaboration this project can grow well. 
+And please forgive my bad English. It’s not my native language.
+By the way, I would really appreciate some feed back, like bug report, suggestions, tips, etc.
+
+Regards,
+
+Francesco Artur Perrotti
&amp;lt;/pre&amp;gt;&lt;/pre&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Perrotti</dc:creator><pubDate>Thu, 02 May 2013 11:43:29 -0000</pubDate><guid>https://sourceforge.net36472c19221f4aa492c74348a1273c31b422626e</guid></item></channel></rss>