Thursday, June 28, 2012

Generating Random Numbers in ANSI C

To generate random numbers in ANSI C, you will need to include the standard library header:
#include<stdlib.h>
The ANSI C standard library provides functions for generating random integers. Before generating random numbers, you must make sure that you initialize the random number generator with a random seed. This random seed can be provided by using the current time. This means you will also need to use the ANSI C time operations library:
#include<time.h>
Example:
 time_t seconds;
 int randomNumber = 0;
 double realRandomNumber = 0.0;

 /*Returns the number of seconds since 1 January 1970*/
 time(&seconds);
 /*Initializes the random number generator*/
 srand(seconds);

 /*Generates a random integer between 0 and RAND_MAX*/
 randomNumber = rand();

 /*Generates a random integer between 0 and 255*/
 randomNumber = rand()%255;

 /*Generates a random integer between 127 and 255*/
 randomNumber = rand()%(255-127) + 127;

 /*Generates a random integer between -127 and -255*/
 randomNumber = - (rand()%(255-127) + 127);

 /*Generates a random integer between -127 and 255*/
 randomNumber = rand()%(255+127) - 127;

 /*Generates a random floating point number between 0.0 and 255.0*/
 realRandomNumber = (double)(rand()%2550)/10.0;

 /*Generates a random floating point number between 127.3 and 255.4*/
 realRandomNumber = (double)(rand()%(2554-1273) + 1273)/10.0;

 /*Generates a random floating point number between -127.3 and -255.4*/
 realRandomNumber = - ((double)(rand()%(2554-1273) + 1273)/10.0);

 /*Generates a random floating point number between -127.3 and 255.4*/
 realRandomNumber =  (double)(rand()%(2554+1273) - 1273)/10.0;
Notes:
  • You can obtain real random numbers by transforming the floating point number into a integer (ex: 253.23 -> 25323) and after using int rand(), dividing the result with 10^n (where n represents the number of digits after the decimal point).
  • You can obtain negative numbers (either integer or real) by applying the same rules as for positive and multiplying the result with -1.

Wednesday, June 27, 2012

Rounding Functions in ANSI C

To use rounding functions in ANSI C, you will need to include the mathematics header:
#include<math.h>

The ANSI C mathematical library provides support for rounding (rounding-up, rounding down, rounding to the nearest integer) and truncating real numbers.
Example:
#include<stdio.h>
#include<math.h>

int main(int argc, char** argv)
{
 double nr1 = 3.23;
 double nr2 = 3.53;
 double nr3 = -3.23;
 double nr4 = -3.53;
 double r1=0.0, r2=0.0, r3=0.0, r4=0.0;
 int i1 = 0, i2 = 0, i3 = 0, i4 = 0;

 /*
  * Rounds up the number using the formula
  * r = [x]+1
  * where [x] represents the integer part of x
  */
 r1 = ceil(nr1);
 r2 = ceil(nr2);
 r3 = ceil(nr3);
 r4 = ceil(nr4);
 printf("Ceil  : %.2f->%.2f   %.2f->%.2f   %.2f->%.2f   %.2f->%.2f\n",
   nr1,r1,nr2,r2,nr3,r3,nr4,r4);

 /*
  * Rounds down the number using the formula
  * r = [x] - 1
  * where [x] represents the integer part of x
  */
 r1 = floor(nr1);
 r2 = floor(nr2);
 r3 = floor(nr3);
 r4 = floor(nr4);
 printf("Floor : %.2f->%.2f   %.2f->%.2f   %.2f->%.2f   %.2f->%.2f\n",
   nr1,r1,nr2,r2,nr3,r3,nr4,r4);
 /*
  * Truncates the number using the formula
  * r = [x]
  * where [x] represents the integer part of x
  */
 r1 = trunc(nr1);
 r2 = trunc(nr2);
 r3 = trunc(nr3);
 r4 = trunc(nr4);
 printf("Trunc : %.2f->%.2f   %.2f->%.2f   %.2f->%.2f   %.2f->%.2f\n",
   nr1,r1,nr2,r2,nr3,r3,nr4,r4);

 /*
  * Rounds the number using the formula
  * r = [x+0.5]
  * where [x] represents the integer part of x
  */
 r1 = round(nr1);
 r2 = round(nr2);
 r3 = round(nr3);
 r4 = round(nr4);
 printf("Round : %.2f->%.2f   %.2f->%.2f   %.2f->%.2f   %.2f->%.2f\n",
   nr1,r1,nr2,r2,nr3,r3,nr4,r4);

 /*
  * Rounds the number using the formula
  * r = [x+0.5]
  * where [x] represents the integer part of x
  */
 i1 = rint(nr1);
 i2 = rint(nr2);
 i3 = rint(nr3);
 i4 = rint(nr4);
 printf("Rint  : %.2f->%4d   %.2f->%4d   %.2f->%4d    %.2f->%4d\n",
   nr1,i1,nr2,i2,nr3,i3,nr4,i4);
 return 0;
}
/*
Ceil  : 3.23->4.00   3.53->4.00   -3.23->-3.00   -3.53->-3.00
Floor : 3.23->3.00   3.53->3.00   -3.23->-4.00   -3.53->-4.00
Trunc : 3.23->3.00   3.53->3.00   -3.23->-3.00   -3.53->-3.00
Round : 3.23->3.00   3.53->4.00   -3.23->-3.00   -3.53->-4.00
Rint  : 3.23->   3   3.53->   4   -3.23->  -3    -3.53->  -4
 */
Note:
All compilers compliant with C99 should have functions that allow you to use the float and long double data type in the same way we used double.

All functions that operate with float will have have the same name as their double counterparts plus the -f suffix
Example: float roundf(float arg)

All functions that operate with long double will have have the same name as their double counterparts plus the -l suffix
Example: long double ceill(long double arg)

The function of rint also variants according to the returned type:
Exemple: long lrintf(float arg), long long llrintl(long double arg)

Mathematical notions:

Sunday, June 24, 2012

Error and Gamma Functions in ANSI C

To use error and gamma functions in ANSI C, you will need to include the mathematics header:
#include<math.h>
1.Error Functions
ANSI C mathematical library provides functions for computing the Gauss error function and its complementary.

Example:
 float nrF = 0.32f;
 double nrD = 0.3232;
 long double nrL = 0.323232;
 /*Error function*/
 float eF = erff(nrF);
 double eD = erf(nrD);
 long double eL = erfL(nrL);
 /*Complementary error function*/
 float ceF = erfcf(nrF);
 double ceD = erfc(nrD);
 long double ceL = erfcl(ceL);
2.Gamma Functions
ANSI C mathematical library provides functions for computing gamma function and the natural logarithm of the gamma function. 

Example:
 float nrF = 0.32f;
 double nrD = 0.3232;
 long double nrL = 0.323232;
 /*Gamma function*/
 float eF = tgammaf(nrF);
 double eD = tgamma(nrD);
 long double eL = tgammal(nrL);
 /*Natural logarithm of the gamma function*/
 float ceF = lgammaf(nrF);
 double ceD = lgamma(nrD);
 long double ceL = lgammal(ceL);
Mathematical notions:

Friday, June 22, 2012

Exponential, Logarithmic and Power Functions in ANSI C

To use exponential, logarithmic and power functions in ANSI C, you will need to include the mathematics header:
#include<math.h>
1.Exponential Functions
ANSI C mathematical library provides functions for computing e (Euler's constant) and 2 raised at a given power.

Example
 double n = 3.2;
 /*Computes v1 = e^n*/
 double v1 = exp(n);
 /*Computes v2 = e^n*/
 double v2 = exp2(n);
 /*Computes v3 = (e^n)-1. It provides better precision than
  *exp(m)-1 when the result is close to 0*/
 double v3 = expm1(n);
2.Logarithmic Functions
ANSI C mathematical library provides functions for computing the natural (e), common (10) and base 2 logarithm for a given number.

Example
 double n = 3.2;
 /*Computes the natural logarithm of n*/
 double v1 = log(n);
 /*Computes the common logarithm of n*/
 double v2 = log10(n);
 /*Computes the base 2 logarithm of n*/
 double v3 = log2(n);
 /*Computes the natural algorithm of (1+n).It provides
  *more accurate results than using log(n+1) when n
  *is close to 0*/
 double v3 = log1p(n);
3.Power functions
ANSI C mathematical library provides functions for computing the power, square root, cubic root of a given number and the square root of the sum of the squares of 2 given numbers.

Example
 double n1 = 3.2, n2 = 3.6;
 /*Computes v1 = n1^3*/
 double v1 = pow(n1,3.0);
 /*Computes the square root of n1*/
 double v2 = sqrt(n1);
 /*Computes the cubic root of n1*/
 double v3 = cbrt(n1);
 /*Computes v4 = sqrt(pow(n1,2)+pow(n2,2))*/
 double v4 = hypot(n1,n2);
Note:
All compilers compliant with C99 should have functions that allow you to use the float and long double data type in the same way we used double.

All functions that operate with float will have have the same name as their double counterparts plus the -f suffix
Example: float logf(float arg)

All functions that operate with long double will have have the same name as their double counterparts plus the -l suffix
Example: long double cbrtl(long double n1, long double n2)

Mathematical notions:

Basic Mathematical Functions in ANSI C

To use the basic mathematical functions described below, you will need to include the mathematics header:
#include<math.h>
1.Absolute value of a numeric variable
ANSI C provides a wide range of functions that can be used for obtaining the absolute value of any numeric primitive data type.

Example:
 int iNumber = -200;
 long int liNumber = -200l;
 long long int lliNumber = -200L;
 float fNumber = -200.0f;
 double dNumber = -200.0;
 long double ldNumber = -200.0l;
 
 /*Absolute value of an int*/
 int absiNumber = abs(iNumber);
 /*Absolute value of a long int*/
 long int absliNumber = labs(liNumber);
 /*Absolute value of a long long int*/
 long long int abslliNumber = llabs(lliNumber);
 /*Absolute value of a float*/
 float absfNumber = fabsf(fNumber);
 /*Absolute value of a double*/
 double absdNumber =  fabs(dNumber);
 /*Absolute value of a long double*/
 long double absldNumber = fabsl(ldNumber);
2.Computing the quotient and remainder of a division
ANSI C mathematical library also provides support for finding the quotient and remainder of a integer division.

In ANSI C (and the majority of programming languages) the division of 2 integers by using the divide operator (\) returns only the quotient of the division, while the remainder is lost.

When it comes to floating point numbers, there are available two functions for remainder calculations:
  • double fmod(double x, double y) and its variants for float and long double (fmodf, fmodl) which computes the unsigned remainder of the division x/y.
  • double remainder(double x, double y) and its variants for float and long double (remainderf, remainderl) which computes the signed remainder of the division x/y (the result will be negative if (x/y)>(y/2) 
Example:
#include<math.h>
#include<stdio.h>
#include<stdlib.h>

int main(int argc, char** argv)
{
   int ia = 256, ib = 44;
   long int lia = 2560, lib = 440;
   long long int llia = 256000, llib = 44000;
   float fa = 256.3f, fb = 44.9f;
   double da = 2560.33, db = 440.99;
   long double lda = 25600.333l, ldb = 4400.999l;
   /* Computes the remainder and quotient of 2 int numbers*/
   div_t  ria  = div(ia,ib);
   /* Computes the remainder and quotient of 2 long int numbers*/
   ldiv_t rlia = ldiv(lia,lib);
   /* Computes the remainder and quotient of 2 long long int numbers*/
   lldiv_t rllia = lldiv(llia, llib);
   /* Computes the remainder of floating point numbers using fmod*/
   float fRem = fmodf(fa,fb);
   float dRem = fmod(da,db);
   float ldRem = fmodl(lda,ldb);
   /* Computes the remainder of floating point numbers using remainder*/
   float fRem2 = remainderf(fa,fb);
   float dRem2 = remainder(da,db);
   float ldRem2 = remainderl(lda,ldb);
   /* Prints the results */
   printf("[int] Remainder: %d  Quotient: %d\n",
          ria.rem, ria.quot);
   printf("[long] Remainder: %ld  Quotient: %ld\n",
          rlia.rem, rlia.quot);
   printf("[long long] Remainder: %lld  Quotient: %lld\n",
          rllia.rem, rllia.quot);
   printf("[float] Remainder1: %f Remainder2: %f\n",fRem, fRem2);
   printf("[double] Remainder1: %f Remainder2: %f\n",dRem, dRem2);
   printf("[long double] Remainder1: %lf Remainder2: %lf\n",ldRem, ldRem2);
   return 0;
}
/*Output
[int] Remainder: 36  Quotient: 5
[long] Remainder: 360  Quotient: 5
[long long] Remainder: 36000  Quotient: 5
[float] Remainder1: 31.799980 Remainder2: -13.100021
[double] Remainder1: 355.380005 Remainder2: -85.610001
[long double] Remainder1: 3595.337891 Remainder2: -805.661011
 */
3.Other useful floating-point functions
ANSI C mathematical library also provides a few other floating point functions which may prove very useful when building your applications:
 float fa = 0.3f, fb = 0.5f;
 double da = 0.5, db = 0.6;
 long double la = 0.5l, lb=0.5l;
 /*Returns the smallest of the two parameters*/
 float fmin = fminf(fa,fb);
 double dmin = fmin(da,db);
 long double ldmin = fminl(la,lb);
 /*Returns the largest of the two parameters*/
 float fmax = fmaxf(fa,fb);
 double dmax = fmax(da,db);
 long double lmax = fmaxl(la,lb);
 /*Returns the positive difference between the two parameters
  *If x <= y, the result is always equals to 0, otherwise it is x - y.*/
 float fdist = fdimf(fa,fb);
 double ddist = fdim(da,db);
 long double ldist = fdiml(la,lb);
Mathematical notions:

Trigonometric and Hyperbolic Functions in ANSI C

To use trigonometric and hyperbolic functions in ANSI C, you will need to include the mathematics header:
#include<math.h>
1. Trigonometric Functions
The mathematics header provides support for most trigonometric functions.

The non-inverse trigonometric functions implemented in the mathematics header are: cos, sin and tan. Using these functions you can easily implement cot, sec and csc.

Also, in order to receive the results you want, the value of the angle you send should be specified in radians, not degrees.
Example:
 /*The value of angle in radians*/
 double valInRadians = 3.14/2.0;
 /*sin(val)*/
 double valSin  = sin(valInRadians);
 /*cos(val)*/
 double valCos  = cos(valInRadians);
 /*tan(val)*/
 double valTan  = tan(valInRadians);
 /*ctan(val)*/
 double valCtan = 1/valTan;
 /*sec(val)*/
 double valSec  = 1/valCos;
 /*csc(val)*/
 double valCsc  = 1/valSin;
2. Inverse Trigonometric Functions
The mathematics header also provides support for most inverse trigonometric functions. The same rules apply as in the case of trigonometric functions (the values which are returned are in radians).

Example:
 #define PI 3.1417
 double value  = -0.5;
 double value2 =  0.5;
 /* arcsin(val)
  * val must be in the range [-1, 1]*/
 double valArcsin = asin(value);
 /* arccos(val)
  * val must be in the range [-1, 1]*/
 double valArccos = acos(value);
 /* arctan(val) */
 double valAtan   = atan(value);
 /* arctan(val1, val2) */
 double valAtan2  = atan2(value,value2);
 /* arccot(val) */
 double valArccot = PI/2 - atan(value);
 /* arcsec(val) */
 double valArcsec = acos(1.0/value);
 /* arccsc(val) */
 double valArccsc = asin(1.0/value);
3. Hyperbolic functions
The mathematics header also provides support for most hyperbolic functions. The same rules apply as in the case of trigonometric functions.

Example:
 /*The value of the hyperbolic angle*/
 double value = 0.5;
 /*sinh(val)*/
 double valSinh  = sinh(value);
 /*cosh(val)*/
 double valCosh  = cosh(value);
 /*tanh(val)*/
 double valTanh  = tanh(value);
 /*ctanh(val)*/
 double valCtanh = 1/valTanh;
 /*sech(val)*/
 double valSech  = 1/valCosh;
 /*csch(val)*/
 double valCsch  = 1/valSinh;
4. Inverse Hyperbolic functions
The mathematics header also provides support for most inverse hyperbolic functions. The same rules apply as in the case of trigonometric functions.

Example:
 double value  = -0.5;
 /* arcsinh(val)*/
 double valArcsinh = asinh(value);
 /* arccosh(val) */
 double valArccosh = acosh(value);
 /* arctanh(val) */
 double valAtanh   = atanh(value);
 /* arccoth(val) */
 double valArccoth = atanh(1/value);
 /* arcsech(val) */
 double valArcsech = acosh(1.0/value);
 /* arccsch(val) */
 double valArccsch = asinh(1.0/value);
Note:
All compilers compliant with C99 should have functions that allow you to use the float and long double data type in the same way we used double.

All functions that operate with float will have have the same name as their double counterparts plus the -f suffix
Example: float sinf(float arg), float atanhf(float arg)

All functions that operate with long double will have have the same name as their double counterparts plus the -l suffix
Example: long double sinl(long double arg), long double atanhl(long double arg)

Mathematical notions:

Thursday, June 21, 2012

YUV - RGB Conversion Algorithms in C

In order to understand this article you should probably read this article first:

If you are curious about the theory behind the HSI and RGB color spaces, you can read this articles:

1.RGB to YUV Conversion

This function will create a YUV model from a RGB model. The algorithm behind the conversion is described by the formulas below:
RGB to YUV algorithm
The meaning of the variables:
R,G,B - the components of the RGB model (red, green, blue)
Y,U,V - the components of YIQ model (luma, chrominance components)

The components of the RGB model (r,g,b) and luma should have values in the range [0,1], while the U component should have values in the range [-0.436 ,0.436] and the V component should have values in the range [-0.615, 0.615].


The prototype of the function is:
/* Description:
 *  Creates a YuvColor structure from RGB components
 * Parameters:
 *  r,g,b - the components of an RGB model expressed
 *          as real numbers
 * Returns:
 *  A pointer to the YuvColor is the parameters are
 * correct. Otherwise returns NULL.
 */
YuvColor* Yuv_CreateFromRgbF(double r, double g, double f);
The function can be implemented as:
YuvColor* Yuv_CreateFromRgbF(double r, double g, double b)
{
    YuvColor* color = NULL;
    if (RgbF_IsValid(r, g, b) == true)
    {
        color = Yuv_Create(0.0, 0.0, 0.0);
        color->Y = 0.299 * r + 0.587 * b + 0.114 * b;
        color->U = 0.492 * (b - color->Y);
        color->V = 0.877 * (r - color->Y);
    }
    return color;
}
2.YUV to RGB Conversion
This function will create a RGB model from a YUV model. The algorithm behind the conversion is described by the formulas below:
YUV to RGB algorithm
The meaning of the variables:
R,G,B - the components of the RGB model (red, green, blue)
Y,U,V - the components of YIQ model (luma, chrominance components)

The components of the RGB model (r,g,b) and luma should have values in the range [0,1], while the U component should have values in the range [-0.436 ,0.436] and the V component should have values in the range [-0.615, 0.615].

The prototype of the function is:
/*
 * Description:
 *  Creates a RgbFColor structure from YUV components
 * Parameters:
 *  y,u,v - the components of an YUV model expressed
 *          as real numbers
 * Returns:
 *  A pointer to the RgbFColor is the parameters are
 * correct. Otherwise returns NULL.
 */
RgbFColor* RgbF_CreateFromYuv(double y, double u, double v);
The function can be implemented as:
RgbFColor* RgbF_CreateFromYuv(double y, double u, double v)
{
    RgbFColor *color = NULL;
    if (Yiq_IsValid(y, u, v) == true)
    {
        color = RgbF_Create(0.0, 0.0, 0.0);
        color->R = y + 1.140 * v;
        color->G = y - 0.395 * u - 0.581 * v;
        color->B = y + 2.032 * u;
    }
    return color;
}
3.Exemplu
#include<stdio.h>
#include"colorspace.h"

int main(int argc, char** argv)
{
    YuvColor* yuv = NULL;
    RgbFColor* rgbF = NULL;
    RgbIColor* rgbI = NULL;

    /*YUV to RGB*/
    yuv = Yuv_Create(0.4, 0.1, -0.11);
    rgbF = RgbF_CreateFromYuv(yuv->Y, yuv->U, yuv->V);
    rgbI = RgbI_CreateFromRealForm(rgbF->R, rgbF->G, rgbF->B);
    printf("\nYIQ : %f %f %f", yuv->Y, yuv->U, yuv->V);
    printf("\nRGBf : %f %f %f", rgbF->R, rgbF->G, rgbF->B);
    printf("\nRGBi : %d %d %d", rgbI->R, rgbI->G, rgbI->B);

    /*Frees the resources*/
    free(yuv);
    free(rgbF);
    free(rgbI);

    /*RGB to YUV*/
    rgbI = RgbI_Create(108U, 198U, 78U);
    rgbF = RgbF_CreateFromIntegerForm(rgbI->R, rgbI->G, rgbI->B);
    yuv = Yuv_CreateFromRgbF(rgbF->R, rgbF->G, rgbF->B);
    printf("\nYIQ : %f %f %f", yuv->Y, yuv->U, yuv->V);
    printf("\nRGBf : %f %f %f", rgbF->R, rgbF->G, rgbF->B);
    printf("\nRGBi : %d %d %d", rgbI->R, rgbI->G, rgbI->B);
    return 0;
}
/*
 YIQ : 0.400000 0.100000 -0.110000
 RGBf : 0.274600 0.424410 0.603200
 RGBi : 70 108 154
 YIQ : 0.341059 -0.017307 0.072327
 RGBf : 0.423529 0.776471 0.305882
 RGBi : 108 198 78
 */

Wednesday, June 20, 2012

YIQ - RGB Conversion Algorithms in C

In order to understand this article you should probably read this article first:

If you are curious about the theory behind the HSI and RGB color spaces, you can read this articles:
YIQ color space
RGB color space

1.RGB to YIQ Conversion

This function will create a YIQ model from a RGB model. The algorithm behind the conversion is described by the formulas below:
RGB To YIQ Algorithm
The meaning of the variables:
R,G,B - the components of the RGB model (red, green, blue)
Y,I,Q - the components of YIQ model (luma, in-phase, quadrature)

The components of the RGB model (r,g,b) and luma should have values in the range [0,1], while the the in-phase (I) should have values in the range [-0.5957 ,0.5957] and the quadrature should have values in the range [-0.5226, 0.5226].

The prototype of the function is:
/* Description:
 *  Creates a YiqColor structure from RGB components
 * Parameters:
 *  r,g,b - the components of an RGB model expressed
 *          as real numbers
 * Returns:
 *  A pointer to the YiqColor is the parameters are
 * correct. Otherwise returns NULL.
 */
YiqColor* Yiq_CreateFromRgbF(double r, double g, double b);
The function can be implemented as:
YiqColor* Yiq_CreateFromRgbF(double r, double g, double b)
{
    YiqColor* color = NULL;
    if (RgbF_IsValid(r, g, b) == true)
    {
        color = Yiq_Create(0.0, 0.0, 0.0);
        color->Y = 0.299900 * r + 0.587000 * b + 0.114000 * b;
        color->I = 0.595716 * r - 0.274453 * b - 0.321264 * b;
        color->Q = 0.211456 * r - 0.522591 * b + 0.311350 * b;
    }
    return color;
}
2.YIQ to RGB Conversion
This function will create a RGB model from a YIQ model. The algorithm behind the conversion is described by the formulas below:
YIQ to RGB Algorithm
The meaning of the variables:
R,G,B - the components of the RGB model (red, green, blue)
Y,I,Q - the components of YIQ model (luma, in-phase, quadrature)

The components of the RGB model (r,g,b) and luma should have values in the range [0,1], while the the in-phase (I) should have values in the range [-0.5957 ,0.5957] and the quadrature should have values in the range [-0.5226, 0.5226].

The prototype of the function is:
/*
 * Description:
 *  Creates a RgbFColor structure from YIQ components
 * Parameters:
 *  y,i,q - the components of an YIQ model expressed
 *          as real numbers
 * Returns:
 *  A pointer to the RgbFColor is the parameters are
 * correct. Otherwise returns NULL.
 */
RgbFColor* RgbF_CreateFromYiq(double y, double i, double q);
The function can be implemented as:
RgbFColor* RgbF_CreateFromYiq(double y, double i, double q)
{
    RgbFColor *color = NULL;
    if (Yiq_IsValid(y, i, q) == true)
    {
        color = RgbF_Create(0.0, 0.0, 0.0);
        color->R = y + 0.9563 * i + 0.6210 * q;
        color->G = y - 0.2721 * i - 0.6474 * q;
        color->B = y - 1.1070 * i + 1.7046 * q;
    }
    return color;
}
3.Example
#include<stdio.h>
#include"colorspace.h"

int main(int argc, char** argv)
{
    YiqColor* yiq = NULL;
    RgbFColor* rgbF = NULL;
    RgbIColor* rgbI = NULL;

    /*YIQ to RGB*/
    yiq = Yiq_Create(0.4, 0.1, -0.11);
    rgbF = RgbF_CreateFromYiq(yiq->Y, yiq->I, yiq->Q);
    rgbI = RgbI_CreateFromRealForm(rgbF->R, rgbF->G, rgbF->B);
    printf("\nYIQ : %f %f %f", yiq->Y, yiq->I, yiq->Q);
    printf("\nRGBf : %f %f %f", rgbF->R, rgbF->G, rgbF->B);
    printf("\nRGBi : %d %d %d", rgbI->R, rgbI->G, rgbI->B);

    /*Frees the resources*/
    free(yiq);
    free(rgbF);
    free(rgbI);

    /*RGB to YIQ*/
    rgbI = RgbI_Create(108U, 198U, 78U);
    rgbF = RgbF_CreateFromIntegerForm(rgbI->R, rgbI->G, rgbI->B);
    yiq = Yiq_CreateFromRgbF(rgbF->R, rgbF->G, rgbF->B);
    printf("\nYIQ : %f %f %f", yiq->Y, yiq->I, yiq->Q);
    printf("\nRGBf : %f %f %f", rgbF->R, rgbF->G, rgbF->B);
    printf("\nRGBi : %d %d %d", rgbI->R, rgbI->G, rgbI->B);
    return 0;
}
/*
 YIQ : 0.400000 0.100000 -0.110000
 RGBf : 0.427320 0.444004 0.101794
 RGBi : 109 113 26
 YIQ : 0.341440 0.070084 0.024943
 RGBf : 0.423529 0.776471 0.305882
 RGBi : 108 198 78
 */

Sunday, June 17, 2012

HSV - RGB Conversion Algorithms in C

In order to understand this article you should probably read this article first:

If you are curious about the theory behind the HSV and RGB color spaces, you can read this articles:

1. RGB to HSV Conversion 
This function will create a HSV model from a RGB model. The algorithm behind the conversion is described by the formulas below.
RGB to HSV algorithm
The meaning of the variables:
M - the RGB component with the greatest value
m - the RGB component with the smalles value
c - chroma
r,g,b - the components of the RGB model (red, green, blue)
h,s,v - the components of HSV model (hue, saturation, value)

The components of the RGB model (r,g,b), saturation (s)  and value (v) should have values in the range [0,1], while the hue (h) should have values in the rnage [0,360].

The prototype of the function is:
/* Description:
 *  Creates a HsvColor structure from RGB components
 * Parameters:
 *  r,g,b - the components of an RGB model expressed
 *          as real numbers
 * Returns:
 *  A pointer to the HsvColor is the parameters are
 * correct. Otherwise returns NULL.
 */
HsvColor* Hsv_CreateFromRgbF(double r, double g, double b);
The function can be implemented as:
HsvColor* Hsv_CreateFromRgbF(double r, double g, double b)
{
    double M = 0.0, m = 0.0, c = 0.0;
    HsvColor* color = NULL;
    if (RgbF_IsValid(r, g, b) == true)
    {
        color = Hsv_Create(0.0, 0.0, 0.0);
        M = Double_GetMaximum(r, g, b);
        m = Double_GetMinimum(r, g, b);
        c = M - m;
        color->V = M;
        if (c != 0.0f)
        {
            if (M == r)
            {
                color->H = fmod(((g - b) / c), 6.0);
            }
            else if (M == g)
            {
                color->H = (b - r) / c + 2.0;
            }
            else /*if(M==b)*/
            {
                color->H = (r - g) / c + 4.0;
            }
            color->H *= 60.0;
            color->S = c / color->V;
        }
    }
    return color;
}
2.HSV to RGB Conversion
This function will create a RGB model from a HSV model. The algorithm behind the conversion is described by the formulas below.
HSV to RGB algorithm
The meaning of the variables:
c - chroma
m - the RGB component with the smalles value
x - an intermediate value used for computing the RGB model
r,g,b - the components of the RGB model (red, green, blue)
h,s,v - the components of HSV model (hue, saturation, value)

The components of the RGB model (r,g,b), saturation (s)  and value (v) should have values in the range [0,1], while the hue (h) should have values in the rnage [0,360].


The prototype of the function is:
/*
 * Description:
 *  Creates a RgbFColor structure from HSV components
 * Parameters:
 *  h,s,v - the components of an HSV model expressed
 *          as real numbers
 * Returns:
 *  A pointer to the RgbFColor is the parameters are
 * correct. Otherwise returns NULL.
 */
RgbFColor* RgbF_CreateFromHsv(double h, double s, double v);
The function can be implemented as:
HsvColor* Hsv_CreateFromRgbF(double r, double g, double b)
{
    double M = 0.0, m = 0.0, c = 0.0;
    HsvColor* color = NULL;
    if (RgbF_IsValid(r, g, b) == true)
    {
        color = Hsv_Create(0.0, 0.0, 0.0);
        M = Double_GetMaximum(r, g, b);
        m = Double_GetMinimum(r, g, b);
        c = M - m;
        color->V = M;
        if (c != 0.0f)
        {
            if (M == r)
            {
                color->H = fmod(((g - b) / c), 6.0);
            }
            else if (M == g)
            {
                color->H = (b - r) / c + 2.0;
            }
            else /*if(M==b)*/
            {
                color->H = (r - g) / c + 4.0;
            }
            color->H *= 60.0;
            color->S = c / color->V;
        }
    }
    return color;
}

The function can be implemented as:
RgbFColor* RgbF_CreateFromHsv(double h, double s, double v)
{
    double c = 0.0, m = 0.0, x = 0.0;
    RgbFColor *color = NULL;
    if (Hsv_IsValid(h, s, v) == true)
    {
        c = v * s;
        x = c * (1.0 - fabs(fmod(h / 60.0, 2) - 1.0));
        m = v - c;
        if (h >= 0.0 && h < 60.0)
        {
            color = RgbF_Create(c + m, x + m, m);
        }
        else if (h >= 60.0 && h < 120.0)
        {
            color = RgbF_Create(x + m, c + m, m);
        }
        else if (h >= 120.0 && h < 180.0)
        {
            color = RgbF_Create(m, c + m, x + m);
        }
        else if (h >= 180.0 && h < 240.0)
        {
            color = RgbF_Create(m, x + m, c + m);
        }
        else if (h >= 240.0 && h < 300.0)
        {
            color = RgbF_Create(x + m, m, c + m);
        }
        else if (h >= 300.0 && h < 360.0)
        {
            color = RgbF_Create(c + m, m, x + m);
        }
        else
        {
            color = RgbF_Create(m, m, m);
        }
    }
    return color;
}
3.Example
#include<stdio.h>
#include"colorspace.h"

int main(int argc, char** argv)
{
    HsvColor* hsv = NULL;
    RgbFColor* rgbF = NULL;
    RgbIColor* rgbI = NULL;

    /*HSI to RGB*/
    hsv = Hsv_Create(240.5, 0.316, 0.721);
    rgbF = RgbF_CreateFromHsv(hsv->H, hsv->S, hsv->V);
    rgbI = RgbI_CreateFromRealForm(rgbF->R, rgbF->G, rgbF->B);
    printf("\nHSV : %f %f %f", hsv->H, hsv->S, hsv->V);
    printf("\nRGBf : %f %f %f", rgbF->R, rgbF->G, rgbF->B);
    printf("\nRGBi : %d %d %d", rgbI->R, rgbI->G, rgbI->B);

    /*Frees the resources*/
    free(hsv);
    free(rgbF);
    free(rgbI);

    /*RGB to HSI*/
    rgbI = RgbI_Create(108U, 198U, 78U);
    rgbF = RgbF_CreateFromIntegerForm(rgbI->R, rgbI->G, rgbI->B);
    hsv = Hsv_CreateFromRgbF(rgbF->R, rgbF->G, rgbF->B);
    printf("\nHSV : %f %f %f", hsv->H, hsv->S, hsv->V);
    printf("\nRGBf : %f %f %f", rgbF->R, rgbF->G, rgbF->B);
    printf("\nRGBi : %d %d %d", rgbI->R, rgbI->G, rgbI->B);
    return 0;
}
/*Output:
HSV : 240.500000 0.316000 0.721000
RGBf : 0.495063 0.493164 0.721000
RGBi : 126 126 184
HSV : 105.000000 0.606061 0.776471
RGBf : 0.423529 0.776471 0.305882
RGBi : 108 198 78
 */

HSL - RGB Conversion Algorithms in C

In order to understand this article you should probably read this article first:

If you are curious about the theory behind the HSL and RGB color spaces, you should read this articles:

1.RGB To HSL Conversion
This function will create a HSL model from a RGB model. The algorithm behind the conversion is described by the formulas below.
RGB to HSL algorithm
The meaning of the variables:
M - the RGB component with the greatest value
m - the RGB component with the smalles value
c - chroma
r,g,b - the components of the RGB model (red, green, blue)
h,s,l - the components of HSL model (hue, saturation, lightness)

The components of the RGB model (r,g,b), saturation (s)  and intensity (i) should have values in the range [0,1], while the hue (h) should have values in the rnage [0,360].

The prototype of the function is:
/* Description:
 *  Creates a HslColor structure from RGB components
 * Parameters:
 *  r,g,b - the components of an RGB model expressed
 *          as real numbers
 * Returns:
 *  A pointer to the HslColor is the parameters are
 * correct. Otherwise returns NULL.
 */
HslColor* Hsl_CreateFromRgbF(double r, double g, double b);
The function can be implemented as:
HslColor* Hsl_CreateFromRgbF(double r, double g, double b)
{
    double M = 0.0, m = 0.0, c = 0.0;
    HslColor* color = NULL;
    if (RgbF_IsValid(r, g, b) == true)
    {
        M = Double_GetMaximum(r, g, b);
        m = Double_GetMinimum(r, g, b);
        c = M - m;
        color = Hsl_Create(0.0, 0.0, 0.0);
        color->L = 0.5 * (M + m);
        if (c != 0.0)
        {
            if (M == r)
            {
                color->H = fmod(((g - b) / c), 6.0);
            }
            else if (M == g)
            {
                color->H = ((b - r) / c) + 2.0;
            }
            else/*if(M==b)*/
            {
                color->H = ((r - g) / c) + 4.0;
            }
            color->H *= 60.0;
            color->S = c / (1.0 - fabs(2.0 * color->L - 1.0));
        }
    }
    return color;
}
2.HSL to RGB Conversion
This function will create a RGB model from an HSL model. The algorithm behind the conversion is described by the formulas below.
HSL to RGB algorithm
The meaning of the variables:
c - chroma
x - intermediate value used for computing r,g,b
m - intermediate value used for creating the r,g,b baseline
r,g,b - the components of the RGB model (red, green, blue)
h,s,l - the components of HSL model (hue, saturation, lightness)

The components of the RGB model (r,g,b), saturation (s)  and intensity (i) should have values in the range [0,1], while the hue (h) should have values in the rnage [0,360].

The prototype of the function is:
/*
 * Description:
 *  Creates a RgbFColor structure from HSL components
 * Parameters:
 *  h,s,l - the components of an HSL model expressed
 *          as real numbers
 * Returns:
 *  A pointer to the RgbFColor is the parameters are
 * correct. Otherwise returns NULL.
 */
RgbFColor* RgbF_CreateFromHsl(double h, double s, double l);
The function can be implemented as:
RgbFColor* RgbF_CreateFromHsl(double h, double s, double l)
{
    RgbFColor* color = NULL;
    double c = 0.0, m = 0.0, x = 0.0;
    if (Hsl_IsValid(h, s, l) == true)
    {
        c = (1.0 - fabs(2 * l - 1.0)) * s;
        m = 1.0 * (l - 0.5 * c);
        x = c * (1.0 - fabs(fmod(h / 60.0, 2) - 1.0));
        if (h >= 0.0 && h < (HUE_UPPER_LIMIT / 6.0))
        {
            color = RgbF_Create(c + m, x + m, m);
        }
        else if (h >= (HUE_UPPER_LIMIT / 6.0) && h < (HUE_UPPER_LIMIT / 3.0))
        {
            color = RgbF_Create(x + m, c + m, m);
        }
        else if (h < (HUE_UPPER_LIMIT / 3.0) && h < (HUE_UPPER_LIMIT / 2.0))
        {
            color = RgbF_Create(m, c + m, x + m);
        }
        else if (h >= (HUE_UPPER_LIMIT / 2.0)
                && h < (2.0f * HUE_UPPER_LIMIT / 3.0))
        {
            color = RgbF_Create(m, x + m, c + m);
        }
        else if (h >= (2.0 * HUE_UPPER_LIMIT / 3.0)
                && h < (5.0 * HUE_UPPER_LIMIT / 6.0))
        {
            color = RgbF_Create(x + m, m, c + m);
        }
        else if (h >= (5.0 * HUE_UPPER_LIMIT / 6.0) && h < HUE_UPPER_LIMIT)
        {
            color = RgbF_Create(c + m, m, x + m);
        }
        else
        {
            color = RgbF_Create(m, m, m);
        }
    }
    return color;
}
3.Example
#include<stdio.h>
#include"colorspace.h"

int main(int argc, char** argv)
{
    HslColor* hsl = NULL;
    RgbFColor* rgbF = NULL;
    RgbIColor* rgbI = NULL;

    /*HSI to RGB*/
    hsl = Hsl_Create(84.0, 1.0, 0.4);
    rgbF = RgbF_CreateFromHsl(hsl->H, hsl->S, hsl->L);
    rgbI = RgbI_CreateFromRealForm(rgbF->R, rgbF->G, rgbF->B);
    printf("\nHSL : %f %f %f", hsl->H, hsl->S, hsl->L);
    printf("\nRGBf : %f %f %f", rgbF->R, rgbF->G, rgbF->B);
    printf("\nRGBi : %d %d %d", rgbI->R, rgbI->G, rgbI->B);

    /*Frees the resources*/
    free(hsl);
    free(rgbF);
    free(rgbI);

    /*RGB to HSI*/
    rgbI = RgbI_Create(108U, 198U, 78U);
    rgbF = RgbF_CreateFromIntegerForm(rgbI->R, rgbI->G, rgbI->B);
    hsl = Hsl_CreateFromRgbF(rgbF->R, rgbF->G, rgbF->B);
    printf("\nHSL : %f %f %f", hsl->H, hsl->S, hsl->L);
    printf("\nRGBf : %f %f %f", rgbF->R, rgbF->G, rgbF->B);
    printf("\nRGBi : %d %d %d", rgbI->R, rgbI->G, rgbI->B);
    return 0;
}
/*
HSL : 84.000000 1.000000 0.400000
RGBf : 0.480000 0.800000 0.000000
RGBi : 122 204 0
HSL : 105.000000 0.512821 0.541176
RGBf : 0.423529 0.776471 0.305882
RGBi : 108 198 78
 */

Tuesday, June 12, 2012

Measuring the Execution Time of an Algorithm in ANSI C

The only system-independent way to measure the execution time of a algorithm is by using the ANSI library time.h
#include<time.h>
To actually obtain the execution time, you must measure the the time when the algorithm starts and the time when the algorithm stops. The difference between these values will provide the execution time of the algorithm.
Execution time formula
dt - the execution time of the algorithm
tf - the time value measured when the algorithm stops
ts - the time value measured when the algorithm starts
The times tf and ts will be measured using the clock_t clock() function (who will return the number of ticks since the program was started). Since the difference will be in ticks, you must divide the result with the constant CLOCKS_PER_SEC in order to get the result in seconds. 
#include<stdio.h>
#include<time.h>

int main(void)
{
   clock_t startTime, endTime;
   /*Measures ts*/
   startTime = clock();
   /*Insert your algorithm here
    *
    *
    *
    *
   */
   /*Measures tf*/
   endTime = clock();
   /*Calculates and prints the time in ticks*/
   printf("Time in ticks: %ld",(endTime-startTime));
   /*Calculates and prints the time in seconds*/
   printf(" %f",(double)(endTime-startTime)/CLOCKS_PER_SEC);
   return 0;
}

Friday, June 1, 2012

Radix Conversion Applet

This simple applet allows you to convert between any radices (bases) ranging from 2 to 36.
How to use:
Input a number in the Number textbox, the radix of that number in Old radix textbox and the radix you wish the number to be converted in the New radix textbox. Click convert to obtain the result.

Useful links
Radix Conversion Methods in Java
Radix Conversion Algorithms in C

Download:
Applet JAR archive
Source
Related Posts Plugin for WordPress, Blogger...