00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifdef HAVE_CONFIG_H
00014 #include <config.h>
00015 #endif
00016
00017 #include <stdlib.h>
00018 #include <stdio.h>
00019 #include <string.h>
00020 #include "gif_lib.h"
00021
00022 #define MAX(x, y) (((x) > (y)) ? (x) : (y))
00023
00024
00025
00026
00027
00028 int BitSize(int n)
00029
00030 {
00031 register int i;
00032
00033 for (i = 1; i <= 8; i++)
00034 if ((1 << i) >= n)
00035 break;
00036 return(i);
00037 }
00038
00039
00040
00041
00042
00043
00044 ColorMapObject *MakeMapObject(int ColorCount, const GifColorType *ColorMap)
00045
00046
00047
00048
00049 {
00050 ColorMapObject *Object;
00051
00052 if (ColorCount != (1 << BitSize(ColorCount)))
00053 return((ColorMapObject *)NULL);
00054
00055 Object = (ColorMapObject *)malloc(sizeof(ColorMapObject));
00056 if (Object == (ColorMapObject *)NULL)
00057 return((ColorMapObject *)NULL);
00058
00059 Object->Colors = (GifColorType *)calloc(ColorCount, sizeof(GifColorType));
00060 if (Object->Colors == (GifColorType *)NULL)
00061 return((ColorMapObject *)NULL);
00062
00063 Object->ColorCount = ColorCount;
00064 Object->BitsPerPixel = BitSize(ColorCount);
00065
00066 if (ColorMap)
00067 memcpy((char *)Object->Colors,
00068 (char *)ColorMap, ColorCount * sizeof(GifColorType));
00069
00070 return(Object);
00071 }
00072
00073 void FreeMapObject(ColorMapObject *Object)
00074
00075
00076
00077 {
00078 free(Object->Colors);
00079 free(Object);
00080 }
00081
00082 #ifdef DEBUG
00083 void DumpColorMap(ColorMapObject *Object, FILE *fp)
00084 {
00085 if (Object)
00086 {
00087 int i, j, Len = Object->ColorCount;
00088
00089 for (i = 0; i < Len; i+=4) {
00090 for (j = 0; j < 4 && j < Len; j++) {
00091 fprintf(fp,
00092 "%3d: %02x %02x %02x ", i + j,
00093 Object->Colors[i + j].Red,
00094 Object->Colors[i + j].Green,
00095 Object->Colors[i + j].Blue);
00096 }
00097 fprintf(fp, "\n");
00098 }
00099 }
00100 }
00101 #endif
00102
00103 ColorMapObject *UnionColorMap(
00104 const ColorMapObject *ColorIn1,
00105 const ColorMapObject *ColorIn2,
00106 GifPixelType ColorTransIn2[])
00107
00108
00109
00110
00111
00112
00113
00114 {
00115 int i, j, CrntSlot, RoundUpTo, NewBitSize;
00116 ColorMapObject *ColorUnion;
00117
00118
00119
00120
00121 ColorUnion
00122 = MakeMapObject(MAX(ColorIn1->ColorCount,ColorIn2->ColorCount)*2,NULL);
00123
00124 if (ColorUnion == NULL)
00125 return(NULL);
00126
00127
00128 for (i = 0; i < ColorIn1->ColorCount; i++)
00129 ColorUnion->Colors[i] = ColorIn1->Colors[i];
00130 CrntSlot = ColorIn1->ColorCount;
00131
00132
00133
00134
00135
00136
00137
00138
00139 while (ColorIn1->Colors[CrntSlot-1].Red == 0
00140 && ColorIn1->Colors[CrntSlot-1].Green == 0
00141 && ColorIn1->Colors[CrntSlot-1].Red == 0)
00142 CrntSlot--;
00143
00144
00145 for (i = 0; i < ColorIn2->ColorCount && CrntSlot<=256; i++)
00146 {
00147
00148 for (j = 0; j < ColorIn1->ColorCount; j++)
00149 if (memcmp(&ColorIn1->Colors[j], &ColorIn2->Colors[i], sizeof(GifColorType)) == 0)
00150 break;
00151
00152 if (j < ColorIn1->ColorCount)
00153 ColorTransIn2[i] = j;
00154 else
00155 {
00156
00157 ColorUnion->Colors[CrntSlot] = ColorIn2->Colors[i];
00158 ColorTransIn2[i] = CrntSlot++;
00159 }
00160 }
00161
00162 if (CrntSlot > 256)
00163 {
00164 FreeMapObject(ColorUnion);
00165 return((ColorMapObject *)NULL);
00166 }
00167
00168 NewBitSize = BitSize(CrntSlot);
00169 RoundUpTo = (1 << NewBitSize);
00170
00171 if (RoundUpTo != ColorUnion->ColorCount)
00172 {
00173 register GifColorType *Map = ColorUnion->Colors;
00174
00175
00176
00177
00178
00179
00180 for (j = CrntSlot; j < RoundUpTo; j++)
00181 Map[j].Red = Map[j].Green = Map[j].Blue = 0;
00182
00183
00184 if (RoundUpTo < ColorUnion->ColorCount)
00185 ColorUnion->Colors
00186 = (GifColorType *)realloc(Map, sizeof(GifColorType)*RoundUpTo);
00187 }
00188
00189 ColorUnion->ColorCount = RoundUpTo;
00190 ColorUnion->BitsPerPixel = NewBitSize;
00191
00192 return(ColorUnion);
00193 }
00194
00195 void ApplyTranslation(SavedImage *Image, GifPixelType Translation[])
00196
00197
00198
00199 {
00200 register int i;
00201 register int RasterSize = Image->ImageDesc.Height * Image->ImageDesc.Width;
00202
00203 for (i = 0; i < RasterSize; i++)
00204 Image->RasterBits[i] = Translation[(int)(Image->RasterBits[i])];
00205 }
00206
00207
00208
00209
00210
00211 void MakeExtension(SavedImage *New, int Function)
00212 {
00213 New->Function = Function;
00214
00215
00216
00217 }
00218
00219 int AddExtensionBlock(SavedImage *New, int Len, char ExtData[])
00220 {
00221 ExtensionBlock *ep;
00222
00223 if (New->ExtensionBlocks == NULL)
00224 New->ExtensionBlocks = (ExtensionBlock *)malloc(sizeof(ExtensionBlock));
00225 else
00226 New->ExtensionBlocks =
00227 (ExtensionBlock *)realloc(New->ExtensionBlocks,
00228 sizeof(ExtensionBlock) * (New->ExtensionBlockCount + 1));
00229
00230 if (New->ExtensionBlocks == NULL)
00231 return(GIF_ERROR);
00232
00233 ep = &New->ExtensionBlocks[New->ExtensionBlockCount++];
00234
00235 if ((ep->Bytes = (char *)malloc(ep->ByteCount = Len)) == NULL)
00236 return(GIF_ERROR);
00237
00238 if (ExtData) {
00239 memcpy(ep->Bytes, ExtData, Len);
00240 ep->Function = New->Function;
00241 }
00242
00243 return(GIF_OK);
00244 }
00245
00246 void FreeExtension(SavedImage *Image)
00247 {
00248 ExtensionBlock *ep;
00249
00250 for (ep = Image->ExtensionBlocks;
00251 ep < Image->ExtensionBlocks + Image->ExtensionBlockCount;
00252 ep++)
00253 (void) free((char *)ep->Bytes);
00254 free((char *)Image->ExtensionBlocks);
00255 Image->ExtensionBlocks = NULL;
00256 }
00257
00258
00259
00260
00261 SavedImage *MakeSavedImage(GifFileType *GifFile, const SavedImage *CopyFrom)
00262
00263
00264
00265 {
00266 SavedImage *sp;
00267
00268 if (GifFile->SavedImages == NULL)
00269 GifFile->SavedImages = (SavedImage *)malloc(sizeof(SavedImage));
00270 else
00271 GifFile->SavedImages = (SavedImage *)realloc(GifFile->SavedImages,
00272 sizeof(SavedImage) * (GifFile->ImageCount+1));
00273
00274 if (GifFile->SavedImages == NULL)
00275 return((SavedImage *)NULL);
00276 else
00277 {
00278 sp = &GifFile->SavedImages[GifFile->ImageCount++];
00279 memset((char *)sp, '\0', sizeof(SavedImage));
00280
00281 if (CopyFrom)
00282 {
00283 memcpy((char *)sp, CopyFrom, sizeof(SavedImage));
00284
00285
00286
00287
00288
00289
00290
00291
00292 if (sp->ImageDesc.ColorMap)
00293 sp->ImageDesc.ColorMap =
00294 MakeMapObject(CopyFrom->ImageDesc.ColorMap->ColorCount,
00295 CopyFrom->ImageDesc.ColorMap->Colors);
00296
00297
00298 sp->RasterBits = (char *)malloc(sizeof(GifPixelType)
00299 * CopyFrom->ImageDesc.Height
00300 * CopyFrom->ImageDesc.Width);
00301 memcpy(sp->RasterBits,
00302 CopyFrom->RasterBits,
00303 sizeof(GifPixelType)
00304 * CopyFrom->ImageDesc.Height
00305 * CopyFrom->ImageDesc.Width);
00306
00307
00308 if (sp->ExtensionBlocks)
00309 {
00310 sp->ExtensionBlocks
00311 = (ExtensionBlock*)malloc(sizeof(ExtensionBlock)
00312 * CopyFrom->ExtensionBlockCount);
00313 memcpy(sp->ExtensionBlocks,
00314 CopyFrom->ExtensionBlocks,
00315 sizeof(ExtensionBlock)
00316 * CopyFrom->ExtensionBlockCount);
00317
00318
00319
00320
00321
00322 }
00323 }
00324
00325 return(sp);
00326 }
00327 }
00328
00329 void FreeSavedImages(GifFileType *GifFile)
00330 {
00331 SavedImage *sp;
00332
00333 for (sp = GifFile->SavedImages;
00334 sp < GifFile->SavedImages + GifFile->ImageCount;
00335 sp++)
00336 {
00337 if (sp->ImageDesc.ColorMap)
00338 FreeMapObject(sp->ImageDesc.ColorMap);
00339
00340 if (sp->RasterBits)
00341 free((char *)sp->RasterBits);
00342
00343 if (sp->ExtensionBlocks)
00344 FreeExtension(sp);
00345 }
00346 free((char *) GifFile->SavedImages);
00347 }
00348
00349
00350