home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / UNIX / Web / Utilities / wwwcount-2.3 / combine / writegif.c < prev   
Encoding:
C/C++ Source or Header  |  1996-05-02  |  5.4 KB  |  274 lines

  1. /*
  2.  *    WriteGIF()    -    writes an image in GIF format
  3.  *
  4.  *    RCS:
  5.  *        $Revision: 2.3 $
  6.  *        $Date: 1996/05/03 02:21:34 $
  7.  *
  8.  *    Security:
  9.  *        Unclassified
  10.  *
  11.  *    Description:
  12.  *        this function writes an image in GIF89a format
  13.  *        GIF is copyrighted trademark of Compuserve Inc.
  14.  *
  15.  *      from ImageMagick
  16.  *    Input Parameters:
  17.  *        type    identifier    description
  18.  *
  19.  *        text
  20.  *
  21.  *    Output Parameters:
  22.  *        type    identifier    description
  23.  *
  24.  *        text
  25.  *
  26.  *    Return Values:
  27.  *        value    description
  28.  *
  29.  *    Side Effects:
  30.  *        text
  31.  *
  32.  *    Limitations and Comments:
  33.  *        text
  34.  *
  35.  *    Development History:
  36.  *        when    who        why
  37.  *    08/04/94    muquit     first cut for ntf2gif
  38.  */
  39.  
  40. #include "combine.h"
  41. #include "defines.h"
  42. #include "errcds.h"
  43.  
  44. int WriteGIFImage(gifimage,filename)
  45. Image
  46.     *gifimage;
  47. char
  48.     *filename;
  49. {
  50.     register int
  51.         x,
  52.         i;
  53.     
  54.     unsigned char
  55.         bits_per_pixel,
  56.         c,
  57.         *alpha;
  58.  
  59.     unsigned int
  60.         colors,
  61.         status;
  62.  
  63.     FILE
  64.         *fp;
  65.  
  66.     int
  67.         rc = 0;
  68.     
  69.     register Runlength
  70.         *p;
  71.  
  72.     setbuf(stdout, NULL);
  73.  
  74.     fp = stdout;
  75.  
  76. #ifdef SYS_WIN32
  77.     _setmode(_fileno(fp), _O_BINARY);
  78. #endif
  79.     
  80.     colors = 256;
  81.     gifimage->fp = fp;
  82.     alpha=(unsigned char *)NULL;
  83.  
  84.     if (gifimage->alpha)
  85.     {
  86.         if (!UncompressImage(gifimage))
  87.             return (5);
  88.         
  89.         p=gifimage->pixels;
  90.         alpha=(unsigned char *)
  91.             malloc(gifimage->columns*gifimage->rows*sizeof(unsigned char));
  92.         if (alpha == (unsigned char *) NULL)
  93.         {
  94.             fprintf (stderr, "WriteGIF: memory allocation failed!\n");
  95.             rc = MALLOC_FAILED;
  96.             goto ExitProcessing;
  97.         } 
  98.         else
  99.         {
  100.             for(x=0; x < (gifimage->columns*gifimage->rows); x++)
  101.             {
  102.                 alpha[x]=(unsigned char) (p->index & 0xff);
  103.                 p++;
  104.             }
  105.             colors--;
  106.         }
  107.     }
  108.  
  109.     if ((gifimage->class == DirectClass) || (gifimage->colors > colors))
  110.     {
  111.         QuantizeImage(gifimage, colors, 8, False, RGBColorspace, True);
  112.         SyncImage(gifimage);
  113.         if (!UncompressImage(gifimage))
  114.         {
  115.             (void) fprintf (stderr," Failed to uncompress!\n");
  116.             return(5);
  117.         }
  118.     }
  119.  
  120.     colors = gifimage->colors;
  121.  
  122.     if (alpha != (unsigned char *) NULL)
  123.     {
  124.         CompressColormap(gifimage);
  125.         colors++;
  126.     }
  127.  
  128. #ifdef DEBUG
  129.     fprintf (stderr, "GIF image colors: %d\n", colors);
  130. #endif
  131.  
  132.     for (bits_per_pixel = 1; bits_per_pixel < 8; bits_per_pixel++)
  133.         if ((1 << bits_per_pixel) >= colors)
  134.             break;
  135.     
  136.     /*
  137.     ** Write GIF Header
  138.     */
  139.  
  140.     (void) fwrite("GIF89a", 1, 6, fp);
  141.     (void) fflush(fp);
  142.     LSBFirstWriteShort (gifimage->columns, fp);
  143.     (void) fflush(fp);
  144.     LSBFirstWriteShort (gifimage->rows, fp);
  145.     (void) fflush(fp);
  146.     c = 0x80;
  147.     c|=(8-1) << 4;
  148.     c|=(bits_per_pixel-1);
  149.     (void) fputc((char) c, fp);
  150.     (void) fputc (0x0, fp);
  151.     (void) fputc (0x0, fp);
  152.  
  153.     /*
  154.     ** write colormap
  155.     */
  156.  
  157.     for (i=0; i < gifimage->colors; i++)
  158.     {
  159.         (void) fputc ((char) gifimage->colormap[i].red, fp);
  160.         (void) fputc ((char) gifimage->colormap[i].green, fp);
  161.         (void) fputc ((char) gifimage->colormap[i].blue, fp);
  162.     }
  163.  
  164.     /*
  165.     ** wrtie transparent channel
  166.     */
  167.     if (alpha != (unsigned char *) NULL)
  168.     {
  169.         p=gifimage->pixels;
  170.         for (x=0; x < (gifimage->columns*gifimage->rows); x++)
  171.         {
  172.             if (alpha[x] == Transparent)
  173.                 break;
  174.             p++;
  175.         }
  176.         (void) fputc((char) gifimage->colormap[p->index].red,fp);
  177.         (void) fputc((char) gifimage->colormap[p->index].green,fp);
  178.         (void) fputc((char) gifimage->colormap[p->index].blue,fp);
  179.         i++;
  180.     }
  181.  
  182.     for (; i < (int) (1 << bits_per_pixel); i++)
  183.     {
  184.         (void) fputc (0x0, fp);
  185.         (void) fputc (0x0, fp);
  186.         (void) fputc (0x0, fp);
  187.     }
  188.  
  189.     if (strcmp(gifimage->type, "GIF87") != 0)
  190.     {
  191.         if (gifimage->comments != (char *) NULL)
  192.         {
  193.             register char
  194.                 *p;
  195.             
  196.             register unsigned int
  197.                 count;
  198.             
  199.             /*
  200.             ** write comment extension block
  201.             */
  202.  
  203.             (void) fputc (0x21, fp);
  204.             (void) fputc (0xfe, fp);
  205.  
  206.             p = gifimage->comments;
  207.  
  208.             while ((int) strlen (p) > 0)
  209.             {
  210.                 count = Min ((int) strlen(p), 255);
  211.                 (void) fputc (count, fp);
  212.  
  213.                 for (i=0; i < count; i++)
  214.                     (void) fputc (*p++, fp);
  215.             }
  216.  
  217.             (void) fputc (0x0, fp);
  218.         }
  219.  
  220.         if (alpha != (unsigned char *) NULL)
  221.         {
  222.             (void) fputc(0x21,fp);
  223.             (void) fputc(0xf9,fp);
  224.             (void) fputc(0x4,fp);
  225.             (void) fputc(0x1,fp);
  226.             (void) fputc(0x0,fp);
  227.             (void) fputc(0x0,fp);
  228.             (void) fputc((char) gifimage->colors,fp);
  229.             (void) fputc(0x0,fp);
  230.             
  231.             p=gifimage->pixels;
  232.             for (x=0; x < (gifimage->columns*gifimage->rows); x++)
  233.             {
  234.                 if (alpha[x] == Transparent)
  235.                     p->index=gifimage->colors;
  236.                 p++;
  237.             } 
  238.             (void) free ((char *) alpha);
  239.         }
  240.     }
  241. /*
  242. ** write gifimage separator
  243. */
  244.     (void) fputc (',', fp);
  245.  
  246.     LSBFirstWriteShort (0, fp);
  247.     (void) fflush(fp);
  248.     LSBFirstWriteShort (0, fp);
  249.     (void) fflush(fp);
  250.     LSBFirstWriteShort (gifimage->columns, fp);
  251.     (void) fflush(fp);
  252.     LSBFirstWriteShort (gifimage->rows, fp);
  253.     (void) fflush(fp);
  254.     (void) fputc (0x0, fp);
  255.     c = Max(bits_per_pixel, 2);
  256.     (void) fputc ((char) c, fp);
  257.  
  258.     status = LZWEncodeImage (gifimage, Max(bits_per_pixel, 2)+1);
  259.  
  260.     if (status == False)
  261.     {
  262.         (void) fprintf (stderr,
  263.         "Unable to write gifimage, Memory allocation failed!\n");
  264.         rc = MALLOC_FAILED;
  265.         goto ExitProcessing;
  266.     }
  267.  
  268.     (void) fputc(0x0, fp);
  269.     (void) fputc(';',fp);
  270.  
  271. ExitProcessing:
  272.     return (rc);
  273. }
  274.