home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / fbm / src / flclr.c < prev    next >
C/C++ Source or Header  |  1990-06-24  |  8KB  |  309 lines

  1. /*****************************************************************
  2.  * flclr.c: FBM Release 1.0 25-Feb-90 Michael Mauldin
  3.  *
  4.  * Copyright (C) 1989,1990 by Michael Mauldin.  Permission is granted
  5.  * to use this file in whole or in part for any purpose, educational,
  6.  * recreational or commercial, provided that this copyright notice
  7.  * is retained unchanged.  This software is available to all free of
  8.  * charge by anonymous FTP and in the UUNET archives.
  9.  *
  10.  * flclr.c: Color <--> BW, (Mapped Color | BW) --> unmapped color
  11.  *
  12.  * CONTENTS
  13.  *    clr2gray (input, output, rw, gw, bw)
  14.  *    gray2clr (input, output, sun)
  15.  *
  16.  * EDITLOG
  17.  *    LastEditDate = Mon Jun 25 00:05:04 1990 - Michael Mauldin
  18.  *    LastFileName = /usr2/mlm/src/misc/fbm/flclr.c
  19.  *
  20.  * HISTORY
  21.  * 25-Jun-90  Michael Mauldin (mlm@cs.cmu.edu) Carnegie Mellon
  22.  *    Package for Release 1.0
  23.  *
  24.  * 07-Mar-89  Michael Mauldin (mlm) at Carnegie Mellon University
  25.  *    Beta release (version 0.9) mlm@cs.cmu.edu
  26.  *
  27.  * 28-Nov-88  Michael Mauldin (mlm) at Carnegie-Mellon University
  28.  *    Created.
  29.  *****************************************************************/
  30.  
  31. # include <stdio.h>
  32. # include "fbm.h"
  33.  
  34. /****************************************************************
  35.  * clr2gray: Apply a triplet of weights to each color in and RGB
  36.  *         or mapped image and produce an 8bit grayscale image
  37.  ****************************************************************/
  38.  
  39. #ifndef lint
  40. static char *fbmid =
  41. "$FBM flclr.c <1.0> 25-Jun-90  (C) 1989,1990 by Michael Mauldin, source \
  42. code available free from MLM@CS.CMU.EDU and from UUNET archives$";
  43. #endif
  44.  
  45. clr2gray (input, output, rw, gw, bw)
  46. FBM *input, *output;
  47. int rw, gw, bw;
  48. { int rw1, gw1, bw1, width, height, clrlen, rowlen, colors;
  49.   register int i, j;
  50.   register unsigned char *bmp, *obm;
  51.  
  52.   /* Already monochrome? */
  53.   if (input->hdr.planes == 1 && input->hdr.clrlen == 0)
  54.   { *output = *input; return (1); }
  55.   
  56.   /* Invalid raster type */
  57.   if (input->hdr.planes != 3 && input->hdr.clrlen == 0)
  58.   { fprintf (stderr,
  59.      "clr2gray was passed invalid raster type, clrlen %d, planes %d\n",
  60.      input->hdr.clrlen, input->hdr.planes);
  61.     return (0);
  62.   }
  63.   
  64.   /* Adjust weights for fast division via shift */
  65.   rw1 = rw * 256 / (rw + gw + bw);
  66.   gw1 = gw * 256 / (rw + gw + bw);
  67.   bw1 = 256 - (rw1+gw1);
  68.   
  69.   fprintf (stderr, "Using weights [%2d %2d %2d] ==> <%3d, %3d, %3d>\n",
  70.        rw, gw, bw, rw1, gw1, bw1);
  71.  
  72.   /* Allocate output bitmap */
  73.   output->hdr = input->hdr;
  74.   output->hdr.clrlen = 0;
  75.   output->hdr.planes = 1;
  76.   output->hdr.bits = output->hdr.physbits = 8;
  77.   alloc_fbm (output);
  78.   
  79.   /* Set commonly used vars */
  80.   width = input->hdr.cols;
  81.   height = input->hdr.rows;
  82.   rowlen = input->hdr.rowlen;
  83.   clrlen = input->hdr.clrlen;
  84.   colors = clrlen / 3;
  85.  
  86.   /* Mapped color to gray scale */
  87.   if (input->hdr.clrlen > 0)
  88.   { register int *gray;
  89.   
  90.     gray = (int *) malloc ((unsigned) input->hdr.clrlen * sizeof (int));
  91.     
  92.     for (i=0; i<colors; i++)
  93.     { gray[i] = (rw1 * input->cm[i] + 
  94.          gw1 * input->cm[i+colors] + 
  95.          bw1 * input->cm[i+(colors<<1)]) >> 8;
  96.  
  97. # ifdef DEBUG
  98.       fprintf (stderr, "color %3d:  [%3d %3d %3d] => %3d\n",
  99.         i,
  100.         input->cm[i],
  101.         input->cm[i+colors],
  102.         input->cm[i+colors*2],
  103.         gray[i]);
  104. # endif
  105.  
  106.     }
  107.     
  108.     for (j=0; j<height; j++)
  109.     { bmp = &(input->bm[j*rowlen]);
  110.       obm = &(output->bm[j*rowlen]);
  111.       
  112.       for (i=0; i<width; i++)
  113.       { *obm++ = gray[*bmp++]; }
  114.     }
  115.   }
  116.          
  117.  
  118.   /* RGB color to gray scale */
  119.   else if (input->hdr.planes == 3 && input->hdr.physbits == 8)
  120.   { register unsigned char *rp, *gp, *bp;
  121.  
  122.     for (j=0; j<height; j++)
  123.     { rp = &(input->bm[j*rowlen]);
  124.       gp = rp + input->hdr.plnlen;
  125.       bp = gp + input->hdr.plnlen;
  126.       obm = (&output->bm[j*rowlen]);
  127.  
  128.       for (i=0; i<width; i++)
  129.       { *obm++ = (rw1 * *rp++ + 
  130.           gw1 * *gp++ + 
  131.           bw1 * *bp++) >> 8;
  132.       }
  133.     }
  134.   }
  135.   
  136.   return (1);
  137. }
  138.  
  139. /****************************************************************
  140.  * gray2clr: Add a colormap (shades of gray) to a grayscale file
  141.  ****************************************************************/
  142.  
  143. gray2clr (input, output, sun_map)
  144. FBM *input, *output;
  145. int sun_map;
  146. { register unsigned char *rmap, *gmap, *bmap, *bmp, *obm;
  147.   register int i, maplen, plnlen;
  148.  
  149.   /* Invalid raster type */
  150.   if (input->hdr.planes == 3)
  151.   { fprintf (stderr, "Input already is in RGB format\n");
  152.     *output = *input; return (1);
  153.   }
  154.     
  155.   /* Invalid raster type */
  156.   if (input->hdr.clrlen > 0 )
  157.   { fprintf (stderr, "Input already has color map with %d colors\n",
  158.          input->hdr.clrlen / 3);
  159.     *output = *input; return (1);
  160.   }
  161.  
  162.   /* Invalid raster type */
  163.   if (input->hdr.planes != 1 || input->hdr.clrlen != 0)
  164.   { fprintf (stderr,
  165.      "gray2clr was passed invalid raster type, clrlen %d, planes %d\n",
  166.      input->hdr.clrlen, input->hdr.planes);
  167.     return (0);
  168.   }
  169.   
  170.   plnlen = input->hdr.plnlen;
  171.   
  172.   /* Make colormap length power of two */
  173.   maplen = 1 << input->hdr.bits;
  174.  
  175.   /* Allocate output bitmap */
  176.   output->hdr = input->hdr;
  177.   output->hdr.clrlen = maplen * 3;
  178.   alloc_fbm (output);
  179.   
  180.   rmap = &(output->cm[0]);
  181.   gmap = &(output->cm[maplen]);
  182.   bmap = &(output->cm[2*maplen]);
  183.  
  184.   for (i=0; i<maplen; i++)
  185.   { *rmap++ = *gmap++ = *bmap++ = i; }
  186.  
  187.   /* For sun_map, swap colors 0 and 255 */
  188.   if (sun_map && (maplen == 256))
  189.   { rmap = &(output->cm[0]);
  190.     gmap = &(output->cm[maplen]);
  191.     bmap = &(output->cm[2*maplen]);
  192.  
  193.     rmap[0] = gmap[0] = bmap[0] = 255;
  194.     rmap[255] = gmap[255] = bmap[255] = 0;
  195.  
  196.     /* Copy bits */
  197.     for (bmp = input->bm, obm = output-> bm, i=0; i<plnlen; i++, bmp++)
  198.     { if (*bmp == 0)        *obm++ = 255;
  199.       else if (*bmp == 255)    *obm++ = 0;
  200.       else            *obm++ = *bmp;
  201.     }
  202.   }
  203.  
  204.   else  
  205.   {
  206.     /* Copy bits */
  207.     for (bmp = input->bm, obm = output-> bm, i=0; i<plnlen; i++)
  208.     { *obm++ = *bmp++; }
  209.   }
  210.  
  211.   return (1);
  212. }
  213.  
  214. /****************************************************************
  215.  * clr_unmap: Convert a mapped color image into RGB
  216.  ****************************************************************/
  217.  
  218. clr_unmap (input, output)
  219. FBM *input, *output;
  220. { register unsigned char *red, *grn, *blu, *bmp, *obm, *tail;
  221.   register int plnlen, k;
  222.  
  223.   if (input->hdr.planes == 3)
  224.   { *output = *input; return (1); }
  225.  
  226.   if (input->hdr.planes != 1)
  227.   { fprintf (stderr, "clr_unmap cannot handle images with %d planes\n", 
  228.          input->hdr.planes);
  229.     return (0);
  230.   }
  231.  
  232.   if (input->hdr.physbits != 8)
  233.   { fprintf (stderr, "clr_unmap cannot handle images with %d physbits\n", 
  234.          input->hdr.physbits);
  235.     return (0);
  236.   }
  237.  
  238.   output->hdr = input->hdr;
  239.   output->hdr.planes = 3;
  240.   output->hdr.clrlen = 0;
  241.   output->hdr.bits = output->hdr.physbits;
  242.   
  243.   alloc_fbm (output);
  244.  
  245.   /* Real mapped color image */
  246.   if (input->hdr.clrlen > 0)
  247.   { red = &(input->cm[0]);
  248.     grn = red + input->hdr.clrlen / 3;
  249.     blu = grn + input->hdr.clrlen / 3;
  250.     plnlen = input->hdr.plnlen;
  251.     
  252.     bmp = input->bm;
  253.     obm = output->bm;
  254.     tail = bmp + plnlen;
  255.     
  256.     while (bmp < tail)
  257.     { k = *bmp++;
  258.     
  259.       obm[0]            = red[k];
  260.       obm[plnlen]        = grn[k];
  261.       obm[plnlen+plnlen]    = blu[k];
  262.       obm++;
  263.     }
  264.     
  265.   }
  266.   
  267.   /* Grayscale image (just duplicate planes) */
  268.   else
  269.   { plnlen = input->hdr.plnlen;
  270.   
  271.     bmp = input->bm;
  272.     tail = bmp + plnlen;
  273.     
  274.     red = output->bm;
  275.     grn = red + plnlen;
  276.     blu = grn + plnlen;
  277.     
  278.     while (bmp < tail)
  279.     { *red++ = *grn++ = *blu++ = *bmp++; }
  280.   }
  281.   
  282.   return (1);
  283. }
  284.  
  285. /****************************************************************
  286.  * copy_clr: Copy colormap from input to output
  287.  ****************************************************************/
  288.  
  289. copy_clr (input, output)
  290. FBM *input, *output;
  291. { register int i, clrlen;
  292.   register unsigned char *ic, *oc;
  293.  
  294.   if (output->hdr.clrlen != input->hdr.clrlen)
  295.   { if (output->hdr.clrlen > 0) free (output->cm);
  296.     output->cm = (unsigned char *) malloc (input->hdr.clrlen);
  297.   }
  298.  
  299.   output->hdr.clrlen = clrlen = input->hdr.clrlen;
  300.  
  301.   ic = input->cm;
  302.   oc = output->cm;
  303.   
  304.   for (i=0; i < clrlen; i++)
  305.   { *oc++ = *ic++; }
  306.  
  307.   return (1);
  308. }
  309.