📄 gif.c
字号:
while (GetDataBlock(src, (unsigned char *) buf) != 0);
return FALSE;
}
static int ZeroDataBlock = FALSE;
static int
GetDataBlock(MG_RWops *src, unsigned char *buf)
{
unsigned char count;
if (!ReadOK(src, &count, 1))
return -1;
ZeroDataBlock = count == 0;
if ((count != 0) && (!ReadOK(src, buf, count)))
return -1;
return count;
}
static int
GetCode(MG_RWops *src, int code_size, int flag)
{
static unsigned char buf[280];
static int curbit, lastbit, done, last_byte;
int i, j, ret;
unsigned char count;
if (flag) {
curbit = 0;
lastbit = 0;
done = FALSE;
return 0;
}
if ((curbit + code_size) >= lastbit) {
if (done) {
if (curbit >= lastbit)
#ifdef _DEBUG
fprintf (stderr,"__mg_load_gif: bad decode\n");
#endif
return -1;
}
buf[0] = buf[last_byte - 2];
buf[1] = buf[last_byte - 1];
if ((count = GetDataBlock(src, &buf[2])) == 0)
done = TRUE;
last_byte = 2 + count;
curbit = (curbit - lastbit) + 16;
lastbit = (2 + count) * 8;
}
ret = 0;
for (i = curbit, j = 0; j < code_size; ++i, ++j)
ret |= ((buf[i / 8] & (1 << (i % 8))) != 0) << j;
curbit += code_size;
return ret;
}
static int
LWZReadByte(MG_RWops *src, int flag, int input_code_size)
{
int code, incode;
register int i;
static int fresh = FALSE;
static int code_size, set_code_size;
static int max_code, max_code_size;
static int firstcode, oldcode;
static int clear_code, end_code;
static int table[2][(1 << MAX_LWZ_BITS)];
static int stack[(1 << (MAX_LWZ_BITS)) * 2], *sp;
if (flag) {
set_code_size = input_code_size;
code_size = set_code_size + 1;
clear_code = 1 << set_code_size;
end_code = clear_code + 1;
max_code_size = 2 * clear_code;
max_code = clear_code + 2;
GetCode(src, 0, TRUE);
fresh = TRUE;
for (i = 0; i < clear_code; ++i) {
table[0][i] = 0;
table[1][i] = i;
}
for (; i < (1 << MAX_LWZ_BITS); ++i)
table[0][i] = table[1][0] = 0;
sp = stack;
return 0;
} else if (fresh) {
fresh = FALSE;
do {
firstcode = oldcode = GetCode(src, code_size, FALSE);
} while (firstcode == clear_code);
return firstcode;
}
if (sp > stack)
return *--sp;
while ((code = GetCode(src, code_size, FALSE)) >= 0) {
if (code == clear_code) {
for (i = 0; i < clear_code; ++i) {
table[0][i] = 0;
table[1][i] = i;
}
for (; i < (1 << MAX_LWZ_BITS); ++i)
table[0][i] = table[1][i] = 0;
code_size = set_code_size + 1;
max_code_size = 2 * clear_code;
max_code = clear_code + 2;
sp = stack;
firstcode = oldcode = GetCode(src, code_size, FALSE);
return firstcode;
} else if (code == end_code) {
int count;
unsigned char buf[260];
if (ZeroDataBlock)
return -2;
while ((count = GetDataBlock(src, buf)) > 0);
if (count != 0) {
/*
* fprintf (stderr,"missing EOD in data stream (common occurence)");
*/
}
return -2;
}
incode = code;
if (code >= max_code) {
*sp++ = firstcode;
code = oldcode;
}
while (code >= clear_code) {
*sp++ = table[1][code];
if (code == table[0][code])
fprintf (stderr, "__mg_load_gif: circular table entry\n");
code = table[0][code];
}
*sp++ = firstcode = table[1][code];
if ((code = max_code) < (1 << MAX_LWZ_BITS)) {
table[0][code] = oldcode;
table[1][code] = firstcode;
++max_code;
if ((max_code >= max_code_size) &&
(max_code_size < (1 << MAX_LWZ_BITS))) {
max_code_size *= 2;
++code_size;
}
}
oldcode = incode;
if (sp > stack)
return *--sp;
}
return code;
}
static int
ReadImage(MG_RWops* src, MYBITMAP* bmp, RGB* pal, int len, int height, int cmapSize,
unsigned char cmap[3][MAXCOLORMAPSIZE],
int gray, int interlace, int ignore)
{
unsigned char c;
int i, v;
int xpos = 0, ypos = 0, pass = 0;
/*
* Initialize the compression routines
*/
if (!ReadOK(src, &c, 1)) {
fprintf (stderr,"__mg_load_gif: EOF on image data\n");
return 0;
}
if (LWZReadByte(src, TRUE, c) < 0) {
fprintf (stderr,"__mg_load_gif: error reading image\n");
return 0;
}
/*
* If this is an "uninteresting picture" ignore it.
*/
if (ignore) {
while (LWZReadByte(src, FALSE, c) >= 0);
return 0;
}
/*image = ImageNewCmap(len, height, cmapSize);*/
bmp->w = len;
bmp->h = height;
bmp->frames = 1;
bmp->depth = 8;
bmpComputePitch (8, len, &bmp->pitch, TRUE);
bmp->bits = malloc (height * bmp->pitch);
if(!bmp->bits)
return 0;
for (i = 0; i < cmapSize; i++) {
/*ImageSetCmap(image, i, cmap[CM_RED][i],
cmap[CM_GREEN][i], cmap[CM_BLUE][i]);*/
pal[i].r = cmap[CM_RED][i];
pal[i].g = cmap[CM_GREEN][i];
pal[i].b = cmap[CM_BLUE][i];
}
while ((v = LWZReadByte(src, FALSE, c)) >= 0) {
bmp->bits[ypos * bmp->pitch + xpos] = v;
++xpos;
if (xpos == len) {
xpos = 0;
if (interlace) {
switch (pass) {
case 0:
case 1:
ypos += 8;
break;
case 2:
ypos += 4;
break;
case 3:
ypos += 2;
break;
}
if (ypos >= height) {
++pass;
switch (pass) {
case 1:
ypos = 4;
break;
case 2:
ypos = 2;
break;
case 3:
ypos = 1;
break;
default:
goto fini;
}
}
} else {
++ypos;
}
}
if (ypos >= height)
break;
}
fini:
return 1;
}
BOOL __mg_check_gif (MG_RWops* fp)
{
char buf[16];
char version[4];
if (!ReadOK (fp, buf, 6))
return FALSE; /* not gif image*/
if (strncmp(buf, "GIF", 3) != 0)
return FALSE;
strncpy (version, buf + 3, 3);
version [3] = '\0';
if (strcmp(version, "87a") != 0 && strcmp(version, "89a") != 0) {
return FALSE; /* image loading error*/
}
return TRUE;
}
#endif /* _GIF_FILE_SUPPORT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -