This is rgbtran.c in view mode; [Download] [Up]
#include "combine.h"
#include "defines.h"
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% R G B T r a n s f o r m I m a g e %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Procedure RGBTransformImage converts the reference image from RGB to
% an alternate colorspace.
%
% The format of the RGBTransformImage routine is:
%
% RGBTransformImage(image,colorspace)
%
% A description of each parameter follows:
%
% o image: The address of a structure of type Image; returned from
% ReadImage.
%
% o colorspace: An unsigned integer value that indicates which colorspace
% to transform the image.
%
%
*/
void RGBTransformImage(image,colorspace)
Image
*image;
unsigned int
colorspace;
{
#define X 0
#define Y (MaxRGB+1)
#define Z (MaxRGB+1)*2
long
tx,
ty,
tz,
*x,
*y,
*z;
register int
blue,
green,
i,
red;
register Runlength
*p;
register unsigned char
*range_limit;
unsigned char
*range_table;
if (colorspace == RGBColorspace)
return;
/*
Allocate the tables.
*/
x=(long *) malloc(3*(MaxRGB+1)*sizeof(long));
y=(long *) malloc(3*(MaxRGB+1)*sizeof(long));
z=(long *) malloc(3*(MaxRGB+1)*sizeof(long));
range_table=(unsigned char *) malloc(3*(MaxRGB+1)*sizeof(unsigned char));
if ((x == (long *) NULL) || (y == (long *) NULL) ||
(z == (long *) NULL) || (range_table == (unsigned char *) NULL))
{
(void) fprintf (stderr,
"Unable to transform color space,Memory allocation failed\n");
return;
}
/*
Pre-compute conversion tables.
*/
for (i=0; i <= MaxRGB; i++)
{
range_table[i]=0;
range_table[i+(MaxRGB+1)]=(unsigned char) i;
range_table[i+(MaxRGB+1)*2]=MaxRGB;
}
range_limit=range_table+(MaxRGB+1);
tx=0;
ty=0;
tz=0;
switch (colorspace)
{
case GRAYColorspace:
{
/*
Initialize GRAY tables:
G = 0.29900*R+0.58700*G+0.11400*B
*/
for (i=0; i <= MaxRGB; i++)
{
x[i+X]=UpShifted(0.29900)*i;
y[i+X]=UpShifted(0.58700)*i;
z[i+X]=UpShifted(0.11400)*i;
x[i+Y]=UpShifted(0.29900)*i;
y[i+Y]=UpShifted(0.58700)*i;
z[i+Y]=UpShifted(0.11400)*i;
x[i+Z]=UpShifted(0.29900)*i;
y[i+Z]=UpShifted(0.58700)*i;
z[i+Z]=UpShifted(0.11400)*i;
}
break;
}
case OHTAColorspace:
{
/*
Initialize OHTA tables:
I1 = 0.33333*R+0.33334*G+0.33333*B
I2 = 0.50000*R+0.00000*G-0.50000*B
I3 =-0.25000*R+0.50000*G-0.25000*B
I and Q, normally -0.5 through 0.5, are normalized to the range 0
through MaxRGB.
*/
ty=UpShifted((MaxRGB+1) >> 1);
tz=UpShifted((MaxRGB+1) >> 1);
for (i=0; i <= MaxRGB; i++)
{
x[i+X]=UpShifted(0.33333)*i;
y[i+X]=UpShifted(0.33334)*i;
z[i+X]=UpShifted(0.33333)*i;
x[i+Y]=UpShifted(0.50000)*i;
y[i+Y]=0;
z[i+Y]=(-UpShifted(0.50000))*i;
x[i+Z]=(-UpShifted(0.25000))*i;
y[i+Z]=UpShifted(0.50000)*i;
z[i+Z]=(-UpShifted(0.25000))*i;
}
break;
}
case YCbCrColorspace:
{
/*
Initialize YCbCr tables:
Y = 0.29900*R+0.58700*G+0.11400*B
Cb= -0.16864*R-0.33126*G+0.50000*B
Cr= 0.50000*R-0.41869*G-0.08131*B
Cb and Cr, normally -0.5 through 0.5, are normalized to the range 0
through MaxRGB.
*/
ty=UpShifted((MaxRGB+1) >> 1);
tz=UpShifted((MaxRGB+1) >> 1);
for (i=0; i <= MaxRGB; i++)
{
x[i+X]=UpShifted(0.29900)*i;
y[i+X]=UpShifted(0.58700)*i;
z[i+X]=UpShifted(0.11400)*i;
x[i+Y]=(-UpShifted(0.16874))*i;
y[i+Y]=(-UpShifted(0.33126))*i;
z[i+Y]=UpShifted(0.50000)*i;
x[i+Z]=UpShifted(0.50000)*i;
y[i+Z]=(-UpShifted(0.41869))*i;
z[i+Z]=(-UpShifted(0.08131))*i;
}
break;
}
case YIQColorspace:
{
/*
Initialize YIQ tables:
Y = 0.29900*R+0.58700*G+0.11400*B
I = 0.59600*R-0.27400*G-0.32200*B
Q = 0.21100*R-0.52300*G+0.31200*B
I and Q, normally -0.5 through 0.5, are normalized to the range 0
through MaxRGB.
*/
ty=UpShifted((MaxRGB+1) >> 1);
tz=UpShifted((MaxRGB+1) >> 1);
for (i=0; i <= MaxRGB; i++)
{
x[i+X]=UpShifted(0.29900)*i;
y[i+X]=UpShifted(0.58700)*i;
z[i+X]=UpShifted(0.11400)*i;
x[i+Y]=UpShifted(0.59600)*i;
y[i+Y]=(-UpShifted(0.27400))*i;
z[i+Y]=(-UpShifted(0.32200))*i;
x[i+Z]=UpShifted(0.21100)*i;
y[i+Z]=(-UpShifted(0.52300))*i;
z[i+Z]=UpShifted(0.31200)*i;
}
break;
}
case YUVColorspace:
default:
{
/*
Initialize YUV tables:
Y = 0.29900*R+0.58700*G+0.11400*B
U = -0.14740*R-0.28950*G+0.43690*B
V = 0.61500*R-0.51500*G-0.10000*B
U and V, normally -0.5 through 0.5, are normalized to the range 0
through MaxRGB.
*/
ty=UpShifted((MaxRGB+1) >> 1);
tz=UpShifted((MaxRGB+1) >> 1);
for (i=0; i <= MaxRGB; i++)
{
x[i+X]=UpShifted(0.29900)*i;
y[i+X]=UpShifted(0.58700)*i;
z[i+X]=UpShifted(0.11400)*i;
x[i+Y]=(-UpShifted(0.14740))*i;
y[i+Y]=(-UpShifted(0.28950))*i;
z[i+Y]=UpShifted(0.43690)*i;
x[i+Z]=UpShifted(0.61500)*i;
y[i+Z]=(-UpShifted(0.51500))*i;
z[i+Z]=(-UpShifted(0.10000))*i;
}
break;
}
case XYZColorspace:
{
/*
Initialize XYZ tables:
X = 0.49000*R+0.31000*G+0.20000*B
Y = 0.17700*R+0.81300*G+0.01100*B
Z = 0.00000*R+0.01000*G+0.99000*B
*/
for (i=0; i <= MaxRGB; i++)
{
x[i+X]=UpShifted(0.49000)*i;
y[i+X]=UpShifted(0.31000)*i;
z[i+X]=UpShifted(0.20000)*i;
x[i+Y]=UpShifted(0.17700)*i;
y[i+Y]=UpShifted(0.81300)*i;
z[i+Y]=UpShifted(0.01100)*i;
x[i+Z]=0;
y[i+Z]=UpShifted(0.01000)*i;
z[i+Z]=UpShifted(0.99000)*i;
}
break;
}
}
/*
Convert from RGB.
*/
switch (image->class)
{
case DirectClass:
{
/*
Convert DirectClass image.
*/
p=image->pixels;
for (i=0; i < image->packets; i++)
{
red=p->red;
green=p->green;
blue=p->blue;
p->red=range_limit[DownShift(x[red+X]+y[green+X]+z[blue+X]+tx)];
p->green=range_limit[DownShift(x[red+Y]+y[green+Y]+z[blue+Y]+ty)];
p->blue=range_limit[DownShift(x[red+Z]+y[green+Z]+z[blue+Z]+tz)];
p++;
}
break;
}
case PseudoClass:
{
/*
Convert PseudoClass image.
*/
for (i=0; i < image->colors; i++)
{
red=image->colormap[i].red;
green=image->colormap[i].green;
blue=image->colormap[i].blue;
image->colormap[i].red=
range_limit[DownShift(x[red+X]+y[green+X]+z[blue+X]+tx)];
image->colormap[i].green=
range_limit[DownShift(x[red+Y]+y[green+Y]+z[blue+Y]+ty)];
image->colormap[i].blue=
range_limit[DownShift(x[red+Z]+y[green+Z]+z[blue+Z]+tz)];
}
SyncImage(image);
break;
}
}
/*
Free allocated memory.
*/
(void) free((char *) range_table);
(void) free((char *) z);
(void) free((char *) y);
(void) free((char *) x);
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.