source: trunk/src/oleaut32/libgif/gifalloc.c@ 10366

Last change on this file since 10366 was 10266, checked in by sandervl, 22 years ago

PF: GIF and JPEG static libs for IPicture interface implementation

File size: 9.3 KB
Line 
1/*****************************************************************************
2* "Gif-Lib" - Yet another gif library. *
3* *
4* Written by: Gershon Elber Ver 0.1, Jun. 1989 *
5* Extensively hacked by: Eric S. Raymond Ver 1.?, Sep 1992 *
6******************************************************************************
7* GIF construction tools *
8******************************************************************************
9* History: *
10* 15 Sep 92 - Version 1.0 by Eric Raymond. *
11*****************************************************************************/
12#include <stdlib.h>
13#include <stdio.h>
14#include <string.h>
15#include <malloc.h>
16#include "gif_lib.h"
17
18#define MAX(x, y) (((x) > (y)) ? (x) : (y))
19
20/******************************************************************************
21* Miscellaneous utility functions *
22******************************************************************************/
23
24int BitSize(int n)
25/* return smallest bitfield size n will fit in */
26{
27 register i;
28
29 for (i = 1; i <= 8; i++)
30 if ((1 << i) >= n)
31 break;
32 return(i);
33}
34
35
36/******************************************************************************
37* Color map object functions *
38******************************************************************************/
39
40ColorMapObject *MakeMapObject(int ColorCount, GifColorType *ColorMap)
41/*
42 * Allocate a color map of given size; initialize with contents of
43 * ColorMap if that pointer is non-NULL.
44 */
45{
46 ColorMapObject *Object;
47
48 if (ColorCount != (1 << BitSize(ColorCount)))
49 return((ColorMapObject *)NULL);
50
51 Object = (ColorMapObject *)malloc(sizeof(ColorMapObject));
52 if (Object == (ColorMapObject *)NULL)
53 return((ColorMapObject *)NULL);
54
55 Object->Colors = (GifColorType *)calloc(ColorCount, sizeof(GifColorType));
56 if (Object->Colors == (GifColorType *)NULL)
57 return((ColorMapObject *)NULL);
58
59 Object->ColorCount = ColorCount;
60 Object->BitsPerPixel = BitSize(ColorCount);
61
62 if (ColorMap)
63 memcpy((char *)Object->Colors,
64 (char *)ColorMap, ColorCount * sizeof(GifColorType));
65
66 return(Object);
67}
68
69void FreeMapObject(ColorMapObject *Object)
70/*
71 * Free a color map object
72 */
73{
74 free(Object->Colors);
75 free(Object);
76}
77
78#ifdef DEBUG
79void DumpColorMap(ColorMapObject *Object, FILE *fp)
80{
81 if (Object)
82 {
83 int i, j, Len = Object->ColorCount;
84
85 for (i = 0; i < Len; i+=4) {
86 for (j = 0; j < 4 && j < Len; j++) {
87 fprintf(fp,
88 "%3d: %02x %02x %02x ", i + j,
89 Object->Colors[i + j].Red,
90 Object->Colors[i + j].Green,
91 Object->Colors[i + j].Blue);
92 }
93 fprintf(fp, "\n");
94 }
95 }
96}
97#endif /* DEBUG */
98
99ColorMapObject *UnionColorMap(
100 ColorMapObject *ColorIn1,
101 ColorMapObject *ColorIn2,
102 GifPixelType ColorTransIn2[])
103/*
104 * Compute the union of two given color maps and return it. If result can't
105 * fit into 256 colors, NULL is returned, the allocated union otherwise.
106 * ColorIn1 is copied as is to ColorUnion, while colors from ColorIn2 are
107 * copied iff they didn't exist before. ColorTransIn2 maps the old
108 * ColorIn2 into ColorUnion color map table.
109 */
110{
111 int i, j, CrntSlot, RoundUpTo, NewBitSize;
112 ColorMapObject *ColorUnion;
113
114 /*
115 * Allocate table which will hold the result for sure.
116 */
117 ColorUnion
118 = MakeMapObject(MAX(ColorIn1->ColorCount,ColorIn2->ColorCount)*2,NULL);
119
120 if (ColorUnion == NULL)
121 return(NULL);
122
123 /* Copy ColorIn1 to ColorUnionSize; */
124 for (i = 0; i < ColorIn1->ColorCount; i++)
125 ColorUnion->Colors[i] = ColorIn1->Colors[i];
126 CrntSlot = ColorIn1->ColorCount;
127
128 /*
129 * Potentially obnoxious hack:
130 *
131 * Back CrntSlot down past all contiguous {0, 0, 0} slots at the end
132 * of table 1. This is very useful if your display is limited to
133 * 16 colors.
134 */
135 while (ColorIn1->Colors[CrntSlot-1].Red == 0
136 && ColorIn1->Colors[CrntSlot-1].Green == 0
137 && ColorIn1->Colors[CrntSlot-1].Red == 0)
138 CrntSlot--;
139
140 /* Copy ColorIn2 to ColorUnionSize (use old colors if they exist): */
141 for (i = 0; i < ColorIn2->ColorCount && CrntSlot<=256; i++)
142 {
143 /* Let's see if this color already exists: */
144 for (j = 0; j < ColorIn1->ColorCount; j++)
145 if (memcmp(&ColorIn1->Colors[j], &ColorIn2->Colors[i], sizeof(GifColorType)) == 0)
146 break;
147
148 if (j < ColorIn1->ColorCount)
149 ColorTransIn2[i] = j; /* color exists in Color1 */
150 else
151 {
152 /* Color is new - copy it to a new slot: */
153 ColorUnion->Colors[CrntSlot] = ColorIn2->Colors[i];
154 ColorTransIn2[i] = CrntSlot++;
155 }
156 }
157
158 if (CrntSlot > 256)
159 {
160 FreeMapObject(ColorUnion);
161 return((ColorMapObject *)NULL);
162 }
163
164 NewBitSize = BitSize(CrntSlot);
165 RoundUpTo = (1 << NewBitSize);
166
167 if (RoundUpTo != ColorUnion->ColorCount)
168 {
169 register GifColorType *Map = ColorUnion->Colors;
170
171 /*
172 * Zero out slots up to next power of 2.
173 * We know these slots exist because of the way ColorUnion's
174 * start dimension was computed.
175 */
176 for (j = CrntSlot; j < RoundUpTo; j++)
177 Map[j].Red = Map[j].Green = Map[j].Blue = 0;
178
179 /* perhaps we can shrink the map? */
180 if (RoundUpTo < ColorUnion->ColorCount)
181 ColorUnion->Colors
182 = (GifColorType *)realloc(Map, sizeof(GifColorType)*RoundUpTo);
183 }
184
185 ColorUnion->ColorCount = RoundUpTo;
186 ColorUnion->BitsPerPixel = NewBitSize;
187
188 return(ColorUnion);
189}
190
191void ApplyTranslation(SavedImage *Image, GifPixelType Translation[])
192/*
193 * Apply a given color translation to the raster bits of an image
194 */
195{
196 register int i;
197 register int RasterSize = Image->ImageDesc.Height * Image->ImageDesc.Width;
198
199 for (i = 0; i < RasterSize; i++)
200 Image->RasterBits[i] = Translation[Image->RasterBits[i]];
201}
202
203/******************************************************************************
204* Extension record functions *
205******************************************************************************/
206
207void MakeExtension(SavedImage *New, int Function)
208{
209 New->Function = Function;
210 /*
211 * Someday we might have to deal with multiple extensions.
212 */
213}
214
215int AddExtensionBlock(SavedImage *New, int Len, char ExtData[])
216{
217 ExtensionBlock *ep;
218
219 if (New->ExtensionBlocks == NULL)
220 New->ExtensionBlocks = (ExtensionBlock *)malloc(sizeof(ExtensionBlock));
221 else
222 New->ExtensionBlocks =
223 (ExtensionBlock *)realloc(New->ExtensionBlocks,
224 sizeof(ExtensionBlock) * (New->ExtensionBlockCount + 1));
225
226 if (New->ExtensionBlocks == NULL)
227 return(GIF_ERROR);
228
229 ep = &New->ExtensionBlocks[New->ExtensionBlockCount++];
230
231 if ((ep->Bytes = (char *)malloc(ep->ByteCount = Len)) == NULL)
232 return(GIF_ERROR);
233
234 if (ExtData) {
235 memcpy(ep->Bytes, ExtData, Len);
236 ep->Function = New->Function;
237 }
238
239 return(GIF_OK);
240}
241
242void FreeExtension(SavedImage *Image)
243{
244 ExtensionBlock *ep;
245
246 for (ep = Image->ExtensionBlocks;
247 ep < Image->ExtensionBlocks + Image->ExtensionBlockCount;
248 ep++)
249 (void) free((char *)ep->Bytes);
250 free((char *)Image->ExtensionBlocks);
251 Image->ExtensionBlocks = NULL;
252}
253
254/******************************************************************************
255* Image block allocation functions *
256******************************************************************************/
257SavedImage *MakeSavedImage(GifFileType *GifFile, SavedImage *CopyFrom)
258/*
259 * Append an image block to the SavedImages array
260 */
261{
262 SavedImage *sp;
263
264 if (GifFile->SavedImages == NULL)
265 GifFile->SavedImages = (SavedImage *)malloc(sizeof(SavedImage));
266 else
267 GifFile->SavedImages = (SavedImage *)realloc(GifFile->SavedImages,
268 sizeof(SavedImage) * (GifFile->ImageCount+1));
269
270 if (GifFile->SavedImages == NULL)
271 return((SavedImage *)NULL);
272 else
273 {
274 sp = &GifFile->SavedImages[GifFile->ImageCount++];
275 memset((char *)sp, '\0', sizeof(SavedImage));
276
277 if (CopyFrom)
278 {
279 memcpy((char *)sp, CopyFrom, sizeof(SavedImage));
280
281 /*
282 * Make our own allocated copies of the heap fields in the
283 * copied record. This guards against potential aliasing
284 * problems.
285 */
286
287 /* first, the local color map */
288 if (sp->ImageDesc.ColorMap)
289 sp->ImageDesc.ColorMap =
290 MakeMapObject(CopyFrom->ImageDesc.ColorMap->ColorCount,
291 CopyFrom->ImageDesc.ColorMap->Colors);
292
293 /* next, the raster */
294 sp->RasterBits = (char *)malloc(sizeof(GifPixelType)
295 * CopyFrom->ImageDesc.Height
296 * CopyFrom->ImageDesc.Width);
297 memcpy(sp->RasterBits,
298 CopyFrom->RasterBits,
299 sizeof(GifPixelType)
300 * CopyFrom->ImageDesc.Height
301 * CopyFrom->ImageDesc.Width);
302
303 /* finally, the extension blocks */
304 if (sp->ExtensionBlocks)
305 {
306 sp->ExtensionBlocks
307 = (ExtensionBlock*)malloc(sizeof(ExtensionBlock)
308 * CopyFrom->ExtensionBlockCount);
309 memcpy(sp->ExtensionBlocks,
310 CopyFrom->ExtensionBlocks,
311 sizeof(ExtensionBlock)
312 * CopyFrom->ExtensionBlockCount);
313
314 /*
315 * For the moment, the actual blocks can take their
316 * chances with free(). We'll fix this later.
317 */
318 }
319 }
320
321 return(sp);
322 }
323}
324
325void FreeSavedImages(GifFileType *GifFile)
326{
327 SavedImage *sp;
328
329 for (sp = GifFile->SavedImages;
330 sp < GifFile->SavedImages + GifFile->ImageCount;
331 sp++)
332 {
333 if (sp->ImageDesc.ColorMap)
334 FreeMapObject(sp->ImageDesc.ColorMap);
335
336 if (sp->RasterBits)
337 free((char *)sp->RasterBits);
338
339 if (sp->ExtensionBlocks)
340 FreeExtension(sp);
341 }
342 free((char *) GifFile->SavedImages);
343}
344
345
346
Note: See TracBrowser for help on using the repository browser.