Chapter 2. Digital Media Data Conversion Examples

This chapter contains sample applications that demonstrate how to use the digital media converters.

Color Conversion

Example 2-1 contains a listing of lator.c, a “color calculator” application that demonstrates how to use the Color Space Library.

Example 2-1. Color Calculator: lator.c


/*
 * lator.h
 */
void lator_red(char *);
void lator_green(char *);
void lator_blue(char *);
void lator_gofigure(char **, char **, char **,
        char **, char **, char **, 
        char **, char **, char **, 
        char **, char **, char **,
        char **, char **);
/*
 * lator.c 
 */
#include <stdio.h>
#include <stdlib.h>
#include <bstring.h>

#include "lator.h"

static void rgb_rgbprime(char *rgbx, char *rgbx_prime);
static void rgb_ycrcb(char *rgbx, char *ycrcb);
/*
static void ycc601toyccjfif(char *ycc601, char *yccjfif);
*/
void matmul(float a[3], float m[3][3], float b[3]);
static void rgb_xyz(char *rgbx, float xyz[3]);
static void xyz_xy(float xyz[3], float xy[2]);

#define    CLAMP0(v)    (v < 0 ? 0 : (v > 255 ? 255 : v))

/* byte offset of each component in DM_IMAGE_PACKING_RGBX */
#define    RED    0
#define    GREEN    1
#define    BLUE    2
static char rgbx[4];

/* byte offset of each component in DM_IMAGE_PACKING_CbYCr */
#define    Cb    0
#define    Y    1
#define    Cr    2

/* normalized primary matrix for XYZ = NPM * RGB, SMPTE RP 176-1993 */
#define NPM_X_R                         0.4123907993
#define NPM_X_G                         0.3575843394
#define NPM_X_B                         0.1804807884

#define NPM_Y_R                         0.2126390059
#define NPM_Y_G                         0.7151686788
#define NPM_Y_B                         0.0721923154

#define NPM_Z_R                         0.0193308187
#define NPM_Z_G                         0.1191947798
#define NPM_Z_B                         0.9505321522

float npm[3][3] =
{
{ NPM_X_R, NPM_X_G, NPM_X_B },
{ NPM_Y_R, NPM_Y_G, NPM_Y_B },
{ NPM_Z_R, NPM_Z_G, NPM_Z_B },
};
static void
fill(char color[4], char *picture, int npixels)
{
    int *p = (int *)picture;

    while (npixels--) {
        *p++ = *(int *)color;
    }
}

void
lator_red(char *r)
{
    int v = atoi(r);
    rgbx[RED] = CLAMP0(v);
}

void
lator_green(char *g)
{
    int v = atoi(g);
    rgbx[GREEN] = CLAMP0(v);
}

void
lator_blue(char *b)
{
    int v = atoi(b);
    rgbx[BLUE] = CLAMP0(v);
}

static char redstr[8];
static char greenstr[8];
static char bluestr[8];
static char rpstr[8];
static char gpstr[8];
static char bpstr[8];
static char ystr[8];
static char crstr[8];
static char cbstr[8];
static char bigx_str[8];
static char bigy_str[8];
static char bigz_str[8];
static char litx_str[8];
static char lity_str[8];
void
lator_gofigure(    char **r, char **g, char **b,
        char **rp, char **gp, char **bp,
        char **y, char **cr, char **cb,
        char **bigx, char **bigy, char **bigz,
        char **litx, char **lity)
{
    char rgbxp[4], ycrcb[4];
    float xyz[3], xy[2];

    bzero(rgbxp, 4);
    bzero(ycrcb, 4);
    bzero(xyz, 3);
    rgb_rgbprime(rgbx, rgbxp);
    rgb_ycrcb(rgbxp, ycrcb);
    rgb_xyz(rgbx, xyz);
    xyz_xy(xyz, xy);

    sprintf(redstr,   "%3d", rgbx[RED]);        *r = redstr;
    sprintf(greenstr, "%3d", rgbx[GREEN]);        *g = greenstr;
    sprintf(bluestr,  "%3d", rgbx[BLUE]);        *b = bluestr;

    sprintf(rpstr, "%3d", rgbxp[RED]);        *rp = rpstr;
    sprintf(gpstr, "%3d", rgbxp[GREEN]);        *gp = gpstr;
    sprintf(bpstr, "%3d", rgbxp[BLUE]);        *bp = bpstr;

    sprintf(ystr, "%3d", ycrcb[Y]);            *y = ystr;
    sprintf(crstr, "%3d", ycrcb[Cr]);        *cr = crstr;
    sprintf(cbstr, "%3d", ycrcb[Cb]);        *cb = cbstr;

    sprintf(bigx_str, "%.3f", xyz[0]);        *bigx = bigx_str;
    sprintf(bigy_str, "%.3f", xyz[1]);        *bigy = bigy_str;
    sprintf(bigz_str, "%.3f", xyz[2]);        *bigz = bigz_str;

    sprintf(litx_str, "%.3f", xy[0]);        *litx = litx_str;
    sprintf(lity_str, "%.3f", xy[1]);        *lity = lity_str;
}

#include <dmedia/dm_params.h>
#include <dmedia/dm_image.h>
#include <dmedia/dm_color.h>
static void
rgb_rgbprime(char *rgbx, char *rgbx_prime)
{
    DMcolorconverter cvt;
    DMparams *p, *pc;

    dmColorCreate(&cvt);

    dmParamsCreate(&p);
    dmSetImageDefaults(p, 1, 1, DM_IMAGE_PACKING_RGBX);
    dmColorSetSrcParams(cvt, p);

    dmParamsCreate(&pc);
    dmParamsSetFloat(pc, DM_IMAGE_GAMMA, .45);
    dmParamsSetParams(p, DM_IMAGE_COMPONENT_ALL, pc);
    dmColorSetDstParams(cvt, p);

    dmParamsDestroy(p);
    dmParamsDestroy(pc);

    if (dmColorConvert(cvt, rgbx, rgbx_prime)) {
        printf("dmcolor error, rgb -> r'g'b'\n");
    }
    dmColorDestroy(cvt);
}

static void
rgb_ycrcb(char *rgbx, char *ycrcb)
{
    DMcolorconverter cvt;
    DMparams *p;

    dmColorCreate(&cvt);

    dmParamsCreate(&p);
    dmSetImageDefaults(p, 1, 1, DM_IMAGE_PACKING_RGBX);
    dmColorSetSrcParams(cvt, p);
    dmParamsDestroy(p);

    dmParamsCreate(&p);
    dmSetImageDefaults(p, 1, 1, DM_IMAGE_PACKING_CbYCr);
    dmColorSetDstParams(cvt, p);
    dmParamsDestroy(p);
    if (dmColorConvert(cvt, rgbx, ycrcb)) {
        printf("dmcolor error, rgb -> ycrcb\n");
    }
    dmColorDestroy(cvt);
}


static void
rgb_xyz(char *rgbx, float *xyz)
{
    float f_rgbx[3];

    f_rgbx[0] = rgbx[RED]/255.;
    f_rgbx[1] = rgbx[GREEN]/255.;
    f_rgbx[2] = rgbx[BLUE]/255.;

    matmul(xyz, npm, f_rgbx);
}

static void
xyz_xy(float xyz[3], float xy[2])
{
    float sum = xyz[0] + xyz[1] + xyz[2];

    xy[0] = xyz[0]/sum;
    xy[1] = xyz[1]/sum;
}

static void
matmul(float a[3], float m[3][3], float b[3])
{
        a[0] = m[0][0] * b[0] + m[0][1] * b[1] + m[0][2] * b[2];
        a[1] = m[1][0] * b[0] + m[1][1] * b[1] + m[1][2] * b[2];
        a[2] = m[2][0] * b[0] + m[2][1] * b[1] + m[2][2] * b[2];
}