home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume19 / fbm / part05 / flclr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-06-08  |  7.4 KB  |  296 lines

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