move PackBits packing code to packbits.c
new functions : - PackBits_pack_init() - PackBits_pack_add() - PackBits_pack_flush()
This commit is contained in:
113
src/packbits.c
113
src/packbits.c
@@ -28,6 +28,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "struct.h"
|
||||
#include "io.h"
|
||||
#include "gfx2log.h"
|
||||
#include "packbits.h"
|
||||
|
||||
@@ -67,3 +68,115 @@ int PackBits_unpack_from_file(FILE * f, byte * dest, unsigned int count)
|
||||
}
|
||||
return PACKBITS_UNPACK_OK;
|
||||
}
|
||||
|
||||
void PackBits_pack_init(T_PackBits_data * data, FILE * f)
|
||||
{
|
||||
memset(data, 0, sizeof(T_PackBits_data));
|
||||
data->f = f;
|
||||
}
|
||||
|
||||
int PackBits_pack_add(T_PackBits_data * data, byte b)
|
||||
{
|
||||
switch (data->list_size)
|
||||
{
|
||||
case 0 : // First color
|
||||
data->list[0] = b;
|
||||
data->list_size = 1;
|
||||
break;
|
||||
case 1 : // second color
|
||||
data->repetition_mode = (data->list[0] == b);
|
||||
data->list[1] = b;
|
||||
data->list_size = 2;
|
||||
break;
|
||||
default: // next colors
|
||||
if (data->list[data->list_size - 1] == b) // repeat detected
|
||||
{
|
||||
if ( !data->repetition_mode && data->list_size >= 127)
|
||||
{
|
||||
// diff mode with 126 bytes then 2 identical bytes
|
||||
data->list_size--;
|
||||
if (PackBits_pack_flush(data) < 0)
|
||||
return -1;
|
||||
data->list[0] = b;
|
||||
data->list[1] = b;
|
||||
data->list_size = 2;
|
||||
data->repetition_mode = 1;
|
||||
}
|
||||
else if ((data->repetition_mode) || (data->list[data->list_size - 2] != b))
|
||||
{
|
||||
// same mode is kept
|
||||
if (data->list_size == 128)
|
||||
{
|
||||
if (PackBits_pack_flush(data) < 0)
|
||||
return -1;
|
||||
}
|
||||
data->list[data->list_size++] = b;
|
||||
}
|
||||
else
|
||||
{
|
||||
// diff mode and 3 identical bytes
|
||||
data->list_size -= 2;
|
||||
if (PackBits_pack_flush(data) < 0)
|
||||
return -1;
|
||||
data->list[0] = b;
|
||||
data->list[1] = b;
|
||||
data->list[2] = b;
|
||||
data->list_size = 3;
|
||||
data->repetition_mode = 1;
|
||||
}
|
||||
}
|
||||
else // the color is different from the previous one
|
||||
{
|
||||
if (!data->repetition_mode) // keep mode
|
||||
{
|
||||
if (data->list_size == 128)
|
||||
{
|
||||
if (PackBits_pack_flush(data) < 0)
|
||||
return -1;
|
||||
}
|
||||
data->list[data->list_size++] = b;
|
||||
}
|
||||
else // change mode
|
||||
{
|
||||
if (PackBits_pack_flush(data) < 0)
|
||||
return -1;
|
||||
data->list[data->list_size++] = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0; // OK
|
||||
}
|
||||
|
||||
int PackBits_pack_flush(T_PackBits_data * data)
|
||||
{
|
||||
if (data->list_size > 0)
|
||||
{
|
||||
if (data->list_size > 128)
|
||||
{
|
||||
GFX2_Log(GFX2_ERROR, "PackBits_pack_flush() list_size=%d !\n", data->list_size);
|
||||
}
|
||||
if (data->repetition_mode)
|
||||
{
|
||||
if (data->f != NULL)
|
||||
{
|
||||
if (!Write_byte(data->f, 257 - data->list_size) ||
|
||||
!Write_byte(data->f, data->list[0]))
|
||||
return -1;
|
||||
}
|
||||
data->output_count += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (data->f != NULL)
|
||||
{
|
||||
if (!Write_byte(data->f, data->list_size - 1) ||
|
||||
!Write_bytes(data->f, data->list, data->list_size))
|
||||
return -1;
|
||||
}
|
||||
data->output_count += 1 + data->list_size;
|
||||
}
|
||||
data->list_size = 0;
|
||||
data->repetition_mode = 0;
|
||||
}
|
||||
return data->output_count;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user