home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************
- * Copyright (c) 1987 *
- * by CompuServe Inc, Columbus, Ohio. All Rights Reserved *
- ***********************************************************/
-
- #include <stdio.h>
- #include "buildgif.h"
-
- static short Write_Color_Map();
- static char GIF_signature[] = "GIF87a";
-
-
- short Create_GIF (read_pixel, write_byte, width, height, cr, interlaced,
- bp, color_map)
- /*
- * Function:
- * Create a 1-image GIF image-set. The size of the screen will be the
- * same as the image.
- *
- * Inputs:
- */
- short (*read_pixel)(); /* ptr to caller's pixel reader */
- short (*write_byte)(); /* ptr to caller's byte writer */
- short width; /* width of image in pixels */
- short height; /* height of image in pixels */
- short cr; /* bits of color resolution (1..8) */
- short interlaced; /* interlaced flag */
- short bp; /* bits per pixel (1..8) */
- struct ColorEntry color_map[]; /* ptr to color map */
- /*
- * Returns:
- * 0 = OK, else error code
- */
- {
- short status; /* return status */
-
- status = Write_Screen_Desc (write_byte, width, height, cr, 0, bp, color_map);
- if (status != 0) return status;
-
- status = Write_Image_Desc (write_byte, 0, 0, width, height, 0, interlaced, 0, NULL);
- if (status != 0) return status;
-
- status = Compress_Data (bp, read_pixel, write_byte);
- if (status != 0) return status;
-
- return (*write_byte)(';');
- }
-
- short Write_Screen_Desc (write_byte, width, height, cr, fill_color, bp, color_map)
- /*
- * Function:
- * Write the GIF signature, the screen description, and the optional
- * color map.
- *
- * Inputs:
- */
- short (*write_byte)(); /* ptr to caller's byte writer */
- short width; /* width of the screen in pixels */
- short height; /* height of the screen in pixels */
- short cr; /* bits of color resolution (1..8) */
- short fill_color; /* pixel value used to fill the background */
- short bp; /* bits per pixel (1..8) */
- struct ColorEntry color_map[]; /* ptr to the optional color map */
- /*
- * Returns:
- * 0 = OK, else error code
- */
- {
- short status;
- short i;
-
- for (i = 0; i < 6; i++)
- if ((status = (*write_byte)(GIF_signature[i])) != 0) return status;
-
- status = (*write_byte)(width & 0xFF);
- if (status != 0) return status;
-
- status = (*write_byte)(width >> 8);
- if (status != 0) return status;
-
- status = (*write_byte)(height & 0xFF);
- if (status != 0) return status;
-
- status = (*write_byte)(height >> 8);
- if (status != 0) return status;
-
- if (color_map == NULL)
- status = (*write_byte)(((cr - 1) & 0x07) << 4);
- else
- status = (*write_byte)(0x80 | ((cr - 1) << 4) | ((bp - 1) & 0x07));
-
- if (status != 0) return status;
-
- status = (*write_byte)(fill_color);
- if (status != 0) return status;
-
- status = (*write_byte)(0); /* reserved */
- if (status != 0) return status;
-
- if (color_map != NULL)
- return Write_Color_Map (write_byte, cr, bp, color_map);
- else
- return 0;
- }
-
- short Write_Image_Desc (write_byte, left_edge, top_edge, width, height,
- cr, interlaced, bp, color_map)
- /*
- * Function:
- * Write the image description and optional local color map.
- *
- * Inputs:
- */
- short (*write_byte)(); /* ptr to caller's byte writer */
- short left_edge; /* (left_edge, top_edge) is the upper left */
- short top_edge; /* position in pixels of the image */
- short width; /* width of the image in pixels */
- short height; /* height of the image in pixels */
- short cr; /* bits of color resolution (1..8) */
- short interlaced; /* 1 = interlace the image */
- short bp; /* bits per pixel for this image */
- struct ColorEntry color_map[]; /* ptr to local color map */
- /*
- * Returns:
- * 0 = OK, else error code
- */
- {
- short status;
-
- status = (*write_byte)(',');
- if (status != 0) return status;
-
- status = (*write_byte)(left_edge & 0xFF);
- if (status != 0) return status;
-
- status = (*write_byte)(left_edge >> 8);
- if (status != 0) return status;
-
- status = (*write_byte)(top_edge & 0xFF);
- if (status != 0) return status;
-
- status = (*write_byte)(top_edge >> 8);
- if (status != 0) return status;
-
- status = (*write_byte)(width & 0xFF);
- if (status != 0) return status;
-
- status = (*write_byte)(width >> 8);
- if (status != 0) return status;
-
- status = (*write_byte)(height & 0xFF);
- if (status != 0) return status;
-
- status = (*write_byte)(height >> 8);
- if (status != 0) return status;
-
- if (color_map == NULL)
- status = (*write_byte)(interlaced << 6);
- else
- status = (*write_byte)(0x80 | (interlaced << 6) | ((bp - 1) & 0x07));
-
- if (status != 0) return status;
-
- if (color_map != NULL)
- Write_Color_Map (write_byte, cr, bp, color_map);
- else
- return 0;
- }
-
- static short Write_Color_Map (write_byte, cr, bp, color_map)
- /*
- * Function:
- * Write the specified color map.
- *
- * Inputs:
- * (see above)
- *
- * Returns:
- * 0 = OK, else error code
- */
- short (*write_byte)();
- short cr;
- short bp;
- struct ColorEntry color_map[];
- {
- short num_colors;
- short n, i;
- short status;
-
- num_colors = 1 << bp;
- n = (1 << cr) - 1;
-
- for (i = 0; i < num_colors; i++)
- {
- status = (*write_byte)(color_map[i].red*255/n);
- if (status != 0) return status;
-
- status = (*write_byte)(color_map[i].green*255/n);
- if (status != 0) return status;
-
- status = (*write_byte)(color_map[i].blue*255/n);
- if (status != 0) return status;
- }
-
- return 0;
- }
-