7void WritePixel(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_pixelData,
short p_column,
short p_row,
byte p_pixel);
9 LPBITMAPINFOHEADER p_bitmapHeader,
16int ClampLine(LPBITMAPINFOHEADER p_bitmapHeader,
short& p_column,
short& p_row,
short& p_count);
18 LPBITMAPINFOHEADER p_bitmapHeader,
26 LPBITMAPINFOHEADER p_bitmapHeader,
34 LPBITMAPINFOHEADER p_bitmapHeader,
39 BYTE* p_decodedColorMap
43void DecodeColorPacket(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_data,
short p_index,
short p_count);
44void DecodeColors64(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_data);
45void DecodeBrun(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_pixelData, BYTE* p_data,
FLIC_HEADER* p_flcHeader);
46void DecodeLC(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_pixelData, BYTE* p_data,
FLIC_HEADER* p_flcHeader);
47void DecodeSS2(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_pixelData, BYTE* p_data,
FLIC_HEADER* p_flcHeader);
48void DecodeBlack(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_pixelData, BYTE* p_data,
FLIC_HEADER* p_flcHeader);
49void DecodeCopy(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_pixelData, BYTE* p_data,
FLIC_HEADER* p_flcHeader);
53void WritePixel(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_pixelData,
short p_column,
short p_row,
byte p_pixel)
55 if (p_column < 0 || p_row < 0 || p_column >= p_bitmapHeader->biWidth || p_row >= p_bitmapHeader->biHeight) {
59 *(((p_bitmapHeader->biWidth + 3) & -4) * p_row + p_column + p_pixelData) = p_pixel;
65 LPBITMAPINFOHEADER p_bitmapHeader,
74 short zcol = p_column;
76 if (!
ClampLine(p_bitmapHeader, p_column, p_row, p_count)) {
80 short offset = p_column - zcol;
85 BYTE* dest = ((p_bitmapHeader->biWidth + 3) & -4) * p_row + p_column + p_pixelData;
86 memcpy(dest, p_data, p_count);
91int ClampLine(LPBITMAPINFOHEADER p_bitmapHeader,
short& p_column,
short& p_row,
short& p_count)
93 short column = p_column;
95 short f_count = p_count;
96 short end = column + f_count;
98 if (a_row < 0 || p_bitmapHeader->biHeight <= a_row || end < 0 || p_bitmapHeader->biWidth <= column) {
108 if (p_bitmapHeader->biWidth < end) {
109 f_count -= end - (short) p_bitmapHeader->biWidth;
123 LPBITMAPINFOHEADER p_bitmapHeader,
131 if (!
ClampLine(p_bitmapHeader, p_column, p_row, p_count)) {
135 BYTE* dst = ((p_bitmapHeader->biWidth + 3) & -4) * p_row + p_column + p_pixelData;
137 while (--p_count >= 0) {
145 LPBITMAPINFOHEADER p_bitmapHeader,
155 if (!
ClampLine(p_bitmapHeader, p_column, p_row, p_count)) {
159 short is_odd = p_count & 1;
162 WORD* dst = (WORD*) (((p_bitmapHeader->biWidth + 3) & -4) * p_row + p_column + p_pixelData);
163 while (--p_count >= 0) {
168 BYTE* dst_byte = (BYTE*) dst;
176 LPBITMAPINFOHEADER p_bitmapHeader,
180 BYTE* p_flcSubchunks,
181 BYTE* p_decodedColorMap
184 *p_decodedColorMap =
FALSE;
186 for (
short subchunk = 0; subchunk < (short) p_flcFrame->
chunks; subchunk++) {
188 p_flcSubchunks += chunk->
size;
190 switch (chunk->
type) {
193 *p_decodedColorMap =
TRUE;
196 DecodeSS2(p_bitmapHeader, p_pixelData, (BYTE*) (chunk + 1), p_flcHeader);
200 *p_decodedColorMap =
TRUE;
203 DecodeLC(p_bitmapHeader, p_pixelData, (BYTE*) (chunk + 1), p_flcHeader);
206 DecodeBlack(p_bitmapHeader, p_pixelData, (BYTE*) (chunk + 1), p_flcHeader);
209 DecodeBrun(p_bitmapHeader, p_pixelData, (BYTE*) (chunk + 1), p_flcHeader);
212 DecodeCopy(p_bitmapHeader, p_pixelData, (BYTE*) (chunk + 1), p_flcHeader);
233 short colorIndex = 0;
234 BYTE* colors = p_data;
235 short* pPackets = (
short*) colors;
236 short packets = *pPackets;
239 while (--packets >= 0) {
240 colorIndex += *colors++;
241 short colorCount = *colors++;
243 if (colorCount == 0) {
248 colors += colorCount * 3;
249 colorIndex += colorCount;
255void DecodeColorPacket(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_data,
short index,
short p_count)
257 RGBQUAD* palette = (RGBQUAD*) ((BYTE*) p_bitmapHeader + p_bitmapHeader->biSize) + index;
260 palette->rgbRed = p_data[0];
261 palette->rgbGreen = p_data[1];
262 palette->rgbBlue = p_data[2];
280 short width = p_flcHeader->
width;
281 short height = p_flcHeader->
height;
283 BYTE* offset = ((p_bitmapHeader->biWidth + 3) & -4) * (height - 1) + p_pixelData;
286 short width2 = width;
288 while (--line >= 0) {
292 while ((column += count) < width2) {
297 for (i = 0; i < count; i++) {
305 for (i = 0; i < count; i++) {
311 offset -= (((p_bitmapHeader->biWidth + 3) & -4) + width);
317void DecodeLC(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_pixelData, BYTE* p_data,
FLIC_HEADER* p_flcHeader)
321 short* word_data = (
short*) p_data;
322 BYTE* data = (BYTE*) word_data + 4;
323 short row = p_flcHeader->
height - (*word_data + yofs) - 1;
326 short lines = *word_data;
328 while (--lines >= 0) {
330 BYTE packets = *data++;
332 while (packets > 0) {
334 char type = *((
char*) data++);
338 WritePixelRun(p_bitmapHeader, p_pixelData, column, row, *data++, type);
340 packets = packets - 1;
343 WritePixels(p_bitmapHeader, p_pixelData, column, row, data, type);
346 packets = packets - 1;
358 short width = (short) p_flcHeader->
width - 1;
359 short row = (
short) p_flcHeader->
height - 1;
360 short lines = *((
short*) p_data);
361 BYTE* data = p_data + 2;
363 while (--lines > 0) {
367 token = *((
short*) data);
371 if (token & 0x4000) {
375 WritePixel(p_bitmapHeader, p_pixelData, width, row, token);
376 token = *((WORD*) data);
398 short type = *((
char*) data++);
402 WritePixels(p_bitmapHeader, p_pixelData, column, row, data, type);
408 short p_pixel = *((WORD*) data);
410 WritePixelPairs(p_bitmapHeader, p_pixelData, column, row, p_pixel, type >> 1);
423 short height = p_flcHeader->
height;
424 short width = p_flcHeader->
width;
429 pixel[0] = pixel[1] = 0;
431 for (
short i = height - 1; i >= 0; i--) {
432 WritePixelPairs(p_bitmapHeader, p_pixelData, t_col, t_row + i, *(WORD*) pixel, width / 2);
435 WritePixel(p_bitmapHeader, p_pixelData, t_col + width - 1, t_row + i, 0);
444 short height = p_flcHeader->
height;
445 short width = p_flcHeader->
width;
449 for (
short i = height - 1; i >= 0; i--) {
450 WritePixels(p_bitmapHeader, p_pixelData, t_col, t_row + i, p_data, width);
458 LPBITMAPINFOHEADER p_bitmapHeader,
462 BYTE* p_decodedColorMap
470 if (
DecodeChunks(p_bitmapHeader, p_pixelData, p_flcHeader, frame, (BYTE*) (p_flcFrame + 1), p_decodedColorMap)) {
#define DECOMP_SIZE_ASSERT(T, S)
void DecodeLC(LPBITMAPINFOHEADER p_bitmapHeader, BYTE *p_pixelData, BYTE *p_data, FLIC_HEADER *p_flcHeader)
void DecodeBlack(LPBITMAPINFOHEADER p_bitmapHeader, BYTE *p_pixelData, BYTE *p_data, FLIC_HEADER *p_flcHeader)
short DecodeChunks(LPBITMAPINFOHEADER p_bitmapHeader, BYTE *p_pixelData, FLIC_HEADER *p_flcHeader, FLIC_FRAME *p_flcFrame, BYTE *p_flcSubchunks, BYTE *p_decodedColorMap)
void DecodeColorPacket(LPBITMAPINFOHEADER p_bitmapHeader, BYTE *p_data, short p_index, short p_count)
void WritePixelRun(LPBITMAPINFOHEADER p_bitmapHeader, BYTE *p_pixelData, short p_column, short p_row, byte p_pixel, short p_count)
void DecodeSS2(LPBITMAPINFOHEADER p_bitmapHeader, BYTE *p_pixelData, BYTE *p_data, FLIC_HEADER *p_flcHeader)
void DecodeColorPackets(LPBITMAPINFOHEADER p_bitmapHeader, BYTE *p_data)
void DecodeColors256(LPBITMAPINFOHEADER p_bitmapHeader, BYTE *p_data)
void WritePixel(LPBITMAPINFOHEADER p_bitmapHeader, BYTE *p_pixelData, short p_column, short p_row, byte p_pixel)
void DecodeColors64(LPBITMAPINFOHEADER p_bitmapHeader, BYTE *p_data)
int ClampLine(LPBITMAPINFOHEADER p_bitmapHeader, short &p_column, short &p_row, short &p_count)
void DecodeCopy(LPBITMAPINFOHEADER p_bitmapHeader, BYTE *p_pixelData, BYTE *p_data, FLIC_HEADER *p_flcHeader)
void DecodeBrun(LPBITMAPINFOHEADER p_bitmapHeader, BYTE *p_pixelData, BYTE *p_data, FLIC_HEADER *p_flcHeader)
void DecodeFLCFrame(LPBITMAPINFOHEADER p_bitmapHeader, BYTE *p_pixelData, FLIC_HEADER *p_flcHeader, FLIC_FRAME *p_flcFrame, BYTE *p_decodedColorMap)
[AI] Decodes a single FLIC (FLI/FLC) animation frame and updates the pixel data and palette.
void WritePixels(LPBITMAPINFOHEADER p_bitmapHeader, BYTE *p_pixelData, short p_column, short p_row, BYTE *p_data, short p_count)
void WritePixelPairs(LPBITMAPINFOHEADER p_bitmapHeader, BYTE *p_pixelData, short p_column, short p_row, WORD p_pixel, short p_count)
@ FLI_CHUNK_FRAME
Marks the start of a FLIC animation frame. [AI].
@ FLI_CHUNK_COPY
No compression; raw pixel data for the frame. [AI].
@ FLI_CHUNK_COLOR64
64-level color palette info. Updates only 64 palette entries. [AI]
@ FLI_CHUNK_BLACK
Entire frame is filled with color index 0 (black). [AI].
@ FLI_CHUNK_LC
Byte-oriented delta compression. Encodes lines with byte-level difference encoding....
@ FLI_CHUNK_SS2
Word-oriented delta compression. Efficient for lines with word-aligned runs or minimal pixel changes....
@ FLI_CHUNK_BRUN
Byte run-length compression. Lossless RLE for frame data. [AI].
@ FLI_CHUNK_COLOR256
256-level color palette info. Updates the color lookup table with 256 entries. [AI]
[AI] Represents a generic chunk header in a FLIC animation file.
DWORD size
[AI] Total size of the chunk in bytes, including the header and payload/subchunks.
WORD type
[AI] Chunk type identifier (see FLI_CHUNK_TYPE).
[AI] Structure describing the header of a FLIC animation frame, used to organize frame subchunks and ...
WORD chunks
[AI] Number of subchunks that compose this animation frame (palette/image/compression chunks)....