home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / graphics / gifbla20.zip / SOURCE / GB20CODE.C < prev    next >
C/C++ Source or Header  |  1992-12-15  |  5KB  |  209 lines

  1.  
  2. /* gb20code.c - Special purpose GIF compressor routines (version 2.0). */
  3.  
  4. #include <stdio.h>
  5. #include <string.h>
  6.  
  7. #include "uffile.h"
  8. #include "arith.h"
  9. #include "arithmod.h"
  10. #include "gbcon.h"
  11. #include "gb20code.h"
  12.  
  13. int copy_if_larger=1;
  14.  
  15. extern void *(*basic_alloc) P((size_t size),());
  16. extern void (*basic_free) P((void *block),());
  17.  
  18. GB20_CODER *
  19. gb20_alloc_coder()
  20. {
  21.     GB20_CODER *gb20;
  22.  
  23.     if ((gb20=basic_alloc(sizeof(GB20_CODER))) == NULL)
  24.         return NULL;
  25.     gb20->ac_order_1_cons =
  26.         basic_alloc(ARCON_NCODES*sizeof(ARCON_SMALL_CONTEXT));
  27.     if (gb20->ac_order_1_cons == NULL) {
  28.         basic_free(gb20);
  29.         return NULL;
  30.     }
  31.     return gb20;
  32. }
  33.  
  34. void
  35. gb20_free_coder(gb20)
  36. GB20_CODER *gb20;
  37. {
  38.     if (gb20 != NULL) {
  39.         if (gb20->ac_order_1_cons != NULL)
  40.             basic_free(gb20->ac_order_1_cons);
  41.         basic_free(gb20);
  42.     }
  43. }
  44.  
  45. static void
  46. gb20_init(gb20)
  47. GB20_CODER *gb20;
  48. {
  49.     int i;
  50.  
  51.     arcon_big_init(&gb20->ac_order_0_con);
  52.     for (i=0; i<ARCON_NCODES; i++)
  53.         arcon_small_init(&(gb20->ac_order_1_cons[i]),ARCON_V20_SMALL_RBSIZE);
  54.     for (i=0; i<=V20_TYPEMASK; i++)
  55.         arcon_type_init(&(gb20->ac_type_cons[i]));
  56.     gb20->prev = gb20->prevts = 0;
  57.     gb20->im_bpp = 0;
  58. }
  59.  
  60. int
  61. gb20_start_encoding(gb20,ff)
  62. GB20_CODER *gb20; FFILE *ff;
  63. {
  64.     gb20_init(gb20);
  65.     return arith_start_encoding(&gb20->ac_struct,ff);
  66. }
  67.  
  68. void
  69. gb20_init_image(gb20,im_bpp)
  70. GB20_CODER *gb20; int im_bpp;
  71. {
  72.     int i;
  73.  
  74.     gb20->im_bpp = im_bpp;
  75.     if (im_bpp == 1) {
  76.         for (i=0; i<=V20_BITMASK; i++)
  77.             arcon_type_init(&(gb20->ac_bit_cons[i]));
  78.         gb20->prevbits = 0;
  79.     }
  80. }
  81.  
  82. void
  83. gb20_end_image(gb20)
  84. GB20_CODER *gb20;
  85. {
  86.     gb20->im_bpp = 0;
  87. }
  88.  
  89. int
  90. gb20_encode_c(c,gb20)
  91. int c; GB20_CODER *gb20;
  92. {
  93.     int t,rstart,rend,rtot,trstart,trend,trtot;
  94.     ARCON_BIG_CONTEXT *big_con;
  95.     ARCON_SMALL_CONTEXT *small_con;
  96.     ARCON_TYPE_CONTEXT *type_con;
  97.     ARCON_TYPE_CONTEXT *bit_con;
  98.  
  99.     if (gb20->im_bpp == 1) {
  100.         bit_con = &gb20->ac_bit_cons[gb20->prevbits];
  101.         if (arcon_type_find_range(bit_con,c,&rstart,&rend))
  102.             rtot = arcon_type_rtot(bit_con);
  103.         else
  104.             return -1;
  105.         if (arith_encode(&gb20->ac_struct,rstart,rend,rtot)<0
  106.             || arcon_type_add(bit_con,c)<0)
  107.             return -1;
  108.         gb20->prevbits = (((gb20->prevbits<<1)|c)&V20_BITMASK);
  109.         return 0;
  110.     }
  111.     big_con = &gb20->ac_order_0_con;
  112.     small_con = &gb20->ac_order_1_cons[gb20->prev];
  113.     type_con = &gb20->ac_type_cons[gb20->prevts];
  114.     if (arcon_small_find_range(small_con,c,&rstart,&rend)) {
  115.         t = 1;
  116.         rtot = arcon_small_rtot(small_con);
  117.     } else if (arcon_big_find_range(big_con,c,&rstart,&rend)) {
  118.         t = 0;
  119.         rtot = arcon_big_rtot(big_con);
  120.     } else
  121.         return -1;
  122.     if (arcon_type_find_range(type_con,t,&trstart,&trend))
  123.         trtot = arcon_type_rtot(type_con);
  124.     else
  125.         return -1;
  126.     if (arith_encode(&gb20->ac_struct,trstart,trend,trtot)<0
  127.         || arith_encode(&gb20->ac_struct,rstart,rend,rtot)<0
  128.         || arcon_small_add(small_con,c)<0
  129.         || (t==0 && arcon_big_add(big_con,c)<0)
  130.         || arcon_type_add(type_con,t)<0)
  131.         return -1;
  132.     gb20->prev = c;
  133.     gb20->prevts = (((gb20->prevts<<1)|t)&V20_TYPEMASK);
  134.     return 0;
  135. }
  136.  
  137. int
  138. gb20_end_encoding(gb20)
  139. GB20_CODER *gb20;
  140. {
  141.     return arith_end_encoding(&gb20->ac_struct);
  142. }
  143.  
  144. int
  145. gb20_start_decoding(gb20,ff)
  146. GB20_CODER *gb20; FFILE *ff;
  147. {
  148.     gb20_init(gb20);
  149.     return arith_start_decoding(&gb20->ac_struct,ff);
  150. }
  151.  
  152. int
  153. gb20_decode_c(gb20)
  154. GB20_CODER *gb20;
  155. {
  156.     int trstart,trend,trtot,trpos,t,rstart,rend,rtot,rpos,c;
  157.     ARCON_BIG_CONTEXT *big_con;
  158.     ARCON_SMALL_CONTEXT *small_con;
  159.     ARCON_TYPE_CONTEXT *type_con;
  160.     ARCON_TYPE_CONTEXT *bit_con;
  161.  
  162.     if (gb20->im_bpp == 1) {
  163.         bit_con = &gb20->ac_bit_cons[gb20->prevbits];
  164.         rtot = arcon_type_rtot(bit_con);
  165.         rpos = arith_decode_getrpos(&gb20->ac_struct,rtot);
  166.         if ((c=arcon_type_find_c(bit_con,rpos,&rstart,&rend))<0
  167.             || arith_decode_advance(&gb20->ac_struct,rstart,rend,rtot)<0
  168.             || arcon_type_add(bit_con,c)<0)
  169.             return -1;
  170.         gb20->prevbits = (((gb20->prevbits<<1)|c)&V20_BITMASK);
  171.         return c;
  172.     }
  173.     big_con = &gb20->ac_order_0_con;
  174.     small_con = &(gb20->ac_order_1_cons[gb20->prev]);
  175.     type_con = &gb20->ac_type_cons[gb20->prevts];
  176.     trtot = arcon_type_rtot(type_con);
  177.     trpos = arith_decode_getrpos(&gb20->ac_struct,trtot);
  178.     if ((t=arcon_type_find_c(type_con,trpos,&trstart,&trend))<0
  179.         || arith_decode_advance(&gb20->ac_struct,trstart,trend,trtot)<0
  180.         || arcon_type_add(type_con,t)<0)
  181.         return -1;
  182.     if (t == 0) {
  183.         rtot = arcon_big_rtot(big_con);
  184.         rpos = arith_decode_getrpos(&gb20->ac_struct,rtot);
  185.         if ((c=arcon_big_find_c(big_con,rpos,&rstart,&rend))<0
  186.             || arith_decode_advance(&gb20->ac_struct,rstart,rend,rtot)<0
  187.             || arcon_big_add(big_con,c)<0
  188.             || arcon_small_add(small_con,c)<0)
  189.             return -1;
  190.     } else {
  191.         rtot = arcon_small_rtot(small_con);
  192.         rpos = arith_decode_getrpos(&gb20->ac_struct,rtot);
  193.         if ((c=arcon_small_find_c(small_con,rpos,&rstart,&rend))<0
  194.             || arith_decode_advance(&gb20->ac_struct,rstart,rend,rtot)<0
  195.             || arcon_small_add(small_con,c)<0)
  196.             return -1;
  197.     }
  198.     gb20->prev = c;
  199.     gb20->prevts = (((gb20->prevts<<1)|t)&V20_TYPEMASK);
  200.     return c;
  201. }
  202.  
  203. int
  204. gb20_end_decoding(gb20)
  205. GB20_CODER *gb20;
  206. {
  207.     return arith_end_decoding(&gb20->ac_struct);
  208. }
  209.