home *** CD-ROM | disk | FTP | other *** search
/ Graphics 16,000 / graphics-16000.iso / msdos / utils / fbm2fl03.lha / fppbrun.c < prev    next >
C/C++ Source or Header  |  1993-11-09  |  6KB  |  263 lines

  1. /****************************************************************
  2.  * fppbrun.c
  3.  ****************************************************************/
  4.  
  5. /******
  6.   Copyright (C) 1993 by Klaus Ehrenfried. 
  7.  
  8.   Permission to use, copy, modify, and distribute this software
  9.   is hereby granted, provided that the above copyright notice appears 
  10.   in all copies and that the software is available to all free of charge. 
  11.   The author disclaims all warranties with regard to this software, 
  12.   including all implied warranties of merchant-ability and fitness. 
  13.   The code is simply distributed as it is.
  14. *******/
  15.  
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include "fpfli.h"
  19.  
  20. static int work[FLI_MAX_X];
  21. static int val[FLI_MAX_X];
  22.  
  23. static int make_brun_line(unsigned char *image_line,
  24.     unsigned char *brun_line);
  25. static int improve_brun_line();
  26. static int test_brun_packets();
  27.  
  28. static int merge_count;
  29.  
  30. /****************************************************************
  31.  * make_brun_chunk
  32.  ****************************************************************/
  33.  
  34. int
  35. make_brun_chunk
  36. (
  37. UBYTE *image                /* first image */
  38. )
  39. {
  40.     int chunk_count, j, help;
  41.     unsigned char *brun_line;
  42.     float compression;
  43.  
  44.     chunk_count=6;            /* 4 bytes for chunk size */
  45.                     /* 2 bytes for chunk type */
  46.     for (j=0; j < fli_height; j++)
  47.     {
  48.     brun_line = &pixel_chunk_buffer[chunk_count];
  49.     chunk_count += make_brun_line(image, brun_line);
  50.     image += fli_width;
  51.     }
  52.  
  53.     if ((chunk_count % 2) == 1)
  54.     add_bytes(pixel_chunk_buffer, &chunk_count, 0x0000, IOM_UBYTE);
  55.  
  56.     help=0;
  57.     add_bytes(pixel_chunk_buffer, &help, chunk_count, IOM_LONG);
  58.     add_bytes(pixel_chunk_buffer, &help, FLI_BRUN, IOM_UWORD);
  59.  
  60.     compression=fli_size/((float)chunk_count);
  61.  
  62.     fprintf(stdout," Brun chunk: %d bytes    compression: %f\n",
  63.         chunk_count,compression);
  64.  
  65.     return(chunk_count);
  66. }
  67.  
  68. /****************************************************************
  69.  * make_brun_line
  70.  ****************************************************************/
  71.  
  72. static int make_brun_line
  73. (
  74. unsigned char *image_line,
  75. unsigned char *brun_line
  76. )
  77. {
  78.     int i, ipos, packets;
  79.     int size_count, help;
  80.  
  81.     for (i=0; i < fli_width; i++)
  82.         val[i]=image_line[i];
  83.  
  84.     work[fli_width-1]=-1;
  85.  
  86.     for (i=(fli_width-2); i >= 0; i--)
  87.     {
  88.         if (val[i] == val[i+1])
  89.     {
  90.             if (work[i+1] > 0)
  91.             {
  92.             work[i]=work[i+1]+1;
  93.                 if (work[i] > 127) work[i]=1;
  94.             }
  95.             else
  96.             {
  97.                 work[i+1]=1;
  98.                 work[i]=2;
  99.             }
  100.         }
  101.     else
  102.         {
  103.             if (work[i+1] < 0)
  104.             {
  105.             work[i]=work[i+1]-1;
  106.                 if (work[i] < -127) work[i]=-1;
  107.             }
  108.         else
  109.             {
  110.                 work[i]=-1;
  111.             }
  112.         }
  113.     }
  114.  
  115.     merge_count=1;
  116.     while (merge_count > 0)
  117.       {
  118.     merge_count=0;
  119.     improve_brun_line();
  120.       }
  121.     test_brun_packets();
  122.  
  123.     ipos=1;
  124.  
  125.     packets=0;
  126.     i=0;
  127.     while (i < fli_width)
  128.     {
  129.         size_count=work[i];
  130.     /* fprintf(stdout," %d  %d\n",i,size_count); */
  131.  
  132.         add_bytes(brun_line, &ipos, size_count, IOM_UBYTE);
  133.         if (size_count > 0)
  134.         {
  135.             add_bytes(brun_line, &ipos, val[i], IOM_UBYTE);
  136.             i += size_count;
  137.         }
  138.         else
  139.         {
  140.         help = i - size_count;
  141.             while (i < help)
  142.         {
  143.                 add_bytes(brun_line, &ipos, val[i++], IOM_UBYTE);
  144.             }
  145.     }
  146.     packets++;
  147.     }
  148.     /* fprintf(stdout," packets: %d    ipos: %d\n\n",packets,ipos); */
  149.  
  150.     help=0;
  151.     add_bytes(brun_line, &help, packets, IOM_UBYTE);
  152.  
  153.     return(ipos);
  154. }
  155.  
  156. /****************************************************************
  157.  * get_packet_start
  158.  ****************************************************************/
  159.  
  160. static int get_packet_start(int i)
  161. {
  162.   int j,igo;
  163.  
  164.   igo=0;
  165.  
  166.   for (j=i; j > 0; j--)
  167.     {
  168.       if (work[j-1] != (work[j]-1))
  169.     {
  170.       igo=j;
  171.       break;
  172.     }
  173.     }
  174.  
  175.   return(igo);
  176. }
  177.  
  178.  
  179. /****************************************************************
  180.  * merge_packets
  181.  ****************************************************************/
  182.  
  183. static int merge_packets(int igo1, int igo2)
  184. {
  185.   int j, len, m;
  186.  
  187.   len = igo2-igo1+1;
  188.   if (len > 127) return(0);
  189.  
  190.   merge_count++;
  191.  
  192.   m=-1;
  193.   for (j=igo2; j >= igo1; j--) work[j] = m--;
  194.  
  195.   return(m);
  196. }
  197.  
  198. /****************************************************************
  199.  * improve_brun_line
  200.  ****************************************************************/
  201.  
  202. static int improve_brun_line()
  203. {
  204.   int i,igo1,igo2;
  205.  
  206.   for (i=0; i < fli_width-1; i++)                  /* | -1 | 2 | */
  207.     {
  208.       if ((work[i] == -1) && (work[i+1] == 2))
  209.     {
  210.       igo1 = get_packet_start(i);
  211.       igo2 = i+2;
  212.       merge_packets(igo1,igo2);
  213.     }
  214.     }
  215.  
  216.   for (i=0; i < fli_width-2; i++)                  /* | XX |  2 |  1 | -N | */
  217.     {
  218.       if ((work[i] == 2) && (work[i+2] < 0) &&
  219.       ((i == 0) || (work[i-1] != 3)))
  220.     {
  221.       igo1 = i;
  222.       igo2 = i+1-work[i+2];
  223.       merge_packets(igo1,igo2);
  224.     }
  225.     }
  226.  
  227.   for (i=0; i < fli_width-1; i++)                   /* | -1 | -N | */
  228.     {
  229.       if ((work[i] == -1) && (work[i+1] < 0))
  230.     {
  231.       igo1 = get_packet_start(i);
  232.       igo2 = i-work[i+1];
  233.       merge_packets(igo1,igo2);
  234.     }
  235.     }
  236.   return(1);
  237. }
  238.  
  239. /****************************************************************
  240.  * test_brun_packets
  241.  ****************************************************************/
  242.  
  243. static int test_brun_packets()
  244. {
  245.   int packets,i, igo1,igo2;
  246.  
  247.   packets=0;
  248.   for (i = 0; i < fli_width; i++)
  249.     if ((work[i] == 1) || (work[i] == -1)) packets++;
  250.   if (packets < 256) return(packets);
  251.  
  252.   igo1=0;
  253.   while (igo1 < fli_width)
  254.     {
  255.       igo2=igo1+125;
  256.       if (igo2 >= fli_width) igo2=fli_width-1;
  257.       merge_packets(igo1,igo2);
  258.       igo1=igo2+1;
  259.     }
  260.  
  261.   return(-1);
  262. }
  263.