-
Notifications
You must be signed in to change notification settings - Fork 16
/
in_gif.cpp
103 lines (84 loc) · 3.47 KB
/
in_gif.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
* in_gif.cpp -- read a Compuserve GIF file
* by [email protected] at Fri Mar 1 22:28:46 CET 2002
*
*/
/*The creators of the GIF format require the following
acknowledgement:
The Graphics Interchange Format(c) is the Copyright property of
CompuServe Incorporated. GIF(sm) is a Service Mark property of
CompuServe Incorporated.
*/
#ifdef __GNUC__
#ifndef __clang__
#pragma implementation
#endif
#endif
#ifdef USE_GNU_SOURCE_INSTEAD_OF_POSIX_SOURCE
#define _GNU_SOURCE 1 /* Implies _POSIX_C_SOURCE and _POSIX_C_SOURCE >= 2. */
#else
#define _POSIX_SOURCE 1
#define _POSIX_C_SOURCE 2
#endif
#include "config2.h" /* SUXX, ignores features.h */
#if USE_IN_GIF
#include "cgif.h"
#include "cgif.c" /* _POSIX_SOURCE */
#include "image.hpp"
#include "error.hpp"
#include "gensio.hpp"
#undef CGIFFF
#define CGIFFF CGIF::
static void *xmalloc(size_t size) {
void *result = malloc(size + (size == 0));
if (!result) Error::sev(Error::EERROR) << "GIF: out of memory" << (Error*)0;
return result;
}
static void *xrealloc(void *ptr, size_t size) {
void *result = realloc(ptr, size + (size == 0));
if (!result) Error::sev(Error::EERROR) << "GIF: out of memory" << (Error*)0;
return result;
}
static Image::Sampled *in_gif_reader(Image::Loader::UFD *ufd, SimBuffer::Flat const&) {
Image::Indexed *img;
CGIFFF GifFileType *giff;
CGIFFF SavedImage *sp;
CGIFFF ColorMapObject *cm;
char const *err;
/* Dat: (CGIFFF GetGifError() || "unknown error") doesn't work like in Perl or Ruby */
if (0==(giff=CGIFFF DGifOpenFILE(((Filter::UngetFILED*)ufd)->getFILE(/*seekable:*/false))) || GIF_ERROR==CGIFFF DGifSlurp(giff))
Error::sev(Error::EERROR) << "GIF: " << ((err=CGIFFF GetGifError()) ? err : "unknown error") << (Error*)0;
if (giff->ImageCount<1)
Error::sev(Error::EERROR) << "GIF: no image in file" << (Error*)0;
sp=giff->SavedImages+0;
cm = (sp->ImageDesc.ColorMap ? sp->ImageDesc.ColorMap : giff->SColorMap);
img=new Image::Indexed(sp->ImageDesc.Width, sp->ImageDesc.Height, cm->ColorCount, 8);
CGIFFF GifColorType *co=cm->Colors, *ce=co+cm->ColorCount;
char *p=img->getHeadp();
while (co!=ce) { *p++=(char)co->Red; *p++=(char)co->Green; *p++=(char)co->Blue; co++; }
// fprintf(stderr, "transp=%d\n", sp->transp);
if (sp->transp!=-1) img->setTransp(sp->transp);
/* ^^^ comment out this line to ignore transparency of the GIF file */
assert(1L*sp->ImageDesc.Width*sp->ImageDesc.Height<=img->end_()-img->getRowbeg());
memcpy(img->getRowbeg(), sp->RasterBits, (slen_t)sp->ImageDesc.Width*sp->ImageDesc.Height);
CGIFFF DGifCloseFile(giff); /* also frees memory structure */
return img;
}
static Image::Loader::reader_t in_gif_checker(char buf[Image::Loader::MAGIC_LEN], char [Image::Loader::MAGIC_LEN], SimBuffer::Flat const&, Image::Loader::UFD*) {
return (0==memcmp(buf,"GIF87a",6) || 0==memcmp(buf,"GIF89a",6)) ? in_gif_reader : 0;
}
#define in_gif_name "GIF"
#else
#include <string.h>
#include "image.hpp"
#include "error.hpp"
#define in_gif_name (char const*)NULLP
/* #define in_gif_checker (Image::Loader::checker_t)NULLP */
static Image::Loader::reader_t in_gif_checker(char buf[Image::Loader::MAGIC_LEN], char [Image::Loader::MAGIC_LEN], SimBuffer::Flat const&, Image::Loader::UFD*) {
if (0==memcmp(buf,"GIF87a",6) || 0==memcmp(buf,"GIF89a",6)) {
Error::sev(Error::WARNING) << "loader: please `configure --enable-gif' for loading GIF files" << (Error*)0;
}
return 0;
}
#endif /* USE_IN_GIF */
Image::Loader in_gif_loader = { in_gif_name, in_gif_checker, 0 };