2. Conventions
Start reading our code and you’ll get the hang of it. For the readability, we apply some conventions detailed in the following sections.
This is open source software. Consider the people who will read your code, and make it look nice for them. It’s sort of like driving a car: Perhaps you love doing donuts when you’re alone, but with passengers the goal is to make the ride as smooth as possible.
2.1. Coding Conventions
2.1.1. General
Indentation is made by using spaces (4 spaces).
ALWAYS put spaces after list items and method parameters (
[1, 2, 3]
, not[1,2,3]
), around operators (x += 1
, notx+=1
), and around hash arrows.The number of characters is limited to 120 per line of code.
For data buffers, explicitly sized types from
stdint.h
should be preferred (for instance,int
is NOT good andint32_t
should be used instead).Please use unsigned integers to store data that cannot take negative values.
Use double precision floating-points numbers ONLY when it is necessary. Most of the time, simple precision floating-points numbers should be enough.
2.1.2. Functions
First parameters parenthesis is put directly after the function name (
motion_compute(int param)
is valid, whilemotion_compute (int param)
is NOT valid).Parameters that are only read in the function have to be post-fixed by the
const
qualifier (ex.:void my_func(const float* read_only_data, float* write_data)
),Braces are directly put after the last parameters parenthesis (see the example below).
void filename_verb(int param, int long_param_name) {
for (int i = 0; i < 12; i++) {
printf("Hello World %d\n", i);
}
}
2.1.3. Structures and Enumerations
Here are some code examples to illustrate the conventions.
typedef struct {
uint32_t attr1_var;
uint32_t attr2_var;
uint32_t* attr3_ptr;
} my_struct_t;
enum color_e { COLOR_MISC = 0,
COLOR_GRAY,
COLOR_GREEN,
COLOR_RED,
COLOR_PURPLE,
COLOR_ORANGE,
COLOR_BLUE,
COLOR_YELLOW,
N_COLORS
};
2.1.4. Conditional Structures and Loops
Here are some code examples to illustrate the conventions.
if (counter < 12 && is_valid) {
// do something
} else {
// do something else
}
switch (value) {
case 1:
// do something
break;
case 2:
// do something
break;
case 3:
// do something
break;
default:
break;
}
for (int i = 0; i < 12; i++) {
// do something
}
while (i < 100) {
// do something
i++;
}
2.1.5. Source Code Auto-format
This project mainly follow LLVM coding conventions. For coding conventions
(except for the naming) the code formatting can be automatized thanks to
the clang-format
parser. At the root of the project a clang-format
configuration file is provided (see the .clang-format
file).
For instance, if you want to auto-format the src/motion.c
file you can run
clang-format
from the project root as follow:
clang-format -i src/motion.c
2.2. Naming Conventions
2.2.1. General
This is an English code (functions/variables/defines/comments/… should be written in English).
The snake case is used, (
my_variable
, notmyVariable
), classes start with an upper case (My_class
, notmy_class
) and variables/methods/functions start with a lower case.
2.2.2. Variables
Global variables are prefixed with
g_
.Parameter variables from the command line are prefixed with
p_
.If a variable contains more that one element, its name should ends with a “s” (ex.:
int values[100]
).Static variables from defines are all uppercase (ex.:
#define MY_STATIC_VAR 12
).Defines that come from the compiler should be prefixed with
FMDT_
.
2.2.3. Functions
Function name starts with the corresponding module name (for instance, if you are in the
motion_compute.c
file and you want to write a function that compute the motion, the function name could bemotion_compute
).Function name should always contains a verb.
void filename_verb(int param, int long_param_name) {
for (int i = 0; i < 12; i++) {
printf("Hello World %d\n", i);
}
}
2.2.4. Structures and Enumerations
Structure name is always post-fixed with
_t
(ex.:my_struct_t
).Enumeration name is always post-fixed with
_e
(ex.:my_enum_e
).Enumeration values are in uppercase and always start with the name of the enumeration (in the following example
COLOR_
). Except for the last value that can be in the formN_*s
.
enum color_e { COLOR_MISC = 0,
COLOR_GRAY,
COLOR_GREEN,
COLOR_RED,
COLOR_PURPLE,
COLOR_ORANGE,
COLOR_BLUE,
COLOR_YELLOW,
N_COLORS
};
2.3. Other Conventions
2.3.1. Images Sizes and Borders
In FMDT the image sizes are given with 4 parameters:
i0
: first height index in the image (included),i1
: last height index in the image (included),j0
: first width index in the image (included),j1
: last width index in the image (included).
Images data can be accessed in 2D: img[id_height][id_width]
.
For instance if the resolution of the image is \(1920 \times 1080\), then
the first pixel can be accessed like this: img[0][0]
and the last one like this: img[1079][1919]
. In the previous example:
i0 = 0
,i1 = 1079
,j0 = 0
,j1 = 1919
.
Here is an example how to loop over an image in FMDT:
for (int i = i0; i <= i1; i++)
for (int j = j0; j <= j1; i++)
printf("Pixel img[%d][%d] has the following val: %d\n",
i, j, img[i][j]);
In FMDT, images are allocated with the NRC library (see
Section 1.4.2). Then images can have borders (= extra columns or
lines). The extra columns or lines on the left or on the top can be accessed
with negatives indexes. The extra columns or lines on the right or on the bottom
can be accessed with higher indexes than i1
and j1
values.
2.3.2. Objects Identifiers
In FMDT there are mainly two different types of object: the RoIs (= CCs) and the tracks. A RoI represents a set of connected pixels at a given time \(t\) while a track represents an object over the time (stars, meteors, noise, …). To distinguish different objects of the same type (RoI or track), FMDT uses unique identifiers. These identifiers are encoded by 32-bit unsigned integers and they start from 1 (and NOT 0). The 0 value is used to recognize uninitialized objects or to mark an object for later deletion.