home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Photo CD Demo 1
/
Demo.bin
/
fbm
/
src
/
flclr.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-06-24
|
8KB
|
309 lines
/*****************************************************************
* flclr.c: FBM Release 1.0 25-Feb-90 Michael Mauldin
*
* Copyright (C) 1989,1990 by Michael Mauldin. Permission is granted
* to use this file in whole or in part for any purpose, educational,
* recreational or commercial, provided that this copyright notice
* is retained unchanged. This software is available to all free of
* charge by anonymous FTP and in the UUNET archives.
*
* flclr.c: Color <--> BW, (Mapped Color | BW) --> unmapped color
*
* CONTENTS
* clr2gray (input, output, rw, gw, bw)
* gray2clr (input, output, sun)
*
* EDITLOG
* LastEditDate = Mon Jun 25 00:05:04 1990 - Michael Mauldin
* LastFileName = /usr2/mlm/src/misc/fbm/flclr.c
*
* HISTORY
* 25-Jun-90 Michael Mauldin (mlm@cs.cmu.edu) Carnegie Mellon
* Package for Release 1.0
*
* 07-Mar-89 Michael Mauldin (mlm) at Carnegie Mellon University
* Beta release (version 0.9) mlm@cs.cmu.edu
*
* 28-Nov-88 Michael Mauldin (mlm) at Carnegie-Mellon University
* Created.
*****************************************************************/
# include <stdio.h>
# include "fbm.h"
/****************************************************************
* clr2gray: Apply a triplet of weights to each color in and RGB
* or mapped image and produce an 8bit grayscale image
****************************************************************/
#ifndef lint
static char *fbmid =
"$FBM flclr.c <1.0> 25-Jun-90 (C) 1989,1990 by Michael Mauldin, source \
code available free from MLM@CS.CMU.EDU and from UUNET archives$";
#endif
clr2gray (input, output, rw, gw, bw)
FBM *input, *output;
int rw, gw, bw;
{ int rw1, gw1, bw1, width, height, clrlen, rowlen, colors;
register int i, j;
register unsigned char *bmp, *obm;
/* Already monochrome? */
if (input->hdr.planes == 1 && input->hdr.clrlen == 0)
{ *output = *input; return (1); }
/* Invalid raster type */
if (input->hdr.planes != 3 && input->hdr.clrlen == 0)
{ fprintf (stderr,
"clr2gray was passed invalid raster type, clrlen %d, planes %d\n",
input->hdr.clrlen, input->hdr.planes);
return (0);
}
/* Adjust weights for fast division via shift */
rw1 = rw * 256 / (rw + gw + bw);
gw1 = gw * 256 / (rw + gw + bw);
bw1 = 256 - (rw1+gw1);
fprintf (stderr, "Using weights [%2d %2d %2d] ==> <%3d, %3d, %3d>\n",
rw, gw, bw, rw1, gw1, bw1);
/* Allocate output bitmap */
output->hdr = input->hdr;
output->hdr.clrlen = 0;
output->hdr.planes = 1;
output->hdr.bits = output->hdr.physbits = 8;
alloc_fbm (output);
/* Set commonly used vars */
width = input->hdr.cols;
height = input->hdr.rows;
rowlen = input->hdr.rowlen;
clrlen = input->hdr.clrlen;
colors = clrlen / 3;
/* Mapped color to gray scale */
if (input->hdr.clrlen > 0)
{ register int *gray;
gray = (int *) malloc ((unsigned) input->hdr.clrlen * sizeof (int));
for (i=0; i<colors; i++)
{ gray[i] = (rw1 * input->cm[i] +
gw1 * input->cm[i+colors] +
bw1 * input->cm[i+(colors<<1)]) >> 8;
# ifdef DEBUG
fprintf (stderr, "color %3d: [%3d %3d %3d] => %3d\n",
i,
input->cm[i],
input->cm[i+colors],
input->cm[i+colors*2],
gray[i]);
# endif
}
for (j=0; j<height; j++)
{ bmp = &(input->bm[j*rowlen]);
obm = &(output->bm[j*rowlen]);
for (i=0; i<width; i++)
{ *obm++ = gray[*bmp++]; }
}
}
/* RGB color to gray scale */
else if (input->hdr.planes == 3 && input->hdr.physbits == 8)
{ register unsigned char *rp, *gp, *bp;
for (j=0; j<height; j++)
{ rp = &(input->bm[j*rowlen]);
gp = rp + input->hdr.plnlen;
bp = gp + input->hdr.plnlen;
obm = (&output->bm[j*rowlen]);
for (i=0; i<width; i++)
{ *obm++ = (rw1 * *rp++ +
gw1 * *gp++ +
bw1 * *bp++) >> 8;
}
}
}
return (1);
}
/****************************************************************
* gray2clr: Add a colormap (shades of gray) to a grayscale file
****************************************************************/
gray2clr (input, output, sun_map)
FBM *input, *output;
int sun_map;
{ register unsigned char *rmap, *gmap, *bmap, *bmp, *obm;
register int i, maplen, plnlen;
/* Invalid raster type */
if (input->hdr.planes == 3)
{ fprintf (stderr, "Input already is in RGB format\n");
*output = *input; return (1);
}
/* Invalid raster type */
if (input->hdr.clrlen > 0 )
{ fprintf (stderr, "Input already has color map with %d colors\n",
input->hdr.clrlen / 3);
*output = *input; return (1);
}
/* Invalid raster type */
if (input->hdr.planes != 1 || input->hdr.clrlen != 0)
{ fprintf (stderr,
"gray2clr was passed invalid raster type, clrlen %d, planes %d\n",
input->hdr.clrlen, input->hdr.planes);
return (0);
}
plnlen = input->hdr.plnlen;
/* Make colormap length power of two */
maplen = 1 << input->hdr.bits;
/* Allocate output bitmap */
output->hdr = input->hdr;
output->hdr.clrlen = maplen * 3;
alloc_fbm (output);
rmap = &(output->cm[0]);
gmap = &(output->cm[maplen]);
bmap = &(output->cm[2*maplen]);
for (i=0; i<maplen; i++)
{ *rmap++ = *gmap++ = *bmap++ = i; }
/* For sun_map, swap colors 0 and 255 */
if (sun_map && (maplen == 256))
{ rmap = &(output->cm[0]);
gmap = &(output->cm[maplen]);
bmap = &(output->cm[2*maplen]);
rmap[0] = gmap[0] = bmap[0] = 255;
rmap[255] = gmap[255] = bmap[255] = 0;
/* Copy bits */
for (bmp = input->bm, obm = output-> bm, i=0; i<plnlen; i++, bmp++)
{ if (*bmp == 0) *obm++ = 255;
else if (*bmp == 255) *obm++ = 0;
else *obm++ = *bmp;
}
}
else
{
/* Copy bits */
for (bmp = input->bm, obm = output-> bm, i=0; i<plnlen; i++)
{ *obm++ = *bmp++; }
}
return (1);
}
/****************************************************************
* clr_unmap: Convert a mapped color image into RGB
****************************************************************/
clr_unmap (input, output)
FBM *input, *output;
{ register unsigned char *red, *grn, *blu, *bmp, *obm, *tail;
register int plnlen, k;
if (input->hdr.planes == 3)
{ *output = *input; return (1); }
if (input->hdr.planes != 1)
{ fprintf (stderr, "clr_unmap cannot handle images with %d planes\n",
input->hdr.planes);
return (0);
}
if (input->hdr.physbits != 8)
{ fprintf (stderr, "clr_unmap cannot handle images with %d physbits\n",
input->hdr.physbits);
return (0);
}
output->hdr = input->hdr;
output->hdr.planes = 3;
output->hdr.clrlen = 0;
output->hdr.bits = output->hdr.physbits;
alloc_fbm (output);
/* Real mapped color image */
if (input->hdr.clrlen > 0)
{ red = &(input->cm[0]);
grn = red + input->hdr.clrlen / 3;
blu = grn + input->hdr.clrlen / 3;
plnlen = input->hdr.plnlen;
bmp = input->bm;
obm = output->bm;
tail = bmp + plnlen;
while (bmp < tail)
{ k = *bmp++;
obm[0] = red[k];
obm[plnlen] = grn[k];
obm[plnlen+plnlen] = blu[k];
obm++;
}
}
/* Grayscale image (just duplicate planes) */
else
{ plnlen = input->hdr.plnlen;
bmp = input->bm;
tail = bmp + plnlen;
red = output->bm;
grn = red + plnlen;
blu = grn + plnlen;
while (bmp < tail)
{ *red++ = *grn++ = *blu++ = *bmp++; }
}
return (1);
}
/****************************************************************
* copy_clr: Copy colormap from input to output
****************************************************************/
copy_clr (input, output)
FBM *input, *output;
{ register int i, clrlen;
register unsigned char *ic, *oc;
if (output->hdr.clrlen != input->hdr.clrlen)
{ if (output->hdr.clrlen > 0) free (output->cm);
output->cm = (unsigned char *) malloc (input->hdr.clrlen);
}
output->hdr.clrlen = clrlen = input->hdr.clrlen;
ic = input->cm;
oc = output->cm;
for (i=0; i < clrlen; i++)
{ *oc++ = *ic++; }
return (1);
}