Gentoo Archives: gentoo-commits

From: "Robin H. Johnson (robbat2)" <robbat2@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo-x86 commit in x11-misc/xplanet/files: xplanet-1.3.0-giflib.patch
Date: Fri, 27 Dec 2013 22:55:11
Message-Id: 20131227225508.513812004C@flycatcher.gentoo.org
1 robbat2 13/12/27 22:55:08
2
3 Added: xplanet-1.3.0-giflib.patch
4 Log:
5 Bug #488406: newer giflib compile fixes.
6
7 (Portage version: 2.2.7/cvs/Linux x86_64, unsigned Manifest commit)
8
9 Revision Changes Path
10 1.1 x11-misc/xplanet/files/xplanet-1.3.0-giflib.patch
11
12 file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/x11-misc/xplanet/files/xplanet-1.3.0-giflib.patch?rev=1.1&view=markup
13 plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/x11-misc/xplanet/files/xplanet-1.3.0-giflib.patch?rev=1.1&content-type=text/plain
14
15 Index: xplanet-1.3.0-giflib.patch
16 ===================================================================
17 Fixes from upstream SVN, to support giflib-4.2 and giflib-5.
18
19 Index: src/libimage/gif.c
20 ===================================================================
21 --- src/libimage/gif.c (revision 184)
22 +++ src/libimage/gif.c (revision 186)
23 @@ -20,222 +20,581 @@
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 +#include <string.h>
28
29 #include <gif_lib.h>
30
31 /*
32 - A lot of this is based on the gif2rgb and rgb2gif codes in the libungif
33 - distribution.
34 + Based on the gif2rgb and rgb2gif codes in the libgif distribution.
35 */
36
37 int
38 read_gif(const char *filename, int *width, int *height, unsigned char **rgb)
39 {
40 - int interlace_offset[] = { 0, 4, 2, 1 };
41 - int interlace_jump[] = { 8, 8, 4, 2 };
42 - GifColorType *colormap;
43 - GifFileType *infile;
44 - GifRecordType record_type;
45 - GifRowType *buffer = NULL;
46 + int BackGround = 0;
47 + /* The way Interlaced image should be read - offsets and
48 + jumps... */
49 + int InterlacedOffset[] = { 0, 4, 2, 1 };
50 + int InterlacedJumps[] = { 8, 8, 4, 2 };
51 + ColorMapObject *ColorMap;
52
53 - int i, j;
54 - int color_index;
55 - unsigned char *ptr = NULL;
56 + int i, j, Size, Row, Col, Width, Height, ExtCode, Count;
57 + GifRecordType RecordType;
58 + GifByteType *Extension;
59 + GifRowType *ScreenBuffer;
60
61 - infile = DGifOpenFileName(filename);
62 + GifRowType GifRow;
63 + GifColorType *ColorMapEntry;
64 + unsigned char *BufferP;
65
66 - if (infile == NULL)
67 + GifFileType *GifFile;
68 +#if GIFLIB_MAJOR >= 5
69 + GifFile = DGifOpenFileName(filename, NULL);
70 +#else
71 + GifFile = DGifOpenFileName(filename);
72 +#endif
73 + if (GifFile == NULL) {
74 + fprintf(stderr, "Can't open GIF file %s\n", filename);
75 + return(0);
76 + }
77 + /* (Following comment was probably written on a 286 running under DOS.) */
78 + /* Allocate the screen as vector of column of rows. We can't allocate the*/
79 + /* whole screen at once, as this broken minded CPU can allocate up to */
80 + /* 64k at a time and our image can be bigger than that: */
81 + /* Note this screen is device independent - it's the screen defined by */
82 + /* the GIF file parameters. */
83 + if ((ScreenBuffer = (GifRowType *)
84 + malloc(GifFile->SHeight * sizeof(GifRowType))) == NULL)
85 {
86 - PrintGifError();
87 - return(0);
88 + fprintf(stderr, "Failed to allocate memory required, aborted.");
89 + return(0);
90 }
91
92 - do
93 + Size = GifFile->SWidth * sizeof(GifPixelType);/* Size in bytes one row.*/
94 + if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL) /* First row. */
95 {
96 - if (DGifGetRecordType(infile, &record_type) == GIF_ERROR)
97 - {
98 - PrintGifError();
99 - return(0);
100 + fprintf(stderr, "Failed to allocate memory required, aborted.");
101 + return(0);
102 + }
103 +
104 + for (i = 0; i < GifFile->SWidth; i++) /* Set its color to BackGround. */
105 + ScreenBuffer[0][i] = GifFile->SBackGroundColor;
106 + for (i = 1; i < GifFile->SHeight; i++) {
107 + /* Allocate the other rows, and set their color to background too: */
108 + if ((ScreenBuffer[i] = (GifRowType) malloc(Size)) == NULL)
109 + {
110 + fprintf(stderr, "Failed to allocate memory required, aborted.\n");
111 + return(0);
112 + }
113 +
114 + memcpy(ScreenBuffer[i], ScreenBuffer[0], Size);
115 + }
116 +
117 + /* Scan the content of the GIF file and load the image(s) in: */
118 + do {
119 + if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) {
120 + fprintf(stderr, "Can't read GIF file\n");
121 + return(0);
122 + }
123 + switch (RecordType) {
124 + case IMAGE_DESC_RECORD_TYPE:
125 + if (DGifGetImageDesc(GifFile) == GIF_ERROR) {
126 + return(0);
127 + }
128 + Row = GifFile->Image.Top; /* Image Position relative to Screen. */
129 + Col = GifFile->Image.Left;
130 + Width = GifFile->Image.Width;
131 + Height = GifFile->Image.Height;
132 + if (GifFile->Image.Left + GifFile->Image.Width > GifFile->SWidth ||
133 + GifFile->Image.Top + GifFile->Image.Height > GifFile->SHeight) {
134 + return(0);
135 + }
136 + if (GifFile->Image.Interlace) {
137 + /* Need to perform 4 passes on the images: */
138 + for (Count = i = 0; i < 4; i++)
139 + for (j = Row + InterlacedOffset[i]; j < Row + Height;
140 + j += InterlacedJumps[i]) {
141 + if (DGifGetLine(GifFile, &ScreenBuffer[j][Col],
142 + Width) == GIF_ERROR) {
143 + return(0);
144 + }
145 + }
146 + }
147 + else {
148 + for (i = 0; i < Height; i++) {
149 + if (DGifGetLine(GifFile, &ScreenBuffer[Row++][Col],
150 + Width) == GIF_ERROR) {
151 + return(0);
152 + }
153 + }
154 + }
155 + break;
156 + case EXTENSION_RECORD_TYPE:
157 + /* Skip any extension blocks in file: */
158 + if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) {
159 + return(0);
160 + }
161 + while (Extension != NULL) {
162 + if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) {
163 + return(0);
164 + }
165 + }
166 + break;
167 + case TERMINATE_RECORD_TYPE:
168 + break;
169 + default: /* Should be traps by DGifGetRecordType. */
170 + break;
171 + }
172 + } while (RecordType != TERMINATE_RECORD_TYPE);
173 +
174 + /* Lets dump it - set the global variables required and do it: */
175 + BackGround = GifFile->SBackGroundColor;
176 + ColorMap = (GifFile->Image.ColorMap
177 + ? GifFile->Image.ColorMap
178 + : GifFile->SColorMap);
179 + if (ColorMap == NULL) {
180 + fprintf(stderr, "Gif Image does not have a colormap\n");
181 + return(0);
182 + }
183 +
184 + *width = GifFile->SWidth;
185 + *height = GifFile->SHeight;
186 +
187 + rgb[0] = malloc(3 * *width * *height);
188 + if (rgb[0] == NULL)
189 + {
190 + fprintf(stderr, "Can't allocate memory for GIF file.\n");
191 + return(0);
192 + }
193 +
194 + BufferP = rgb[0];
195 +
196 + for (i = 0; i < *height; i++) {
197 + GifRow = ScreenBuffer[i];
198 + for (j = 0; j < *width; j++) {
199 + ColorMapEntry = &ColorMap->Colors[GifRow[j]];
200 + *BufferP++ = ColorMapEntry->Red;
201 + *BufferP++ = ColorMapEntry->Green;
202 + *BufferP++ = ColorMapEntry->Blue;
203 + }
204 + }
205 +
206 + if (DGifCloseFile(GifFile) == GIF_ERROR) {
207 + return(0);
208 + }
209 +
210 + return(1);
211 +}
212 +
213 +/* Make some variables global, so we could access them faster: */
214 +static int
215 + ExpNumOfColors = 8,
216 + ColorMapSize = 256;
217 +
218 +/******************************************************************************
219 + * Code to quantize high resolution image into lower one. You may want to
220 + * peek into the following article this code is based on:
221 + * "Color Image Quantization for frame buffer Display", by Paul Heckbert
222 + * SIGGRAPH 1982 page 297-307.
223 + ******************************************************************************
224 + * History:
225 + * 5 Jan 90 - Version 1.0 by Gershon Elber.
226 + *****************************************************************************/
227 +
228 +#define ABS(x) ((x) > 0 ? (x) : (-(x)))
229 +
230 +#define COLOR_ARRAY_SIZE 32768
231 +#define BITS_PER_PRIM_COLOR 5
232 +#define MAX_PRIM_COLOR 0x1f
233 +
234 +static int SortRGBAxis;
235 +
236 +typedef struct QuantizedColorType {
237 + GifByteType RGB[3];
238 + GifByteType NewColorIndex;
239 + long Count;
240 + struct QuantizedColorType *Pnext;
241 +} QuantizedColorType;
242 +
243 +typedef struct NewColorMapType {
244 + GifByteType RGBMin[3], RGBWidth[3];
245 + unsigned int NumEntries; /* # of QuantizedColorType in linked list below */
246 + unsigned long Count; /* Total number of pixels in all the entries */
247 + QuantizedColorType *QuantizedColors;
248 +} NewColorMapType;
249 +
250 +static int SubdivColorMap(NewColorMapType * NewColorSubdiv,
251 + unsigned int ColorMapSize,
252 + unsigned int *NewColorMapSize);
253 +static int SortCmpRtn(const void *Entry1, const void *Entry2);
254 +
255 +/******************************************************************************
256 + * Quantize high resolution image into lower one. Input image consists of a
257 + * 2D array for each of the RGB colors with size Width by Height. There is no
258 + * Color map for the input. Output is a quantized image with 2D array of
259 + * indexes into the output color map.
260 + * Note input image can be 24 bits at the most (8 for red/green/blue) and
261 + * the output has 256 colors at the most (256 entries in the color map.).
262 + * ColorMapSize specifies size of color map up to 256 and will be updated to
263 + * real size before returning.
264 + * Also non of the parameter are allocated by this routine.
265 + * This function returns GIF_OK if succesfull, GIF_ERROR otherwise.
266 + ******************************************************************************/
267 +static int
268 +QuantizeBuffer(unsigned int Width,
269 + unsigned int Height,
270 + int *ColorMapSize,
271 + GifByteType * RedInput,
272 + GifByteType * GreenInput,
273 + GifByteType * BlueInput,
274 + GifByteType * OutputBuffer,
275 + GifColorType * OutputColorMap) {
276 +
277 + unsigned int Index, NumOfEntries;
278 + int i, j, MaxRGBError[3];
279 + unsigned int NewColorMapSize;
280 + long Red, Green, Blue;
281 + NewColorMapType NewColorSubdiv[256];
282 + QuantizedColorType *ColorArrayEntries, *QuantizedColor;
283 +
284 + ColorArrayEntries = (QuantizedColorType *)malloc(
285 + sizeof(QuantizedColorType) * COLOR_ARRAY_SIZE);
286 + if (ColorArrayEntries == NULL) {
287 + return GIF_ERROR;
288 + }
289 +
290 + for (i = 0; i < COLOR_ARRAY_SIZE; i++) {
291 + ColorArrayEntries[i].RGB[0] = i >> (2 * BITS_PER_PRIM_COLOR);
292 + ColorArrayEntries[i].RGB[1] = (i >> BITS_PER_PRIM_COLOR) &
293 + MAX_PRIM_COLOR;
294 + ColorArrayEntries[i].RGB[2] = i & MAX_PRIM_COLOR;
295 + ColorArrayEntries[i].Count = 0;
296 + }
297 +
298 + /* Sample the colors and their distribution: */
299 + for (i = 0; i < (int)(Width * Height); i++) {
300 + Index = ((RedInput[i] >> (8 - BITS_PER_PRIM_COLOR)) <<
301 + (2 * BITS_PER_PRIM_COLOR)) +
302 + ((GreenInput[i] >> (8 - BITS_PER_PRIM_COLOR)) <<
303 + BITS_PER_PRIM_COLOR) +
304 + (BlueInput[i] >> (8 - BITS_PER_PRIM_COLOR));
305 + ColorArrayEntries[Index].Count++;
306 + }
307 +
308 + /* Put all the colors in the first entry of the color map, and call the
309 + * recursive subdivision process. */
310 + for (i = 0; i < 256; i++) {
311 + NewColorSubdiv[i].QuantizedColors = NULL;
312 + NewColorSubdiv[i].Count = NewColorSubdiv[i].NumEntries = 0;
313 + for (j = 0; j < 3; j++) {
314 + NewColorSubdiv[i].RGBMin[j] = 0;
315 + NewColorSubdiv[i].RGBWidth[j] = 255;
316 }
317 + }
318
319 - switch (record_type)
320 - {
321 - case IMAGE_DESC_RECORD_TYPE:
322 - if (DGifGetImageDesc(infile) == GIF_ERROR)
323 - {
324 - PrintGifError();
325 - return(0);
326 + /* Find the non empty entries in the color table and chain them: */
327 + for (i = 0; i < COLOR_ARRAY_SIZE; i++)
328 + if (ColorArrayEntries[i].Count > 0)
329 + break;
330 + QuantizedColor = NewColorSubdiv[0].QuantizedColors = &ColorArrayEntries[i];
331 + NumOfEntries = 1;
332 + while (++i < COLOR_ARRAY_SIZE)
333 + if (ColorArrayEntries[i].Count > 0) {
334 + QuantizedColor->Pnext = &ColorArrayEntries[i];
335 + QuantizedColor = &ColorArrayEntries[i];
336 + NumOfEntries++;
337 + }
338 + QuantizedColor->Pnext = NULL;
339 +
340 + NewColorSubdiv[0].NumEntries = NumOfEntries; /* Different sampled colors */
341 + NewColorSubdiv[0].Count = ((long)Width) * Height; /* Pixels */
342 + NewColorMapSize = 1;
343 + if (SubdivColorMap(NewColorSubdiv, *ColorMapSize, &NewColorMapSize) !=
344 + GIF_OK) {
345 + free((char *)ColorArrayEntries);
346 + return GIF_ERROR;
347 + }
348 + if (NewColorMapSize < *ColorMapSize) {
349 + /* And clear rest of color map: */
350 + for (i = NewColorMapSize; i < *ColorMapSize; i++)
351 + OutputColorMap[i].Red = OutputColorMap[i].Green =
352 + OutputColorMap[i].Blue = 0;
353 + }
354 +
355 + /* Average the colors in each entry to be the color to be used in the
356 + * output color map, and plug it into the output color map itself. */
357 + for (i = 0; i < NewColorMapSize; i++) {
358 + if ((j = NewColorSubdiv[i].NumEntries) > 0) {
359 + QuantizedColor = NewColorSubdiv[i].QuantizedColors;
360 + Red = Green = Blue = 0;
361 + while (QuantizedColor) {
362 + QuantizedColor->NewColorIndex = i;
363 + Red += QuantizedColor->RGB[0];
364 + Green += QuantizedColor->RGB[1];
365 + Blue += QuantizedColor->RGB[2];
366 + QuantizedColor = QuantizedColor->Pnext;
367 }
368 + OutputColorMap[i].Red = (Red << (8 - BITS_PER_PRIM_COLOR)) / j;
369 + OutputColorMap[i].Green = (Green << (8 - BITS_PER_PRIM_COLOR)) / j;
370 + OutputColorMap[i].Blue = (Blue << (8 - BITS_PER_PRIM_COLOR)) / j;
371 + } else
372 + fprintf(stderr,
373 + "Null entry in quantized color map - that's weird.\n");
374 + }
375
376 - *width = infile->Image.Width;
377 - *height = infile->Image.Height;
378 + /* Finally scan the input buffer again and put the mapped index in the
379 + * output buffer. */
380 + MaxRGBError[0] = MaxRGBError[1] = MaxRGBError[2] = 0;
381 + for (i = 0; i < (int)(Width * Height); i++) {
382 + Index = ((RedInput[i] >> (8 - BITS_PER_PRIM_COLOR)) <<
383 + (2 * BITS_PER_PRIM_COLOR)) +
384 + ((GreenInput[i] >> (8 - BITS_PER_PRIM_COLOR)) <<
385 + BITS_PER_PRIM_COLOR) +
386 + (BlueInput[i] >> (8 - BITS_PER_PRIM_COLOR));
387 + Index = ColorArrayEntries[Index].NewColorIndex;
388 + OutputBuffer[i] = Index;
389 + if (MaxRGBError[0] < ABS(OutputColorMap[Index].Red - RedInput[i]))
390 + MaxRGBError[0] = ABS(OutputColorMap[Index].Red - RedInput[i]);
391 + if (MaxRGBError[1] < ABS(OutputColorMap[Index].Green - GreenInput[i]))
392 + MaxRGBError[1] = ABS(OutputColorMap[Index].Green - GreenInput[i]);
393 + if (MaxRGBError[2] < ABS(OutputColorMap[Index].Blue - BlueInput[i]))
394 + MaxRGBError[2] = ABS(OutputColorMap[Index].Blue - BlueInput[i]);
395 + }
396
397 - buffer = malloc(*height * sizeof(GifRowType *));
398 - if (buffer == NULL)
399 - {
400 - fprintf(stderr, "Can't allocate memory for GIF file.\n");
401 - return(0);
402 - }
403 -
404 - for (i = 0; i < *height; i++)
405 - {
406 - buffer[i] = malloc(*width * sizeof(GifPixelType));
407 - if (buffer[i] == NULL)
408 - {
409 - fprintf(stderr, "Can't allocate memory for GIF line.\n");
410 - return(0);
411 + free((char *)ColorArrayEntries);
412 +
413 + *ColorMapSize = NewColorMapSize;
414 +
415 + return GIF_OK;
416 +}
417 +
418 +/******************************************************************************
419 + * Routine to subdivide the RGB space recursively using median cut in each
420 + * axes alternatingly until ColorMapSize different cubes exists.
421 + * The biggest cube in one dimension is subdivide unless it has only one entry.
422 + * Returns GIF_ERROR if failed, otherwise GIF_OK.
423 + ******************************************************************************/
424 +static int
425 +SubdivColorMap(NewColorMapType * NewColorSubdiv,
426 + unsigned int ColorMapSize,
427 + unsigned int *NewColorMapSize) {
428 +
429 + int MaxSize;
430 + unsigned int i, j, Index = 0, NumEntries, MinColor, MaxColor;
431 + long Sum, Count;
432 + QuantizedColorType *QuantizedColor, **SortArray;
433 +
434 + while (ColorMapSize > *NewColorMapSize) {
435 + /* Find candidate for subdivision: */
436 + MaxSize = -1;
437 + for (i = 0; i < *NewColorMapSize; i++) {
438 + for (j = 0; j < 3; j++) {
439 + if ((((int)NewColorSubdiv[i].RGBWidth[j]) > MaxSize) &&
440 + (NewColorSubdiv[i].NumEntries > 1)) {
441 + MaxSize = NewColorSubdiv[i].RGBWidth[j];
442 + Index = i;
443 + SortRGBAxis = j;
444 }
445 }
446 -
447 - if (infile->Image.Interlace)
448 - {
449 - for (i = 0; i < 4; i++)
450 - for (j = interlace_offset[i]; j < *height;
451 - j += interlace_jump[i])
452 - DGifGetLine(infile, buffer[j], *width);
453 - }
454 - else
455 - {
456 - for (i = 0; i < *height; i++)
457 - DGifGetLine(infile, buffer[i], *width);
458 - }
459 - break;
460 - case EXTENSION_RECORD_TYPE:
461 - {
462 - /* Skip extension blocks */
463 - int ext_code;
464 - GifByteType *ext;
465 - if (DGifGetExtension(infile, &ext_code, &ext) == GIF_ERROR)
466 - {
467 - PrintGifError();
468 - return(0);
469 - }
470 - while (ext != NULL)
471 - {
472 - if (DGifGetExtensionNext(infile, &ext) == GIF_ERROR)
473 - {
474 - PrintGifError();
475 - return(0);
476 - }
477 - }
478 }
479 - break;
480 - case TERMINATE_RECORD_TYPE:
481 - break;
482 - default:
483 - fprintf(stderr, "unknown record type in GIF file\n");
484 - break;
485 - }
486 - } while (record_type != TERMINATE_RECORD_TYPE);
487
488 - colormap = (infile->Image.ColorMap ? infile->Image.ColorMap->Colors
489 - : infile->SColorMap->Colors);
490 + if (MaxSize == -1)
491 + return GIF_OK;
492
493 - rgb[0] = malloc(3 * *width * *height);
494 - if (rgb[0] == NULL)
495 - {
496 - fprintf(stderr, "Can't allocate memory for GIF file.\n");
497 - return(0);
498 - }
499 + /* Split the entry Index into two along the axis SortRGBAxis: */
500
501 - ptr = rgb[0];
502 + /* Sort all elements in that entry along the given axis and split at
503 + * the median. */
504 + SortArray = (QuantizedColorType **)malloc(
505 + sizeof(QuantizedColorType *) *
506 + NewColorSubdiv[Index].NumEntries);
507 + if (SortArray == NULL)
508 + return GIF_ERROR;
509 + for (j = 0, QuantizedColor = NewColorSubdiv[Index].QuantizedColors;
510 + j < NewColorSubdiv[Index].NumEntries && QuantizedColor != NULL;
511 + j++, QuantizedColor = QuantizedColor->Pnext)
512 + SortArray[j] = QuantizedColor;
513
514 - for (j = 0; j < *height; j++)
515 - {
516 - for (i = 0; i < *width; i++)
517 - {
518 - color_index = (int) buffer[j][i];
519 - *ptr++ = (unsigned char) colormap[color_index].Red;
520 - *ptr++ = (unsigned char) colormap[color_index].Green;
521 - *ptr++ = (unsigned char) colormap[color_index].Blue;
522 + qsort(SortArray, NewColorSubdiv[Index].NumEntries,
523 + sizeof(QuantizedColorType *), SortCmpRtn);
524 +
525 + /* Relink the sorted list into one: */
526 + for (j = 0; j < NewColorSubdiv[Index].NumEntries - 1; j++)
527 + SortArray[j]->Pnext = SortArray[j + 1];
528 + SortArray[NewColorSubdiv[Index].NumEntries - 1]->Pnext = NULL;
529 + NewColorSubdiv[Index].QuantizedColors = QuantizedColor = SortArray[0];
530 + free((char *)SortArray);
531 +
532 + /* Now simply add the Counts until we have half of the Count: */
533 + Sum = NewColorSubdiv[Index].Count / 2 - QuantizedColor->Count;
534 + NumEntries = 1;
535 + Count = QuantizedColor->Count;
536 + while (QuantizedColor->Pnext != NULL &&
537 + (Sum -= QuantizedColor->Pnext->Count) >= 0 &&
538 + QuantizedColor->Pnext->Pnext != NULL) {
539 + QuantizedColor = QuantizedColor->Pnext;
540 + NumEntries++;
541 + Count += QuantizedColor->Count;
542 }
543 - free(buffer[j]);
544 + /* Save the values of the last color of the first half, and first
545 + * of the second half so we can update the Bounding Boxes later.
546 + * Also as the colors are quantized and the BBoxes are full 0..255,
547 + * they need to be rescaled.
548 + */
549 + MaxColor = QuantizedColor->RGB[SortRGBAxis]; /* Max. of first half */
550 + /* coverity[var_deref_op] */
551 + MinColor = QuantizedColor->Pnext->RGB[SortRGBAxis]; /* of second */
552 + MaxColor <<= (8 - BITS_PER_PRIM_COLOR);
553 + MinColor <<= (8 - BITS_PER_PRIM_COLOR);
554 +
555 + /* Partition right here: */
556 + NewColorSubdiv[*NewColorMapSize].QuantizedColors =
557 + QuantizedColor->Pnext;
558 + QuantizedColor->Pnext = NULL;
559 + NewColorSubdiv[*NewColorMapSize].Count = Count;
560 + NewColorSubdiv[Index].Count -= Count;
561 + NewColorSubdiv[*NewColorMapSize].NumEntries =
562 + NewColorSubdiv[Index].NumEntries - NumEntries;
563 + NewColorSubdiv[Index].NumEntries = NumEntries;
564 + for (j = 0; j < 3; j++) {
565 + NewColorSubdiv[*NewColorMapSize].RGBMin[j] =
566 + NewColorSubdiv[Index].RGBMin[j];
567 + NewColorSubdiv[*NewColorMapSize].RGBWidth[j] =
568 + NewColorSubdiv[Index].RGBWidth[j];
569 + }
570 + NewColorSubdiv[*NewColorMapSize].RGBWidth[SortRGBAxis] =
571 + NewColorSubdiv[*NewColorMapSize].RGBMin[SortRGBAxis] +
572 + NewColorSubdiv[*NewColorMapSize].RGBWidth[SortRGBAxis] - MinColor;
573 + NewColorSubdiv[*NewColorMapSize].RGBMin[SortRGBAxis] = MinColor;
574 +
575 + NewColorSubdiv[Index].RGBWidth[SortRGBAxis] =
576 + MaxColor - NewColorSubdiv[Index].RGBMin[SortRGBAxis];
577 +
578 + (*NewColorMapSize)++;
579 }
580 -
581 - free(buffer);
582
583 - DGifCloseFile(infile);
584 - return(1);
585 + return GIF_OK;
586 }
587
588 +/****************************************************************************
589 + * Routine called by qsort to compare two entries.
590 + ****************************************************************************/
591 +static int
592 +SortCmpRtn(const void *Entry1,
593 + const void *Entry2) {
594 +
595 + return (*((QuantizedColorType **) Entry1))->RGB[SortRGBAxis] -
596 + (*((QuantizedColorType **) Entry2))->RGB[SortRGBAxis];
597 +}
598 +
599 +/******************************************************************************
600 +* Close output file (if open), and exit.
601 +******************************************************************************/
602 +static void QuitGifError(GifFileType *GifFile)
603 +{
604 + fprintf(stderr, "Error writing GIF file\n");
605 + if (GifFile != NULL) EGifCloseFile(GifFile);
606 +}
607 +
608 int
609 write_gif(const char *filename, int width, int height, char *rgb)
610 {
611 int i;
612 - int colormap_size = 256;
613 - GifByteType *red, *green, *blue, *buffer, *ptr;
614 - GifFileType *outfile;
615 - ColorMapObject *colormap;
616 + GifByteType *red, *green, *blue;
617
618 + GifByteType *OutputBuffer = NULL;
619 + ColorMapObject *OutputColorMap = NULL;
620 +
621 + GifFileType *GifFile;
622 + GifByteType *Ptr;
623 +
624 + bool GifTestExistance = false;
625 +
626 + ColorMapSize = 1 << ExpNumOfColors;
627 +
628 +#if GIFLIB_MAJOR >= 5
629 + OutputColorMap = GifMakeMapObject(ColorMapSize, NULL);
630 +#else
631 + OutputColorMap = MakeMapObject(ColorMapSize, NULL);
632 +#endif
633 +
634 + if (OutputColorMap == NULL ||
635 + (OutputBuffer = (GifByteType *) malloc(width * height *
636 + sizeof(GifByteType))) == NULL)
637 + {
638 + fprintf(stderr,"Failed to allocate memory required, aborted.");
639 + return(0);
640 + }
641 +
642 red = malloc(width * height * sizeof(GifByteType));
643 green = malloc(width * height * sizeof(GifByteType));
644 blue = malloc(width * height * sizeof(GifByteType));
645 - buffer = malloc(width * height * sizeof(GifByteType));
646 -
647 - if (red == NULL || green == NULL || blue == NULL || buffer == NULL)
648 + if (red == NULL || green == NULL || blue == NULL)
649 {
650 - fprintf(stderr, "Can't allocate memory for GIF file.\n");
651 - return(0);
652 + fprintf(stderr, "Can't allocate memory for GIF file.\n");
653 + return(0);
654 }
655 -
656 - colormap = MakeMapObject(colormap_size, NULL);
657 -
658 for (i = 0; i < width * height; i++)
659 {
660 - red[i] = (GifByteType) rgb[3*i ];
661 - green[i] = (GifByteType) rgb[3*i+1];
662 - blue[i] = (GifByteType) rgb[3*i+2];
663 + red[i] = (GifByteType) rgb[3*i ];
664 + green[i] = (GifByteType) rgb[3*i+1];
665 + blue[i] = (GifByteType) rgb[3*i+2];
666 }
667 -
668 - if (QuantizeBuffer(width, height, &colormap_size, red, green, blue,
669 - buffer, colormap->Colors) == GIF_ERROR)
670 +
671 + if (QuantizeBuffer(width, height, &ColorMapSize,
672 + red, green, blue,
673 + OutputBuffer, OutputColorMap->Colors) == GIF_ERROR)
674 +
675 {
676 - PrintGifError();
677 - return(0);
678 + QuitGifError(NULL);
679 + return(0);
680 }
681
682 free(red);
683 free(green);
684 free(blue);
685
686 - outfile = EGifOpenFileName((char *) filename, FALSE);
687 - if (outfile == NULL)
688 + Ptr = OutputBuffer;
689 +
690 +#if GIFLIB_MAJOR >= 5
691 + GifFile = EGifOpenFileName(filename, GifTestExistance, NULL);
692 +#else
693 + GifFile = EGifOpenFileName(filename, GifTestExistance);
694 +#endif
695 + /* Open stdout for the output file: */
696 + if (GifFile == NULL)
697 {
698 - PrintGifError();
699 - return(0);
700 + QuitGifError(GifFile);
701 + return(0);
702 }
703
704 - if (EGifPutScreenDesc(outfile, width, height, colormap_size, 0, colormap)
705 - == GIF_ERROR)
706 + if (EGifPutScreenDesc(GifFile,
707 + width, height, ExpNumOfColors, 0,
708 + OutputColorMap) == GIF_ERROR ||
709 + EGifPutImageDesc(GifFile,
710 + 0, 0, width, height, false, NULL) == GIF_ERROR)
711 +
712 {
713 - PrintGifError();
714 - return(0);
715 + QuitGifError(GifFile);
716 + return(0);
717 }
718
719 - if (EGifPutImageDesc(outfile, 0, 0, width, height, FALSE, NULL)
720 - == GIF_ERROR)
721 - {
722 - PrintGifError();
723 - return(0);
724 + for (i = 0; i < height; i++) {
725 + if (EGifPutLine(GifFile, Ptr, width) == GIF_ERROR)
726 +
727 + {
728 + QuitGifError(GifFile);
729 + return(0);
730 + }
731 + Ptr += width;
732 }
733
734 - ptr = buffer;
735 - for (i = 0; i < height; i++)
736 + if (EGifCloseFile(GifFile) == GIF_ERROR)
737 +
738 {
739 - if (EGifPutLine(outfile, ptr, width) == GIF_ERROR)
740 - {
741 - PrintGifError();
742 - return(0);
743 - }
744 - ptr += width;
745 + QuitGifError(GifFile);
746 + return(0);
747 }
748
749 - EGifSpew(outfile);
750 -
751 - if (EGifCloseFile(outfile) == GIF_ERROR)
752 - PrintGifError();
753 -
754 - free(buffer);
755 -
756 return(1);
757 }