📄 gifloader.cpp
字号:
#include "stdafx.h"
#include "mmi.h"
extern U32 image_static_row_data[];
extern U32 image_static_palette[];
extern U32 image_static_buffer[];
/*****************************************************************************
* FUNCTION
* GIF_get_byte
* DESCRIPTION
*
* PARAMETERS
* file [?]
* RETURNS
*
*****************************************************************************/
static U8 GIF_get_byte(bytestream *file)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
return (bytestream_fgetbyte(file));
}
/*****************************************************************************
* FUNCTION
* GIF_write_line
* DESCRIPTION
*
* PARAMETERS
* ix [IN]
* iy [IN]
* b [?]
* buffer [?]
* length [IN]
* y [IN]
* palette [?]
* transparent_GIF [IN]
* transparent_color_index [IN]
* RETURNS
* void
*****************************************************************************/
static void GIF_write_line(
S32 ix,
S32 iy,
bitmap *b,
U8 *buffer,
S16 length,
S16 y,
U8 palette[][3],
U8 transparent_GIF,
U8 transparent_color_index)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
if (b == NULL)
{
return;
}
if (transparent_GIF)
{
{
S32 i;
U8 color_index;
U32 offset = (y + iy) * b->xsize + ix;
U16 *bitmap_data = (U16*) b->data;
U16 d;
for (i = 0; i < length; i++)
{
color_index = (U8) buffer[i];
d = MMI_RGB_TO_HW_FORMAT(palette[color_index][0], palette[color_index][1], palette[color_index][2]);
if (color_index == transparent_color_index)
{
SET_RGB_TRANSPARENT_COLOR_16(d);
}
bitmap_data[offset++] = d;
}
}
}
else
{
{
S32 i;
U8 color_index;
U32 offset = (y + iy) * b->xsize + ix;
U16 *bitmap_data = (U16*) b->data;
U16 d;
for (i = 0; i < length; i++)
{
color_index = (U8) buffer[i];
d = MMI_RGB_TO_HW_FORMAT(palette[color_index][0], palette[color_index][1], palette[color_index][2]);
bitmap_data[offset++] = d;
}
}
}
}
#define GIF_MAX_CODES 4095
S16 GIF_current_code_size, GIF_clear_code, GIF_end_code, GIF_new_codes, GIF_top_slot, GIF_slot;
S16 GIF_navailable_bytes, GIF_nbits_left, GIF_b1;
U8 GIF_byte_buffer[257], *GIF_pbytes;
U16 GIF_code_mask[13] = {0x0000,
0x0001, 0x0003,
0x0007, 0x000f,
0x001f, 0x003f,
0x007f, 0x00ff,
0x01ff, 0x03ff,
0x07ff, 0x0fff
};
/*****************************************************************************
* FUNCTION
* GIF_initialize_decoder
* DESCRIPTION
*
* PARAMETERS
* size [IN]
* RETURNS
* void
*****************************************************************************/
static void GIF_initialize_decoder(S16 size)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
GIF_current_code_size = (S16) (size + 1);
GIF_top_slot = (S16) (1 << GIF_current_code_size);
GIF_clear_code = (S16) (1 << size);
GIF_end_code = (S16) (GIF_clear_code + 1);
GIF_slot = (GIF_new_codes) = (S16) (GIF_end_code + 1);
GIF_navailable_bytes = GIF_nbits_left = (S16) 0;
}
/*****************************************************************************
* FUNCTION
* GIF_get_next_code
* DESCRIPTION
*
* PARAMETERS
* file [?]
* RETURNS
*
*****************************************************************************/
static S16 GIF_get_next_code(bytestream *file)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
S16 i, x, ret;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
if (GIF_nbits_left == 0)
{
if (GIF_navailable_bytes <= 0)
{
GIF_pbytes = GIF_byte_buffer;
GIF_navailable_bytes = GIF_get_byte(file);
if (GIF_navailable_bytes < 0)
{
return (GIF_navailable_bytes);
}
else if (GIF_navailable_bytes > 0)
{
for (i = 0; i < GIF_navailable_bytes; i++)
{
x = GIF_get_byte(file);
if (x < 0)
{
return (x);
}
GIF_byte_buffer[i] = (U8) x;
}
}
}
GIF_b1 = *GIF_pbytes++;
GIF_nbits_left = 8;
GIF_navailable_bytes--;
}
ret = (S16) (GIF_b1 >> (8 - GIF_nbits_left));
while (GIF_current_code_size > GIF_nbits_left)
{
if (GIF_navailable_bytes <= 0)
{
GIF_pbytes = GIF_byte_buffer;
GIF_navailable_bytes = GIF_get_byte(file);
if (GIF_navailable_bytes < 0)
{
return (GIF_navailable_bytes);
}
else if (GIF_navailable_bytes > 0)
{
for (i = 0; i < GIF_navailable_bytes; i++)
{
x = GIF_get_byte(file);
if (x < 0)
{
return (x);
}
GIF_byte_buffer[i] = (U8) x;
}
}
}
GIF_b1 = *GIF_pbytes++;
ret |= GIF_b1 << GIF_nbits_left;
GIF_nbits_left += 8;
GIF_navailable_bytes--;
}
GIF_nbits_left = (S16) (GIF_nbits_left - GIF_current_code_size);
ret &= GIF_code_mask[GIF_current_code_size];
return (ret);
}
S16 GIF_stack[GIF_MAX_CODES + 1];
S16 GIF_suffix[GIF_MAX_CODES + 1];
S16 GIF_prefix[GIF_MAX_CODES + 1];
/*****************************************************************************
* FUNCTION
* GIF_interlace_pass
* DESCRIPTION
*
* PARAMETERS
* y [?]
* pass [?]
* ysize [IN]
* RETURNS
* void
*****************************************************************************/
static void GIF_interlace_pass(S16 *y, S16 *pass, S16 ysize)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
switch (*pass)
{
case 0:
(*y) += 8;
if (*y >= ysize)
{
*y = 4;
(*pass)++;
}
break;
case 1:
(*y) += 8;
if (*y >= ysize)
{
*y = 2;
(*pass)++;
}
break;
case 2:
(*y) += 4;
if (*y >= ysize)
{
*y = 1;
(*pass)++;
}
break;
case 3:
(*y) += 2;
break;
}
}
/*****************************************************************************
* FUNCTION
* GIF_decoder
* DESCRIPTION
*
* PARAMETERS
* ix [IN]
* iy [IN]
* file [?]
* b [?]
* xsize [IN]
* ysize [IN]
* interlaced [IN]
* palette [?]
* transparent_GIF [IN]
* transparent_color_index [IN]
* RETURNS
* void
*****************************************************************************/
static void GIF_decoder(
S32 ix,
S32 iy,
bytestream *file,
bitmap *b,
S16 xsize,
S16 ysize,
U8 interlaced,
U8 palette[][3],
U8 transparent_GIF,
U8 transparent_color_index)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
S16 *stack_pointer;
U8 *buffer_pointer;
U8 *buffer;
S16 code, fc, oc, buffer_count, c, size, y = 0, pass = 0;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
size = GIF_get_byte(file);
if (size < 0)
{
return;
}
GIF_initialize_decoder(size);
oc = fc = 0;
buffer = (U8*) image_static_row_data;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -