home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************
- * 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);
- }
-