home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1997 May / PCO_5_97.ISO / FilesBBS / OS2 / WWWCNT15.ARJ / WWWCNT15 / WWWCNT15.ZIP / combine / writegif.c < prev   
Encoding:
C/C++ Source or Header  |  1995-09-09  |  5.8 KB  |  294 lines

  1. /*
  2.  *    WriteGIF()    -    writes an image in GIF format
  3.  *
  4.  *    RCS:
  5.  *        $Revision: 1.3 $
  6.  *        $Date: 1995/07/16 17:03:54 $
  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.     
  77.     colors = 256;
  78.     gifimage->fp = fp;
  79. /*
  80.     if (image != (Image *) NULL)
  81.     {
  82.         gifimage = DuplicateImage (image, image->columns, 
  83.             image->rows, True);
  84.     }
  85.     else
  86.     {
  87.         (void) fprintf (stderr, "Unable to convert image to GIF!\n");
  88.         rc = EMPTY_IMAGE_STRUCT;
  89.         goto ExitProcessing;
  90.     }
  91.  
  92.     if (gifimage == (Image *) NULL)
  93.     {
  94.         fprintf (stderr, "WriteGIF: memory allocation failed!\n");
  95.         rc = MALLOC_FAILED;
  96.         goto ExitProcessing;
  97.     }
  98. */
  99.     alpha=(unsigned char *)NULL;
  100.  
  101.     if (gifimage->alpha)
  102.     {
  103.         if (!UncompressImage(gifimage))
  104.             return (5);
  105.         
  106.         p=gifimage->pixels;
  107.         alpha=(unsigned char *)
  108.             malloc(gifimage->columns*gifimage->rows*sizeof(unsigned char));
  109.         if (alpha == (unsigned char *) NULL)
  110.         {
  111.             fprintf (stderr, "WriteGIF: memory allocation failed!\n");
  112.             rc = MALLOC_FAILED;
  113.             goto ExitProcessing;
  114.         } 
  115.         else
  116.         {
  117.             for(x=0; x < (gifimage->columns*gifimage->rows); x++)
  118.             {
  119.                 alpha[x]=(unsigned char) (p->index & 0xff);
  120.                 p++;
  121.             }
  122.             colors--;
  123.         }
  124.     }
  125.  
  126.     if ((gifimage->class == DirectClass) || (gifimage->colors > colors))
  127.     {
  128.         QuantizeImage(gifimage, colors, 8, False, RGBColorspace, True);
  129.         SyncImage(gifimage);
  130.         if (!UncompressImage(gifimage))
  131.         {
  132.             (void) fprintf (stderr," Failed to uncompress!\n");
  133.             return(5);
  134.         }
  135.     }
  136.  
  137.     colors = gifimage->colors;
  138.  
  139.     if (alpha != (unsigned char *) NULL)
  140.     {
  141.         CompressColormap(gifimage);
  142.         colors++;
  143.     }
  144.  
  145. #ifdef DEBUG
  146.     fprintf (stderr, "GIF image colors: %d\n", colors);
  147. #endif
  148.  
  149.     for (bits_per_pixel = 1; bits_per_pixel < 8; bits_per_pixel++)
  150.         if ((1 << bits_per_pixel) >= colors)
  151.             break;
  152.     
  153.     /*
  154.     ** Write GIF Header
  155.     */
  156.  
  157.     (void) fwrite("GIF89a", 1, 6, fp);
  158.     (void) fflush(fp);
  159.     LSBFirstWriteShort (gifimage->columns, fp);
  160.     (void) fflush(fp);
  161.     LSBFirstWriteShort (gifimage->rows, fp);
  162.     (void) fflush(fp);
  163.     c = 0x80;
  164.     c|=(8-1) << 4;
  165.     c|=(bits_per_pixel-1);
  166.     (void) fputc((char) c, fp);
  167.     (void) fputc (0x0, fp);
  168.     (void) fputc (0x0, fp);
  169.  
  170.     /*
  171.     ** write colormap
  172.     */
  173.  
  174.     for (i=0; i < gifimage->colors; i++)
  175.     {
  176.         (void) fputc ((char) gifimage->colormap[i].red, fp);
  177.         (void) fputc ((char) gifimage->colormap[i].green, fp);
  178.         (void) fputc ((char) gifimage->colormap[i].blue, fp);
  179.     }
  180.  
  181.     /*
  182.     ** wrtie transparent channel
  183.     */
  184.     if (alpha != (unsigned char *) NULL)
  185.     {
  186.         p=gifimage->pixels;
  187.         for (x=0; x < (gifimage->columns*gifimage->rows); x++)
  188.         {
  189.             if (alpha[x] == Transparent)
  190.                 break;
  191.             p++;
  192.         }
  193.         (void) fputc((char) gifimage->colormap[p->index].red,fp);
  194.         (void) fputc((char) gifimage->colormap[p->index].green,fp);
  195.         (void) fputc((char) gifimage->colormap[p->index].blue,fp);
  196.         i++;
  197.     }
  198.  
  199.     for (; i < (int) (1 << bits_per_pixel); i++)
  200.     {
  201.         (void) fputc (0x0, fp);
  202.         (void) fputc (0x0, fp);
  203.         (void) fputc (0x0, fp);
  204.     }
  205.  
  206.     if (strcmp(gifimage->type, "GIF87") != 0)
  207.     {
  208.         if (gifimage->comments != (char *) NULL)
  209.         {
  210.             register char
  211.                 *p;
  212.             
  213.             register unsigned int
  214.                 count;
  215.             
  216.             /*
  217.             ** write comment extension block
  218.             */
  219.  
  220.             (void) fputc (0x21, fp);
  221.             (void) fputc (0xfe, fp);
  222.  
  223.             p = gifimage->comments;
  224.  
  225.             while ((int) strlen (p) > 0)
  226.             {
  227.                 count = Min ((int) strlen(p), 255);
  228.                 (void) fputc (count, fp);
  229.  
  230.                 for (i=0; i < count; i++)
  231.                     (void) fputc (*p++, fp);
  232.             }
  233.  
  234.             (void) fputc (0x0, fp);
  235.         }
  236.  
  237.         if (alpha != (unsigned char *) NULL)
  238.         {
  239.             (void) fputc(0x21,fp);
  240.             (void) fputc(0xf9,fp);
  241.             (void) fputc(0x4,fp);
  242.             (void) fputc(0x1,fp);
  243.             (void) fputc(0x0,fp);
  244.             (void) fputc(0x0,fp);
  245.             (void) fputc((char) gifimage->colors,fp);
  246.             (void) fputc(0x0,fp);
  247.             
  248.             p=gifimage->pixels;
  249.             for (x=0; x < (gifimage->columns*gifimage->rows); x++)
  250.             {
  251.                 if (alpha[x] == Transparent)
  252.                     p->index=gifimage->colors;
  253.                 p++;
  254.             } 
  255.             (void) free ((char *) alpha);
  256.         }
  257.     }
  258. /*
  259. ** write gifimage separator
  260. */
  261.     (void) fputc (',', fp);
  262.  
  263.     LSBFirstWriteShort (0, fp);
  264.     (void) fflush(fp);
  265.     LSBFirstWriteShort (0, fp);
  266.     (void) fflush(fp);
  267.     LSBFirstWriteShort (gifimage->columns, fp);
  268.     (void) fflush(fp);
  269.     LSBFirstWriteShort (gifimage->rows, fp);
  270.     (void) fflush(fp);
  271.     (void) fputc (0x0, fp);
  272.     c = Max(bits_per_pixel, 2);
  273.     (void) fputc ((char) c, fp);
  274.  
  275.     status = LZWEncodeImage (gifimage, Max(bits_per_pixel, 2)+1);
  276.  
  277.     if (status == False)
  278.     {
  279.         (void) fprintf (stderr,
  280.         "Unable to write gifimage, Memory allocation failed!\n");
  281.         rc = MALLOC_FAILED;
  282.         goto ExitProcessing;
  283.     }
  284.  
  285.     (void) fputc(0x0, fp);
  286.     (void) fputc(';',fp);
  287.  
  288.     if (gifimage != (Image *) NULL)
  289.         DestroyAnyImageStruct (&gifimage);
  290.  
  291. ExitProcessing:
  292.     return (rc);
  293. }
  294.