home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics 16,000
/
graphics-16000.iso
/
msdos
/
utils
/
fbm2fl03.lha
/
fppbrun.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-09
|
6KB
|
263 lines
/****************************************************************
* fppbrun.c
****************************************************************/
/******
Copyright (C) 1993 by Klaus Ehrenfried.
Permission to use, copy, modify, and distribute this software
is hereby granted, provided that the above copyright notice appears
in all copies and that the software is available to all free of charge.
The author disclaims all warranties with regard to this software,
including all implied warranties of merchant-ability and fitness.
The code is simply distributed as it is.
*******/
#include <stdio.h>
#include <stdlib.h>
#include "fpfli.h"
static int work[FLI_MAX_X];
static int val[FLI_MAX_X];
static int make_brun_line(unsigned char *image_line,
unsigned char *brun_line);
static int improve_brun_line();
static int test_brun_packets();
static int merge_count;
/****************************************************************
* make_brun_chunk
****************************************************************/
int
make_brun_chunk
(
UBYTE *image /* first image */
)
{
int chunk_count, j, help;
unsigned char *brun_line;
float compression;
chunk_count=6; /* 4 bytes for chunk size */
/* 2 bytes for chunk type */
for (j=0; j < fli_height; j++)
{
brun_line = &pixel_chunk_buffer[chunk_count];
chunk_count += make_brun_line(image, brun_line);
image += fli_width;
}
if ((chunk_count % 2) == 1)
add_bytes(pixel_chunk_buffer, &chunk_count, 0x0000, IOM_UBYTE);
help=0;
add_bytes(pixel_chunk_buffer, &help, chunk_count, IOM_LONG);
add_bytes(pixel_chunk_buffer, &help, FLI_BRUN, IOM_UWORD);
compression=fli_size/((float)chunk_count);
fprintf(stdout," Brun chunk: %d bytes compression: %f\n",
chunk_count,compression);
return(chunk_count);
}
/****************************************************************
* make_brun_line
****************************************************************/
static int make_brun_line
(
unsigned char *image_line,
unsigned char *brun_line
)
{
int i, ipos, packets;
int size_count, help;
for (i=0; i < fli_width; i++)
val[i]=image_line[i];
work[fli_width-1]=-1;
for (i=(fli_width-2); i >= 0; i--)
{
if (val[i] == val[i+1])
{
if (work[i+1] > 0)
{
work[i]=work[i+1]+1;
if (work[i] > 127) work[i]=1;
}
else
{
work[i+1]=1;
work[i]=2;
}
}
else
{
if (work[i+1] < 0)
{
work[i]=work[i+1]-1;
if (work[i] < -127) work[i]=-1;
}
else
{
work[i]=-1;
}
}
}
merge_count=1;
while (merge_count > 0)
{
merge_count=0;
improve_brun_line();
}
test_brun_packets();
ipos=1;
packets=0;
i=0;
while (i < fli_width)
{
size_count=work[i];
/* fprintf(stdout," %d %d\n",i,size_count); */
add_bytes(brun_line, &ipos, size_count, IOM_UBYTE);
if (size_count > 0)
{
add_bytes(brun_line, &ipos, val[i], IOM_UBYTE);
i += size_count;
}
else
{
help = i - size_count;
while (i < help)
{
add_bytes(brun_line, &ipos, val[i++], IOM_UBYTE);
}
}
packets++;
}
/* fprintf(stdout," packets: %d ipos: %d\n\n",packets,ipos); */
help=0;
add_bytes(brun_line, &help, packets, IOM_UBYTE);
return(ipos);
}
/****************************************************************
* get_packet_start
****************************************************************/
static int get_packet_start(int i)
{
int j,igo;
igo=0;
for (j=i; j > 0; j--)
{
if (work[j-1] != (work[j]-1))
{
igo=j;
break;
}
}
return(igo);
}
/****************************************************************
* merge_packets
****************************************************************/
static int merge_packets(int igo1, int igo2)
{
int j, len, m;
len = igo2-igo1+1;
if (len > 127) return(0);
merge_count++;
m=-1;
for (j=igo2; j >= igo1; j--) work[j] = m--;
return(m);
}
/****************************************************************
* improve_brun_line
****************************************************************/
static int improve_brun_line()
{
int i,igo1,igo2;
for (i=0; i < fli_width-1; i++) /* | -1 | 2 | */
{
if ((work[i] == -1) && (work[i+1] == 2))
{
igo1 = get_packet_start(i);
igo2 = i+2;
merge_packets(igo1,igo2);
}
}
for (i=0; i < fli_width-2; i++) /* | XX | 2 | 1 | -N | */
{
if ((work[i] == 2) && (work[i+2] < 0) &&
((i == 0) || (work[i-1] != 3)))
{
igo1 = i;
igo2 = i+1-work[i+2];
merge_packets(igo1,igo2);
}
}
for (i=0; i < fli_width-1; i++) /* | -1 | -N | */
{
if ((work[i] == -1) && (work[i+1] < 0))
{
igo1 = get_packet_start(i);
igo2 = i-work[i+1];
merge_packets(igo1,igo2);
}
}
return(1);
}
/****************************************************************
* test_brun_packets
****************************************************************/
static int test_brun_packets()
{
int packets,i, igo1,igo2;
packets=0;
for (i = 0; i < fli_width; i++)
if ((work[i] == 1) || (work[i] == -1)) packets++;
if (packets < 256) return(packets);
igo1=0;
while (igo1 < fli_width)
{
igo2=igo1+125;
if (igo2 >= fli_width) igo2=fli_width-1;
merge_packets(igo1,igo2);
igo1=igo2+1;
}
return(-1);
}