libkate: /home/v/Kate/WORK_TREES/kate-sorceress-backup/v/src/kate/src/kate_rle.c Source File

- Main Page
- Related Pages
- Data Structures
- Files
- Examples

- File List

# /home/v/Kate/WORK_TREES/kate-sorceress-backup/v/src/kate/src/kate_rle.c

    00001 /* Copyright (C) 2008 Vincent Penquerc'h.
    00002    This file is part of the Kate codec library.
    00003    Written by Vincent Penquerc'h.
    00004
    00005    Use, distribution and reproduction of this library is governed
    00006    by a BSD style source license included with this source in the
    00007    file 'COPYING'. Please read these terms before distributing. */
    00008
    00009
    00010 #define KATE_INTERNAL
    00011 #include "kate_internal.h"
    00012
    00013 #ifdef HAVE_STRING_H
    00014 #include <string.h>
    00015 #endif
    00016 #include "kate/kate.h"
    00017 #include "kate_rle.h"
    00018
    00019 /* 4 seems to be optimal for basic - 723 KB */
    00020 /* 3 seems to be optimal for basic_startend - 685 KB */
    00021 /* 4 seems to be optimal for basic_stop - 697 KB */
    00022 #define KATE_RLE_RUN_LENGTH_BITS_BASIC 4
    00023 #define KATE_RLE_RUN_LENGTH_BITS_BASIC_IN_DELTA 3
    00024 #define KATE_RLE_RUN_LENGTH_BITS_BASIC_STARTEND 3
    00025 #define KATE_RLE_RUN_LENGTH_BITS_BASIC_STOP 6
    00026 #define KATE_RLE_RUN_LENGTH_BITS_DELTA 6
    00027 #define KATE_RLE_RUN_LENGTH_BITS_BASIC_STARTEND_START 9
    00028 #define KATE_RLE_RUN_LENGTH_BITS_BASIC_STARTEND_END 8
    00029 #define KATE_RLE_RUN_LENGTH_BITS_BASIC_STOP_START 8
    00030 #define KATE_RLE_RUN_LENGTH_BITS_BASIC_IN_DELTA_STOP 3
    00031 #define KATE_RLE_RUN_LENGTH_BITS_DELTA_STOP 5
    00032 #define KATE_RLE_RUN_LENGTH_BITS_BASIC_ZERO 8
    00033 #define KATE_RLE_RUN_LENGTH_BITS_BASIC_NON_ZERO 3
    00034
    00035 #define KATE_RLE_TYPE_EMPTY 0
    00036 #define KATE_RLE_TYPE_BASIC 1
    00037 #define KATE_RLE_TYPE_DELTA 2
    00038 #define KATE_RLE_TYPE_BASIC_STOP 3
    00039 #define KATE_RLE_TYPE_BASIC_STARTEND 4
    00040 #define KATE_RLE_TYPE_DELTA_STOP 5
    00041 #define KATE_RLE_TYPE_BASIC_ZERO 6
    00042
    00043 #define KATE_RLE_TYPE_BITS 3
    00044
    00045 #define kate_unused __attribute__((unused))
    00046
    00047 static size_t get_run_length(size_t max_run_length,size_t count,const unsigned char *values)
    00048 {
    00049   const size_t limit=max_run_length>count?count:max_run_length;
    00050   size_t run_length=1;
    00051   while (run_length<limit && values[run_length]==values[0])
    00052     ++run_length;
    00053   return run_length;
    00054 }
    00055
    00056 static size_t get_run_length_identical(size_t max_run_length,size_t count,const unsigned char *values,const unsigned char *previous,unsigned char zero)
    00057 {
    00058   const size_t limit=max_run_length>count?count:max_run_length;
    00059   size_t run_length=0;
    00060   if (previous) {
    00061     while (run_length<limit && values[run_length]==previous[run_length])
    00062       ++run_length;
    00063   }
    00064   else {
    00065     while (run_length<limit && values[run_length]==zero)
    00066       ++run_length;
    00067   }
    00068   return run_length;
    00069 }
    00070
    00071 static size_t get_run_length_zero(size_t max_run_length,size_t count,const unsigned char *values,unsigned char zero)
    00072 {
    00073   const size_t limit=max_run_length>count?count:max_run_length;
    00074   size_t run_length=1;
    00075   while (run_length<limit && values[run_length]==zero)
    00076     ++run_length;
    00077   return run_length;
    00078 }
    00079
    00080 static size_t get_run_length_zero_back(size_t max_run_length,size_t count,const unsigned char *values,size_t nvalues,unsigned char zero)
    00081 {
    00082   const size_t limit=max_run_length>count?count:max_run_length;
    00083   size_t run_length=0;
    00084   while (run_length<limit && values[nvalues-1-run_length]==zero)
    00085     ++run_length;
    00086   return run_length;
    00087 }
    00088
    00089 static int kate_rle_encode_line_basic(size_t count,const unsigned char *values,size_t bits,unsigned char zero kate_unused,const unsigned char *previous kate_unused,kate_pack_buffer *kpb)
    00090 {
    00091   const size_t run_length_bits=KATE_RLE_RUN_LENGTH_BITS_BASIC;
    00092   const size_t run_length_cutoff=1<<run_length_bits;
    00093   size_t run_length,max_run_length;
    00094
    00095   while (count>0) {
    00096     max_run_length=run_length_cutoff;
    00097     run_length=get_run_length(max_run_length,count,values);
    00098     kate_pack_write(kpb,run_length-1,run_length_bits);
    00099     kate_pack_write(kpb,values[0],bits);
    00100     values+=run_length;
    00101     count-=run_length;
    00102   }
    00103
    00104   return 0;
    00105 }
    00106
    00107 static int kate_rle_encode_line_basic_zero(size_t count,const unsigned char *values,size_t bits,unsigned char zero kate_unused,const unsigned char *previous kate_unused,kate_pack_buffer *kpb)
    00108 {
    00109   const size_t run_length_bits_zero=KATE_RLE_RUN_LENGTH_BITS_BASIC_ZERO;
    00110   const size_t run_length_bits_non_zero=KATE_RLE_RUN_LENGTH_BITS_BASIC_NON_ZERO;
    00111   const size_t run_length_zero_cutoff=1<<run_length_bits_zero;
    00112   const size_t run_length_non_zero_cutoff=1<<run_length_bits_non_zero;
    00113   size_t run_length,max_run_length,run_length_bits;
    00114
    00115   while (count>0) {
    00116     if (values[0]==zero) {
    00117       max_run_length=run_length_zero_cutoff;
    00118       run_length_bits=run_length_bits_zero;
    00119     }
    00120     else {
    00121       max_run_length=run_length_non_zero_cutoff;
    00122       run_length_bits=run_length_bits_non_zero;
    00123     }
    00124     run_length=get_run_length(max_run_length,count,values);
    00125     kate_pack_write(kpb,values[0],bits);
    00126     kate_pack_write(kpb,run_length-1,run_length_bits);
    00127     values+=run_length;
    00128     count-=run_length;
    00129   }
    00130
    00131   return 0;
    00132 }
    00133
    00134 static int kate_rle_encode_line_basic_startend(size_t count,const unsigned char *values,size_t bits,unsigned char zero,const unsigned char *previous kate_unused,kate_pack_buffer *kpb)
    00135 {
    00136   const size_t run_length_bits=KATE_RLE_RUN_LENGTH_BITS_BASIC_STARTEND;
    00137   const size_t run_length_cutoff=1<<run_length_bits;
    00138   size_t run_length,run_length_start,run_length_end,max_run_length;
    00139
    00140   max_run_length=(1<<KATE_RLE_RUN_LENGTH_BITS_BASIC_STARTEND_START)-1;
    00141   run_length_start=get_run_length_zero(max_run_length,count,values,zero);
    00142   kate_pack_write(kpb,run_length_start,KATE_RLE_RUN_LENGTH_BITS_BASIC_STARTEND_START);
    00143   values+=run_length_start;
    00144   count-=run_length_start;
    00145
    00146   max_run_length=(1<<KATE_RLE_RUN_LENGTH_BITS_BASIC_STARTEND_END)-1;
    00147   run_length_end=get_run_length_zero_back(max_run_length,count,values,count,zero);
    00148   kate_pack_write(kpb,run_length_end,KATE_RLE_RUN_LENGTH_BITS_BASIC_STARTEND_END);
    00149   count-=run_length_end;
    00150
    00151   while (count>0) {
    00152     max_run_length=run_length_cutoff;
    00153     run_length=get_run_length(max_run_length,count,values);
    00154     kate_pack_write(kpb,run_length-1,run_length_bits);
    00155     kate_pack_write(kpb,values[0],bits);
    00156     values+=run_length;
    00157     count-=run_length;
    00158   }
    00159
    00160   return 0;
    00161 }
    00162
    00163 static int kate_rle_encode_line_basic_stop(size_t count,const unsigned char *values,size_t bits,unsigned char zero,const unsigned char *previous kate_unused,kate_pack_buffer *kpb)
    00164 {
    00165   const size_t run_length_bits=KATE_RLE_RUN_LENGTH_BITS_BASIC_STOP;
    00166   const size_t run_length_cutoff=(1<<run_length_bits)-1;
    00167   size_t run_length,run_length_start,max_run_length;
    00168
    00169   max_run_length=(1<<KATE_RLE_RUN_LENGTH_BITS_BASIC_STOP_START)-1;
    00170   run_length_start=get_run_length_zero(max_run_length,count,values,zero);
    00171   kate_pack_write(kpb,run_length_start,KATE_RLE_RUN_LENGTH_BITS_BASIC_STOP_START);
    00172   values+=run_length_start;
    00173   count-=run_length_start;
    00174
    00175   while (count>0) {
    00176     if (values[0]==zero) {
    00177       run_length=get_run_length(count,count,values);
    00178       if (run_length==count) {
    00179         kate_pack_write(kpb,0,run_length_bits);
    00180         break;
    00181       }
    00182     }
    00183     max_run_length=run_length_cutoff;
    00184     run_length=get_run_length(max_run_length,count,values);
    00185     kate_pack_write(kpb,run_length,run_length_bits);
    00186     kate_pack_write(kpb,values[0],bits);
    00187     values+=run_length;
    00188     count-=run_length;
    00189   }
    00190
    00191   return 0;
    00192 }
    00193
    00194 static int kate_rle_encode_line_empty(size_t count,const unsigned char *values,size_t bits kate_unused,unsigned char zero,const unsigned char *previous kate_unused,kate_pack_buffer *kpb kate_unused)
    00195 {
    00196   size_t run_length=get_run_length_zero(count,count,values,zero);
    00197   if (run_length<count) return -1;
    00198   return 0;
    00199 }
    00200
    00201 static int kate_rle_encode_line_delta(size_t count,const unsigned char *values,size_t bits,unsigned char zero kate_unused,const unsigned char *previous,kate_pack_buffer *kpb)
    00202 {
    00203   const size_t run_length_delta_bits=KATE_RLE_RUN_LENGTH_BITS_DELTA;
    00204   const size_t run_length_delta_cutoff=(1<<run_length_delta_bits);
    00205   const size_t run_length_basic_bits=KATE_RLE_RUN_LENGTH_BITS_BASIC_IN_DELTA;
    00206   const size_t run_length_basic_cutoff=(1<<run_length_basic_bits);
    00207   size_t max_run_length_delta,max_run_length_basic;
    00208   size_t run_length_delta,run_length_basic;
    00209
    00210   while (count>0) {
    00211     max_run_length_delta=run_length_delta_cutoff;
    00212     run_length_delta=get_run_length_identical(max_run_length_delta,count,values,previous,zero);
    00213
    00214     max_run_length_basic=run_length_basic_cutoff;
    00215     run_length_basic=get_run_length(max_run_length_basic,count,values);
    00216
    00217     if (run_length_delta>run_length_basic) {
    00218       kate_pack_write(kpb,1,1);
    00219       kate_pack_write(kpb,run_length_delta-1,run_length_delta_bits);
    00220       values+=run_length_delta;
    00221       if (previous) previous+=run_length_delta;
    00222       count-=run_length_delta;
    00223     }
    00224     else {
    00225       kate_pack_write(kpb,0,1);
    00226       kate_pack_write(kpb,run_length_basic-1,run_length_basic_bits);
    00227       kate_pack_write(kpb,values[0],bits);
    00228       values+=run_length_basic;
    00229       if (previous) previous+=run_length_basic;
    00230       count-=run_length_basic;
    00231     }
    00232   }
    00233
    00234   return 0;
    00235 }
    00236
    00237 static int kate_rle_encode_line_delta_stop(size_t count,const unsigned char *values,size_t bits,unsigned char zero,const unsigned char *previous,kate_pack_buffer *kpb)
    00238 {
    00239   const size_t run_length_delta_bits=KATE_RLE_RUN_LENGTH_BITS_DELTA_STOP;
    00240   const size_t run_length_delta_cutoff=(1<<run_length_delta_bits);
    00241   const size_t run_length_basic_bits=KATE_RLE_RUN_LENGTH_BITS_BASIC_IN_DELTA_STOP;
    00242   const size_t run_length_basic_cutoff=(1<<run_length_basic_bits)-1;
    00243   size_t max_run_length_delta,max_run_length_basic;
    00244   size_t run_length_delta,run_length_basic,run_length;
    00245
    00246   while (count>0) {
    00247     if (values[0]==zero) {
    00248       run_length=get_run_length(count,count,values);
    00249       if (run_length==count) {
    00250         kate_pack_write(kpb,0,1);
    00251         kate_pack_write(kpb,0,run_length_basic_bits);
    00252         break;
    00253       }
    00254     }
    00255
    00256     max_run_length_delta=run_length_delta_cutoff;
    00257     run_length_delta=get_run_length_identical(max_run_length_delta,count,values,previous,zero);
    00258
    00259     max_run_length_basic=run_length_basic_cutoff;
    00260     run_length_basic=get_run_length(max_run_length_basic,count,values);
    00261
    00262     if (run_length_delta>run_length_basic) {
    00263       kate_pack_write(kpb,1,1);
    00264       run_length=run_length_delta;
    00265       kate_pack_write(kpb,run_length-1,run_length_delta_bits);
    00266     }
    00267     else {
    00268       kate_pack_write(kpb,0,1);
    00269       run_length=run_length_basic;
    00270       kate_pack_write(kpb,run_length,run_length_basic_bits);
    00271       kate_pack_write(kpb,values[0],bits);
    00272     }
    00273     values+=run_length;
    00274     if (previous) previous+=run_length;
    00275     count-=run_length;
    00276   }
    00277
    00278   return 0;
    00279 }
    00280
    00281 #ifdef DEBUG
    00282 int kate_rle_stats[8]={0};
    00283 int kate_rle_stats_overall[8]={0};
    00284 #endif
    00285
    00286 static int kate_rle_try_encoding(kate_pack_buffer *kpb,int (*encoder)(size_t,const unsigned char*,size_t,unsigned char,const unsigned char*,kate_pack_buffer*),size_t width,const unsigned char *values,size_t bits,unsigned char zero,const unsigned char *previous,int kpb_type,int type)
    00287 {
    00288   kate_pack_buffer tmp;
    00289   kate_pack_writeinit(&tmp);
    00290   if ((*encoder)(width,values,bits,zero,previous,&tmp)==0) {
    00291     long kpb_size=kate_pack_bits(kpb);
    00292     long tmp_size=kate_pack_bits(&tmp);
    00293     if (kpb_type<0 || tmp_size<kpb_size) {
    00294       kate_pack_writeclear(kpb);
    00295       memcpy(kpb,&tmp,sizeof(tmp));
    00296       return type;
    00297     }
    00298   }
    00299   kate_pack_writeclear(&tmp);
    00300   return kpb_type;
    00301 }
    00302
    00303 static unsigned char get_zero(size_t count,const unsigned char *values)
    00304 {
    00305   int counts[256],n,best=0;
    00306   memset(counts,0,sizeof(counts));
    00307   while (count-->0) ++counts[*values++];
    00308   for (n=0;n<256;++n) if (counts[n]>counts[best]) best=n;
    00309   return best;
    00310 }
    00311
    00312 static int kate_rle_encode_best(size_t width,size_t height,const unsigned char *values,size_t bits,kate_pack_buffer *kpb)
    00313 {
    00314   const unsigned char *previous=NULL;
    00315   const unsigned char zero=get_zero(width*height,values);
    00316
    00317 #ifdef DEBUG
    00318   memset(kate_rle_stats,0,sizeof(kate_rle_stats));
    00319 #endif
    00320
    00321   kate_pack_write(kpb,zero,bits);
    00322   while (height>0) {
    00323     int best_type=-1;
    00324     kate_pack_buffer best_buffer;
    00325     kate_pack_writeinit(&best_buffer);
    00326
    00327     best_type=kate_rle_try_encoding(&best_buffer,&kate_rle_encode_line_empty,width,values,bits,zero,previous,best_type,KATE_RLE_TYPE_EMPTY);
    00328     best_type=kate_rle_try_encoding(&best_buffer,&kate_rle_encode_line_delta,width,values,bits,zero,previous,best_type,KATE_RLE_TYPE_DELTA);
    00329     best_type=kate_rle_try_encoding(&best_buffer,&kate_rle_encode_line_basic,width,values,bits,zero,previous,best_type,KATE_RLE_TYPE_BASIC);
    00330     best_type=kate_rle_try_encoding(&best_buffer,&kate_rle_encode_line_basic_startend,width,values,bits,zero,previous,best_type,KATE_RLE_TYPE_BASIC_STARTEND);
    00331     best_type=kate_rle_try_encoding(&best_buffer,&kate_rle_encode_line_basic_stop,width,values,bits,zero,previous,best_type,KATE_RLE_TYPE_BASIC_STOP);
    00332     best_type=kate_rle_try_encoding(&best_buffer,&kate_rle_encode_line_delta_stop,width,values,bits,zero,previous,best_type,KATE_RLE_TYPE_DELTA_STOP);
    00333     best_type=kate_rle_try_encoding(&best_buffer,&kate_rle_encode_line_basic_zero,width,values,bits,zero,previous,best_type,KATE_RLE_TYPE_BASIC_ZERO);
    00334
    00335 #ifdef DEBUG
    00336     ++kate_rle_stats[best_type];
    00337     ++kate_rle_stats_overall[best_type];
    00338 #endif
    00339
    00340     kate_pack_write(kpb,best_type,KATE_RLE_TYPE_BITS);
    00341     kate_pack_writecopy(kpb,kate_pack_get_buffer(&best_buffer),kate_pack_bits(&best_buffer));
    00342
    00343     kate_pack_writeclear(&best_buffer);
    00344
    00345     previous=values;
    00346
    00347     values+=width;
    00348     --height;
    00349   }
    00350
    00351   return 0;
    00352 }
    00353
    00354 int kate_rle_encode(size_t width,size_t height,const unsigned char *values,size_t bits,kate_pack_buffer *kpb)
    00355 {
    00356   return kate_rle_encode_best(width,height,values,bits,kpb);
    00357 }
    00358
    00359 static int kate_rle_decode_line_empty(size_t count,unsigned char *values,size_t bits kate_unused,unsigned char zero,kate_pack_buffer *kpb kate_unused)
    00360 {
    00361   memset(values,zero,count);
    00362   return 0;
    00363 }
    00364
    00365 static int kate_rle_decode_line_basic(size_t count,unsigned char *values,size_t bits,kate_pack_buffer *kpb)
    00366 {
    00367   const size_t run_length_bits=KATE_RLE_RUN_LENGTH_BITS_BASIC;
    00368   size_t run_length;
    00369   int value;
    00370
    00371   while (count>0) {
    00372     run_length=1+kate_pack_read(kpb,run_length_bits);
    00373     if (run_length==0 || run_length>count) return KATE_E_BAD_PACKET;
    00374     value=kate_pack_read(kpb,bits);
    00375     memset(values,value,run_length);
    00376     values+=run_length;
    00377     count-=run_length;
    00378   }
    00379
    00380   return 0;
    00381 }
    00382
    00383 static int kate_rle_decode_line_basic_zero(size_t count,unsigned char *values,size_t bits,unsigned char zero,kate_pack_buffer *kpb)
    00384 {
    00385   const size_t run_length_bits_zero=KATE_RLE_RUN_LENGTH_BITS_BASIC_ZERO;
    00386   const size_t run_length_bits_non_zero=KATE_RLE_RUN_LENGTH_BITS_BASIC_NON_ZERO;
    00387   size_t run_length;
    00388   int value;
    00389
    00390   while (count>0) {
    00391     value=kate_pack_read(kpb,bits);
    00392     if (value==zero) {
    00393       run_length=1+kate_pack_read(kpb,run_length_bits_zero);
    00394     }
    00395     else {
    00396       run_length=1+kate_pack_read(kpb,run_length_bits_non_zero);
    00397     }
    00398     if (run_length==0 || run_length>count) return KATE_E_BAD_PACKET;
    00399     memset(values,value,run_length);
    00400     values+=run_length;
    00401     count-=run_length;
    00402   }
    00403
    00404   return 0;
    00405 }
    00406
    00407 static int kate_rle_decode_line_basic_stop(size_t count,unsigned char *values,size_t bits,unsigned char zero,kate_pack_buffer *kpb)
    00408 {
    00409   const size_t run_length_bits=KATE_RLE_RUN_LENGTH_BITS_BASIC_STOP;
    00410   size_t run_length;
    00411   int value;
    00412
    00413   run_length=kate_pack_read(kpb,KATE_RLE_RUN_LENGTH_BITS_BASIC_STOP_START);
    00414   if (run_length>0) {
    00415     if (run_length>count) return KATE_E_BAD_PACKET;
    00416     memset(values,zero,run_length);
    00417     values+=run_length;
    00418     count-=run_length;
    00419   }
    00420
    00421   while (count>0) {
    00422     run_length=kate_pack_read(kpb,run_length_bits);
    00423     if (run_length>count) return KATE_E_BAD_PACKET;
    00424     if (run_length==0) {
    00425       memset(values,zero,count);
    00426       break;
    00427     }
    00428     value=kate_pack_read(kpb,bits);
    00429     memset(values,value,run_length);
    00430     values+=run_length;
    00431     count-=run_length;
    00432   }
    00433
    00434   return 0;
    00435 }
    00436
    00437 static int kate_rle_decode_line_basic_startend(size_t count,unsigned char *values,size_t bits,unsigned char zero,kate_pack_buffer *kpb)
    00438 {
    00439   const size_t run_length_bits=KATE_RLE_RUN_LENGTH_BITS_BASIC_STARTEND;
    00440   size_t run_length;
    00441   int value;
    00442
    00443   run_length=kate_pack_read(kpb,KATE_RLE_RUN_LENGTH_BITS_BASIC_STARTEND_START);
    00444   if (run_length>0) {
    00445     if (run_length>count) return KATE_E_BAD_PACKET;
    00446     memset(values,zero,run_length);
    00447     values+=run_length;
    00448     count-=run_length;
    00449   }
    00450
    00451   run_length=kate_pack_read(kpb,KATE_RLE_RUN_LENGTH_BITS_BASIC_STARTEND_END);
    00452   if (run_length>0) {
    00453     if (run_length>count) return KATE_E_BAD_PACKET;
    00454     memset(values+count-run_length,zero,run_length);
    00455     count-=run_length;
    00456   }
    00457
    00458   while (count>0) {
    00459     run_length=1+kate_pack_read(kpb,run_length_bits);
    00460     if (run_length_bits==0 || run_length>count) return KATE_E_BAD_PACKET;
    00461     value=kate_pack_read(kpb,bits);
    00462     memset(values,value,run_length);
    00463     values+=run_length;
    00464     count-=run_length;
    00465   }
    00466
    00467   return 0;
    00468 }
    00469
    00470 static int kate_rle_decode_line_delta(size_t count,unsigned char *values,const unsigned char *previous,size_t bits,unsigned char zero,kate_pack_buffer *kpb)
    00471 {
    00472   const size_t run_length_delta_bits=KATE_RLE_RUN_LENGTH_BITS_DELTA;
    00473   const size_t run_length_basic_bits=KATE_RLE_RUN_LENGTH_BITS_BASIC_IN_DELTA;
    00474   int value;
    00475
    00476   while (count>0) {
    00477     int type=kate_pack_read1(kpb);
    00478     if (type) {
    00479       size_t run_length=1+kate_pack_read(kpb,run_length_delta_bits);
    00480       if (run_length==0 || run_length>count) return KATE_E_BAD_PACKET;
    00481       if (previous) {
    00482         memcpy(values,previous,run_length);
    00483         previous+=run_length;
    00484       }
    00485       else {
    00486         memset(values,zero,run_length);
    00487       }
    00488       values+=run_length;
    00489       count-=run_length;
    00490     }
    00491     else {
    00492       size_t run_length=1+kate_pack_read(kpb,run_length_basic_bits);
    00493       if (run_length==0 || run_length>count) return KATE_E_BAD_PACKET;
    00494       value=kate_pack_read(kpb,bits);
    00495       memset(values,value,run_length);
    00496       values+=run_length;
    00497       if (previous) previous+=run_length;
    00498       count-=run_length;
    00499     }
    00500   }
    00501   return 0;
    00502 }
    00503
    00504 static int kate_rle_decode_line_delta_stop(size_t count,unsigned char *values,const unsigned char *previous,size_t bits,unsigned char zero,kate_pack_buffer *kpb)
    00505 {
    00506   const size_t run_length_delta_bits=KATE_RLE_RUN_LENGTH_BITS_DELTA_STOP;
    00507   const size_t run_length_basic_bits=KATE_RLE_RUN_LENGTH_BITS_BASIC_IN_DELTA_STOP;
    00508   size_t run_length;
    00509   int value,type;
    00510
    00511   while (count>0) {
    00512     type=kate_pack_read1(kpb);
    00513     if (type) {
    00514       run_length=1+kate_pack_read(kpb,run_length_delta_bits);
    00515       if (run_length==0 || run_length>count) return KATE_E_BAD_PACKET;
    00516       if (previous) {
    00517         memcpy(values,previous,run_length);
    00518       }
    00519       else {
    00520         memset(values,zero,run_length);
    00521       }
    00522     }
    00523     else {
    00524       run_length=kate_pack_read(kpb,run_length_basic_bits);
    00525       if (run_length==0) {
    00526         memset(values,zero,count);
    00527         break;
    00528       }
    00529       if (run_length>count) return KATE_E_BAD_PACKET;
    00530       value=kate_pack_read(kpb,bits);
    00531       memset(values,value,run_length);
    00532     }
    00533     values+=run_length;
    00534     if (previous) previous+=run_length;
    00535     count-=run_length;
    00536   }
    00537   return 0;
    00538 }
    00539
    00540 static int kate_rle_decode_best(size_t width,size_t height,unsigned char *values,size_t bits,kate_pack_buffer *kpb)
    00541 {
    00542   const unsigned char *previous=NULL;
    00543   int ret;
    00544
    00545   const unsigned char zero=kate_pack_read(kpb,bits);
    00546   while (height>0) {
    00547     int type=kate_pack_read(kpb,KATE_RLE_TYPE_BITS);
    00548     switch (type) {
    00549       case KATE_RLE_TYPE_EMPTY:
    00550         ret=kate_rle_decode_line_empty(width,values,bits,zero,kpb);
    00551         break;
    00552       case KATE_RLE_TYPE_DELTA:
    00553         ret=kate_rle_decode_line_delta(width,values,previous,bits,zero,kpb);
    00554         break;
    00555       case KATE_RLE_TYPE_BASIC:
    00556         ret=kate_rle_decode_line_basic(width,values,bits,kpb);
    00557         break;
    00558       case KATE_RLE_TYPE_BASIC_STARTEND:
    00559         ret=kate_rle_decode_line_basic_startend(width,values,bits,zero,kpb);
    00560         break;
    00561       case KATE_RLE_TYPE_BASIC_STOP:
    00562         ret=kate_rle_decode_line_basic_stop(width,values,bits,zero,kpb);
    00563         break;
    00564       case KATE_RLE_TYPE_DELTA_STOP:
    00565         ret=kate_rle_decode_line_delta_stop(width,values,previous,bits,zero,kpb);
    00566         break;
    00567       case KATE_RLE_TYPE_BASIC_ZERO:
    00568         ret=kate_rle_decode_line_basic_zero(width,values,bits,zero,kpb);
    00569         break;
    00570       default:
    00571         ret=KATE_E_BAD_PACKET;
    00572         break;
    00573     }
    00574     if (ret<0) return ret;
    00575
    00576     previous=values;
    00577     values+=width;
    00578     --height;
    00579   }
    00580
    00581   return 0;
    00582 }
    00583
    00584 int kate_rle_decode(size_t width,size_t height,unsigned char *values,size_t bits,kate_pack_buffer *kpb)
    00585 {
    00586   return kate_rle_decode_best(width,height,values,bits,kpb);
    00587 }
    00588