Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

gifunopt.c

Go to the documentation of this file.
00001 /* gifunopt.c - Unoptimization function for the GIF library.
00002    Copyright (C) 1997-9 Eddie Kohler, eddietwo@lcs.mit.edu
00003    This file is part of the GIF library.
00004 
00005    The GIF library is free software*. It is distributed under the GNU General
00006    Public License, version 2 or later; you can copy, distribute, or alter it
00007    at will, as long as this notice is kept intact and this source code is made
00008    available. There is no warranty, express or implied.
00009 
00010    *The LZW compression method used by GIFs is patented. Unisys, the patent
00011    holder, allows the compression algorithm to be used without a license in
00012    software distributed at no cost to the user. */
00013 
00014 #ifdef HAVE_CONFIG_H
00015 # include "config.h"
00016 #endif
00017 #include "gif.h"
00018 #include <assert.h>
00019 #include <string.h>
00020 #ifdef __cplusplus
00021 extern "C" {
00022 #endif
00023 
00024 #define TRANSPARENT 256
00025 
00026 static void
00027 put_image_in_screen(Gif_Stream *gfs, Gif_Image *gfi, u_int16_t *screen)
00028 {
00029   int transparent = gfi->transparent;
00030   int x, y;
00031   int w = gfi->width;
00032   int h = gfi->height;
00033   if (gfi->left + w > gfs->screen_width) w = gfs->screen_width - gfi->left;
00034   if (gfi->top + h > gfs->screen_height) h = gfs->screen_height - gfi->top;
00035   
00036   for (y = 0; y < h; y++) {
00037     u_int16_t *move = screen + gfs->screen_width * (y + gfi->top) + gfi->left;
00038     byte *line = gfi->img[y];
00039     for (x = 0; x < w; x++, move++, line++)
00040       if (*line != transparent)
00041         *move = *line;
00042   }
00043 }
00044 
00045 
00046 static void
00047 put_background_in_screen(Gif_Stream *gfs, Gif_Image *gfi, u_int16_t *screen)
00048 {
00049   u_int16_t solid;
00050   int x, y;
00051   int w = gfi->width;
00052   int h = gfi->height;
00053   if (gfi->left + w > gfs->screen_width) w = gfs->screen_width - gfi->left;
00054   if (gfi->top + h > gfs->screen_height) h = gfs->screen_height - gfi->top;
00055   
00056   if (gfi->transparent >= 0)
00057     solid = TRANSPARENT;
00058   else if (gfs->images[0]->transparent >= 0)
00059     solid = TRANSPARENT;
00060   else
00061     solid = gfs->background;
00062   
00063   for (y = 0; y < h; y++) {
00064     u_int16_t *move = screen + gfs->screen_width * (y + gfi->top) + gfi->left;
00065     for (x = 0; x < w; x++, move++)
00066       *move = solid;
00067   }
00068 }
00069 
00070 
00071 static int
00072 create_image_data(Gif_Stream *gfs, Gif_Image *gfi, u_int16_t *screen,
00073                   byte *new_data)
00074 {
00075   int have[257];
00076   int transparent = -1;
00077   int size = gfs->screen_width * gfs->screen_height;
00078   u_int16_t *move;
00079   int i;
00080 
00081   /* mark colors used opaquely in the image */
00082   assert(TRANSPARENT == 256);
00083   for (i = 0; i < 257; i++)
00084     have[i] = 0;
00085   for (i = 0, move = screen; i < size; i++, move++)
00086     have[*move] = 1;
00087   
00088   /* the new transparent color is a color unused in either */
00089   if (have[TRANSPARENT]) {
00090     for (i = 0; i < 256 && transparent < 0; i++)
00091       if (!have[i])
00092         transparent = i;
00093     if (transparent < 0)
00094       goto error;
00095     if (transparent >= gfs->global->ncol) {
00096       Gif_ReArray(gfs->global->col, Gif_Color, 256);
00097       if (!gfs->global->col) goto error;
00098       gfs->global->ncol = transparent + 1;
00099     }
00100   }
00101   
00102   /* map the wide image onto the new data */
00103   for (i = 0, move = screen; i < size; i++, move++, new_data++)
00104     if (*move == TRANSPARENT)
00105       *new_data = transparent;
00106     else
00107       *new_data = *move;
00108 
00109   gfi->transparent = transparent;
00110   return 1;
00111   
00112  error:
00113   return 0;
00114 }
00115 
00116 
00117 static int
00118 unoptimize_image(Gif_Stream *gfs, Gif_Image *gfi, u_int16_t *screen)
00119 {
00120   int size = gfs->screen_width * gfs->screen_height;
00121   byte *new_data = Gif_NewArray(byte, size);
00122   u_int16_t *new_screen = screen;
00123   if (!new_data) return 0;
00124   
00125   /* Oops! May need to uncompress it */
00126   Gif_UncompressImage(gfi);
00127   Gif_ReleaseCompressedImage(gfi);
00128   
00129   if (gfi->disposal == GIF_DISPOSAL_PREVIOUS) {
00130     new_screen = Gif_NewArray(u_int16_t, size);
00131     if (!new_screen) return 0;
00132     memcpy(new_screen, screen, size * sizeof(u_int16_t));
00133   }
00134   
00135   put_image_in_screen(gfs, gfi, new_screen);
00136   if (!create_image_data(gfs, gfi, new_screen, new_data)) {
00137     Gif_DeleteArray(new_data);
00138     return 0;
00139   }
00140   
00141   if (gfi->disposal == GIF_DISPOSAL_PREVIOUS)
00142     Gif_DeleteArray(new_screen);
00143   else if (gfi->disposal == GIF_DISPOSAL_BACKGROUND)
00144     put_background_in_screen(gfs, gfi, screen);
00145   
00146   gfi->left = 0;
00147   gfi->top = 0;
00148   gfi->width = gfs->screen_width;
00149   gfi->height = gfs->screen_height;
00150   gfi->disposal = GIF_DISPOSAL_BACKGROUND;
00151   Gif_SetUncompressedImage(gfi, new_data, Gif_DeleteArrayFunc, 0);
00152   
00153   return 1;
00154 }
00155 
00156 
00157 int
00158 Gif_Unoptimize(Gif_Stream *gfs)
00159 {
00160   int ok = 1;
00161   int i, size;
00162   u_int16_t *screen;
00163   u_int16_t background;
00164   Gif_Image *gfi;
00165   
00166   if (gfs->nimages < 1) return 1;
00167   for (i = 0; i < gfs->nimages; i++)
00168     if (gfs->images[i]->local)
00169       return 0;
00170   if (!gfs->global)
00171     return 0;
00172   
00173   Gif_CalculateScreenSize(gfs, 0);
00174   size = gfs->screen_width * gfs->screen_height;
00175   
00176   screen = Gif_NewArray(u_int16_t, size);
00177   gfi = gfs->images[0];
00178   background = gfi->transparent >= 0 ? TRANSPARENT : gfs->background;
00179   for (i = 0; i < size; i++)
00180     screen[i] = background;
00181   
00182   for (i = 0; i < gfs->nimages; i++)
00183     if (!unoptimize_image(gfs, gfs->images[i], screen))
00184       ok = 0;
00185   
00186   Gif_DeleteArray(screen);
00187   return ok;
00188 }
00189 
00190 
00191 #ifdef __cplusplus
00192 }
00193 #endif
 

Powered by Plone

This site conforms to the following standards: